5.9.4-rc1 review
Subsystems (6)
Greg Kroah-Hartman
maintainercover 5.9.4-rc1 review
This is the start of the stable review cycle for the 5.9.4 release. There are 391 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 05 Nov 2020 20:29:58 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.9.4-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-5.9.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 5.9.4-rc1
Stephen Boyd <[email protected]>
KVM: arm64: ARM_SMCCC_ARCH_WORKAROUND_1 doesn't return SMCCC_RET_NOT_REQUIRED
Quanyang Wang <[email protected]>
time/sched_clock: Mark sched_clock_read_begin/retry() as notrace
Zeng Tao <[email protected]>
time: Prevent undefined behaviour in timespec64_to_ns()
Jing Xiangfeng <[email protected]>
vdpa/mlx5: Fix error return in map_direct_mr()
Dan Carpenter <[email protected]>
vhost_vdpa: Return -EFAULT if copy_from_user() fails
Rafael J. Wysocki <[email protected]>
cpufreq: schedutil: Always call driver if CPUFREQ_NEED_UPDATE_LIMITS is set
Rafael J. Wysocki <[email protected]>
cpufreq: Introduce cpufreq_driver_test_flags()
Alexander Sverdlin <[email protected]>
staging: octeon: Drop on uncorrectable alignment or FCS error
Alexander Sverdlin <[email protected]>
staging: octeon: repair "fixed-link" support
Ian Abbott <[email protected]>
staging: comedi: cb_pcidas: Allow 2-channel commands for AO subdevice
Jing Xiangfeng <[email protected]>
staging: fieldbus: anybuss: jump to correct label in an error path
Zong Li <[email protected]>
stop_machine, rcu: Mark functions as notrace
Marc Zyngier <[email protected]>
KVM: arm64: Fix AArch32 handling of DBGD{CCINT,SCRext} and DBGVCR
Takashi Iwai <[email protected]>
KVM: x86: Fix NULL dereference at kvm_msr_ignored_check()
Andy Shevchenko <[email protected]>
device property: Don't clear secondary pointer for shared primary firmware node
Andy Shevchenko <[email protected]>
device property: Keep secondary firmware node secondary by type
Suzuki K Poulose <[email protected]>
coresight: cti: Initialize dynamic sysfs attributes
Kanchan Joshi <[email protected]>
null_blk: synchronization fix for zoned device
Pali Rohár <[email protected]>
arm64: dts: marvell: espressobin: Add ethernet switch aliases
Fangrui Song <[email protected]>
arm64: Change .weak to SYM_FUNC_START_WEAK_PI for arch/arm64/lib/mem*.S
Krzysztof Kozlowski <[email protected]>
ARM: s3c24xx: fix missing system reset
Krzysztof Kozlowski <[email protected]>
ARM: samsung: fix PM debug build with DEBUG_LL but !MMU
Joel Stanley <[email protected]>
ARM: config: aspeed: Fix selection of media drivers
Krzysztof Kozlowski <[email protected]>
ARM: dts: s5pv210: fix pinctrl property of "vibrator-en" regulator in Aries
Joel Stanley <[email protected]>
ARM: aspeed: g5: Do not set sirq polarity
Frank Wunderlich <[email protected]>
arm: dts: mt7623: add missing pause for switchport
Helge Deller <[email protected]>
hil/parisc: Disable HIL driver when it gets stuck
Matthew Wilcox (Oracle) <[email protected]>
cachefiles: Handle readpage error correctly
Jisheng Zhang <[email protected]>
arm64: berlin: Select DW_APB_TIMER_OF
Linus Torvalds <[email protected]>
tty: make FONTX ioctl use the tty pointer they were actually passed
Likun Gao <[email protected]>
drm/amdgpu: correct the cu and rb info for sienna cichlid
Andrey Grodzovsky <[email protected]>
drm/amd/psp: Fix sysfs: cannot create duplicate filename
Kevin Wang <[email protected]>
drm/amd/swsmu: add missing feature map for sienna_cichlid
Kenneth Feng <[email protected]>
drm/amd/pm: fix pp_dpm_fclk
Evan Quan <[email protected]>
drm/amd/pm: increase mclk switch threshold to 200 us
Alex Deucher <[email protected]>
drm/amdgpu/swsmu: drop smu i2c bus on navi1x
Andrei Vagin <[email protected]>
futex: Adjust absolute futex timeouts with per time namespace offset
Alex Dewar <[email protected]>
memory: brcmstb_dpfe: Fix memory leak
Thierry Reding <[email protected]>
memory: tegra: Remove GPU from DRM IOMMU group
Jisheng Zhang <[email protected]>
mmc: sdhci: Use Auto CMD Auto Select only when v4_mode is true
Michael Walle <[email protected]>
mmc: sdhci-of-esdhc: set timeout to max before tuning
Yangbo Lu <[email protected]>
mmc: sdhci-of-esdhc: make sure delay chain locked for HS400
Dave Airlie <[email protected]>
drm/ttm: fix eviction valuable range check.
yangerkun <[email protected]>
ext4: do not use extent after put_bh
Ritesh Harjani <[email protected]>
ext4: fix bs < ps issue reported with dioread_nolock mount opt
Zhang Xiaoxu <[email protected]>
ext4: fix bdev write error check failed when mount fs with ro
zhangyi (F) <[email protected]>
ext4: clear buffer verified flag if read meta block from disk
Constantine Sapuntzakis <[email protected]>
ext4: fix superblock checksum calculation race
Luo Meng <[email protected]>
ext4: fix invalid inode checksum
Ritesh Harjani <[email protected]>
ext4: implement swap_activate aops using iomap
Dinghao Liu <[email protected]>
ext4: fix error handling code in add_new_gdb
Eric Biggers <[email protected]>
ext4: fix leaking sysfs kobject after failed mount
Stefano Garzarella <[email protected]>
vringh: fix __vringh_iov() when riov and wiov are different
Rafael J. Wysocki <[email protected]>
cpufreq: intel_pstate: Avoid missing HWP max updates in passive mode
Rafael J. Wysocki <[email protected]>
cpufreq: Introduce CPUFREQ_NEED_UPDATE_LIMITS driver flag
Rafael J. Wysocki <[email protected]>
cpufreq: Avoid configuring old governors as default with intel_pstate
Chen Yu <[email protected]>
intel_idle: Fix max_cstate for processor models without C-state tables
Mel Gorman <[email protected]>
intel_idle: Ignore _CST if control cannot be taken from the platform
Qiujun Huang <[email protected]>
ring-buffer: Return 0 on success from ring_buffer_resize()
Ansuel Smith <[email protected]>
PCI: qcom: Make sure PCIe is reset before init for rev 2.1.0
Artur Molchanov <[email protected]>
net/sunrpc: Fix return value for sysctl sunrpc.transports
Matthew Wilcox (Oracle) <[email protected]>
9P: Cast to loff_t before multiplying
Ilya Dryomov <[email protected]>
libceph: clear con->out_msg on Policy::stateful_server faults
Matthew Wilcox (Oracle) <[email protected]>
ceph: promote to unsigned long long before shifting
Takashi Iwai <[email protected]>
drm/amd/display: Fix kernel panic by dal_gpio_open() error
Takashi Iwai <[email protected]>
drm/amd/display: Don't invoke kgdb_breakpoint() unconditionally
Christian König <[email protected]>
drm/amdgpu: increase the reserved VM size to 2MB
Likun Gao <[email protected]>
drm/amdgpu: add function to program pbb mode for sienna cichlid
Andrey Grodzovsky <[email protected]>
drm/amd/display: Avoid MST manager resource leak.
Jay Cornwall <[email protected]>
drm/amdkfd: Use same SQ prefetch setting as amdgpu
Evan Quan <[email protected]>
drm/amdgpu: correct the gpu reset handling for job != NULL case
Likun Gao <[email protected]>
drm/amdgpu: update golden setting for sienna_cichlid
Veerabadhran G <[email protected]>
drm/amdgpu: vcn and jpeg ring synchronization
Wesley Chalmers <[email protected]>
drm/amd/display: Increase timeout for DP Disable
David Galiffi <[email protected]>
drm/amd/display: Fix incorrect backlight register offset for DCN
Madhav Chauhan <[email protected]>
drm/amdgpu: don't map BO in reserved region
Krzysztof Kozlowski <[email protected]>
i2c: imx: Fix external abort on interrupt in exit paths
Bartosz Golaszewski <[email protected]>
rtc: rx8010: don't modify the global rtc ops
Krzysztof Kozlowski <[email protected]>
ia64: fix build error with !COREDUMP
Zhihao Cheng <[email protected]>
ubi: check kthread_should_stop() after the setting of task state
Vineet Gupta <[email protected]>
ARC: perf: redo the pct irq missing in device-tree handling
Jiri Olsa <[email protected]>
perf python scripting: Fix printable strings in python3 scripts
Kim Phillips <[email protected]>
perf vendor events amd: Add L2 Prefetch events for zen1
Zhihao Cheng <[email protected]>
ubifs: mount_ubifs: Release authentication resource in error handling path
Zhihao Cheng <[email protected]>
ubifs: Don't parse authentication mount options in remount process
Zhihao Cheng <[email protected]>
ubifs: Fix a memleak after dumping authentication mount options
Richard Weinberger <[email protected]>
ubifs: journal: Make sure to not dirty twice for auth nodes
Zhihao Cheng <[email protected]>
ubifs: xattr: Fix some potential memory leaks while iterating entries
Zhihao Cheng <[email protected]>
ubifs: dent: Fix some potential memory leaks while iterating entries
Chuck Lever <[email protected]>
NFSD: Add missing NFSv2 .pc_func methods
Olga Kornievskaia <[email protected]>
NFSv4.2: support EXCHGID4_FLAG_SUPP_FENCE_OPS 4.2 EXCHANGE_ID flag
Benjamin Coddington <[email protected]>
NFSv4: Wait for stateid updates after CLOSE/OPEN_DOWNGRADE
Bob Peterson <[email protected]>
gfs2: Only access gl_delete for iopen glocks
Andreas Gruenbacher <[email protected]>
gfs2: Make sure we don't miss any delayed withdraws
Sibi Sankar <[email protected]>
remoteproc: Fixup coredump debugfs disable request
Jens Axboe <[email protected]>
io_uring: use type appropriate io_kiocb handler for double poll
Naohiro Aota <[email protected]>
block: advance iov_iter on bio_add_hw_page failure
Christophe Leroy <[email protected]>
powerpc/32: Fix vmap stack - Properly set r1 before activating MMU
Christophe Leroy <[email protected]>
powerpc/32: Fix vmap stack - Do not activate MMU before reading task struct
Michael Neuling <[email protected]>
powerpc: Fix undetected data corruption with P9N DD2.1 VSX CI load emulation
Ganesh Goudar <[email protected]>
powerpc/mce: Avoid nmi_enter/exit in real mode on pseries hash
Christophe Leroy <[email protected]>
powerpc/powermac: Fix low_sleep_handler with KUAP and KUEP
Mahesh Salgaonkar <[email protected]>
powerpc/powernv/elog: Fix race while processing OPAL error log event.
Aneesh Kumar K.V <[email protected]>
powerpc/memhotplug: Make lmb size 64bit
Joel Stanley <[email protected]>
powerpc: Warn about use of smt_snooze_delay
Andrew Donnellan <[email protected]>
powerpc/rtas: Restrict RTAS requests from userspace
Sven Schnelle <[email protected]>
s390/stp: add locking to sysfs functions
Paul Cercueil <[email protected]>
MIPS: configs: lb60: Fix defconfig not selecting correct board
Maciej W. Rozycki <[email protected]>
MIPS: DEC: Restore bootmem reservation for firmware working memory area
Paul E. McKenney <[email protected]>
rcu-tasks: Enclose task-list scan in rcu_read_lock()
Paul E. McKenney <[email protected]>
rcu-tasks: Fix low-probability task_struct leak
Paul E. McKenney <[email protected]>
rcu-tasks: Fix grace-period/unlock race in RCU Tasks Trace
Aneesh Kumar K.V <[email protected]>
powerpc/drmem: Make lmb_size 64 bit
Jonathan Cameron <[email protected]>
iio:gyro:itg3200: Fix timestamp alignment and prevent data leak.
Jonathan Cameron <[email protected]>
iio:imu:st_lsm6dsx Fix alignment and data leak issues
Jonathan Cameron <[email protected]>
iio:adc:ti-adc12138 Fix alignment issue with timestamp
Jonathan Cameron <[email protected]>
iio:adc:ti-adc0832 Fix alignment issue with timestamp
Nuno Sá <[email protected]>
iio: ad7292: Fix of_node refcounting
Tobias Jordan <[email protected]>
iio: adc: gyroadc: fix leak of device node iterator
Jonathan Cameron <[email protected]>
iio:light:si1145: Fix timestamp alignment and prevent data leak.
Tom Rix <[email protected]>
iio:imu:st_lsm6dsx: check st_lsm6dsx_shub_read_output return
Jonathan Cameron <[email protected]>
iio:imu:inv_mpu6050 Fix dma and ts alignment and data leak issues.
Eugen Hristev <[email protected]>
iio: adc: at91-sama5d2_adc: fix DMA conversion crash
Nuno Sá <[email protected]>
iio: ltc2983: Fix of_node refcounting
Daniel Vetter <[email protected]>
drm/shme-helpers: Fix dma_buf_mmap forwarding bug
Laurent Vivier <[email protected]>
vdpa_sim: Fix DMA mask
Paul Cercueil <[email protected]>
dmaengine: dma-jz4780: Fix race in jz4780_dma_tx_status
Jan Kara <[email protected]>
udf: Fix memory leak when mounting
Christophe Leroy <[email protected]>
powerpc: Fix random segfault when freeing hugetlb range
Michael S. Tsirkin <[email protected]>
Revert "vhost-vdpa: fix page pinning leakage in error path"
Gaurav Kohli <[email protected]>
tracing: Fix race in trace_open and buffer resize call
Vladimir Oltean <[email protected]>
tty: serial: fsl_lpuart: LS1021A has a FIFO size of 16 words, like LS1028A
Russell King <[email protected]>
tty: serial: 21285: fix lockup on open
Borislav Petkov <[email protected]>
x86/mce: Allow for copy_mc_fragile symbol checksum to be generated
Jason Gerecke <[email protected]>
HID: wacom: Avoid entering wacom_wac_pen_report for pad / battery
Jiri Slaby <[email protected]>
vt_ioctl: fix GIO_UNIMAP regression
Jiri Slaby <[email protected]>
vt: keyboard, extend func_buf_lock to readers
Jiri Slaby <[email protected]>
vt: keyboard, simplify vt_kdgkbsent
Chris Wilson <[email protected]>
drm/i915: Force VT'd workarounds when running as a guest OS
Bastien Nocera <[email protected]>
USB: apple-mfi-fastcharge: don't probe unhandled devices
Bastien Nocera <[email protected]>
usbcore: Check both id_table and match() when both available
Ran Wang <[email protected]>
usb: host: fsl-mph-dr-of: check return of dma_set_mask()
Li Jun <[email protected]>
usb: typec: tcpm: reset hard_reset_count for any disconnect
Jerome Brunet <[email protected]>
usb: cdc-acm: fix cooldown mechanism
Pawel Laszczak <[email protected]>
usb: cdns3: Fix on-chip memory overflow issue
Thinh Nguyen <[email protected]>
usb: dwc3: gadget: END_TRANSFER before CLEAR_STALL command
Thinh Nguyen <[email protected]>
usb: dwc3: gadget: Resume pending requests after CLEAR_STALL
Li Jun <[email protected]>
usb: dwc3: core: don't trigger runtime pm when remove driver
Li Jun <[email protected]>
usb: dwc3: core: add phy cleanup for probe error handling
Thinh Nguyen <[email protected]>
usb: dwc3: gadget: Reclaim extra TRBs after request completion
Thinh Nguyen <[email protected]>
usb: dwc3: gadget: Check MPS of the request length
Thinh Nguyen <[email protected]>
usb: dwc3: ep0: Fix ZLP for OUT ep0 requests
Raymond Tan <[email protected]>
usb: dwc3: pci: Allow Elkhart Lake to utilize DSM method for PM functionality
Sandeep Singh <[email protected]>
usb: xhci: Workaround for S3 issue on AMD SNPS 3.0 xHC
Josef Bacik <[email protected]>
btrfs: drop the path before adding block group sysfs files
Filipe Manana <[email protected]>
btrfs: fix readahead hang and use-after-free after removing a device
Filipe Manana <[email protected]>
btrfs: fix use-after-free on readahead extent after failure to create it
Daniel Xu <[email protected]>
btrfs: tree-checker: validate number of chunk stripes and parity
Anand Jain <[email protected]>
btrfs: skip devices without magic signature when mounting
Josef Bacik <[email protected]>
btrfs: cleanup cow block on error
Johannes Thumshirn <[email protected]>
btrfs: reschedule when cloning lots of extents
Qu Wenruo <[email protected]>
btrfs: tree-checker: fix false alert caused by legacy btrfs root item
Denis Efremov <[email protected]>
btrfs: use kvzalloc() to allocate clone_roots in btrfs_ioctl_send()
Filipe Manana <[email protected]>
btrfs: send, recompute reference path after orphanization of a directory
Filipe Manana <[email protected]>
btrfs: send, orphanize first all conflicting inodes when processing references
Filipe Manana <[email protected]>
btrfs: reschedule if necessary when logging directory items
Qu Wenruo <[email protected]>
btrfs: tracepoints: output proper root owner for trace_find_free_extent()
Josef Bacik <[email protected]>
btrfs: sysfs: init devices outside of the chunk_mutex
Qu Wenruo <[email protected]>
btrfs: qgroup: fix qgroup meta rsv leak for subvolume operations
Anand Jain <[email protected]>
btrfs: improve device scanning messages
Qu Wenruo <[email protected]>
btrfs: qgroup: fix wrong qgroup metadata reserve for delayed inode
Xiang Chen <[email protected]>
PM: runtime: Remove link state checks in rpm_get/put_supplier()
Quinn Tran <[email protected]>
scsi: qla2xxx: Fix crash on session cleanup with unload
Arun Easi <[email protected]>
scsi: qla2xxx: Fix reset of MPI firmware
Arun Easi <[email protected]>
scsi: qla2xxx: Fix MPI reset needed message
Helge Deller <[email protected]>
scsi: mptfusion: Fix null pointer dereferences in mptscsih_remove()
Kees Cook <[email protected]>
fs/kernel_read_file: Remove FIRMWARE_PREALLOC_BUFFER enum
Martin Fuzzey <[email protected]>
w1: mxc_w1: Fix timeout resolution problem leading to bus error
Jens Axboe <[email protected]>
io-wq: assign NUMA node locality if appropriate
Wei Huang <[email protected]>
acpi-cpufreq: Honor _PSD table setting on new AMD CPUs
Rafael J. Wysocki <[email protected]>
ACPI: EC: PM: Drop ec_no_wakeup check from acpi_ec_dispatch_gpe()
Rafael J. Wysocki <[email protected]>
ACPI: EC: PM: Flush EC work unconditionally after wakeup
Lukas Wunner <[email protected]>
PCI/ACPI: Whitelist hotplug ports for D3 if power managed by ACPI
Jamie Iles <[email protected]>
ACPI: debug: don't allow debugging when ACPI is disabled
Alex Hung <[email protected]>
ACPI: video: use ACPI backlight for HP 635 Notebook
Ben Hutchings <[email protected]>
ACPI / extlog: Check for RDMSR failure
[email protected] <[email protected]>
ACPI: button: fix handling lid state changes when input device closed
Ashish Sangwan <[email protected]>
NFS: fix nfs_path in case of a rename retry
Hanjun Guo <[email protected]>
ACPI: configfs: Add missing config_item_put() to fix refcount leak
Jan Kara <[email protected]>
fs: Don't invalidate page buffers in block_write_full_page()
Hans de Goede <[email protected]>
media: uvcvideo: Fix uvc_ctrl_fixup_xu_info() not having any effect
Steve Foreman <[email protected]>
hwmon: (pmbus/max34440) Fix OC fault limits
Marek Behún <[email protected]>
leds: bcm6328, bcm6358: use devres LED registering function
Krzysztof Kozlowski <[email protected]>
extcon: ptn5150: Fix usage of atomic GPIO with sleeping GPIO chips
Krzysztof Kozlowski <[email protected]>
spi: sprd: Release DMA channel also on probe deferral
Chuanhong Guo <[email protected]>
spi: spi-mtk-nor: fix timeout calculation overflow
Kim Phillips <[email protected]>
perf/x86/amd/ibs: Fix raw sample data accumulation
Kim Phillips <[email protected]>
perf/x86/amd/ibs: Don't include randomized bits in get_ibs_op_count()
Kim Phillips <[email protected]>
perf/amd/uncore: Set all slices and threads to restore perf stat -a behaviour
Kim Phillips <[email protected]>
perf/x86/amd: Fix sampling Large Increment per Cycle events
Kan Liang <[email protected]>
perf/x86/intel: Fix Ice Lake event constraint table
Andy Lutomirski <[email protected]>
selftests/x86/fsgsbase: Test PTRACE_PEEKUSER for GSBASE with invalid LDT GS
Jann Horn <[email protected]>
seccomp: Make duplicate listener detection non-racy
Bharata B Rao <[email protected]>
mm: memcg/slab: uncharge during kmem_cache_free_bulk()
Raul E Rangel <[email protected]>
mmc: sdhci-acpi: AMDI0040: Set SDHCI_QUIRK2_PRESET_VALUE_BROKEN
Adrian Hunter <[email protected]>
mmc: sdhci: Add LTR support for some Intel BYT based controllers
Song Liu <[email protected]>
md/raid5: fix oops during stripe resizing
Guoqing Jiang <[email protected]>
md: fix the checking of wrong work queue
Huacai Chen <[email protected]>
irqchip/loongson-htvec: Fix initial interrupt clearing
Nick Desaulniers <[email protected]>
vmlinux.lds.h: Add PGO and AutoFDO input sections
Chao Leng <[email protected]>
nvme-rdma: fix crash when connect rejected
Douglas Gilbert <[email protected]>
sgl_alloc_order: fix memory leak
Xiubo Li <[email protected]>
nbd: make the config put is called before the notifying the waiter
Konrad Dybcio <[email protected]>
arm64: dts: qcom: kitakami: Temporarily disable SDHCI1
Sudeep Holla <[email protected]>
firmware: arm_scmi: Move scmi bus init and exit calls into the driver
Grygorii Strashko <[email protected]>
bindings: soc: ti: soc: ringacc: remove ti,dma-ring-reset-quirk
Grygorii Strashko <[email protected]>
soc: ti: k3: ringacc: add am65x sr2.0 support
Stephen Boyd <[email protected]>
soc: qcom: rpmh-rsc: Sleep waiting for tcs slots to be free
Krzysztof Kozlowski <[email protected]>
ARM: dts: s5pv210: align SPI GPIO node name with dtschema in Aries
Krzysztof Kozlowski <[email protected]>
ARM: dts: s5pv210: add RTC 32 KHz clock in Aries family
Krzysztof Kozlowski <[email protected]>
ARM: dts: s5pv210: remove dedicated 'audio-subsystem' node
Krzysztof Kozlowski <[email protected]>
ARM: dts: s5pv210: move PMU node out of clock controller
Krzysztof Kozlowski <[email protected]>
ARM: dts: s5pv210: move fixed clocks under root node
Krzysztof Kozlowski <[email protected]>
ARM: dts: s5pv210: remove DMA controller bus node name to fix dtschema warnings
Jonathan Bakker <[email protected]>
ARM: dts: s5pv210: Enable audio on Aries boards
Dan Carpenter <[email protected]>
memory: emif: Remove bogus debugfs error handling
Tony Lindgren <[email protected]>
ARM: dts: omap4: Fix sgx clock rate for 4430
Yoshihiro Shimoda <[email protected]>
arm64: dts: renesas: ulcb: add full-pwr-cycle-in-suspend into eMMC nodes
Ronnie Sahlberg <[email protected]>
cifs: handle -EINTR in cifs_setattr
Rohith Surabattula <[email protected]>
Handle STATUS_IO_TIMEOUT gracefully
Anant Thazhemadam <[email protected]>
gfs2: add validation checks for size of superblock
Jamie Iles <[email protected]>
gfs2: use-after-free in sysfs deregistration
Andrew Price <[email protected]>
gfs2: Fix NULL pointer dereference in gfs2_rgrp_dump
Bob Peterson <[email protected]>
gfs2: call truncate_inode_pages_final for address space glocks
Christoph Hellwig <[email protected]>
scsi: core: Clean up allocation and freeing of sgtables
Fabiano Rosas <[email protected]>
KVM: PPC: Book3S HV: Do not allocate HPT for a nested guest
Jan Kara <[email protected]>
ext4: Detect already used quota file early
changfengnan <[email protected]>
jbd2: avoid transaction reuse after reformatting
Madhuparna Bhowmik <[email protected]>
drivers: watchdog: rdc321x_wdt: Fix race condition bugs
Yan, Zheng <[email protected]>
ceph: encode inodes' parent/d_name in cap reconnect message
Anant Thazhemadam <[email protected]>
net: 9p: initialize sun_server.sun_path to have addr's value only when addr is valid
J. Bruce Fields <[email protected]>
nfsd4: remove check_conflicting_opens warning
Hou Tao <[email protected]>
nfsd: rename delegation related tracepoints to make them less confusing
Tero Kristo <[email protected]>
clk: ti: clockdomain: fix static checker warning
Tuan Phan <[email protected]>
PCI/ACPI: Add Ampere Altra SOC MCFG quirk
Chris Lew <[email protected]>
rpmsg: glink: Use complete_all for open states
Michael Chan <[email protected]>
bnxt_en: Log unknown link speed appropriately.
Chao Yu <[email protected]>
f2fs: fix to set SBI_NEED_FSCK flag for inconsistent inode
Zhao Heming <[email protected]>
md/bitmap: md_bitmap_get_counter returns wrong blocks
Anand Jain <[email protected]>
btrfs: fix replace of seed device
Gabriel Krisman Bertazi <[email protected]>
block: Consider only dispatched requests for inflight statistic
Zhen Lei <[email protected]>
ARC: [dts] fix the errors detected by dtbs_check
Rodrigo Siqueira <[email protected]>
drm/amd/display: Avoid set zero in the requested clk
Fangzhi Zuo <[email protected]>
drm/amd/display: HDMI remote sink need mode validation for Linux
Xiongfeng Wang <[email protected]>
power: supply: test_power: add missing newlines when printing parameters by sysfs
Jonathan Cameron <[email protected]>
ACPI: HMAT: Fix handling of changes from ACPI 6.2 to ACPI 6.3
Diana Craciun <[email protected]>
bus/fsl_mc: Do not rely on caller to provide non NULL mc_io
Bhaumik Bhatt <[email protected]>
bus: mhi: core: Abort suspends due to outgoing pending packets
Li Jun <[email protected]>
usb: dwc3: core: do not queue work if dr_mode is not USB_DR_MODE_OTG
Xie He <[email protected]>
drivers/net/wan/hdlc_fr: Correctly handle special skb->protocol values
Wen Gong <[email protected]>
ath11k: change to disable softirqs for ath11k_regd_update to solve deadlock
Carl Huang <[email protected]>
ath11k: fix warning caused by lockdep_assert_held
Wen Gong <[email protected]>
ath11k: Use GFP_ATOMIC instead of GFP_KERNEL in ath11k_dp_htt_get_ppdu_desc
Wright Feng <[email protected]>
brcmfmac: Fix warning message after dongle setup failed
Stanislaw Kardach <[email protected]>
octeontx2-af: fix LD CUSTOM LTYPE aliasing
Jonathan Cameron <[email protected]>
ACPI: Add out of bounds and numa_off protections to pxm_to_node()
Gao Xiang <[email protected]>
xfs: avoid LR buffer overrun due to crafted h_len
Darrick J. Wong <[email protected]>
xfs: don't free rt blocks when we're doing a REMAP bunmapi call
farah kassabri <[email protected]>
habanalabs: remove security from ARB_MST_QUIET register
Joakim Zhang <[email protected]>
can: flexcan: disable clocks during stop mode
Zhengyuan Liu <[email protected]>
arm64/mm: return cpu_all_mask when node is NUMA_NO_NODE
Dmitry Osipenko <[email protected]>
cpuidle: tegra: Correctly handle result of arm_cpuidle_simple_enter()
Chuck Lever <[email protected]>
SUNRPC: Mitigate cond_resched() in xprt_transmit()
Peter Chen <[email protected]>
usb: xhci: omit duplicate actions when suspending a runtime suspended host.
Felix Fietkau <[email protected]>
mac80211: add missing queue/hash initialization to 802.3 xmit
Luben Tuikov <[email protected]>
drm/amdgpu: No sysfs, not an error condition
Linu Cherian <[email protected]>
coresight: Make sysfs functional on topologies with per core sink
Lang Dai <[email protected]>
uio: free uio id after uio file node is freed
Oliver Neukum <[email protected]>
USB: adutux: fix debugging
Alain Volmat <[email protected]>
cpufreq: sti-cpufreq: add stih418 support
Zong Li <[email protected]>
riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO
Rodrigo Siqueira <[email protected]>
drm/amd/display: Check clock table return
Magnus Karlsson <[email protected]>
samples/bpf: Fix possible deadlock in xdpsock
Stephen Smalley <[email protected]>
selinux: access policycaps with READ_ONCE/WRITE_ONCE
Yonghong Song <[email protected]>
selftests/bpf: Define string const as global for test_sysctl_prog.c
Krzysztof Kozlowski <[email protected]>
nfc: s3fwrn5: Add missing CRYPTO_HASH dependency
Daniel W. S. Almeida <[email protected]>
media: uvcvideo: Fix dereference of out-of-bound list iterator
Marek Szyprowski <[email protected]>
drm: panfrost: fix common struct sg_table related issues
Marek Szyprowski <[email protected]>
drm: lima: fix common struct sg_table related issues
Marek Szyprowski <[email protected]>
xen: gntdev: fix common struct sg_table related issues
Marek Szyprowski <[email protected]>
drm: exynos: fix common struct sg_table related issues
Yonghong Song <[email protected]>
bpf: Permit map_ptr arithmetic with opcode add and offset 0
Douglas Anderson <[email protected]>
kgdb: Make "kgdbcon" work properly with "kgdb_earlycon"
Michael Ellerman <[email protected]>
selftests/powerpc: Make using_hash_mmu() work on Cell & PowerMac
Masami Hiramatsu <[email protected]>
ia64: kprobes: Use generic kretprobe trampoline handler
John Ogness <[email protected]>
printk: reduce LOG_BUF_SHIFT range for H8300
Valentin Schneider <[email protected]>
arm64: topology: Stop using MPIDR for topology information
Dmitry Osipenko <[email protected]>
brcmfmac: increase F2 watermark for BCM4329
Antonio Borneo <[email protected]>
drm/bridge/synopsys: dsi: add support for non-continuous HS clock
Madhuparna Bhowmik <[email protected]>
mmc: via-sdmmc: Fix data race bug
Hans Verkuil <[email protected]>
media: imx274: fix frame interval handling
Sidong Yang <[email protected]>
drm/vkms: avoid warning in vkms_get_vblank_timestamp
Tom Rix <[email protected]>
media: tw5864: check status of tw5864_frameinterval_get
Badhri Jagan Sridharan <[email protected]>
usb: typec: tcpm: During PR_SWAP, source caps should be sent only after tSwapSourceStart
Xia Jiang <[email protected]>
media: platform: Improve queue set up flow for bug fixing
Jérôme Pouiller <[email protected]>
staging: wfx: fix potential use before init
Marek Szyprowski <[email protected]>
misc: fastrpc: fix common struct sg_table related issues
Akshu Agrawal <[email protected]>
ASoC: AMD: Clean kernel log from deferred probe error messages
Hans Verkuil <[email protected]>
media: videodev2.h: RGB BT2020 and HSV are always full range
Enric Balletbo i Serra <[email protected]>
drm/bridge_connector: Set default status connected for eDP connectors
Andy Lutomirski <[email protected]>
selftests/x86/fsgsbase: Reap a forgotten child
Rander Wang <[email protected]>
ASoC: SOF: fix a runtime pm issue in SOF when HDMI codec doesn't work
Nadezda Lutovinova <[email protected]>
drm/brige/megachips: Add checking if ge_b850v3_lvds_init() is working correctly
Luben Tuikov <[email protected]>
drm/scheduler: Scheduler priority fixes (v2)
Sathishkumar Muruganandam <[email protected]>
ath10k: fix VHT NSS calculation when STBC is enabled
Wen Gong <[email protected]>
ath10k: start recovery process when payload length exceeds max htc length for sdio
Tom Rix <[email protected]>
video: fbdev: pvr2fb: initialize variables
Guchun Chen <[email protected]>
drm/amdgpu: restore ras flags when user resets eeprom(v2)
Thomas Zimmermann <[email protected]>
drm/ast: Separate DRM driver from PCI code
Arvind Sankar <[email protected]>
x86/kaslr: Initialize mem_limit to the real maximum address
Venkateswara Naralasetty <[email protected]>
ath10k: fix retry packets update in station dump
Pavel Begunkov <[email protected]>
io_uring: don't set COMP_LOCKED if won't put
Darrick J. Wong <[email protected]>
xfs: fix realtime bitmap/summary file truncation when growing rt volume
Darrick J. Wong <[email protected]>
xfs: change the order in which child and parent defer ops are finished
Krzysztof Kozlowski <[email protected]>
power: supply: bq27xxx: report "not charging" on all types
Darrick J. Wong <[email protected]>
xfs: log new intent items created as part of finishing recovered intent items
Chandan Babu R <[email protected]>
xfs: Set xfs_buf's b_ops member when zeroing bitmap/summary files
Chandan Babu R <[email protected]>
xfs: Set xfs_buf type flag when growing summary/bitmap files
Dave Wysochanski <[email protected]>
NFS4: Fix oops when copy_file_range is attempted with NFS4.0 source
Douglas Anderson <[email protected]>
ARM: 8997/2: hw_breakpoint: Handle inexact watchpoint addresses
Nicholas Piggin <[email protected]>
powerpc/64s: handle ISA v3.1 local copy-paste context switches
David Howells <[email protected]>
afs: Don't assert on unpurgeable server records
Jaegeuk Kim <[email protected]>
f2fs: handle errors of f2fs_get_meta_page_nofail
Johannes Berg <[email protected]>
um: change sigio_spinlock to a mutex
Harald Freudenberger <[email protected]>
s390/ap/zcrypt: revisit ap and zcrypt error handling
Chao Yu <[email protected]>
f2fs: compress: fix to disallow enabling compress on non-empty file
Vasily Gorbik <[email protected]>
s390/startup: avoid save_area_sync overflow
Chao Yu <[email protected]>
f2fs: fix to check segment boundary during SIT page readahead
Chao Yu <[email protected]>
f2fs: fix uninit-value in f2fs_lookup
Chao Yu <[email protected]>
f2fs: do sanity check on zoned block device path
Zhang Qilong <[email protected]>
f2fs: add trace exit in exception path
Nicholas Piggin <[email protected]>
sparc64: remove mm_cpumask clearing to fix kthread_use_mm race
Nicholas Piggin <[email protected]>
powerpc: select ARCH_WANT_IRQS_OFF_ACTIVATE_MM
Nicholas Piggin <[email protected]>
mm: fix exec activate_mm vs TLB shootdown and lazy tlb switching race
Ravi Bangoria <[email protected]>
powerpc/watchpoint/ptrace: Fix SETHWDEBUG when CONFIG_HAVE_HW_BREAKPOINT=N
Chao Yu <[email protected]>
f2fs: allocate proper size memory for zstd decompress
Jason Gunthorpe <[email protected]>
RDMA/core: Change how failing destroy is handled during uobj abort
Oliver O'Halloran <[email protected]>
powerpc/powernv/smp: Fix spurious DBG() warning
Aneesh Kumar K.V <[email protected]>
powerpc/vmemmap: Fix memory leak with vmemmap list allocation failures.
Mateusz Nosek <[email protected]>
futex: Fix incorrect should_fail_futex() handling
Tang Bin <[email protected]>
usb: host: ehci-tegra: Fix error handling in tegra_ehci_probe()
Peter Zijlstra <[email protected]>
lockdep: Fix preemption WARN for spurious IRQ-enable
Georgi Djakov <[email protected]>
interconnect: qcom: sdm845: Enable keepalive for the MM1 BCM
Laurent Vivier <[email protected]>
vdpasim: fix MAC address configuration
David Howells <[email protected]>
afs: Fix dirty-region encoding on ppc32 with 64K pages
David Howells <[email protected]>
afs: Fix afs_invalidatepage to adjust the dirty region
David Howells <[email protected]>
afs: Alter dirty range encoding in page->private
David Howells <[email protected]>
afs: Wrap page->private manipulations in inline functions
David Howells <[email protected]>
afs: Fix where page->private is set during write
David Howells <[email protected]>
afs: Fix page leak on afs_write_begin() failure
David Howells <[email protected]>
afs: Fix to take ref on page when PG_private is set
Ard Biesheuvel <[email protected]>
arm64: efi: increase EFI PE/COFF header padding to 64 KB
Sascha Hauer <[email protected]>
ata: sata_nv: Fix retrieving of active qcs
Alok Prasad <[email protected]>
RDMA/qedr: Fix memory leak in iWARP CM
David Howells <[email protected]>
afs: Fix afs_launder_page to not clear PG_writeback
Dan Carpenter <[email protected]>
afs: Fix a use after free in afs_xattr_get_acl()
Sasha Levin <[email protected]>
tracing, synthetic events: Replace buggy strcat() with seq_buf operations
Amit Cohen <[email protected]>
mlxsw: core: Fix use-after-free in mlxsw_emad_trans_finish()
Parav Pandit <[email protected]>
RDMA/mlx5: Fix devlink deadlock on net namespace deletion
Sasha Levin <[email protected]>
ionic: no rx flush in deinit
Juergen Gross <[email protected]>
x86/alternative: Don't call text_poke() in lazy TLB mode
Florian Fainelli <[email protected]>
firmware: arm_scmi: Fix duplicate workqueue name
Cristian Marussi <[email protected]>
firmware: arm_scmi: Fix locking in notifications
Jiri Slaby <[email protected]>
x86/unwind/orc: Fix inactive tasks with stack pointer in %sp on GCC 10 compiled kernels
Sudeep Holla <[email protected]>
firmware: arm_scmi: Add missing Rx size re-initialisation
Sumit Garg <[email protected]>
tee: client UUID: Skip REE kernel login method as well
Etienne Carriere <[email protected]>
firmware: arm_scmi: Expand SMC/HVC message pool to more than one
Etienne Carriere <[email protected]>
firmware: arm_scmi: Fix ARCH_COLD_RESET
Juergen Gross <[email protected]>
xen/events: block rogue events for some time
Juergen Gross <[email protected]>
xen/events: defer eoi in case of excessive number of events
Juergen Gross <[email protected]>
xen/events: use a common cpu hotplug hook for event channels
Juergen Gross <[email protected]>
xen/events: switch user event channels to lateeoi model
Juergen Gross <[email protected]>
xen/pciback: use lateeoi irq binding
Juergen Gross <[email protected]>
xen/pvcallsback: use lateeoi irq binding
Juergen Gross <[email protected]>
xen/scsiback: use lateeoi irq binding
Juergen Gross <[email protected]>
xen/netback: use lateeoi irq binding
Juergen Gross <[email protected]>
xen/blkback: use lateeoi irq binding
Juergen Gross <[email protected]>
xen/events: add a new "late EOI" evtchn framework
Juergen Gross <[email protected]>
xen/events: fix race in evtchn_fifo_unmask()
Juergen Gross <[email protected]>
xen/events: add a proper barrier to 2-level uevent unmasking
Juergen Gross <[email protected]>
xen/events: avoid removing an event channel while handling it
-------------
Diffstat:
Documentation/admin-guide/kernel-parameters.txt | 8 + .../devicetree/bindings/soc/ti/k3-ringacc.yaml | 6 - .../userspace-api/media/v4l/colorspaces-defs.rst | 9 +- .../media/v4l/colorspaces-details.rst | 5 +- Makefile | 4 +- arch/Kconfig | 7 + arch/arc/boot/dts/axc001.dtsi | 2 +- arch/arc/boot/dts/axc003.dtsi | 2 +- arch/arc/boot/dts/axc003_idu.dtsi | 2 +- arch/arc/boot/dts/vdk_axc003.dtsi | 2 +- arch/arc/boot/dts/vdk_axc003_idu.dtsi | 2 +- arch/arc/kernel/perf_event.c | 27 +- arch/arm/Kconfig | 2 + arch/arm/boot/dts/aspeed-g5.dtsi | 1 - arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 1 + arch/arm/boot/dts/omap4.dtsi | 2 +- arch/arm/boot/dts/omap443x.dtsi | 10 + arch/arm/boot/dts/s5pv210-aries.dtsi | 26 +- arch/arm/boot/dts/s5pv210-fascinate4g.dts | 98 +++++ arch/arm/boot/dts/s5pv210-galaxys.dts | 85 +++++ arch/arm/boot/dts/s5pv210.dtsi | 163 ++++---- arch/arm/configs/aspeed_g4_defconfig | 3 +- arch/arm/configs/aspeed_g5_defconfig | 3 +- arch/arm/kernel/hw_breakpoint.c | 100 +++-- arch/arm/plat-samsung/Kconfig | 1 + arch/arm64/Kconfig.platforms | 1 + .../marvell/armada-3720-espressobin-v7-emmc.dts | 10 +- .../dts/marvell/armada-3720-espressobin-v7.dts | 10 +- .../boot/dts/marvell/armada-3720-espressobin.dtsi | 12 +- .../dts/qcom/msm8994-sony-xperia-kitakami.dtsi | 7 +- arch/arm64/boot/dts/renesas/ulcb.dtsi | 1 + arch/arm64/include/asm/kvm_host.h | 1 + arch/arm64/include/asm/numa.h | 3 + arch/arm64/kernel/efi-header.S | 2 +- arch/arm64/kernel/topology.c | 32 +- arch/arm64/kvm/hypercalls.c | 2 +- arch/arm64/kvm/sys_regs.c | 6 +- arch/arm64/lib/memcpy.S | 3 +- arch/arm64/lib/memmove.S | 3 +- arch/arm64/lib/memset.S | 3 +- arch/arm64/mm/numa.c | 6 +- arch/ia64/kernel/Makefile | 2 +- arch/ia64/kernel/kprobes.c | 77 +--- arch/mips/configs/qi_lb60_defconfig | 1 + arch/mips/dec/setup.c | 9 +- arch/powerpc/Kconfig | 14 + arch/powerpc/include/asm/drmem.h | 4 +- arch/powerpc/include/asm/mmu_context.h | 2 +- arch/powerpc/kernel/head_32.S | 8 +- arch/powerpc/kernel/head_32.h | 72 ++-- arch/powerpc/kernel/mce.c | 7 +- arch/powerpc/kernel/process.c | 16 +- arch/powerpc/kernel/ptrace/ptrace-noadv.c | 2 +- arch/powerpc/kernel/rtas.c | 153 ++++++++ arch/powerpc/kernel/sysfs.c | 42 +- arch/powerpc/kernel/traps.c | 2 +- arch/powerpc/kvm/book3s_hv.c | 13 + arch/powerpc/kvm/book3s_hv_rmhandlers.S | 8 + arch/powerpc/mm/hugetlbpage.c | 18 +- arch/powerpc/mm/init_64.c | 35 +- arch/powerpc/platforms/powermac/sleep.S | 9 +- arch/powerpc/platforms/powernv/opal-elog.c | 33 +- arch/powerpc/platforms/powernv/smp.c | 2 +- arch/powerpc/platforms/pseries/hotplug-memory.c | 43 ++- arch/riscv/include/uapi/asm/auxvec.h | 3 + arch/s390/boot/head.S | 21 +- arch/s390/kernel/time.c | 118 ++++-- arch/sparc/kernel/smp_64.c | 65 +--- arch/um/kernel/sigio.c | 6 +- arch/x86/boot/compressed/kaslr.c | 41 +- arch/x86/events/amd/ibs.c | 38 +- arch/x86/events/amd/uncore.c | 28 +- arch/x86/events/core.c | 4 +- arch/x86/events/intel/core.c | 2 +- arch/x86/include/asm/asm-prototypes.h | 1 + arch/x86/include/asm/msr-index.h | 1 + arch/x86/kernel/alternative.c | 9 + arch/x86/kernel/unwind_orc.c | 9 +- arch/x86/kvm/x86.c | 8 +- block/bio.c | 11 +- block/blk-mq.c | 2 +- drivers/acpi/acpi_configfs.c | 1 + drivers/acpi/acpi_dbg.c | 3 + drivers/acpi/acpi_extlog.c | 6 +- drivers/acpi/button.c | 13 +- drivers/acpi/ec.c | 10 +- drivers/acpi/numa/hmat.c | 3 +- drivers/acpi/numa/srat.c | 2 +- drivers/acpi/pci_mcfg.c | 20 + drivers/acpi/video_detect.c | 9 + drivers/ata/sata_nv.c | 2 +- drivers/base/core.c | 4 +- drivers/base/firmware_loader/main.c | 5 +- drivers/base/power/runtime.c | 5 +- drivers/block/nbd.c | 2 +- drivers/block/null_blk.h | 1 + drivers/block/null_blk_zoned.c | 22 +- drivers/block/xen-blkback/blkback.c | 22 +- drivers/block/xen-blkback/xenbus.c | 5 +- drivers/bus/fsl-mc/mc-io.c | 7 +- drivers/bus/mhi/core/pm.c | 6 +- drivers/clk/ti/clockdomain.c | 2 + drivers/cpufreq/Kconfig | 2 + drivers/cpufreq/acpi-cpufreq.c | 3 +- drivers/cpufreq/cpufreq.c | 15 +- drivers/cpufreq/intel_pstate.c | 13 +- drivers/cpufreq/sti-cpufreq.c | 6 +- drivers/cpuidle/cpuidle-tegra.c | 34 +- drivers/dma/dma-jz4780.c | 7 +- drivers/extcon/extcon-ptn5150.c | 8 +- drivers/firmware/arm_scmi/base.c | 2 + drivers/firmware/arm_scmi/bus.c | 6 +- drivers/firmware/arm_scmi/clock.c | 2 + drivers/firmware/arm_scmi/common.h | 5 + drivers/firmware/arm_scmi/driver.c | 24 +- drivers/firmware/arm_scmi/notify.c | 22 +- drivers/firmware/arm_scmi/perf.c | 2 + drivers/firmware/arm_scmi/reset.c | 4 +- drivers/firmware/arm_scmi/sensors.c | 2 + drivers/firmware/arm_scmi/smc.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 4 +- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 6 +- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 10 + drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 3 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 13 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 6 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 2 + drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 4 +- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 72 ++++ drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c | 24 +- drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 28 +- drivers/gpu/drm/amd/amdgpu/vcn_v1_0.h | 3 +- .../drm/amd/amdkfd/kfd_device_queue_manager_v10.c | 5 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 + .../amd/display/dc/clk_mgr/dce112/dce112_clk_mgr.c | 3 +- .../drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c | 7 +- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 2 +- .../gpu/drm/amd/display/dc/dce/dce_panel_cntl.h | 2 +- .../amd/display/dc/dcn10/dcn10_stream_encoder.c | 4 +- drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c | 4 +- drivers/gpu/drm/amd/display/dc/os_types.h | 2 +- drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 2 +- drivers/gpu/drm/amd/powerplay/inc/smu_types.h | 1 + drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 26 -- drivers/gpu/drm/amd/powerplay/sienna_cichlid_ppt.c | 6 + drivers/gpu/drm/ast/ast_drv.c | 59 +-- .../drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c | 12 +- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 9 +- drivers/gpu/drm/drm_bridge_connector.c | 1 + drivers/gpu/drm/drm_gem.c | 4 +- drivers/gpu/drm/drm_gem_shmem_helper.c | 7 +- drivers/gpu/drm/exynos/exynos_drm_g2d.c | 10 +- drivers/gpu/drm/i915/i915_drv.h | 6 +- drivers/gpu/drm/lima/lima_gem.c | 11 +- drivers/gpu/drm/lima/lima_vm.c | 5 +- drivers/gpu/drm/panfrost/panfrost_gem.c | 4 +- drivers/gpu/drm/panfrost/panfrost_mmu.c | 7 +- drivers/gpu/drm/scheduler/sched_main.c | 4 +- drivers/gpu/drm/ttm/ttm_bo.c | 2 +- drivers/gpu/drm/vkms/vkms_crtc.c | 5 + drivers/hid/wacom_wac.c | 4 +- drivers/hwmon/pmbus/max34440.c | 23 ++ drivers/hwtracing/coresight/coresight-cti-sysfs.c | 7 + drivers/hwtracing/coresight/coresight-priv.h | 3 +- drivers/hwtracing/coresight/coresight.c | 62 ++- drivers/i2c/busses/i2c-imx.c | 24 +- drivers/idle/intel_idle.c | 9 +- drivers/iio/adc/ad7292.c | 4 +- drivers/iio/adc/at91-sama5d2_adc.c | 16 +- drivers/iio/adc/rcar-gyroadc.c | 21 +- drivers/iio/adc/ti-adc0832.c | 11 +- drivers/iio/adc/ti-adc12138.c | 13 +- drivers/iio/gyro/itg3200_buffer.c | 15 +- drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 12 +- drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 12 +- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 6 + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 42 +- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c | 2 + drivers/iio/light/si1145.c | 19 +- drivers/iio/temperature/ltc2983.c | 19 +- drivers/infiniband/core/rdma_core.c | 30 +- drivers/infiniband/hw/mlx5/main.c | 6 +- drivers/infiniband/hw/qedr/qedr_iw_cm.c | 1 + drivers/input/serio/hil_mlc.c | 21 +- drivers/input/serio/hp_sdc_mlc.c | 8 +- drivers/interconnect/qcom/sdm845.c | 2 +- drivers/irqchip/irq-loongson-htvec.c | 4 +- drivers/leds/leds-bcm6328.c | 2 +- drivers/leds/leds-bcm6358.c | 2 +- drivers/md/md-bitmap.c | 2 +- drivers/md/md.c | 2 +- drivers/md/raid5.c | 4 +- drivers/media/i2c/imx274.c | 8 +- drivers/media/pci/tw5864/tw5864-video.c | 6 + drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c | 7 + drivers/media/usb/uvc/uvc_ctrl.c | 27 +- drivers/memory/brcmstb_dpfe.c | 16 +- drivers/memory/emif.c | 33 +- drivers/memory/tegra/tegra124.c | 1 - drivers/message/fusion/mptscsih.c | 13 +- drivers/misc/fastrpc.c | 4 +- drivers/misc/habanalabs/gaudi/gaudi_security.c | 55 +-- drivers/mmc/host/sdhci-acpi.c | 37 ++ drivers/mmc/host/sdhci-esdhc.h | 2 + drivers/mmc/host/sdhci-of-esdhc.c | 28 ++ drivers/mmc/host/sdhci-pci-core.c | 154 ++++++++ drivers/mmc/host/sdhci.c | 6 +- drivers/mmc/host/via-sdmmc.c | 3 + drivers/mtd/ubi/wl.c | 13 + drivers/net/can/flexcan.c | 30 +- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 6 +- drivers/net/ethernet/marvell/octeontx2/af/npc.h | 4 +- drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h | 5 - drivers/net/ethernet/mellanox/mlxsw/core.c | 3 + drivers/net/ethernet/pensando/ionic/ionic_lif.c | 1 - drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 13 - drivers/net/ethernet/pensando/ionic/ionic_txrx.h | 1 - drivers/net/wan/hdlc_fr.c | 98 ++--- drivers/net/wireless/ath/ath10k/htt_rx.c | 16 +- drivers/net/wireless/ath/ath10k/mac.c | 5 +- drivers/net/wireless/ath/ath10k/sdio.c | 4 + drivers/net/wireless/ath/ath11k/dp_rx.c | 2 +- drivers/net/wireless/ath/ath11k/dp_tx.c | 4 + drivers/net/wireless/ath/ath11k/reg.c | 6 +- .../wireless/broadcom/brcm80211/brcmfmac/fweh.c | 10 +- .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 1 + drivers/net/xen-netback/common.h | 15 + drivers/net/xen-netback/interface.c | 61 ++- drivers/net/xen-netback/netback.c | 11 +- drivers/net/xen-netback/rx.c | 13 +- drivers/nfc/s3fwrn5/Kconfig | 1 + drivers/nvme/host/rdma.c | 1 - drivers/pci/controller/dwc/pcie-qcom.c | 13 + drivers/pci/ecam.c | 10 + drivers/pci/pci-acpi.c | 10 + drivers/power/supply/bq27xxx_battery.c | 6 +- drivers/power/supply/test_power.c | 6 + drivers/remoteproc/remoteproc_debugfs.c | 2 +- drivers/rpmsg/qcom_glink_native.c | 6 +- drivers/rtc/rtc-rx8010.c | 24 +- drivers/s390/crypto/ap_bus.h | 1 + drivers/s390/crypto/ap_queue.c | 8 +- drivers/s390/crypto/zcrypt_debug.h | 8 + drivers/s390/crypto/zcrypt_error.h | 88 ++--- drivers/s390/crypto/zcrypt_msgtype50.c | 50 +-- drivers/s390/crypto/zcrypt_msgtype6.c | 92 ++--- drivers/scsi/qla2xxx/qla_attr.c | 10 +- drivers/scsi/qla2xxx/qla_gbl.h | 1 - drivers/scsi/qla2xxx/qla_init.c | 2 + drivers/scsi/qla2xxx/qla_isr.c | 2 +- drivers/scsi/qla2xxx/qla_target.c | 13 +- drivers/scsi/qla2xxx/qla_tmpl.c | 49 +-- drivers/scsi/scsi_lib.c | 22 +- drivers/scsi/sd.c | 27 +- drivers/scsi/sr.c | 16 +- drivers/soc/qcom/rpmh-internal.h | 4 + drivers/soc/qcom/rpmh-rsc.c | 115 +++--- drivers/soc/ti/k3-ringacc.c | 33 +- drivers/spi/spi-mtk-nor.c | 6 +- drivers/spi/spi-sprd.c | 2 +- drivers/staging/comedi/drivers/cb_pcidas.c | 1 + drivers/staging/fieldbus/anybuss/arcx-anybus.c | 2 +- drivers/staging/octeon/ethernet-mdio.c | 6 - drivers/staging/octeon/ethernet-rx.c | 34 +- drivers/staging/octeon/ethernet.c | 9 + drivers/staging/wfx/sta.c | 28 +- drivers/tee/tee_core.c | 3 +- drivers/tty/serial/21285.c | 12 +- drivers/tty/serial/fsl_lpuart.c | 13 +- drivers/tty/vt/keyboard.c | 39 +- drivers/tty/vt/vt_ioctl.c | 47 +-- drivers/uio/uio.c | 4 +- drivers/usb/cdns3/ep0.c | 65 ++-- drivers/usb/cdns3/gadget.c | 102 ++--- drivers/usb/cdns3/gadget.h | 3 +- drivers/usb/class/cdc-acm.c | 12 +- drivers/usb/class/cdc-acm.h | 3 +- drivers/usb/core/driver.c | 30 +- drivers/usb/core/generic.c | 4 +- drivers/usb/core/usb.h | 2 + drivers/usb/dwc3/core.c | 21 +- drivers/usb/dwc3/core.h | 1 + drivers/usb/dwc3/dwc3-pci.c | 3 +- drivers/usb/dwc3/ep0.c | 27 +- drivers/usb/dwc3/gadget.c | 70 +++- drivers/usb/dwc3/gadget.h | 1 + drivers/usb/host/ehci-tegra.c | 4 +- drivers/usb/host/fsl-mph-dr-of.c | 9 +- drivers/usb/host/xhci-pci.c | 17 + drivers/usb/host/xhci.c | 7 +- drivers/usb/host/xhci.h | 1 + drivers/usb/misc/adutux.c | 1 + drivers/usb/misc/apple-mfi-fastcharge.c | 17 +- drivers/usb/typec/tcpm/tcpm.c | 8 +- drivers/vdpa/mlx5/core/mr.c | 5 +- drivers/vdpa/vdpa_sim/vdpa_sim.c | 7 +- drivers/vhost/vdpa.c | 129 +++---- drivers/vhost/vringh.c | 9 +- drivers/video/fbdev/pvr2fb.c | 2 + drivers/w1/masters/mxc_w1.c | 14 +- drivers/watchdog/rdc321x_wdt.c | 5 +- drivers/xen/events/events_2l.c | 9 +- drivers/xen/events/events_base.c | 423 +++++++++++++++++++-- drivers/xen/events/events_fifo.c | 83 ++-- drivers/xen/events/events_internal.h | 20 +- drivers/xen/evtchn.c | 7 +- drivers/xen/gntdev-dmabuf.c | 13 +- drivers/xen/pvcalls-back.c | 76 ++-- drivers/xen/xen-pciback/pci_stub.c | 13 +- drivers/xen/xen-pciback/pciback.h | 12 +- drivers/xen/xen-pciback/pciback_ops.c | 48 ++- drivers/xen/xen-pciback/xenbus.c | 2 +- drivers/xen/xen-scsiback.c | 23 +- fs/9p/vfs_file.c | 4 +- fs/afs/dir.c | 12 +- fs/afs/dir_edit.c | 6 +- fs/afs/file.c | 77 +++- fs/afs/internal.h | 57 +++ fs/afs/server.c | 7 +- fs/afs/write.c | 105 ++--- fs/afs/xattr.c | 2 +- fs/btrfs/block-group.c | 1 + fs/btrfs/ctree.c | 6 + fs/btrfs/ctree.h | 4 +- fs/btrfs/delayed-inode.c | 3 +- fs/btrfs/dev-replace.c | 7 +- fs/btrfs/disk-io.c | 8 +- fs/btrfs/extent-tree.c | 7 +- fs/btrfs/inode.c | 2 +- fs/btrfs/ioctl.c | 6 +- fs/btrfs/reada.c | 47 +++ fs/btrfs/reflink.c | 2 + fs/btrfs/root-tree.c | 13 +- fs/btrfs/send.c | 201 ++++++++-- fs/btrfs/tree-checker.c | 35 +- fs/btrfs/tree-log.c | 8 + fs/btrfs/volumes.c | 42 +- fs/btrfs/volumes.h | 1 + fs/buffer.c | 16 - fs/cachefiles/rdwr.c | 3 +- fs/ceph/addr.c | 2 +- fs/ceph/mds_client.c | 89 +++-- fs/cifs/cifsglob.h | 2 + fs/cifs/connect.c | 15 +- fs/cifs/inode.c | 13 +- fs/cifs/smb2maperror.c | 2 +- fs/cifs/smb2ops.c | 15 + fs/exec.c | 24 +- fs/ext4/balloc.c | 1 + fs/ext4/extents.c | 33 +- fs/ext4/ialloc.c | 1 + fs/ext4/inode.c | 29 +- fs/ext4/resize.c | 4 +- fs/ext4/super.c | 31 +- fs/f2fs/checkpoint.c | 10 +- fs/f2fs/compress.c | 7 +- fs/f2fs/dir.c | 8 +- fs/f2fs/f2fs.h | 4 +- fs/f2fs/file.c | 2 + fs/f2fs/inode.c | 3 + fs/f2fs/node.c | 2 +- fs/f2fs/segment.c | 12 +- fs/f2fs/super.c | 6 + fs/gfs2/glock.c | 18 +- fs/gfs2/glops.c | 11 +- fs/gfs2/incore.h | 1 + fs/gfs2/log.c | 61 +-- fs/gfs2/ops_fstype.c | 40 +- fs/gfs2/rgrp.c | 9 +- fs/gfs2/rgrp.h | 2 +- fs/gfs2/super.c | 3 + fs/gfs2/sys.c | 5 +- fs/gfs2/util.c | 2 +- fs/gfs2/util.h | 10 + fs/io-wq.c | 1 + fs/io_uring.c | 8 +- fs/jbd2/recovery.c | 78 +++- fs/nfs/namespace.c | 12 +- fs/nfs/nfs4_fs.h | 8 + fs/nfs/nfs4file.c | 3 +- fs/nfs/nfs4proc.c | 90 +++-- fs/nfs/nfs4trace.h | 1 + fs/nfsd/nfs4state.c | 5 +- fs/nfsd/nfsproc.c | 16 + fs/nfsd/trace.h | 4 +- fs/ubifs/debug.c | 1 + fs/ubifs/journal.c | 6 +- fs/ubifs/orphan.c | 2 + fs/ubifs/super.c | 44 ++- fs/ubifs/tnc.c | 3 + fs/ubifs/xattr.c | 2 + fs/udf/super.c | 21 +- fs/xfs/libxfs/xfs_bmap.c | 19 +- fs/xfs/libxfs/xfs_defer.c | 37 +- fs/xfs/libxfs/xfs_defer.h | 6 + fs/xfs/xfs_bmap_item.c | 2 +- fs/xfs/xfs_log_recover.c | 39 +- fs/xfs/xfs_refcount_item.c | 2 +- fs/xfs/xfs_rtalloc.c | 19 +- include/asm-generic/vmlinux.lds.h | 5 +- include/drm/gpu_scheduler.h | 12 +- include/linux/arm-smccc.h | 2 + include/linux/cpufreq.h | 11 +- include/linux/fs.h | 1 - include/linux/hil_mlc.h | 2 +- include/linux/mlx5/driver.h | 18 + include/linux/pci-ecam.h | 1 + include/linux/rcupdate_trace.h | 4 + include/linux/time64.h | 4 + include/linux/usb/pd.h | 1 + include/rdma/ib_verbs.h | 5 - include/scsi/scsi_cmnd.h | 3 +- include/trace/events/afs.h | 22 +- include/trace/events/btrfs.h | 10 +- include/uapi/linux/btrfs_tree.h | 14 + include/uapi/linux/nfs4.h | 3 + include/uapi/linux/videodev2.h | 17 +- include/xen/events.h | 21 + init/Kconfig | 3 +- kernel/bpf/verifier.c | 4 + kernel/debug/debug_core.c | 22 +- kernel/futex.c | 9 +- kernel/locking/lockdep.c | 4 +- kernel/module.c | 2 +- kernel/rcu/tasks.h | 16 +- kernel/rcu/tree.c | 2 +- kernel/sched/cpufreq_schedutil.c | 6 +- kernel/seccomp.c | 38 +- kernel/stop_machine.c | 2 +- kernel/time/itimer.c | 4 - kernel/time/sched_clock.c | 4 +- kernel/trace/ring_buffer.c | 18 +- kernel/trace/trace_events_synth.c | 23 +- lib/scatterlist.c | 2 +- mm/slab.c | 2 +- mm/slab.h | 42 +- mm/slub.c | 3 +- net/9p/trans_fd.c | 2 +- net/ceph/messenger.c | 5 + net/mac80211/tx.c | 6 + net/sunrpc/sysctl.c | 8 +- net/sunrpc/xprt.c | 6 +- samples/bpf/xdpsock_user.c | 1 + security/integrity/digsig.c | 2 +- security/integrity/ima/ima_fs.c | 2 +- security/integrity/ima/ima_main.c | 6 +- security/selinux/include/security.h | 14 +- security/selinux/ss/services.c | 3 +- sound/soc/amd/acp3x-rt5682-max9836.c | 11 +- sound/soc/sof/intel/hda-codec.c | 4 +- tools/perf/pmu-events/arch/x86/amdzen1/cache.json | 18 + tools/perf/util/print_binary.c | 2 +- .../testing/selftests/bpf/progs/test_sysctl_prog.c | 4 +- tools/testing/selftests/powerpc/utils.c | 4 +- tools/testing/selftests/x86/fsgsbase.c | 68 ++++ 460 files changed, 5209 insertions(+), 2493 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/391 xen/events: avoid removing an event channel while handling it
From: Juergen Gross <[email protected]>
commit 073d0552ead5bfc7a3a9c01de590e924f11b5dd2 upstream.
Today it can happen that an event channel is being removed from the system while the event handling loop is active. This can lead to a race resulting in crashes or WARN() splats when trying to access the irq_info structure related to the event channel.
Fix this problem by using a rwlock taken as reader in the event handling loop and as writer when deallocating the irq_info structure.
As the observed problem was a NULL dereference in evtchn_from_irq() make this function more robust against races by testing the irq_info pointer to be not NULL before dereferencing it.
And finally make all accesses to evtchn_to_irq[row][col] atomic ones in order to avoid seeing partial updates of an array element in irq handling. Note that irq handling can be entered only for event channels which have been valid before, so any not populated row isn't a problem in this regard, as rows are only ever added and never removed.
This is XSA-331.
--- drivers/xen/events/events_base.c | 41 ++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-)
drivers/xen/events/events_base.c +36 -5
@@ -33,6 +33,7 @@#include <linux/slab.h> #include <linux/irqnr.h> #include <linux/pci.h> +#include <linux/spinlock.h> #ifdef CONFIG_X86 #include <asm/desc.h>
@@ -71,6 +72,23 @@ const struct evtchn_ops *evtchn_ops;*/ static DEFINE_MUTEX (irq_mapping_update_lock); +/* +* Lock protecting event handling loop against removing event channels. +* Adding of event channels is no issue as the associated IRQ becomes active +* only after everything is setup (before request_[threaded_]irq() the handler +* can't be entered for an event, as the event channel will be unmasked only +* then). +*/ +static DEFINE_RWLOCK (evtchn_rwlock); + +/* +* Lock hierarchy: +* +* irq_mapping_update_lock +* evtchn_rwlock +* IRQ-desc lock +*/ +static LIST_HEAD (xen_irq_list_head);/* IRQ <-> VIRQ mapping. */
@@ -105,7 +123,7 @@ static void clear_evtchn_to_irq_row(unsiunsigned col;for (col =0 ; col <EVTCHN_PER_ROW ; col++) - evtchn_to_irq[row][col] =-1 ; +WRITE_ONCE (evtchn_to_irq[row][col],-1 ); }static void clear_evtchn_to_irq_all (void )
@@ -142,7 +160,7 @@ static int set_evtchn_to_irq(evtchn_portclear_evtchn_to_irq_row (row); } - evtchn_to_irq[row][col] = irq; +WRITE_ONCE (evtchn_to_irq[row][col], irq);return 0 ; }
@@ -152,7 +170,7 @@ int get_evtchn_to_irq(evtchn_port_t evtcreturn -1 ;if (evtchn_to_irq[EVTCHN_ROW (evtchn)] ==NULL )return -1 ; -return evtchn_to_irq[EVTCHN_ROW (evtchn)][EVTCHN_COL (evtchn)]; +return READ_ONCE (evtchn_to_irq[EVTCHN_ROW (evtchn)][EVTCHN_COL (evtchn)]); }/* Get info for IRQ */
@@ -261,10 +279,14 @@ static void xen_irq_info_cleanup(struct*/ evtchn_port_t evtchn_from_irq (unsigned irq) { -if (WARN (irq >= nr_irqs,"Invalid irq %d!\n" , irq)) +const struct irq_info *info =NULL ; + +if (likely (irq < nr_irqs)) + info =info_for_irq (irq); +if (!info)return 0 ; -return info_for_irq (irq)->evtchn; +return info->evtchn; }unsigned int irq_from_evtchn (evtchn_port_t evtchn)
@@ -440,16 +462,21 @@ static int __must_check xen_allocate_irqstatic void xen_free_irq (unsigned irq) {struct irq_info *info =info_for_irq (irq); +unsigned long flags;if (WARN_ON (!info))return ; +write_lock_irqsave (&evtchn_rwlock, flags); +list_del (&info->list);set_info_for_irq (irq,NULL );WARN_ON (info->refcnt >0 ); +write_unlock_irqrestore (&evtchn_rwlock, flags); +kfree (info);/* Legacy IRQ descriptors are managed by the arch. */
@@ -1233,6 +1260,8 @@ static void __xen_evtchn_do_upcall(void)struct vcpu_info *vcpu_info =__this_cpu_read (xen_vcpu);int cpu =smp_processor_id (); +read_lock (&evtchn_rwlock); + do { vcpu_info->evtchn_upcall_pending = 0;
@@ -1243,6 +1272,8 @@ static void __xen_evtchn_do_upcall(void)virt_rmb ();/* Hypervisor can set upcall pending. */ }while (vcpu_info->evtchn_upcall_pending); + +read_unlock (&evtchn_rwlock); }void xen_evtchn_do_upcall (struct pt_regs *regs)
Greg Kroah-Hartman
maintainerPATCH 2/391 xen/events: add a proper barrier to 2-level uevent unmasking
In reply to Greg Kroah-HartmanFrom: Juergen Gross <[email protected]>
commit 4d3fe31bd993ef504350989786858aefdb877daa upstream.
A follow-up patch will require certain write to happen before an event channel is unmasked.
While the memory barrier is not strictly necessary for all the callers, the main one will need it. In order to avoid an extra memory barrier when using fifo event channels, mandate evtchn_unmask() to provide write ordering.
The 2-level event handling unmask operation is missing an appropriate barrier, so add it. Fifo event channels are fine in this regard due to using sync_cmpxchg().
This is part of XSA-332.
--- drivers/xen/events/events_2l.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/xen/events/events_2l.c +2 -0
@@ -91,6 +91,8 @@ static void evtchn_2l_unmask(evtchn_portBUG_ON (!irqs_disabled ()); +smp_wmb ();/* All writes before unmask must be visible. */ +if (unlikely ((cpu !=cpu_from_evtchn (port)))) do_hypercall =1 ;else {
Greg Kroah-Hartman
maintainerPATCH 3/391 xen/events: fix race in evtchn_fifo_unmask()
In reply to Greg Kroah-HartmanFrom: Juergen Gross <[email protected]>
commit f01337197419b7e8a492e83089552b77d3b5fb90 upstream.
Unmasking a fifo event channel can result in unmasking it twice, once directly in the kernel and once via a hypercall in case the event was pending.
Fix that by doing the local unmask only if the event is not pending.
This is part of XSA-332.
--- drivers/xen/events/events_fifo.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/xen/events/events_fifo.c +9 -4
@@ -227,19 +227,25 @@ static bool evtchn_fifo_is_masked(evtchnreturn sync_test_bit (EVTCHN_FIFO_BIT (MASKED , word),BM (word)); }/* -* Clear MASKED, spinning if BUSY is set. +* Clear MASKED if not PENDING, spinning if BUSY is set. +* Return true if mask was cleared. */ -static void clear_masked (volatile event_word_t *word) +static bool clear_masked_cond (volatile event_word_t *word) {event_word_t new, old, w; w = *word;do { +if (w & (1 <<EVTCHN_FIFO_PENDING )) +return false; + old = w & ~(1 <<EVTCHN_FIFO_BUSY ); new = old & ~(1 <<EVTCHN_FIFO_MASKED ); w =sync_cmpxchg (word, old, new); }while (w != old); + +return true; }static void evtchn_fifo_unmask (evtchn_port_t port)
@@ -248,8 +254,7 @@ static void evtchn_fifo_unmask(evtchn_poBUG_ON (!irqs_disabled ()); -clear_masked (word); -if (evtchn_fifo_is_pending (port)) { +if (!clear_masked_cond (word)) {struct evtchn_unmask unmask = { .port = port }; (void )HYPERVISOR_event_channel_op (EVTCHNOP_unmask, &unmask); }
Greg Kroah-Hartman
maintainerPATCH 4/391 xen/events: add a new "late EOI" evtchn framework
In reply to Greg Kroah-HartmanFrom: Juergen Gross <[email protected]>
commit 54c9de89895e0a36047fcc4ae754ea5b8655fb9d upstream.
In order to avoid tight event channel related IRQ loops add a new framework of "late EOI" handling: the IRQ the event channel is bound to will be masked until the event has been handled and the related driver is capable to handle another event. The driver is responsible for unmasking the event channel via the new function xen_irq_lateeoi().
This is similar to binding an event channel to a threaded IRQ, but without having to structure the driver accordingly.
In order to support a future special handling in case a rogue guest is sending lots of unsolicited events, add a flag to xen_irq_lateeoi() which can be set by the caller to indicate the event was a spurious one.
This is part of XSA-332.
--- drivers/xen/events/events_base.c | 151 ++++++++++++++++++++++++++++++++++----- include/xen/events.h | 21 +++++ 2 files changed, 155 insertions(+), 17 deletions(-)
drivers/xen/events/events_base.c +134 -17
@@ -113,6 +113,7 @@ static bool (*pirq_needs_eoi)(unsigned istatic struct irq_info *legacy_info_ptrs[NR_IRQS_LEGACY ];static struct irq_chip xen_dynamic_chip; +static struct irq_chip xen_lateeoi_chip;static struct irq_chip xen_percpu_chip;static struct irq_chip xen_pirq_chip;static void enable_dynirq (struct irq_data *data);
@@ -397,6 +398,33 @@ void notify_remote_via_irq(int irq) }EXPORT_SYMBOL_GPL (notify_remote_via_irq); +static void xen_irq_lateeoi_locked (struct irq_info *info) +{ +evtchn_port_t evtchn; + + evtchn = info->evtchn; +if (!VALID_EVTCHN (evtchn)) +return ; + +unmask_evtchn (evtchn); +} + +void xen_irq_lateeoi (unsigned int irq,unsigned int eoi_flags) +{ +struct irq_info *info; +unsigned long flags; + +read_lock_irqsave (&evtchn_rwlock, flags); + + info =info_for_irq (irq); + +if (info) +xen_irq_lateeoi_locked (info); + +read_unlock_irqrestore (&evtchn_rwlock, flags); +} +EXPORT_SYMBOL_GPL (xen_irq_lateeoi); +static void xen_irq_init (unsigned irq) {struct irq_info *info;
@@ -868,7 +896,7 @@ int xen_pirq_from_irq(unsigned irq) }EXPORT_SYMBOL_GPL (xen_pirq_from_irq); -int bind_evtchn_to_irq (evtchn_port_t evtchn) +static int bind_evtchn_to_irq_chip (evtchn_port_t evtchn,struct irq_chip *chip) {int irq;int ret;
@@ -885,7 +913,7 @@ int bind_evtchn_to_irq(evtchn_port_t evtif (irq <0 ) goto out; -irq_set_chip_and_handler_name (irq, &xen_dynamic_chip, +irq_set_chip_and_handler_name (irq, chip, handle_edge_irq,"event" ); ret =xen_irq_info_evtchn_setup (irq, evtchn);
@@ -906,8 +934,19 @@ out:return irq; } + +int bind_evtchn_to_irq (evtchn_port_t evtchn) +{ +return bind_evtchn_to_irq_chip (evtchn, &xen_dynamic_chip); +}EXPORT_SYMBOL_GPL (bind_evtchn_to_irq); +int bind_evtchn_to_irq_lateeoi (evtchn_port_t evtchn) +{ +return bind_evtchn_to_irq_chip (evtchn, &xen_lateeoi_chip); +} +EXPORT_SYMBOL_GPL (bind_evtchn_to_irq_lateeoi); +static int bind_ipi_to_irq (unsigned int ipi,unsigned int cpu) {struct evtchn_bind_ipi bind_ipi;
@@ -949,8 +988,9 @@ static int bind_ipi_to_irq(unsigned intreturn irq; } -int bind_interdomain_evtchn_to_irq (unsigned int remote_domain, -evtchn_port_t remote_port) +static int bind_interdomain_evtchn_to_irq_chip (unsigned int remote_domain, +evtchn_port_t remote_port, +struct irq_chip *chip) {struct evtchn_bind_interdomain bind_interdomain;int err;
@@ -961,10 +1001,26 @@ int bind_interdomain_evtchn_to_irq(unsig err =HYPERVISOR_event_channel_op (EVTCHNOP_bind_interdomain, &bind_interdomain); -return err ? :bind_evtchn_to_irq (bind_interdomain.local_port); +return err ? :bind_evtchn_to_irq_chip (bind_interdomain.local_port, + chip); +} + +int bind_interdomain_evtchn_to_irq (unsigned int remote_domain, +evtchn_port_t remote_port) +{ +return bind_interdomain_evtchn_to_irq_chip (remote_domain, remote_port, + &xen_dynamic_chip); }EXPORT_SYMBOL_GPL (bind_interdomain_evtchn_to_irq); +int bind_interdomain_evtchn_to_irq_lateeoi (unsigned int remote_domain, +evtchn_port_t remote_port) +{ +return bind_interdomain_evtchn_to_irq_chip (remote_domain, remote_port, + &xen_lateeoi_chip); +} +EXPORT_SYMBOL_GPL (bind_interdomain_evtchn_to_irq_lateeoi); +static int find_virq (unsigned int virq,unsigned int cpu,evtchn_port_t *evtchn) {struct evtchn_status status;
@@ -1061,14 +1117,15 @@ static void unbind_from_irq(unsigned intmutex_unlock (&irq_mapping_update_lock); } -int bind_evtchn_to_irqhandler (evtchn_port_t evtchn, -irq_handler_t handler, -unsigned long irqflags, -const char *devname,void *dev_id) +static int bind_evtchn_to_irqhandler_chip (evtchn_port_t evtchn, +irq_handler_t handler, +unsigned long irqflags, +const char *devname,void *dev_id, +struct irq_chip *chip) {int irq, retval; - irq =bind_evtchn_to_irq (evtchn); + irq =bind_evtchn_to_irq_chip (evtchn, chip);if (irq <0 )return irq; retval =request_irq (irq, handler, irqflags, devname, dev_id);
@@ -1079,18 +1136,38 @@ int bind_evtchn_to_irqhandler(evtchn_porreturn irq; } + +int bind_evtchn_to_irqhandler (evtchn_port_t evtchn, +irq_handler_t handler, +unsigned long irqflags, +const char *devname,void *dev_id) +{ +return bind_evtchn_to_irqhandler_chip (evtchn, handler, irqflags, + devname, dev_id, + &xen_dynamic_chip); +}EXPORT_SYMBOL_GPL (bind_evtchn_to_irqhandler); -int bind_interdomain_evtchn_to_irqhandler (unsigned int remote_domain, -evtchn_port_t remote_port, -irq_handler_t handler, -unsigned long irqflags, -const char *devname, -void *dev_id) +int bind_evtchn_to_irqhandler_lateeoi (evtchn_port_t evtchn, +irq_handler_t handler, +unsigned long irqflags, +const char *devname,void *dev_id) +{ +return bind_evtchn_to_irqhandler_chip (evtchn, handler, irqflags, + devname, dev_id, + &xen_lateeoi_chip); +} +EXPORT_SYMBOL_GPL (bind_evtchn_to_irqhandler_lateeoi); + +static int bind_interdomain_evtchn_to_irqhandler_chip ( +unsigned int remote_domain,evtchn_port_t remote_port, +irq_handler_t handler,unsigned long irqflags, +const char *devname,void *dev_id,struct irq_chip *chip) {int irq, retval; - irq =bind_interdomain_evtchn_to_irq (remote_domain, remote_port); + irq =bind_interdomain_evtchn_to_irq_chip (remote_domain, remote_port, + chip);if (irq <0 )return irq;
@@ -1102,8 +1179,33 @@ int bind_interdomain_evtchn_to_irqhandlereturn irq; } + +int bind_interdomain_evtchn_to_irqhandler (unsigned int remote_domain, +evtchn_port_t remote_port, +irq_handler_t handler, +unsigned long irqflags, +const char *devname, +void *dev_id) +{ +return bind_interdomain_evtchn_to_irqhandler_chip (remote_domain, + remote_port, handler, irqflags, devname, + dev_id, &xen_dynamic_chip); +}EXPORT_SYMBOL_GPL (bind_interdomain_evtchn_to_irqhandler); +int bind_interdomain_evtchn_to_irqhandler_lateeoi (unsigned int remote_domain, +evtchn_port_t remote_port, +irq_handler_t handler, +unsigned long irqflags, +const char *devname, +void *dev_id) +{ +return bind_interdomain_evtchn_to_irqhandler_chip (remote_domain, + remote_port, handler, irqflags, devname, + dev_id, &xen_lateeoi_chip); +} +EXPORT_SYMBOL_GPL (bind_interdomain_evtchn_to_irqhandler_lateeoi); +int bind_virq_to_irqhandler (unsigned int virq,unsigned int cpu,irq_handler_t handler,unsigned long irqflags,const char *devname,void *dev_id)
@@ -1634,6 +1736,21 @@ static struct irq_chip xen_dynamic_chip .irq_mask_ack = mask_ack_dynirq, .irq_set_affinity = set_affinity_irq, + .irq_retrigger = retrigger_dynirq, +}; + +static struct irq_chip xen_lateeoi_chip__read_mostly = { +/* The chip name needs to contain "xen-dyn" for irqbalance to work. */ + .name ="xen-dyn-lateeoi" , + + .irq_disable = disable_dynirq, + .irq_mask = disable_dynirq, + .irq_unmask = enable_dynirq, + + .irq_ack = mask_ack_dynirq, + .irq_mask_ack = mask_ack_dynirq, + + .irq_set_affinity = set_affinity_irq, .irq_retrigger = retrigger_dynirq, };
include/xen/events.h +21 -0
@@ -15,10 +15,15 @@unsigned xen_evtchn_nr_channels (void );int bind_evtchn_to_irq (evtchn_port_t evtchn); +int bind_evtchn_to_irq_lateeoi (evtchn_port_t evtchn);int bind_evtchn_to_irqhandler (evtchn_port_t evtchn,irq_handler_t handler,unsigned long irqflags,const char *devname,void *dev_id); +int bind_evtchn_to_irqhandler_lateeoi (evtchn_port_t evtchn, +irq_handler_t handler, +unsigned long irqflags,const char *devname, +void *dev_id);int bind_virq_to_irq (unsigned int virq,unsigned int cpu,bool percpu); int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu, irq_handler_t handler,
@@ -32,12 +37,20 @@ int bind_ipi_to_irqhandler(enum ipi_vect void *dev_id);int bind_interdomain_evtchn_to_irq (unsigned int remote_domain,evtchn_port_t remote_port); +int bind_interdomain_evtchn_to_irq_lateeoi (unsigned int remote_domain, +evtchn_port_t remote_port);int bind_interdomain_evtchn_to_irqhandler (unsigned int remote_domain,evtchn_port_t remote_port,irq_handler_t handler,unsigned long irqflags,const char *devname,void *dev_id); +int bind_interdomain_evtchn_to_irqhandler_lateeoi (unsigned int remote_domain, +evtchn_port_t remote_port, +irq_handler_t handler, +unsigned long irqflags, +const char *devname, +void *dev_id);/* * Common unbind function for all event sources. Takes IRQ to unbind from.
@@ -46,6 +59,14 @@ int bind_interdomain_evtchn_to_irqhandle*/ void unbind_from_irqhandler (unsigned int irq,void *dev_id); +/* +* Send late EOI for an IRQ bound to an event channel via one of the *_lateeoi +* functions above. +*/ +void xen_irq_lateeoi (unsigned int irq,unsigned int eoi_flags); +/* Signal an event was spurious, i.e. there was no action resulting from it. */ +#define XEN_EOI_FLAG_SPURIOUS 0x00000001 +#define XEN_IRQ_PRIORITY_MAX EVTCHN_FIFO_PRIORITY_MAX#define XEN_IRQ_PRIORITY_DEFAULT EVTCHN_FIFO_PRIORITY_DEFAULT#define XEN_IRQ_PRIORITY_MIN EVTCHN_FIFO_PRIORITY_MIN
Greg Kroah-Hartman
maintainerPATCH 5/391 xen/blkback: use lateeoi irq binding
In reply to Greg Kroah-HartmanFrom: Juergen Gross <[email protected]>
commit 01263a1fabe30b4d542f34c7e2364a22587ddaf2 upstream.
In order to reduce the chance for the system becoming unresponsive due to event storms triggered by a misbehaving blkfront use the lateeoi irq binding for blkback and unmask the event channel only after processing all pending requests.
As the thread processing requests is used to do purging work in regular intervals an EOI may be sent only after having received an event. If there was no pending I/O request flag the EOI as spurious.
This is part of XSA-332.
--- drivers/block/xen-blkback/blkback.c | 22 +++++++++++++++++----- drivers/block/xen-blkback/xenbus.c | 5 ++--- 2 files changed, 19 insertions(+), 8 deletions(-)
drivers/block/xen-blkback/blkback.c +17 -5
@@ -201,7 +201,7 @@ static inline void shrink_free_pagepool(#define vaddr (page) ((unsigned long)pfn_to_kaddr(page_to_pfn(page))) -static int do_block_io_op (struct xen_blkif_ring *ring); +static int do_block_io_op (struct xen_blkif_ring *ring,unsigned int *eoi_flags);static int dispatch_rw_block_io (struct xen_blkif_ring *ring,struct blkif_request *req,struct pending_req *pending_req);
@@ -612,6 +612,8 @@ int xen_blkif_schedule(void *arg)struct xen_vbd *vbd = &blkif->vbd;unsigned long timeout;int ret; +bool do_eoi; +unsigned int eoi_flags =XEN_EOI_FLAG_SPURIOUS ;set_freezable ();while (!kthread_should_stop ()) {
@@ -636,16 +638,23 @@ int xen_blkif_schedule(void *arg)if (timeout ==0 ) goto purge_gnt_list; + do_eoi = ring->waiting_reqs; + ring->waiting_reqs =0 ;smp_mb ();/* clear flag *before* checking for work */ - ret =do_block_io_op (ring); + ret =do_block_io_op (ring, &eoi_flags);if (ret >0 ) ring->waiting_reqs =1 ;if (ret == -EACCES )wait_event_interruptible (ring->shutdown_wq,kthread_should_stop ()); +if (do_eoi && !ring->waiting_reqs) { +xen_irq_lateeoi (ring->irq, eoi_flags); + eoi_flags |=XEN_EOI_FLAG_SPURIOUS ; + } + purge_gnt_list:if (blkif->vbd.feature_gnt_persistent &&time_after (jiffies, ring->next_lru)) {
@@ -1121,7 +1130,7 @@ static void end_block_io_op(struct bio ** and transmute it to the block API to hand it over to the proper block disk. */ static int -__do_block_io_op (struct xen_blkif_ring *ring) +__do_block_io_op (struct xen_blkif_ring *ring,unsigned int *eoi_flags) {union blkif_back_rings *blk_rings = &ring->blk_rings;struct blkif_request req;
@@ -1144,6 +1153,9 @@ __do_block_io_op(struct xen_blkif_ring *if (RING_REQUEST_CONS_OVERFLOW (&blk_rings->common, rc))break ; +/* We've seen a request, so clear spurious eoi flag. */ + *eoi_flags &= ~XEN_EOI_FLAG_SPURIOUS ; +if (kthread_should_stop ()) { more_to_do =1 ;break ;
@@ -1202,13 +1214,13 @@ done: }static int -do_block_io_op (struct xen_blkif_ring *ring) +do_block_io_op (struct xen_blkif_ring *ring,unsigned int *eoi_flags) {union blkif_back_rings *blk_rings = &ring->blk_rings;int more_to_do; do { - more_to_do = __do_block_io_op(ring); + more_to_do = __do_block_io_op(ring, eoi_flags); if (more_to_do) break;
drivers/block/xen-blkback/xenbus.c +2 -3
@@ -246,9 +246,8 @@ static int xen_blkif_map(struct xen_blkiif (req_prod - rsp_prod > size) goto fail; - err =bind_interdomain_evtchn_to_irqhandler (blkif->domid, evtchn, - xen_blkif_be_int,0 , -"blkif-backend" , ring); + err =bind_interdomain_evtchn_to_irqhandler_lateeoi (blkif->domid, + evtchn, xen_blkif_be_int,0 ,"blkif-backend" , ring);if (err <0 ) goto fail; ring->irq = err;
Greg Kroah-Hartman
maintainerPATCH 6/391 xen/netback: use lateeoi irq binding
In reply to Greg Kroah-HartmanFrom: Juergen Gross <[email protected]>
commit 23025393dbeb3b8b3b60ebfa724cdae384992e27 upstream.
In order to reduce the chance for the system becoming unresponsive due to event storms triggered by a misbehaving netfront use the lateeoi irq binding for netback and unmask the event channel only just before going to sleep waiting for new events.
Make sure not to issue an EOI when none is pending by introducing an eoi_pending element to struct xenvif_queue.
When no request has been consumed set the spurious flag when sending the EOI for an interrupt.
This is part of XSA-332.
--- drivers/net/xen-netback/common.h | 15 ++++++++ drivers/net/xen-netback/interface.c | 61 ++++++++++++++++++++++++++++++------ drivers/net/xen-netback/netback.c | 11 +++++- drivers/net/xen-netback/rx.c | 13 +++++-- 4 files changed, 86 insertions(+), 14 deletions(-)
drivers/net/xen-netback/common.h +15 -0
@@ -140,6 +140,20 @@ struct xenvif_queue { /* Per-queue datachar name[QUEUE_NAME_SIZE ];/* DEVNAME-qN */ struct xenvif *vif;/* Parent VIF */ +/* +* TX/RX common EOI handling. +* When feature-split-event-channels = 0, interrupt handler sets +* NETBK_COMMON_EOI, otherwise NETBK_RX_EOI and NETBK_TX_EOI are set +* by the RX and TX interrupt handlers. +* RX and TX handler threads will issue an EOI when either +* NETBK_COMMON_EOI or their specific bits (NETBK_RX_EOI or +* NETBK_TX_EOI) are set and they will reset those bits. +*/ +atomic_t eoi_pending; +#define NETBK_RX_EOI 0x01 +#define NETBK_TX_EOI 0x02 +#define NETBK_COMMON_EOI 0x04 +/* Use NAPI for guest TX */ struct napi_struct napi;/* When feature-split-event-channels = 0, tx_irq = rx_irq. */
@@ -378,6 +392,7 @@ int xenvif_dealloc_kthread(void *data);irqreturn_t xenvif_ctrl_irq_fn (int irq,void *data); +bool xenvif_have_rx_work (struct xenvif_queue *queue,bool test_kthread);void xenvif_rx_action (struct xenvif_queue *queue);void xenvif_rx_queue_tail (struct xenvif_queue *queue,struct sk_buff *skb);
drivers/net/xen-netback/interface.c +52 -9
111 lines not on this page · raw message
drivers/net/xen-netback/netback.c +10 -1
@@ -169,6 +169,10 @@ void xenvif_napi_schedule_or_enable_evenif (more_to_do)napi_schedule (&queue->napi); +else if (atomic_fetch_andnot (NETBK_TX_EOI |NETBK_COMMON_EOI , + &queue->eoi_pending) & + (NETBK_TX_EOI |NETBK_COMMON_EOI )) +xen_irq_lateeoi (queue->tx_irq,0 ); }static void tx_add_credit (struct xenvif_queue *queue)
@@ -1643,9 +1647,14 @@ static bool xenvif_ctrl_work_todo(structirqreturn_t xenvif_ctrl_irq_fn (int irq,void *data) {struct xenvif *vif = data; +unsigned int eoi_flag =XEN_EOI_FLAG_SPURIOUS ; -while (xenvif_ctrl_work_todo (vif)) +while (xenvif_ctrl_work_todo (vif)) {xenvif_ctrl_action (vif); + eoi_flag =0 ; + } + +xen_irq_lateeoi (irq, eoi_flag);return IRQ_HANDLED ; }
drivers/net/xen-netback/rx.c +9 -4
@@ -503,13 +503,13 @@ static bool xenvif_rx_queue_ready(structreturn queue->stalled && prod - cons >=1 ; } -static bool xenvif_have_rx_work (struct xenvif_queue *queue) +bool xenvif_have_rx_work (struct xenvif_queue *queue,bool test_kthread) {return xenvif_rx_ring_slots_available (queue) || (queue->vif->stall_timeout && (xenvif_rx_queue_stalled (queue) ||xenvif_rx_queue_ready (queue))) || -kthread_should_stop () || + (test_kthread &&kthread_should_stop ()) || queue->vif->disabled; }
@@ -540,15 +540,20 @@ static void xenvif_wait_for_rx_work(stru {DEFINE_WAIT (wait); -if (xenvif_have_rx_work (queue)) +if (xenvif_have_rx_work (queue, true))return ;for (;;) {long ret;prepare_to_wait (&queue->wq, &wait,TASK_INTERRUPTIBLE ); -if (xenvif_have_rx_work (queue)) +if (xenvif_have_rx_work (queue, true))break ; +if (atomic_fetch_andnot (NETBK_RX_EOI |NETBK_COMMON_EOI , + &queue->eoi_pending) & + (NETBK_RX_EOI |NETBK_COMMON_EOI )) +xen_irq_lateeoi (queue->rx_irq,0 ); + ret =schedule_timeout (xenvif_rx_queue_timeout (queue));if (!ret)break ;
Greg Kroah-Hartman
maintainerPATCH 7/391 xen/scsiback: use lateeoi irq binding
In reply to Greg Kroah-HartmanFrom: Juergen Gross <[email protected]>
commit 86991b6e7ea6c613b7692f65106076943449b6b7 upstream.
In order to reduce the chance for the system becoming unresponsive due to event storms triggered by a misbehaving scsifront use the lateeoi irq binding for scsiback and unmask the event channel only just before leaving the event handling function.
In case of a ring protocol error don't issue an EOI in order to avoid the possibility to use that for producing an event storm. This at once will result in no further call of scsiback_irq_fn(), so the ring_error struct member can be dropped and scsiback_do_cmd_fn() can signal the protocol error via a negative return value.
This is part of XSA-332.
--- drivers/xen/xen-scsiback.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
drivers/xen/xen-scsiback.c +13 -10
@@ -91,7 +91,6 @@ struct vscsibk_info {unsigned int irq;struct vscsiif_back_ring ring; -int ring_error;spinlock_t ring_lock;atomic_t nr_unreplied_reqs;
@@ -722,7 +721,8 @@ static struct vscsibk_pend *prepare_pendreturn pending_req; } -static int scsiback_do_cmd_fn (struct vscsibk_info *info) +static int scsiback_do_cmd_fn (struct vscsibk_info *info, +unsigned int *eoi_flags) {struct vscsiif_back_ring *ring = &info->ring;struct vscsiif_request ring_req;
@@ -739,11 +739,12 @@ static int scsiback_do_cmd_fn(struct vsc rc = ring->rsp_prod_pvt;pr_warn ("Dom%d provided bogus ring requests (%#x - %#x = %u). Halting ring processing\n" , info->domid, rp, rc, rp - rc); - info->ring_error =1 ; -return 0 ; +return -EINVAL ; }while ((rc != rp)) { + *eoi_flags &= ~XEN_EOI_FLAG_SPURIOUS ; +if (RING_REQUEST_CONS_OVERFLOW (ring, rc))break ;
@@ -802,13 +803,16 @@ static int scsiback_do_cmd_fn(struct vscstatic irqreturn_t scsiback_irq_fn (int irq,void *dev_id) {struct vscsibk_info *info = dev_id; +int rc; +unsigned int eoi_flags =XEN_EOI_FLAG_SPURIOUS ; -if (info->ring_error) -return IRQ_HANDLED ; - -while (scsiback_do_cmd_fn (info)) +while ((rc =scsiback_do_cmd_fn (info, &eoi_flags)) >0 )cond_resched (); +/* In case of a ring error we keep the event channel masked. */ +if (!rc) +xen_irq_lateeoi (irq, eoi_flags); +return IRQ_HANDLED ; }
@@ -829,7 +833,7 @@ static int scsiback_init_sring(struct vs sring = (struct vscsiif_sring *)area;BACK_RING_INIT (&info->ring, sring,PAGE_SIZE ); - err =bind_interdomain_evtchn_to_irq (info->domid, evtchn); + err =bind_interdomain_evtchn_to_irq_lateeoi (info->domid, evtchn);if (err <0 ) goto unmap_page;
@@ -1253,7 +1257,6 @@ static int scsiback_probe(struct xenbus_ info->domid = dev->otherend_id;spin_lock_init (&info->ring_lock); - info->ring_error =0 ;atomic_set (&info->nr_unreplied_reqs,0 );init_waitqueue_head (&info->waiting_to_free); info->dev = dev;
Greg Kroah-Hartman
maintainerPATCH 8/391 xen/pvcallsback: use lateeoi irq binding
In reply to Greg Kroah-HartmanFrom: Juergen Gross <[email protected]>
commit c8d647a326f06a39a8e5f0f1af946eacfa1835f8 upstream.
In order to reduce the chance for the system becoming unresponsive due to event storms triggered by a misbehaving pvcallsfront use the lateeoi irq binding for pvcallsback and unmask the event channel only after handling all write requests, which are the ones coming in via an irq.
This requires modifying the logic a little bit to not require an event for each write request, but to keep the ioworker running until no further data is found on the ring page to be processed.
This is part of XSA-332.
--- drivers/xen/pvcalls-back.c | 76 +++++++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 30 deletions(-)
drivers/xen/pvcalls-back.c +46 -30
@@ -66,6 +66,7 @@ struct sock_mapping {atomic_t write;atomic_t io;atomic_t release; +atomic_t eoi;void (*saved_data_ready)(struct sock *sk);struct pvcalls_ioworker ioworker; };
@@ -87,7 +88,7 @@ static int pvcalls_back_release_active(sstruct pvcalls_fedata *fedata, struct sock_mapping *map); -static void pvcalls_conn_back_read (void *opaque) +static bool pvcalls_conn_back_read (void *opaque) {struct sock_mapping *map = (struct sock_mapping *)opaque;struct msghdr msg;
@@ -107,17 +108,17 @@ static void pvcalls_conn_back_read(voidvirt_mb ();if (error) -return ; +return false; size =pvcalls_queued (prod, cons, array_size);if (size >= array_size) -return ; +return false;spin_lock_irqsave (&map->sock->sk->sk_receive_queue.lock, flags);if (skb_queue_empty (&map->sock->sk->sk_receive_queue)) {atomic_set (&map->read,0 );spin_unlock_irqrestore (&map->sock->sk->sk_receive_queue.lock, flags); -return ; +return true; }spin_unlock_irqrestore (&map->sock->sk->sk_receive_queue.lock, flags); wanted = array_size - size;
@@ -141,7 +142,7 @@ static void pvcalls_conn_back_read(void ret =inet_recvmsg (map->sock, &msg, wanted,MSG_DONTWAIT );WARN_ON (ret > wanted);if (ret == -EAGAIN )/* shouldn't happen */ -return ; +return true;if (!ret) ret = -ENOTCONN ;spin_lock_irqsave (&map->sock->sk->sk_receive_queue.lock, flags);
@@ -160,10 +161,10 @@ static void pvcalls_conn_back_read(voidvirt_wmb ();notify_remote_via_irq (map->irq); -return ; +return true; } -static void pvcalls_conn_back_write (struct sock_mapping *map) +static bool pvcalls_conn_back_write (struct sock_mapping *map) {struct pvcalls_data_intf *intf = map->ring;struct pvcalls_data *data = &map->data;
@@ -180,7 +181,7 @@ static void pvcalls_conn_back_write(stru array_size =XEN_FLEX_RING_SIZE (map->ring_order); size =pvcalls_queued (prod, cons, array_size);if (size ==0 ) -return ; +return false;memset (&msg,0 ,sizeof (msg)); msg.msg_flags |=MSG_DONTWAIT ;
@@ -198,12 +199,11 @@ static void pvcalls_conn_back_write(struatomic_set (&map->write,0 ); ret =inet_sendmsg (map->sock, &msg, size); -if (ret == -EAGAIN || (ret >=0 && ret < size)) { +if (ret == -EAGAIN ) {atomic_inc (&map->write);atomic_inc (&map->io); +return true; } -if (ret == -EAGAIN ) -return ;/* write the data, then update the indexes */ virt_wmb ();
@@ -216,9 +216,13 @@ static void pvcalls_conn_back_write(stru }/* update the indexes, then notify the other end */ virt_wmb (); -if (prod != cons + ret) +if (prod != cons + ret) {atomic_inc (&map->write); +atomic_inc (&map->io); + }notify_remote_via_irq (map->irq); + +return true; }static void pvcalls_back_ioworker (struct work_struct *work)
@@ -227,6 +231,7 @@ static void pvcalls_back_ioworker(struct struct pvcalls_ioworker, register_work); struct sock_mapping *map = container_of(ioworker, struct sock_mapping, ioworker); +unsigned int eoi_flags =XEN_EOI_FLAG_SPURIOUS ;while (atomic_read (&map->io) >0 ) {if (atomic_read (&map->release) >0 ) {
@@ -234,10 +239,18 @@ static void pvcalls_back_ioworker(structreturn ; } -if (atomic_read (&map->read) >0 ) -pvcalls_conn_back_read (map); -if (atomic_read (&map->write) >0 ) -pvcalls_conn_back_write (map); +if (atomic_read (&map->read) >0 && +pvcalls_conn_back_read (map)) + eoi_flags =0 ; +if (atomic_read (&map->write) >0 && +pvcalls_conn_back_write (map)) + eoi_flags =0 ; + +if (atomic_read (&map->eoi) >0 && !atomic_read (&map->write)) { +atomic_set (&map->eoi,0 ); +xen_irq_lateeoi (map->irq, eoi_flags); + eoi_flags =XEN_EOI_FLAG_SPURIOUS ; + }atomic_dec (&map->io); }
@@ -334,12 +347,9 @@ static struct sock_mapping *pvcalls_new_ goto out; map->bytes = page; - ret =bind_interdomain_evtchn_to_irqhandler (fedata->dev->otherend_id, - evtchn, - pvcalls_back_conn_event, -0 , -"pvcalls-backend" , - map); + ret =bind_interdomain_evtchn_to_irqhandler_lateeoi ( + fedata->dev->otherend_id, evtchn, + pvcalls_back_conn_event,0 ,"pvcalls-backend" , map);if (ret <0 ) goto out; map->irq = ret;
@@ -873,15 +883,18 @@ static irqreturn_t pvcalls_back_event(in {struct xenbus_device *dev = dev_id;struct pvcalls_fedata *fedata =NULL ; +unsigned int eoi_flags =XEN_EOI_FLAG_SPURIOUS ; -if (dev ==NULL ) -return IRQ_HANDLED ; +if (dev) { + fedata =dev_get_drvdata (&dev->dev); +if (fedata) { +pvcalls_back_work (fedata); + eoi_flags =0 ; + } + } - fedata =dev_get_drvdata (&dev->dev); -if (fedata ==NULL ) -return IRQ_HANDLED ; +xen_irq_lateeoi (irq, eoi_flags); -pvcalls_back_work (fedata);return IRQ_HANDLED ; }
@@ -891,12 +904,15 @@ static irqreturn_t pvcalls_back_conn_evestruct pvcalls_ioworker *iow;if (map ==NULL || map->sock ==NULL || map->sock->sk ==NULL || - map->sock->sk->sk_user_data != map) + map->sock->sk->sk_user_data != map) { +xen_irq_lateeoi (irq,0 );return IRQ_HANDLED ; + } iow = &map->ioworker;atomic_inc (&map->write); +atomic_inc (&map->eoi);atomic_inc (&map->io);queue_work (iow->wq, &iow->register_work);
@@ -932,7 +948,7 @@ static int backend_connect(struct xenbus goto error; } - err =bind_interdomain_evtchn_to_irq (dev->otherend_id, evtchn); + err =bind_interdomain_evtchn_to_irq_lateeoi (dev->otherend_id, evtchn);if (err <0 ) goto error; fedata->irq = err;
Greg Kroah-Hartman
maintainerPATCH 9/391 xen/pciback: use lateeoi irq binding
In reply to Greg Kroah-HartmanFrom: Juergen Gross <[email protected]>
commit c2711441bc961b37bba0615dd7135857d189035f upstream.
In order to reduce the chance for the system becoming unresponsive due to event storms triggered by a misbehaving pcifront use the lateeoi irq binding for pciback and unmask the event channel only just before leaving the event handling function.
Restructure the handling to support that scheme. Basically an event can come in for two reasons: either a normal request for a pciback action, which is handled in a worker, or in case the guest has finished an AER request which was requested by pciback.
When an AER request is issued to the guest and a normal pciback action is currently active issue an EOI early in order to be able to receive another event when the AER request has been finished by the guest.
Let the worker processing the normal requests run until no further request is pending, instead of starting a new worker ion that case. Issue the EOI only just before leaving the worker.
This scheme allows to drop calling the generic function xen_pcibk_test_and_schedule_op() after processing of any request as the handling of both request types is now separated more cleanly.
This is part of XSA-332.
--- drivers/xen/xen-pciback/pci_stub.c | 13 ++++----- drivers/xen/xen-pciback/pciback.h | 12 +++++++- drivers/xen/xen-pciback/pciback_ops.c | 48 ++++++++++++++++++++++++++-------- drivers/xen/xen-pciback/xenbus.c | 2 - 4 files changed, 56 insertions(+), 19 deletions(-)
drivers/xen/xen-pciback/pci_stub.c +7 -6
@@ -734,10 +734,17 @@ static pci_ers_result_t common_process(swmb ();notify_remote_via_irq (pdev->evtchn_irq); +/* Enable IRQ to signal "request done". */ +xen_pcibk_lateeoi (pdev,0 ); + ret =wait_event_timeout (xen_pcibk_aer_wait_queue, !(test_bit (_XEN_PCIB_active, (unsigned long *) &sh_info->flags)),300 *HZ ); +/* Enable IRQ for pcifront request if not already active. */ +if (!test_bit (_PDEVF_op_active, &pdev->flags)) +xen_pcibk_lateeoi (pdev,0 ); +if (!ret) {if (test_bit (_XEN_PCIB_active, (unsigned long *)&sh_info->flags)) {
@@ -751,12 +758,6 @@ static pci_ers_result_t common_process(s }clear_bit (_PCIB_op_pending, (unsigned long *)&pdev->flags); -if (test_bit (_XEN_PCIF_active, - (unsigned long *)&sh_info->flags)) { -dev_dbg (&psdev->dev->dev,"schedule pci_conf service\n" ); -xen_pcibk_test_and_schedule_op (psdev->pdev); - } - res = (pci_ers_result_t )aer_op->err;return res; }
drivers/xen/xen-pciback/pciback.h +10 -2
@@ -14,6 +14,7 @@#include <linux/spinlock.h> #include <linux/workqueue.h> #include <linux/atomic.h> +#include <xen/events.h> #include <xen/interface/io/pciif.h> #define DRV_NAME "xen-pciback"
@@ -27,6 +28,8 @@ struct pci_dev_entry {#define PDEVF_op_active (1<<(_PDEVF_op_active))#define _PCIB_op_pending (1)#define PCIB_op_pending (1<<(_PCIB_op_pending)) +#define _EOI_pending (2) +#define EOI_pending (1<<(_EOI_pending))struct xen_pcibk_device {void *pci_dev_data;
@@ -183,10 +186,15 @@ static inline void xen_pcibk_release_devirqreturn_t xen_pcibk_handle_event (int irq,void *dev_id);void xen_pcibk_do_op (struct work_struct *data); +static inline void xen_pcibk_lateeoi (struct xen_pcibk_device *pdev, +unsigned int eoi_flag) +{ +if (test_and_clear_bit (_EOI_pending, &pdev->flags)) +xen_irq_lateeoi (pdev->evtchn_irq, eoi_flag); +} +int xen_pcibk_xenbus_register (void );void xen_pcibk_xenbus_unregister (void ); - -void xen_pcibk_test_and_schedule_op (struct xen_pcibk_device *pdev);#endif /* Handles shared IRQs that can to device domain and control domain. */
drivers/xen/xen-pciback/pciback_ops.c +38 -10
90 lines not on this page · raw message
drivers/xen/xen-pciback/xenbus.c +1 -1
@@ -123,7 +123,7 @@ static int xen_pcibk_do_attach(struct xe pdev->sh_info = vaddr; - err =bind_interdomain_evtchn_to_irqhandler ( + err =bind_interdomain_evtchn_to_irqhandler_lateeoi ( pdev->xdev->otherend_id, remote_evtchn, xen_pcibk_handle_event,0 ,DRV_NAME , pdev);if (err <0 ) {
Greg Kroah-Hartman
maintainerPATCH 10/391 xen/events: switch user event channels to lateeoi model
In reply to Greg Kroah-HartmanFrom: Juergen Gross <[email protected]>
commit c44b849cee8c3ac587da3b0980e01f77500d158c upstream.
Instead of disabling the irq when an event is received and enabling it again when handled by the user process use the lateeoi model.
This is part of XSA-332.
--- drivers/xen/evtchn.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/xen/evtchn.c +3 -4
@@ -167,7 +167,6 @@ static irqreturn_t evtchn_interrupt(int"Interrupt for port %u, but apparently not enabled; per-user %p\n" , evtchn->port, u); -disable_irq_nosync (irq); evtchn->enabled = false;spin_lock (&u->ring_prod_lock);
@@ -293,7 +292,7 @@ static ssize_t evtchn_write(struct file evtchn =find_evtchn (u, port);if (evtchn && !evtchn->enabled) { evtchn->enabled = true; -enable_irq (irq_from_evtchn (port)); +xen_irq_lateeoi (irq_from_evtchn (port),0 ); } }
@@ -393,8 +392,8 @@ static int evtchn_bind_to_user(struct peif (rc <0 ) goto err; - rc =bind_evtchn_to_irqhandler (port, evtchn_interrupt,0 , - u->name, evtchn); + rc =bind_evtchn_to_irqhandler_lateeoi (port, evtchn_interrupt,0 , + u->name, evtchn);if (rc <0 ) goto err;
Greg Kroah-Hartman
maintainerPATCH 11/391 xen/events: use a common cpu hotplug hook for event channels
In reply to Greg Kroah-HartmanFrom: Juergen Gross <[email protected]>
commit 7beb290caa2adb0a399e735a1e175db9aae0523a upstream.
Today only fifo event channels have a cpu hotplug callback. In order to prepare for more percpu (de)init work move that callback into events_base.c and add percpu_init() and percpu_deinit() hooks to struct evtchn_ops.
This is part of XSA-332.
--- drivers/xen/events/events_base.c | 25 +++++++++++++++++++++ drivers/xen/events/events_fifo.c | 40 ++++++++++++++++------------------- drivers/xen/events/events_internal.h | 3 ++ 3 files changed, 47 insertions(+), 21 deletions(-)
drivers/xen/events/events_base.c +25 -0
@@ -34,6 +34,7 @@#include <linux/irqnr.h> #include <linux/pci.h> #include <linux/spinlock.h> +#include <linux/cpuhotplug.h> #ifdef CONFIG_X86 #include <asm/desc.h>
@@ -1830,6 +1831,26 @@ static inline void xen_alloc_callback_vestatic bool fifo_events = true;module_param (fifo_events, bool,0 ); +static int xen_evtchn_cpu_prepare (unsigned int cpu) +{ +int ret =0 ; + +if (evtchn_ops->percpu_init) + ret = evtchn_ops->percpu_init (cpu); + +return ret; +} + +static int xen_evtchn_cpu_dead (unsigned int cpu) +{ +int ret =0 ; + +if (evtchn_ops->percpu_deinit) + ret = evtchn_ops->percpu_deinit (cpu); + +return ret; +} +void __init xen_init_IRQ (void ) {int ret = -EINVAL ;
@@ -1840,6 +1861,10 @@ void __init xen_init_IRQ(void)if (ret <0 )xen_evtchn_2l_init (); +cpuhp_setup_state_nocalls (CPUHP_XEN_EVTCHN_PREPARE , +"xen/evtchn:prepare" , + xen_evtchn_cpu_prepare, xen_evtchn_cpu_dead); + evtchn_to_irq =kcalloc (EVTCHN_ROW (xen_evtchn_max_channels ()),sizeof (*evtchn_to_irq),GFP_KERNEL );BUG_ON (!evtchn_to_irq);
drivers/xen/events/events_fifo.c +19 -21
@@ -385,21 +385,6 @@ static void evtchn_fifo_resume(void) event_array_pages =0 ; } -static const struct evtchn_ops evtchn_ops_fifo = { - .max_channels = evtchn_fifo_max_channels, - .nr_channels = evtchn_fifo_nr_channels, - .setup = evtchn_fifo_setup, - .bind_to_cpu = evtchn_fifo_bind_to_cpu, - .clear_pending = evtchn_fifo_clear_pending, - .set_pending = evtchn_fifo_set_pending, - .is_pending = evtchn_fifo_is_pending, - .test_and_set_mask = evtchn_fifo_test_and_set_mask, - .mask = evtchn_fifo_mask, - .unmask = evtchn_fifo_unmask, - .handle_events = evtchn_fifo_handle_events, - .resume = evtchn_fifo_resume, -}; -static int evtchn_fifo_alloc_control_block (unsigned cpu) {void *control_block =NULL ;
@@ -422,19 +407,36 @@ static int evtchn_fifo_alloc_control_bloreturn ret; } -static int xen_evtchn_cpu_prepare (unsigned int cpu) +static int evtchn_fifo_percpu_init (unsigned int cpu) {if (!per_cpu (cpu_control_block, cpu))return evtchn_fifo_alloc_control_block (cpu);return 0 ; } -static int xen_evtchn_cpu_dead (unsigned int cpu) +static int evtchn_fifo_percpu_deinit (unsigned int cpu) {__evtchn_fifo_handle_events (cpu, true);return 0 ; } +static const struct evtchn_ops evtchn_ops_fifo = { + .max_channels = evtchn_fifo_max_channels, + .nr_channels = evtchn_fifo_nr_channels, + .setup = evtchn_fifo_setup, + .bind_to_cpu = evtchn_fifo_bind_to_cpu, + .clear_pending = evtchn_fifo_clear_pending, + .set_pending = evtchn_fifo_set_pending, + .is_pending = evtchn_fifo_is_pending, + .test_and_set_mask = evtchn_fifo_test_and_set_mask, + .mask = evtchn_fifo_mask, + .unmask = evtchn_fifo_unmask, + .handle_events = evtchn_fifo_handle_events, + .resume = evtchn_fifo_resume, + .percpu_init = evtchn_fifo_percpu_init, + .percpu_deinit = evtchn_fifo_percpu_deinit, +}; +int __init xen_evtchn_fifo_init (void ) {int cpu =smp_processor_id ();
@@ -448,9 +450,5 @@ int __init xen_evtchn_fifo_init(void) evtchn_ops = &evtchn_ops_fifo; -cpuhp_setup_state_nocalls (CPUHP_XEN_EVTCHN_PREPARE , -"xen/evtchn:prepare" , - xen_evtchn_cpu_prepare, xen_evtchn_cpu_dead); -return ret; }
drivers/xen/events/events_internal.h +3 -0
@@ -69,6 +69,9 @@ struct evtchn_ops {void (*handle_events)(unsigned cpu);void (*resume)(void ); + +int (*percpu_init)(unsigned int cpu); +int (*percpu_deinit)(unsigned int cpu); };extern const struct evtchn_ops *evtchn_ops;
Greg Kroah-Hartman
maintainerPATCH 12/391 xen/events: defer eoi in case of excessive number of events
In reply to Greg Kroah-HartmanFrom: Juergen Gross <[email protected]>
commit e99502f76271d6bc4e374fe368c50c67a1fd3070 upstream.
In case rogue guests are sending events at high frequency it might happen that xen_evtchn_do_upcall() won't stop processing events in dom0. As this is done in irq handling a crash might be the result.
In order to avoid that, delay further inter-domain events after some time in xen_evtchn_do_upcall() by forcing eoi processing into a worker on the same cpu, thus inhibiting new events coming in.
The time after which eoi processing is to be delayed is configurable via a new module parameter "event_loop_timeout" which specifies the maximum event loop time in jiffies (default: 2, the value was chosen after some tests showing that a value of 2 was the lowest with an only slight drop of dom0 network throughput while multiple guests performed an event storm).
How long eoi processing will be delayed can be specified via another parameter "event_eoi_delay" (again in jiffies, default 10, again the value was chosen after testing with different delay values).
This is part of XSA-332.
--- Documentation/admin-guide/kernel-parameters.txt | 8 + drivers/xen/events/events_2l.c | 7 drivers/xen/events/events_base.c | 189 +++++++++++++++++++++++- drivers/xen/events/events_fifo.c | 30 +-- drivers/xen/events/events_internal.h | 14 + 5 files changed, 216 insertions(+), 32 deletions(-)
Documentation/admin-guide/kernel-parameters.txt +8 -0
@@ -5828,6 +5828,14 @@ improve timer resolution at the expense of processing more timer interrupts. + xen.event_eoi_delay= [XEN] + How long to delay EOI handling in case of event + storms (jiffies). Default is 10. + + xen.event_loop_timeout= [XEN] + After which time (jiffies) the event handling loop + should start to delay EOI handling. Default is 2. + nopv= [X86,XEN,KVM,HYPER_V,VMWARE] Disables the PV optimizations forcing the guest to run as generic guest with no PV drivers. Currently support
drivers/xen/events/events_2l.c +2 -5
@@ -161,7 +161,7 @@ static inline xen_ulong_t active_evtchns* a bitset of words which contain pending event bits. The second * level is a bitset of pending events themselves. */ -static void evtchn_2l_handle_events (unsigned cpu) +static void evtchn_2l_handle_events (unsigned cpu,struct evtchn_loop_ctrl *ctrl) {int irq;xen_ulong_t pending_words;
@@ -242,10 +242,7 @@ static void evtchn_2l_handle_events(unsi/* Process port. */ port = (word_idx *BITS_PER_EVTCHN_WORD ) + bit_idx; - irq =get_evtchn_to_irq (port); - -if (irq !=-1 ) -generic_handle_irq (irq); +handle_irq_for_port (port, ctrl); bit_idx = (bit_idx +1 ) %BITS_PER_EVTCHN_WORD ;
drivers/xen/events/events_base.c +184 -5
287 lines not on this page · raw message
drivers/xen/events/events_fifo.c +11 -19
@@ -275,19 +275,9 @@ static uint32_t clear_linked(volatile evreturn w &EVTCHN_FIFO_LINK_MASK ; } -static void handle_irq_for_port (evtchn_port_t port) -{ -int irq; - - irq =get_evtchn_to_irq (port); -if (irq !=-1 ) -generic_handle_irq (irq); -} - -static void consume_one_event (unsigned cpu, +static void consume_one_event (unsigned cpu,struct evtchn_loop_ctrl *ctrl,struct evtchn_fifo_control_block *control_block, -unsigned priority,unsigned long *ready, -bool drop) +unsigned priority,unsigned long *ready) {struct evtchn_fifo_queue *q = &per_cpu (cpu_queue, cpu);uint32_t head;
@@ -320,16 +310,17 @@ static void consume_one_event(unsigned cclear_bit (priority, ready);if (evtchn_fifo_is_pending (port) && !evtchn_fifo_is_masked (port)) { -if (unlikely (drop)) +if (unlikely (!ctrl))pr_warn ("Dropping pending event for port %u\n" , port);else -handle_irq_for_port (port); +handle_irq_for_port (port, ctrl); } q->head[priority] = head; } -static void __evtchn_fifo_handle_events (unsigned cpu,bool drop) +static void __evtchn_fifo_handle_events (unsigned cpu, +struct evtchn_loop_ctrl *ctrl) {struct evtchn_fifo_control_block *control_block;unsigned long ready;
@@ -341,14 +332,15 @@ static void __evtchn_fifo_handle_events(while (ready) { q =find_first_bit (&ready,EVTCHN_FIFO_MAX_QUEUES ); -consume_one_event (cpu, control_block, q, &ready, drop); +consume_one_event (cpu, ctrl, control_block, q, &ready); ready |=xchg (&control_block->ready,0 ); } } -static void evtchn_fifo_handle_events (unsigned cpu) +static void evtchn_fifo_handle_events (unsigned cpu, +struct evtchn_loop_ctrl *ctrl) { -__evtchn_fifo_handle_events (cpu, false); +__evtchn_fifo_handle_events (cpu, ctrl); }static void evtchn_fifo_resume (void )
@@ -416,7 +408,7 @@ static int evtchn_fifo_percpu_init(unsigstatic int evtchn_fifo_percpu_deinit (unsigned int cpu) { -__evtchn_fifo_handle_events (cpu, true); +__evtchn_fifo_handle_events (cpu,NULL );return 0 ; }
drivers/xen/events/events_internal.h +11 -3
@@ -30,11 +30,15 @@ enum xen_irq_type {*/ struct irq_info {struct list_head list; +struct list_head eoi_list;int refcnt;enum xen_irq_type type;/* type */ unsigned irq;evtchn_port_t evtchn;/* event channel */ unsigned short cpu;/* cpu bound */ +unsigned short eoi_cpu;/* EOI must happen on this cpu */ +unsigned int irq_epoch;/* If eoi_cpu valid: irq_epoch of event */ +u64 eoi_time;/* Time in jiffies when to EOI. */ union {unsigned short virq;
@@ -53,6 +57,8 @@ struct irq_info {#define PIRQ_SHAREABLE (1 << 1)#define PIRQ_MSI_GROUP (1 << 2) +struct evtchn_loop_ctrl ; +struct evtchn_ops {unsigned (*max_channels)(void );unsigned (*nr_channels)(void );
@@ -67,7 +73,7 @@ struct evtchn_ops {void (*mask)(evtchn_port_t port);void (*unmask)(evtchn_port_t port); -void (*handle_events)(unsigned cpu); +void (*handle_events)(unsigned cpu,struct evtchn_loop_ctrl *ctrl);void (*resume)(void );int (*percpu_init)(unsigned int cpu);
@@ -78,6 +84,7 @@ extern const struct evtchn_ops *evtchn_oextern int **evtchn_to_irq;int get_evtchn_to_irq (evtchn_port_t evtchn); +void handle_irq_for_port (evtchn_port_t port,struct evtchn_loop_ctrl *ctrl);struct irq_info *info_for_irq (unsigned irq);unsigned cpu_from_irq (unsigned irq);
@@ -135,9 +142,10 @@ static inline void unmask_evtchn(evtchn_return evtchn_ops->unmask (port); } -static inline void xen_evtchn_handle_events (unsigned cpu) +static inline void xen_evtchn_handle_events (unsigned cpu, +struct evtchn_loop_ctrl *ctrl) { -return evtchn_ops->handle_events (cpu); +return evtchn_ops->handle_events (cpu, ctrl); }static inline void xen_evtchn_resume (void )
Greg Kroah-Hartman
maintainerPATCH 13/391 xen/events: block rogue events for some time
In reply to Greg Kroah-HartmanFrom: Juergen Gross <[email protected]>
commit 5f7f77400ab5b357b5fdb7122c3442239672186c upstream.
In order to avoid high dom0 load due to rogue guests sending events at high frequency, block those events in case there was no action needed in dom0 to handle the events.
This is done by adding a per-event counter, which set to zero in case an EOI without the XEN_EOI_FLAG_SPURIOUS is received from a backend driver, and incremented when this flag has been set. In case the counter is 2 or higher delay the EOI by 1 << (cnt - 2) jiffies, but not more than 1 second.
In order not to waste memory shorten the per-event refcnt to two bytes (it should normally never exceed a value of 2). Add an overflow check to evtchn_get() to make sure the 2 bytes really won't overflow.
This is part of XSA-332.
--- drivers/xen/events/events_base.c | 27 ++++++++++++++++++++++----- drivers/xen/events/events_internal.h | 3 ++- 2 files changed, 24 insertions(+), 6 deletions(-)
drivers/xen/events/events_base.c +22 -5
@@ -461,17 +461,34 @@ static void lateeoi_list_add(struct irq_spin_unlock_irqrestore (&eoi->eoi_list_lock, flags); } -static void xen_irq_lateeoi_locked (struct irq_info *info) +static void xen_irq_lateeoi_locked (struct irq_info *info,bool spurious) {evtchn_port_t evtchn;unsigned int cpu; +unsigned int delay =0 ; evtchn = info->evtchn;if (!VALID_EVTCHN (evtchn) || !list_empty (&info->eoi_list))return ; +if (spurious) { +if ((1 << info->spurious_cnt) < (HZ <<2 )) + info->spurious_cnt++; +if (info->spurious_cnt >1 ) { + delay =1 << (info->spurious_cnt -2 ); +if (delay >HZ ) + delay =HZ ; +if (!info->eoi_time) + info->eoi_cpu =smp_processor_id (); + info->eoi_time =get_jiffies_64 () + delay; + } + }else { + info->spurious_cnt =0 ; + } + cpu = info->eoi_cpu; -if (info->eoi_time && info->irq_epoch ==per_cpu (irq_epoch, cpu)) { +if (info->eoi_time && + (info->irq_epoch ==per_cpu (irq_epoch, cpu) || delay)) {lateeoi_list_add (info);return ; }
@@ -508,7 +525,7 @@ static void xen_irq_lateeoi_worker(struc info->eoi_time =0 ; -xen_irq_lateeoi_locked (info); +xen_irq_lateeoi_locked (info, false); }if (info)
@@ -537,7 +554,7 @@ void xen_irq_lateeoi(unsigned int irq, u info =info_for_irq (irq);if (info) -xen_irq_lateeoi_locked (info); +xen_irq_lateeoi_locked (info, eoi_flags &XEN_EOI_FLAG_SPURIOUS );read_unlock_irqrestore (&evtchn_rwlock, flags); }
@@ -1441,7 +1458,7 @@ int evtchn_get(evtchn_port_t evtchn) goto done; err = -EINVAL ; -if (info->refcnt <=0 ) +if (info->refcnt <=0 || info->refcnt ==SHRT_MAX ) goto done; info->refcnt++;
drivers/xen/events/events_internal.h +2 -1
@@ -31,7 +31,8 @@ enum xen_irq_type {struct irq_info {struct list_head list;struct list_head eoi_list; -int refcnt; +short refcnt; +short spurious_cnt;enum xen_irq_type type;/* type */ unsigned irq;evtchn_port_t evtchn;/* event channel */
Greg Kroah-Hartman
maintainerPATCH 14/391 firmware: arm_scmi: Fix ARCH_COLD_RESET
In reply to Greg Kroah-HartmanFrom: Etienne Carriere <[email protected]>
[ Upstream commit 45b9e04d5ba0b043783dfe2b19bb728e712cb32e ]
The defination for ARCH_COLD_RESET is wrong. Let us fix it according to the SCMI specification.
--- drivers/firmware/arm_scmi/reset.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/firmware/arm_scmi/reset.c +1 -3
@@ -36,9 +36,7 @@ struct scmi_msg_reset_domain_reset {#define EXPLICIT_RESET_ASSERT BIT(1)#define ASYNCHRONOUS_RESET BIT(2)__le32 reset_state; -#define ARCH_RESET_TYPE BIT(31) -#define COLD_RESET_STATE BIT(0) -#define ARCH_COLD_RESET (ARCH_RESET_TYPE | COLD_RESET_STATE) +#define ARCH_COLD_RESET 0 };struct scmi_msg_reset_notify {
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 15/391 firmware: arm_scmi: Expand SMC/HVC message pool to more than one
In reply to Greg Kroah-HartmanFrom: Etienne Carriere <[email protected]>
[ Upstream commit 7adb2c8aaaa6a387af7140e57004beba2c04a4c6 ]
SMC/HVC can transmit only one message at the time as the shared memory needs to be protected and the calls are synchronous.
However, in order to allow multiple threads to send SCMI messages simultaneously, we need a larger poll of memory.
Let us just use value of 20 to keep it in sync mailbox transport implementation. Any other value must work perfectly.
--- drivers/firmware/arm_scmi/smc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/firmware/arm_scmi/smc.c +1 -1
@@ -149,6 +149,6 @@ static struct scmi_transport_ops scmi_smc_ops = {const struct scmi_desc scmi_smc_desc = { .ops = &scmi_smc_ops, .max_rx_timeout_ms =30 , - .max_msg =1 , + .max_msg =20 , .max_msg_size =128 , };
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 16/391 tee: client UUID: Skip REE kernel login method as well
In reply to Greg Kroah-HartmanFrom: Sumit Garg <[email protected]>
[ Upstream commit 722939528a37aa0cb22d441e2045c0cf53e78fb0 ]
Since the addition of session's client UUID generation via commit [1], login via REE kernel method was disallowed. So fix that via passing nill UUID in case of TEE_IOCTL_LOGIN_REE_KERNEL method as well.
--- drivers/tee/tee_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/tee/tee_core.c +2 -1
@@ -200,7 +200,8 @@ int tee_session_calc_client_uuid(uuid_t *uuid, u32 connection_method,int name_len;int rc; -if (connection_method ==TEE_IOCTL_LOGIN_PUBLIC ) { +if (connection_method ==TEE_IOCTL_LOGIN_PUBLIC || + connection_method ==TEE_IOCTL_LOGIN_REE_KERNEL ) {/* Nil UUID to be passed to TEE environment */ uuid_copy (uuid, &uuid_null);return 0 ;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 17/391 firmware: arm_scmi: Add missing Rx size re-initialisation
In reply to Greg Kroah-HartmanFrom: Sudeep Holla <[email protected]>
[ Upstream commit 9724722fde8f9bbd2b87340f00b9300c9284001e ]
Few commands provide the list of description partially and require to be called consecutively until all the descriptors are fetched completely. In such cases, we don't release the buffers and reuse them for consecutive transmits.
However, currently we don't reset the Rx size which will be set as per the response for the last transmit. This may result in incorrect response size being interpretted as the firmware may repond with size greater than the one set but we read only upto the size set by previous response.
Let us reset the receive buffer size to max possible in such cases as we don't know the exact size of the response.
--- drivers/firmware/arm_scmi/base.c | 2 ++ drivers/firmware/arm_scmi/clock.c | 2 ++ drivers/firmware/arm_scmi/common.h | 2 ++ drivers/firmware/arm_scmi/driver.c | 8 ++++++++ drivers/firmware/arm_scmi/perf.c | 2 ++ drivers/firmware/arm_scmi/sensors.c | 2 ++ 6 files changed, 18 insertions(+)
drivers/firmware/arm_scmi/base.c +2 -0
@@ -197,6 +197,8 @@ static int scmi_base_implementation_list_get(const struct scmi_handle *handle, protocols_imp[tot_num_ret + loop] = *(list + loop); tot_num_ret += loop_num_ret; + +scmi_reset_rx_to_maxsz (handle, t); }while (loop_num_ret);scmi_xfer_put (handle, t);
drivers/firmware/arm_scmi/clock.c +2 -0
@@ -192,6 +192,8 @@ scmi_clock_describe_rates_get(const struct scmi_handle *handle, u32 clk_id, } tot_rate_cnt += num_returned; + +scmi_reset_rx_to_maxsz (handle, t);/* * check for both returned and remaining to avoid infinite * loop due to buggy firmware
drivers/firmware/arm_scmi/common.h +2 -0
@@ -147,6 +147,8 @@ int scmi_do_xfer_with_response(const struct scmi_handle *h, struct scmi_xfer *xfer);int scmi_xfer_get_init (const struct scmi_handle *h,u8 msg_id,u8 prot_id,size_t tx_size,size_t rx_size,struct scmi_xfer **p); +void scmi_reset_rx_to_maxsz (const struct scmi_handle *handle, +struct scmi_xfer *xfer);int scmi_handle_put (const struct scmi_handle *handle);struct scmi_handle *scmi_handle_get (struct device *dev);void scmi_set_handle (struct scmi_device *scmi_dev);
drivers/firmware/arm_scmi/driver.c +8 -0
@@ -402,6 +402,14 @@ int scmi_do_xfer(const struct scmi_handle *handle, struct scmi_xfer *xfer)return ret; } +void scmi_reset_rx_to_maxsz (const struct scmi_handle *handle, +struct scmi_xfer *xfer) +{ +struct scmi_info *info =handle_to_scmi_info (handle); + + xfer->rx.len = info->desc->max_msg_size; +} +#define SCMI_MAX_RESPONSE_TIMEOUT (2 * MSEC_PER_SEC)/**
drivers/firmware/arm_scmi/perf.c +2 -0
@@ -304,6 +304,8 @@ scmi_perf_describe_levels_get(const struct scmi_handle *handle, u32 domain, } tot_opp_cnt += num_returned; + +scmi_reset_rx_to_maxsz (handle, t);/* * check for both returned and remaining to avoid infinite * loop due to buggy firmware
drivers/firmware/arm_scmi/sensors.c +2 -0
@@ -166,6 +166,8 @@ static int scmi_sensor_description_get(const struct scmi_handle *handle, } desc_index += num_returned; + +scmi_reset_rx_to_maxsz (handle, t);/* * check for both returned and remaining to avoid infinite * loop due to buggy firmware
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 18/391 x86/unwind/orc: Fix inactive tasks with stack pointer in %sp on GCC 10 compiled kernels
In reply to Greg Kroah-HartmanFrom: Jiri Slaby <[email protected]>
[ Upstream commit f2ac57a4c49d40409c21c82d23b5706df9b438af ]
GCC 10 optimizes the scheduler code differently than its predecessors.
When CONFIG_DEBUG_SECTION_MISMATCH=y, the Makefile forces GCC not to inline some functions (-fno-inline-functions-called-once). Before GCC 10, "no-inlined" __schedule() starts with the usual prologue:
push %bp
mov %sp, %bp
So the ORC unwinder simply picks stack pointer from %bp and unwinds from __schedule() just perfectly:
$ cat /proc/1/stack [<0>] ep_poll+0x3e9/0x450 [<0>] do_epoll_wait+0xaa/0xc0 [<0>] __x64_sys_epoll_wait+0x1a/0x20 [<0>] do_syscall_64+0x33/0x40 [<0>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
But now, with GCC 10, there is no %bp prologue in __schedule():
$ cat /proc/1/stack <nothing>
The ORC entry of the point in __schedule() is:
sp:sp+88 bp:last_sp-48 type:call end:0
In this case, nobody subtracts sizeof "struct inactive_task_frame" in __unwind_start(). The struct is put on the stack by __switch_to_asm() and only then __switch_to_asm() stores %sp to task->thread.sp. But we start unwinding from a point in __schedule() (stored in frame->ret_addr by 'call') and not in __switch_to_asm().
So for these example values in __unwind_start():
sp=ffff94b50001fdc8 bp=ffff8e1f41d29340 ip=__schedule+0x1f0
The stack is:
ffff94b50001fdc8: ffff8e1f41578000 # struct inactive_task_frame
ffff94b50001fdd0: 0000000000000000
ffff94b50001fdd8: ffff8e1f41d29340
ffff94b50001fde0: ffff8e1f41611d40 # ...
ffff94b50001fde8: ffffffff93c41920 # bx
ffff94b50001fdf0: ffff8e1f41d29340 # bp
ffff94b50001fdf8: ffffffff9376cad0 # ret_addr (and end of the struct)
0xffffffff9376cad0 is __schedule+0x1f0 (after the call to __switch_to_asm). Now follow those 88 bytes from the ORC entry (sp+88). The entry is correct, __schedule() really pushes 48 bytes (8*7) + 32 bytes via subq to store some local values (like 4U below). So to unwind, look at the offset 88-sizeof(long) = 0x50 from here:
ffff94b50001fe00: ffff8e1f41578618
ffff94b50001fe08: 00000cc000000255
ffff94b50001fe10: 0000000500000004
ffff94b50001fe18: 7793fab6956b2d00 # NOTE (see below)
ffff94b50001fe20: ffff8e1f41578000
ffff94b50001fe28: ffff8e1f41578000
ffff94b50001fe30: ffff8e1f41578000
ffff94b50001fe38: ffff8e1f41578000
ffff94b50001fe40: ffff94b50001fed8
ffff94b50001fe48: ffff8e1f41577ff0
ffff94b50001fe50: ffffffff9376cf12
Here ^^^^^^^^^^^^^^^^ is the correct ret addr from__schedule(). It translates to schedule+0x42 (insn after a call to __schedule()).
BUT, unwind_next_frame() tries to take the address starting from 0xffff94b50001fdc8. That is exactly from thread.sp+88-sizeof(long) = 0xffff94b50001fdc8+88-8 = 0xffff94b50001fe18, which is garbage marked as NOTE above. So this quits the unwinding as 7793fab6956b2d00 is obviously not a kernel address.
There was a fix to skip 'struct inactive_task_frame' in unwind_get_return_address_ptr in the following commit:
187b96db5ca7 ("x86/unwind/orc: Fix unwind_get_return_address_ptr() for inactive tasks")
But we need to skip the struct already in the unwinder proper. So subtract the size (increase the stack pointer) of the structure in __unwind_start() directly. This allows for removal of the code added by commit 187b96db5ca7 completely, as the address is now at '(unsigned long *)state->sp - 1', the same as in the generic case.
[ mingo: Cleaned up the changelog a bit, for better readability. ]
--- arch/x86/kernel/unwind_orc.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
arch/x86/kernel/unwind_orc.c +1 -8
@@ -320,19 +320,12 @@ EXPORT_SYMBOL_GPL(unwind_get_return_address);unsigned long *unwind_get_return_address_ptr (struct unwind_state *state) { -struct task_struct *task = state->task; -if (unwind_done (state))return NULL ;if (state->regs)return &state->regs->ip; -if (task != current && state->sp == task->thread.sp) { -struct inactive_task_frame *frame = (void *)task->thread.sp; -return &frame->ret_addr; - } -if (state->sp)return (unsigned long *)state->sp -1 ;
@@ -662,7 +655,7 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task, }else {struct inactive_task_frame *frame = (void *)task->thread.sp; - state->sp = task->thread.sp; + state->sp = task->thread.sp +sizeof (*frame); state->bp =READ_ONCE_NOCHECK (frame->bp); state->ip =READ_ONCE_NOCHECK (frame->ret_addr); state->signal = (void *)state->ip == ret_from_fork;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 19/391 firmware: arm_scmi: Fix locking in notifications
In reply to Greg Kroah-HartmanFrom: Cristian Marussi <[email protected]>
[ Upstream commit c7821c2d9c0dda0adf2bcf88e79b02a19a430be4 ]
When a protocol registers its events, the notification core takes care to rescan the hashtable of pending event handlers and activate all the possibly existent handlers referring to any of the events that are just registered by the new protocol. When a pending handler becomes active the core requests and enables the corresponding events in the SCMI firmware.
If, for whatever reason, the enable fails, such invalid event handler must be finally removed and freed. Let us ensure to use the scmi_put_active_handler() helper which handles properly the needed additional locking.
Failing to properly acquire all the needed mutexes exposes a race that leads to the following splat being observed:
WARNING: CPU: 0 PID: 388 at lib/refcount.c:28 refcount_warn_saturate+0xf8/0x148 Hardware name: ARM LTD ARM Juno Development Platform/ARM Juno Development Platform, BIOS EDK II Jun 30 2020 pstate: 40000005 (nZcv daif -PAN -UAO BTYPE=--) pc : refcount_warn_saturate+0xf8/0x148 lr : refcount_warn_saturate+0xf8/0x148 Call trace: refcount_warn_saturate+0xf8/0x148 scmi_put_handler_unlocked.isra.10+0x204/0x208 scmi_put_handler+0x50/0xa0 scmi_unregister_notifier+0x1bc/0x240 scmi_notify_tester_remove+0x4c/0x68 [dummy_scmi_consumer] scmi_dev_remove+0x54/0x68 device_release_driver_internal+0x114/0x1e8 driver_detach+0x58/0xe8 bus_remove_driver+0x88/0xe0 driver_unregister+0x38/0x68 scmi_driver_unregister+0x1c/0x28 scmi_drv_exit+0x1c/0xae0 [dummy_scmi_consumer] __arm64_sys_delete_module+0x1a4/0x268 el0_svc_common.constprop.3+0x94/0x178 do_el0_svc+0x2c/0x98 el0_sync_handler+0x148/0x1a8 el0_sync+0x158/0x180
--- drivers/firmware/arm_scmi/notify.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
drivers/firmware/arm_scmi/notify.c +13 -7
@@ -1403,15 +1403,21 @@ static void scmi_protocols_late_init(struct work_struct *work)"finalized PENDING handler - key:%X\n" , hndl->key); ret =scmi_event_handler_enable_events (hndl); +if (ret) { +dev_dbg (ni->handle->dev, +"purging INVALID handler - key:%X\n" , + hndl->key); +scmi_put_active_handler (ni, hndl); + } }else { ret =scmi_valid_pending_handler (ni, hndl); - } -if (ret) { -dev_dbg (ni->handle->dev, -"purging PENDING handler - key:%X\n" , - hndl->key); -/* this hndl can be only a pending one */ -scmi_put_handler_unlocked (ni, hndl); +if (ret) { +dev_dbg (ni->handle->dev, +"purging PENDING handler - key:%X\n" , + hndl->key); +/* this hndl can be only a pending one */ +scmi_put_handler_unlocked (ni, hndl); + } } }mutex_unlock (&ni->pending_mtx);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 20/391 firmware: arm_scmi: Fix duplicate workqueue name
In reply to Greg Kroah-HartmanFrom: Florian Fainelli <[email protected]>
[ Upstream commit b9ceca6be43233845be70792be9b5ab315d2e010 ]
When more than a single SCMI device are present in the system, the creation of the notification workqueue with the WQ_SYSFS flag will lead to the following sysfs duplicate node warning:
sysfs: cannot create duplicate filename '/devices/virtual/workqueue/scmi_notify'
CPU: 0 PID: 20 Comm: kworker/0:1 Not tainted 5.9.0-gdf4dd84a3f7d #29 Hardware name: Broadcom STB (Flattened Device Tree) Workqueue: events deferred_probe_work_func Backtrace: show_stack + 0x20/0x24 dump_stack + 0xbc/0xe0 sysfs_warn_dup + 0x70/0x80 sysfs_create_dir_ns + 0x15c/0x1a4 kobject_add_internal + 0x140/0x4d0 kobject_add + 0xc8/0x138 device_add + 0x1dc/0xc20 device_register + 0x24/0x28 workqueue_sysfs_register + 0xe4/0x1f0 alloc_workqueue + 0x448/0x6ac scmi_notification_init + 0x78/0x1dc scmi_probe + 0x268/0x4fc platform_drv_probe + 0x70/0xc8 really_probe + 0x184/0x728 driver_probe_device + 0xa4/0x278 __device_attach_driver + 0xe8/0x148 bus_for_each_drv + 0x108/0x158 __device_attach + 0x190/0x234 device_initial_probe + 0x1c/0x20 bus_probe_device + 0xdc/0xec deferred_probe_work_func + 0xd4/0x11c process_one_work + 0x420/0x8f0 worker_thread + 0x4fc/0x91c kthread + 0x21c/0x22c ret_from_fork + 0x14/0x20 kobject_add_internal failed for scmi_notify with -EEXIST, don't try to register things with the same name in the same directory. arm-scmi brcm_scmi@1: SCMI Notifications - Initialization Failed. arm-scmi brcm_scmi@1: SCMI Notifications NOT available. arm-scmi brcm_scmi@1: SCMI Protocol v1.0 'brcm-scmi:' Firmware version 0x1
Fix this by using dev_name(handle->dev) which guarantees that the name is unique and this also helps correlate which notification workqueue corresponds to which SCMI device instance.
--- drivers/firmware/arm_scmi/notify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/firmware/arm_scmi/notify.c +1 -1
@@ -1474,7 +1474,7 @@ int scmi_notification_init(struct scmi_handle *handle) ni->gid = gid; ni->handle = handle; - ni->notify_wq =alloc_workqueue ("scmi_notify" , + ni->notify_wq =alloc_workqueue (dev_name (handle->dev),WQ_UNBOUND |WQ_FREEZABLE |WQ_SYSFS ,0 );if (!ni->notify_wq)
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 21/391 x86/alternative: Dont call text_poke() in lazy TLB mode
In reply to Greg Kroah-HartmanFrom: Juergen Gross <[email protected]>
[ Upstream commit abee7c494d8c41bb388839bccc47e06247f0d7de ]
When running in lazy TLB mode the currently active page tables might be the ones of a previous process, e.g. when running a kernel thread.
This can be problematic in case kernel code is being modified via text_poke() in a kernel thread, and on another processor exit_mmap() is active for the process which was running on the first cpu before the kernel thread.
As text_poke() is using a temporary address space and the former address space (obtained via cpu_tlbstate.loaded_mm) is restored afterwards, there is a race possible in case the cpu on which exit_mmap() is running wants to make sure there are no stale references to that address space on any cpu active (this e.g. is required when running as a Xen PV guest, where this problem has been observed and analyzed).
In order to avoid that, drop off TLB lazy mode before switching to the temporary address space.
--- arch/x86/kernel/alternative.c | 9 +++++++++ 1 file changed, 9 insertions(+)
arch/x86/kernel/alternative.c +9 -0
@@ -807,6 +807,15 @@ static inline temp_mm_state_t use_temporary_mm(struct mm_struct *mm)temp_mm_state_t temp_state;lockdep_assert_irqs_disabled (); + +/* +* Make sure not to be in TLB lazy mode, as otherwise we'll end up +* with a stale address space WITHOUT being in lazy mode after +* restoring the previous mm. +*/ +if (this_cpu_read (cpu_tlbstate.is_lazy)) +leave_mm (smp_processor_id ()); + temp_state.mm =this_cpu_read (cpu_tlbstate.loaded_mm);switch_mm_irqs_off (NULL , mm, current);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 22/391 ionic: no rx flush in deinit
In reply to Greg Kroah-Hartman[ Upstream commit 43ecf7b46f2688fd37909801aee264f288b3917b ]
Kmemleak pointed out to us that ionic_rx_flush() is sending skbs into napi_gro_XXX with a disabled napi context, and these end up getting lost and leaked. We can safely remove the flush.
--- drivers/net/ethernet/pensando/ionic/ionic_lif.c | 1 - drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 13 ------------- drivers/net/ethernet/pensando/ionic/ionic_txrx.h | 1 - 3 files changed, 15 deletions(-)
drivers/net/ethernet/pensando/ionic/ionic_lif.c +0 -1
@@ -1512,7 +1512,6 @@ static void ionic_txrx_deinit(struct ionic_lif *lif)if (lif->rxqcqs) {for (i =0 ; i < lif->nxqs; i++) {ionic_lif_qcq_deinit (lif, lif->rxqcqs[i].qcq); -ionic_rx_flush (&lif->rxqcqs[i].qcq->cq);ionic_rx_empty (&lif->rxqcqs[i].qcq->q); } }
drivers/net/ethernet/pensando/ionic/ionic_txrx.c +0 -13
@@ -253,19 +253,6 @@ static bool ionic_rx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info)return true; } -void ionic_rx_flush (struct ionic_cq *cq) -{ -struct ionic_dev *idev = &cq->lif->ionic->idev; -u32 work_done; - - work_done =ionic_cq_service (cq, cq->num_descs, - ionic_rx_service,NULL ,NULL ); - -if (work_done) -ionic_intr_credits (idev->intr_ctrl, cq->bound_intr->index, - work_done,IONIC_INTR_CRED_RESET_COALESCE ); -} -static struct page *ionic_rx_page_alloc (struct ionic_queue *q,dma_addr_t *dma_addr) {
drivers/net/ethernet/pensando/ionic/ionic_txrx.h +0 -1
@@ -4,7 +4,6 @@#ifndef _IONIC_TXRX_H_#define _IONIC_TXRX_H_ -void ionic_rx_flush (struct ionic_cq *cq);void ionic_tx_flush (struct ionic_cq *cq);void ionic_rx_fill (struct ionic_queue *q);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 23/391 RDMA/mlx5: Fix devlink deadlock on net namespace deletion
In reply to Greg Kroah-HartmanFrom: Parav Pandit <[email protected]>
[ Upstream commit fbdd0049d98d44914fc57d4b91f867f4996c787b ]
When a mlx5 core devlink instance is reloaded in different net namespace, its associated IB device is deleted and recreated.
Example sequence is:
$ ip netns add foo $ devlink dev reload pci/0000:00:08.0 netns foo $ ip netns del foo
mlx5 IB device needs to attach and detach the netdevice to it through the netdev notifier chain during load and unload sequence. A below call graph of the unload flow.
cleanup_net()
down_read(&pernet_ops_rwsem); <- first sem acquired
ops_pre_exit_list()
pre_exit()
devlink_pernet_pre_exit()
devlink_reload()
mlx5_devlink_reload_down()
mlx5_unload_one()
[...]
mlx5_ib_remove()
mlx5_ib_unbind_slave_port()
mlx5_remove_netdev_notifier()
unregister_netdevice_notifier()
down_write(&pernet_ops_rwsem);<- recurrsive lockHence, when net namespace is deleted, mlx5 reload results in deadlock.
When deadlock occurs, devlink mutex is also held. This not only deadlocks the mlx5 device under reload, but all the processes which attempt to access unrelated devlink devices are deadlocked.
Hence, fix this by mlx5 ib driver to register for per net netdev notifier instead of global one, which operats on the net namespace without holding the pernet_ops_rwsem.
--- drivers/infiniband/hw/mlx5/main.c | 6 ++++-- .../net/ethernet/mellanox/mlx5/core/lib/mlx5.h | 5 ----- include/linux/mlx5/driver.h | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+), 7 deletions(-)
drivers/infiniband/hw/mlx5/main.c +4 -2
@@ -3318,7 +3318,8 @@ static int mlx5_add_netdev_notifier(struct mlx5_ib_dev *dev, u8 port_num)int err; dev->port[port_num].roce.nb.notifier_call = mlx5_netdev_event; - err =register_netdevice_notifier (&dev->port[port_num].roce.nb); + err =register_netdevice_notifier_net (mlx5_core_net (dev->mdev), + &dev->port[port_num].roce.nb);if (err) { dev->port[port_num].roce.nb.notifier_call =NULL ;return err;
@@ -3330,7 +3331,8 @@ static int mlx5_add_netdev_notifier(struct mlx5_ib_dev *dev, u8 port_num)static void mlx5_remove_netdev_notifier (struct mlx5_ib_dev *dev,u8 port_num) {if (dev->port[port_num].roce.nb.notifier_call) { -unregister_netdevice_notifier (&dev->port[port_num].roce.nb); +unregister_netdevice_notifier_net (mlx5_core_net (dev->mdev), + &dev->port[port_num].roce.nb); dev->port[port_num].roce.nb.notifier_call =NULL ; } }
drivers/net/ethernet/mellanox/mlx5/core/lib/mlx5.h +0 -5
@@ -90,9 +90,4 @@ int mlx5_create_encryption_key(struct mlx5_core_dev *mdev, u32 key_type, u32 *p_key_id);void mlx5_destroy_encryption_key (struct mlx5_core_dev *mdev,u32 key_id); -static inline struct net *mlx5_core_net (struct mlx5_core_dev *dev) -{ -return devlink_net (priv_to_devlink (dev)); -} -#endif
include/linux/mlx5/driver.h +18 -0
@@ -1212,4 +1212,22 @@ static inline bool mlx5_is_roce_enabled(struct mlx5_core_dev *dev) return val.vbool; } +/** +* mlx5_core_net - Provide net namespace of the mlx5_core_dev +* @dev: mlx5 core device +* +* mlx5_core_net() returns the net namespace of mlx5 core device. +* This can be called only in below described limited context. +* (a) When a devlink instance for mlx5_core is registered and +* when devlink reload operation is disabled. +* or +* (b) during devlink reload reload_down() and reload_up callbacks +* where it is ensured that devlink instance's net namespace is +* stable. +*/ +static inline struct net *mlx5_core_net (struct mlx5_core_dev *dev) +{ +return devlink_net (priv_to_devlink (dev)); +} +#endif /* MLX5_DRIVER_H */
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 24/391 mlxsw: core: Fix use-after-free in mlxsw_emad_trans_finish()
In reply to Greg Kroah-HartmanFrom: Amit Cohen <[email protected]>
[ Upstream commit 0daf2bf5a2dcf33d446b76360908f109816e2e21 ]
Each EMAD transaction stores the skb used to issue the EMAD request ('trans->tx_skb') so that the request could be retried in case of a timeout. The skb can be freed when a corresponding response is received or as part of the retry logic (e.g., failed retransmit, exceeded maximum number of retries).
The two tasks (i.e., response processing and retransmits) are synchronized by the atomic 'trans->active' field which ensures that responses to inactive transactions are ignored.
In case of a failed retransmit the transaction is finished and all of its resources are freed. However, the current code does not mark it as inactive. Syzkaller was able to hit a race condition in which a concurrent response is processed while the transaction's resources are being freed, resulting in a use-after-free [1].
Fix the issue by making sure to mark the transaction as inactive after a failed retransmit and free its resources only if a concurrent task did not already do that.
[1]
BUG: KASAN: use-after-free in consume_skb+0x30/0x370
net/core/skbuff.c:833
Read of size 4 at addr ffff88804f570494 by task syz-executor.0/1004
CPU: 0 PID: 1004 Comm: syz-executor.0 Not tainted 5.8.0-rc7+ #68
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0xf6/0x16e lib/dump_stack.c:118
print_address_description.constprop.0+0x1c/0x250
mm/kasan/report.c:383
__kasan_report mm/kasan/report.c:513 [inline]
kasan_report.cold+0x1f/0x37 mm/kasan/report.c:530
check_memory_region_inline mm/kasan/generic.c:186 [inline]
check_memory_region+0x14e/0x1b0 mm/kasan/generic.c:192
instrument_atomic_read include/linux/instrumented.h:56 [inline]
atomic_read include/asm-generic/atomic-instrumented.h:27 [inline]
refcount_read include/linux/refcount.h:147 [inline]
skb_unref include/linux/skbuff.h:1044 [inline]
consume_skb+0x30/0x370 net/core/skbuff.c:833
mlxsw_emad_trans_finish+0x64/0x1c0 drivers/net/ethernet/mellanox/mlxsw/core.c:592
mlxsw_emad_process_response drivers/net/ethernet/mellanox/mlxsw/core.c:651 [inline]
mlxsw_emad_rx_listener_func+0x5c9/0xac0 drivers/net/ethernet/mellanox/mlxsw/core.c:672
mlxsw_core_skb_receive+0x4df/0x770 drivers/net/ethernet/mellanox/mlxsw/core.c:2063
mlxsw_pci_cqe_rdq_handle drivers/net/ethernet/mellanox/mlxsw/pci.c:595 [inline]
mlxsw_pci_cq_tasklet+0x12a6/0x2520 drivers/net/ethernet/mellanox/mlxsw/pci.c:651
tasklet_action_common.isra.0+0x13f/0x3e0 kernel/softirq.c:550
__do_softirq+0x223/0x964 kernel/softirq.c:292
asm_call_on_stack+0x12/0x20 arch/x86/entry/entry_64.S:711
Allocated by task 1006:
save_stack+0x1b/0x40 mm/kasan/common.c:48
set_track mm/kasan/common.c:56 [inline]
__kasan_kmalloc mm/kasan/common.c:494 [inline]
__kasan_kmalloc.constprop.0+0xc2/0xd0 mm/kasan/common.c:467
slab_post_alloc_hook mm/slab.h:586 [inline]
slab_alloc_node mm/slub.c:2824 [inline]
slab_alloc mm/slub.c:2832 [inline]
kmem_cache_alloc+0xcd/0x2e0 mm/slub.c:2837
__build_skb+0x21/0x60 net/core/skbuff.c:311
__netdev_alloc_skb+0x1e2/0x360 net/core/skbuff.c:464
netdev_alloc_skb include/linux/skbuff.h:2810 [inline]
mlxsw_emad_alloc drivers/net/ethernet/mellanox/mlxsw/core.c:756 [inline]
mlxsw_emad_reg_access drivers/net/ethernet/mellanox/mlxsw/core.c:787 [inline]
mlxsw_core_reg_access_emad+0x1ab/0x1420 drivers/net/ethernet/mellanox/mlxsw/core.c:1817
mlxsw_reg_trans_query+0x39/0x50 drivers/net/ethernet/mellanox/mlxsw/core.c:1831
mlxsw_sp_sb_pm_occ_clear drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c:260 [inline]
mlxsw_sp_sb_occ_max_clear+0xbff/0x10a0 drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c:1365
mlxsw_devlink_sb_occ_max_clear+0x76/0xb0 drivers/net/ethernet/mellanox/mlxsw/core.c:1037
devlink_nl_cmd_sb_occ_max_clear_doit+0x1ec/0x280 net/core/devlink.c:1765
genl_family_rcv_msg_doit net/netlink/genetlink.c:669 [inline]
genl_family_rcv_msg net/netlink/genetlink.c:714 [inline]
genl_rcv_msg+0x617/0x980 net/netlink/genetlink.c:731
netlink_rcv_skb+0x152/0x440 net/netlink/af_netlink.c:2470
genl_rcv+0x24/0x40 net/netlink/genetlink.c:742
netlink_unicast_kernel net/netlink/af_netlink.c:1304 [inline]
netlink_unicast+0x53a/0x750 net/netlink/af_netlink.c:1330
netlink_sendmsg+0x850/0xd90 net/netlink/af_netlink.c:1919
sock_sendmsg_nosec net/socket.c:651 [inline]
sock_sendmsg+0x150/0x190 net/socket.c:671
____sys_sendmsg+0x6d8/0x840 net/socket.c:2359
___sys_sendmsg+0xff/0x170 net/socket.c:2413
__sys_sendmsg+0xe5/0x1b0 net/socket.c:2446
do_syscall_64+0x56/0xa0 arch/x86/entry/common.c:384
entry_SYSCALL_64_after_hwframe+0x44/0xa9
Freed by task 73:
save_stack+0x1b/0x40 mm/kasan/common.c:48
set_track mm/kasan/common.c:56 [inline]
kasan_set_free_info mm/kasan/common.c:316 [inline]
__kasan_slab_free+0x12c/0x170 mm/kasan/common.c:455
slab_free_hook mm/slub.c:1474 [inline]
slab_free_freelist_hook mm/slub.c:1507 [inline]
slab_free mm/slub.c:3072 [inline]
kmem_cache_free+0xbe/0x380 mm/slub.c:3088
kfree_skbmem net/core/skbuff.c:622 [inline]
kfree_skbmem+0xef/0x1b0 net/core/skbuff.c:616
__kfree_skb net/core/skbuff.c:679 [inline]
consume_skb net/core/skbuff.c:837 [inline]
consume_skb+0xe1/0x370 net/core/skbuff.c:831
mlxsw_emad_trans_finish+0x64/0x1c0 drivers/net/ethernet/mellanox/mlxsw/core.c:592
mlxsw_emad_transmit_retry.isra.0+0x9d/0xc0 drivers/net/ethernet/mellanox/mlxsw/core.c:613
mlxsw_emad_trans_timeout_work+0x43/0x50 drivers/net/ethernet/mellanox/mlxsw/core.c:625
process_one_work+0xa3e/0x17a0 kernel/workqueue.c:2269
worker_thread+0x9e/0x1050 kernel/workqueue.c:2415
kthread+0x355/0x470 kernel/kthread.c:291
ret_from_fork+0x22/0x30 arch/x86/entry/entry_64.S:293
The buggy address belongs to the object at ffff88804f5703c0
which belongs to the cache skbuff_head_cache of size 224
The buggy address is located 212 bytes inside of
224-byte region [ffff88804f5703c0, ffff88804f5704a0)
The buggy address belongs to the page:
page:ffffea00013d5c00 refcount:1 mapcount:0 mapping:0000000000000000
index:0x0
flags: 0x100000000000200(slab)
raw: 0100000000000200 dead000000000100 dead000000000122 ffff88806c625400
raw: 0000000000000000 00000000000c000c 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff88804f570380: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
ffff88804f570400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff88804f570480: fb fb fb fb fc fc fc fc fc fc fc fc fc fc fc fc
^
ffff88804f570500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff88804f570580: 00 00 00 00 00 00 00 00 00 00 00 00 fc fc fc fc--- drivers/net/ethernet/mellanox/mlxsw/core.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/core.c +3 -0
@@ -607,6 +607,9 @@ static void mlxsw_emad_transmit_retry(struct mlxsw_core *mlxsw_core, err =mlxsw_emad_transmit (trans->core, trans);if (err ==0 )return ; + +if (!atomic_dec_and_test (&trans->active)) +return ; }else { err = -EIO ; }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 25/391 tracing, synthetic events: Replace buggy strcat() with seq_buf operations
In reply to Greg Kroah-Hartman[ Upstream commit 761a8c58db6bc884994b28cd6d9707b467d680c1 ]
There was a memory corruption bug happening while running the synthetic event selftests:
kmemleak: Cannot insert 0xffff8c196fa2afe5 into the object search tree (overlaps existing)
CPU: 5 PID: 6866 Comm: ftracetest Tainted: G W 5.9.0-rc5-test+ #577
Hardware name: Hewlett-Packard HP Compaq Pro 6300 SFF/339A, BIOS K01 v03.03 07/14/2016
Call Trace:
dump_stack+0x8d/0xc0
create_object.cold+0x3b/0x60
slab_post_alloc_hook+0x57/0x510
? tracing_map_init+0x178/0x340
__kmalloc+0x1b1/0x390
tracing_map_init+0x178/0x340
event_hist_trigger_func+0x523/0xa40
trigger_process_regex+0xc5/0x110
event_trigger_write+0x71/0xd0
vfs_write+0xca/0x210
ksys_write+0x70/0xf0
do_syscall_64+0x33/0x40
entry_SYSCALL_64_after_hwframe+0x44/0xa9
RIP: 0033:0x7fef0a63a487
Code: 64 89 02 48 c7 c0 ff ff ff ff eb bb 0f 1f 80 00 00 00 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 48 89 54 24 18 48 89 74 24
RSP: 002b:00007fff76f18398 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 0000000000000039 RCX: 00007fef0a63a487
RDX: 0000000000000039 RSI: 000055eb3b26d690 RDI: 0000000000000001
RBP: 000055eb3b26d690 R08: 000000000000000a R09: 0000000000000038
R10: 000055eb3b2cdb80 R11: 0000000000000246 R12: 0000000000000039
R13: 00007fef0a70b500 R14: 0000000000000039 R15: 00007fef0a70b700
kmemleak: Kernel memory leak detector disabled
kmemleak: Object 0xffff8c196fa2afe0 (size 8):
kmemleak: comm "ftracetest", pid 6866, jiffies 4295082531
kmemleak: min_count = 1
kmemleak: count = 0
kmemleak: flags = 0x1
kmemleak: checksum = 0
kmemleak: backtrace:
__kmalloc+0x1b1/0x390
tracing_map_init+0x1be/0x340
event_hist_trigger_func+0x523/0xa40
trigger_process_regex+0xc5/0x110
event_trigger_write+0x71/0xd0
vfs_write+0xca/0x210
ksys_write+0x70/0xf0
do_syscall_64+0x33/0x40
entry_SYSCALL_64_after_hwframe+0x44/0xa9The cause came down to a use of strcat() that was adding an string that was shorten, but the strcat() did not take that into account.
strcat() is extremely dangerous as it does not care how big the buffer is. Replace it with seq_buf operations that prevent the buffer from being overwritten if what is being written is bigger than the buffer.
--- kernel/trace/trace_events_synth.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-)
kernel/trace/trace_events_synth.c +12 -11
@@ -465,6 +465,7 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,struct synth_field *field;const char *prefix =NULL , *field_type = argv[0 ], *field_name, *array;int len, ret =0 ; +struct seq_buf s;ssize_t size;if (field_type[0 ] ==';' )
@@ -503,13 +504,9 @@ static struct synth_field *parse_synth_field(int argc, const char **argv, field_type++; len =strlen (field_type) +1 ; -if (array) { -int l =strlen (array); +if (array) + len +=strlen (array); -if (l && array[l -1 ] ==';' ) - l--; - len += l; - }if (prefix) len +=strlen (prefix);
@@ -518,14 +515,18 @@ static struct synth_field *parse_synth_field(int argc, const char **argv, ret = -ENOMEM ; goto free; } +seq_buf_init (&s, field->type, len);if (prefix) -strcat (field->type, prefix); -strcat (field->type, field_type); +seq_buf_puts (&s, prefix); +seq_buf_puts (&s, field_type);if (array) { -strcat (field->type, array); -if (field->type[len -1 ] ==';' ) - field->type[len -1 ] ='\0' ; +seq_buf_puts (&s, array); +if (s.buffer[s.len -1 ] ==';' ) + s.len--; } +if (WARN_ON_ONCE (!seq_buf_buffer_left (&s))) + goto free; + s.buffer[s.len] ='\0' ; size =synth_field_size (field->type);if (size <=0 ) {
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 26/391 afs: Fix a use after free in afs_xattr_get_acl()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit 248c944e2159de4868bef558feea40214aaf8464 ]
The "op" pointer is freed earlier when we call afs_put_operation().
--- fs/afs/xattr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/afs/xattr.c +1 -1
@@ -85,7 +85,7 @@ static int afs_xattr_get_acl(const struct xattr_handler *handler,if (acl->size <= size)memcpy (buffer, acl->data, acl->size);else - op->error = -ERANGE ; + ret = -ERANGE ; } }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 27/391 afs: Fix afs_launder_page to not clear PG_writeback
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit d383e346f97d6bb0d654bb3d63c44ab106d92d29 ]
Fix afs_launder_page() to not clear PG_writeback on the page it is laundering as the flag isn't set in this case.
--- fs/afs/internal.h | 1 + fs/afs/write.c | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-)
fs/afs/internal.h +1 -0
@@ -811,6 +811,7 @@ struct afs_operation {pgoff_t last;/* last page in mapping to deal with */ unsigned first_offset;/* offset into mapping[first] */ unsigned last_to;/* amount of mapping[last] */ +bool laundering;/* Laundering page, PG_writeback not set */ } store;struct {struct iattr *attr;
fs/afs/write.c +6 -4
@@ -396,7 +396,8 @@ static void afs_store_data_success(struct afs_operation *op) op->ctime = op->file[0 ].scb.status.mtime_client;afs_vnode_commit_status (op, &op->file[0 ]);if (op->error ==0 ) { -afs_pages_written_back (vnode, op->store.first, op->store.last); +if (!op->store.laundering) +afs_pages_written_back (vnode, op->store.first, op->store.last);afs_stat_v (vnode, n_stores); atomic_long_add((op->store.last * PAGE_SIZE + op->store.last_to) - (op->store.first * PAGE_SIZE + op->store.first_offset),
@@ -415,7 +416,7 @@ static const struct afs_operation_ops afs_store_data_operation = {*/ static int afs_store_data (struct address_space *mapping,pgoff_t first,pgoff_t last, -unsigned offset,unsigned to) +unsigned offset,unsigned to,bool laundering) {struct afs_vnode *vnode =AFS_FS_I (mapping->host);struct afs_operation *op;
@@ -448,6 +449,7 @@ static int afs_store_data(struct address_space *mapping, op->store.last = last; op->store.first_offset = offset; op->store.last_to = to; + op->store.laundering = laundering; op->mtime = vnode->vfs_inode.i_mtime; op->flags |=AFS_OPERATION_UNINTR ; op->ops = &afs_store_data_operation;
@@ -601,7 +603,7 @@ no_more:if (end > i_size) to = i_size & ~PAGE_MASK ; - ret =afs_store_data (mapping, first, last, offset, to); + ret =afs_store_data (mapping, first, last, offset, to, false);switch (ret) {case 0 : ret = count;
@@ -921,7 +923,7 @@ int afs_launder_page(struct page *page)trace_afs_page_dirty (vnode,tracepoint_string ("launder" ), page->index, priv); - ret =afs_store_data (mapping, page->index, page->index, t, f); + ret =afs_store_data (mapping, page->index, page->index, t, f, true); } trace_afs_page_dirty(vnode, tracepoint_string("laundered"),
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 28/391 RDMA/qedr: Fix memory leak in iWARP CM
In reply to Greg Kroah-HartmanFrom: Alok Prasad <[email protected]>
[ Upstream commit a2267f8a52eea9096861affd463f691be0f0e8c9 ]
Fixes memory leak in iWARP CM
--- drivers/infiniband/hw/qedr/qedr_iw_cm.c | 1 + 1 file changed, 1 insertion(+)
drivers/infiniband/hw/qedr/qedr_iw_cm.c +1 -0
@@ -727,6 +727,7 @@ int qedr_iw_destroy_listen(struct iw_cm_id *cm_id) listener->qed_handle); cm_id->rem_ref (cm_id); +kfree (listener);return rc; }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 29/391 ata: sata_nv: Fix retrieving of active qcs
In reply to Greg Kroah-HartmanFrom: Sascha Hauer <[email protected]>
[ Upstream commit 8e4c309f9f33b76c09daa02b796ef87918eee494 ]
ata_qc_complete_multiple() has to be called with the tags physically active, that is the hw tag is at bit 0. ap->qc_active has the same tag at bit ATA_TAG_INTERNAL instead, so call ata_qc_get_active() to fix that up. This is done in the vein of 8385d756e114 ("libata: Fix retrieving of active qcs").
--- drivers/ata/sata_nv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ata/sata_nv.c +1 -1
@@ -2100,7 +2100,7 @@ static int nv_swncq_sdbfis(struct ata_port *ap) pp->dhfis_bits &= ~done_mask; pp->dmafis_bits &= ~done_mask; pp->sdbfis_bits |= done_mask; -ata_qc_complete_multiple (ap, ap->qc_active ^ done_mask); +ata_qc_complete_multiple (ap,ata_qc_get_active (ap) ^ done_mask);if (!ap->qc_active) {DPRINTK ("over\n" );
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 30/391 arm64: efi: increase EFI PE/COFF header padding to 64 KB
In reply to Greg Kroah-HartmanFrom: Ard Biesheuvel <[email protected]>
[ Upstream commit a2d50c1c77aa879af24f9f67b33186737b3d4885 ]
Commit 76085aff29f5 ("efi/libstub/arm64: align PE/COFF sections to segment alignment") increased the PE/COFF section alignment to match the minimum segment alignment of the kernel image, which ensures that the kernel does not need to be moved around in memory by the EFI stub if it was built as relocatable.
However, the first PE/COFF section starts at _stext, which is only 4 KB aligned, and so the section layout is inconsistent. Existing EFI loaders seem to care little about this, but it is better to clean this up.
So let's pad the header to 64 KB to match the PE/COFF section alignment.
--- arch/arm64/kernel/efi-header.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/kernel/efi-header.S +1 -1
@@ -147,6 +147,6 @@ efi_debug_entry: * correctly at this alignment, we must ensure that .text is * placed at a 4k boundary in the Image to begin with. */ - .align 12 + .balign SEGMENT_ALIGN efi_header_end: .endm
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 31/391 afs: Fix to take ref on page when PG_private is set
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit fa04a40b169fcee615afbae97f71a09332993f64 ]
Fix afs to take a ref on a page when it sets PG_private on it and to drop the ref when removing the flag.
Note that in afs_write_begin(), a lot of the time, PG_private is already set on a page to which we're going to add some data. In such a case, we leave the bit set and mustn't increment the page count.
As suggested by Matthew Wilcox, use attach/detach_page_private() where possible.
--- fs/afs/dir.c | 12 ++++-------- fs/afs/dir_edit.c | 6 ++---- fs/afs/file.c | 8 ++------ fs/afs/write.c | 18 ++++++++++-------- 4 files changed, 18 insertions(+), 26 deletions(-)
fs/afs/dir.c +4 -8
@@ -281,8 +281,7 @@ retry:if (ret <0 ) goto error; -set_page_private (req->pages[i],1 ); -SetPagePrivate (req->pages[i]); +attach_page_private (req->pages[i], (void *)1 );unlock_page (req->pages[i]); i++; }else {
@@ -1975,8 +1974,7 @@ static int afs_dir_releasepage(struct page *page, gfp_t gfp_flags)_enter ("{{%llx:%llu}[%lu]}" , dvnode->fid.vid, dvnode->fid.vnode, page->index); -set_page_private (page,0 ); -ClearPagePrivate (page); +detach_page_private (page);/* The directory will need reloading. */ if (test_and_clear_bit (AFS_VNODE_DIR_VALID , &dvnode->flags))
@@ -2003,8 +2001,6 @@ static void afs_dir_invalidatepage(struct page *page, unsigned int offset,afs_stat_v (dvnode, n_inval);/* we clean up only if the entire page is being invalidated */ -if (offset ==0 && length ==PAGE_SIZE ) { -set_page_private (page,0 ); -ClearPagePrivate (page); - } +if (offset ==0 && length ==PAGE_SIZE ) +detach_page_private (page); }
fs/afs/dir_edit.c +2 -4
@@ -243,10 +243,8 @@ void afs_edit_dir_add(struct afs_vnode *vnode, index, gfp);if (!page) goto error; -if (!PagePrivate (page)) { -set_page_private (page,1 ); -SetPagePrivate (page); - } +if (!PagePrivate (page)) +attach_page_private (page, (void *)1 ); dir_page =kmap (page); }
fs/afs/file.c +2 -6
@@ -626,11 +626,9 @@ static void afs_invalidatepage(struct page *page, unsigned int offset,#endif if (PagePrivate (page)) { - priv =page_private (page); + priv = (unsigned long )detach_page_private (page);trace_afs_page_dirty (vnode,tracepoint_string ("inval" ), page->index, priv); -set_page_private (page,0 ); -ClearPagePrivate (page); } }
@@ -660,11 +658,9 @@ static int afs_releasepage(struct page *page, gfp_t gfp_flags)#endif if (PagePrivate (page)) { - priv =page_private (page); + priv = (unsigned long )detach_page_private (page);trace_afs_page_dirty (vnode,tracepoint_string ("rel" ), page->index, priv); -set_page_private (page,0 ); -ClearPagePrivate (page); }/* indicate that the page can be released */
fs/afs/write.c +10 -8
@@ -151,8 +151,10 @@ try_again: priv |= f;trace_afs_page_dirty (vnode,tracepoint_string ("begin" ), page->index, priv); -SetPagePrivate (page); -set_page_private (page, priv); +if (PagePrivate (page)) +set_page_private (page, priv); +else +attach_page_private (page, (void *)priv);_leave (" = 0" );return 0 ;
@@ -334,10 +336,9 @@ static void afs_pages_written_back(struct afs_vnode *vnode, ASSERTCMP(pv.nr, ==, count);for (loop =0 ; loop < count; loop++) { - priv =page_private (pv.pages[loop]); + priv = (unsigned long )detach_page_private (pv.pages[loop]);trace_afs_page_dirty (vnode,tracepoint_string ("clear" ), pv.pages[loop]->index, priv); -set_page_private (pv.pages[loop],0 );end_page_writeback (pv.pages[loop]); } first += count;
@@ -863,8 +864,10 @@ vm_fault_t afs_page_mkwrite(struct vm_fault *vmf) priv |=0 ;/* From */ trace_afs_page_dirty (vnode,tracepoint_string ("mkwrite" ), vmf->page->index, priv); -SetPagePrivate (vmf->page); -set_page_private (vmf->page, priv); +if (PagePrivate (vmf->page)) +set_page_private (vmf->page, priv); +else +attach_page_private (vmf->page, (void *)priv);file_update_time (file);sb_end_pagefault (inode->i_sb);
@@ -926,10 +929,9 @@ int afs_launder_page(struct page *page) ret =afs_store_data (mapping, page->index, page->index, t, f, true); } + priv = (unsigned long )detach_page_private (page);trace_afs_page_dirty (vnode,tracepoint_string ("laundered" ), page->index, priv); -set_page_private (page,0 ); -ClearPagePrivate (page);#ifdef CONFIG_AFS_FSCACHE if (PageFsCache (page)) {
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 32/391 afs: Fix page leak on afs_write_begin() failure
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit 21db2cdc667f744691a407105b7712bc18d74023 ]
Fix the leak of the target page in afs_write_begin() when it fails.
--- fs/afs/write.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-)
fs/afs/write.c +11 -12
@@ -76,7 +76,7 @@ static int afs_fill_page(struct afs_vnode *vnode, struct key *key,*/ int afs_write_begin (struct file *file,struct address_space *mapping,loff_t pos,unsigned len,unsigned flags, -struct page **pagep,void **fsdata) +struct page **_page,void **fsdata) {struct afs_vnode *vnode =AFS_FS_I (file_inode (file));struct page *page;
@@ -110,9 +110,6 @@ int afs_write_begin(struct file *file, struct address_space *mapping,SetPageUptodate (page); } -/* page won't leak in error case: it eventually gets cleaned off LRU */ - *pagep = page; - try_again:/* See if this page is already partially written in a way that we can * merge the new write with.
@@ -155,6 +152,7 @@ try_again:set_page_private (page, priv); else attach_page_private(page, (void *)priv); + *_page = page;_leave (" = 0" );return 0 ;
@@ -164,17 +162,18 @@ try_again: flush_conflicting_write:_debug ("flush conflict" ); ret =write_one_page (page); -if (ret <0 ) { -_leave (" = %d" , ret); -return ret; - } +if (ret <0 ) + goto error; ret =lock_page_killable (page); -if (ret <0 ) { -_leave (" = %d" , ret); -return ret; - } +if (ret <0 ) + goto error; goto try_again; + +error: +put_page (page); +_leave (" = %d" , ret); +return ret; }/*
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 33/391 afs: Fix where page->private is set during write
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit f792e3ac82fe2c6c863e93187eb7ddfccab68fa7 ]
In afs, page->private is set to indicate the dirty region of a page. This is done in afs_write_begin(), but that can't take account of whether the copy into the page actually worked.
Fix this by moving the change of page->private into afs_write_end().
--- fs/afs/write.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-)
fs/afs/write.c +26 -15
@@ -135,23 +135,8 @@ try_again:if (!test_bit (AFS_VNODE_NEW_CONTENT , &vnode->flags) && (to < f || from > t)) goto flush_conflicting_write; -if (from < f) - f = from; -if (to > t) - t = to; - }else { - f = from; - t = to; } - priv = (unsigned long )t <<AFS_PRIV_SHIFT ; - priv |= f; -trace_afs_page_dirty (vnode,tracepoint_string ("begin" ), - page->index, priv); -if (PagePrivate (page)) -set_page_private (page, priv); -else -attach_page_private (page, (void *)priv); *_page = page;_leave (" = 0" );return 0 ;
@@ -185,6 +170,9 @@ int afs_write_end(struct file *file, struct address_space *mapping, {struct afs_vnode *vnode =AFS_FS_I (file_inode (file));struct key *key =afs_file_key (file); +unsigned long priv; +unsigned int f, from = pos & (PAGE_SIZE -1 ); +unsigned int t, to = from + copied;loff_t i_size, maybe_i_size;int ret;
@@ -216,6 +204,29 @@ int afs_write_end(struct file *file, struct address_space *mapping,SetPageUptodate (page); } +if (PagePrivate (page)) { + priv =page_private (page); + f = priv &AFS_PRIV_MAX ; + t = priv >>AFS_PRIV_SHIFT ; +if (from < f) + f = from; +if (to > t) + t = to; + priv = (unsigned long )t <<AFS_PRIV_SHIFT ; + priv |= f; +set_page_private (page, priv); +trace_afs_page_dirty (vnode,tracepoint_string ("dirty+" ), + page->index, priv); + }else { + f = from; + t = to; + priv = (unsigned long )t <<AFS_PRIV_SHIFT ; + priv |= f; +attach_page_private (page, (void *)priv); +trace_afs_page_dirty (vnode,tracepoint_string ("dirty" ), + page->index, priv); + } +set_page_dirty (page);if (PageDirty (page))_debug ("dirtied" );
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 34/391 afs: Wrap page->private manipulations in inline functions
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit 185f0c7073bd5c78f86265f703f5daf1306ab5a7 ]
The afs filesystem uses page->private to store the dirty range within a page such that in the event of a conflicting 3rd-party write to the server, we write back just the bits that got changed locally.
However, there are a couple of problems with this:
(1) I need a bit to note if the page might be mapped so that partial invalidation doesn't shrink the range.
(2) There aren't necessarily sufficient bits to store the entire range of data altered (say it's a 32-bit system with 64KiB pages or transparent huge pages are in use).
So wrap the accesses in inline functions so that future commits can change how this works.
Also move them out of the tracing header into the in-directory header. There's not really any need for them to be in the tracing header.
--- fs/afs/internal.h | 28 ++++++++++++++++++++++++++++ fs/afs/write.c | 31 +++++++++++++------------------ include/trace/events/afs.h | 19 +++---------------- 3 files changed, 44 insertions(+), 34 deletions(-)
fs/afs/internal.h +28 -0
@@ -857,6 +857,34 @@ struct afs_vnode_cache_aux {u64 data_version; } __packed; +/* +* We use page->private to hold the amount of the page that we've written to, +* splitting the field into two parts. However, we need to represent a range +* 0...PAGE_SIZE inclusive, so we can't support 64K pages on a 32-bit system. +*/ +#if PAGE_SIZE >32768 +#define __AFS_PAGE_PRIV_MASK 0xffffffffUL +#define __AFS_PAGE_PRIV_SHIFT 32 +#else +#define __AFS_PAGE_PRIV_MASK 0xffffUL +#define __AFS_PAGE_PRIV_SHIFT 16 +#endif + +static inline size_t afs_page_dirty_from (unsigned long priv) +{ +return priv & __AFS_PAGE_PRIV_MASK; +} + +static inline size_t afs_page_dirty_to (unsigned long priv) +{ +return (priv >> __AFS_PAGE_PRIV_SHIFT) & __AFS_PAGE_PRIV_MASK; +} + +static inline unsigned long afs_page_dirty (size_t from,size_t to) +{ +return ((unsigned long )to << __AFS_PAGE_PRIV_SHIFT) | from; +} +#include <trace/events/afs.h> /*****************************************************************************/
fs/afs/write.c +13 -18
@@ -117,8 +117,8 @@ try_again: t = f =0 ;if (PagePrivate (page)) { priv =page_private (page); - f = priv &AFS_PRIV_MAX ; - t = priv >>AFS_PRIV_SHIFT ; + f =afs_page_dirty_from (priv); + t =afs_page_dirty_to (priv); ASSERTCMP(f, <=, t); }
@@ -206,22 +206,18 @@ int afs_write_end(struct file *file, struct address_space *mapping,if (PagePrivate (page)) { priv =page_private (page); - f = priv &AFS_PRIV_MAX ; - t = priv >>AFS_PRIV_SHIFT ; + f =afs_page_dirty_from (priv); + t =afs_page_dirty_to (priv);if (from < f) f = from;if (to > t) t = to; - priv = (unsigned long )t <<AFS_PRIV_SHIFT ; - priv |= f; + priv =afs_page_dirty (f, t);set_page_private (page, priv);trace_afs_page_dirty (vnode,tracepoint_string ("dirty+" ), page->index, priv); }else { - f = from; - t = to; - priv = (unsigned long )t <<AFS_PRIV_SHIFT ; - priv |= f; + priv =afs_page_dirty (from, to);attach_page_private (page, (void *)priv);trace_afs_page_dirty (vnode,tracepoint_string ("dirty" ), page->index, priv);
@@ -522,8 +518,8 @@ static int afs_write_back_from_locked_page(struct address_space *mapping,*/ start = primary_page->index; priv =page_private (primary_page); - offset = priv &AFS_PRIV_MAX ; - to = priv >>AFS_PRIV_SHIFT ; + offset =afs_page_dirty_from (priv); + to =afs_page_dirty_to (priv);trace_afs_page_dirty (vnode,tracepoint_string ("store" ), primary_page->index, priv);
@@ -568,8 +564,8 @@ static int afs_write_back_from_locked_page(struct address_space *mapping, } priv =page_private (page); - f = priv &AFS_PRIV_MAX ; - t = priv >>AFS_PRIV_SHIFT ; + f =afs_page_dirty_from (priv); + t =afs_page_dirty_to (priv);if (f !=0 && !test_bit (AFS_VNODE_NEW_CONTENT , &vnode->flags)) {unlock_page (page);
@@ -870,8 +866,7 @@ vm_fault_t afs_page_mkwrite(struct vm_fault *vmf)*/ wait_on_page_writeback (vmf->page); - priv = (unsigned long )PAGE_SIZE <<AFS_PRIV_SHIFT ;/* To */ - priv |=0 ;/* From */ + priv =afs_page_dirty (0 ,PAGE_SIZE );trace_afs_page_dirty (vnode,tracepoint_string ("mkwrite" ), vmf->page->index, priv);if (PagePrivate (vmf->page))
@@ -930,8 +925,8 @@ int afs_launder_page(struct page *page) f =0 ; t =PAGE_SIZE ;if (PagePrivate (page)) { - f = priv &AFS_PRIV_MAX ; - t = priv >>AFS_PRIV_SHIFT ; + f =afs_page_dirty_from (priv); + t =afs_page_dirty_to (priv); } trace_afs_page_dirty(vnode, tracepoint_string("launder"),
include/trace/events/afs.h +3 -16
@@ -884,19 +884,6 @@ TRACE_EVENT(afs_dir_check_failed, __entry->vnode, __entry->off, __entry->i_size) ); -/* -* We use page->private to hold the amount of the page that we've written to, -* splitting the field into two parts. However, we need to represent a range -* 0...PAGE_SIZE inclusive, so we can't support 64K pages on a 32-bit system. -*/ -#if PAGE_SIZE >32768 -#define AFS_PRIV_MAX 0xffffffff -#define AFS_PRIV_SHIFT 32 -#else -#define AFS_PRIV_MAX 0xffff -#define AFS_PRIV_SHIFT 16 -#endif - TRACE_EVENT(afs_page_dirty, TP_PROTO(struct afs_vnode *vnode, const char *where, pgoff_t page, unsigned long priv),
@@ -917,10 +904,10 @@ TRACE_EVENT(afs_page_dirty, __entry->priv = priv; ), -TP_printk ("vn=%p %lx %s %lu-%lu" , +TP_printk ("vn=%p %lx %s %zx-%zx" , __entry->vnode, __entry->page, __entry->where, - __entry->priv &AFS_PRIV_MAX , - __entry->priv >>AFS_PRIV_SHIFT ) +afs_page_dirty_from (__entry->priv), +afs_page_dirty_to (__entry->priv)) ); TRACE_EVENT(afs_call_state,
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 35/391 afs: Alter dirty range encoding in page->private
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit 65dd2d6072d393a3aa14ded8afa9a12f27d9c8ad ]
Currently, page->private on an afs page is used to store the range of dirtied data within the page, where the range includes the lower bound, but excludes the upper bound (e.g. 0-1 is a range covering a single byte).
This, however, requires a superfluous bit for the last-byte bound so that on a 4KiB page, it can say 0-4096 to indicate the whole page, the idea being that having both numbers the same would indicate an empty range. This is unnecessary as the PG_private bit is clear if it's an empty range (as is PG_dirty).
Alter the way the dirty range is encoded in page->private such that the upper bound is reduced by 1 (e.g. 0-0 is then specified the same single byte range mentioned above).
Applying this to both bounds frees up two bits, one of which can be used in a future commit.
This allows the afs filesystem to be compiled on ppc32 with 64K pages; without this, the following warnings are seen:
../fs/afs/internal.h: In function 'afs_page_dirty_to':../fs/afs/internal.h:881:15: warning: right shift count >= width of type [-Wshift-count-overflow]
881 | return (priv >> __AFS_PAGE_PRIV_SHIFT) & __AFS_PAGE_PRIV_MASK;
| ^~../fs/afs/internal.h: In function 'afs_page_dirty':../fs/afs/internal.h:886:28: warning: left shift count >= width of type [-Wshift-count-overflow]
886 | return ((unsigned long)to << __AFS_PAGE_PRIV_SHIFT) | from;
| ^~
--- fs/afs/internal.h | 6 +++--- fs/afs/write.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
fs/afs/internal.h +3 -3
@@ -862,7 +862,7 @@ struct afs_vnode_cache_aux {* splitting the field into two parts. However, we need to represent a range * 0...PAGE_SIZE inclusive, so we can't support 64K pages on a 32-bit system. */ -#if PAGE_SIZE >32768 +#ifdef CONFIG_64BIT #define __AFS_PAGE_PRIV_MASK 0xffffffffUL#define __AFS_PAGE_PRIV_SHIFT 32#else
@@ -877,12 +877,12 @@ static inline size_t afs_page_dirty_from(unsigned long priv)static inline size_t afs_page_dirty_to (unsigned long priv) { -return (priv >> __AFS_PAGE_PRIV_SHIFT) & __AFS_PAGE_PRIV_MASK; +return ((priv >> __AFS_PAGE_PRIV_SHIFT) & __AFS_PAGE_PRIV_MASK) +1 ; }static inline unsigned long afs_page_dirty (size_t from,size_t to) { -return ((unsigned long )to << __AFS_PAGE_PRIV_SHIFT) | from; +return ((unsigned long )(to -1 ) << __AFS_PAGE_PRIV_SHIFT) | from; }#include <trace/events/afs.h>
fs/afs/write.c +1 -1
@@ -93,7 +93,7 @@ int afs_write_begin(struct file *file, struct address_space *mapping,/* We want to store information about how much of a page is altered in * page->private. */ -BUILD_BUG_ON (PAGE_SIZE >32768 &&sizeof (page->private) <8 ); +BUILD_BUG_ON (PAGE_SIZE -1 > __AFS_PAGE_PRIV_MASK &&sizeof (page->private) <8 ); page =grab_cache_page_write_begin (mapping, index, flags);if (!page)
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 36/391 afs: Fix afs_invalidatepage to adjust the dirty region
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit f86726a69dec5df6ba051baf9265584419478b64 ]
Fix afs_invalidatepage() to adjust the dirty region recorded in page->private when truncating a page. If the dirty region is entirely removed, then the private data is cleared and the page dirty state is cleared.
Without this, if the page is truncated and then expanded again by truncate, zeros from the expanded, but no-longer dirty region may get written back to the server if the page gets laundered due to a conflicting 3rd-party write.
It mustn't, however, shorten the dirty region of the page if that page is still mmapped and has been marked dirty by afs_page_mkwrite(), so a flag is stored in page->private to record this.
--- fs/afs/file.c | 71 ++++++++++++++++++++++++++++++++------ fs/afs/internal.h | 16 +++++++-- fs/afs/write.c | 1 + include/trace/events/afs.h | 5 +-- 4 files changed, 79 insertions(+), 14 deletions(-)
fs/afs/file.c +61 -10
@@ -600,6 +600,63 @@ static int afs_readpages(struct file *file, struct address_space *mapping,return ret; } +/* +* Adjust the dirty region of the page on truncation or full invalidation, +* getting rid of the markers altogether if the region is entirely invalidated. +*/ +static void afs_invalidate_dirty (struct page *page,unsigned int offset, +unsigned int length) +{ +struct afs_vnode *vnode =AFS_FS_I (page->mapping->host); +unsigned long priv; +unsigned int f, t, end = offset + length; + + priv =page_private (page); + +/* we clean up only if the entire page is being invalidated */ +if (offset ==0 && length ==thp_size (page)) + goto full_invalidate; + +/* If the page was dirtied by page_mkwrite(), the PTE stays writable +* and we don't get another notification to tell us to expand it +* again. +*/ +if (afs_is_page_dirty_mmapped (priv)) +return ; + +/* We may need to shorten the dirty region */ + f =afs_page_dirty_from (priv); + t =afs_page_dirty_to (priv); + +if (t <= offset || f >= end) +return ;/* Doesn't overlap */ + +if (f < offset && t > end) +return ;/* Splits the dirty region - just absorb it */ + +if (f >= offset && t <= end) + goto undirty; + +if (f < offset) + t = offset; +else + f = end; +if (f == t) + goto undirty; + + priv =afs_page_dirty (f, t); +set_page_private (page, priv); +trace_afs_page_dirty (vnode,tracepoint_string ("trunc" ), page->index, priv); +return ; + +undirty: +trace_afs_page_dirty (vnode,tracepoint_string ("undirty" ), page->index, priv); +clear_page_dirty_for_io (page); +full_invalidate: + priv = (unsigned long )detach_page_private (page); +trace_afs_page_dirty (vnode,tracepoint_string ("inval" ), page->index, priv); +} +/* * invalidate part or all of a page * - release a page and clean up its private data if offset is 0 (indicating
@@ -608,29 +665,23 @@ static int afs_readpages(struct file *file, struct address_space *mapping,static void afs_invalidatepage (struct page *page,unsigned int offset,unsigned int length) { -struct afs_vnode *vnode =AFS_FS_I (page->mapping->host); -unsigned long priv; -_enter ("{%lu},%u,%u" , page->index, offset, length);BUG_ON (!PageLocked (page)); +#ifdef CONFIG_AFS_FSCACHE /* we clean up only if the entire page is being invalidated */ if (offset ==0 && length ==PAGE_SIZE ) { -#ifdef CONFIG_AFS_FSCACHE if (PageFsCache (page)) {struct afs_vnode *vnode =AFS_FS_I (page->mapping->host);fscache_wait_on_page_write (vnode->cache, page);fscache_uncache_page (vnode->cache, page); } + }#endif -if (PagePrivate (page)) { - priv = (unsigned long )detach_page_private (page); -trace_afs_page_dirty (vnode,tracepoint_string ("inval" ), - page->index, priv); - } - } +if (PagePrivate (page)) +afs_invalidate_dirty (page, offset, length);_leave ("" ); }
fs/afs/internal.h +14 -2
@@ -863,11 +863,13 @@ struct afs_vnode_cache_aux {* 0...PAGE_SIZE inclusive, so we can't support 64K pages on a 32-bit system. */ #ifdef CONFIG_64BIT -#define __AFS_PAGE_PRIV_MASK 0xffffffffUL +#define __AFS_PAGE_PRIV_MASK 0x7fffffffUL#define __AFS_PAGE_PRIV_SHIFT 32 +#define __AFS_PAGE_PRIV_MMAPPED 0x80000000UL#else -#define __AFS_PAGE_PRIV_MASK 0xffffUL +#define __AFS_PAGE_PRIV_MASK 0x7fffUL#define __AFS_PAGE_PRIV_SHIFT 16 +#define __AFS_PAGE_PRIV_MMAPPED 0x8000UL#endif static inline size_t afs_page_dirty_from (unsigned long priv)
@@ -885,6 +887,16 @@ static inline unsigned long afs_page_dirty(size_t from, size_t to)return ((unsigned long )(to -1 ) << __AFS_PAGE_PRIV_SHIFT) | from; } +static inline unsigned long afs_page_dirty_mmapped (unsigned long priv) +{ +return priv | __AFS_PAGE_PRIV_MMAPPED; +} + +static inline bool afs_is_page_dirty_mmapped (unsigned long priv) +{ +return priv & __AFS_PAGE_PRIV_MMAPPED; +} +#include <trace/events/afs.h> /*****************************************************************************/
fs/afs/write.c +1 -0
@@ -867,6 +867,7 @@ vm_fault_t afs_page_mkwrite(struct vm_fault *vmf)wait_on_page_writeback (vmf->page); priv =afs_page_dirty (0 ,PAGE_SIZE ); + priv =afs_page_dirty_mmapped (priv);trace_afs_page_dirty (vnode,tracepoint_string ("mkwrite" ), vmf->page->index, priv);if (PagePrivate (vmf->page))
include/trace/events/afs.h +3 -2
@@ -904,10 +904,11 @@ TRACE_EVENT(afs_page_dirty, __entry->priv = priv; ), -TP_printk ("vn=%p %lx %s %zx-%zx" , +TP_printk ("vn=%p %lx %s %zx-%zx%s" , __entry->vnode, __entry->page, __entry->where,afs_page_dirty_from (__entry->priv), -afs_page_dirty_to (__entry->priv)) +afs_page_dirty_to (__entry->priv), +afs_is_page_dirty_mmapped (__entry->priv) ?" M" :"" ) ); TRACE_EVENT(afs_call_state,
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 37/391 afs: Fix dirty-region encoding on ppc32 with 64K pages
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit 2d9900f26ad61e63a34f239bc76c80d2f8a6ff41 ]
The dirty region bounds stored in page->private on an afs page are 15 bits on a 32-bit box and can, at most, represent a range of up to 32K within a 32K page with a resolution of 1 byte. This is a problem for powerpc32 with 64K pages enabled.
Further, transparent huge pages may get up to 2M, which will be a problem for the afs filesystem on all 32-bit arches in the future.
Fix this by decreasing the resolution. For the moment, a 64K page will have a resolution determined from PAGE_SIZE. In the future, the page will need to be passed in to the helper functions so that the page size can be assessed and the resolution determined dynamically.
Note that this might not be the ideal way to handle this, since it may allow some leakage of undirtied zero bytes to the server's copy in the case of a 3rd-party conflict. Fixing that would require a separately allocated record and is a more complicated fix.
--- fs/afs/internal.h | 24 ++++++++++++++++++++---- fs/afs/write.c | 5 ----- 2 files changed, 20 insertions(+), 9 deletions(-)
fs/afs/internal.h +20 -4
@@ -860,7 +860,8 @@ struct afs_vnode_cache_aux {/* * We use page->private to hold the amount of the page that we've written to, * splitting the field into two parts. However, we need to represent a range -* 0...PAGE_SIZE inclusive, so we can't support 64K pages on a 32-bit system. +* 0...PAGE_SIZE, so we reduce the resolution if the size of the page +* exceeds what we can encode. */ #ifdef CONFIG_64BIT #define __AFS_PAGE_PRIV_MASK 0x7fffffffUL
@@ -872,19 +873,34 @@ struct afs_vnode_cache_aux {#define __AFS_PAGE_PRIV_MMAPPED 0x8000UL#endif +static inline unsigned int afs_page_dirty_resolution (void ) +{ +int shift =PAGE_SHIFT - (__AFS_PAGE_PRIV_SHIFT -1 ); +return (shift >0 ) ? shift :0 ; +} +static inline size_t afs_page_dirty_from (unsigned long priv) { -return priv & __AFS_PAGE_PRIV_MASK; +unsigned long x = priv & __AFS_PAGE_PRIV_MASK; + +/* The lower bound is inclusive */ +return x <<afs_page_dirty_resolution (); }static inline size_t afs_page_dirty_to (unsigned long priv) { -return ((priv >> __AFS_PAGE_PRIV_SHIFT) & __AFS_PAGE_PRIV_MASK) +1 ; +unsigned long x = (priv >> __AFS_PAGE_PRIV_SHIFT) & __AFS_PAGE_PRIV_MASK; + +/* The upper bound is immediately beyond the region */ +return (x +1 ) <<afs_page_dirty_resolution (); }static inline unsigned long afs_page_dirty (size_t from,size_t to) { -return ((unsigned long )(to -1 ) << __AFS_PAGE_PRIV_SHIFT) | from; +unsigned int res =afs_page_dirty_resolution (); + from >>= res; + to = (to -1 ) >> res; +return (to << __AFS_PAGE_PRIV_SHIFT) | from; }static inline unsigned long afs_page_dirty_mmapped (unsigned long priv)
fs/afs/write.c +0 -5
@@ -90,11 +90,6 @@ int afs_write_begin(struct file *file, struct address_space *mapping,_enter ("{%llx:%llu},{%lx},%u,%u" , vnode->fid.vid, vnode->fid.vnode, index, from, to); -/* We want to store information about how much of a page is altered in -* page->private. -*/ -BUILD_BUG_ON (PAGE_SIZE -1 > __AFS_PAGE_PRIV_MASK &&sizeof (page->private) <8 ); - page =grab_cache_page_write_begin (mapping, index, flags);if (!page)return -ENOMEM ;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 38/391 vdpasim: fix MAC address configuration
In reply to Greg Kroah-HartmanFrom: Laurent Vivier <[email protected]>
[ Upstream commit 4a6a42db53aae049a8a64d4b273761bc80c46ebf ]
vdpa_sim generates a ramdom MAC address but it is never used by upper layers because the VIRTIO_NET_F_MAC bit is not set in the features list.
Because of that, virtio-net always regenerates a random MAC address each time it is loaded whereas the address should only change on vdpa_sim load/unload.
Fix that by adding VIRTIO_NET_F_MAC in the features list of vdpa_sim.
--- drivers/vdpa/vdpa_sim/vdpa_sim.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/vdpa/vdpa_sim/vdpa_sim.c +2 -1
@@ -60,7 +60,8 @@ struct vdpasim_virtqueue {static u64 vdpasim_features = (1ULL <<VIRTIO_F_ANY_LAYOUT ) | (1ULL <<VIRTIO_F_VERSION_1 ) | - (1ULL <<VIRTIO_F_ACCESS_PLATFORM ); + (1ULL <<VIRTIO_F_ACCESS_PLATFORM ) | + (1ULL <<VIRTIO_NET_F_MAC );/* State of each vdpasim device */ struct vdpasim {
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 39/391 interconnect: qcom: sdm845: Enable keepalive for the MM1 BCM
In reply to Greg Kroah-HartmanFrom: Georgi Djakov <[email protected]>
[ Upstream commit 5be1805dc3961ce0465bcb0beab85fe8580af08d ]
After enabling interconnect scaling for display on the db845c board, in certain configurations the board hangs, while the following errors are observed on the console:
Error sending AMC RPMH requests (-110)
qcom_rpmh TCS Busy, retrying RPMH message send: addr=0x50000 qcom_rpmh TCS Busy, retrying RPMH message send: addr=0x50000 qcom_rpmh TCS Busy, retrying RPMH message send: addr=0x50000
...
In this specific case, the above is related to one of the sequencers being stuck, while client drivers are returning from probe and trying to disable the currently unused clock and interconnect resources. Generally we want to keep the multimedia NoC enabled like the rest of the NoCs, so let's set the keepalive flag on it too.
--- drivers/interconnect/qcom/sdm845.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/interconnect/qcom/sdm845.c +1 -1
@@ -151,7 +151,7 @@ DEFINE_QBCM(bcm_mc0, "MC0", true, &ebi);DEFINE_QBCM (bcm_sh0,"SH0" , true, &qns_llcc);DEFINE_QBCM (bcm_mm0,"MM0" , false, &qns_mem_noc_hf);DEFINE_QBCM (bcm_sh1,"SH1" , false, &qns_apps_io); -DEFINE_QBCM (bcm_mm1,"MM1" , false, &qxm_camnoc_hf0_uncomp, &qxm_camnoc_hf1_uncomp, &qxm_camnoc_sf_uncomp, &qxm_camnoc_hf0, &qxm_camnoc_hf1, &qxm_mdp0, &qxm_mdp1); +DEFINE_QBCM (bcm_mm1,"MM1" , true, &qxm_camnoc_hf0_uncomp, &qxm_camnoc_hf1_uncomp, &qxm_camnoc_sf_uncomp, &qxm_camnoc_hf0, &qxm_camnoc_hf1, &qxm_mdp0, &qxm_mdp1);DEFINE_QBCM (bcm_sh2,"SH2" , false, &qns_memnoc_snoc);DEFINE_QBCM (bcm_mm2,"MM2" , false, &qns2_mem_noc);DEFINE_QBCM (bcm_sh3,"SH3" , false, &acm_tcu);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 40/391 lockdep: Fix preemption WARN for spurious IRQ-enable
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
[ Upstream commit f8e48a3dca060e80f672d398d181db1298fbc86c ]
It is valid (albeit uncommon) to call local_irq_enable() without first having called local_irq_disable(). In this case we enter lockdep_hardirqs_on*() with IRQs enabled and trip a preemption warning for using __this_cpu_read().
Use this_cpu_read() instead to avoid the warning.
--- kernel/locking/lockdep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/locking/lockdep.c +2 -2
@@ -3681,7 +3681,7 @@ void lockdep_hardirqs_on_prepare(unsigned long ip)if (unlikely (in_nmi ()))return ; -if (unlikely (__this_cpu_read (lockdep_recursion))) +if (unlikely (this_cpu_read (lockdep_recursion)))return ;if (unlikely (lockdep_hardirqs_enabled ())) {
@@ -3750,7 +3750,7 @@ void noinstr lockdep_hardirqs_on(unsigned long ip) goto skip_checks; } -if (unlikely (__this_cpu_read (lockdep_recursion))) +if (unlikely (this_cpu_read (lockdep_recursion)))return ;if (lockdep_hardirqs_enabled ()) {
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 41/391 usb: host: ehci-tegra: Fix error handling in tegra_ehci_probe()
In reply to Greg Kroah-HartmanFrom: Tang Bin <[email protected]>
[ Upstream commit 32d174d2d5eb318c34ff36771adefabdf227c186 ]
If the function platform_get_irq() failed, the negative value returned will not be detected here. So fix error handling in tegra_ehci_probe().
--- drivers/usb/host/ehci-tegra.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/host/ehci-tegra.c +2 -2
@@ -479,8 +479,8 @@ static int tegra_ehci_probe(struct platform_device *pdev) u_phy->otg->host =hcd_to_bus (hcd); irq =platform_get_irq (pdev,0 ); -if (!irq) { - err = -ENODEV ; +if (irq <0 ) { + err = irq; goto cleanup_phy; }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 42/391 futex: Fix incorrect should_fail_futex() handling
In reply to Greg Kroah-HartmanFrom: Mateusz Nosek <[email protected]>
[ Upstream commit 921c7ebd1337d1a46783d7e15a850e12aed2eaa0 ]
If should_futex_fail() returns true in futex_wake_pi(), then the 'ret' variable is set to -EFAULT and then immediately overwritten. So the failure injection is non-functional.
Fix it by actually leaving the function and returning -EFAULT.
The Fixes tag is kinda blury because the initial commit which introduced failure injection was already sloppy, but the below mentioned commit broke it completely.
[ tglx: Massaged changelog ]
--- kernel/futex.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
kernel/futex.c +3 -1
@@ -1502,8 +1502,10 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_pi_state *pi_*/ newval =FUTEX_WAITERS |task_pid_vnr (new_owner); -if (unlikely (should_fail_futex (true))) +if (unlikely (should_fail_futex (true))) { ret = -EFAULT ; + goto out_unlock; + } ret =cmpxchg_futex_value_locked (&curval, uaddr, uval, newval);if (!ret && (curval != uval)) {
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 43/391 powerpc/vmemmap: Fix memory leak with vmemmap list allocation failures.
In reply to Greg Kroah-HartmanFrom: Aneesh Kumar K.V <[email protected]>
[ Upstream commit ccaea15296f9773abd43aaa17ee4b88848e4a505 ]
If we fail to allocate vmemmap list, we don't keep track of allocated vmemmap block buf. Hence on section deactivate we skip vmemmap block buf free. This results in memory leak.
--- arch/powerpc/mm/init_64.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-)
arch/powerpc/mm/init_64.c +28 -7
@@ -162,16 +162,16 @@ static __meminit struct vmemmap_backing * vmemmap_list_alloc(int node)return next++; } -static __meminit void vmemmap_list_populate (unsigned long phys, -unsigned long start, -int node) +static __meminit int vmemmap_list_populate (unsigned long phys, +unsigned long start, +int node) {struct vmemmap_backing *vmem_back; vmem_back =vmemmap_list_alloc (node);if (unlikely (!vmem_back)) { -WARN_ON (1 ); -return ; +pr_debug ("vmemap list allocation failed\n" ); +return -ENOMEM ; } vmem_back->phys = phys;
@@ -179,6 +179,7 @@ static __meminit void vmemmap_list_populate(unsigned long phys, vmem_back->list = vmemmap_list; vmemmap_list = vmem_back; +return 0 ; } static bool altmap_cross_boundary(struct vmem_altmap *altmap, unsigned long start,
@@ -199,6 +200,7 @@ static bool altmap_cross_boundary(struct vmem_altmap *altmap, unsigned long starint __meminit vmemmap_populate (unsigned long start,unsigned long end,int node,struct vmem_altmap *altmap) { +bool altmap_alloc;unsigned long page_size =1 << mmu_psize_defs[mmu_vmemmap_psize].shift;/* Align to the page size of the linear mapping. */
@@ -228,13 +230,32 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node, p =vmemmap_alloc_block_buf (page_size, node, altmap);if (!p)pr_debug ("altmap block allocation failed, falling back to system memory" ); +else + altmap_alloc = true; } -if (!p) +if (!p) { p =vmemmap_alloc_block_buf (page_size, node,NULL ); + altmap_alloc = false; + }if (!p)return -ENOMEM ; -vmemmap_list_populate (__pa (p), start, node); +if (vmemmap_list_populate (__pa (p), start, node)) { +/* +* If we don't populate vmemap list, we don't have +* the ability to free the allocated vmemmap +* pages in section_deactivate. Hence free them +* here. +*/ +int nr_pfns = page_size >>PAGE_SHIFT ; +unsigned long page_order =get_order (page_size); + +if (altmap_alloc) +vmem_altmap_free (altmap, nr_pfns); +else +free_pages ((unsigned long )p, page_order); +return -ENOMEM ; + }pr_debug (" * %016lx..%016lx allocated at %p\n" , start, start + page_size, p);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 44/391 powerpc/powernv/smp: Fix spurious DBG() warning
In reply to Greg Kroah-HartmanFrom: Oliver O'Halloran <[email protected]>
[ Upstream commit f6bac19cf65c5be21d14a0c9684c8f560f2096dd ]
When building with W=1 we get the following warning:
arch/powerpc/platforms/powernv/smp.c: In function ‘pnv_smp_cpu_kill_self’:
arch/powerpc/platforms/powernv/smp.c:276:16: error: suggest braces around
empty body in an ‘if’ statement [-Werror=empty-body]
276 | cpu, srr1);
| ^
cc1: all warnings being treated as errors
The full context is this block:
if (srr1 && !generic_check_cpu_restart(cpu))
DBG("CPU%d Unexpected exit while offline srr1=%lx!\n",
cpu, srr1);
When building with DEBUG undefined DBG() expands to nothing and GCC emits the warning due to the lack of braces around an empty statement.
--- arch/powerpc/platforms/powernv/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/platforms/powernv/smp.c +1 -1
@@ -43,7 +43,7 @@#include <asm/udbg.h> #define DBG(fmt...) udbg_printf(fmt)#else -#define DBG(fmt...) +#define DBG(fmt...) do { } while (0)#endif static void pnv_smp_setup_cpu (int cpu)
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 45/391 RDMA/core: Change how failing destroy is handled during uobj abort
In reply to Greg Kroah-HartmanFrom: Jason Gunthorpe <[email protected]>
[ Upstream commit f553246f7f794675da1794ae7ee07d1f35e561ae ]
Currently it triggers a WARN_ON and then goes ahead and destroys the uobject anyhow, leaking any driver memory.
The only place that leaks driver memory should be during FD close() in uverbs_destroy_ufile_hw().
Drivers are only allowed to fail destroy uobjects if they guarantee destroy will eventually succeed. uverbs_destroy_ufile_hw() provides the loop to give the driver that chance.
--- drivers/infiniband/core/rdma_core.c | 30 ++++++++++++++--------------- include/rdma/ib_verbs.h | 5 ----- 2 files changed, 15 insertions(+), 20 deletions(-)
drivers/infiniband/core/rdma_core.c +15 -15
@@ -130,17 +130,6 @@ static int uverbs_destroy_uobject(struct ib_uobject *uobj,lockdep_assert_held (&ufile->hw_destroy_rwsem);assert_uverbs_usecnt (uobj,UVERBS_LOOKUP_WRITE ); -if (reason ==RDMA_REMOVE_ABORT_HWOBJ ) { - reason =RDMA_REMOVE_ABORT ; - ret = uobj->uapi_object->type_class->destroy_hw (uobj, reason, - attrs); -/* -* Drivers are not permitted to ignore RDMA_REMOVE_ABORT, see -* ib_is_destroy_retryable, cleanup_retryable == false here. -*/ -WARN_ON (ret); - } -if (reason ==RDMA_REMOVE_ABORT ) {WARN_ON (!list_empty (&uobj->list));WARN_ON (!uobj->context);
@@ -674,11 +663,22 @@ void rdma_alloc_abort_uobject(struct ib_uobject *uobj, bool hw_obj_valid) {struct ib_uverbs_file *ufile = uobj->ufile; +int ret; + +if (hw_obj_valid) { + ret = uobj->uapi_object->type_class->destroy_hw ( + uobj,RDMA_REMOVE_ABORT , attrs); +/* +* If the driver couldn't destroy the object then go ahead and +* commit it. Leaking objects that can't be destroyed is only +* done during FD close after the driver has a few more tries to +* destroy it. +*/ +if (WARN_ON (ret)) +return rdma_alloc_commit_uobject (uobj, attrs); + } -uverbs_destroy_uobject (uobj, - hw_obj_valid ?RDMA_REMOVE_ABORT_HWOBJ : -RDMA_REMOVE_ABORT , - attrs); +uverbs_destroy_uobject (uobj,RDMA_REMOVE_ABORT , attrs);/* Matches the down_read in rdma_alloc_begin_uobject */ up_read (&ufile->hw_destroy_rwsem);
include/rdma/ib_verbs.h +0 -5
@@ -1463,11 +1463,6 @@ enum rdma_remove_reason {RDMA_REMOVE_DRIVER_REMOVE ,/* uobj is being cleaned-up before being committed */ RDMA_REMOVE_ABORT, -/* -* uobj has been fully created, with the uobj->object set, but is being -* cleaned up before being comitted -*/ - RDMA_REMOVE_ABORT_HWOBJ, }; struct ib_rdmacg_object {
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 46/391 f2fs: allocate proper size memory for zstd decompress
In reply to Greg Kroah-HartmanFrom: Chao Yu <[email protected]>
[ Upstream commit 0e2b7385cb59e566520cfd0a04b4b53bc9461e98 ]
As 5kft <[email protected]> reported:
kworker/u9:3: page allocation failure: order:9, mode:0x40c40(GFP_NOFS|__GFP_COMP), nodemask=(null),cpuset=/,mems_allowed=0
CPU: 3 PID: 8168 Comm: kworker/u9:3 Tainted: G C 5.8.3-sunxi #trunk Hardware name: Allwinner sun8i Family Workqueue: f2fs_post_read_wq f2fs_post_read_work [<c010d6d5>] (unwind_backtrace) from [<c0109a55>] (show_stack+0x11/0x14) [<c0109a55>] (show_stack) from [<c056d489>] (dump_stack+0x75/0x84) [<c056d489>] (dump_stack) from [<c0243b53>] (warn_alloc+0xa3/0x104) [<c0243b53>] (warn_alloc) from [<c024473b>] (__alloc_pages_nodemask+0xb87/0xc40) [<c024473b>] (__alloc_pages_nodemask) from [<c02267c5>] (kmalloc_order+0x19/0x38) [<c02267c5>] (kmalloc_order) from [<c02267fd>] (kmalloc_order_trace+0x19/0x90) [<c02267fd>] (kmalloc_order_trace) from [<c047c665>] (zstd_init_decompress_ctx+0x21/0x88) [<c047c665>] (zstd_init_decompress_ctx) from [<c047e9cf>] (f2fs_decompress_pages+0x97/0x228) [<c047e9cf>] (f2fs_decompress_pages) from [<c045d0ab>] (__read_end_io+0xfb/0x130) [<c045d0ab>] (__read_end_io) from [<c045d141>] (f2fs_post_read_work+0x61/0x84) [<c045d141>] (f2fs_post_read_work) from [<c0130b2f>] (process_one_work+0x15f/0x3b0) [<c0130b2f>] (process_one_work) from [<c0130e7b>] (worker_thread+0xfb/0x3e0) [<c0130e7b>] (worker_thread) from [<c0135c3b>] (kthread+0xeb/0x10c) [<c0135c3b>] (kthread) from [<c0100159>]
zstd may allocate large size memory for {,de}compression, it may cause file copy failure on low-end device which has very few memory.
For decompression, let's just allocate proper size memory based on current file's cluster size instead of max cluster size.
--- fs/f2fs/compress.c | 7 ++++--- fs/f2fs/f2fs.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-)
fs/f2fs/compress.c +4 -3
@@ -382,16 +382,17 @@ static int zstd_init_decompress_ctx(struct decompress_io_ctx *dic)ZSTD_DStream *stream;void *workspace;unsigned int workspace_size; +unsigned int max_window_size = +MAX_COMPRESS_WINDOW_SIZE (dic->log_cluster_size); - workspace_size =ZSTD_DStreamWorkspaceBound (MAX_COMPRESS_WINDOW_SIZE ); + workspace_size =ZSTD_DStreamWorkspaceBound (max_window_size); workspace =f2fs_kvmalloc (F2FS_I_SB (dic->inode), workspace_size,GFP_NOFS );if (!workspace)return -ENOMEM ; - stream =ZSTD_initDStream (MAX_COMPRESS_WINDOW_SIZE , - workspace, workspace_size); + stream =ZSTD_initDStream (max_window_size, workspace, workspace_size);if (!stream) { printk_ratelimited("%sF2FS-fs (%s): %s ZSTD_initDStream failed\n", KERN_ERR, F2FS_I_SB(dic->inode)->sb->s_id,
fs/f2fs/f2fs.h +1 -1
@@ -1394,7 +1394,7 @@ struct decompress_io_ctx {#define NULL_CLUSTER ((unsigned int)(~0))#define MIN_COMPRESS_LOG_SIZE 2#define MAX_COMPRESS_LOG_SIZE 8 -#define MAX_COMPRESS_WINDOW_SIZE ((PAGE_SIZE) << MAX_COMPRESS_LOG_SIZE) +#define MAX_COMPRESS_WINDOW_SIZE (log_size) ((PAGE_SIZE) << (log_size))struct f2fs_sb_info {struct super_block *sb;/* pointer to VFS super block */
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 47/391 powerpc/watchpoint/ptrace: Fix SETHWDEBUG when CONFIG_HAVE_HW_BREAKPOINT=N
In reply to Greg Kroah-HartmanFrom: Ravi Bangoria <[email protected]>
[ Upstream commit 9b6b7c680cc20971444d9f836e49fc98848bcd0a ]
When kernel is compiled with CONFIG_HAVE_HW_BREAKPOINT=N, user can still create watchpoint using PPC_PTRACE_SETHWDEBUG, with limited functionalities. But, such watchpoints are never firing because of the missing privilege settings. Fix that.
It's safe to set HW_BRK_TYPE_PRIV_ALL because we don't really leak any kernel address in signal info. Setting HW_BRK_TYPE_PRIV_ALL will also help to find scenarios when kernel accesses user memory.
--- arch/powerpc/kernel/ptrace/ptrace-noadv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/kernel/ptrace/ptrace-noadv.c +1 -1
@@ -217,7 +217,7 @@ long ppc_set_hwdebug(struct task_struct *child, struct ppc_hw_breakpoint *bp_infreturn -EIO ; brk.address =ALIGN_DOWN (bp_info->addr,HW_BREAKPOINT_SIZE ); - brk.type =HW_BRK_TYPE_TRANSLATE ; + brk.type =HW_BRK_TYPE_TRANSLATE |HW_BRK_TYPE_PRIV_ALL ; brk.len =DABR_MAX_LEN ; brk.hw_len =DABR_MAX_LEN ;if (bp_info->trigger_type &PPC_BREAKPOINT_TRIGGER_READ )
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 48/391 mm: fix exec activate_mm vs TLB shootdown and lazy tlb switching race
In reply to Greg Kroah-HartmanFrom: Nicholas Piggin <[email protected]>
[ Upstream commit d53c3dfb23c45f7d4f910c3a3ca84bf0a99c6143 ]
Reading and modifying current->mm and current->active_mm and switching mm should be done with irqs off, to prevent races seeing an intermediate state.
This is similar to commit 38cf307c1f20 ("mm: fix kthread_use_mm() vs TLB invalidate"). At exec-time when the new mm is activated, the old one should usually be single-threaded and no longer used, unless something else is holding an mm_users reference (which may be possible).
Absent other mm_users, there is also a race with preemption and lazy tlb switching. Consider the kernel_execve case where the current thread is using a lazy tlb active mm:
call_usermodehelper()
kernel_execve()
old_mm = current->mm;
active_mm = current->active_mm;
*** preempt *** --------------------> schedule()
prev->active_mm = NULL;
mmdrop(prev active_mm);
...
<-------------------- schedule()
current->mm = mm;
current->active_mm = mm;
if (!old_mm)
mmdrop(active_mm);If we switch back to the kernel thread from a different mm, there is a double free of the old active_mm, and a missing free of the new one.
Closing this race only requires interrupts to be disabled while ->mm and ->active_mm are being switched, but the TLB problem requires also holding interrupts off over activate_mm. Unfortunately not all archs can do that yet, e.g., arm defers the switch if irqs are disabled and expects finish_arch_post_lock_switch() to be called to complete the flush; um takes a blocking lock in activate_mm().
So as a first step, disable interrupts across the mm/active_mm updates to close the lazy tlb preempt race, and provide an arch option to extend that to activate_mm which allows architectures doing IPI based TLB shootdowns to close the second race.
This is a bit ugly, but in the interest of fixing the bug and backporting before all architectures are converted this is a compromise.
--- arch/Kconfig | 7 +++++++ fs/exec.c | 17 +++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-)
arch/Kconfig +7 -0
@@ -414,6 +414,13 @@ config MMU_GATHER_NO_GATHER bool depends on MMU_GATHER_TABLE_FREE +config ARCH_WANT_IRQS_OFF_ACTIVATE_MM + bool + help + Temporary select until all architectures can be converted to have + irqs disabled over activate_mm. Architectures that do IPI based TLB + shootdowns should enable this. + config ARCH_HAVE_NMI_SAFE_CMPXCHG bool
fs/exec.c +15 -2
@@ -1131,11 +1131,24 @@ static int exec_mmap(struct mm_struct *mm) }task_lock (tsk); - active_mm = tsk->active_mm;membarrier_exec_mmap (mm); - tsk->mm = mm; + +local_irq_disable (); + active_mm = tsk->active_mm; tsk->active_mm = mm; + tsk->mm = mm; +/* +* This prevents preemption while active_mm is being loaded and +* it and mm are being updated, which could cause problems for +* lazy tlb mm refcounting when these are updated by context +* switches. Not all architectures can handle irqs off over +* activate_mm yet. +*/ +if (!IS_ENABLED (CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM )) +local_irq_enable ();activate_mm (active_mm, mm); +if (IS_ENABLED (CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM )) +local_irq_enable (); tsk->mm->vmacache_seqnum =0 ;vmacache_flush (tsk);task_unlock (tsk);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 49/391 powerpc: select ARCH_WANT_IRQS_OFF_ACTIVATE_MM
In reply to Greg Kroah-HartmanFrom: Nicholas Piggin <[email protected]>
[ Upstream commit 66acd46080bd9e5ad2be4b0eb1d498d5145d058e ]
powerpc uses IPIs in some situations to switch a kernel thread away from a lazy tlb mm, which is subject to the TLB flushing race described in the changelog introducing ARCH_WANT_IRQS_OFF_ACTIVATE_MM.
--- arch/powerpc/Kconfig | 1 + arch/powerpc/include/asm/mmu_context.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
arch/powerpc/Kconfig +1 -0
@@ -148,6 +148,7 @@ config PPC select ARCH_USE_QUEUED_RWLOCKS if PPC_QUEUED_SPINLOCKS select ARCH_USE_QUEUED_SPINLOCKS if PPC_QUEUED_SPINLOCKS select ARCH_WANT_IPC_PARSE_VERSION + select ARCH_WANT_IRQS_OFF_ACTIVATE_MM select ARCH_WEAK_RELEASE_ACQUIRE select BINFMT_ELF select BUILDTIME_TABLE_SORT
arch/powerpc/include/asm/mmu_context.h +1 -1
@@ -244,7 +244,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,*/ static inline void activate_mm (struct mm_struct *prev,struct mm_struct *next) { -switch_mm (prev, next, current); +switch_mm_irqs_off (prev, next, current); }/* We don't currently use enter_lazy_tlb() for anything */
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 50/391 sparc64: remove mm_cpumask clearing to fix kthread_use_mm race
In reply to Greg Kroah-HartmanFrom: Nicholas Piggin <[email protected]>
[ Upstream commit bafb056ce27940c9994ea905336aa8f27b4f7275 ]
The de facto (and apparently uncommented) standard for using an mm had, thanks to this code in sparc if nothing else, been that you must have a reference on mm_users *and that reference must have been obtained with mmget()*, i.e., from a thread with a reference to mm_users that had used the mm.
The introduction of mmget_not_zero() in commit d2005e3f41d4 ("userfaultfd: don't pin the user memory in userfaultfd_file_create()") allowed mm_count holders to aoperate on user mappings asynchronously from the actual threads using the mm, but they were not to load those mappings into their TLB (i.e., walking vmas and page tables is okay, kthread_use_mm() is not).
io_uring 2b188cc1bb857 ("Add io_uring IO interface") added code which does a kthread_use_mm() from a mmget_not_zero() refcount.
The problem with this is code which previously assumed mm == current->mm and mm->mm_users == 1 implies the mm will remain single-threaded at least until this thread creates another mm_users reference, has now broken.
arch/sparc/kernel/smp_64.c:
if (atomic_read(&mm->mm_users) == 1) {
cpumask_copy(mm_cpumask(mm), cpumask_of(cpu));
goto local_flush_and_out;
}vs fs/io_uring.c
if (unlikely(!(ctx->flags & IORING_SETUP_SQPOLL) ||
!mmget_not_zero(ctx->sqo_mm)))
return -EFAULT;
kthread_use_mm(ctx->sqo_mm);mmget_not_zero() could come in right after the mm_users == 1 test, then kthread_use_mm() which sets its CPU in the mm_cpumask. That update could be lost if cpumask_copy() occurs afterward.
I propose we fix this by allowing mmget_not_zero() to be a first-class reference, and not have this obscure undocumented and unchecked restriction.
The basic fix for sparc64 is to remove its mm_cpumask clearing code. The optimisation could be effectively restored by sending IPIs to mm_cpumask members and having them remove themselves from mm_cpumask. This is more tricky so I leave it as an exercise for someone with a sparc64 SMP. powerpc has a (currently similarly broken) example.
--- arch/sparc/kernel/smp_64.c | 65 ++++++++------------------------------ 1 file changed, 14 insertions(+), 51 deletions(-)
arch/sparc/kernel/smp_64.c +14 -51
@@ -1039,38 +1039,9 @@ void smp_fetch_global_pmu(void)* are flush_tlb_*() routines, and these run after flush_cache_*() * which performs the flushw. * -* The SMP TLB coherency scheme we use works as follows: -* -* 1) mm->cpu_vm_mask is a bit mask of which cpus an address -* space has (potentially) executed on, this is the heuristic -* we use to avoid doing cross calls. -* -* Also, for flushing from kswapd and also for clones, we -* use cpu_vm_mask as the list of cpus to make run the TLB. -* -* 2) TLB context numbers are shared globally across all processors -* in the system, this allows us to play several games to avoid -* cross calls. -* -* One invariant is that when a cpu switches to a process, and -* that processes tsk->active_mm->cpu_vm_mask does not have the -* current cpu's bit set, that tlb context is flushed locally. -* -* If the address space is non-shared (ie. mm->count == 1) we avoid -* cross calls when we want to flush the currently running process's -* tlb state. This is done by clearing all cpu bits except the current -* processor's in current->mm->cpu_vm_mask and performing the -* flush locally only. This will force any subsequent cpus which run -* this task to flush the context from the local tlb if the process -* migrates to another cpu (again). -* -* 3) For shared address spaces (threads) and swapping we bite the -* bullet for most cases and perform the cross call (but only to -* the cpus listed in cpu_vm_mask). -* -* The performance gain from "optimizing" away the cross call for threads is -* questionable (in theory the big win for threads is the massive sharing of -* address space state across processors). +* mm->cpu_vm_mask is a bit mask of which cpus an address +* space has (potentially) executed on, this is the heuristic +* we use to limit cross calls. */ /* This currently is only used by the hugetlb arch pre-fault
@@ -1080,18 +1051,13 @@ void smp_fetch_global_pmu(void)void smp_flush_tlb_mm (struct mm_struct *mm) {u32 ctx =CTX_HWBITS (mm->context); -int cpu =get_cpu (); -if (atomic_read (&mm->mm_users) ==1 ) { -cpumask_copy (mm_cpumask (mm),cpumask_of (cpu)); - goto local_flush_and_out; - } +get_cpu ();smp_cross_call_masked (&xcall_flush_tlb_mm, ctx,0 ,0 ,mm_cpumask (mm)); -local_flush_and_out:__flush_tlb_mm (ctx,SECONDARY_CONTEXT );put_cpu ();
@@ -1114,17 +1080,15 @@ void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long {u32 ctx =CTX_HWBITS (mm->context);struct tlb_pending_info info; -int cpu =get_cpu (); + +get_cpu (); info.ctx = ctx; info.nr = nr; info.vaddrs = vaddrs; -if (mm == current->mm &&atomic_read (&mm->mm_users) ==1 ) -cpumask_copy (mm_cpumask (mm),cpumask_of (cpu)); -else -smp_call_function_many (mm_cpumask (mm), tlb_pending_func, - &info,1 ); +smp_call_function_many (mm_cpumask (mm), tlb_pending_func, + &info,1 );__flush_tlb_pending (ctx, nr, vaddrs);
@@ -1134,14 +1098,13 @@ void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned longvoid smp_flush_tlb_page (struct mm_struct *mm,unsigned long vaddr) {unsigned long context =CTX_HWBITS (mm->context); -int cpu =get_cpu (); -if (mm == current->mm &&atomic_read (&mm->mm_users) ==1 ) -cpumask_copy (mm_cpumask (mm),cpumask_of (cpu)); -else -smp_cross_call_masked (&xcall_flush_tlb_page, - context, vaddr,0 , -mm_cpumask (mm)); +get_cpu (); + +smp_cross_call_masked (&xcall_flush_tlb_page, + context, vaddr,0 , +mm_cpumask (mm)); +__flush_tlb_page (context, vaddr);put_cpu ();
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 51/391 f2fs: add trace exit in exception path
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit 9b66482282888d02832b7d90239e1cdb18e4b431 ]
Missing the trace exit in f2fs_sync_dirty_inodes
--- fs/f2fs/checkpoint.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
fs/f2fs/checkpoint.c +5 -1
@@ -1047,8 +1047,12 @@ int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)get_pages (sbi, is_dir ? F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA)); retry: -if (unlikely (f2fs_cp_error (sbi))) +if (unlikely (f2fs_cp_error (sbi))) { +trace_f2fs_sync_dirty_inodes_exit (sbi->sb, is_dir, +get_pages (sbi, is_dir ? +F2FS_DIRTY_DENTS :F2FS_DIRTY_DATA ));return -EIO ; + }spin_lock (&sbi->inode_lock[type]);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 52/391 f2fs: do sanity check on zoned block device path
In reply to Greg Kroah-HartmanFrom: Chao Yu <[email protected]>
[ Upstream commit 07eb1d699452de04e9d389ff17fb8fc9e975d7bf ]
sbi->devs would be initialized only if image enables multiple device feature or blkzoned feature, if blkzoned feature flag was set by fuzz in non-blkzoned device, we will suffer below panic:
get_zone_idx fs/f2fs/segment.c:4892 [inline] f2fs_usable_zone_blks_in_seg fs/f2fs/segment.c:4943 [inline] f2fs_usable_blks_in_seg+0x39b/0xa00 fs/f2fs/segment.c:4999 Call Trace: check_block_count+0x69/0x4e0 fs/f2fs/segment.h:704 build_sit_entries fs/f2fs/segment.c:4403 [inline] f2fs_build_segment_manager+0x51da/0xa370 fs/f2fs/segment.c:5100 f2fs_fill_super+0x3880/0x6ff0 fs/f2fs/super.c:3684 mount_bdev+0x32e/0x3f0 fs/super.c:1417 legacy_get_tree+0x105/0x220 fs/fs_context.c:592 vfs_get_tree+0x89/0x2f0 fs/super.c:1547 do_new_mount fs/namespace.c:2896 [inline] path_mount+0x12ae/0x1e70 fs/namespace.c:3216 do_mount fs/namespace.c:3229 [inline] __do_sys_mount fs/namespace.c:3437 [inline] __se_sys_mount fs/namespace.c:3414 [inline] __x64_sys_mount+0x27f/0x300 fs/namespace.c:3414 do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46
Add sanity check to inconsistency on factors: blkzoned flag, device path and device character to avoid above panic.
--- fs/f2fs/super.c | 6 ++++++ 1 file changed, 6 insertions(+)
fs/f2fs/super.c +6 -0
@@ -2832,6 +2832,12 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, segment_count, dev_seg_count);return -EFSCORRUPTED ; } + }else { +if (__F2FS_HAS_FEATURE (raw_super,F2FS_FEATURE_BLKZONED ) && + !bdev_is_zoned (sbi->sb->s_bdev)) { +f2fs_info (sbi,"Zoned block device path is missing" ); +return -EFSCORRUPTED ; + } }if (secs_per_zone > total_sections || !secs_per_zone) {
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 53/391 f2fs: fix uninit-value in f2fs_lookup
In reply to Greg Kroah-HartmanFrom: Chao Yu <[email protected]>
[ Upstream commit 6d7ab88a98c1b7a47c228f8ffb4f44d631eaf284 ]
As syzbot reported:
Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x21c/0x280 lib/dump_stack.c:118 kmsan_report+0xf7/0x1e0 mm/kmsan/kmsan_report.c:122 __msan_warning+0x58/0xa0 mm/kmsan/kmsan_instr.c:219 f2fs_lookup+0xe05/0x1a80 fs/f2fs/namei.c:503 lookup_open fs/namei.c:3082 [inline] open_last_lookups fs/namei.c:3177 [inline] path_openat+0x2729/0x6a90 fs/namei.c:3365 do_filp_open+0x2b8/0x710 fs/namei.c:3395 do_sys_openat2+0xa88/0x1140 fs/open.c:1168 do_sys_open fs/open.c:1184 [inline] __do_compat_sys_openat fs/open.c:1242 [inline] __se_compat_sys_openat+0x2a4/0x310 fs/open.c:1240 __ia32_compat_sys_openat+0x56/0x70 fs/open.c:1240 do_syscall_32_irqs_on arch/x86/entry/common.c:80 [inline] __do_fast_syscall_32+0x129/0x180 arch/x86/entry/common.c:139 do_fast_syscall_32+0x6a/0xc0 arch/x86/entry/common.c:162 do_SYSENTER_32+0x73/0x90 arch/x86/entry/common.c:205 entry_SYSENTER_compat_after_hwframe+0x4d/0x5c
In f2fs_lookup(), @res_page could be used before being initialized, because in __f2fs_find_entry(), once F2FS_I(dir)->i_current_depth was been fuzzed to zero, then @res_page will never be initialized, causing this kmsan warning, relocating @res_page initialization place to fix this bug.
--- fs/f2fs/dir.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
fs/f2fs/dir.c +3 -5
@@ -357,16 +357,15 @@ struct f2fs_dir_entry *__f2fs_find_entry(struct inode *dir,unsigned int max_depth;unsigned int level; + *res_page =NULL ; +if (f2fs_has_inline_dentry (dir)) { - *res_page =NULL ; de =f2fs_find_in_inline_dir (dir, fname, res_page); goto out; } -if (npages ==0 ) { - *res_page =NULL ; +if (npages ==0 ) goto out; - } max_depth =F2FS_I (dir)->i_current_depth;if (unlikely (max_depth >MAX_DIR_HASH_DEPTH )) {
@@ -377,7 +376,6 @@ struct f2fs_dir_entry *__f2fs_find_entry(struct inode *dir, }for (level =0 ; level < max_depth; level++) { - *res_page =NULL ; de =find_in_level (dir, level, fname, res_page);if (de ||IS_ERR (*res_page))break ;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 54/391 f2fs: fix to check segment boundary during SIT page readahead
In reply to Greg Kroah-HartmanFrom: Chao Yu <[email protected]>
[ Upstream commit 6a257471fa42c8c9c04a875cd3a2a22db148e0f0 ]
As syzbot reported:
kernel BUG at fs/f2fs/segment.h:657!
invalid opcode: 0000 [#1] PREEMPT SMP KASAN
CPU: 1 PID: 16220 Comm: syz-executor.0 Not tainted 5.9.0-rc5-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:f2fs_ra_meta_pages+0xa51/0xdc0 fs/f2fs/segment.h:657 Call Trace: build_sit_entries fs/f2fs/segment.c:4195 [inline] f2fs_build_segment_manager+0x4b8a/0xa3c0 fs/f2fs/segment.c:4779 f2fs_fill_super+0x377d/0x6b80 fs/f2fs/super.c:3633 mount_bdev+0x32e/0x3f0 fs/super.c:1417 legacy_get_tree+0x105/0x220 fs/fs_context.c:592 vfs_get_tree+0x89/0x2f0 fs/super.c:1547 do_new_mount fs/namespace.c:2875 [inline] path_mount+0x1387/0x2070 fs/namespace.c:3192 do_mount fs/namespace.c:3205 [inline] __do_sys_mount fs/namespace.c:3413 [inline] __se_sys_mount fs/namespace.c:3390 [inline] __x64_sys_mount+0x27f/0x300 fs/namespace.c:3390 do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46 entry_SYSCALL_64_after_hwframe+0x44/0xa9
@blkno in f2fs_ra_meta_pages could exceed max segment count, causing panic in following sanity check in current_sit_addr(), add check condition to avoid this issue.
--- fs/f2fs/checkpoint.c | 2 ++ 1 file changed, 2 insertions(+)
fs/f2fs/checkpoint.c +2 -0
@@ -243,6 +243,8 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, blkno * NAT_ENTRY_PER_BLOCK);break ;case META_SIT : +if (unlikely (blkno >=TOTAL_SEGS (sbi))) + goto out;/* get sit block addr */ fio.new_blkaddr =current_sit_addr (sbi, blkno *SIT_ENTRY_PER_BLOCK );
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 55/391 s390/startup: avoid save_area_sync overflow
In reply to Greg Kroah-HartmanFrom: Vasily Gorbik <[email protected]>
[ Upstream commit 2835c2ea95d50625108e47a459e1a47f6be836ce ]
Currently we overflow save_area_sync and write over save_area_async. Although this is not a real problem make startup_pgm_check_handler consistent with late pgm check handler and store [%r0,%r7] directly into gpregs_save_area.
--- arch/s390/boot/head.S | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
arch/s390/boot/head.S +11 -10
@@ -360,22 +360,23 @@ ENTRY(startup_kdump) # the save area and does disabled wait with a faulty address. # ENTRY(startup_pgm_check_handler) - stmg %r0,%r15,__LC_SAVE_AREA_SYNC - la %r1,4095 - stctg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r1) - mvc __LC_GPREGS_SAVE_AREA-4095(128,%r1),__LC_SAVE_AREA_SYNC - mvc __LC_PSW_SAVE_AREA-4095(16,%r1),__LC_PGM_OLD_PSW + stmg %r8,%r15,__LC_SAVE_AREA_SYNC + la %r8,4095 + stctg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r8) + stmg %r0,%r7,__LC_GPREGS_SAVE_AREA-4095(%r8) + mvc __LC_GPREGS_SAVE_AREA-4095+64(64,%r8),__LC_SAVE_AREA_SYNC + mvc __LC_PSW_SAVE_AREA-4095(16,%r8),__LC_PGM_OLD_PSW mvc __LC_RETURN_PSW(16),__LC_PGM_OLD_PSW ni __LC_RETURN_PSW,0xfc # remove IO and EX bits ni __LC_RETURN_PSW+1,0xfb # remove MCHK bit oi __LC_RETURN_PSW+1,0x2 # set wait state bit - larl %r2,.Lold_psw_disabled_wait - stg %r2,__LC_PGM_NEW_PSW+8 - l %r15,.Ldump_info_stack-.Lold_psw_disabled_wait(%r2) + larl %r9,.Lold_psw_disabled_wait + stg %r9,__LC_PGM_NEW_PSW+8 + l %r15,.Ldump_info_stack-.Lold_psw_disabled_wait(%r9) brasl %r14,print_pgm_check_info .Lold_psw_disabled_wait: - la %r1,4095 - lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1) + la %r8,4095 + lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r8) lpswe __LC_RETURN_PSW # disabled wait .Ldump_info_stack: .long 0x5000 + PAGE_SIZE - STACK_FRAME_OVERHEAD
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 56/391 f2fs: compress: fix to disallow enabling compress on non-empty file
In reply to Greg Kroah-HartmanFrom: Chao Yu <[email protected]>
[ Upstream commit 519a5a2f37b850f4eb86674a10d143088670a390 ]
Compressed inode and normal inode has different layout, so we should disallow enabling compress on non-empty file to avoid race condition during inode .i_addr array parsing and updating.
--- fs/f2fs/file.c | 2 ++ 1 file changed, 2 insertions(+)
fs/f2fs/file.c +2 -0
@@ -1836,6 +1836,8 @@ static int f2fs_setflags_common(struct inode *inode, u32 iflags, u32 mask)if (iflags &F2FS_COMPR_FL ) {if (!f2fs_may_compress (inode))return -EINVAL ; +if (S_ISREG (inode->i_mode) && inode->i_size) +return -EINVAL ;set_compress_context (inode); }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 57/391 s390/ap/zcrypt: revisit ap and zcrypt error handling
In reply to Greg Kroah-HartmanFrom: Harald Freudenberger <[email protected]>
[ Upstream commit e0332629e33d1926c93348d918aaaf451ef9a16b ]
Revisit the ap queue error handling: Based on discussions and evaluatios with the firmware folk here is now a rework of the response code handling for all the AP instructions. The idea is to distinguish between failures because of some kind of invalid request where a retry does not make any sense and a failure where another attempt to send the very same request may succeed. The first case is handled by returning EINVAL to the userspace application. The second case results in retries within the zcrypt API controlled by a per message retry counter.
Revisit the zcrpyt error handling: Similar here, based on discussions with the firmware people here comes a rework of the handling of all the reply codes. Main point here is that there are only very few cases left, where a zcrypt device queue is switched to offline. It should never be the case that an AP reply message is 'unknown' to the device driver as it indicates a total mismatch between device driver and crypto card firmware. In all other cases, the code distinguishes between failure because of invalid message (see above - EINVAL) or failures of the infrastructure (see above - EAGAIN).
--- drivers/s390/crypto/ap_bus.h | 1 + drivers/s390/crypto/ap_queue.c | 8 +-- drivers/s390/crypto/zcrypt_debug.h | 8 +++ drivers/s390/crypto/zcrypt_error.h | 88 +++++++++--------------- drivers/s390/crypto/zcrypt_msgtype50.c | 50 +++++++------- drivers/s390/crypto/zcrypt_msgtype6.c | 92 +++++++++++++------------- 6 files changed, 116 insertions(+), 131 deletions(-)
drivers/s390/crypto/ap_bus.h +1 -0
@@ -50,6 +50,7 @@ static inline int ap_test_bit(unsigned int *ptr, unsigned int nr)#define AP_RESPONSE_NO_FIRST_PART 0x13#define AP_RESPONSE_MESSAGE_TOO_BIG 0x15#define AP_RESPONSE_REQ_FAC_NOT_INST 0x16 +#define AP_RESPONSE_INVALID_DOMAIN 0x42/* * Known device types
drivers/s390/crypto/ap_queue.c +3 -5
@@ -237,6 +237,9 @@ static enum ap_sm_wait ap_sm_write(struct ap_queue *aq)case AP_RESPONSE_RESET_IN_PROGRESS : aq->sm_state =AP_SM_STATE_RESET_WAIT ;return AP_SM_WAIT_TIMEOUT ; +case AP_RESPONSE_INVALID_DOMAIN : +AP_DBF (DBF_WARN ,"AP_RESPONSE_INVALID_DOMAIN on NQAP\n" ); + fallthrough;case AP_RESPONSE_MESSAGE_TOO_BIG :case AP_RESPONSE_REQ_FAC_NOT_INST :list_del_init (&ap_msg->list);
@@ -278,11 +281,6 @@ static enum ap_sm_wait ap_sm_reset(struct ap_queue *aq) aq->sm_state =AP_SM_STATE_RESET_WAIT ; aq->interrupt =AP_INTR_DISABLED ;return AP_SM_WAIT_TIMEOUT ; -case AP_RESPONSE_BUSY : -return AP_SM_WAIT_TIMEOUT ; -case AP_RESPONSE_Q_NOT_AVAIL : -case AP_RESPONSE_DECONFIGURED : -case AP_RESPONSE_CHECKSTOPPED :default : aq->sm_state =AP_SM_STATE_BORKED ;return AP_SM_WAIT_NONE ;
drivers/s390/crypto/zcrypt_debug.h +8 -0
@@ -21,6 +21,14 @@#define ZCRYPT_DBF (...) \ debug_sprintf_event(zcrypt_dbf_info, ##__VA_ARGS__) +#define ZCRYPT_DBF_ERR (...) \ + debug_sprintf_event(zcrypt_dbf_info, DBF_ERR, ##__VA_ARGS__) +#define ZCRYPT_DBF_WARN (...) \ + debug_sprintf_event(zcrypt_dbf_info, DBF_WARN, ##__VA_ARGS__) +#define ZCRYPT_DBF_INFO (...) \ + debug_sprintf_event(zcrypt_dbf_info, DBF_INFO, ##__VA_ARGS__) +#define ZCRYPT_DBF_DBG (...) \ + debug_sprintf_event(zcrypt_dbf_info, DBF_DEBUG, ##__VA_ARGS__)extern debug_info_t *zcrypt_dbf_info;
drivers/s390/crypto/zcrypt_error.h +32 -56
124 lines not on this page · raw message
drivers/s390/crypto/zcrypt_msgtype50.c +26 -24
82 lines not on this page · raw message
drivers/s390/crypto/zcrypt_msgtype6.c +46 -46
131 lines not on this page · raw message
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 58/391 um: change sigio_spinlock to a mutex
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
[ Upstream commit f2d05059e15af3f70502074f4e3a504530af504a ]
Lockdep complains at boot:
=============================
[ BUG: Invalid wait context ]
5.7.0-05093-g46d91ecd597b #98 Not tainted
-----------------------------
swapper/1 is trying to lock:0000000060931b98 (&desc[i].request_mutex){+.+.}-{3:3}, at: __setup_irq+0x11d/0x623 other info that might help us debug this:
context-{4:4}
1 lock held by swapper/1:
#0: 000000006074fed8 (sigio_spinlock){+.+.}-{2:2}, at: sigio_lock+0x1a/0x1c
stack backtrace: CPU: 0 PID: 1 Comm: swapper Not tainted 5.7.0-05093-g46d91ecd597b #98 Stack: 7fa4fab0 6028dfd1 0000002a 6008bea5 7fa50700 7fa50040 7fa4fac0 6028e016 7fa4fb50 6007f6da 60959c18 00000000 Call Trace: [<60023a0e>] show_stack+0x13b/0x155 [<6028e016>] dump_stack+0x2a/0x2c [<6007f6da>] __lock_acquire+0x515/0x15f2 [<6007eb50>] lock_acquire+0x245/0x273 [<6050d9f1>] __mutex_lock+0xbd/0x325 [<6050dc76>] mutex_lock_nested+0x1d/0x1f [<6008e27e>] __setup_irq+0x11d/0x623 [<6008e8ed>] request_threaded_irq+0x169/0x1a6 [<60021eb0>] um_request_irq+0x1ee/0x24b [<600234ee>] write_sigio_irq+0x3b/0x76 [<600383ca>] sigio_broken+0x146/0x2e4 [<60020bd8>] do_one_initcall+0xde/0x281
Because we hold sigio_spinlock and then get into requesting an interrupt with a mutex.
Change the spinlock to a mutex to avoid that.
--- arch/um/kernel/sigio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/um/kernel/sigio.c +3 -3
@@ -35,14 +35,14 @@ int write_sigio_irq(int fd) }/* These are called from os-Linux/sigio.c to protect its pollfds arrays. */ -static DEFINE_SPINLOCK (sigio_spinlock); +static DEFINE_MUTEX (sigio_mutex);void sigio_lock (void ) { -spin_lock (&sigio_spinlock); +mutex_lock (&sigio_mutex); }void sigio_unlock (void ) { -spin_unlock (&sigio_spinlock); +mutex_unlock (&sigio_mutex); }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 59/391 f2fs: handle errors of f2fs_get_meta_page_nofail
In reply to Greg Kroah-HartmanFrom: Jaegeuk Kim <[email protected]>
[ Upstream commit 86f33603f8c51537265ff7ac0320638fd2cbdb1b ]
First problem is we hit BUG_ON() in f2fs_get_sum_page given EIO on f2fs_get_meta_page_nofail().
Quick fix was not to give any error with infinite loop, but syzbot caught a case where it goes to that loop from fuzzed image. In turned out we abused f2fs_get_meta_page_nofail() like in the below call stack.
- f2fs_fill_super
- f2fs_build_segment_manager
- build_sit_entries
- get_current_sit_page
INFO: task syz-executor178:6870 can't die for more than 143 seconds.
task:syz-executor178 state:R
stack:26960 pid: 6870 ppid: 6869 flags:0x00004006
Call Trace:
Showing all locks held in the system:
1 lock held by khungtaskd/1179:
#0: ffffffff8a554da0 (rcu_read_lock){....}-{1:2}, at: debug_show_all_locks+0x53/0x260 kernel/locking/lockdep.c:6242
1 lock held by systemd-journal/3920:
1 lock held by in:imklog/6769:
#0: ffff88809eebc130 (&f->f_pos_lock){+.+.}-{3:3}, at: __fdget_pos+0xe9/0x100 fs/file.c:930
1 lock held by syz-executor178/6870:
#0: ffff8880925120e0 (&type->s_umount_key#47/1){+.+.}-{3:3}, at: alloc_super+0x201/0xaf0 fs/super.c:229Actually, we didn't have to use _nofail in this case, since we could return error to mount(2) already with the error handler.
As a result, this patch tries to 1) remove _nofail callers as much as possible,
2) deal with error case in last remaining caller, f2fs_get_sum_page().
--- fs/f2fs/checkpoint.c | 2 +- fs/f2fs/f2fs.h | 2 +- fs/f2fs/node.c | 2 +- fs/f2fs/segment.c | 12 +++++++++--- 4 files changed, 12 insertions(+), 6 deletions(-)
fs/f2fs/checkpoint.c +1 -1
@@ -107,7 +107,7 @@ struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index)return __get_meta_page (sbi, index, true); } -struct page *f2fs_get_meta_page_nofail (struct f2fs_sb_info *sbi,pgoff_t index) +struct page *f2fs_get_meta_page_retry (struct f2fs_sb_info *sbi,pgoff_t index) {struct page *page;int count =0 ;
fs/f2fs/f2fs.h +1 -1
@@ -3385,7 +3385,7 @@ enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,void f2fs_stop_checkpoint (struct f2fs_sb_info *sbi,bool end_io);struct page *f2fs_grab_meta_page (struct f2fs_sb_info *sbi,pgoff_t index);struct page *f2fs_get_meta_page (struct f2fs_sb_info *sbi,pgoff_t index); -struct page *f2fs_get_meta_page_nofail (struct f2fs_sb_info *sbi,pgoff_t index); +struct page *f2fs_get_meta_page_retry (struct f2fs_sb_info *sbi,pgoff_t index);struct page *f2fs_get_tmp_page (struct f2fs_sb_info *sbi,pgoff_t index);bool f2fs_is_valid_blkaddr (struct f2fs_sb_info *sbi,block_t blkaddr,int type);
fs/f2fs/node.c +1 -1
@@ -109,7 +109,7 @@ static void clear_node_page_dirty(struct page *page)static struct page *get_current_nat_page (struct f2fs_sb_info *sbi,nid_t nid) { -return f2fs_get_meta_page_nofail (sbi,current_nat_addr (sbi, nid)); +return f2fs_get_meta_page (sbi,current_nat_addr (sbi, nid)); }static struct page *get_next_nat_page (struct f2fs_sb_info *sbi,nid_t nid)
fs/f2fs/segment.c +9 -3
@@ -2344,7 +2344,9 @@ int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra)*/ struct page *f2fs_get_sum_page (struct f2fs_sb_info *sbi,unsigned int segno) { -return f2fs_get_meta_page_nofail (sbi,GET_SUM_BLOCK (sbi, segno)); +if (unlikely (f2fs_cp_error (sbi))) +return ERR_PTR (-EIO ); +return f2fs_get_meta_page_retry (sbi,GET_SUM_BLOCK (sbi, segno)); } void f2fs_update_meta_page(struct f2fs_sb_info *sbi,
@@ -2616,7 +2618,11 @@ static void change_curseg(struct f2fs_sb_info *sbi, int type)__next_free_blkoff (sbi, curseg,0 ); sum_page =f2fs_get_sum_page (sbi, new_segno); -f2fs_bug_on (sbi,IS_ERR (sum_page)); +if (IS_ERR (sum_page)) { +/* GC won't be able to use stale summary pages by cp_error */ +memset (curseg->sum_blk,0 ,SUM_ENTRY_SIZE ); +return ; + } sum_node = (struct f2fs_summary_block *)page_address (sum_page);memcpy (curseg->sum_blk, sum_node,SUM_ENTRY_SIZE );f2fs_put_page (sum_page,1 );
@@ -3781,7 +3787,7 @@ int f2fs_lookup_journal_in_cursum(struct f2fs_journal *journal, int type,static struct page *get_current_sit_page (struct f2fs_sb_info *sbi,unsigned int segno) { -return f2fs_get_meta_page_nofail (sbi,current_sit_addr (sbi, segno)); +return f2fs_get_meta_page (sbi,current_sit_addr (sbi, segno)); } static struct page *get_next_sit_page(struct f2fs_sb_info *sbi,
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 60/391 afs: Dont assert on unpurgeable server records
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit 7530d3eb3dcf1a30750e8e7f1f88b782b96b72b8 ]
Don't give an assertion failure on unpurgeable afs_server records - which kills the thread - but rather emit a trace line when we are purging a record (which only happens during network namespace removal or rmmod) and print a notice of the problem.
--- fs/afs/server.c | 7 ++++++- include/trace/events/afs.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-)
fs/afs/server.c +6 -1
@@ -550,7 +550,12 @@ void afs_manage_servers(struct work_struct *work)_debug ("manage %pU %u" , &server->uuid, active); - ASSERTIFCMP(purging, active, ==, 0); +if (purging) { +trace_afs_server (server,atomic_read (&server->ref), + active, afs_server_trace_purging); +if (active !=0 ) +pr_notice ("Can't purge s=%08x\n" , server->debug_id); + }if (active ==0 ) {time64_t expire_at = server->unuse_time;
include/trace/events/afs.h +2 -0
@@ -40,6 +40,7 @@ enum afs_server_trace { afs_server_trace_get_new_cbi, afs_server_trace_get_probe, afs_server_trace_give_up_cb, + afs_server_trace_purging, afs_server_trace_put_call, afs_server_trace_put_cbi, afs_server_trace_put_find_rsq,
@@ -270,6 +271,7 @@ enum afs_cb_break_reason { EM(afs_server_trace_get_new_cbi, "GET cbi ") \ EM(afs_server_trace_get_probe, "GET probe") \ EM(afs_server_trace_give_up_cb, "giveup-cb") \ + EM(afs_server_trace_purging, "PURGE ") \ EM(afs_server_trace_put_call, "PUT call ") \ EM(afs_server_trace_put_cbi, "PUT cbi ") \EM (afs_server_trace_put_find_rsq,"PUT f-rsq" ) \
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 61/391 powerpc/64s: handle ISA v3.1 local copy-paste context switches
In reply to Greg Kroah-HartmanFrom: Nicholas Piggin <[email protected]>
[ Upstream commit dc462267d2d7aacffc3c1d99b02d7a7c59db7c66 ]
The ISA v3.1 the copy-paste facility has a new memory move functionality which allows the copy buffer to be pasted to domestic memory (RAM) as opposed to foreign memory (accelerator).
This means the POWER9 trick of avoiding the cp_abort on context switch if the process had not mapped foreign memory does not work on POWER10. Do the cp_abort unconditionally there.
KVM must also cp_abort on guest exit to prevent copy buffer state leaking between contexts.
--- arch/powerpc/kernel/process.c | 16 +++++++++------- arch/powerpc/kvm/book3s_hv.c | 7 +++++++ arch/powerpc/kvm/book3s_hv_rmhandlers.S | 8 ++++++++ 3 files changed, 24 insertions(+), 7 deletions(-)
arch/powerpc/kernel/process.c +9 -7
@@ -1256,15 +1256,17 @@ struct task_struct *__switch_to(struct task_struct *prev,restore_math (current->thread.regs);/* -* The copy-paste buffer can only store into foreign real -* addresses, so unprivileged processes can not see the -* data or use it in any way unless they have foreign real -* mappings. If the new process has the foreign real address -* mappings, we must issue a cp_abort to clear any state and -* prevent snooping, corruption or a covert channel. +* On POWER9 the copy-paste buffer can only paste into +* foreign real addresses, so unprivileged processes can not +* see the data or use it in any way unless they have +* foreign real mappings. If the new process has the foreign +* real address mappings, we must issue a cp_abort to clear +* any state and prevent snooping, corruption or a covert +* channel. ISA v3.1 supports paste into local memory. */ if (current->mm && - atomic_read(¤t->mm->context.vas_windows)) + (cpu_has_feature (CPU_FTR_ARCH_31 ) || +atomic_read (¤t->mm->context.vas_windows))) asm volatile(PPC_CP_ABORT); } #endif /* CONFIG_PPC_BOOK3S_64 */
arch/powerpc/kvm/book3s_hv.c +7 -0
@@ -3530,6 +3530,13 @@ static int kvmhv_load_hv_regs_and_go(struct kvm_vcpu *vcpu, u64 time_limit,*/ asmvolatile ("eieio; tlbsync; ptesync" ); +/* +* cp_abort is required if the processor supports local copy-paste +* to clear the copy buffer that was under control of the guest. +*/ +if (cpu_has_feature (CPU_FTR_ARCH_31 )) + asm volatile(PPC_CP_ABORT); +mtspr (SPRN_LPID , vcpu->kvm->arch.host_lpid);/* restore host LPID */ isync ();
arch/powerpc/kvm/book3s_hv_rmhandlers.S +8 -0
@@ -1830,6 +1830,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_P9_RADIX_PREFETCH_BUG) 2: #endif /* CONFIG_PPC_RADIX_MMU */ + /* + * cp_abort is required if the processor supports local copy-paste + * to clear the copy buffer that was under control of the guest. + */ +BEGIN_FTR_SECTION + PPC_CP_ABORT +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_31) + /* * POWER7/POWER8 guest -> host partition switch code. * We don't have to lock against tlbies but we do
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 62/391 ARM: 8997/2: hw_breakpoint: Handle inexact watchpoint addresses
In reply to Greg Kroah-HartmanFrom: Douglas Anderson <[email protected]>
[ Upstream commit 22c9e58299e5f18274788ce54c03d4fb761e3c5d ]
This is commit fdfeff0f9e3d ("arm64: hw_breakpoint: Handle inexact watchpoint addresses") but ported to arm32, which has the same problem.
This problem was found by Android CTS tests, notably the "watchpoint_imprecise" test [1]. I tested locally against a copycat (simplified) version of the test though.
[1] https://android.googlesource.com/platform/bionic/+/master/tests/sys_ptrace_test.cpp
--- arch/arm/kernel/hw_breakpoint.c | 100 +++++++++++++++++++++++--------- 1 file changed, 72 insertions(+), 28 deletions(-)
arch/arm/kernel/hw_breakpoint.c +72 -28
@@ -683,6 +683,40 @@ static void disable_single_step(struct perf_event *bp)arch_install_hw_breakpoint (bp); } +/* +* Arm32 hardware does not always report a watchpoint hit address that matches +* one of the watchpoints set. It can also report an address "near" the +* watchpoint if a single instruction access both watched and unwatched +* addresses. There is no straight-forward way, short of disassembling the +* offending instruction, to map that address back to the watchpoint. This +* function computes the distance of the memory access from the watchpoint as a +* heuristic for the likelyhood that a given access triggered the watchpoint. +* +* See this same function in the arm64 platform code, which has the same +* problem. +* +* The function returns the distance of the address from the bytes watched by +* the watchpoint. In case of an exact match, it returns 0. +*/ +static u32 get_distance_from_watchpoint (unsigned long addr,u32 val, +struct arch_hw_breakpoint_ctrl *ctrl) +{ +u32 wp_low, wp_high; +u32 lens, lene; + + lens =__ffs (ctrl->len); + lene =__fls (ctrl->len); + + wp_low = val + lens; + wp_high = val + lene; +if (addr < wp_low) +return wp_low - addr; +else if (addr > wp_high) +return addr - wp_high; +else +return 0 ; +} +static int watchpoint_fault_on_uaccess (struct pt_regs *regs,struct arch_hw_breakpoint *info) {
@@ -692,23 +726,25 @@ static int watchpoint_fault_on_uaccess(struct pt_regs *regs,static void watchpoint_handler (unsigned long addr,unsigned int fsr,struct pt_regs *regs) { -int i, access; -u32 val, ctrl_reg, alignment_mask; +int i, access, closest_match =0 ; +u32 min_dist =-1 , dist; +u32 val, ctrl_reg;struct perf_event *wp, **slots;struct arch_hw_breakpoint *info;struct arch_hw_breakpoint_ctrl ctrl; slots =this_cpu_ptr (wp_on_reg); +/* +* Find all watchpoints that match the reported address. If no exact +* match is found. Attribute the hit to the closest watchpoint. +*/ +rcu_read_lock ();for (i =0 ; i < core_num_wrps; ++i) { -rcu_read_lock (); - wp = slots[i]; -if (wp ==NULL ) - goto unlock; +continue ; - info =counter_arch_bp (wp);/* * The DFAR is an unknown value on debug architectures prior * to 7.1. Since we only allow a single watchpoint on these
@@ -717,33 +753,31 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,*/ if (debug_arch <ARM_DEBUG_ARCH_V7_1 ) {BUG_ON (i >0 ); + info =counter_arch_bp (wp); info->trigger = wp->attr.bp_addr; }else { -if (info->ctrl.len ==ARM_BREAKPOINT_LEN_8 ) - alignment_mask =0x7 ; -else - alignment_mask =0x3 ; - -/* Check if the watchpoint value matches. */ - val =read_wb_reg (ARM_BASE_WVR + i); -if (val != (addr & ~alignment_mask)) - goto unlock; - -/* Possible match, check the byte address select. */ - ctrl_reg =read_wb_reg (ARM_BASE_WCR + i); -decode_ctrl_reg (ctrl_reg, &ctrl); -if (!((1 << (addr & alignment_mask)) & ctrl.len)) - goto unlock; -/* Check that the access type matches. */ if (debug_exception_updates_fsr ()) { access = (fsr &ARM_FSR_ACCESS_MASK ) ?HW_BREAKPOINT_W :HW_BREAKPOINT_R ;if (!(access &hw_breakpoint_type (wp))) - goto unlock; +continue ; } + val =read_wb_reg (ARM_BASE_WVR + i); + ctrl_reg =read_wb_reg (ARM_BASE_WCR + i); +decode_ctrl_reg (ctrl_reg, &ctrl); + dist =get_distance_from_watchpoint (addr, val, &ctrl); +if (dist < min_dist) { + min_dist = dist; + closest_match = i; + } +/* Is this an exact match? */ +if (dist !=0 ) +continue ; +/* We have a winner. */ + info =counter_arch_bp (wp); info->trigger = addr; }
@@ -765,13 +799,23 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,* we can single-step over the watchpoint trigger. */ if (!is_default_overflow_handler (wp)) - goto unlock; - +continue ; step:enable_single_step (wp,instruction_pointer (regs)); -unlock: -rcu_read_unlock (); } + +if (min_dist >0 && min_dist !=-1 ) { +/* No exact match found. */ + wp = slots[closest_match]; + info =counter_arch_bp (wp); + info->trigger = addr; +pr_debug ("watchpoint fired: address = 0x%x\n" , info->trigger); +perf_bp_event (wp, regs); +if (is_default_overflow_handler (wp)) +enable_single_step (wp,instruction_pointer (regs)); + } + +rcu_read_unlock (); }static void watchpoint_single_step_handler (unsigned long pc)
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 63/391 NFS4: Fix oops when copy_file_range is attempted with NFS4.0 source
In reply to Greg Kroah-HartmanFrom: Dave Wysochanski <[email protected]>
[ Upstream commit d8a6ad913c286d4763ae20b14c02fe6f39d7cd9f ]
The following oops is seen during xfstest/565 when the 'test' (source of the copy) is NFS4.0 and 'scratch' (destination) is NFS4.2
[ 59.692458] run fstests generic/565 at 2020-08-01 05:50:35 [ 60.613588] BUG: kernel NULL pointer dereference, address: 0000000000000008 [ 60.624970] #PF: supervisor read access in kernel mode [ 60.627671] #PF: error_code(0x0000) - not-present page [ 60.630347] PGD 0 P4D 0 [ 60.631853] Oops: 0000 [#1] SMP PTI [ 60.634086] CPU: 6 PID: 2828 Comm: xfs_io Kdump: loaded Not tainted 5.8.0-rc3 #1 [ 60.637676] Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 [ 60.639901] RIP: 0010:nfs4_check_serverowner_major_id+0x5/0x30 [nfsv4] [ 60.642719] Code: 89 ff e8 3e b3 b8 e1 e9 71 fe ff ff 41 bc da d8 ff ff e9 c3 fe ff ff e8 e9 9d 08 e2 66 0f 1f 84 00 00 00 00 00 66 66 66 66 90 <8b> 57 08 31 c0 3b 56 08 75 12 48 83 c6 0c 48 83 c7 0c e8 c4 97 bb [ 60.652629] RSP: 0018:ffffc265417f7e10 EFLAGS: 00010287 [ 60.655379] RAX: ffffa0664b066400 RBX: 0000000000000000 RCX: 0000000000000001 [ 60.658754] RDX: ffffa066725fb000 RSI: ffffa066725fd000 RDI: 0000000000000000 [ 60.662292] RBP: 0000000000020000 R08: 0000000000020000 R09: 0000000000000000 [ 60.666189] R10: 0000000000000003 R11: 0000000000000000 R12: ffffa06648258d00 [ 60.669914] R13: 0000000000000000 R14: 0000000000000000 R15: ffffa06648258100 [ 60.673645] FS: 00007faa9fb35800(0000) GS:ffffa06677d80000(0000) knlGS:0000000000000000 [ 60.677698] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 60.680773] CR2: 0000000000000008 CR3: 0000000203f14000 CR4: 00000000000406e0 [ 60.684476] Call Trace: [ 60.685809] nfs4_copy_file_range+0xfc/0x230 [nfsv4] [ 60.688704] vfs_copy_file_range+0x2ee/0x310 [ 60.691104] __x64_sys_copy_file_range+0xd6/0x210 [ 60.693527] do_syscall_64+0x4d/0x90 [ 60.695512] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 60.698006] RIP: 0033:0x7faa9febc1bd
--- fs/nfs/nfs4file.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/nfs/nfs4file.c +2 -1
@@ -146,7 +146,8 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in,/* Only offload copy if superblock is the same */ if (file_in->f_op != &nfs4_file_operations)return -EXDEV ; -if (!nfs_server_capable (file_inode (file_out),NFS_CAP_COPY )) +if (!nfs_server_capable (file_inode (file_out),NFS_CAP_COPY ) || + !nfs_server_capable (file_inode (file_in),NFS_CAP_COPY ))return -EOPNOTSUPP ;if (file_inode (file_in) ==file_inode (file_out))return -EOPNOTSUPP ;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 64/391 xfs: Set xfs_buf type flag when growing summary/bitmap files
In reply to Greg Kroah-HartmanFrom: Chandan Babu R <[email protected]>
[ Upstream commit 72cc95132a93293dcd0b6f68353f4741591c9aeb ]
The following sequence of commands,
mkfs.xfs -f -m reflink=0 -r rtdev=/dev/loop1,size=10M /dev/loop0 mount -o rtdev=/dev/loop1 /dev/loop0 /mnt
xfs_growfs /mnt
... causes the following call trace to be printed on the console,
XFS: Assertion failed: (bip->bli_flags & XFS_BLI_STALE) || (xfs_blft_from_flags(&bip->__bli_format) > XFS_BLFT_UNKNOWN_BUF && xfs_blft_from_flags(&bip->__bli_format) < XFS_BLFT_MAX_BUF), file: fs/xfs/xfs_buf_item.c, line: 331
Call Trace: xfs_buf_item_format+0x632/0x680 ? kmem_alloc_large+0x29/0x90 ? kmem_alloc+0x70/0x120 ? xfs_log_commit_cil+0x132/0x940 xfs_log_commit_cil+0x26f/0x940 ? xfs_buf_item_init+0x1ad/0x240 ? xfs_growfs_rt_alloc+0x1fc/0x280 __xfs_trans_commit+0xac/0x370 xfs_growfs_rt_alloc+0x1fc/0x280 xfs_growfs_rt+0x1a0/0x5e0 xfs_file_ioctl+0x3fd/0xc70 ? selinux_file_ioctl+0x174/0x220 ksys_ioctl+0x87/0xc0 __x64_sys_ioctl+0x16/0x20 do_syscall_64+0x3e/0x70 entry_SYSCALL_64_after_hwframe+0x44/0xa9
This occurs because the buffer being formatted has the value of XFS_BLFT_UNKNOWN_BUF assigned to the 'type' subfield of bip->bli_formats->blf_flags.
This commit fixes the issue by assigning one of XFS_BLFT_RTSUMMARY_BUF and XFS_BLFT_RTBITMAP_BUF to the 'type' subfield of bip->bli_formats->blf_flags before committing the corresponding transaction.
--- fs/xfs/xfs_rtalloc.c | 8 ++++++++ 1 file changed, 8 insertions(+)
fs/xfs/xfs_rtalloc.c +8 -0
@@ -778,8 +778,14 @@ xfs_growfs_rt_alloc(struct xfs_bmbt_irec map;/* block map output */ int nmap;/* number of block maps */ int resblks;/* space reservation */ +enum xfs_blft buf_type;struct xfs_trans *tp; +if (ip == mp->m_rsumip) + buf_type =XFS_BLFT_RTSUMMARY_BUF ; +else + buf_type =XFS_BLFT_RTBITMAP_BUF ; +/* * Allocate space to the file, as necessary. */
@@ -841,6 +847,8 @@ xfs_growfs_rt_alloc( mp->m_bsize, 0, &bp);if (error) goto out_trans_cancel; + +xfs_trans_buf_set_type (tp, bp, buf_type);memset (bp->b_addr,0 , mp->m_sb.sb_blocksize);xfs_trans_log_buf (tp, bp,0 , mp->m_sb.sb_blocksize -1 );/*
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 65/391 xfs: Set xfs_bufs b_ops member when zeroing bitmap/summary files
In reply to Greg Kroah-HartmanFrom: Chandan Babu R <[email protected]>
[ Upstream commit c54e14d155f5fdbac73a8cd4bd2678cb252149dc ]
In xfs_growfs_rt(), we enlarge bitmap and summary files by allocating new blocks for both files. For each of the new blocks allocated, we allocate an xfs_buf, zero the payload, log the contents and commit the transaction. Hence these buffers will eventually find themselves appended to list at xfs_ail->ail_buf_list.
Later, xfs_growfs_rt() loops across all of the new blocks belonging to the bitmap inode to set the bitmap values to 1. In doing so, it allocates a new transaction and invokes the following sequence of functions,
- xfs_rtfree_range()
- xfs_rtmodify_range()
- xfs_rtbuf_get()
We pass '&xfs_rtbuf_ops' as the ops pointer to xfs_trans_read_buf().
- xfs_trans_read_buf()
We find the xfs_buf of interest in per-ag hash table, invoke xfs_buf_reverify() which ends up assigning '&xfs_rtbuf_ops' to xfs_buf->b_ops.
On the other hand, if xfs_growfs_rt_alloc() had allocated a few blocks for the bitmap inode and returned with an error, all the xfs_bufs corresponding to the new bitmap blocks that have been allocated would continue to be on xfs_ail->ail_buf_list list without ever having a non-NULL value assigned to their b_ops members. An AIL flush operation would then trigger the following warning message to be printed on the console,
XFS (loop0): _xfs_buf_ioapply: no buf ops on daddr 0x58 len 8
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ CPU: 3 PID: 449 Comm: xfsaild/loop0 Not tainted 5.8.0-rc4-chandan-00038-g4d8c2b9de9ab-dirty #37 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 Call Trace: dump_stack+0x57/0x70 _xfs_buf_ioapply+0x37c/0x3b0 ? xfs_rw_bdev+0x1e0/0x1e0 ? xfs_buf_delwri_submit_buffers+0xd4/0x210 __xfs_buf_submit+0x6d/0x1f0 xfs_buf_delwri_submit_buffers+0xd4/0x210 xfsaild+0x2c8/0x9e0 ? __switch_to_asm+0x42/0x70 ? xfs_trans_ail_cursor_first+0x80/0x80 kthread+0xfe/0x140 ? kthread_park+0x90/0x90 ret_from_fork+0x22/0x30
This message indicates that the xfs_buf had its b_ops member set to NULL.
This commit fixes the issue by assigning "&xfs_rtbuf_ops" to b_ops member of each of the xfs_bufs logged by xfs_growfs_rt_alloc().
--- fs/xfs/xfs_rtalloc.c | 1 + 1 file changed, 1 insertion(+)
fs/xfs/xfs_rtalloc.c +1 -0
@@ -849,6 +849,7 @@ xfs_growfs_rt_alloc( goto out_trans_cancel;xfs_trans_buf_set_type (tp, bp, buf_type); + bp->b_ops = &xfs_rtbuf_ops;memset (bp->b_addr,0 , mp->m_sb.sb_blocksize);xfs_trans_log_buf (tp, bp,0 , mp->m_sb.sb_blocksize -1 );/*
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 66/391 xfs: log new intent items created as part of finishing recovered intent items
In reply to Greg Kroah-HartmanFrom: Darrick J. Wong <[email protected]>
[ Upstream commit 93293bcbde93567efaf4e6bcd58cad270e1fcbf5 ]
During a code inspection, I found a serious bug in the log intent item recovery code when an intent item cannot complete all the work and decides to requeue itself to get that done. When this happens, the item recovery creates a new incore deferred op representing the remaining work and attaches it to the transaction that it allocated. At the end of _item_recover, it moves the entire chain of deferred ops to the dummy parent_tp that xlog_recover_process_intents passed to it, but fail to log a new intent item for the remaining work before committing the transaction for the single unit of work.
xlog_finish_defer_ops logs those new intent items once recovery has finished dealing with the intent items that it recovered, but this isn't sufficient. If the log is forced to disk after a recovered log item decides to requeue itself and the system goes down before we call xlog_finish_defer_ops, the second log recovery will never see the new intent item and therefore has no idea that there was more work to do. It will finish recovery leaving the filesystem in a corrupted state.
The same logic applies to /any/ deferred ops added during intent item recovery, not just the one handling the remaining work.
--- fs/xfs/libxfs/xfs_defer.c | 26 ++++++++++++++++++++++++-- fs/xfs/libxfs/xfs_defer.h | 6 ++++++ fs/xfs/xfs_bmap_item.c | 2 +- fs/xfs/xfs_refcount_item.c | 2 +- 4 files changed, 32 insertions(+), 4 deletions(-)
fs/xfs/libxfs/xfs_defer.c +24 -2
@@ -186,8 +186,9 @@ xfs_defer_create_intent( {const struct xfs_defer_op_type *ops = defer_op_types[dfp->dfp_type]; - dfp->dfp_intent = ops->create_intent (tp, &dfp->dfp_work, - dfp->dfp_count, sort); +if (!dfp->dfp_intent) + dfp->dfp_intent = ops->create_intent (tp, &dfp->dfp_work, + dfp->dfp_count, sort); }/*
@@ -390,6 +391,7 @@ xfs_defer_finish_one(list_add (li, &dfp->dfp_work); dfp->dfp_count++; dfp->dfp_done =NULL ; + dfp->dfp_intent =NULL ;xfs_defer_create_intent (tp, dfp, false); }
@@ -552,3 +554,23 @@ xfs_defer_move(xfs_defer_reset (stp); } + +/* +* Prepare a chain of fresh deferred ops work items to be completed later. Log +* recovery requires the ability to put off until later the actual finishing +* work so that it can process unfinished items recovered from the log in +* correct order. +* +* Create and log intent items for all the work that we're capturing so that we +* can be assured that the items will get replayed if the system goes down +* before log recovery gets a chance to finish the work it put off. Then we +* move the chain from stp to dtp. +*/ +void +xfs_defer_capture ( +struct xfs_trans *dtp, +struct xfs_trans *stp) +{ +xfs_defer_create_intents (stp); +xfs_defer_move (dtp, stp); +}
fs/xfs/libxfs/xfs_defer.h +6 -0
@@ -63,4 +63,10 @@ extern const struct xfs_defer_op_type xfs_rmap_update_defer_type;extern const struct xfs_defer_op_type xfs_extent_free_defer_type;extern const struct xfs_defer_op_type xfs_agfl_free_defer_type; +/* +* Functions to capture a chain of deferred operations and continue them later. +* This doesn't normally happen except log recovery. +*/ +void xfs_defer_capture (struct xfs_trans *dtp,struct xfs_trans *stp); +#endif /* __XFS_DEFER_H__ */
fs/xfs/xfs_bmap_item.c +1 -1
@@ -534,7 +534,7 @@ xfs_bui_item_recover(xfs_bmap_unmap_extent (tp, ip, &irec); } -xfs_defer_move (parent_tp, tp); +xfs_defer_capture (parent_tp, tp); error =xfs_trans_commit (tp);xfs_iunlock (ip,XFS_ILOCK_EXCL );xfs_irele (ip);
fs/xfs/xfs_refcount_item.c +1 -1
@@ -555,7 +555,7 @@ xfs_cui_item_recover( }xfs_refcount_finish_one_cleanup (tp, rcur, error); -xfs_defer_move (parent_tp, tp); +xfs_defer_capture (parent_tp, tp); error =xfs_trans_commit (tp);return error;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 67/391 power: supply: bq27xxx: report "not charging" on all types
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 7bf738ba110722b63e9dc8af760d3fb2aef25593 ]
Commit 6f24ff97e323 ("power: supply: bq27xxx_battery: Add the BQ27Z561 Battery monitor") and commit d74534c27775 ("power:bq27xxx_battery: Add support for additional bq27xxx family devices") added support for new device types by copying most of the code and adding necessary quirks.
However they did not copy the code in bq27xxx_battery_status() responsible for returning POWER_SUPPLY_STATUS_NOT_CHARGING.
Unify the bq27xxx_battery_status() so for all types when charger is supplied, it will return "not charging" status.
--- drivers/power/supply/bq27xxx_battery.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/power/supply/bq27xxx_battery.c +4 -2
@@ -1772,8 +1772,6 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di, status =POWER_SUPPLY_STATUS_FULL ; else if (di->cache.flags & BQ27000_FLAG_CHGS) status =POWER_SUPPLY_STATUS_CHARGING ; - else if (power_supply_am_i_supplied(di->bat) > 0) - status =POWER_SUPPLY_STATUS_NOT_CHARGING ; else status =POWER_SUPPLY_STATUS_DISCHARGING ; }else if (di->opts &BQ27Z561_O_BITS ) {
@@ -1792,6 +1790,10 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di, status =POWER_SUPPLY_STATUS_CHARGING ; } +if ((status ==POWER_SUPPLY_STATUS_DISCHARGING ) && + (power_supply_am_i_supplied (di->bat) >0 )) + status =POWER_SUPPLY_STATUS_NOT_CHARGING ; + val->intval = status;return 0 ;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 68/391 xfs: change the order in which child and parent defer ops are finished
In reply to Greg Kroah-HartmanFrom: Darrick J. Wong <[email protected]>
[ Upstream commit 27dada070d59c28a441f1907d2cec891b17dcb26 ]
The defer ops code has been finishing items in the wrong order -- if a top level defer op creates items A and B, and finishing item A creates more defer ops A1 and A2, we'll put the new items on the end of the chain and process them in the order A B A1 A2. This is kind of weird, since it's convenient for programmers to be able to think of A and B as an ordered sequence where all the sub-tasks for A must finish before we move on to B, e.g. A A1 A2 D.
Right now, our log intent items are not so complex that this matters, but this will become important for the atomic extent swapping patchset. In order to maintain correct reference counting of extents, we have to unmap and remap extents in that order, and we want to complete that work before moving on to the next range that the user wants to swap. This patch fixes defer ops to satsify that requirement.
The primary symptom of the incorrect order was noticed in an early performance analysis of the atomic extent swap code. An astonishingly large number of deferred work items accumulated when userspace requested an atomic update of two very fragmented files. The cause of this was traced to the same ordering bug in the inner loop of xfs_defer_finish_noroll.
If the ->finish_item method of a deferred operation queues new deferred operations, those new deferred ops are appended to the tail of the pending work list. To illustrate, say that a caller creates a transaction t0 with four deferred operations D0-D3. The first thing defer ops does is roll the transaction to t1, leaving us with:
t1: D0(t0), D1(t0), D2(t0), D3(t0)
Let's say that finishing each of D0-D3 will create two new deferred ops. After finish D0 and roll, we'll have the following chain:
t2: D1(t0), D2(t0), D3(t0), d4(t1), d5(t1)
d4 and d5 were logged to t1. Notice that while we're about to start work on D1, we haven't actually completed all the work implied by D0 being finished. So far we've been careful (or lucky) to structure the dfops callers such that D1 doesn't depend on d4 or d5 being finished, but this is a potential logic bomb.
There's a second problem lurking. Let's see what happens as we finish D1-D3:
t3: D2(t0), D3(t0), d4(t1), d5(t1), d6(t2), d7(t2)
t4: D3(t0), d4(t1), d5(t1), d6(t2), d7(t2), d8(t3), d9(t3)
t5: d4(t1), d5(t1), d6(t2), d7(t2), d8(t3), d9(t3), d10(t4), d11(t4)
Let's say that d4-d11 are simple work items that don't queue any other operations, which means that we can complete each d4 and roll to t6:
t6: d5(t1), d6(t2), d7(t2), d8(t3), d9(t3), d10(t4), d11(t4)
t7: d6(t2), d7(t2), d8(t3), d9(t3), d10(t4), d11(t4)
...
t11: d10(t4), d11(t4)
t12: d11(t4)
<done>
When we try to roll to transaction #12, we're holding defer op d11, which we logged way back in t4. This means that the tail of the log is pinned at t4. If the log is very small or there are a lot of other threads updating metadata, this means that we might have wrapped the log and cannot get roll to t11 because there isn't enough space left before we'd run into t4.
Let's shift back to the original failure. I mentioned before that I discovered this flaw while developing the atomic file update code. In that scenario, we have a defer op (D0) that finds a range of file blocks to remap, creates a handful of new defer ops to do that, and then asks to be continued with however much work remains.
So, D0 is the original swapext deferred op. The first thing defer ops does is rolls to t1:
t1: D0(t0)
We try to finish D0, logging d1 and d2 in the process, but can't get all the work done. We log a done item and a new intent item for the work that D0 still has to do, and roll to t2:
t2: D0'(t1), d1(t1), d2(t1)
We roll and try to finish D0', but still can't get all the work done, so we log a done item and a new intent item for it, requeue D0 a second time, and roll to t3:
t3: D0''(t2), d1(t1), d2(t1), d3(t2), d4(t2)
If it takes 48 more rolls to complete D0, then we'll finally dispense with D0 in t50:
t50: D<fifty primes>(t49), d1(t1), ..., d102(t50)
We then try to roll again to get a chain like this:
t51: d1(t1), d2(t1), ..., d101(t50), d102(t50)
...
t152: d102(t50)
<done>
Notice that in rolling to transaction #51, we're holding on to a log intent item for d1 that was logged in transaction #1. This means that the tail of the log is pinned at t1. If the log is very small or there are a lot of other threads updating metadata, this means that we might have wrapped the log and cannot roll to t51 because there isn't enough space left before we'd run into t1. This is of course problem #2 again.
But notice the third problem with this scenario: we have 102 defer ops tied to this transaction! Each of these items are backed by pinned kernel memory, which means that we risk OOM if the chains get too long.
Yikes. Problem #1 is a subtle logic bomb that could hit someone in the future; problem #2 applies (rarely) to the current upstream, and problem #3 applies to work under development.
This is not how incremental deferred operations were supposed to work. The dfops design of logging in the same transaction an intent-done item and a new intent item for the work remaining was to make it so that we only have to juggle enough deferred work items to finish that one small piece of work. Deferred log item recovery will find that first unfinished work item and restart it, no matter how many other intent items might follow it in the log. Therefore, it's ok to put the new intents at the start of the dfops chain.
For the first example, the chains look like this:
t2: d4(t1), d5(t1), D1(t0), D2(t0), D3(t0)
t3: d5(t1), D1(t0), D2(t0), D3(t0)
...
t9: d9(t7), D3(t0)
t10: D3(t0)
t11: d10(t10), d11(t10)
t12: d11(t10)
For the second example, the chains look like this:
t1: D0(t0)
t2: d1(t1), d2(t1), D0'(t1)
t3: d2(t1), D0'(t1)
t4: D0'(t1)
t5: d1(t4), d2(t4), D0''(t4)
...
t148: D0<50 primes>(t147)
t149: d101(t148), d102(t148)
t150: d102(t148)
<done>
This actually sucks more for pinning the log tail (we try to roll to t10 while holding an intent item that was logged in t1) but we've solved problem #1. We've also reduced the maximum chain length from:
sum(all the new items) + nr_original_items
to:
max(new items that each original item creates) + nr_original_items
This solves problem #3 by sharply reducing the number of defer ops that can be attached to a transaction at any given time. The change makes the problem of log tail pinning worse, but is improvement we need to solve problem #2. Actually solving #2, however, is left to the next patch.
Note that a subsequent analysis of some hard-to-trigger reflink and COW livelocks on extremely fragmented filesystems (or systems running a lot of IO threads) showed the same symptoms -- uncomfortably large numbers of incore deferred work items and occasional stalls in the transaction grant code while waiting for log reservations. I think this patch and the next one will also solve these problems.
As originally written, the code used list_splice_tail_init instead of list_splice_init, so change that, and leave a short comment explaining our actions.
--- fs/xfs/libxfs/xfs_defer.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
fs/xfs/libxfs/xfs_defer.c +10 -1
@@ -430,8 +430,17 @@ xfs_defer_finish_noroll(/* Until we run out of pending work to finish... */ while (!list_empty (&dop_pending) || !list_empty (&(*tp)->t_dfops)) { +/* +* Deferred items that are created in the process of finishing +* other deferred work items should be queued at the head of +* the pending list, which puts them ahead of the deferred work +* that was created by the caller. This keeps the number of +* pending work items to a minimum, which decreases the amount +* of time that any one intent item can stick around in memory, +* pinning the log tail. +*/ xfs_defer_create_intents (*tp); -list_splice_tail_init (&(*tp)->t_dfops, &dop_pending); +list_splice_init (&(*tp)->t_dfops, &dop_pending); error =xfs_defer_trans_roll (tp);if (error)
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 69/391 xfs: fix realtime bitmap/summary file truncation when growing rt volume
In reply to Greg Kroah-HartmanFrom: Darrick J. Wong <[email protected]>
[ Upstream commit f4c32e87de7d66074d5612567c5eac7325024428 ]
The realtime bitmap and summary files are regular files that are hidden away from the directory tree. Since they're regular files, inode inactivation will try to purge what it thinks are speculative preallocations beyond the incore size of the file. Unfortunately, xfs_growfs_rt forgets to update the incore size when it resizes the inodes, with the result that inactivating the rt inodes at unmount time will cause their contents to be truncated.
Fix this by updating the incore size when we change the ondisk size as part of updating the superblock. Note that we don't do this when we're allocating blocks to the rt inodes because we actually want those blocks to get purged if the growfs fails.
This fixes corruption complaints from the online rtsummary checker when running xfs/233. Since that test requires rmap, one can also trigger this by growing an rt volume, cycling the mount, and creating rt files.
--- fs/xfs/xfs_rtalloc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
fs/xfs/xfs_rtalloc.c +8 -2
@@ -1027,10 +1027,13 @@ xfs_growfs_rt(xfs_ilock (mp->m_rbmip,XFS_ILOCK_EXCL );xfs_trans_ijoin (tp, mp->m_rbmip,XFS_ILOCK_EXCL );/* -* Update the bitmap inode's size. +* Update the bitmap inode's size ondisk and incore. We need +* to update the incore size so that inode inactivation won't +* punch what it thinks are "posteof" blocks. */ mp->m_rbmip->i_d.di_size = nsbp->sb_rbmblocks * nsbp->sb_blocksize; +i_size_write (VFS_I (mp->m_rbmip), mp->m_rbmip->i_d.di_size);xfs_trans_log_inode (tp, mp->m_rbmip,XFS_ILOG_CORE );/* * Get the summary inode into the transaction.
@@ -1038,9 +1041,12 @@ xfs_growfs_rt(xfs_ilock (mp->m_rsumip,XFS_ILOCK_EXCL );xfs_trans_ijoin (tp, mp->m_rsumip,XFS_ILOCK_EXCL );/* -* Update the summary inode's size. +* Update the summary inode's size. We need to update the +* incore size so that inode inactivation won't punch what it +* thinks are "posteof" blocks. */ mp->m_rsumip->i_d.di_size = nmp->m_rsumsize; +i_size_write (VFS_I (mp->m_rsumip), mp->m_rsumip->i_d.di_size);xfs_trans_log_inode (tp, mp->m_rsumip,XFS_ILOG_CORE );/* * Copy summary data from old to new sizes.
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 70/391 io_uring: dont set COMP_LOCKED if wont put
In reply to Greg Kroah-HartmanFrom: Pavel Begunkov <[email protected]>
[ Upstream commit 368c5481ae7c6a9719c40984faea35480d9f4872 ]
__io_kill_linked_timeout() sets REQ_F_COMP_LOCKED for a linked timeout even if it can't cancel it, e.g. it's already running. It not only races with io_link_timeout_fn() for ->flags field, but also leaves the flag set and so io_link_timeout_fn() may find it and decide that it holds the lock. Hopefully, the second problem is potential.
--- fs/io_uring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/io_uring.c +1 -1
@@ -1650,6 +1650,7 @@ static bool io_link_cancel_timeout(struct io_kiocb *req) ret =hrtimer_try_to_cancel (&req->io->timeout.timer);if (ret !=-1 ) { + req->flags |=REQ_F_COMP_LOCKED ;io_cqring_fill_event (req, -ECANCELED );io_commit_cqring (ctx); req->flags &= ~REQ_F_LINK_HEAD ;
@@ -1672,7 +1673,6 @@ static bool __io_kill_linked_timeout(struct io_kiocb *req)return false;list_del_init (&link->link_list); - link->flags |=REQ_F_COMP_LOCKED ; wake_ev =io_link_cancel_timeout (link); req->flags &= ~REQ_F_LINK_TIMEOUT ;return wake_ev;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 71/391 ath10k: fix retry packets update in station dump
In reply to Greg Kroah-HartmanFrom: Venkateswara Naralasetty <[email protected]>
[ Upstream commit 67b927f9820847d30e97510b2f00cd142b9559b6 ]
When tx status enabled, retry count is updated from tx completion status. which is not working as expected due to firmware limitation where firmware can not provide per MSDU rate statistics from tx completion status. Due to this tx retry count is always 0 in station dump.
Fix this issue by updating the retry packet count from per peer statistics. This patch will not break on SDIO devices since, this retry count is already updating from peer statistics for SDIO devices.
Tested-on: QCA9984 PCI 10.4-3.6-00104
Tested-on: QCA9882 PCI 10.2.4-1.0-00047
--- drivers/net/wireless/ath/ath10k/htt_rx.c | 8 +++++--- drivers/net/wireless/ath/ath10k/mac.c | 5 +++-- 2 files changed, 8 insertions(+), 5 deletions(-)
drivers/net/wireless/ath/ath10k/htt_rx.c +5 -3
@@ -3583,12 +3583,14 @@ ath10k_update_per_peer_tx_stats(struct ath10k *ar, }if (ar->htt.disable_tx_comp) { - arsta->tx_retries += peer_stats->retry_pkts; arsta->tx_failed += peer_stats->failed_pkts; -ath10k_dbg (ar,ATH10K_DBG_HTT ,"htt tx retries %d tx failed %d\n" , - arsta->tx_retries, arsta->tx_failed); +ath10k_dbg (ar,ATH10K_DBG_HTT ,"tx failed %d\n" , + arsta->tx_failed); } + arsta->tx_retries += peer_stats->retry_pkts; +ath10k_dbg (ar,ATH10K_DBG_HTT ,"htt tx retries %d" , arsta->tx_retries); +if (ath10k_debug_is_extd_tx_stats_enabled (ar))ath10k_accumulate_per_peer_tx_stats (ar, arsta, peer_stats, rate_idx);
drivers/net/wireless/ath/ath10k/mac.c +3 -2
@@ -8542,12 +8542,13 @@ static void ath10k_sta_statistics(struct ieee80211_hw *hw, sinfo->filled |=BIT_ULL (NL80211_STA_INFO_TX_BITRATE );if (ar->htt.disable_tx_comp) { - sinfo->tx_retries = arsta->tx_retries; - sinfo->filled |=BIT_ULL (NL80211_STA_INFO_TX_RETRIES ); sinfo->tx_failed = arsta->tx_failed; sinfo->filled |=BIT_ULL (NL80211_STA_INFO_TX_FAILED ); } + sinfo->tx_retries = arsta->tx_retries; + sinfo->filled |=BIT_ULL (NL80211_STA_INFO_TX_RETRIES ); +ath10k_mac_sta_get_peer_stats_info (ar, sta, sinfo); }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 72/391 x86/kaslr: Initialize mem_limit to the real maximum address
In reply to Greg Kroah-HartmanFrom: Arvind Sankar <[email protected]>
[ Upstream commit 451286940d95778e83fa7f97006316d995b4c4a8 ]
On 64-bit, the kernel must be placed below MAXMEM (64TiB with 4-level paging or 4PiB with 5-level paging). This is currently not enforced by KASLR, which thus implicitly relies on physical memory being limited to less than 64TiB.
On 32-bit, the limit is KERNEL_IMAGE_SIZE (512MiB). This is enforced by special checks in __process_mem_region().
Initialize mem_limit to the maximum (depending on architecture), instead of ULLONG_MAX, and make sure the command-line arguments can only decrease it. This makes the enforcement explicit on 64-bit, and eliminates the 32-bit specific checks to keep the kernel below 512M.
Check upfront to make sure the minimum address is below the limit before doing any work.
--- arch/x86/boot/compressed/kaslr.c | 41 +++++++++++++++++--------------- 1 file changed, 22 insertions(+), 19 deletions(-)
arch/x86/boot/compressed/kaslr.c +22 -19
@@ -87,8 +87,11 @@ static unsigned long get_boot_seed(void)static bool memmap_too_large; -/* Store memory limit specified by "mem=nn[KMG]" or "memmap=nn[KMG]" */ -static unsigned long long mem_limit =ULLONG_MAX ; +/* +* Store memory limit: MAXMEM on 64-bit and KERNEL_IMAGE_SIZE on 32-bit. +* It may be reduced by "mem=nn[KMG]" or "memmap=nn[KMG]" command line options. +*/ +static unsigned long long mem_limit;/* Number of immovable memory regions */ static int num_immovable_mem;
@@ -214,7 +217,7 @@ static void mem_avoid_memmap(enum parse_mode mode, char *str)if (start ==0 ) {/* Store the specified memory limit if size > 0 */ -if (size >0 ) +if (size >0 && size < mem_limit) mem_limit = size;continue ;
@@ -302,7 +305,8 @@ static void handle_mem_options(void)if (mem_size ==0 ) goto out; - mem_limit = mem_size; +if (mem_size < mem_limit) + mem_limit = mem_size; }else if (!strcmp (param,"efi_fake_mem" )) {mem_avoid_memmap (PARSE_EFI , val); }
@@ -314,7 +318,9 @@ out: }/* -* In theory, KASLR can put the kernel anywhere in the range of [16M, 64T). +* In theory, KASLR can put the kernel anywhere in the range of [16M, MAXMEM) +* on 64-bit, and [16M, KERNEL_IMAGE_SIZE) on 32-bit. +* * The mem_avoid array is used to store the ranges that need to be avoided * when KASLR searches for an appropriate random address. We must avoid any * regions that are unsafe to overlap with during decompression, and other
@@ -614,10 +620,6 @@ static void __process_mem_region(struct mem_vector *entry,unsigned long start_orig, end;struct mem_vector cur_entry; -/* On 32-bit, ignore entries entirely above our maximum. */ -if (IS_ENABLED (CONFIG_X86_32 ) && entry->start >=KERNEL_IMAGE_SIZE ) -return ; -/* Ignore entries entirely below our minimum. */ if (entry->start + entry->size < minimum)return ;
@@ -650,11 +652,6 @@ static void __process_mem_region(struct mem_vector *entry,/* Reduce size by any delta from the original address. */ region.size -= region.start - start_orig; -/* On 32-bit, reduce region size to fit within max size. */ -if (IS_ENABLED (CONFIG_X86_32 ) && - region.start + region.size >KERNEL_IMAGE_SIZE ) - region.size =KERNEL_IMAGE_SIZE - region.start; -/* Return if region can't contain decompressed kernel */ if (region.size < image_size)return ;
@@ -839,15 +836,16 @@ static void process_e820_entries(unsigned long minimum,static unsigned long find_random_phys_addr (unsigned long minimum,unsigned long image_size) { +/* Bail out early if it's impossible to succeed. */ +if (minimum + image_size > mem_limit) +return 0 ; +/* Check if we had too many memmaps. */ if (memmap_too_large) {debug_putstr ("Aborted memory entries scan (more than 4 memmap= args)!\n" );return 0 ; } -/* Make sure minimum is aligned. */ - minimum =ALIGN (minimum,CONFIG_PHYSICAL_ALIGN ); -if (process_efi_entries (minimum, image_size))return slots_fetch_random ();
@@ -860,8 +858,6 @@ static unsigned long find_random_virt_addr(unsigned long minimum, {unsigned long slots, random_addr; -/* Make sure minimum is aligned. */ - minimum =ALIGN (minimum,CONFIG_PHYSICAL_ALIGN );/* Align image_size for easy slot calculations. */ image_size =ALIGN (image_size,CONFIG_PHYSICAL_ALIGN );
@@ -908,6 +904,11 @@ void choose_random_location(unsigned long input,/* Prepare to add new identity pagetables on demand. */ initialize_identity_maps (); +if (IS_ENABLED (CONFIG_X86_32 )) + mem_limit =KERNEL_IMAGE_SIZE ; +else + mem_limit =MAXMEM ; +/* Record the various known unsafe memory ranges. */ mem_avoid_init (input, input_size, *output);
@@ -917,6 +918,8 @@ void choose_random_location(unsigned long input,* location: */ min_addr =min (*output,512UL <<20 ); +/* Make sure minimum is aligned. */ + min_addr =ALIGN (min_addr,CONFIG_PHYSICAL_ALIGN );/* Walk available memory entries to find a random address. */ random_addr =find_random_phys_addr (min_addr, output_size);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 73/391 drm/ast: Separate DRM driver from PCI code
In reply to Greg Kroah-HartmanFrom: Thomas Zimmermann <[email protected]>
[ Upstream commit d50ace1e72f05708cc5dbc89b9bbb9873f150092 ]
Putting the DRM driver to the top of the file and the PCI code to the bottom makes ast_drv.c more readable. While at it, the patch prefixes file-scope variables with ast_.
--- drivers/gpu/drm/ast/ast_drv.c | 59 ++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 28 deletions(-)
drivers/gpu/drm/ast/ast_drv.c +31 -28
@@ -43,9 +43,33 @@ int ast_modeset = -1;MODULE_PARM_DESC (modeset,"Disable/Enable modesetting" );module_param_named (modeset, ast_modeset, int,0400 ); -#define PCI_VENDOR_ASPEED 0x1a03 +/* +* DRM driver +*/ + +DEFINE_DRM_GEM_FOPS (ast_fops); + +static struct drm_driver ast_driver = { + .driver_features =DRIVER_ATOMIC | +DRIVER_GEM | +DRIVER_MODESET , + + .fops = &ast_fops, + .name =DRIVER_NAME , + .desc =DRIVER_DESC , + .date =DRIVER_DATE , + .major =DRIVER_MAJOR , + .minor =DRIVER_MINOR , + .patchlevel =DRIVER_PATCHLEVEL , -static struct drm_driver driver; +DRM_GEM_VRAM_DRIVER +}; + +/* +* PCI driver +*/ + +#define PCI_VENDOR_ASPEED 0x1a03#define AST_VGA_DEVICE (id, info) { \ .class = PCI_BASE_CLASS_DISPLAY << 16, \
@@ -56,13 +80,13 @@ static struct drm_driver driver; .subdevice = PCI_ANY_ID, \ .driver_data = (unsigned long) info } -static const struct pci_device_id pciidlist[] = { +static const struct pci_device_id ast_pciidlist[] = {AST_VGA_DEVICE (PCI_CHIP_AST2000 ,NULL ),AST_VGA_DEVICE (PCI_CHIP_AST2100 ,NULL ), {0 ,0 ,0 }, }; -MODULE_DEVICE_TABLE (pci, pciidlist); +MODULE_DEVICE_TABLE (pci, ast_pciidlist);static void ast_kick_out_firmware_fb (struct pci_dev *pdev) {
@@ -94,7 +118,7 @@ static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)if (ret)return ret; - dev =drm_dev_alloc (&driver, &pdev->dev); + dev =drm_dev_alloc (&ast_driver, &pdev->dev);if (IS_ERR (dev))return PTR_ERR (dev);
@@ -118,11 +142,9 @@ err_ast_driver_unload: err_drm_dev_put:drm_dev_put (dev);return ret; - } -static void -ast_pci_remove (struct pci_dev *pdev) +static void ast_pci_remove (struct pci_dev *pdev) {struct drm_device *dev =pci_get_drvdata (pdev);
@@ -217,30 +239,12 @@ static const struct dev_pm_ops ast_pm_ops = {static struct pci_driver ast_pci_driver = { .name =DRIVER_NAME , - .id_table = pciidlist, + .id_table = ast_pciidlist, .probe = ast_pci_probe, .remove = ast_pci_remove, .driver.pm = &ast_pm_ops, }; -DEFINE_DRM_GEM_FOPS (ast_fops); - -static struct drm_driver driver = { - .driver_features =DRIVER_ATOMIC | -DRIVER_GEM | -DRIVER_MODESET , - - .fops = &ast_fops, - .name =DRIVER_NAME , - .desc =DRIVER_DESC , - .date =DRIVER_DATE , - .major =DRIVER_MAJOR , - .minor =DRIVER_MINOR , - .patchlevel =DRIVER_PATCHLEVEL , - -DRM_GEM_VRAM_DRIVER -}; -static int __init ast_init (void ) {if (vgacon_text_force () && ast_modeset ==-1 )
@@ -261,4 +265,3 @@ module_exit(ast_exit);MODULE_AUTHOR (DRIVER_AUTHOR );MODULE_DESCRIPTION (DRIVER_DESC );MODULE_LICENSE ("GPL and additional rights" ); -
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 74/391 drm/amdgpu: restore ras flags when user resets eeprom(v2)
In reply to Greg Kroah-HartmanFrom: Guchun Chen <[email protected]>
[ Upstream commit bf0b91b78f002faa1be1902a75eeb0797f9fbcf3 ]
RAS flags needs to be cleaned as well when user requires one clean eeprom.
v2: RAS flags shall be restored after eeprom reset succeeds.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +10 -3
@@ -367,12 +367,19 @@ static ssize_t amdgpu_ras_debugfs_ctrl_write(struct file *f, const char __user *static ssize_t amdgpu_ras_debugfs_eeprom_write (struct file *f,const char __user *buf,size_t size,loff_t *pos) { -struct amdgpu_device *adev = (struct amdgpu_device *)file_inode (f)->i_private; +struct amdgpu_device *adev = + (struct amdgpu_device *)file_inode (f)->i_private;int ret; - ret =amdgpu_ras_eeprom_reset_table (&adev->psp.ras.ras->eeprom_control); + ret =amdgpu_ras_eeprom_reset_table ( + &(amdgpu_ras_get_context (adev)->eeprom_control)); -return ret ==1 ? size : -EIO ; +if (ret ==1 ) { +amdgpu_ras_get_context (adev)->flags =RAS_DEFAULT_FLAGS ; +return size; + }else { +return -EIO ; + } }static const struct file_operations amdgpu_ras_debugfs_ctrl_ops = {
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 75/391 video: fbdev: pvr2fb: initialize variables
In reply to Greg Kroah-HartmanFrom: Tom Rix <[email protected]>
[ Upstream commit 8e1ba47c60bcd325fdd097cd76054639155e5d2e ]
clang static analysis reports this repesentative error
pvr2fb.c:1049:2: warning: 1st function call argument
is an uninitialized value [core.CallAndMessage]
if (*cable_arg)
^~~~~~~~~~~~~~~Problem is that cable_arg depends on the input loop to set the cable_arg[0]. If it does not, then some random value from the stack is used.
A similar problem exists for output_arg.
So initialize cable_arg and output_arg.
--- drivers/video/fbdev/pvr2fb.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/video/fbdev/pvr2fb.c +2 -0
@@ -1028,6 +1028,8 @@ static int __init pvr2fb_setup(char *options)if (!options || !*options)return 0 ; + cable_arg[0 ] = output_arg[0 ] =0 ; +while ((this_opt =strsep (&options,"," ))) {if (!*this_opt)continue ;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 76/391 ath10k: start recovery process when payload length exceeds max htc length for sdio
In reply to Greg Kroah-HartmanFrom: Wen Gong <[email protected]>
[ Upstream commit 2fd3c8f34d08af0a6236085f9961866ad92ef9ec ]
When simulate random transfer fail for sdio write and read, it happened "payload length exceeds max htc length" and recovery later sometimes.
Test steps:
1. Add config and update kernel:CONFIG_FAIL_MMC_REQUEST=yCONFIG_FAULT_INJECTION=yCONFIG_FAULT_INJECTION_DEBUG_FS=y
2. Run simulate fail:
cd /sys/kernel/debug/mmc1/fail_mmc_request
echo 10 > probability
echo 10 > times # repeat until hitting issues
3. It happened payload length exceeds max htc length.
[ 199.935506] ath10k_sdio mmc1:0001:1: payload length 57005 exceeds max htc length: 4088 .... [ 264.990191] ath10k_sdio mmc1:0001:1: payload length 57005 exceeds max htc length: 4088
4. after some time, such as 60 seconds, it start recovery which triggered by wmi command timeout for periodic scan.
[ 269.229232] ieee80211 phy0: Hardware restart was requested [ 269.734693] ath10k_sdio mmc1:0001:1: device successfully recovered
The simulate fail of sdio is not a real sdio transter fail, it only set an error status in mmc_should_fail_request after the transfer end, actually the transfer is success, then sdio_io_rw_ext_helper will return error status and stop transfer the left data. For example, the really RX len is 286 bytes, then it will split to 2 blocks in sdio_io_rw_ext_helper, one is 256 bytes, left is 30 bytes, if the first 256 bytes get an error status by mmc_should_fail_request,then the left 30 bytes will not read in this RX operation. Then when the next RX arrive, the left 30 bytes will be considered as the header of the read, the top 4 bytes of the 30 bytes will be considered as lookaheads, but actually the 4 bytes is not the lookaheads, so the len from this lookaheads is not correct, it exceeds max htc length 4088 sometimes. When happened exceeds, the buffer chain is not matched between firmware and ath10k, then it need to start recovery ASAP. Recently then recovery will be started by wmi command timeout, but it will be long time later, for example, it is 60+ seconds later from the periodic scan, if it does not have periodic scan, it will be longer.
Start recovery when it happened "payload length exceeds max htc length" will be reasonable.
This patch only effect sdio chips.
Tested with QCA6174 SDIO with firmware WLAN.RMH.4.4.1-00029.
--- drivers/net/wireless/ath/ath10k/sdio.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/wireless/ath/ath10k/sdio.c +4 -0
@@ -557,6 +557,10 @@ static int ath10k_sdio_mbox_rx_alloc(struct ath10k *ar,le16_to_cpu (htc_hdr->len), ATH10K_HTC_MBOX_MAX_PAYLOAD_LENGTH); ret = -ENOMEM ; + +queue_work (ar->workqueue, &ar->restart_work); +ath10k_warn (ar,"exceeds length, start recovery\n" ); + goto err; }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 77/391 ath10k: fix VHT NSS calculation when STBC is enabled
In reply to Greg Kroah-HartmanFrom: Sathishkumar Muruganandam <[email protected]>
[ Upstream commit 99f41b8e43b8b4b31262adb8ac3e69088fff1289 ]
When STBC is enabled, NSTS_SU value need to be accounted for VHT NSS calculation for SU case.
Without this fix, 1SS + STBC enabled case was reported wrongly as 2SS in radiotap header on monitor mode capture.
Tested-on: QCA9984 10.4-3.10-00047
--- drivers/net/wireless/ath/ath10k/htt_rx.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/net/wireless/ath/ath10k/htt_rx.c +7 -1
@@ -949,6 +949,7 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar,u8 preamble =0 ;u8 group_id;u32 info1, info2, info3; +u32 stbc, nsts_su; info1 =__le32_to_cpu (rxd->ppdu_start.info1); info2 =__le32_to_cpu (rxd->ppdu_start.info2);
@@ -993,11 +994,16 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar,*/ bw = info2 &3 ; sgi = info3 &1 ; + stbc = (info2 >>3 ) &1 ; group_id = (info2 >>4 ) &0x3F ;if (GROUP_ID_IS_SU_MIMO (group_id)) { mcs = (info3 >>4 ) &0x0F ; - nss = ((info2 >>10 ) &0x07 ) +1 ; + nsts_su = ((info2 >>10 ) &0x07 ); +if (stbc) + nss = (nsts_su >>2 ) +1 ; +else + nss = (nsts_su +1 ); }else {/* Hardware doesn't decode VHT-SIG-B into Rx descriptor * so it's impossible to decode MCS. Also since
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 78/391 drm/scheduler: Scheduler priority fixes (v2)
In reply to Greg Kroah-HartmanFrom: Luben Tuikov <[email protected]>
[ Upstream commit e2d732fdb7a9e421720a644580cd6a9400f97f60 ]
Remove DRM_SCHED_PRIORITY_LOW, as it was used in only one place.
Rename and separate by a line DRM_SCHED_PRIORITY_MAX to DRM_SCHED_PRIORITY_COUNT as it represents a (total) count of said priorities and it is used as such in loops throughout the code. (0-based indexing is the the count number.)
Remove redundant word HIGH in priority names, and rename *KERNEL* to *HIGH*, as it really means that, high.
v2: Add back KERNEL and remove SW and HW,
in lieu of a single HIGH between NORMAL and KERNEL.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 6 +++--- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +- drivers/gpu/drm/scheduler/sched_main.c | 4 ++-- include/drm/gpu_scheduler.h | 12 +++++++----- 8 files changed, 18 insertions(+), 16 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +2 -2
@@ -46,7 +46,7 @@ const unsigned int amdgpu_ctx_num_entities[AMDGPU_HW_IP_NUM] = {static int amdgpu_ctx_priority_permit (struct drm_file *filp,enum drm_sched_priority priority) { -if (priority <0 || priority >=DRM_SCHED_PRIORITY_MAX ) +if (priority <0 || priority >=DRM_SCHED_PRIORITY_COUNT )return -EINVAL ;/* NORMAL and below are accessible by everyone */
@@ -65,7 +65,7 @@ static int amdgpu_ctx_priority_permit(struct drm_file *filp,static enum gfx_pipe_priority amdgpu_ctx_sched_prio_to_compute_prio (enum drm_sched_priority prio) {switch (prio) { -case DRM_SCHED_PRIORITY_HIGH_HW : +case DRM_SCHED_PRIORITY_HIGH :case DRM_SCHED_PRIORITY_KERNEL :return AMDGPU_GFX_PIPE_PRIO_HIGH ;default :
drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +1 -1
@@ -251,7 +251,7 @@ void amdgpu_job_stop_all_jobs_on_sched(struct drm_gpu_scheduler *sched)int i;/* Signal all jobs not yet scheduled */ -for (i =DRM_SCHED_PRIORITY_MAX -1 ; i >=DRM_SCHED_PRIORITY_MIN ; i--) { +for (i =DRM_SCHED_PRIORITY_COUNT -1 ; i >=DRM_SCHED_PRIORITY_MIN ; i--) {struct drm_sched_rq *rq = &sched->sched_rq[i];if (!rq)
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +1 -1
@@ -267,7 +267,7 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, &ring->sched; } -for (i =0 ; i <DRM_SCHED_PRIORITY_MAX ; ++i) +for (i =DRM_SCHED_PRIORITY_MIN ; i <DRM_SCHED_PRIORITY_COUNT ; ++i)atomic_set (&ring->num_jobs[i],0 );return 0 ;
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +1 -1
@@ -243,7 +243,7 @@ struct amdgpu_ring {bool has_compute_vm_bug;bool no_scheduler; -atomic_t num_jobs[DRM_SCHED_PRIORITY_MAX ]; +atomic_t num_jobs[DRM_SCHED_PRIORITY_COUNT ];struct mutex priority_mutex;/* protected by priority_mutex */ int priority;
drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +3 -3
@@ -36,14 +36,14 @@ enum drm_sched_priority amdgpu_to_sched_priority(int amdgpu_priority) {switch (amdgpu_priority) {case AMDGPU_CTX_PRIORITY_VERY_HIGH : -return DRM_SCHED_PRIORITY_HIGH_HW ; +return DRM_SCHED_PRIORITY_HIGH ;case AMDGPU_CTX_PRIORITY_HIGH : -return DRM_SCHED_PRIORITY_HIGH_SW ; +return DRM_SCHED_PRIORITY_HIGH ;case AMDGPU_CTX_PRIORITY_NORMAL :return DRM_SCHED_PRIORITY_NORMAL ;case AMDGPU_CTX_PRIORITY_LOW :case AMDGPU_CTX_PRIORITY_VERY_LOW : -return DRM_SCHED_PRIORITY_LOW ; +return DRM_SCHED_PRIORITY_MIN ;case AMDGPU_CTX_PRIORITY_UNSET :return DRM_SCHED_PRIORITY_UNSET ;default :
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +1 -1
@@ -2101,7 +2101,7 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable) ring = adev->mman.buffer_funcs_ring; sched = &ring->sched; r =drm_sched_entity_init (&adev->mman.entity, -DRM_SCHED_PRIORITY_KERNEL , &sched, +DRM_SCHED_PRIORITY_KERNEL , &sched,1 ,NULL );if (r) { DRM_ERROR("Failed setting up TTM BO move entity (%d)\n",
drivers/gpu/drm/scheduler/sched_main.c +2 -2
@@ -625,7 +625,7 @@ drm_sched_select_entity(struct drm_gpu_scheduler *sched)return NULL ;/* Kernel run queue has higher priority than normal run queue*/ -for (i =DRM_SCHED_PRIORITY_MAX -1 ; i >=DRM_SCHED_PRIORITY_MIN ; i--) { +for (i =DRM_SCHED_PRIORITY_COUNT -1 ; i >=DRM_SCHED_PRIORITY_MIN ; i--) { entity =drm_sched_rq_select_entity (&sched->sched_rq[i]);if (entity)break ;
@@ -852,7 +852,7 @@ int drm_sched_init(struct drm_gpu_scheduler *sched, sched->name = name; sched->timeout = timeout; sched->hang_limit = hang_limit; -for (i =DRM_SCHED_PRIORITY_MIN ; i <DRM_SCHED_PRIORITY_MAX ; i++) +for (i =DRM_SCHED_PRIORITY_MIN ; i <DRM_SCHED_PRIORITY_COUNT ; i++)drm_sched_rq_init (sched, &sched->sched_rq[i]);init_waitqueue_head (&sched->wake_up_worker);
include/drm/gpu_scheduler.h +7 -5
@@ -33,14 +33,16 @@struct drm_gpu_scheduler ;struct drm_sched_rq ; +/* These are often used as an (initial) index +* to an array, and as such should start at 0. +*/ enum drm_sched_priority {DRM_SCHED_PRIORITY_MIN , -DRM_SCHED_PRIORITY_LOW =DRM_SCHED_PRIORITY_MIN ,DRM_SCHED_PRIORITY_NORMAL , -DRM_SCHED_PRIORITY_HIGH_SW , -DRM_SCHED_PRIORITY_HIGH_HW , +DRM_SCHED_PRIORITY_HIGH ,DRM_SCHED_PRIORITY_KERNEL , -DRM_SCHED_PRIORITY_MAX , + +DRM_SCHED_PRIORITY_COUNT ,DRM_SCHED_PRIORITY_INVALID =-1 ,DRM_SCHED_PRIORITY_UNSET =-2 };
@@ -274,7 +276,7 @@ struct drm_gpu_scheduler {uint32_t hw_submission_limit;long timeout;const char *name; -struct drm_sched_rq sched_rq[DRM_SCHED_PRIORITY_MAX ]; +struct drm_sched_rq sched_rq[DRM_SCHED_PRIORITY_COUNT ];wait_queue_head_t wake_up_worker;wait_queue_head_t job_scheduled;atomic_t hw_rq_count;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 79/391 drm/brige/megachips: Add checking if ge_b850v3_lvds_init() is working correctly
In reply to Greg Kroah-HartmanFrom: Nadezda Lutovinova <[email protected]>
[ Upstream commit f688a345f0d7a6df4dd2aeca8e4f3c05e123a0ee ]
If ge_b850v3_lvds_init() does not allocate memory for ge_b850v3_lvds_ptr, then a null pointer dereference is accessed.
The patch adds checking of the return value of ge_b850v3_lvds_init().
Found by Linux Driver Verification project (linuxtesting.org).
--- .../gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c +10 -2
@@ -302,8 +302,12 @@ static int stdp4028_ge_b850v3_fw_probe(struct i2c_client *stdp4028_i2c, const struct i2c_device_id *id) {struct device *dev = &stdp4028_i2c->dev; +int ret; + + ret =ge_b850v3_lvds_init (dev); -ge_b850v3_lvds_init (dev); +if (ret) +return ret; ge_b850v3_lvds_ptr->stdp4028_i2c = stdp4028_i2c;i2c_set_clientdata (stdp4028_i2c, ge_b850v3_lvds_ptr);
@@ -361,8 +365,12 @@ static int stdp2690_ge_b850v3_fw_probe(struct i2c_client *stdp2690_i2c, const struct i2c_device_id *id) {struct device *dev = &stdp2690_i2c->dev; +int ret; + + ret =ge_b850v3_lvds_init (dev); -ge_b850v3_lvds_init (dev); +if (ret) +return ret; ge_b850v3_lvds_ptr->stdp2690_i2c = stdp2690_i2c;i2c_set_clientdata (stdp2690_i2c, ge_b850v3_lvds_ptr);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 80/391 ASoC: SOF: fix a runtime pm issue in SOF when HDMI codec doesnt work
In reply to Greg Kroah-HartmanFrom: Rander Wang <[email protected]>
[ Upstream commit 6c63c954e1c52f1262f986f36d95f557c6f8fa94 ]
When hda_codec_probe() doesn't initialize audio component, we disable the codec and keep going. However,the resources are not released. The child_count of SOF device is increased in snd_hdac_ext_bus_device_init but is not decrease in error case, so SOF can't get suspended.
snd_hdac_ext_bus_device_exit will be invoked in HDA framework if it gets a error. Now copy this behavior to release resources and decrease SOF device child_count to release SOF device.
--- sound/soc/sof/intel/hda-codec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/sof/intel/hda-codec.c +2 -2
@@ -151,7 +151,7 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,if (!hdev->bus->audio_component) {dev_dbg (sdev->dev,"iDisp hw present but no driver\n" ); -return -ENOENT ; + goto error; } hda_priv->need_display_power = true; }
@@ -174,7 +174,7 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,* other return codes without modification */ if (ret ==0 ) - ret = -ENOENT ; + goto error; }return ret;
Signature · 1 line
2.27.0
Re: [PATCH 5.9 080/391] ASoC: SOF: fix a runtime pm issue in SOF when HDMI codec doesnt work
Greg Kroah-Hartman schreef op di 03-11-2020 om 21:32 [+0100]:
Quoted 39 lines
From: Rander Wang <[email protected]>
[ Upstream commit
6c63c954e1c52f1262f986f36d95f557c6f8fa94]When
hda_codec_probe()doesn't initialize audio component, we disable the codec and keep going. However,the resources are not released. Thechild_countof SOF device is increased insnd_hdac_ext_bus_device_initbut is not decrease in error case, so SOF can't get suspended.
snd_hdac_ext_bus_device_exitwill be invoked in HDA framework if it gets a error. Now copy this behavior to release resources and decrease SOF devicechild_countto release SOF device.Signed-off-by Rander Wang <[email protected]>Reviewed-by Pierre-Louis Bossart <[email protected]>Reviewed-by Bard Liao <[email protected]>Reviewed-by Guennadi Liakhovetski <[email protected]>Signed-off-by Ranjani Sridharan <[email protected]>Signed-off-by Mark Brown <[email protected]>Signed-off-by Sasha Levin <[email protected]>--- sound/soc/sof/intel/hda-codec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)sound/soc/sof/intel/hda-codec.c +1
-1@@ -151,7 +151,7 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,if (!hdev->bus->audio_component) {dev_dbg (sdev->dev,"iDisp hw present but no driver\n" ); -return -ENOENT ; + goto error; } hda_priv->need_display_power = true; }
sound/soc/sof/intel/hda-codec.c static int hda_codec_probe(struct snd_sof_dev *sdev, int address, · line 180
Quoted 8 lines
sound/soc/sof/intel/hda-codec.c +1
-1@@ -174,7 +174,7 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,* other return codes without modification */ if (ret ==0 ) - ret = -ENOENT ; + goto error; }return ret;
My local build of v5.9.5 broke on this patch.
sound/soc/sof/intel/hda-codec.c: In function 'hda_codec_probe':sound/soc/sof/intel/hda-codec.c:177:4: error: label 'error' used but not defined
177 | goto error;
| ^~~~ make[4]: *** [scripts/Makefile.build:283: sound/soc/sof/intel/hda-codec.o] Error 1 make[3]: *** [scripts/Makefile.build:500: sound/soc/sof/intel] Error 2 make[2]: *** [scripts/Makefile.build:500: sound/soc/sof] Error 2 make[1]: *** [scripts/Makefile.build:500: sound/soc] Error 2
make: *** [Makefile:1778: sound] Error 2
There's indeed no error label in v5.9.5. (There is one in v5.10-rc2, I just checked.) Is no-one else running into this?
Thanks,
Paul Bolle
Sasha Levin
maintainerRe: [PATCH 5.9 080/391] ASoC: SOF: fix a runtime pm issue in SOF when HDMI codec doesnt work
Quoted 55 lines · Paul Bolle
Greg Kroah-Hartman schreef op di 03-11-2020 om 21:32 [+0100]:
Quoted 39 lines
From: Rander Wang <[email protected]>
[ Upstream commit
6c63c954e1c52f1262f986f36d95f557c6f8fa94]When
hda_codec_probe()doesn't initialize audio component, we disable the codec and keep going. However,the resources are not released. Thechild_countof SOF device is increased insnd_hdac_ext_bus_device_initbut is not decrease in error case, so SOF can't get suspended.
snd_hdac_ext_bus_device_exitwill be invoked in HDA framework if it gets a error. Now copy this behavior to release resources and decrease SOF devicechild_countto release SOF device.Signed-off-by Rander Wang <[email protected]>Reviewed-by Pierre-Louis Bossart <[email protected]>Reviewed-by Bard Liao <[email protected]>Reviewed-by Guennadi Liakhovetski <[email protected]>Signed-off-by Ranjani Sridharan <[email protected]>Signed-off-by Mark Brown <[email protected]>Signed-off-by Sasha Levin <[email protected]>--- sound/soc/sof/intel/hda-codec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)sound/soc/sof/intel/hda-codec.c +1
-1@@ -151,7 +151,7 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,if (!hdev->bus->audio_component) {dev_dbg (sdev->dev,"iDisp hw present but no driver\n" ); -return -ENOENT ; + goto error; } hda_priv->need_display_power = true; }sound/soc/sof/intel/hda-codec.c static int hda_codec_probe(struct snd_sof_dev *sdev, int address, · line 180
Quoted 8 lines
sound/soc/sof/intel/hda-codec.c +1
-1@@ -174,7 +174,7 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,* other return codes without modification */ if (ret ==0 ) - ret = -ENOENT ; + goto error; }return ret;My local build of v5.9.5 broke on this patch.
sound/soc/sof/intel/hda-codec.c: In function 'hda_codec_probe':sound/soc/sof/intel/hda-codec.c:177:4: error: label 'error' used but not defined177 | goto error; | ^~~~
Quoted 8 lines
make[4]: *** [
scripts/Makefile.build:283:sound/soc/sof/intel/hda-codec.o] Error 1 make[3]: *** [scripts/Makefile.build:500:sound/soc/sof/intel] Error 2 make[2]: *** [scripts/Makefile.build:500:sound/soc/sof] Error 2 make[1]: *** [scripts/Makefile.build:500:sound/soc] Error 2
make: *** [Makefile:1778: sound] Error 2There's indeed no error label in v5.9.5. (There is one in v5.10-rc2, I just checked.) Is no-one else running into this?
It seems that setting CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC=y is very "difficult", it's not being set by allmodconfig nor is it easy to manually set it up.
I'll revert the patch, but it would be nice to make sure it's easier to test this out too.
Signature · 2 lines
Thanks, Sasha
Re: [PATCH 5.9 080/391] ASoC: SOF: fix a runtime pm issue in SOF when HDMI codec doesnt work
Quoted 68 lines · Sasha Levin
Quoted 64 lines · Paul Bolle
Greg Kroah-Hartman schreef op di 03-11-2020 om 21:32 [+0100]:
Quoted 49 lines
From: Rander Wang <[email protected]>
[ Upstream commit
6c63c954e1c52f1262f986f36d95f557c6f8fa94]When
hda_codec_probe()doesn't initialize audio component, we disable the codec and keep going. However,the resources are not released. Thechild_countof SOF device is increased insnd_hdac_ext_bus_device_initbut is not decrease in error case, so SOF can't get suspended.
snd_hdac_ext_bus_device_exitwill be invoked in HDA framework if it gets a error. Now copy this behavior to release resources and decrease SOF devicechild_countto release SOF device.Signed-off-by Rander Wang <[email protected]>Reviewed-by Pierre-Louis Bossart <[email protected]>Reviewed-by Bard Liao <[email protected]>Reviewed-by Guennadi Liakhovetski <[email protected]>Signed-off-by Ranjani Sridharan <[email protected]>Signed-off-by Mark Brown <[email protected]>Signed-off-by Sasha Levin <[email protected]>---
sound/soc/sof/intel/hda-codec.c | 4 ++--1 file changed, 2 insertions(+), 2 deletions(-)sound/soc/sof/intel/hda-codec.c +1
-1@@ -151,7 +151,7 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address, if (!hdev->bus->audio_component) { dev_dbg(sdev->dev, "iDisp hw present but no driver\n"); - return -ENOENT; + goto error; } hda_priv->need_display_power = true;}
sound/soc/sof/intel/hda-codec.c +1
-1@@ -174,7 +174,7 @@ static int hda_codec_probe(struct snd_sof_dev*sdev, int address, * other return codes without modification */ if (ret == 0) - ret = -ENOENT; + goto error; }Quoted 1 line
return ret;
My local build of v5.9.5 broke on this patch.
sound/soc/sof/intel/hda-codec.c: In function 'hda_codec_probe':sound/soc/sof/intel/hda-codec.c:177:4: error: label 'error' used but not defined 177 | goto error;
| ^~~~
make[4]: *** [scripts/Makefile.build:283:sound/soc/sof/intel/hda-codec.o] Error 1 make[3]: *** [scripts/Makefile.build:500:sound/soc/sof/intel] Error 2 make[2]: *** [scripts/Makefile.build:500:sound/soc/sof] Error 2 make[1]: *** [scripts/Makefile.build:500:sound/soc] Error 2
make: *** [Makefile:1778: sound] Error 2Quoted 2 lines
There's indeed no error label in v5.9.5. (There is one in v5.10-rc2, I just checked.) Is no-one else running into this?
Quoted 6 lines
It seems that setting
CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC=yis very "difficult", it's not being set by allmodconfig nor is it easy to manually set it up.I'll revert the patch, but it would be nice to make sure it's easier to test this out too.
this issue comes from out-of-order patches, give me a couple of hours to look into this before reverting. thanks!
Sasha Levin
maintainerRe: [PATCH 5.9 080/391] ASoC: SOF: fix a runtime pm issue in SOF when HDMI codec doesnt work
Quoted 71 lines · Pierre-Louis Bossart
Quoted 68 lines · Sasha Levin
Quoted 66 lines · Paul Bolle
Greg Kroah-Hartman schreef op di 03-11-2020 om 21:32 [+0100]:
Quoted 49 lines
From: Rander Wang <[email protected]>
[ Upstream commit
6c63c954e1c52f1262f986f36d95f557c6f8fa94]When
hda_codec_probe()doesn't initialize audio component, we disable the codec and keep going. However,the resources are not released. Thechild_countof SOF device is increased insnd_hdac_ext_bus_device_initbut is not decrease in error case, so SOF can't get suspended.
snd_hdac_ext_bus_device_exitwill be invoked in HDA framework if it gets a error. Now copy this behavior to release resources and decrease SOF devicechild_countto release SOF device.Signed-off-by Rander Wang <[email protected]>Reviewed-by Pierre-Louis Bossart <[email protected]>Reviewed-by Bard Liao <[email protected]>Reviewed-by Guennadi Liakhovetski <[email protected]>Signed-off-by Ranjani Sridharan <[email protected]>Signed-off-by Mark Brown <[email protected]>Signed-off-by Sasha Levin <[email protected]>---
sound/soc/sof/intel/hda-codec.c | 4 ++--1 file changed, 2 insertions(+), 2 deletions(-)sound/soc/sof/intel/hda-codec.c +1
-1@@ -151,7 +151,7 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address, if (!hdev->bus->audio_component) { dev_dbg(sdev->dev, "iDisp hw present but no driver\n"); - return -ENOENT; + goto error; } hda_priv->need_display_power = true;}
sound/soc/sof/intel/hda-codec.c +1
-1@@ -174,7 +174,7 @@ static int hda_codec_probe(structsnd_sof_dev *sdev, int address, * other return codes without modification */ if (ret == 0) - ret = -ENOENT; + goto error; }Quoted 1 line
return ret;
My local build of v5.9.5 broke on this patch.
sound/soc/sof/intel/hda-codec.c: In function 'hda_codec_probe':sound/soc/sof/intel/hda-codec.c:177:4: error: label 'error' used but not defined 177 | goto error;
| ^~~~
make[4]: *** [scripts/Makefile.build:283:sound/soc/sof/intel/hda-codec.o] Error 1 make[3]: *** [scripts/Makefile.build:500:sound/soc/sof/intel] Error 2 make[2]: *** [scripts/Makefile.build:500:sound/soc/sof] Error 2 make[1]: *** [scripts/Makefile.build:500:sound/soc] Error 2
make: *** [Makefile:1778: sound] Error 2There's indeed no error label in v5.9.5. (There is one in v5.10-rc2, I just checked.) Is no-one else running into this?
Quoted 8 lines
Quoted 6 lines
It seems that setting
CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC=yis very "difficult", it's not being set by allmodconfig nor is it easy to manually set it up.I'll revert the patch, but it would be nice to make sure it's easier to test this out too.
this issue comes from out-of-order patches, give me a couple of hours to look into this before reverting. thanks!
Sure! Thanks for looking into this.
Signature · 2 lines
Thanks, Sasha
Re: [PATCH 5.9 080/391] ASoC: SOF: fix a runtime pm issue in SOF when HDMI codec doesnt work
Quoted 20 lines
Quoted 20 lines
Quoted 20 lines
Quoted 13 lines
My local build of v5.9.5 broke on this patch.
sound/soc/sof/intel/hda-codec.c: In function 'hda_codec_probe':sound/soc/sof/intel/hda-codec.c:177:4: error: label 'error' used but not defined 177 | goto error;
| ^~~~
make[4]: *** [scripts/Makefile.build:283:sound/soc/sof/intel/hda-codec.o] Error 1 make[3]: *** [scripts/Makefile.build:500:sound/soc/sof/intel] Error 2 make[2]: *** [scripts/Makefile.build:500:sound/soc/sof] Error 2 make[1]: *** [scripts/Makefile.build:500:sound/soc] Error 2
make: *** [Makefile:1778: sound] Error 2Quoted 2 lines
There's indeed no error label in v5.9.5. (There is one in v5.10-rc2, I just checked.) Is no-one else running into this?
It seems that setting
CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC=yis very "difficult", it's not being set by allmodconfig nor is it easy to manually set it up.
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines
I'll revert the patch, but it would be nice to make sure it's easier to test this out too.
this issue comes from out-of-order patches, give me a couple of hours to look into this before reverting. thanks!
Sure! Thanks for looking into this.
I would recommend adding this commit to 5.9-stable:
11ec0edc6408a ('ASOC: SOF: Intel: hda-codec: move unused label to correct position')
I just tried with 5.9.5 and the compilation error is solved with this commit.
It was initially intended to solve a minor 'defined but not used' issue, which somehow became a bad 'used but not defined' one. Probably a bad git merge I did, sorry about that.
Thanks!
-Pierre
Greg Kroah-Hartman
maintainerRe: [PATCH 5.9 080/391] ASoC: SOF: fix a runtime pm issue in SOF when HDMI codec doesnt work
Quoted 36 lines · Pierre-Louis Bossart
Quoted 23 lines
Quoted 23 lines
Quoted 23 lines
Quoted 15 lines
My local build of v5.9.5 broke on this patch.
sound/soc/sof/intel/hda-codec.c: In function 'hda_codec_probe':sound/soc/sof/intel/hda-codec.c:177:4: error: label 'error' used but not defined
177 | goto error;
| ^~~~
make[4]: *** [scripts/Makefile.build:283:sound/soc/sof/intel/hda-codec.o] Error 1
make[3]: *** [scripts/Makefile.build:500:sound/soc/sof/intel] Error 2 make[2]: *** [scripts/Makefile.build:500:sound/soc/sof] Error 2 make[1]: *** [scripts/Makefile.build:500:sound/soc] Error 2
make: *** [Makefile:1778: sound] Error 2Quoted 3 lines
There's indeed no error label in v5.9.5. (There is one in v5.10-rc2, I just
checked.) Is no-one else running into this?It seems that setting
CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC=yis very "difficult", it's not being set by allmodconfig nor is it easy to manually set it up.Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
I'll revert the patch, but it would be nice to make sure it's easier to test this out too.
this issue comes from out-of-order patches, give me a couple of hours to look into this before reverting. thanks!
Sure! Thanks for looking into this.
I would recommend adding this commit to 5.9-stable:
11ec0edc6408a('ASOC: SOF: Intel: hda-codec: move unused label to correct position')
Quoted 6 lines
I just tried with 5.9.5 and the compilation error is solved with this commit.
It was initially intended to solve a minor 'defined but not used' issue, which somehow became a bad 'used but not defined' one. Probably a bad git merge I did, sorry about that.
Will go do that now and push out a new release, thanks!
greg k-h
Greg Kroah-Hartman
maintainerPATCH 81/391 selftests/x86/fsgsbase: Reap a forgotten child
In reply to Greg Kroah-HartmanFrom: Andy Lutomirski <[email protected]>
[ Upstream commit ab2dd173330a3f07142e68cd65682205036cd00f ]
The ptrace() test forgot to reap its child. Reap it.
--- tools/testing/selftests/x86/fsgsbase.c | 3 +++ 1 file changed, 3 insertions(+)
tools/testing/selftests/x86/fsgsbase.c +3 -0
@@ -517,6 +517,9 @@ static void test_ptrace_write_gsbase(void) END:ptrace (PTRACE_CONT , child,NULL ,NULL ); +wait (&status); +if (!WIFEXITED (status)) +printf ("[WARN]\tChild didn't exit cleanly.\n" ); }int main ()
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 82/391 drm/bridge_connector: Set default status connected for eDP connectors
In reply to Greg Kroah-HartmanFrom: Enric Balletbo i Serra <[email protected]>
[ Upstream commit c5589b39549d1875bb506da473bf4580c959db8c ]
In an eDP application, HPD is not required and on most bridge chips useless. If HPD is not used, we need to set initial status as connected, otherwise the connector created by the drm_bridge_connector API remains in an unknown state.
--- drivers/gpu/drm/drm_bridge_connector.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/drm_bridge_connector.c +1 -0
@@ -187,6 +187,7 @@ drm_bridge_connector_detect(struct drm_connector *connector, bool force)case DRM_MODE_CONNECTOR_DPI :case DRM_MODE_CONNECTOR_LVDS :case DRM_MODE_CONNECTOR_DSI : +case DRM_MODE_CONNECTOR_eDP: status = connector_status_connected;break ;default :
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 83/391 media: videodev2.h: RGB BT2020 and HSV are always full range
In reply to Greg Kroah-HartmanFrom: Hans Verkuil <[email protected]>
[ Upstream commit b305dfe2e93434b12d438434461b709641f62af4 ]
The default RGB quantization range for BT.2020 is full range (just as for all the other RGB pixel encodings), not limited range.
Update the V4L2_MAP_QUANTIZATION_DEFAULT macro and documentation accordingly.
Also mention that HSV is always full range and cannot be limited range.
When RGB BT2020 was introduced in V4L2 it was not clear whether it should be limited or full range, but full range is the right (and consistent) choice.
--- .../media/v4l/colorspaces-defs.rst | 9 ++++----- .../media/v4l/colorspaces-details.rst | 5 ++--- include/uapi/linux/videodev2.h | 17 ++++++++--------- 3 files changed, 14 insertions(+), 17 deletions(-)
Documentation/userspace-api/media/v4l/colorspaces-defs.rst +4 -5
@@ -36,8 +36,7 @@ whole range, 0-255, dividing the angular value by 1.41. The enum :c:type:`v4l2_hsv_encoding` specifies which encoding is used. .. note:: The default R'G'B' quantization is full range for all - colorspaces except for BT.2020 which uses limited range R'G'B' - quantization. + colorspaces. HSV formats are always full range. .. tabularcolumns:: |p{6.7cm}|p{10.8cm}|
@@ -169,8 +168,8 @@ whole range, 0-255, dividing the angular value by 1.41. The enum - Details * - ``V4L2_QUANTIZATION_DEFAULT`` - Use the default quantization encoding as defined by the - colorspace. This is always full range for R'G'B' (except for the - BT.2020 colorspace) and HSV. It is usually limited range for Y'CbCr. + colorspace. This is always full range for R'G'B' and HSV. + It is usually limited range for Y'CbCr. * - ``V4L2_QUANTIZATION_FULL_RANGE`` - Use the full range quantization encoding. I.e. the range [0…1] is mapped to [0…255] (with possible clipping to [1…254] to avoid the
@@ -180,4 +179,4 @@ whole range, 0-255, dividing the angular value by 1.41. The enum * - ``V4L2_QUANTIZATION_LIM_RANGE`` - Use the limited range quantization encoding. I.e. the range [0…1] is mapped to [16…235]. Cb and Cr are mapped from [-0.5…0.5] to - [16…240]. + [16…240]. Limited Range cannot be used with HSV.
Documentation/userspace-api/media/v4l/colorspaces-details.rst +2 -3
@@ -377,9 +377,8 @@ Colorspace BT.2020 (V4L2_COLORSPACE_BT2020) The :ref:`itu2020` standard defines the colorspace used by Ultra-high definition television (UHDTV). The default transfer function is ``V4L2_XFER_FUNC_709``. The default Y'CbCr encoding is -``V4L2_YCBCR_ENC_BT2020``. The default R'G'B' quantization is limited -range (!), and so is the default Y'CbCr quantization. The chromaticities -of the primary colors and the white reference are: +``V4L2_YCBCR_ENC_BT2020``. The default Y'CbCr quantization is limited range. +The chromaticities of the primary colors and the white reference are:
include/uapi/linux/videodev2.h +8 -9
@@ -373,9 +373,9 @@ enum v4l2_hsv_encoding {enum v4l2_quantization {/* -* The default for R'G'B' quantization is always full range, except -* for the BT2020 colorspace. For Y'CbCr the quantization is always -* limited range, except for COLORSPACE_JPEG: this is full range. +* The default for R'G'B' quantization is always full range. +* For Y'CbCr the quantization is always limited range, except +* for COLORSPACE_JPEG: this is full range. */ V4L2_QUANTIZATION_DEFAULT =0 ,V4L2_QUANTIZATION_FULL_RANGE =1 ,
@@ -384,14 +384,13 @@ enum v4l2_quantization {/* * Determine how QUANTIZATION_DEFAULT should map to a proper quantization. -* This depends on whether the image is RGB or not, the colorspace and the -* Y'CbCr encoding. +* This depends on whether the image is RGB or not, the colorspace. +* The Y'CbCr encoding is not used anymore, but is still there for backwards +* compatibility. */ #define V4L2_MAP_QUANTIZATION_DEFAULT (is_rgb_or_hsv, colsp, ycbcr_enc) \ - (((is_rgb_or_hsv) && (colsp) == V4L2_COLORSPACE_BT2020) ? \ - V4L2_QUANTIZATION_LIM_RANGE : \ - (((is_rgb_or_hsv) || (colsp) == V4L2_COLORSPACE_JPEG) ? \ - V4L2_QUANTIZATION_FULL_RANGE : V4L2_QUANTIZATION_LIM_RANGE)) + (((is_rgb_or_hsv) || (colsp) == V4L2_COLORSPACE_JPEG) ? \ + V4L2_QUANTIZATION_FULL_RANGE : V4L2_QUANTIZATION_LIM_RANGE)/* * Deprecated names for opRGB colorspace (IEC 61966-2-5)
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 84/391 ASoC: AMD: Clean kernel log from deferred probe error messages
In reply to Greg Kroah-HartmanFrom: Akshu Agrawal <[email protected]>
[ Upstream commit f7660445c8e7fda91e8b944128554249d886b1d4 ]
While the driver waits for DAIs to be probed and retries probing, have the error messages at debug level instead of error.
--- sound/soc/amd/acp3x-rt5682-max9836.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
sound/soc/amd/acp3x-rt5682-max9836.c +8 -3
@@ -472,12 +472,17 @@ static int acp3x_probe(struct platform_device *pdev) ret =devm_snd_soc_register_card (&pdev->dev, card);if (ret) { -dev_err (&pdev->dev, +if (ret != -EPROBE_DEFER ) +dev_err (&pdev->dev,"devm_snd_soc_register_card(%s) failed: %d\n" , card->name, ret); -return ret; +else +dev_dbg (&pdev->dev, +"devm_snd_soc_register_card(%s) probe deferred: %d\n" , + card->name, ret); } -return 0 ; + +return ret; }static const struct acpi_device_id acp3x_audio_acpi_match[] = {
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 85/391 misc: fastrpc: fix common struct sg_table related issues
In reply to Greg Kroah-HartmanFrom: Marek Szyprowski <[email protected]>
[ Upstream commit 7cd7edb89437457ec36ffdbb970cc314d00c4aba ]
The Documentation/DMA-API-HOWTO.txt states that the dma_map_sg() function returns the number of the created entries in the DMA address space. However the subsequent calls to the dma_sync_sg_for_{device,cpu}() and dma_unmap_sg must be called with the original number of the entries passed to the dma_map_sg().
struct sg_table is a common structure used for describing a non-contiguous memory buffer, used commonly in the DRM and graphics subsystems. It consists of a scatterlist with memory pages and DMA addresses (sgl entry), as well as the number of scatterlist entries: CPU pages (orig_nents entry) and DMA mapped pages (nents entry).
It turned out that it was a common mistake to misuse nents and orig_nents entries, calling DMA-mapping functions with a wrong number of entries or ignoring the number of mapped entries returned by the dma_map_sg() function.
To avoid such issues, lets use a common dma-mapping wrappers operating directly on the struct sg_table objects and use scatterlist page iterators where possible. This, almost always, hides references to the nents and orig_nents entries, making the code robust, easier to follow and copy/paste safe.
--- drivers/misc/fastrpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/misc/fastrpc.c +2 -2
@@ -518,7 +518,7 @@ fastrpc_map_dma_buf(struct dma_buf_attachment *attachment, table = &a->sgt; -if (!dma_map_sg (attachment->dev, table->sgl, table->nents, dir)) +if (!dma_map_sgtable (attachment->dev, table, dir,0 ))return ERR_PTR (-ENOMEM );return table;
@@ -528,7 +528,7 @@ static void fastrpc_unmap_dma_buf(struct dma_buf_attachment *attach,struct sg_table *table, enum dma_data_direction dir) { - dma_unmap_sg(attach->dev, table->sgl, table->nents, dir); + dma_unmap_sgtable(attach->dev, table, dir, 0); }static void fastrpc_release (struct dma_buf *dmabuf)
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 86/391 staging: wfx: fix potential use before init
In reply to Greg Kroah-HartmanFrom: Jérôme Pouiller <[email protected]>
[ Upstream commit ce3653a8d3db096aa163fc80239d8ec1305c81fa ]
The trace below can appear:
[83613.832200] INFO: trying to register non-static key.
[83613.837248] the code is fine but needs lockdep annotation.
[83613.842808] turning off the locking correctness validator.
[83613.848375] CPU: 3 PID: 141 Comm: kworker/3:2H Tainted: G O 5.6.13-silabs15 #2
[83613.857019] Hardware name: BCM2835
[83613.860605] Workqueue: events_highpri bh_work [wfx]
[83613.865552] Backtrace:
[83613.868041] [<c010f2cc>] (dump_backtrace) from [<c010f7b8>] (show_stack+0x20/0x24)
[83613.881463] [<c010f798>] (show_stack) from [<c0d82138>] (dump_stack+0xe8/0x114)
[83613.888882] [<c0d82050>] (dump_stack) from [<c01a02ec>] (register_lock_class+0x748/0x768)
[83613.905035] [<c019fba4>] (register_lock_class) from [<c019da04>] (__lock_acquire+0x88/0x13dc)
[83613.924192] [<c019d97c>] (__lock_acquire) from [<c019f6a4>] (lock_acquire+0xe8/0x274)
[83613.942644] [<c019f5bc>] (lock_acquire) from [<c0daa5dc>] (_raw_spin_lock_irqsave+0x58/0x6c)
[83613.961714] [<c0daa584>] (_raw_spin_lock_irqsave) from [<c0ab3248>] (skb_dequeue+0x24/0x78)
[83613.974967] [<c0ab3224>] (skb_dequeue) from [<bf330db0>] (wfx_tx_queues_get+0x96c/0x1294 [wfx])
[83613.989728] [<bf330444>] (wfx_tx_queues_get [wfx]) from [<bf320454>] (bh_work+0x454/0x26d8 [wfx])
[83614.009337] [<bf320000>] (bh_work [wfx]) from [<c014c920>] (process_one_work+0x23c/0x7ec)
[83614.028141] [<c014c6e4>] (process_one_work) from [<c014cf1c>] (worker_thread+0x4c/0x55c)
[83614.046861] [<c014ced0>] (worker_thread) from [<c0154c04>] (kthread+0x138/0x168)
[83614.064876] [<c0154acc>] (kthread) from [<c01010b4>] (ret_from_fork+0x14/0x20)
[83614.072200] Exception stack(0xecad3fb0 to 0xecad3ff8)
[83614.077323] 3fa0: 00000000 00000000 00000000 00000000
[83614.085620] 3fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[83614.093914] 3fe0: 00000000 00000000 00000000 00000000 00000013 00000000Indeed, the code of wfx_add_interface() shows that the interface is enabled to early. So, the spinlock associated with some skb_queue may not yet initialized when wfx_tx_queues_get() is called.
--- drivers/staging/wfx/sta.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-)
drivers/staging/wfx/sta.c +14 -14
@@ -761,17 +761,6 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)return -EOPNOTSUPP ; } -for (i =0 ; i <ARRAY_SIZE (wdev->vif); i++) { -if (!wdev->vif[i]) { - wdev->vif[i] = vif; - wvif->id = i; -break ; - } - } -if (i ==ARRAY_SIZE (wdev->vif)) { -mutex_unlock (&wdev->conf_mutex); -return -EOPNOTSUPP ; - }// FIXME: prefer use of container_of() to get vif wvif->vif = vif; wvif->wdev = wdev;
@@ -788,12 +777,22 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)init_completion (&wvif->scan_complete);INIT_WORK (&wvif->scan_work, wfx_hw_scan_work); -mutex_unlock (&wdev->conf_mutex); +wfx_tx_queues_init (wvif); +wfx_tx_policy_init (wvif); + +for (i =0 ; i <ARRAY_SIZE (wdev->vif); i++) { +if (!wdev->vif[i]) { + wdev->vif[i] = vif; + wvif->id = i; +break ; + } + } +WARN (i ==ARRAY_SIZE (wdev->vif),"try to instantiate more vif than supported" );hif_set_macaddr (wvif, vif->addr); -wfx_tx_queues_init (wvif); -wfx_tx_policy_init (wvif); +mutex_unlock (&wdev->conf_mutex); + wvif =NULL ;while ((wvif =wvif_iterate (wdev, wvif)) !=NULL ) {// Combo mode does not support Block Acks. We can re-enable them
@@ -825,6 +824,7 @@ void wfx_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) wvif->vif =NULL ;mutex_unlock (&wdev->conf_mutex); + wvif =NULL ;while ((wvif =wvif_iterate (wdev, wvif)) !=NULL ) {// Combo mode does not support Block Acks. We can re-enable them
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 87/391 media: platform: Improve queue set up flow for bug fixing
In reply to Greg Kroah-HartmanFrom: Xia Jiang <[email protected]>
[ Upstream commit 5095a6413a0cf896ab468009b6142cb0fe617e66 ]
Add checking created buffer size follow in mtk_jpeg_queue_setup().
--- drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c +7 -0
@@ -571,6 +571,13 @@ static int mtk_jpeg_queue_setup(struct vb2_queue *q,if (!q_data)return -EINVAL ; +if (*num_planes) { +for (i =0 ; i < *num_planes; i++) +if (sizes[i] < q_data->sizeimage[i]) +return -EINVAL ; +return 0 ; + } + *num_planes = q_data->fmt->colplanes;for (i =0 ; i < q_data->fmt->colplanes; i++) { sizes[i] = q_data->sizeimage[i];
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 88/391 usb: typec: tcpm: During PR_SWAP, source caps should be sent only after tSwapSourceStart
In reply to Greg Kroah-HartmanFrom: Badhri Jagan Sridharan <[email protected]>
[ Upstream commit 6bbe2a90a0bb4af8dd99c3565e907fe9b5e7fd88 ]
The patch addresses the compliance test failures while running TD.PD.CP.E3, TD.PD.CP.E4, TD.PD.CP.E5 of the "Deterministic PD Compliance MOI" test plan published in https://www.usb.org/usbc.
For a product to be Type-C compliant, it's expected that these tests are run on usb.org certified Type-C compliance tester as mentioned in
https://www.usb.org/usbc.
The purpose of the tests TD.PD.CP.E3, TD.PD.CP.E4, TD.PD.CP.E5 is to verify the PR_SWAP response of the device. While doing so, the test asserts that Source Capabilities message is NOT received from the test device within tSwapSourceStart min (20 ms) from the time the last bit of GoodCRC corresponding to the RS_RDY message sent by the UUT was sent. If it does then the test fails.
This is in line with the requirements from the USB Power Delivery Specification Revision 3.0, Version 1.2:
"6.6.8.1 SwapSourceStartTimer
The SwapSourceStartTimer Shall be used by the new Source, after a Power Role Swap or Fast Role Swap, to ensure that it does not send Source_Capabilities Message before the new Sink is ready to receive theSource_Capabilities Message. The new Source Shall Not send the Source_Capabilities Message earlier than tSwapSourceStart after the last bit of the EOP of GoodCRC Message sent in response to the PS_RDY Message sent by the new Source indicating that its power supply is ready."
The patch makes sure that TCPM does not send the Source_Capabilities Message within tSwapSourceStart(20ms) by transitioning into SRC_STARTUP only after tSwapSourceStart(20ms).
--- drivers/usb/typec/tcpm/tcpm.c | 2 +- include/linux/usb/pd.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
drivers/usb/typec/tcpm/tcpm.c +1 -1
@@ -3573,7 +3573,7 @@ static void run_state_machine(struct tcpm_port *port)*/ tcpm_set_pwr_role (port,TYPEC_SOURCE );tcpm_pd_send_control (port,PD_CTRL_PS_RDY ); -tcpm_set_state (port,SRC_STARTUP ,0 ); +tcpm_set_state (port,SRC_STARTUP ,PD_T_SWAP_SRC_START );break ;case VCONN_SWAP_ACCEPT :
include/linux/usb/pd.h +1 -0
@@ -473,6 +473,7 @@ static inline unsigned int rdo_max_power(u32 rdo)#define PD_T_ERROR_RECOVERY 100/* minimum 25 is insufficient */ #define PD_T_SRCSWAPSTDBY 625/* Maximum of 650ms */ #define PD_T_NEWSRC 250/* Maximum of 275ms */ +#define PD_T_SWAP_SRC_START 20/* Minimum of 20ms */ #define PD_T_DRP_TRY 100/* 75 - 150 ms */ #define PD_T_DRP_TRYWAIT 600/* 400 - 800 ms */
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 89/391 media: tw5864: check status of tw5864_frameinterval_get
In reply to Greg Kroah-HartmanFrom: Tom Rix <[email protected]>
[ Upstream commit 780d815dcc9b34d93ae69385a8465c38d423ff0f ]
clang static analysis reports this problem
tw5864-video.c:773:32: warning: The left expression of the compound
assignment is an uninitialized value.
The computed value will also be garbage
fintv->stepwise.max.numerator *= std_max_fps;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^stepwise.max is set with frameinterval, which comes from
ret = tw5864_frameinterval_get(input, &frameinterval); fintv->stepwise.step = frameinterval; fintv->stepwise.min = frameinterval; fintv->stepwise.max = frameinterval; fintv->stepwise.max.numerator *= std_max_fps;
When tw5864_frameinterval_get() fails, frameinterval is not set. So check the status and fix another similar problem.
--- drivers/media/pci/tw5864/tw5864-video.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/media/pci/tw5864/tw5864-video.c +6 -0
@@ -767,6 +767,9 @@ static int tw5864_enum_frameintervals(struct file *file, void *priv, fintv->type =V4L2_FRMIVAL_TYPE_STEPWISE ; ret =tw5864_frameinterval_get (input, &frameinterval); +if (ret) +return ret; + fintv->stepwise.step = frameinterval; fintv->stepwise.min = frameinterval; fintv->stepwise.max = frameinterval;
@@ -785,6 +788,9 @@ static int tw5864_g_parm(struct file *file, void *priv, cp->capability =V4L2_CAP_TIMEPERFRAME ; ret =tw5864_frameinterval_get (input, &cp->timeperframe); +if (ret) +return ret; + cp->timeperframe.numerator *= input->frame_interval; cp->capturemode =0 ; cp->readbuffers =2 ;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 90/391 drm/vkms: avoid warning in vkms_get_vblank_timestamp
In reply to Greg Kroah-HartmanFrom: Sidong Yang <[email protected]>
[ Upstream commit 05ca530268a9d0ab3547e7b288635e35990a77c4 ]
This patch avoid the warning in vkms_get_vblank_timestamp when vblanks aren't enabled. When running igt test kms_cursor_crc just after vkms module, the warning raised like below. Initial value of vblank time is zero and hrtimer.node.expires is also zero if vblank aren't enabled before. vkms module isn't real hardware but just virtual hardware module. so vkms can't generate a resonable timestamp when hrtimer is off. it's best to grab the current time.
[106444.464503] [IGT] kms_cursor_crc: starting subtest pipe-A-cursor-size-change [106444.471475] WARNING: CPU: 0 PID: 10109 at vkms_get_vblank_timestamp+0x42/0x50 [vkms] [106444.471511] CPU: 0 PID: 10109 Comm: kms_cursor_crc Tainted: G W OE 5.9.0-rc1+ #6 [106444.471514] RIP: 0010:vkms_get_vblank_timestamp+0x42/0x50 [vkms] [106444.471528] Call Trace: [106444.471551] drm_get_last_vbltimestamp+0xb9/0xd0 [drm] [106444.471566] drm_reset_vblank_timestamp+0x63/0xe0 [drm] [106444.471579] drm_crtc_vblank_on+0x85/0x150 [drm] [106444.471582] vkms_crtc_atomic_enable+0xe/0x10 [vkms] [106444.471592] drm_atomic_helper_commit_modeset_enables+0x1db/0x230 [drm_kms_helper] [106444.471594] vkms_atomic_commit_tail+0x38/0xc0 [vkms] [106444.471601] commit_tail+0x97/0x130 [drm_kms_helper] [106444.471608] drm_atomic_helper_commit+0x117/0x140 [drm_kms_helper] [106444.471622] drm_atomic_commit+0x4a/0x50 [drm] [106444.471629] drm_atomic_helper_set_config+0x63/0xb0 [drm_kms_helper] [106444.471642] drm_mode_setcrtc+0x1d9/0x7b0 [drm] [106444.471654] ? drm_mode_getcrtc+0x1a0/0x1a0 [drm] [106444.471666] drm_ioctl_kernel+0xb6/0x100 [drm] [106444.471677] drm_ioctl+0x3ad/0x470 [drm] [106444.471688] ? drm_mode_getcrtc+0x1a0/0x1a0 [drm] [106444.471692] ? tomoyo_file_ioctl+0x19/0x20 [106444.471694] __x64_sys_ioctl+0x96/0xd0 [106444.471697] do_syscall_64+0x37/0x80 [106444.471699] entry_SYSCALL_64_after_hwframe+0x44/0xa9
--- drivers/gpu/drm/vkms/vkms_crtc.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/gpu/drm/vkms/vkms_crtc.c +5 -0
@@ -86,6 +86,11 @@ static bool vkms_get_vblank_timestamp(struct drm_crtc *crtc,struct vkms_output *output = &vkmsdev->output;struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; +if (!READ_ONCE (vblank->enabled)) { + *vblank_time =ktime_get (); +return true; + } + *vblank_time =READ_ONCE (output->vblank_hrtimer.node.expires);if (WARN_ON (*vblank_time == vblank->time))
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 91/391 media: imx274: fix frame interval handling
In reply to Greg Kroah-HartmanFrom: Hans Verkuil <[email protected]>
[ Upstream commit 49b20d981d723fae5a93843c617af2b2c23611ec ]
1) the numerator and/or denominator might be 0, in that case fall back to the default frame interval. This is per the spec and this caused a v4l2-compliance failure.
2) the updated frame interval wasn't returned in the s_frame_interval subdev op.
--- drivers/media/i2c/imx274.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/media/i2c/imx274.c +5 -3
@@ -1235,6 +1235,8 @@ static int imx274_s_frame_interval(struct v4l2_subdev *sd, ret =imx274_set_frame_interval (imx274, fi->interval);if (!ret) { + fi->interval = imx274->frame_interval; +/* * exposure time range is decided by frame interval * need to update it after frame interval changes
@@ -1730,9 +1732,9 @@ static int imx274_set_frame_interval(struct stimx274 *priv, __func__, frame_interval.numerator, frame_interval.denominator); -if (frame_interval.numerator ==0 ) { - err = -EINVAL ; - goto fail; +if (frame_interval.numerator ==0 || frame_interval.denominator ==0 ) { + frame_interval.denominator =IMX274_DEF_FRAME_RATE ; + frame_interval.numerator =1 ; } req_frame_rate = (u32)(frame_interval.denominator
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 92/391 mmc: via-sdmmc: Fix data race bug
In reply to Greg Kroah-HartmanFrom: Madhuparna Bhowmik <[email protected]>
[ Upstream commit 87d7ad089b318b4f319bf57f1daa64eb6d1d10ad ]
via_save_pcictrlreg() should be called with host->lock held as it writes to pm_pcictrl_reg, otherwise there can be a race condition between via_sd_suspend() and via_sdc_card_detect(). The same pattern is used in the function via_reset_pcictrl() as well, where via_save_pcictrlreg() is called with host->lock held.
Found by Linux Driver Verification project (linuxtesting.org).
--- drivers/mmc/host/via-sdmmc.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/mmc/host/via-sdmmc.c +3 -0
@@ -1257,11 +1257,14 @@ static void __maybe_unused via_init_sdc_pm(struct via_crdr_mmc_host *host)static int __maybe_unused via_sd_suspend (struct device *dev) {struct via_crdr_mmc_host *host; +unsigned long flags; host =dev_get_drvdata (dev); +spin_lock_irqsave (&host->lock, flags);via_save_pcictrlreg (host);via_save_sdcreg (host); +spin_unlock_irqrestore (&host->lock, flags);device_wakeup_enable (dev);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 93/391 drm/bridge/synopsys: dsi: add support for non-continuous HS clock
In reply to Greg Kroah-HartmanFrom: Antonio Borneo <[email protected]>
[ Upstream commit c6d94e37bdbb6dfe7e581e937a915ab58399b8a5 ]
Current code enables the HS clock when video mode is started or to send out a HS command, and disables the HS clock to send out a LP command. This is not what DSI spec specify.
Enable HS clock either in command and in video mode. Set automatic HS clock management for panels and devices that support non-continuous HS clock.
--- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +7 -2
@@ -365,7 +365,6 @@ static void dw_mipi_message_config(struct dw_mipi_dsi *dsi,if (lpm) val |=CMD_MODE_ALL_LP ; -dsi_write (dsi,DSI_LPCLK_CTRL , lpm ?0 :PHY_TXREQUESTCLKHS );dsi_write (dsi,DSI_CMD_MODE_CFG , val); }
@@ -541,16 +540,22 @@ static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi)static void dw_mipi_dsi_set_mode (struct dw_mipi_dsi *dsi,unsigned long mode_flags) { +u32 val; +dsi_write (dsi,DSI_PWR_UP ,RESET );if (mode_flags &MIPI_DSI_MODE_VIDEO ) {dsi_write (dsi,DSI_MODE_CFG ,ENABLE_VIDEO_MODE );dw_mipi_dsi_video_mode_config (dsi); -dsi_write (dsi,DSI_LPCLK_CTRL ,PHY_TXREQUESTCLKHS ); }else {dsi_write (dsi,DSI_MODE_CFG ,ENABLE_CMD_MODE ); } + val =PHY_TXREQUESTCLKHS ; +if (dsi->mode_flags &MIPI_DSI_CLOCK_NON_CONTINUOUS ) + val |=AUTO_CLKLANE_CTRL ; +dsi_write (dsi,DSI_LPCLK_CTRL , val); +dsi_write (dsi,DSI_PWR_UP ,POWERUP ); }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 94/391 brcmfmac: increase F2 watermark for BCM4329
In reply to Greg Kroah-HartmanFrom: Dmitry Osipenko <[email protected]>
[ Upstream commit 317da69d10b0247c4042354eb90c75b81620ce9d ]
This patch fixes SDHCI CRC errors during of RX throughput testing on BCM4329 chip if SDIO BUS is clocked above 25MHz. In particular the checksum problem is observed on NVIDIA Tegra20 SoCs. The good watermark value is borrowed from downstream BCMDHD driver and it's matching to the value that is already used for the BCM4339 chip, hence let's re-use it for BCM4329.
--- drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +1 -0
@@ -4278,6 +4278,7 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,brcmf_sdiod_writeb (sdiod,SBSDIO_FUNC1_MESBUSYCTRL ,CY_43012_MESBUSYCTRL , &err);break ; +case SDIO_DEVICE_ID_BROADCOM_4329 :case SDIO_DEVICE_ID_BROADCOM_4339 :brcmf_dbg (INFO ,"set F2 watermark to 0x%x*4 bytes for 4339\n" ,CY_4339_F2_WATERMARK );
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 95/391 arm64: topology: Stop using MPIDR for topology information
In reply to Greg Kroah-HartmanFrom: Valentin Schneider <[email protected]>
[ Upstream commit 3102bc0e6ac752cc5df896acb557d779af4d82a1 ]
In the absence of ACPI or DT topology data, we fallback to haphazardly decoding *something* out of MPIDR. Sadly, the contents of that register are mostly unusable due to the implementation leniancy and things like Aff0 having to be capped to 15 (despite being encoded on 8 bits).
Consider a simple system with a single package of 32 cores, all under the same LLC. We ought to be shoving them in the same core_sibling mask, but MPIDR is going to look like:
| CPU | 0 | ... | 15 | 16 | ... | 31 | |------+---+-----+----+----+-----+----+ | Aff0 | 0 | ... | 15 | 0 | ... | 15 | | Aff1 | 0 | ... | 0 | 1 | ... | 1 | | Aff2 | 0 | ... | 0 | 0 | ... | 0 |
Which will eventually yield
core_sibling(0-15) == 0-15
core_sibling(16-31) == 16-31
NUMA woes
=========
If we try to play games with this and set up NUMA boundaries within those groups of 16 cores via e.g. QEMU:
# Node0: 0-9; Node1: 10-19
$ qemu-system-aarch64 <blah> \
-smp 20 -numa node,cpus=0-9,nodeid=0 -numa node,cpus=10-19,nodeid=1The scheduler's MC domain (all CPUs with same LLC) is going to be built via
arch_topology.c::cpu_coregroup_mask()
In there we try to figure out a sensible mask out of the topology information we have. In short, here we'll pick the smallest of NUMA or core sibling mask.
node_mask(CPU9) == 0-9
core_sibling(CPU9) == 0-15
MC mask for CPU9 will thus be 0-9, not a problem.
node_mask(CPU10) == 10-19
core_sibling(CPU10) == 0-15
MC mask for CPU10 will thus be 10-19, not a problem.
node_mask(CPU16) == 10-19
core_sibling(CPU16) == 16-19
MC mask for CPU16 will thus be 16-19... Uh oh. CPUs 16-19 are in two different unique MC spans, and the scheduler has no idea what to make of that. That triggers the WARN_ON() added by commit
ccf74128d66c ("sched/topology: Assert non-NUMA topology masks don't (partially) overlap")
Fixing MPIDR-derived topology
=============================
We could try to come up with some cleverer scheme to figure out which of the available masks to pick, but really if one of those masks resulted from MPIDR then it should be discarded because it's bound to be bogus.
I was hoping to give MPIDR a chance for SMT, to figure out which threads are in the same core using Aff1-3 as core ID, but Sudeep and Robin pointed out to me that there are systems out there where *all* cores have non-zero values in their higher affinity fields (e.g. RK3288 has "5" in all of its cores' MPIDR.Aff1), which would expose a bogus core ID to userspace.
Stop using MPIDR for topology information. When no other source of topology information is available, mark each CPU as its own core and its NUMA node as its LLC domain.
--- arch/arm64/kernel/topology.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-)
arch/arm64/kernel/topology.c +17 -15
@@ -36,21 +36,23 @@ void store_cpu_topology(unsigned int cpuid)if (mpidr &MPIDR_UP_BITMASK )return ; -/* Create cpu topology mapping based on MPIDR. */ -if (mpidr &MPIDR_MT_BITMASK ) { -/* Multiprocessor system : Multi-threads per core */ - cpuid_topo->thread_id =MPIDR_AFFINITY_LEVEL (mpidr,0 ); - cpuid_topo->core_id =MPIDR_AFFINITY_LEVEL (mpidr,1 ); - cpuid_topo->package_id =MPIDR_AFFINITY_LEVEL (mpidr,2 ) | -MPIDR_AFFINITY_LEVEL (mpidr,3 ) <<8 ; - }else { -/* Multiprocessor system : Single-thread per core */ - cpuid_topo->thread_id =-1 ; - cpuid_topo->core_id =MPIDR_AFFINITY_LEVEL (mpidr,0 ); - cpuid_topo->package_id =MPIDR_AFFINITY_LEVEL (mpidr,1 ) | -MPIDR_AFFINITY_LEVEL (mpidr,2 ) <<8 | -MPIDR_AFFINITY_LEVEL (mpidr,3 ) <<16 ; - } +/* +* This would be the place to create cpu topology based on MPIDR. +* +* However, it cannot be trusted to depict the actual topology; some +* pieces of the architecture enforce an artificial cap on Aff0 values +* (e.g. GICv3's ICC_SGI1R_EL1 limits it to 15), leading to an +* artificial cycling of Aff1, Aff2 and Aff3 values. IOW, these end up +* having absolutely no relationship to the actual underlying system +* topology, and cannot be reasonably used as core / package ID. +* +* If the MT bit is set, Aff0 *could* be used to define a thread ID, but +* we still wouldn't be able to obtain a sane core ID. This means we +* need to entirely ignore MPIDR for any topology deduction. +*/ + cpuid_topo->thread_id =-1 ; + cpuid_topo->core_id = cpuid; + cpuid_topo->package_id =cpu_to_node (cpuid); pr_debug("CPU%u: cluster %d core %d thread %d mpidr %#016llx\n", cpuid, cpuid_topo->package_id, cpuid_topo->core_id,
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 96/391 printk: reduce LOG_BUF_SHIFT range for H8300
In reply to Greg Kroah-HartmanFrom: John Ogness <[email protected]>
[ Upstream commit 550c10d28d21bd82a8bb48debbb27e6ed53262f6 ]
The .bss section for the h8300 is relatively small. A value of CONFIG_LOG_BUF_SHIFT that is larger than 19 will create a static printk ringbuffer that is too large. Limit the range appropriately for the H8300.
--- init/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
init/Kconfig +2 -1
@@ -682,7 +682,8 @@ config IKHEADERS config LOG_BUF_SHIFT int "Kernel log buffer size (16 => 64KB, 17 => 128KB)" - range 12 25 + range 12 25 if !H8300 + range 12 19 if H8300 default 17 depends on PRINTK help
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 97/391 ia64: kprobes: Use generic kretprobe trampoline handler
In reply to Greg Kroah-HartmanFrom: Masami Hiramatsu <[email protected]>
[ Upstream commit e792ff804f49720ce003b3e4c618b5d996256a18 ]
Use the generic kretprobe trampoline handler. Don't use framepointer verification.
--- arch/ia64/kernel/kprobes.c | 77 +------------------------------------- 1 file changed, 2 insertions(+), 75 deletions(-)
arch/ia64/kernel/kprobes.c +2 -75
@@ -396,83 +396,9 @@ static void kretprobe_trampoline(void) { } -/* -* At this point the target function has been tricked into -* returning into our trampoline. Lookup the associated instance -* and then: -* - call the handler function -* - cleanup by marking the instance as unused -* - long jump back to the original return address -*/ int __kprobes trampoline_probe_handler (struct kprobe *p,struct pt_regs *regs) { -struct kretprobe_instance *ri =NULL ; -struct hlist_head *head, empty_rp; -struct hlist_node *tmp; -unsigned long flags, orig_ret_address =0 ; -unsigned long trampoline_address = - ((struct fnptr *)kretprobe_trampoline)->ip; - -INIT_HLIST_HEAD (&empty_rp); -kretprobe_hash_lock (current, &head, &flags); - -/* -* It is possible to have multiple instances associated with a given -* task either because an multiple functions in the call path -* have a return probe installed on them, and/or more than one return -* return probe was registered for a target function. -* -* We can handle this because: -* - instances are always inserted at the head of the list -* - when multiple return probes are registered for the same -* function, the first instance's ret_addr will point to the -* real return address, and all the rest will point to -* kretprobe_trampoline -*/ -hlist_for_each_entry_safe (ri, tmp, head, hlist) { -if (ri->task != current) -/* another task is sharing our hash bucket */ -continue ; - - orig_ret_address = (unsigned long )ri->ret_addr; -if (orig_ret_address != trampoline_address) -/* -* This is the real return address. Any other -* instances associated with this task are for -* other calls deeper on the call stack -*/ -break ; - } - - regs->cr_iip = orig_ret_address; - -hlist_for_each_entry_safe (ri, tmp, head, hlist) { -if (ri->task != current) -/* another task is sharing our hash bucket */ -continue ; - -if (ri->rp && ri->rp->handler) - ri->rp->handler (ri, regs); - - orig_ret_address = (unsigned long )ri->ret_addr; -recycle_rp_inst (ri, &empty_rp); - -if (orig_ret_address != trampoline_address) -/* -* This is the real return address. Any other -* instances associated with this task are for -* other calls deeper on the call stack -*/ -break ; - } -kretprobe_assert (ri, orig_ret_address, trampoline_address); - -kretprobe_hash_unlock (current, &flags); - -hlist_for_each_entry_safe (ri, tmp, &empty_rp, hlist) { -hlist_del (&ri->hlist); -kfree (ri); - } + regs->cr_iip =__kretprobe_trampoline_handler (regs, kretprobe_trampoline,NULL );/* * By returning a non-zero value, we are telling * kprobe_handler() that we don't want the post_handler
@@ -485,6 +411,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs) { ri->ret_addr = (kprobe_opcode_t *)regs->b0; + ri->fp =NULL ;/* Replace the return addr with trampoline addr */ regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 98/391 selftests/powerpc: Make using_hash_mmu() work on Cell & PowerMac
In reply to Greg Kroah-HartmanFrom: Michael Ellerman <[email protected]>
[ Upstream commit 34c103342be3f9397e656da7c5cc86e97b91f514 ]
These platforms don't show the MMU in /proc/cpuinfo, but they always use hash, so teach using_hash_mmu() that.
--- tools/testing/selftests/powerpc/utils.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
tools/testing/selftests/powerpc/utils.c +3 -1
@@ -318,7 +318,9 @@ int using_hash_mmu(bool *using_hash) rc =0 ;while (fgets (line,sizeof (line), f) !=NULL ) { -if (strcmp (line,"MMU : Hash\n" ) ==0 ) { +if (!strcmp (line,"MMU : Hash\n" ) || + !strcmp (line,"platform : Cell\n" ) || + !strcmp (line,"platform : PowerMac\n" )) { *using_hash = true; goto out; }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 99/391 kgdb: Make "kgdbcon" work properly with "kgdb_earlycon"
In reply to Greg Kroah-HartmanFrom: Douglas Anderson <[email protected]>
[ Upstream commit b18b099e04f450cdc77bec72acefcde7042bd1f3 ]
On my system the kernel processes the "kgdb_earlycon" parameter before the "kgdbcon" parameter. When we setup "kgdb_earlycon" we'll end up in kgdb_register_callbacks() and "kgdb_use_con" won't have been set yet so we'll never get around to starting "kgdbcon". Let's remedy this by detecting that the IO module was already registered when setting "kgdb_use_con" and registering the console then.
As part of this, to avoid pre-declaring things, move the handling of the "kgdbcon" further down in the file.
--- kernel/debug/debug_core.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-)
kernel/debug/debug_core.c +14 -8
@@ -94,14 +94,6 @@ int dbg_switch_cpu;/* Use kdb or gdbserver mode */ int dbg_kdb_mode =1 ; -static int __init opt_kgdb_con (char *str) -{ - kgdb_use_con =1 ; -return 0 ; -} - -early_param ("kgdbcon" , opt_kgdb_con); -module_param (kgdb_use_con, int,0644 );module_param (kgdbreboot, int,0644 );
@@ -920,6 +912,20 @@ static struct console kgdbcons = { .index = -1, }; +static int __init opt_kgdb_con (char *str) +{ + kgdb_use_con =1 ; + +if (kgdb_io_module_registered && !kgdb_con_registered) { +register_console (&kgdbcons); + kgdb_con_registered =1 ; + } + +return 0 ; +} + +early_param ("kgdbcon" , opt_kgdb_con); +#ifdef CONFIG_MAGIC_SYSRQ static void sysrq_handle_dbg (int key) {
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 100/391 bpf: Permit map_ptr arithmetic with opcode add and offset 0
In reply to Greg Kroah-HartmanFrom: Yonghong Song <[email protected]>
[ Upstream commit 7c6967326267bd5c0dded0a99541357d70dd11ac ]
Commit 41c48f3a98231 ("bpf: Support access
to bpf map fields") added support to access map fields with CORE support. For example,
struct bpf_map {
__u32 max_entries;
} __attribute__((preserve_access_index));
struct bpf_array {
struct bpf_map map;
__u32 elem_size;
} __attribute__((preserve_access_index));
struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
__uint(max_entries, 4);
__type(key, __u32);
__type(value, __u32);
} m_array SEC(".maps");
SEC("cgroup_skb/egress")
int cg_skb(void *ctx)
{
struct bpf_array *array = (struct bpf_array *)&m_array;
/* .. array->map.max_entries .. */
}In kernel, bpf_htab has similar structure,
struct bpf_htab {
struct bpf_map map;
...
}In the above cg_skb(), to access array->map.max_entries, with CORE, the clang will generate two builtin's.
base = &m_array;
/* access array.map */
map_addr = __builtin_preserve_struct_access_info(base, 0, 0);
/* access array.map.max_entries */
max_entries_addr = __builtin_preserve_struct_access_info(map_addr, 0, 0);
max_entries = *max_entries_addr;In the current llvm, if two builtin's are in the same function or
in the same function after inlining, the compiler is smart enough to chain them together and generates like below:
base = &m_array;
max_entries = *(base + reloc_offset); /* reloc_offset = 0 in this case */
and we are fine.
But if we force no inlining for one of functions in test_map_ptr() selftest, e.g., check_default(), the above two __builtin_preserve_* will be in two different functions. In this case, we will have code like:
func check_hash():
reloc_offset_map = 0;
base = &m_array;
map_base = base + reloc_offset_map;
check_default(map_base, ...)
func check_default(map_base, ...):
max_entries = *(map_base + reloc_offset_max_entries);In kernel, map_ptr (CONST_PTR_TO_MAP) does not allow any arithmetic.
The above "map_base = base + reloc_offset_map" will trigger a verifier failure.
; VERIFY(check_default(&hash->map, map));
0: (18) r7 = 0xffffb4fe8018a004
2: (b4) w1 = 110
3: (63) *(u32 *)(r7 +0) = r1
R1_w=invP110 R7_w=map_value(id=0,off=4,ks=4,vs=8,imm=0) R10=fp0
; VERIFY_TYPE(BPF_MAP_TYPE_HASH, check_hash);
4: (18) r1 = 0xffffb4fe8018a000
6: (b4) w2 = 1
7: (63) *(u32 *)(r1 +0) = r2
R1_w=map_value(id=0,off=0,ks=4,vs=8,imm=0) R2_w=invP1 R7_w=map_value(id=0,off=4,ks=4,vs=8,imm=0) R10=fp0
8: (b7) r2 = 0
9: (18) r8 = 0xffff90bcb500c000
11: (18) r1 = 0xffff90bcb500c000
13: (0f) r1 += r2
R1 pointer arithmetic on map_ptr prohibited
To fix the issue, let us permit map_ptr + 0 arithmetic which will result in exactly the same map_ptr.
--- kernel/bpf/verifier.c | 4 ++++ 1 file changed, 4 insertions(+)
kernel/bpf/verifier.c +4 -0
@@ -5246,6 +5246,10 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, dst, reg_type_str[ptr_reg->type]);return -EACCES ;case CONST_PTR_TO_MAP : +/* smin_val represents the known value */ +if (known && smin_val ==0 && opcode ==BPF_ADD ) +break ; +/* fall-through */ case PTR_TO_PACKET_END :case PTR_TO_SOCKET :case PTR_TO_SOCKET_OR_NULL :
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 101/391 drm: exynos: fix common struct sg_table related issues
In reply to Greg Kroah-HartmanFrom: Marek Szyprowski <[email protected]>
[ Upstream commit 84404614167b829f7b58189cd24b6c0c74897171 ]
The Documentation/DMA-API-HOWTO.txt states that the dma_map_sg() function returns the number of the created entries in the DMA address space. However the subsequent calls to the dma_sync_sg_for_{device,cpu}() and dma_unmap_sg must be called with the original number of the entries passed to the dma_map_sg().
struct sg_table is a common structure used for describing a non-contiguous memory buffer, used commonly in the DRM and graphics subsystems. It consists of a scatterlist with memory pages and DMA addresses (sgl entry), as well as the number of scatterlist entries: CPU pages (orig_nents entry) and DMA mapped pages (nents entry).
It turned out that it was a common mistake to misuse nents and orig_nents entries, calling DMA-mapping functions with a wrong number of entries or ignoring the number of mapped entries returned by the dma_map_sg() function.
To avoid such issues, lets use a common dma-mapping wrappers operating directly on the struct sg_table objects and use scatterlist page iterators where possible. This, almost always, hides references to the nents and orig_nents entries, making the code robust, easier to follow and copy/paste safe.
--- drivers/gpu/drm/exynos/exynos_drm_g2d.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/gpu/drm/exynos/exynos_drm_g2d.c +5 -5
@@ -395,8 +395,8 @@ static void g2d_userptr_put_dma_addr(struct g2d_data *g2d,return ; out: -dma_unmap_sg (to_dma_dev (g2d->drm_dev), g2d_userptr->sgt->sgl, - g2d_userptr->sgt->nents,DMA_BIDIRECTIONAL ); +dma_unmap_sgtable (to_dma_dev (g2d->drm_dev), g2d_userptr->sgt, +DMA_BIDIRECTIONAL ,0 ); pages =frame_vector_pages (g2d_userptr->vec);if (!IS_ERR (pages)) {
@@ -511,10 +511,10 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d, g2d_userptr->sgt = sgt; -if (!dma_map_sg (to_dma_dev (g2d->drm_dev), sgt->sgl, sgt->nents, -DMA_BIDIRECTIONAL )) { + ret =dma_map_sgtable (to_dma_dev (g2d->drm_dev), sgt, +DMA_BIDIRECTIONAL ,0 ); +if (ret) {DRM_DEV_ERROR (g2d->dev,"failed to map sgt with dma region.\n" ); - ret = -ENOMEM ; goto err_sg_free_table; }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 102/391 xen: gntdev: fix common struct sg_table related issues
In reply to Greg Kroah-HartmanFrom: Marek Szyprowski <[email protected]>
[ Upstream commit d1749eb1ab85e04e58c29e58900e3abebbdd6e82 ]
The Documentation/DMA-API-HOWTO.txt states that the dma_map_sg() function returns the number of the created entries in the DMA address space. However the subsequent calls to the dma_sync_sg_for_{device,cpu}() and dma_unmap_sg must be called with the original number of the entries passed to the dma_map_sg().
struct sg_table is a common structure used for describing a non-contiguous memory buffer, used commonly in the DRM and graphics subsystems. It consists of a scatterlist with memory pages and DMA addresses (sgl entry), as well as the number of scatterlist entries: CPU pages (orig_nents entry) and DMA mapped pages (nents entry).
It turned out that it was a common mistake to misuse nents and orig_nents entries, calling DMA-mapping functions with a wrong number of entries or ignoring the number of mapped entries returned by the dma_map_sg() function.
To avoid such issues, lets use a common dma-mapping wrappers operating directly on the struct sg_table objects and use scatterlist page iterators where possible. This, almost always, hides references to the nents and orig_nents entries, making the code robust, easier to follow and copy/paste safe.
--- drivers/xen/gntdev-dmabuf.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
drivers/xen/gntdev-dmabuf.c +6 -7
@@ -247,10 +247,9 @@ static void dmabuf_exp_ops_detach(struct dma_buf *dma_buf,if (sgt) {if (gntdev_dmabuf_attach->dir !=DMA_NONE ) -dma_unmap_sg_attrs (attach->dev, sgt->sgl, - sgt->nents, - gntdev_dmabuf_attach->dir, -DMA_ATTR_SKIP_CPU_SYNC ); +dma_unmap_sgtable (attach->dev, sgt, + gntdev_dmabuf_attach->dir, +DMA_ATTR_SKIP_CPU_SYNC );sg_free_table (sgt); }
@@ -288,8 +287,8 @@ dmabuf_exp_ops_map_dma_buf(struct dma_buf_attachment *attach, sgt =dmabuf_pages_to_sgt (gntdev_dmabuf->pages, gntdev_dmabuf->nr_pages);if (!IS_ERR (sgt)) { -if (!dma_map_sg_attrs (attach->dev, sgt->sgl, sgt->nents, dir, -DMA_ATTR_SKIP_CPU_SYNC )) { +if (dma_map_sgtable (attach->dev, sgt, dir, +DMA_ATTR_SKIP_CPU_SYNC )) {sg_free_table (sgt);kfree (sgt); sgt =ERR_PTR (-ENOMEM );
@@ -633,7 +632,7 @@ dmabuf_imp_to_refs(struct gntdev_dmabuf_priv *priv, struct device *dev,/* Now convert sgt to array of pages and check for page validity. */ i =0 ; -for_each_sg_page (sgt->sgl, &sg_iter, sgt->nents,0 ) { +for_each_sgtable_page (sgt, &sg_iter,0 ) {struct page *page =sg_page_iter_page (&sg_iter);/* * Check if page is valid: this can happen if we are given
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 103/391 drm: lima: fix common struct sg_table related issues
In reply to Greg Kroah-HartmanFrom: Marek Szyprowski <[email protected]>
[ Upstream commit c3d9c17f486d5c54940487dc31a54ebfdeeb371a ]
The Documentation/DMA-API-HOWTO.txt states that the dma_map_sg() function returns the number of the created entries in the DMA address space. However the subsequent calls to the dma_sync_sg_for_{device,cpu}() and dma_unmap_sg must be called with the original number of the entries passed to the dma_map_sg().
struct sg_table is a common structure used for describing a non-contiguous memory buffer, used commonly in the DRM and graphics subsystems. It consists of a scatterlist with memory pages and DMA addresses (sgl entry), as well as the number of scatterlist entries: CPU pages (orig_nents entry) and DMA mapped pages (nents entry).
It turned out that it was a common mistake to misuse nents and orig_nents entries, calling DMA-mapping functions with a wrong number of entries or ignoring the number of mapped entries returned by the dma_map_sg() function.
To avoid such issues, lets use a common dma-mapping wrappers operating directly on the struct sg_table objects and use scatterlist page iterators where possible. This, almost always, hides references to the nents and orig_nents entries, making the code robust, easier to follow and copy/paste safe.
--- drivers/gpu/drm/lima/lima_gem.c | 11 ++++++++--- drivers/gpu/drm/lima/lima_vm.c | 5 ++--- 2 files changed, 10 insertions(+), 6 deletions(-)
drivers/gpu/drm/lima/lima_gem.c +8 -3
@@ -69,8 +69,7 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm)return ret;if (bo->base.sgt) { -dma_unmap_sg (dev, bo->base.sgt->sgl, - bo->base.sgt->nents,DMA_BIDIRECTIONAL ); +dma_unmap_sgtable (dev, bo->base.sgt,DMA_BIDIRECTIONAL ,0 );sg_free_table (bo->base.sgt); }else { bo->base.sgt =kmalloc (sizeof (*bo->base.sgt),GFP_KERNEL );
@@ -80,7 +79,13 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm) } } -dma_map_sg (dev, sgt.sgl, sgt.nents,DMA_BIDIRECTIONAL ); + ret =dma_map_sgtable (dev, &sgt,DMA_BIDIRECTIONAL ,0 ); +if (ret) { +sg_free_table (&sgt); +kfree (bo->base.sgt); + bo->base.sgt =NULL ; +return ret; + } *bo->base.sgt = sgt;
drivers/gpu/drm/lima/lima_vm.c +2 -3
@@ -124,7 +124,7 @@ int lima_vm_bo_add(struct lima_vm *vm, struct lima_bo *bo, bool create)if (err) goto err_out1; -for_each_sg_dma_page (bo->base.sgt->sgl, &sg_iter, bo->base.sgt->nents,0 ) { +for_each_sgtable_dma_page (bo->base.sgt, &sg_iter,0 ) { err =lima_vm_map_page (vm,sg_page_iter_dma_address (&sg_iter), bo_va->node.start + offset);if (err)
@@ -298,8 +298,7 @@ int lima_vm_map_bo(struct lima_vm *vm, struct lima_bo *bo, int pageoff)mutex_lock (&vm->lock); base = bo_va->node.start + (pageoff <<PAGE_SHIFT ); -for_each_sg_dma_page (bo->base.sgt->sgl, &sg_iter, - bo->base.sgt->nents, pageoff) { +for_each_sgtable_dma_page (bo->base.sgt, &sg_iter, pageoff) { err =lima_vm_map_page (vm,sg_page_iter_dma_address (&sg_iter), base + offset);if (err)
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 104/391 drm: panfrost: fix common struct sg_table related issues
In reply to Greg Kroah-HartmanFrom: Marek Szyprowski <[email protected]>
[ Upstream commit 34a4e66faf8b22c8409cbd46839ba5e488b1e6a9 ]
The Documentation/DMA-API-HOWTO.txt states that the dma_map_sg() function returns the number of the created entries in the DMA address space. However the subsequent calls to the dma_sync_sg_for_{device,cpu}() and dma_unmap_sg must be called with the original number of the entries passed to the dma_map_sg().
struct sg_table is a common structure used for describing a non-contiguous memory buffer, used commonly in the DRM and graphics subsystems. It consists of a scatterlist with memory pages and DMA addresses (sgl entry), as well as the number of scatterlist entries: CPU pages (orig_nents entry) and DMA mapped pages (nents entry).
It turned out that it was a common mistake to misuse nents and orig_nents entries, calling DMA-mapping functions with a wrong number of entries or ignoring the number of mapped entries returned by the dma_map_sg() function.
To avoid such issues, lets use a common dma-mapping wrappers operating directly on the struct sg_table objects and use scatterlist page iterators where possible. This, almost always, hides references to the nents and orig_nents entries, making the code robust, easier to follow and copy/paste safe.
--- drivers/gpu/drm/panfrost/panfrost_gem.c | 4 ++-- drivers/gpu/drm/panfrost/panfrost_mmu.c | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-)
drivers/gpu/drm/panfrost/panfrost_gem.c +2 -2
@@ -41,8 +41,8 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj)for (i =0 ; i < n_sgt; i++) {if (bo->sgts[i].sgl) { -dma_unmap_sg (pfdev->dev, bo->sgts[i].sgl, - bo->sgts[i].nents,DMA_BIDIRECTIONAL ); +dma_unmap_sgtable (pfdev->dev, &bo->sgts[i], +DMA_BIDIRECTIONAL ,0 );sg_free_table (&bo->sgts[i]); } }
drivers/gpu/drm/panfrost/panfrost_mmu.c +3 -4
@@ -253,7 +253,7 @@ static int mmu_map_sg(struct panfrost_device *pfdev, struct panfrost_mmu *mmu,struct io_pgtable_ops *ops = mmu->pgtbl_ops;u64 start_iova = iova; -for_each_sg (sgt->sgl, sgl, sgt->nents, count) { +for_each_sgtable_dma_sg (sgt, sgl, count) {unsigned long paddr =sg_dma_address (sgl);size_t len =sg_dma_len (sgl);
@@ -517,10 +517,9 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as,if (ret) goto err_pages; -if (!dma_map_sg (pfdev->dev, sgt->sgl, sgt->nents,DMA_BIDIRECTIONAL )) { - ret = -EINVAL ; + ret =dma_map_sgtable (pfdev->dev, sgt,DMA_BIDIRECTIONAL ,0 ); +if (ret) goto err_map; - }mmu_map_sg (pfdev, bomapping->mmu, addr,IOMMU_WRITE |IOMMU_READ |IOMMU_NOEXEC , sgt);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 105/391 media: uvcvideo: Fix dereference of out-of-bound list iterator
In reply to Greg Kroah-HartmanFrom: Daniel W. S. Almeida <[email protected]>
[ Upstream commit f875bcc375c738bf2f599ff2e1c5b918dbd07c45 ]
Fixes the following coccinelle report:
drivers/media/usb/uvc/uvc_ctrl.c:1860:5-11:
ERROR: invalid reference to the index variable of the iterator on line 1854
by adding a boolean variable to check if the loop has found the
Found using - Coccinelle (http://coccinelle.lip6.fr)
[Replace cursor variable with bool found]
--- drivers/media/usb/uvc/uvc_ctrl.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/media/usb/uvc/uvc_ctrl.c +9 -4
@@ -1848,30 +1848,35 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain, {struct uvc_entity *entity;struct uvc_control *ctrl; -unsigned int i, found =0 ; +unsigned int i; +bool found;u32 reqflags;u16 size;u8 *data =NULL ;int ret;/* Find the extension unit. */ + found = false;list_for_each_entry (entity, &chain->entities, chain) {if (UVC_ENTITY_TYPE (entity) ==UVC_VC_EXTENSION_UNIT && - entity->id == xqry->unit) + entity->id == xqry->unit) { + found = true;break ; + } } -if (entity->id != xqry->unit) { +if (!found) {uvc_trace (UVC_TRACE_CONTROL ,"Extension unit %u not found.\n" , xqry->unit);return -ENOENT ; }/* Find the control and perform delayed initialization if needed. */ + found = false;for (i =0 ; i < entity->ncontrols; ++i) { ctrl = &entity->controls[i];if (ctrl->index == xqry->selector -1 ) { - found =1 ; + found = true;break ; } }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 106/391 nfc: s3fwrn5: Add missing CRYPTO_HASH dependency
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 4aa62c62d4c41d71b2bda5ed01b78961829ee93c ]
The driver uses crypto hash functions so it needs to select CRYPTO_HASH. This fixes build errors:
arc-linux-ld: drivers/nfc/s3fwrn5/firmware.o: in function `s3fwrn5_fw_download':
firmware.c:(.text+0x152): undefined reference to `crypto_alloc_shash'
--- drivers/nfc/s3fwrn5/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/nfc/s3fwrn5/Kconfig +1 -0
@@ -2,6 +2,7 @@ config NFC_S3FWRN5 tristate select CRYPTO + select CRYPTO_HASH help Core driver for Samsung S3FWRN5 NFC chip. Contains core utilities of chip. It's intended to be used by PHYs to avoid duplicating lots
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 107/391 selftests/bpf: Define string const as global for test_sysctl_prog.c
In reply to Greg Kroah-HartmanFrom: Yonghong Song <[email protected]>
[ Upstream commit 6e057fc15a2da4ee03eb1fa6889cf687e690106e ]
When tweaking llvm optimizations, I found that selftest build failed
with the following error:
libbpf: elf: skipping unrecognized data section(6) .rodata.str1.1
libbpf: prog 'sysctl_tcp_mem': bad map relo against '.L__const.is_tcp_mem.tcp_mem_name'
in section '.rodata.str1.1'
Error: failed to open BPF object file: Relocation failed
make: *** [/work/net-next/tools/testing/selftests/bpf/test_sysctl_prog.skel.h] Error 255
make: *** Deleting file `/work/net-next/tools/testing/selftests/bpf/test_sysctl_prog.skel.h'
The local string constant "tcp_mem_name" is put into '.rodata.str1.1' section which libbpf cannot handle. Using untweaked upstream llvm, "tcp_mem_name" is completely inlined after loop unrolling.
Commit 7fb5eefd7639 ("selftests/bpf: Fix test_sysctl_loop{1, 2} failure due to clang change") solved a similar problem by defining the string const as a global. Let us do the same here
for test_sysctl_prog.c so it can weather future potential llvm changes.
--- tools/testing/selftests/bpf/progs/test_sysctl_prog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/testing/selftests/bpf/progs/test_sysctl_prog.c +2 -2
@@ -19,11 +19,11 @@#define ARRAY_SIZE (x) (sizeof(x) / sizeof((x)[0]))#endif +const char tcp_mem_name[] ="net/ipv4/tcp_mem" ; static __always_inline int is_tcp_mem(struct bpf_sysctl *ctx) { -char tcp_mem_name[] ="net/ipv4/tcp_mem" ;unsigned char i; -char name[64 ]; +char name[sizeof (tcp_mem_name)];int ret;memset (name,0 ,sizeof (name));
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 108/391 selinux: access policycaps with READ_ONCE/WRITE_ONCE
In reply to Greg Kroah-HartmanFrom: Stephen Smalley <[email protected]>
[ Upstream commit e8ba53d0023a76ba0f50e6ee3e6288c5442f9d33 ]
Use READ_ONCE/WRITE_ONCE for all accesses to the selinux_state.policycaps booleans to prevent compiler mischief.
--- security/selinux/include/security.h | 14 +++++++------- security/selinux/ss/services.c | 3 ++- 2 files changed, 9 insertions(+), 8 deletions(-)
security/selinux/include/security.h +7 -7
@@ -177,49 +177,49 @@ static inline bool selinux_policycap_netpeer(void) {struct selinux_state *state = &selinux_state; -return state->policycap[POLICYDB_CAPABILITY_NETPEER ]; +return READ_ONCE (state->policycap[POLICYDB_CAPABILITY_NETPEER ]); }static inline bool selinux_policycap_openperm (void ) {struct selinux_state *state = &selinux_state; -return state->policycap[POLICYDB_CAPABILITY_OPENPERM ]; +return READ_ONCE (state->policycap[POLICYDB_CAPABILITY_OPENPERM ]); }static inline bool selinux_policycap_extsockclass (void ) {struct selinux_state *state = &selinux_state; -return state->policycap[POLICYDB_CAPABILITY_EXTSOCKCLASS ]; +return READ_ONCE (state->policycap[POLICYDB_CAPABILITY_EXTSOCKCLASS ]); }static inline bool selinux_policycap_alwaysnetwork (void ) {struct selinux_state *state = &selinux_state; -return state->policycap[POLICYDB_CAPABILITY_ALWAYSNETWORK ]; +return READ_ONCE (state->policycap[POLICYDB_CAPABILITY_ALWAYSNETWORK ]); }static inline bool selinux_policycap_cgroupseclabel (void ) {struct selinux_state *state = &selinux_state; -return state->policycap[POLICYDB_CAPABILITY_CGROUPSECLABEL ]; +return READ_ONCE (state->policycap[POLICYDB_CAPABILITY_CGROUPSECLABEL ]); }static inline bool selinux_policycap_nnp_nosuid_transition (void ) {struct selinux_state *state = &selinux_state; -return state->policycap[POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION ]; +return READ_ONCE (state->policycap[POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION ]); }static inline bool selinux_policycap_genfs_seclabel_symlinks (void ) {struct selinux_state *state = &selinux_state; -return state->policycap[POLICYDB_CAPABILITY_GENFS_SECLABEL_SYMLINKS ]; +return READ_ONCE (state->policycap[POLICYDB_CAPABILITY_GENFS_SECLABEL_SYMLINKS ]); }int security_mls_enabled (struct selinux_state *state);
security/selinux/ss/services.c +2 -1
@@ -2103,7 +2103,8 @@ static void security_load_policycaps(struct selinux_state *state)struct ebitmap_node *node;for (i =0 ; i <ARRAY_SIZE (state->policycap); i++) - state->policycap[i] =ebitmap_get_bit (&p->policycaps, i); +WRITE_ONCE (state->policycap[i], +ebitmap_get_bit (&p->policycaps, i));for (i =0 ; i <ARRAY_SIZE (selinux_policycap_names); i++) pr_info("SELinux: policy capability %s=%d\n",
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 109/391 samples/bpf: Fix possible deadlock in xdpsock
In reply to Greg Kroah-HartmanFrom: Magnus Karlsson <[email protected]>
[ Upstream commit 5a2a0dd88f0f267ac5953acd81050ae43a82201f ]
Fix a possible deadlock in the l2fwd application in xdpsock that can occur when there is no space in the Tx ring. There are two ways to get the kernel to consume entries in the Tx ring: calling sendto() to make it send packets and freeing entries from the completion ring, as the kernel will not send a packet if there is no space for it to add a completion entry in the completion ring. The Tx loop in l2fwd only used to call sendto(). This patches adds cleaning the completion ring in that loop.
--- samples/bpf/xdpsock_user.c | 1 + 1 file changed, 1 insertion(+)
samples/bpf/xdpsock_user.c +1 -0
@@ -1111,6 +1111,7 @@ static void l2fwd(struct xsk_socket_info *xsk, struct pollfd *fds)while (ret != rcvd) {if (ret <0 )exit_with_error (-ret); +complete_tx_l2fwd (xsk, fds);if (xsk_ring_prod__needs_wakeup (&xsk->tx))kick_tx (xsk); ret =xsk_ring_prod__reserve (&xsk->tx, rcvd, &idx_tx);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 110/391 drm/amd/display: Check clock table return
In reply to Greg Kroah-HartmanFrom: Rodrigo Siqueira <[email protected]>
[ Upstream commit 4b4f21ff7f5d11bb77e169b306dcbc5b216f5db5 ]
During the load processes for Renoir, our display code needs to retrieve the SMU clock and voltage table, however, this operation can fail which means that we have to check this scenario. Currently, we are not handling this case properly and as a result, we have seen the following dmesg log during the boot:
RIP: 0010:rn_clk_mgr_construct+0x129/0x3d0 [amdgpu] ... Call Trace: dc_clk_mgr_create+0x16a/0x1b0 [amdgpu] dc_create+0x231/0x760 [amdgpu]
This commit fixes this issue by checking the return status retrieved from the clock table before try to populate any bandwidth.
--- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +5 -2
@@ -761,6 +761,7 @@ void rn_clk_mgr_construct( {struct dc_debug_options *debug = &ctx->dc->debug;struct dpm_clocks clock_table = {0 }; +enum pp_smu_status status =0 ; clk_mgr->base.ctx = ctx; clk_mgr->base.funcs = &dcn21_funcs;
@@ -817,8 +818,10 @@ void rn_clk_mgr_construct( clk_mgr->base.bw_params = &rn_bw_params;if (pp_smu && pp_smu->rn_funcs.get_dpm_clock_table) { - pp_smu->rn_funcs.get_dpm_clock_table (&pp_smu->rn_funcs.pp_smu, &clock_table); -if (ctx->dc_bios && ctx->dc_bios->integrated_info) { + status = pp_smu->rn_funcs.get_dpm_clock_table (&pp_smu->rn_funcs.pp_smu, &clock_table); + +if (status ==PP_SMU_RESULT_OK && + ctx->dc_bios && ctx->dc_bios->integrated_info) {rn_clk_mgr_helper_populate_bw_params (clk_mgr->base.bw_params, &clock_table, ctx->dc_bios->integrated_info); } }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 111/391 riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO
In reply to Greg Kroah-HartmanFrom: Zong Li <[email protected]>
[ Upstream commit b5fca7c55f9fbab5ad732c3bce00f31af6ba5cfa ]
AT_VECTOR_SIZE_ARCH should be defined with the maximum number of NEW_AUX_ENT entries that ARCH_DLINFO can contain, but it wasn't defined for RISC-V at all even though ARCH_DLINFO will contain one NEW_AUX_ENT for the VDSO address.
--- arch/riscv/include/uapi/asm/auxvec.h | 3 +++ 1 file changed, 3 insertions(+)
arch/riscv/include/uapi/asm/auxvec.h +3 -0
@@ -10,4 +10,7 @@/* vDSO location */ #define AT_SYSINFO_EHDR 33 +/* entries in ARCH_DLINFO */ +#define AT_VECTOR_SIZE_ARCH 1 +#endif /* _UAPI_ASM_RISCV_AUXVEC_H */
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 112/391 cpufreq: sti-cpufreq: add stih418 support
In reply to Greg Kroah-HartmanFrom: Alain Volmat <[email protected]>
[ Upstream commit 01a163c52039e9426c7d3d3ab16ca261ad622597 ]
The STiH418 can be controlled the same way as STiH407 & STiH410 regarding cpufreq.
--- drivers/cpufreq/sti-cpufreq.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/cpufreq/sti-cpufreq.c +4 -2
@@ -141,7 +141,8 @@ static const struct reg_field sti_stih407_dvfs_regfields[DVFS_MAX_REGFIELDS] = {static const struct reg_field *sti_cpufreq_match (void ) {if (of_machine_is_compatible ("st,stih407" ) || -of_machine_is_compatible ("st,stih410" )) +of_machine_is_compatible ("st,stih410" ) || +of_machine_is_compatible ("st,stih418" ))return sti_stih407_dvfs_regfields;return NULL ;
@@ -258,7 +259,8 @@ static int sti_cpufreq_init(void)int ret;if ((!of_machine_is_compatible ("st,stih407" )) && - (!of_machine_is_compatible ("st,stih410" ))) + (!of_machine_is_compatible ("st,stih410" )) && + (!of_machine_is_compatible ("st,stih418" )))return -ENODEV ; ddata.cpu =get_cpu_device (0 );
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 113/391 USB: adutux: fix debugging
In reply to Greg Kroah-HartmanFrom: Oliver Neukum <[email protected]>
[ Upstream commit c56150c1bc8da5524831b1dac2eec3c67b89f587 ]
Handling for removal of the controller was missing at one place. Add it.
--- drivers/usb/misc/adutux.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/misc/adutux.c +1 -0
@@ -209,6 +209,7 @@ static void adu_interrupt_out_callback(struct urb *urb)if (status !=0 ) {if ((status != -ENOENT ) && + (status != -ESHUTDOWN ) && (status != -ECONNRESET )) { dev_dbg(&dev->udev->dev, "%s :nonzero status received: %d\n", __func__,
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 114/391 uio: free uio id after uio file node is freed
In reply to Greg Kroah-HartmanFrom: Lang Dai <[email protected]>
[ Upstream commit 8fd0e2a6df262539eaa28b0a2364cca10d1dc662 ]
uio_register_device() do two things.
1) get an uio id from a global pool, e.g. the id is <A>
2) create file nodes like /sys/class/uio/uio<A>
uio_unregister_device() do two things.
1) free the uio id <A> and return it to the global pool
2) free the file node /sys/class/uio/uio<A>
There is a situation is that one worker is calling uio_unregister_device(), and another worker is calling uio_register_device().
If the two workers are X and Y, they go as below sequence,
1) X free the uio id <AAA>
2) Y get an uio id <AAA>
3) Y create file node /sys/class/uio/uio<AAA>
4) X free the file note /sys/class/uio/uio<AAA>
Then it will failed at the 3rd step and cause the phenomenon we saw as it is creating a duplicated file node.
Failure reports as follows:
sysfs: cannot create duplicate filename '/class/uio/uio10'
Call Trace: sysfs_do_create_link_sd.isra.2+0x9e/0xb0 sysfs_create_link+0x25/0x40 device_add+0x2c4/0x640 __uio_register_device+0x1c5/0x576 [uio] adf_uio_init_bundle_dev+0x231/0x280 [intel_qat] adf_uio_register+0x1c0/0x340 [intel_qat] adf_dev_start+0x202/0x370 [intel_qat] adf_dev_start_async+0x40/0xa0 [intel_qat] process_one_work+0x14d/0x410 worker_thread+0x4b/0x460 kthread+0x105/0x140 ? process_one_work+0x410/0x410 ? kthread_bind+0x40/0x40 ret_from_fork+0x1f/0x40 Code: 85 c0 48 89 c3 74 12 b9 00 10 00 00 48 89 c2 31 f6 4c 89 ef e8 ec c4 ff ff 4c 89 e2 48 89 de 48 c7 c7 e8 b4 ee b4 e8 6a d4 d7 ff <0f> 0b 48 89 df e8 20 fa f3 ff 5b 41 5c 41 5d 5d c3 66 0f 1f 84 ---[ end trace a7531c1ed5269e84 ]--- c6xxvf b002:00:00.0: Failed to register UIO devices c6xxvf b002:00:00.0: Failed to register UIO devices
--- drivers/uio/uio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/uio/uio.c +2 -2
@@ -1048,8 +1048,6 @@ void uio_unregister_device(struct uio_info *info) idev = info->uio_dev; -uio_free_minor (idev); -mutex_lock (&idev->info_lock);uio_dev_del_attributes (idev);
@@ -1064,6 +1062,8 @@ void uio_unregister_device(struct uio_info *info)device_unregister (&idev->dev); +uio_free_minor (idev); +return ; }EXPORT_SYMBOL_GPL (uio_unregister_device);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 115/391 coresight: Make sysfs functional on topologies with per core sink
In reply to Greg Kroah-HartmanFrom: Linu Cherian <[email protected]>
[ Upstream commit 6d578258b955fc8888e1bbd9a8fefe7b10065a84 ]
Coresight driver assumes sink is common across all the ETMs, and tries to build a path between ETM and the first enabled sink found using bus based search. This breaks sysFS usage on implementations that has multiple per core sinks in enabled state.
To fix this, coresight_get_enabled_sink API is updated to do a connection based search starting from the given source, instead of bus based search.
With sink selection using sysfs depecrated for perf interface, provision for reset is removed as well in this API.
--- drivers/hwtracing/coresight/coresight-priv.h | 3 +- drivers/hwtracing/coresight/coresight.c | 62 +++++++++----------- 2 files changed, 29 insertions(+), 36 deletions(-)
drivers/hwtracing/coresight/coresight-priv.h +2 -1
@@ -148,7 +148,8 @@ static inline void coresight_write_reg_pair(void __iomem *addr, u64 val,void coresight_disable_path (struct list_head *path);int coresight_enable_path (struct list_head *path,u32 mode,void *sink_data);struct coresight_device *coresight_get_sink (struct list_head *path); -struct coresight_device *coresight_get_enabled_sink (bool reset); +struct coresight_device * +coresight_get_enabled_sink (struct coresight_device *source);struct coresight_device *coresight_get_sink_by_id (u32 id);struct coresight_device *coresight_find_default_sink (struct coresight_device *csdev);
drivers/hwtracing/coresight/coresight.c +27 -35
88 lines not on this page · raw message
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 116/391 drm/amdgpu: No sysfs, not an error condition
In reply to Greg Kroah-HartmanFrom: Luben Tuikov <[email protected]>
[ Upstream commit 5aea5327ea2ddf544cbeff096f45fc2319b0714e ]
Not being able to create amdgpu sysfs attributes is not a fatal error warranting not to continue to try to bring up the display. Thus, if we get an error trying to create amdgpu sysfs attrs, report it and continue on to try to bring up
a display.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +1 -3
@@ -3316,10 +3316,8 @@ fence_driver_init:flush_delayed_work (&adev->delayed_init_work); r =sysfs_create_files (&adev->dev->kobj, amdgpu_dev_attributes); -if (r) { +if (r)dev_err (adev->dev,"Could not create amdgpu device attr\n" ); -return r; - }if (IS_ENABLED (CONFIG_PERF_EVENTS )) r =amdgpu_pmu_init (adev);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 117/391 mac80211: add missing queue/hash initialization to 802.3 xmit
In reply to Greg Kroah-HartmanFrom: Felix Fietkau <[email protected]>
[ Upstream commit 5f8d69eaab1915df97f4f2aca89ea16abdd092d5 ]
Fixes AQL for encap-offloaded tx
--- net/mac80211/tx.c | 6 ++++++ 1 file changed, 6 insertions(+)
net/mac80211/tx.c +6 -0
@@ -4209,6 +4209,12 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,if (is_zero_ether_addr (ra)) goto out_free; +if (local->ops->wake_tx_queue) { +u16 queue =__ieee80211_select_queue (sdata, sta, skb); +skb_set_queue_mapping (skb, queue); +skb_get_hash (skb); + } + multicast =is_multicast_ether_addr (ra);if (sta)
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 118/391 usb: xhci: omit duplicate actions when suspending a runtime suspended host.
In reply to Greg Kroah-HartmanFrom: Peter Chen <[email protected]>
[ Upstream commit 18a367e8947d72dd91b6fc401e88a2952c6363f7 ]
If the xhci-plat.c is the platform driver, after the runtime pm is enabled, the xhci_suspend is called if nothing is connected on the port. When the system goes to suspend, it will call xhci_suspend again if USB wakeup is enabled.
Since the runtime suspend wakeup setting is not always the same as system suspend wakeup setting, eg, at runtime suspend we always need wakeup if the controller is in low power mode; but at system suspend, we may not need wakeup. So, we move the judgement after changing wakeup setting.
[commit message rewording -Mathias]
--- drivers/usb/host/xhci.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/usb/host/xhci.c +5 -2
@@ -982,12 +982,15 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) xhci->shared_hcd->state != HC_STATE_SUSPENDED)return -EINVAL ; -xhci_dbc_suspend (xhci); -/* Clear root port wake on bits if wakeup not allowed. */ if (!do_wakeup)xhci_disable_port_wake_on_bits (xhci); +if (!HCD_HW_ACCESSIBLE (hcd)) +return 0 ; + +xhci_dbc_suspend (xhci); +/* Don't poll the roothubs on bus suspend. */ xhci_dbg (xhci,"%s: stopping port polling.\n" , __func__);clear_bit (HCD_FLAG_POLL_RH , &hcd->flags);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 119/391 SUNRPC: Mitigate cond_resched() in xprt_transmit()
In reply to Greg Kroah-HartmanFrom: Chuck Lever <[email protected]>
[ Upstream commit 6f9f17287e78e5049931af2037b15b26d134a32a ]
The original purpose of this expensive call is to prevent a long queue of requests from blocking other work.
The cond_resched() call is unnecessary after just a single send operation.
For longer queues, instead of invoking the kernel scheduler, simply release the transport send lock and return to the RPC scheduler.
--- net/sunrpc/xprt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
net/sunrpc/xprt.c +4 -2
@@ -1520,10 +1520,13 @@ xprt_transmit(struct rpc_task *task) {struct rpc_rqst *next, *req = task->tk_rqstp;struct rpc_xprt *xprt = req->rq_xprt; -int status; +int counter, status;spin_lock (&xprt->queue_lock); + counter =0 ;while (!list_empty (&xprt->xmit_queue)) { +if (++counter ==20 ) +break ; next =list_first_entry (&xprt->xmit_queue, struct rpc_rqst, rq_xmit);xprt_pin_rqst (next);
@@ -1531,7 +1534,6 @@ xprt_transmit(struct rpc_task *task) status =xprt_request_transmit (next, task);if (status == -EBADMSG && next != req) status =0 ; -cond_resched ();spin_lock (&xprt->queue_lock);xprt_unpin_rqst (next);if (status ==0 ) {
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 120/391 cpuidle: tegra: Correctly handle result of arm_cpuidle_simple_enter()
In reply to Greg Kroah-HartmanFrom: Dmitry Osipenko <[email protected]>
[ Upstream commit 1170433e6611402b869c583fa1fbfd85106ff066 ]
The enter() callback of CPUIDLE drivers returns index of the entered idle state on success or a negative value on failure. The negative value could any negative value, i.e. it doesn't necessarily needs to be a error code. That's because CPUIDLE core only cares about the fact of failure and not about the reason of the enter() failure.
Like every other enter() callback, the arm_cpuidle_simple_enter() returns the entered idle-index on success. Unlike some of other drivers, it never fails. It happened that TEGRA_C1=index=err=0 in the code of cpuidle-tegra driver, and thus, there is no problem for the cpuidle-tegra driver created by the typo in the code which assumes that the arm_cpuidle_simple_enter() returns a error code.
The arm_cpuidle_simple_enter() also may return a -ENODEV error if CPU_IDLE is disabled in a kernel's config, but all CPUIDLE drivers are disabled if CPU_IDLE is disabled, including the cpuidle-tegra driver. So we can't ever see the error code from arm_cpuidle_simple_enter() today.
Of course the code may get some changes in the future and then the typo may transform into a real bug, so let's correct the typo! The tegra_cpuidle_state_enter() is now changed to make it return the entered idle-index on success and negative error code on fail, which puts it on par with the arm_cpuidle_simple_enter(), making code consistent in regards to the error handling.
This patch fixes a minor typo in the code, it doesn't fix any bugs.
--- drivers/cpuidle/cpuidle-tegra.c | 34 +++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-)
drivers/cpuidle/cpuidle-tegra.c +20 -14
@@ -172,7 +172,7 @@ static int tegra_cpuidle_coupled_barrier(struct cpuidle_device *dev)static int tegra_cpuidle_state_enter (struct cpuidle_device *dev,int index,unsigned int cpu) { -int ret; +int err;/* * CC6 state is the "CPU cluster power-off" state. In order to
@@ -183,9 +183,9 @@ static int tegra_cpuidle_state_enter(struct cpuidle_device *dev,* CPU cores, GIC and L2 cache). */ if (index ==TEGRA_CC6 ) { - ret =tegra_cpuidle_coupled_barrier (dev); -if (ret) -return ret; + err =tegra_cpuidle_coupled_barrier (dev); +if (err) +return err; }local_fiq_disable ();
@@ -194,15 +194,15 @@ static int tegra_cpuidle_state_enter(struct cpuidle_device *dev,switch (index) {case TEGRA_C7 : - ret =tegra_cpuidle_c7_enter (); + err =tegra_cpuidle_c7_enter ();break ;case TEGRA_CC6 : - ret =tegra_cpuidle_cc6_enter (cpu); + err =tegra_cpuidle_cc6_enter (cpu);break ;default : - ret = -EINVAL ; + err = -EINVAL ;break ; }
@@ -210,7 +210,7 @@ static int tegra_cpuidle_state_enter(struct cpuidle_device *dev,tegra_pm_clear_cpu_in_lp2 ();local_fiq_enable (); -return ret; +return err ?: index; }static int tegra_cpuidle_adjust_state_index (int index,unsigned int cpu)
@@ -236,21 +236,27 @@ static int tegra_cpuidle_enter(struct cpuidle_device *dev, int index) {unsigned int cpu =cpu_logical_map (dev->cpu); -int err; +int ret; index =tegra_cpuidle_adjust_state_index (index, cpu);if (dev->states_usage[index].disable)return -1 ;if (index ==TEGRA_C1 ) - err =arm_cpuidle_simple_enter (dev, drv, index); + ret =arm_cpuidle_simple_enter (dev, drv, index);else - err =tegra_cpuidle_state_enter (dev, index, cpu); + ret =tegra_cpuidle_state_enter (dev, index, cpu); -if (err && (err != -EINTR || index !=TEGRA_CC6 )) -pr_err_once ("failed to enter state %d err: %d\n" , index, err); +if (ret <0 ) { +if (ret != -EINTR || index !=TEGRA_CC6 ) +pr_err_once ("failed to enter state %d err: %d\n" , + index, ret); + index =-1 ; + }else { + index = ret; + } -return err ?-1 : index; +return index; } static int tegra114_enter_s2idle(struct cpuidle_device *dev,
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 121/391 arm64/mm: return cpu_all_mask when node is NUMA_NO_NODE
In reply to Greg Kroah-HartmanFrom: Zhengyuan Liu <[email protected]>
[ Upstream commit a194c5f2d2b3a05428805146afcabe5140b5d378 ]
The @node passed to cpumask_of_node() can be NUMA_NO_NODE, in that case it will trigger the following WARN_ON(node >= nr_node_ids) due to mismatched data types of @node and @nr_node_ids. Actually we should return cpu_all_mask just like most other architectures do if passed NUMA_NO_NODE.
Also add a similar check to the inline cpumask_of_node() in numa.h.
--- arch/arm64/include/asm/numa.h | 3 +++ arch/arm64/mm/numa.c | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-)
arch/arm64/include/asm/numa.h +3 -0
@@ -25,6 +25,9 @@ const struct cpumask *cpumask_of_node(int node);/* Returns a pointer to the cpumask of CPUs on Node 'node'. */ static inline const struct cpumask *cpumask_of_node (int node) { +if (node ==NUMA_NO_NODE ) +return cpu_all_mask; +return node_to_cpumask_map[node]; }#endif
arch/arm64/mm/numa.c +5 -1
@@ -46,7 +46,11 @@ EXPORT_SYMBOL(node_to_cpumask_map);*/ const struct cpumask *cpumask_of_node (int node) { -if (WARN_ON (node >= nr_node_ids)) + +if (node ==NUMA_NO_NODE ) +return cpu_all_mask; + +if (WARN_ON (node <0 || node >= nr_node_ids))return cpu_none_mask;if (WARN_ON (node_to_cpumask_map[node] ==NULL ))
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 122/391 can: flexcan: disable clocks during stop mode
In reply to Greg Kroah-HartmanFrom: Joakim Zhang <[email protected]>
[ Upstream commit 02f71c6605e1f8259c07f16178330db766189a74 ]
Disable clocks while CAN core is in stop mode.
--- drivers/net/can/flexcan.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-)
drivers/net/can/flexcan.c +20 -10
@@ -1722,8 +1722,6 @@ static int __maybe_unused flexcan_suspend(struct device *device) err =flexcan_chip_disable (priv);if (err)return err; - - err =pm_runtime_force_suspend (device); }netif_stop_queue (dev);netif_device_detach (dev);
@@ -1749,10 +1747,6 @@ static int __maybe_unused flexcan_resume(struct device *device)if (err)return err; }else { - err =pm_runtime_force_resume (device); -if (err) -return err; - err =flexcan_chip_enable (priv); } }
@@ -1783,8 +1777,16 @@ static int __maybe_unused flexcan_noirq_suspend(struct device *device)struct net_device *dev =dev_get_drvdata (device);struct flexcan_priv *priv =netdev_priv (dev); -if (netif_running (dev) &&device_may_wakeup (device)) -flexcan_enable_wakeup_irq (priv, true); +if (netif_running (dev)) { +int err; + +if (device_may_wakeup (device)) +flexcan_enable_wakeup_irq (priv, true); + + err =pm_runtime_force_suspend (device); +if (err) +return err; + }return 0 ; }
@@ -1794,8 +1796,16 @@ static int __maybe_unused flexcan_noirq_resume(struct device *device)struct net_device *dev =dev_get_drvdata (device);struct flexcan_priv *priv =netdev_priv (dev); -if (netif_running (dev) &&device_may_wakeup (device)) -flexcan_enable_wakeup_irq (priv, false); +if (netif_running (dev)) { +int err; + + err =pm_runtime_force_resume (device); +if (err) +return err; + +if (device_may_wakeup (device)) +flexcan_enable_wakeup_irq (priv, false); + }return 0 ; }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 123/391 habanalabs: remove security from ARB_MST_QUIET register
In reply to Greg Kroah-HartmanFrom: farah kassabri <[email protected]>
[ Upstream commit acd330c141b4c49f468f00719ebc944656061eac ]
Allow user application to write to this register in order to be able to configure the quiet period of the QMAN between grants.
--- .../misc/habanalabs/gaudi/gaudi_security.c | 55 +++++++------------ 1 file changed, 19 insertions(+), 36 deletions(-)
drivers/misc/habanalabs/gaudi/gaudi_security.c +19 -36
@@ -831,8 +831,7 @@ static void gaudi_init_mme_protection_bits(struct hl_device *hdev)PROT_BITS_OFFS ; word_offset = ((mmMME0_QM_ARB_MST_CHOISE_PUSH_OFST_23 &PROT_BITS_OFFS ) >>7 ) <<2 ; - mask =1 << ((mmMME0_QM_ARB_MST_QUIET_PER &0x7F ) >>2 ); - mask |=1 << ((mmMME0_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); + mask =1 << ((mmMME0_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); mask |=1 << ((mmMME0_QM_ARB_MSG_MAX_INFLIGHT &0x7F ) >>2 ); mask |=1 << ((mmMME0_QM_ARB_MSG_AWUSER_31_11 &0x7F ) >>2 ); mask |=1 << ((mmMME0_QM_ARB_MSG_AWUSER_SEC_PROP &0x7F ) >>2 );
@@ -1311,8 +1310,7 @@ static void gaudi_init_mme_protection_bits(struct hl_device *hdev)PROT_BITS_OFFS ; word_offset = ((mmMME2_QM_ARB_MST_CHOISE_PUSH_OFST_23 &PROT_BITS_OFFS ) >>7 ) <<2 ; - mask =1 << ((mmMME2_QM_ARB_MST_QUIET_PER &0x7F ) >>2 ); - mask |=1 << ((mmMME2_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); + mask =1 << ((mmMME2_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); mask |=1 << ((mmMME2_QM_ARB_MSG_MAX_INFLIGHT &0x7F ) >>2 ); mask |=1 << ((mmMME2_QM_ARB_MSG_AWUSER_31_11 &0x7F ) >>2 ); mask |=1 << ((mmMME2_QM_ARB_MSG_AWUSER_SEC_PROP &0x7F ) >>2 );
@@ -1790,8 +1788,7 @@ static void gaudi_init_dma_protection_bits(struct hl_device *hdev) word_offset = ((mmDMA0_QM_ARB_MST_CHOISE_PUSH_OFST_23 &PROT_BITS_OFFS ) >>7 ) <<2 ; - mask =1 << ((mmDMA0_QM_ARB_MST_QUIET_PER &0x7F ) >>2 ); - mask |=1 << ((mmDMA0_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); + mask =1 << ((mmDMA0_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); mask |=1 << ((mmDMA0_QM_ARB_MSG_MAX_INFLIGHT &0x7F ) >>2 ); mask |=1 << ((mmDMA0_QM_ARB_MSG_AWUSER_31_11 &0x7F ) >>2 ); mask |=1 << ((mmDMA0_QM_ARB_MSG_AWUSER_SEC_PROP &0x7F ) >>2 );
@@ -2186,8 +2183,7 @@ static void gaudi_init_dma_protection_bits(struct hl_device *hdev) word_offset = ((mmDMA1_QM_ARB_MST_CHOISE_PUSH_OFST_23 &PROT_BITS_OFFS ) >>7 ) <<2 ; - mask =1 << ((mmDMA1_QM_ARB_MST_QUIET_PER &0x7F ) >>2 ); - mask |=1 << ((mmDMA1_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); + mask =1 << ((mmDMA1_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); mask |=1 << ((mmDMA1_QM_ARB_MSG_MAX_INFLIGHT &0x7F ) >>2 ); mask |=1 << ((mmDMA1_QM_ARB_MSG_AWUSER_31_11 &0x7F ) >>2 ); mask |=1 << ((mmDMA1_QM_ARB_MSG_AWUSER_SEC_PROP &0x7F ) >>2 );
@@ -2582,8 +2578,7 @@ static void gaudi_init_dma_protection_bits(struct hl_device *hdev) word_offset = ((mmDMA2_QM_ARB_MST_CHOISE_PUSH_OFST_23 &PROT_BITS_OFFS ) >>7 ) <<2 ; - mask =1 << ((mmDMA2_QM_ARB_MST_QUIET_PER &0x7F ) >>2 ); - mask |=1 << ((mmDMA2_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); + mask =1 << ((mmDMA2_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); mask |=1 << ((mmDMA2_QM_ARB_MSG_MAX_INFLIGHT &0x7F ) >>2 ); mask |=1 << ((mmDMA2_QM_ARB_MSG_AWUSER_31_11 &0x7F ) >>2 ); mask |=1 << ((mmDMA2_QM_ARB_MSG_AWUSER_SEC_PROP &0x7F ) >>2 );
@@ -2978,8 +2973,7 @@ static void gaudi_init_dma_protection_bits(struct hl_device *hdev) word_offset = ((mmDMA3_QM_ARB_MST_CHOISE_PUSH_OFST_23 &PROT_BITS_OFFS ) >>7 ) <<2 ; - mask =1 << ((mmDMA3_QM_ARB_MST_QUIET_PER &0x7F ) >>2 ); - mask |=1 << ((mmDMA3_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); + mask =1 << ((mmDMA3_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); mask |=1 << ((mmDMA3_QM_ARB_MSG_MAX_INFLIGHT &0x7F ) >>2 ); mask |=1 << ((mmDMA3_QM_ARB_MSG_AWUSER_31_11 &0x7F ) >>2 ); mask |=1 << ((mmDMA3_QM_ARB_MSG_AWUSER_SEC_PROP &0x7F ) >>2 );
@@ -3374,8 +3368,7 @@ static void gaudi_init_dma_protection_bits(struct hl_device *hdev) word_offset = ((mmDMA4_QM_ARB_MST_CHOISE_PUSH_OFST_23 &PROT_BITS_OFFS ) >>7 ) <<2 ; - mask =1 << ((mmDMA4_QM_ARB_MST_QUIET_PER &0x7F ) >>2 ); - mask |=1 << ((mmDMA4_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); + mask =1 << ((mmDMA4_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); mask |=1 << ((mmDMA4_QM_ARB_MSG_MAX_INFLIGHT &0x7F ) >>2 ); mask |=1 << ((mmDMA4_QM_ARB_MSG_AWUSER_31_11 &0x7F ) >>2 ); mask |=1 << ((mmDMA4_QM_ARB_MSG_AWUSER_SEC_PROP &0x7F ) >>2 );
@@ -3770,8 +3763,7 @@ static void gaudi_init_dma_protection_bits(struct hl_device *hdev) word_offset = ((mmDMA5_QM_ARB_MST_CHOISE_PUSH_OFST_23 &PROT_BITS_OFFS ) >>7 ) <<2 ; - mask =1 << ((mmDMA5_QM_ARB_MST_QUIET_PER &0x7F ) >>2 ); - mask |=1 << ((mmDMA5_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); + mask =1 << ((mmDMA5_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); mask |=1 << ((mmDMA5_QM_ARB_MSG_MAX_INFLIGHT &0x7F ) >>2 ); mask |=1 << ((mmDMA5_QM_ARB_MSG_AWUSER_31_11 &0x7F ) >>2 ); mask |=1 << ((mmDMA5_QM_ARB_MSG_AWUSER_SEC_PROP &0x7F ) >>2 );
@@ -4166,8 +4158,8 @@ static void gaudi_init_dma_protection_bits(struct hl_device *hdev) word_offset = ((mmDMA6_QM_ARB_MST_CHOISE_PUSH_OFST_23 &PROT_BITS_OFFS ) >>7 ) <<2 ; - mask =1 << ((mmDMA6_QM_ARB_MST_QUIET_PER &0x7F ) >>2 ); - mask |=1 << ((mmDMA6_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); + + mask =1 << ((mmDMA6_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); mask |=1 << ((mmDMA6_QM_ARB_MSG_MAX_INFLIGHT &0x7F ) >>2 ); mask |=1 << ((mmDMA6_QM_ARB_MSG_AWUSER_31_11 &0x7F ) >>2 ); mask |=1 << ((mmDMA6_QM_ARB_MSG_AWUSER_SEC_PROP &0x7F ) >>2 );
@@ -4562,8 +4554,7 @@ static void gaudi_init_dma_protection_bits(struct hl_device *hdev) word_offset = ((mmDMA7_QM_ARB_MST_CHOISE_PUSH_OFST_23 &PROT_BITS_OFFS ) >>7 ) <<2 ; - mask =1 << ((mmDMA7_QM_ARB_MST_QUIET_PER &0x7F ) >>2 ); - mask |=1 << ((mmDMA7_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); + mask =1 << ((mmDMA7_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); mask |=1 << ((mmDMA7_QM_ARB_MSG_MAX_INFLIGHT &0x7F ) >>2 ); mask |=1 << ((mmDMA7_QM_ARB_MSG_AWUSER_31_11 &0x7F ) >>2 ); mask |=1 << ((mmDMA7_QM_ARB_MSG_AWUSER_SEC_PROP &0x7F ) >>2 );
@@ -5491,8 +5482,7 @@ static void gaudi_init_tpc_protection_bits(struct hl_device *hdev) word_offset = ((mmTPC0_QM_ARB_MST_CHOISE_PUSH_OFST_23 &PROT_BITS_OFFS ) >>7 ) <<2 ; - mask =1 << ((mmTPC0_QM_ARB_MST_QUIET_PER &0x7F ) >>2 ); - mask |=1 << ((mmTPC0_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); + mask =1 << ((mmTPC0_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); mask |=1 << ((mmTPC0_QM_ARB_MSG_MAX_INFLIGHT &0x7F ) >>2 ); mask |=1 << ((mmTPC0_QM_ARB_MSG_AWUSER_31_11 &0x7F ) >>2 ); mask |=1 << ((mmTPC0_QM_ARB_MSG_AWUSER_SEC_PROP &0x7F ) >>2 );
@@ -5947,8 +5937,7 @@ static void gaudi_init_tpc_protection_bits(struct hl_device *hdev) word_offset = ((mmTPC1_QM_ARB_MST_CHOISE_PUSH_OFST_23 &PROT_BITS_OFFS ) >>7 ) <<2 ; - mask =1 << ((mmTPC1_QM_ARB_MST_QUIET_PER &0x7F ) >>2 ); - mask |=1 << ((mmTPC1_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); + mask =1 << ((mmTPC1_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); mask |=1 << ((mmTPC1_QM_ARB_MSG_MAX_INFLIGHT &0x7F ) >>2 ); mask |=1 << ((mmTPC1_QM_ARB_MSG_AWUSER_31_11 &0x7F ) >>2 ); mask |=1 << ((mmTPC1_QM_ARB_MSG_AWUSER_SEC_PROP &0x7F ) >>2 );
@@ -6402,8 +6391,7 @@ static void gaudi_init_tpc_protection_bits(struct hl_device *hdev)PROT_BITS_OFFS ; word_offset = ((mmTPC2_QM_ARB_MST_CHOISE_PUSH_OFST_23 &PROT_BITS_OFFS ) >>7 ) <<2 ; - mask =1 << ((mmTPC2_QM_ARB_MST_QUIET_PER &0x7F ) >>2 ); - mask |=1 << ((mmTPC2_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); + mask =1 << ((mmTPC2_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); mask |=1 << ((mmTPC2_QM_ARB_MSG_MAX_INFLIGHT &0x7F ) >>2 ); mask |=1 << ((mmTPC2_QM_ARB_MSG_AWUSER_31_11 &0x7F ) >>2 ); mask |=1 << ((mmTPC2_QM_ARB_MSG_AWUSER_SEC_PROP &0x7F ) >>2 );
@@ -6857,8 +6845,7 @@ static void gaudi_init_tpc_protection_bits(struct hl_device *hdev)PROT_BITS_OFFS ; word_offset = ((mmTPC3_QM_ARB_MST_CHOISE_PUSH_OFST_23 &PROT_BITS_OFFS ) >>7 ) <<2 ; - mask =1 << ((mmTPC3_QM_ARB_MST_QUIET_PER &0x7F ) >>2 ); - mask |=1 << ((mmTPC3_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); + mask =1 << ((mmTPC3_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); mask |=1 << ((mmTPC3_QM_ARB_MSG_MAX_INFLIGHT &0x7F ) >>2 ); mask |=1 << ((mmTPC3_QM_ARB_MSG_AWUSER_31_11 &0x7F ) >>2 ); mask |=1 << ((mmTPC3_QM_ARB_MSG_AWUSER_SEC_PROP &0x7F ) >>2 );
@@ -7312,8 +7299,7 @@ static void gaudi_init_tpc_protection_bits(struct hl_device *hdev)PROT_BITS_OFFS ; word_offset = ((mmTPC4_QM_ARB_MST_CHOISE_PUSH_OFST_23 &PROT_BITS_OFFS ) >>7 ) <<2 ; - mask =1 << ((mmTPC4_QM_ARB_MST_QUIET_PER &0x7F ) >>2 ); - mask |=1 << ((mmTPC4_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); + mask =1 << ((mmTPC4_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); mask |=1 << ((mmTPC4_QM_ARB_MSG_MAX_INFLIGHT &0x7F ) >>2 ); mask |=1 << ((mmTPC4_QM_ARB_MSG_AWUSER_31_11 &0x7F ) >>2 ); mask |=1 << ((mmTPC4_QM_ARB_MSG_AWUSER_SEC_PROP &0x7F ) >>2 );
@@ -7767,8 +7753,7 @@ static void gaudi_init_tpc_protection_bits(struct hl_device *hdev)PROT_BITS_OFFS ; word_offset = ((mmTPC5_QM_ARB_MST_CHOISE_PUSH_OFST_23 &PROT_BITS_OFFS ) >>7 ) <<2 ; - mask =1 << ((mmTPC5_QM_ARB_MST_QUIET_PER &0x7F ) >>2 ); - mask |=1 << ((mmTPC5_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); + mask =1 << ((mmTPC5_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); mask |=1 << ((mmTPC5_QM_ARB_MSG_MAX_INFLIGHT &0x7F ) >>2 ); mask |=1 << ((mmTPC5_QM_ARB_MSG_AWUSER_31_11 &0x7F ) >>2 ); mask |=1 << ((mmTPC5_QM_ARB_MSG_AWUSER_SEC_PROP &0x7F ) >>2 );
@@ -8223,8 +8208,7 @@ static void gaudi_init_tpc_protection_bits(struct hl_device *hdev) word_offset = ((mmTPC6_QM_ARB_MST_CHOISE_PUSH_OFST_23 &PROT_BITS_OFFS ) >>7 ) <<2 ; - mask =1 << ((mmTPC6_QM_ARB_MST_QUIET_PER &0x7F ) >>2 ); - mask |=1 << ((mmTPC6_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); + mask =1 << ((mmTPC6_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); mask |=1 << ((mmTPC6_QM_ARB_MSG_MAX_INFLIGHT &0x7F ) >>2 ); mask |=1 << ((mmTPC6_QM_ARB_MSG_AWUSER_31_11 &0x7F ) >>2 ); mask |=1 << ((mmTPC6_QM_ARB_MSG_AWUSER_SEC_PROP &0x7F ) >>2 );
@@ -8681,8 +8665,7 @@ static void gaudi_init_tpc_protection_bits(struct hl_device *hdev)PROT_BITS_OFFS ; word_offset = ((mmTPC7_QM_ARB_MST_CHOISE_PUSH_OFST_23 &PROT_BITS_OFFS ) >>7 ) <<2 ; - mask =1 << ((mmTPC7_QM_ARB_MST_QUIET_PER &0x7F ) >>2 ); - mask |=1 << ((mmTPC7_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); + mask =1 << ((mmTPC7_QM_ARB_SLV_CHOISE_WDT &0x7F ) >>2 ); mask |=1 << ((mmTPC7_QM_ARB_MSG_MAX_INFLIGHT &0x7F ) >>2 ); mask |=1 << ((mmTPC7_QM_ARB_MSG_AWUSER_31_11 &0x7F ) >>2 ); mask |=1 << ((mmTPC7_QM_ARB_MSG_AWUSER_SEC_PROP &0x7F ) >>2 );
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 124/391 xfs: dont free rt blocks when were doing a REMAP bunmapi call
In reply to Greg Kroah-HartmanFrom: Darrick J. Wong <[email protected]>
[ Upstream commit 8df0fa39bdd86ca81a8d706a6ed9d33cc65ca625 ]
When callers pass XFS_BMAPI_REMAP into xfs_bunmapi, they want the extent to be unmapped from the given file fork without the extent being freed. We do this for non-rt files, but we forgot to do this for realtime files. So far this isn't a big deal since nobody makes a bunmapi call to a rt file with the REMAP flag set, but don't leave a logic bomb.
--- fs/xfs/libxfs/xfs_bmap.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-)
fs/xfs/libxfs/xfs_bmap.c +12 -7
@@ -5046,20 +5046,25 @@ xfs_bmap_del_extent_real( flags =XFS_ILOG_CORE ;if (whichfork ==XFS_DATA_FORK &&XFS_IS_REALTIME_INODE (ip)) { -xfs_fsblock_t bno;xfs_filblks_t len;xfs_extlen_t mod; - bno =div_u64_rem (del->br_startblock, mp->m_sb.sb_rextsize, - &mod); -ASSERT (mod ==0 ); len =div_u64_rem (del->br_blockcount, mp->m_sb.sb_rextsize, &mod);ASSERT (mod ==0 ); - error =xfs_rtfree_extent (tp, bno, (xfs_extlen_t )len); -if (error) - goto done; +if (!(bflags &XFS_BMAPI_REMAP )) { +xfs_fsblock_t bno; + + bno =div_u64_rem (del->br_startblock, + mp->m_sb.sb_rextsize, &mod); +ASSERT (mod ==0 ); + + error =xfs_rtfree_extent (tp, bno, (xfs_extlen_t )len); +if (error) + goto done; + } + do_fx =0 ; nblks = len * mp->m_sb.sb_rextsize; qfield =XFS_TRANS_DQ_RTBCOUNT ;
Signature · 1 line
2.27.0