5.4.23-stable review
Subsystems (3)
Greg Kroah-Hartman
maintainercover 5.4.23-stable review
This is the start of the stable review cycle for the 5.4.23 release. There are 135 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 Sat, 29 Feb 2020 13:21:24 +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.4.23-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.4.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 5.4.23-rc1
John Fastabend <[email protected]>
bpf: Selftests build error in sockmap_basic.c
Nathan Chancellor <[email protected]>
s390/mm: Explicitly compare PAGE_DEFAULT_KEY against zero in storage_key_init_range
Nathan Chancellor <[email protected]>
s390/kaslr: Fix casts in get_random
Aya Levin <[email protected]>
net/mlx5e: Fix crash in recovery flow without devlink reporter
Huy Nguyen <[email protected]>
net/mlx5: Fix sleep while atomic in mlx5_eswitch_get_vepa
Aya Levin <[email protected]>
net/mlx5e: Reset RQ doorbell counter before moving RQ state from RST to RDY
Thomas Gleixner <[email protected]>
xen: Enable interrupts when calling _cond_resched()
Prabhakar Kushwaha <[email protected]>
ata: ahci: Add shutdown to freeze hardware resources of ahci
Stefano Garzarella <[email protected]>
io_uring: prevent sq_thread from spinning when it should stop
David Howells <[email protected]>
rxrpc: Fix call RCU cleanup using non-bh-safe locks
Cong Wang <[email protected]>
netfilter: xt_hashlimit: limit the max size of hashtable
Takashi Iwai <[email protected]>
ALSA: seq: Fix concurrent access to queue current tick/time
Takashi Iwai <[email protected]>
ALSA: seq: Avoid concurrent access to queue flags
Takashi Iwai <[email protected]>
ALSA: rawmidi: Avoid bit fields for state flags
Xiaoguang Wang <[email protected]>
io_uring: fix __io_iopoll_check deadlock in io_sq_thread
Vincenzo Frascino <[email protected]>
arm64: lse: Fix LSE atomics with LLVM
Johannes Krude <[email protected]>
bpf, offload: Replace bitwise AND by logical AND in bpf_prog_offload_info_fill
Thomas Gleixner <[email protected]>
genirq/proc: Reject invalid affinity masks (again)
Tianjia Zhang <[email protected]>
crypto: rename sm3-256 to sm3 in hash_algo_name
Joerg Roedel <[email protected]>
iommu/vt-d: Fix compile warning from intel-svm.h
Aditya Pakki <[email protected]>
ecryptfs: replace BUG_ON with error handling code
Oleksandr Suvorov <[email protected]>
ASoC: fsl_sai: Fix exiting path on probing failure
Arnd Bergmann <[email protected]>
ASoC: atmel: fix atmel_ssc_set_audio link failure
Dan Carpenter <[email protected]>
staging: greybus: use after free in gb_audio_manager_remove_all()
Colin Ian King <[email protected]>
staging: rtl8723bs: fix copy of overlapping memory
Minas Harutyunyan <[email protected]>
usb: dwc2: Fix in ISOC request length checking
Jack Pham <[email protected]>
usb: gadget: composite: Fix bMaxPower for SuperSpeedPlus
Bart Van Assche <[email protected]>
scsi: Revert "target: iscsi: Wait for all commands to finish before freeing a session"
Bart Van Assche <[email protected]>
scsi: Revert "RDMA/isert: Fix a recently introduced regression related to logout"
Rob Clark <[email protected]>
drm/msm/dpu: fix BGR565 vs RGB565 confusion
Chris Wilson <[email protected]>
drm/i915/gt: Protect defer_request() from new waiters
Tomi Valkeinen <[email protected]>
drm/bridge: tc358767: fix poll timeouts
Igor Druzhinin <[email protected]>
drm/i915/gvt: more locking for ppgtt mm LRU list
Chris Wilson <[email protected]>
drm/i915/execlists: Always force a context reload when rewinding RING_TAIL
Chris Wilson <[email protected]>
drm/i915/gt: Detect if we miss WaIdleLiteRestore
Greg Kroah-Hartman <[email protected]>
Revert "dmaengine: imx-sdma: Fix memory leak"
Filipe Manana <[email protected]>
Btrfs: fix deadlock during fast fsync when logging prealloc extents beyond eof
Josef Bacik <[email protected]>
btrfs: don't set path->leave_spinning for truncate
Filipe Manana <[email protected]>
Btrfs: fix race between shrinking truncate and fiemap
Filipe Manana <[email protected]>
Btrfs: fix btrfs_wait_ordered_range() so that it waits for all ordered extents
Josef Bacik <[email protected]>
btrfs: do not check delayed items are empty for single transaction cleanup
Josef Bacik <[email protected]>
btrfs: reset fs_root to NULL on error in open_ctree
Josef Bacik <[email protected]>
btrfs: fix bytes_may_use underflow in prealloc error condtition
Jeff Mahoney <[email protected]>
btrfs: destroy qgroup extent records on transaction abort
Miaohe Lin <[email protected]>
KVM: apic: avoid calculating pending eoi from an uninitialized val
Vitaly Kuznetsov <[email protected]>
KVM: nVMX: handle nested posted interrupts when apicv is disabled for L1
Vitaly Kuznetsov <[email protected]>
KVM: nVMX: clear PIN_BASED_POSTED_INTR from nested pinbased_ctls only when apicv is globally disabled
Oliver Upton <[email protected]>
KVM: nVMX: Check IO instruction VM-exit conditions
Oliver Upton <[email protected]>
KVM: nVMX: Refactor IO bitmap checks into helper function
Eric Biggers <[email protected]>
ext4: fix race between writepages and enabling EXT4_EXTENTS_FL
Eric Biggers <[email protected]>
ext4: rename s_journal_flag_rwsem to s_writepages_rwsem
Jan Kara <[email protected]>
ext4: fix mount failure with quota configured as module
Suraj Jitindar Singh <[email protected]>
ext4: fix potential race between s_flex_groups online resizing and access
Suraj Jitindar Singh <[email protected]>
ext4: fix potential race between s_group_info online resizing and access
Theodore Ts'o <[email protected]>
ext4: fix potential race between online resizing and write operations
Shijie Luo <[email protected]>
ext4: add cond_resched() to __ext4_find_entry()
Qian Cai <[email protected]>
ext4: fix a data race in EXT4_I(inode)->i_disksize
Miaohe Lin <[email protected]>
KVM: x86: don't notify userspace IOAPIC on edge-triggered interrupt EOI
Paolo Bonzini <[email protected]>
KVM: nVMX: Don't emulate instructions in guest mode
Suren Baghdasaryan <[email protected]>
sched/psi: Fix OOB write when writing 0 bytes to PSI files
Jani Nikula <[email protected]>
drm/i915: Update drm/i915 bug filing URL
Chris Wilson <[email protected]>
drm/i915: Wean off drm_pci_alloc/drm_pci_free
Lyude Paul <[email protected]>
drm/nouveau/kms/gv100-: Re-set LUT after clearing for modesets
Alex Deucher <[email protected]>
drm/amdgpu/gfx10: disable gfxoff when reading rlc clock
Alex Deucher <[email protected]>
drm/amdgpu/gfx9: disable gfxoff when reading rlc clock
Alex Deucher <[email protected]>
drm/amdgpu/soc15: fix xclk for raven
Catalin Marinas <[email protected]>
mm: Avoid creating virtual address aliases in brk()/mmap()/mremap()
Alexander Potapenko <[email protected]>
lib/stackdepot.c: fix global out-of-bounds in stack_slabs
Wei Yang <[email protected]>
mm/sparsemem: pfn_to_page is not valid yet on SPARSEMEM
Gavin Shan <[email protected]>
mm/vmscan.c: don't round up scan size for online memory cgroup
Zenghui Yu <[email protected]>
genirq/irqdomain: Make sure all irq domain flags are distinct
Logan Gunthorpe <[email protected]>
nvme-multipath: Fix memory leak with ana_log_buf
Vasily Averin <[email protected]>
mm/memcontrol.c: lost css_put in memcg_expand_shrinker_maps()
Ioanna Alifieraki <[email protected]>
Revert "ipc,sem: remove uneeded sem_undo_list lock usage in exit_sem()"
Rafael J. Wysocki <[email protected]>
ACPI: PM: s2idle: Check fixed wakeup events in acpi_s2idle_wake()
Jani Nikula <[email protected]>
MAINTAINERS: Update drm/i915 bug filing URL
Johan Hovold <[email protected]>
serdev: ttyport: restore client ops on deregistration
satya priya <[email protected]>
tty: serial: qcom_geni_serial: Fix RX cancel command failure
Fugang Duan <[email protected]>
tty: serial: imx: setup the correct sg entry for tx dma
Nicolas Ferre <[email protected]>
tty/serial: atmel: manage shutdown in case of RS485 or ISO7816 mode
Andy Shevchenko <[email protected]>
serial: 8250: Check UPF_IRQ_SHARED in advance
Kim Phillips <[email protected]>
x86/cpu/amd: Enable the fixed Instructions Retired counter IRPERF
Thomas Gleixner <[email protected]>
x86/mce/amd: Fix kobject lifetime
Borislav Petkov <[email protected]>
x86/mce/amd: Publish the bank pointer only after setup has succeeded
Ard Biesheuvel <[email protected]>
x86/ima: use correct identifier for SetupMode variable
wangyan <[email protected]>
jbd2: fix ocfs2 corrupt when clearing block group bits
Will Deacon <[email protected]>
arm64: memory: Add missing brackets to untagged_addr() macro
Christophe Leroy <[email protected]>
powerpc/hugetlb: Fix 8M hugepages on 8xx
Christophe Leroy <[email protected]>
powerpc/hugetlb: Fix 512k hugepages on 8xx with 16k page size
Christophe Leroy <[email protected]>
powerpc/entry: Fix an #if which should be an #ifdef in entry_32.S
Gustavo Luiz Duarte <[email protected]>
powerpc/tm: Fix clearing MSR[TS] in current when reclaiming on signal delivery
Sam Bobroff <[email protected]>
powerpc/eeh: Fix deadlock handling dead PHB
Christophe Leroy <[email protected]>
powerpc/8xx: Fix clearing of bits 20-23 in ITLB miss
Boris Brezillon <[email protected]>
drm/panfrost: perfcnt: Reserve/use the AS attached to the perfcnt MMU context
Larry Finger <[email protected]>
staging: rtl8723bs: Fix potential overuse of kernel memory
Larry Finger <[email protected]>
staging: rtl8723bs: Fix potential security hole
Larry Finger <[email protected]>
staging: rtl8188eu: Fix potential overuse of kernel memory
Larry Finger <[email protected]>
staging: rtl8188eu: Fix potential security hole
Bart Van Assche <[email protected]>
scsi: Revert "target/core: Inline transport_lun_remove_cmd()"
Colin Ian King <[email protected]>
usb: dwc3: debug: fix string position formatting mixup with ret and len
Anurag Kumar Vulisha <[email protected]>
usb: dwc3: gadget: Check for IOC/LST bit in TRB->ctrl fields
Minas Harutyunyan <[email protected]>
usb: dwc2: Fix SET/CLEAR_FEATURE and GET_STATUS flows
Hardik Gajjar <[email protected]>
USB: hub: Fix the broken detection of USB3 device in SMSC hub
Alan Stern <[email protected]>
USB: hub: Don't record a connect-change event during reset-resume
Richard Dodd <[email protected]>
USB: Fix novation SourceControl XL after suspend
EJ Hsu <[email protected]>
usb: uas: fix a plug & unplug racing
Johan Hovold <[email protected]>
USB: quirks: blacklist duplicate ep on Sound Devices USBPre2
Johan Hovold <[email protected]>
USB: core: add endpoint-blacklist quirk
Peter Chen <[email protected]>
usb: host: xhci: update event ring dequeue pointer on purpose
Mathias Nyman <[email protected]>
xhci: Fix memory leak when caching protocol extended capability PSI tables - take 2
Mathias Nyman <[email protected]>
xhci: apply XHCI_PME_STUCK_QUIRK to Intel Comet Lake platforms
Mathias Nyman <[email protected]>
xhci: fix runtime pm enabling for quirky Intel hosts
Mathias Nyman <[email protected]>
xhci: Force Maximum Packet size for Full-speed bulk devices to valid range.
Malcolm Priestley <[email protected]>
staging: vt6656: fix sign of rx_dbm to bb_pre_ed_rssi.
Suren Baghdasaryan <[email protected]>
staging: android: ashmem: Disallow ashmem memory from being remapped
Eric Dumazet <[email protected]>
vt: vt_ioctl: fix race in VT_RESIZEX
Jiri Slaby <[email protected]>
vt: selection, close sel_buffer race
Jiri Slaby <[email protected]>
vt: selection, handle pending signals in paste_selection
Nicolas Pitre <[email protected]>
vt: fix scrollback flushing on background consoles
Linus Torvalds <[email protected]>
floppy: check FDC index for errors before assigning it
Alexander Duyck <[email protected]>
e1000e: Use rtnl_lock to prevent race conditions between net and pci/pm
Greg Kroah-Hartman <[email protected]>
USB: misc: iowarrior: add support for the 100 device
Greg Kroah-Hartman <[email protected]>
USB: misc: iowarrior: add support for the 28 and 28L devices
Greg Kroah-Hartman <[email protected]>
USB: misc: iowarrior: add support for 2 OEMed devices
Mika Westerberg <[email protected]>
thunderbolt: Prevent crash if non-active NVMem file is read
Josef Bacik <[email protected]>
btrfs: handle logged extent failure properly
Wenwen Wang <[email protected]>
ecryptfs: fix a memory leak bug in ecryptfs_init_messaging()
Wenwen Wang <[email protected]>
ecryptfs: fix a memory leak bug in parse_tag_1_packet()
Roberto Sassu <[email protected]>
tpm: Initialize crypto_id of allocated_banks to HASH_ALGO__LAST
Samuel Holland <[email protected]>
ASoC: sun8i-codec: Fix setting DAI data format
Samuel Holland <[email protected]>
ASoC: codec2codec: avoid invalid/double-free of pcm runtime
Takashi Iwai <[email protected]>
ALSA: hda/realtek - Apply quirk for yet another MSI laptop
Takashi Iwai <[email protected]>
ALSA: hda/realtek - Apply quirk for MSI GP63, too
Takashi Iwai <[email protected]>
ALSA: hda: Use scnprintf() for printing texts for sysfs/procfs
Robin Murphy <[email protected]>
iommu/qcom: Fix bogus detach logic
-------------
Diffstat:
Documentation/arm64/tagged-address-abi.rst | 11 +- MAINTAINERS | 2 +- Makefile | 4 +- arch/arm64/include/asm/lse.h | 2 +- arch/arm64/include/asm/memory.h | 2 +- arch/powerpc/include/asm/page.h | 5 + arch/powerpc/kernel/eeh_driver.c | 21 ++-- arch/powerpc/kernel/entry_32.S | 4 +- arch/powerpc/kernel/head_8xx.S | 2 +- arch/powerpc/kernel/signal.c | 17 +++- arch/powerpc/kernel/signal_32.c | 28 ++--- arch/powerpc/kernel/signal_64.c | 22 ++-- arch/powerpc/mm/hugetlbpage.c | 29 ++++-- arch/s390/boot/kaslr.c | 2 +- arch/s390/include/asm/page.h | 2 +- arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/include/asm/msr-index.h | 2 + arch/x86/kernel/cpu/amd.c | 14 +++ arch/x86/kernel/cpu/mce/amd.c | 50 ++++----- arch/x86/kernel/ima_arch.c | 6 +- arch/x86/kvm/irq_comm.c | 2 +- arch/x86/kvm/lapic.c | 9 +- arch/x86/kvm/svm.c | 7 +- arch/x86/kvm/vmx/capabilities.h | 1 + arch/x86/kvm/vmx/nested.c | 44 ++++---- arch/x86/kvm/vmx/nested.h | 5 +- arch/x86/kvm/vmx/vmx.c | 82 +++++++++++---- crypto/hash_info.c | 2 +- drivers/acpi/acpica/evevent.c | 45 ++++++++ drivers/acpi/sleep.c | 7 ++ drivers/ata/ahci.c | 7 ++ drivers/ata/libata-core.c | 21 ++++ drivers/block/floppy.c | 7 +- drivers/char/tpm/tpm2-cmd.c | 2 + drivers/dma/imx-sdma.c | 19 ++-- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 2 + drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 2 + drivers/gpu/drm/amd/amdgpu/soc15.c | 7 +- drivers/gpu/drm/bridge/tc358767.c | 8 +- drivers/gpu/drm/i915/Kconfig | 5 +- drivers/gpu/drm/i915/display/intel_display.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_object_types.h | 3 - drivers/gpu/drm/i915/gem/i915_gem_phys.c | 98 +++++++++--------- drivers/gpu/drm/i915/gt/intel_engine.h | 8 ++ drivers/gpu/drm/i915/gt/intel_engine_types.h | 1 + drivers/gpu/drm/i915/gt/intel_lrc.c | 63 ++++++------ drivers/gpu/drm/i915/gt/intel_ringbuffer.c | 2 + drivers/gpu/drm/i915/gvt/gtt.c | 4 + drivers/gpu/drm/i915/i915_gem.c | 8 +- drivers/gpu/drm/i915/i915_gpu_error.c | 3 +- drivers/gpu/drm/i915/i915_scheduler.c | 6 +- drivers/gpu/drm/i915/i915_utils.c | 5 +- drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c | 4 +- drivers/gpu/drm/nouveau/dispnv50/wndw.c | 2 + drivers/gpu/drm/panfrost/panfrost_mmu.c | 7 +- drivers/gpu/drm/panfrost/panfrost_perfcnt.c | 11 +- drivers/infiniband/ulp/isert/ib_isert.c | 12 +++ drivers/iommu/qcom_iommu.c | 28 +++-- drivers/net/ethernet/intel/e1000e/netdev.c | 68 +++++++------ .../net/ethernet/mellanox/mlx5/core/en/health.c | 2 +- drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h | 8 ++ drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 3 + drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 14 +-- drivers/net/ethernet/mellanox/mlx5/core/wq.c | 39 +++++-- drivers/net/ethernet/mellanox/mlx5/core/wq.h | 2 + drivers/nvme/host/multipath.c | 1 + drivers/staging/android/ashmem.c | 28 +++++ drivers/staging/greybus/audio_manager.c | 2 +- drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 4 +- drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c | 5 +- drivers/staging/rtl8723bs/os_dep/ioctl_linux.c | 4 +- drivers/staging/vt6656/dpc.c | 2 +- drivers/target/iscsi/iscsi_target.c | 16 +-- drivers/target/target_core_transport.c | 31 +++++- drivers/thunderbolt/switch.c | 7 ++ drivers/tty/serdev/serdev-ttyport.c | 6 +- drivers/tty/serial/8250/8250_aspeed_vuart.c | 1 - drivers/tty/serial/8250/8250_core.c | 5 +- drivers/tty/serial/8250/8250_of.c | 1 - drivers/tty/serial/8250/8250_port.c | 4 + drivers/tty/serial/atmel_serial.c | 3 +- drivers/tty/serial/imx.c | 2 +- drivers/tty/serial/qcom_geni_serial.c | 18 +++- drivers/tty/tty_port.c | 5 +- drivers/tty/vt/selection.c | 32 ++++-- drivers/tty/vt/vt.c | 15 ++- drivers/tty/vt/vt_ioctl.c | 17 ++-- drivers/usb/core/config.c | 11 ++ drivers/usb/core/hub.c | 20 +++- drivers/usb/core/hub.h | 1 + drivers/usb/core/quirks.c | 40 ++++++++ drivers/usb/core/usb.h | 3 + drivers/usb/dwc2/gadget.c | 40 ++++---- drivers/usb/dwc3/debug.h | 39 +++---- drivers/usb/dwc3/gadget.c | 3 +- drivers/usb/gadget/composite.c | 8 +- drivers/usb/host/xhci-hub.c | 25 +++-- drivers/usb/host/xhci-mem.c | 71 ++++++++----- drivers/usb/host/xhci-pci.c | 10 +- drivers/usb/host/xhci-ring.c | 60 +++++++---- drivers/usb/host/xhci.h | 14 ++- drivers/usb/misc/iowarrior.c | 31 +++++- drivers/usb/storage/uas.c | 23 ++++- drivers/xen/preempt.c | 4 +- fs/btrfs/disk-io.c | 3 +- fs/btrfs/extent-tree.c | 2 + fs/btrfs/inode.c | 26 ++++- fs/btrfs/ordered-data.c | 7 +- fs/btrfs/qgroup.c | 13 +++ fs/btrfs/qgroup.h | 1 + fs/btrfs/transaction.c | 2 + fs/ecryptfs/crypto.c | 6 +- fs/ecryptfs/keystore.c | 2 +- fs/ecryptfs/messaging.c | 1 + fs/ext4/balloc.c | 14 ++- fs/ext4/ext4.h | 39 +++++-- fs/ext4/ialloc.c | 23 +++-- fs/ext4/inode.c | 16 +-- fs/ext4/mballoc.c | 61 +++++++---- fs/ext4/migrate.c | 27 +++-- fs/ext4/namei.c | 1 + fs/ext4/resize.c | 62 ++++++++--- fs/ext4/super.c | 113 ++++++++++++++------- fs/io_uring.c | 47 ++++----- fs/jbd2/transaction.c | 8 +- include/acpi/acpixf.h | 1 + include/linux/intel-svm.h | 2 +- include/linux/irqdomain.h | 2 +- include/linux/libata.h | 1 + include/linux/tty.h | 2 + include/linux/usb/quirks.h | 3 + include/scsi/iscsi_proto.h | 1 - include/sound/rawmidi.h | 6 +- ipc/sem.c | 6 +- kernel/bpf/offload.c | 2 +- kernel/irq/internals.h | 2 - kernel/irq/manage.c | 18 +--- kernel/irq/proc.c | 22 ++++ kernel/sched/psi.c | 3 + lib/stackdepot.c | 8 +- mm/memcontrol.c | 4 +- mm/mmap.c | 4 - mm/mremap.c | 1 - mm/sparse.c | 2 +- mm/vmscan.c | 9 +- net/netfilter/xt_hashlimit.c | 10 ++ net/rxrpc/call_object.c | 22 +++- sound/core/seq/seq_clientmgr.c | 4 +- sound/core/seq/seq_queue.c | 29 ++++-- sound/core/seq/seq_timer.c | 13 ++- sound/core/seq/seq_timer.h | 3 +- sound/hda/hdmi_chmap.c | 2 +- sound/pci/hda/hda_codec.c | 2 +- sound/pci/hda/hda_eld.c | 2 +- sound/pci/hda/hda_sysfs.c | 4 +- sound/pci/hda/patch_realtek.c | 2 + sound/soc/atmel/Kconfig | 4 +- sound/soc/atmel/Makefile | 10 +- sound/soc/fsl/fsl_sai.c | 22 +++- sound/soc/soc-dapm.c | 3 - sound/soc/sunxi/sun8i-codec.c | 3 +- .../selftests/bpf/prog_tests/sockmap_basic.c | 5 + 162 files changed, 1523 insertions(+), 716 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/135 iommu/qcom: Fix bogus detach logic
From: Robin Murphy <[email protected]>
commit faf305c51aeabd1ea2d7131e798ef5f55f4a7750 upstream.
Currently, the implementation of qcom_iommu_domain_free() is guaranteed to do one of two things: WARN() and leak everything, or dereference NULL and crash. That alone is terrible, but in fact the whole idea of trying to track the liveness of a domain via the qcom_domain->iommu pointer as a sanity check is full of fundamentally flawed assumptions. Make things robust and actually functional by not trying to be quite so clever.
--- drivers/iommu/qcom_iommu.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-)
drivers/iommu/qcom_iommu.c +12 -16
@@ -345,21 +345,19 @@ static void qcom_iommu_domain_free(struc {struct qcom_iommu_domain *qcom_domain =to_qcom_iommu_domain (domain); -if (WARN_ON (qcom_domain->iommu))/* forgot to detach? */ -return ; -iommu_put_dma_cookie (domain); -/* NOTE: unmap can be called after client device is powered off, -* for example, with GPUs or anything involving dma-buf. So we -* cannot rely on the device_link. Make sure the IOMMU is on to -* avoid unclocked accesses in the TLB inv path: -*/ -pm_runtime_get_sync (qcom_domain->iommu->dev); - -free_io_pgtable_ops (qcom_domain->pgtbl_ops); - -pm_runtime_put_sync (qcom_domain->iommu->dev); +if (qcom_domain->iommu) { +/* +* NOTE: unmap can be called after client device is powered +* off, for example, with GPUs or anything involving dma-buf. +* So we cannot rely on the device_link. Make sure the IOMMU +* is on to avoid unclocked accesses in the TLB inv path: +*/ +pm_runtime_get_sync (qcom_domain->iommu->dev); +free_io_pgtable_ops (qcom_domain->pgtbl_ops); +pm_runtime_put_sync (qcom_domain->iommu->dev); + }kfree (qcom_domain); }
@@ -405,7 +403,7 @@ static void qcom_iommu_detach_dev(structstruct qcom_iommu_domain *qcom_domain =to_qcom_iommu_domain (domain);unsigned i; -if (!qcom_domain->iommu) +if (WARN_ON (!qcom_domain->iommu))return ;pm_runtime_get_sync (qcom_iommu->dev);
@@ -418,8 +416,6 @@ static void qcom_iommu_detach_dev(struct ctx->domain =NULL ; }pm_runtime_put_sync (qcom_iommu->dev); - - qcom_domain->iommu =NULL ; } static int qcom_iommu_map(struct iommu_domain *domain, unsigned long iova,
Greg Kroah-Hartman
maintainerPATCH 2/135 ALSA: hda: Use scnprintf() for printing texts for sysfs/procfs
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 44eeb081b8630bb3ad3cd381d1ae1831463e48bb upstream.
Some code in HD-audio driver calls snprintf() in a loop and still expects that the return value were actually written size, while snprintf() returns the expected would-be length instead. When the given buffer limit were small, this leads to a buffer overflow.
Use scnprintf() for addressing those issues. It returns the actually written size unlike snprintf().
--- sound/hda/hdmi_chmap.c | 2 +- sound/pci/hda/hda_codec.c | 2 +- sound/pci/hda/hda_eld.c | 2 +- sound/pci/hda/hda_sysfs.c | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-)
sound/hda/hdmi_chmap.c +1 -1
@@ -250,7 +250,7 @@ void snd_hdac_print_channel_allocation(ifor (i =0 , j =0 ; i <ARRAY_SIZE (cea_speaker_allocation_names); i++) {if (spk_alloc & (1 << i)) - j +=snprintf (buf + j, buflen - j," %s" , + j +=scnprintf (buf + j, buflen - j," %s" , cea_speaker_allocation_names[i]); } buf[j] ='\0' ;/* necessary when j == 0 */
sound/pci/hda/hda_codec.c +1 -1
@@ -4019,7 +4019,7 @@ void snd_print_pcm_bits(int pcm, char *bfor (i =0 , j =0 ; i <ARRAY_SIZE (bits); i++)if (pcm & (AC_SUPPCM_BITS_8 << i)) - j +=snprintf (buf + j, buflen - j," %d" , bits[i]); + j +=scnprintf (buf + j, buflen - j," %d" , bits[i]); buf[j] ='\0' ;/* necessary when j == 0 */ }
sound/pci/hda/hda_eld.c +1 -1
@@ -360,7 +360,7 @@ static void hdmi_print_pcm_rates(int pcmfor (i =0 , j =0 ; i <ARRAY_SIZE (alsa_rates); i++)if (pcm & (1 << i)) - j +=snprintf (buf + j, buflen - j," %d" , + j +=scnprintf (buf + j, buflen - j," %d" , alsa_rates[i]); buf[j] ='\0' ;/* necessary when j == 0 */
sound/pci/hda/hda_sysfs.c +2 -2
@@ -222,7 +222,7 @@ static ssize_t init_verbs_show(struct deint i, len =0 ;mutex_lock (&codec->user_mutex);snd_array_for_each (&codec->init_verbs, i, v) { - len +=snprintf (buf + len,PAGE_SIZE - len, + len +=scnprintf (buf + len,PAGE_SIZE - len,"0x%02x 0x%03x 0x%04x\n" , v->nid, v->verb, v->param); }
@@ -272,7 +272,7 @@ static ssize_t hints_show(struct deviceint i, len =0 ;mutex_lock (&codec->user_mutex);snd_array_for_each (&codec->hints, i, hint) { - len +=snprintf (buf + len,PAGE_SIZE - len, + len +=scnprintf (buf + len,PAGE_SIZE - len,"%s = %s\n" , hint->key, hint->val); }mutex_unlock (&codec->user_mutex);
Greg Kroah-Hartman
maintainerPATCH 3/135 ALSA: hda/realtek - Apply quirk for MSI GP63, too
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit a655e2b107d463ce2745188ce050d07daed09a71 upstream.
The same quirk that was applied to MSI GL73 is needed for MSI GP63, too. Adding the entry with the SSID 1462:1228.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -2447,6 +2447,7 @@ static const struct snd_pci_quirk alc882SND_PCI_QUIRK (0x1071 ,0x8258 ,"Evesham Voyaeger" ,ALC882_FIXUP_EAPD ),SND_PCI_QUIRK (0x1458 ,0xa002 ,"Gigabyte EP45-DS3/Z87X-UD3H" ,ALC889_FIXUP_FRONT_HP_NO_PRESENCE ),SND_PCI_QUIRK (0x1458 ,0xa0b8 ,"Gigabyte AZ370-Gaming" ,ALC1220_FIXUP_GB_DUAL_CODECS ), +SND_PCI_QUIRK (0x1462 ,0x1228 ,"MSI-GP63" ,ALC1220_FIXUP_CLEVO_P950 ),SND_PCI_QUIRK (0x1462 ,0x1276 ,"MSI-GL73" ,ALC1220_FIXUP_CLEVO_P950 ),SND_PCI_QUIRK (0x1462 ,0x7350 ,"MSI-7350" ,ALC889_FIXUP_CD ), SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
Greg Kroah-Hartman
maintainerPATCH 4/135 ALSA: hda/realtek - Apply quirk for yet another MSI laptop
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit cc5049ae4d457194796f854eb2e38b9727ad8c2d upstream.
MSI GP65 laptop with SSID 1462:1293 requires the same quirk as other MSI models.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -2449,6 +2449,7 @@ static const struct snd_pci_quirk alc882SND_PCI_QUIRK (0x1458 ,0xa0b8 ,"Gigabyte AZ370-Gaming" ,ALC1220_FIXUP_GB_DUAL_CODECS ),SND_PCI_QUIRK (0x1462 ,0x1228 ,"MSI-GP63" ,ALC1220_FIXUP_CLEVO_P950 ),SND_PCI_QUIRK (0x1462 ,0x1276 ,"MSI-GL73" ,ALC1220_FIXUP_CLEVO_P950 ), +SND_PCI_QUIRK (0x1462 ,0x1293 ,"MSI-GP65" ,ALC1220_FIXUP_CLEVO_P950 ),SND_PCI_QUIRK (0x1462 ,0x7350 ,"MSI-7350" ,ALC889_FIXUP_CD ),SND_PCI_QUIRK (0x1462 ,0xda57 ,"MSI Z270-Gaming" ,ALC1220_FIXUP_GB_DUAL_CODECS ), SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
Greg Kroah-Hartman
maintainerPATCH 5/135 ASoC: codec2codec: avoid invalid/double-free of pcm runtime
In reply to Greg Kroah-HartmanFrom: Samuel Holland <[email protected]>
commit b6570fdb96edf45bcf71884bd2644bd73d348d1a upstream.
The PCM runtime was freed during PMU in the case that the event hook encountered an error. However, it is also unconditionally freed during PMD. Avoid a double-free by dropping the call to kfree in the PMU hook.
--- sound/soc/soc-dapm.c | 3 --- 1 file changed, 3 deletions(-)
sound/soc/soc-dapm.c +0 -3
@@ -3888,9 +3888,6 @@ snd_soc_dai_link_event_pre_pmu(struct sn runtime->rate =params_rate (params); out: -if (ret <0 ) -kfree (runtime); -kfree (params);return ret; }
Greg Kroah-Hartman
maintainerPATCH 6/135 ASoC: sun8i-codec: Fix setting DAI data format
In reply to Greg Kroah-HartmanFrom: Samuel Holland <[email protected]>
commit 96781fd941b39e1f78098009344ebcd7af861c67 upstream.
Use the correct mask for this two-bit field. This fixes setting the DAI data format to RIGHT_J or DSP_A.
--- sound/soc/sunxi/sun8i-codec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
sound/soc/sunxi/sun8i-codec.c +2 -1
@@ -80,6 +80,7 @@#define SUN8I_SYS_SR_CTRL_AIF1_FS_MASK GENMASK(15, 12)#define SUN8I_SYS_SR_CTRL_AIF2_FS_MASK GENMASK(11, 8) +#define SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT_MASK GENMASK(3, 2)#define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ_MASK GENMASK(5, 4)#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_MASK GENMASK(8, 6)#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV_MASK GENMASK(12, 9)
@@ -241,7 +242,7 @@ static int sun8i_set_fmt(struct snd_soc_return -EINVAL ; }regmap_update_bits (scodec->regmap,SUN8I_AIF1CLK_CTRL , -BIT (SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT ), +SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT_MASK , value <<SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT );return 0 ;
Greg Kroah-Hartman
maintainerPATCH 7/135 tpm: Initialize crypto_id of allocated_banks to HASH_ALGO__LAST
In reply to Greg Kroah-HartmanFrom: Roberto Sassu <[email protected]>
commit dc10e4181c05a2315ddc375e963b7c763b5ee0df upstream.
chip->allocated_banks, an array of tpm_bank_info structures, contains the list of TPM algorithm IDs of allocated PCR banks. It also contains the corresponding ID of the crypto subsystem, so that users of the TPM driver can calculate a digest for a PCR extend operation.
However, if there is no mapping between TPM algorithm ID and crypto ID, the crypto_id field of tpm_bank_info remains set to zero (the array is allocated and initialized with kcalloc() in tpm2_get_pcr_allocation()). Zero should not be used as value for unknown mappings, as it is a valid crypto ID (HASH_ALGO_MD4).
Thus, initialize crypto_id to HASH_ALGO__LAST.
--- drivers/char/tpm/tpm2-cmd.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/char/tpm/tpm2-cmd.c +2 -0
@@ -831,6 +831,8 @@ static int tpm2_init_bank_info(struct tpreturn 0 ; } + bank->crypto_id =HASH_ALGO__LAST ; +return tpm2_pcr_read (chip,0 , &digest, &bank->digest_size); }
Greg Kroah-Hartman
maintainerPATCH 8/135 ecryptfs: fix a memory leak bug in parse_tag_1_packet()
In reply to Greg Kroah-HartmanFrom: Wenwen Wang <[email protected]>
commit fe2e082f5da5b4a0a92ae32978f81507ef37ec66 upstream.
In parse_tag_1_packet(), if tag 1 packet contains a key larger than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES, no cleanup is executed, leading to a memory leak on the allocated 'auth_tok_list_item'. To fix this issue, go to the label 'out_free' to perform the cleanup work.
--- fs/ecryptfs/keystore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ecryptfs/keystore.c +1 -1
@@ -1304,7 +1304,7 @@ parse_tag_1_packet(struct ecryptfs_cryptprintk (KERN_WARNING "Tag 1 packet contains key larger " "than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES\n" ); rc = -EINVAL ; - goto out; + goto out_free; }memcpy ((*new_auth_tok)->session_key.encrypted_key, &data[(*packet_size)], (body_size - (ECRYPTFS_SIG_SIZE +2 )));
Greg Kroah-Hartman
maintainerPATCH 9/135 ecryptfs: fix a memory leak bug in ecryptfs_init_messaging()
In reply to Greg Kroah-HartmanFrom: Wenwen Wang <[email protected]>
commit b4a81b87a4cfe2bb26a4a943b748d96a43ef20e8 upstream.
In ecryptfs_init_messaging(), if the allocation for 'ecryptfs_msg_ctx_arr' fails, the previously allocated 'ecryptfs_daemon_hash' is not deallocated, leading to a memory leak bug. To fix this issue, free 'ecryptfs_daemon_hash' before returning the error.
--- fs/ecryptfs/messaging.c | 1 + 1 file changed, 1 insertion(+)
fs/ecryptfs/messaging.c +1 -0
@@ -379,6 +379,7 @@ int __init ecryptfs_init_messaging(void) * ecryptfs_message_buf_len), GFP_KERNEL);if (!ecryptfs_msg_ctx_arr) { +kfree (ecryptfs_daemon_hash); rc = -ENOMEM ; goto out; }
Greg Kroah-Hartman
maintainerPATCH 10/135 btrfs: handle logged extent failure properly
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
commit bd727173e4432fe6cb70ba108dc1f3602c5409d7 upstream.
If we're allocating a logged extent we attempt to insert an extent record for the file extent directly. We increase space_info->bytes_reserved, because the extent entry addition will call btrfs_update_block_group(), which will convert the ->bytes_reserved to ->bytes_used. However if we fail at any point while inserting the extent entry we will bail and leave space on ->bytes_reserved, which will trigger a WARN_ON() on umount. Fix this by pinning the space if we fail to insert, which is what happens in every other failure case that involves adding the extent entry.
--- fs/btrfs/extent-tree.c | 2 ++ 1 file changed, 2 insertions(+)
fs/btrfs/extent-tree.c +2 -0
@@ -4411,6 +4411,8 @@ int btrfs_alloc_logged_file_extent(struc ret =alloc_reserved_file_extent (trans,0 , root_objectid,0 , owner, offset, ins,1 ); +if (ret) +btrfs_pin_extent (fs_info, ins->objectid, ins->offset,1 );btrfs_put_block_group (block_group);return ret; }
Greg Kroah-Hartman
maintainerPATCH 11/135 thunderbolt: Prevent crash if non-active NVMem file is read
In reply to Greg Kroah-HartmanFrom: Mika Westerberg <[email protected]>
commit 03cd45d2e219301880cabc357e3cf478a500080f upstream.
The driver does not populate .reg_read callback for the non-active NVMem because the file is supposed to be write-only. However, it turns out NVMem subsystem does not yet support this and expects that the .reg_read callback is provided. If user reads the binary attribute it triggers NULL pointer dereference like this one:
BUG: kernel NULL pointer dereference, address: 0000000000000000 ... Call Trace: bin_attr_nvmem_read+0x64/0x80 kernfs_fop_read+0xa7/0x180 vfs_read+0xbd/0x170 ksys_read+0x5a/0xd0 do_syscall_64+0x43/0x150 entry_SYSCALL_64_after_hwframe+0x44/0xa9
Fix this in the driver by providing .reg_read callback that always returns an error.
--- drivers/thunderbolt/switch.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/thunderbolt/switch.c +7 -0
@@ -274,6 +274,12 @@ out:return ret; } +static int tb_switch_nvm_no_read (void *priv,unsigned int offset,void *val, +size_t bytes) +{ +return -EPERM ; +} +static int tb_switch_nvm_write (void *priv,unsigned int offset,void *val,size_t bytes) {
@@ -319,6 +325,7 @@ static struct nvmem_device *register_nvm config.read_only = true; }else { config.name ="nvm_non_active" ; + config.reg_read = tb_switch_nvm_no_read; config.reg_write = tb_switch_nvm_write; config.root_only = true; }
Greg Kroah-Hartman
maintainerPATCH 12/135 USB: misc: iowarrior: add support for 2 OEMed devices
In reply to Greg Kroah-HartmanFrom: Greg Kroah-Hartman <[email protected]>
commit 461d8deb26a7d70254bc0391feb4fd8a95e674e8 upstream.
Add support for two OEM devices that are identical to existing IO-Warrior devices, except for the USB device id.
--- drivers/usb/misc/iowarrior.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
drivers/usb/misc/iowarrior.c +13 -2
@@ -34,6 +34,10 @@/* full speed iowarrior */ #define USB_DEVICE_ID_CODEMERCS_IOW56 0x1503 +/* OEMed devices */ +#define USB_DEVICE_ID_CODEMERCS_IOW24SAG 0x158a +#define USB_DEVICE_ID_CODEMERCS_IOW56AM 0x158b +/* Get a minor range for your devices from the usb maintainer */ #ifdef CONFIG_USB_DYNAMIC_MINORS #define IOWARRIOR_MINOR_BASE 0
@@ -133,6 +137,8 @@ static const struct usb_device_id iowarr {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOWPV1)}, {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOWPV2)}, {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW56)}, + {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24SAG)}, + {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW56AM)}, {} /* Terminating entry */ };MODULE_DEVICE_TABLE (usb, iowarrior_ids);
@@ -357,6 +363,7 @@ static ssize_t iowarrior_write(struct fi }switch (dev->product_id) {case USB_DEVICE_ID_CODEMERCS_IOW24 : +case USB_DEVICE_ID_CODEMERCS_IOW24SAG :case USB_DEVICE_ID_CODEMERCS_IOWPV1 :case USB_DEVICE_ID_CODEMERCS_IOWPV2 :case USB_DEVICE_ID_CODEMERCS_IOW40 :
@@ -371,6 +378,7 @@ static ssize_t iowarrior_write(struct fi goto exit;break ;case USB_DEVICE_ID_CODEMERCS_IOW56 : +case USB_DEVICE_ID_CODEMERCS_IOW56AM :/* The IOW56 uses asynchronous IO and more urbs */ if (atomic_read (&dev->write_busy) ==MAX_WRITES_IN_FLIGHT ) {/* Wait until we are below the limit for submitted urbs */
@@ -493,6 +501,7 @@ static long iowarrior_ioctl(struct fileswitch (cmd) {case IOW_WRITE :if (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW24 || + dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW24SAG || dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOWPV1 || dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOWPV2 || dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW40 ) {
@@ -767,7 +776,8 @@ static int iowarrior_probe(struct usb_in goto error; } -if (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW56 ) { +if ((dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW56 ) || + (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW56AM )) { res =usb_find_last_int_out_endpoint (iface_desc, &dev->int_out_endpoint);if (res) {
@@ -780,7 +790,8 @@ static int iowarrior_probe(struct usb_in/* we have to check the report_size often, so remember it in the endianness suitable for our machine */ dev->report_size =usb_endpoint_maxp (dev->int_in_endpoint);if ((dev->interface->cur_altsetting->desc.bInterfaceNumber ==0 ) && - (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW56 )) + ((dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW56 ) || + (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW56AM )))/* IOWarrior56 has wMaxPacketSize different from report size */ dev->report_size =7 ;
Greg Kroah-Hartman
maintainerPATCH 13/135 USB: misc: iowarrior: add support for the 28 and 28L devices
In reply to Greg Kroah-HartmanFrom: Greg Kroah-Hartman <[email protected]>
commit 5f6f8da2d7b5a431d3f391d0d73ace8edfb42af7 upstream.
Add new device ids for the 28 and 28L devices. These have 4 interfaces instead of 2, but the driver binds the same, so the driver changes are minimal.
--- drivers/usb/misc/iowarrior.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
drivers/usb/misc/iowarrior.c +13 -2
@@ -33,6 +33,9 @@#define USB_DEVICE_ID_CODEMERCS_IOWPV2 0x1512/* full speed iowarrior */ #define USB_DEVICE_ID_CODEMERCS_IOW56 0x1503 +/* fuller speed iowarrior */ +#define USB_DEVICE_ID_CODEMERCS_IOW28 0x1504 +#define USB_DEVICE_ID_CODEMERCS_IOW28L 0x1505/* OEMed devices */ #define USB_DEVICE_ID_CODEMERCS_IOW24SAG 0x158a
@@ -139,6 +142,8 @@ static const struct usb_device_id iowarr {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW56)}, {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24SAG)}, {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW56AM)}, + {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28)}, + {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28L)}, {} /* Terminating entry */ };MODULE_DEVICE_TABLE (usb, iowarrior_ids);
@@ -379,6 +384,8 @@ static ssize_t iowarrior_write(struct fibreak ;case USB_DEVICE_ID_CODEMERCS_IOW56 :case USB_DEVICE_ID_CODEMERCS_IOW56AM : +case USB_DEVICE_ID_CODEMERCS_IOW28 : +case USB_DEVICE_ID_CODEMERCS_IOW28L :/* The IOW56 uses asynchronous IO and more urbs */ if (atomic_read (&dev->write_busy) ==MAX_WRITES_IN_FLIGHT ) {/* Wait until we are below the limit for submitted urbs */
@@ -777,7 +784,9 @@ static int iowarrior_probe(struct usb_in }if ((dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW56 ) || - (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW56AM )) { + (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW56AM ) || + (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW28 ) || + (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW28L )) { res =usb_find_last_int_out_endpoint (iface_desc, &dev->int_out_endpoint);if (res) {
@@ -791,7 +800,9 @@ static int iowarrior_probe(struct usb_in dev->report_size =usb_endpoint_maxp (dev->int_in_endpoint);if ((dev->interface->cur_altsetting->desc.bInterfaceNumber ==0 ) && ((dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW56 ) || - (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW56AM ))) + (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW56AM ) || + (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW28 ) || + (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW28L )))/* IOWarrior56 has wMaxPacketSize different from report size */ dev->report_size =7 ;
Greg Kroah-Hartman
maintainerPATCH 14/135 USB: misc: iowarrior: add support for the 100 device
In reply to Greg Kroah-HartmanFrom: Greg Kroah-Hartman <[email protected]>
commit bab5417f5f0118ce914bc5b2f8381e959e891155 upstream.
Add a new device id for the 100 devie. It has 4 interfaces like the 28 and 28L devices but a larger endpoint so more I/O pins.
--- drivers/usb/misc/iowarrior.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/usb/misc/iowarrior.c +7 -2
@@ -36,6 +36,7 @@/* fuller speed iowarrior */ #define USB_DEVICE_ID_CODEMERCS_IOW28 0x1504#define USB_DEVICE_ID_CODEMERCS_IOW28L 0x1505 +#define USB_DEVICE_ID_CODEMERCS_IOW100 0x1506/* OEMed devices */ #define USB_DEVICE_ID_CODEMERCS_IOW24SAG 0x158a
@@ -144,6 +145,7 @@ static const struct usb_device_id iowarr {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW56AM)}, {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28)}, {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28L)}, + {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW100)}, {} /* Terminating entry */ };MODULE_DEVICE_TABLE (usb, iowarrior_ids);
@@ -386,6 +388,7 @@ static ssize_t iowarrior_write(struct ficase USB_DEVICE_ID_CODEMERCS_IOW56AM :case USB_DEVICE_ID_CODEMERCS_IOW28 :case USB_DEVICE_ID_CODEMERCS_IOW28L : +case USB_DEVICE_ID_CODEMERCS_IOW100 :/* The IOW56 uses asynchronous IO and more urbs */ if (atomic_read (&dev->write_busy) ==MAX_WRITES_IN_FLIGHT ) {/* Wait until we are below the limit for submitted urbs */
@@ -786,7 +789,8 @@ static int iowarrior_probe(struct usb_inif ((dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW56 ) || (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW56AM ) || (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW28 ) || - (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW28L )) { + (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW28L ) || + (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW100 )) { res =usb_find_last_int_out_endpoint (iface_desc, &dev->int_out_endpoint);if (res) {
@@ -802,7 +806,8 @@ static int iowarrior_probe(struct usb_in ((dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW56 ) || (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW56AM ) || (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW28 ) || - (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW28L))) + (dev->product_id ==USB_DEVICE_ID_CODEMERCS_IOW28L ) || + (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW100))) /* IOWarrior56 has wMaxPacketSize different from report size */ dev->report_size = 7;
Greg Kroah-Hartman
maintainerPATCH 15/135 e1000e: Use rtnl_lock to prevent race conditions between net and pci/pm
In reply to Greg Kroah-HartmanFrom: Alexander Duyck <[email protected]>
commit a7023819404ac9bd2bb311a4fafd38515cfa71ec upstream.
This patch is meant to address possible race conditions that can exist between network configuration and power management. A similar issue was fixed for igb in commit 9474933caf21 ("igb: close/suspend race in netif_device_detach").
In addition it consolidates the code so that the PCI error handling code will essentially perform the power management freeze on the device prior to attempting a reset, and will thaw the device afterwards if that is what it is planning to do. Otherwise when we call close on the interface it should see it is detached and not attempt to call the logic to down the interface and free the IRQs again.
Quoted 1 line
From what I can tell the check that was adding the check for
__E1000_DOWN
in e1000e_close was added when runtime power management was added. However it should not be relevant for us as we perform a call to pm_runtime_get_sync before we call e1000_down/free_irq so it should always be back up before we call into this anyway.
--- drivers/net/ethernet/intel/e1000e/netdev.c | 68 ++++++++++++++--------------- 1 file changed, 35 insertions(+), 33 deletions(-)
drivers/net/ethernet/intel/e1000e/netdev.c +35 -33
@@ -4713,12 +4713,12 @@ int e1000e_close(struct net_device *netdpm_runtime_get_sync (&pdev->dev); -if (!test_bit (__E1000_DOWN, &adapter->state)) { +if (netif_device_present (netdev)) {e1000e_down (adapter, true);e1000_free_irq (adapter);/* Link status message must follow this format */ -pr_info ("%s NIC Link is Down\n" , adapter->netdev->name); +pr_info ("%s NIC Link is Down\n" , netdev->name); }napi_disable (&adapter->napi);
@@ -6309,10 +6309,14 @@ static int e1000e_pm_freeze(struct devic {struct net_device *netdev =dev_get_drvdata (dev);struct e1000_adapter *adapter =netdev_priv (netdev); +bool present; +rtnl_lock (); + + present =netif_device_present (netdev);netif_device_detach (netdev); -if (netif_running (netdev)) { +if (present &&netif_running (netdev)) {int count =E1000_CHECK_RESET_COUNT ;while (test_bit (__E1000_RESETTING, &adapter->state) && count--)
@@ -6324,6 +6328,8 @@ static int e1000e_pm_freeze(struct device1000e_down (adapter, false);e1000_free_irq (adapter); } +rtnl_unlock (); +e1000e_reset_interrupt_capability (adapter);/* Allow time for pending master requests to run */
@@ -6571,6 +6577,30 @@ static void e1000e_disable_aspm_locked(s__e1000e_disable_aspm (pdev, state,1 ); } +static int e1000e_pm_thaw (struct device *dev) +{ +struct net_device *netdev =dev_get_drvdata (dev); +struct e1000_adapter *adapter =netdev_priv (netdev); +int rc =0 ; + +e1000e_set_interrupt_capability (adapter); + +rtnl_lock (); +if (netif_running (netdev)) { + rc =e1000_request_irq (adapter); +if (rc) + goto err_irq; + +e1000e_up (adapter); + } + +netif_device_attach (netdev); +err_irq: +rtnl_unlock (); + +return rc; +} +#ifdef CONFIG_PM static int __e1000_resume (struct pci_dev *pdev) {
@@ -6638,26 +6668,6 @@ static int __e1000_resume(struct pci_dev }#ifdef CONFIG_PM_SLEEP -static int e1000e_pm_thaw (struct device *dev) -{ -struct net_device *netdev =dev_get_drvdata (dev); -struct e1000_adapter *adapter =netdev_priv (netdev); - -e1000e_set_interrupt_capability (adapter); -if (netif_running (netdev)) { -u32 err =e1000_request_irq (adapter); - -if (err) -return err; - -e1000e_up (adapter); - } - -netif_device_attach (netdev); - -return 0 ; -} -static int e1000e_pm_suspend (struct device *dev) {struct pci_dev *pdev =to_pci_dev (dev);
@@ -6829,16 +6839,11 @@ static void e1000_netpoll(struct net_devstatic pci_ers_result_t e1000_io_error_detected (struct pci_dev *pdev,pci_channel_state_t state) { -struct net_device *netdev =pci_get_drvdata (pdev); -struct e1000_adapter *adapter =netdev_priv (netdev); - -netif_device_detach (netdev); +e1000e_pm_freeze (&pdev->dev);if (state == pci_channel_io_perm_failure)return PCI_ERS_RESULT_DISCONNECT ; -if (netif_running (netdev)) -e1000e_down (adapter, true);pci_disable_device (pdev);/* Request a slot slot reset. */
@@ -6904,10 +6909,7 @@ static void e1000_io_resume(struct pci_de1000_init_manageability_pt (adapter); -if (netif_running (netdev)) -e1000e_up (adapter); - -netif_device_attach (netdev); +e1000e_pm_thaw (&pdev->dev);/* If the controller has AMT, do not set DRV_LOAD until the interface * is up. For all other cases, let the f/w know that the h/w is now
Greg Kroah-Hartman
maintainerPATCH 16/135 floppy: check FDC index for errors before assigning it
In reply to Greg Kroah-HartmanFrom: Linus Torvalds <[email protected]>
commit 2e90ca68b0d2f5548804f22f0dd61145516171e3 upstream.
Jordy Zomer reported a KASAN out-of-bounds read in the floppy driver in wait_til_ready().
Which on the face of it can't happen, since as Willy Tarreau points out, the function does no particular memory access. Except through the FDCS macro, which just indexes a static allocation through teh current fdc, which is always checked against N_FDC.
Except the checking happens after we've already assigned the value.
The floppy driver is a disgrace (a lot of it going back to my original horrd "design"), and has no real maintainer. Nobody has the hardware, and nobody really cares. But it still gets used in virtual environment because it's one of those things that everybody supports.
The whole thing should be re-written, or at least parts of it should be seriously cleaned up. The 'current fdc' index, which is used by the FDCS macro, and which is often shadowed by a local 'fdc' variable, is a prime example of how not to write code.
But because nobody has the hardware or the motivation, let's just fix up the immediate problem with a nasty band-aid: test the fdc index before actually assigning it to the static 'fdc' variable.
--- drivers/block/floppy.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/block/floppy.c +5 -2
@@ -853,14 +853,17 @@ static void reset_fdc_info(int mode)/* selects the fdc and drive, and enables the fdc's input/dma. */ static void set_fdc (int drive) { +unsigned int new_fdc = fdc; +if (drive >=0 && drive <N_DRIVE ) { - fdc =FDC (drive); + new_fdc =FDC (drive); current_drive = drive; } -if (fdc !=1 && fdc !=0 ) { +if (new_fdc >=N_FDC ) {pr_info ("bad fdc value\n" );return ; } + fdc = new_fdc;set_dor (fdc, ~0 ,8 );#if N_FDC >1 set_dor (1 - fdc, ~8 ,0 );
Greg Kroah-Hartman
maintainerPATCH 17/135 vt: fix scrollback flushing on background consoles
In reply to Greg Kroah-HartmanFrom: Nicolas Pitre <[email protected]>
commit 3f4ef485be9d54040b695f32ec76d0f1ea50bbf3 upstream.
Commit a6dbe4427559 ("vt: perform safe console erase in the right order") provided fixes to an earlier commit by gathering all console scrollback flushing operations in a function of its own. This includes the invocation of vc_sw->con_switch() as previously done through a update_screen() call. That commit failed to carry over the con_is_visible() conditional though, as well as cursor handling, which caused problems when "\e[3J" was written to a background console.
One could argue for preserving the call to update_screen(). However this does far more than we need, and it is best to remove scrollback assumptions from it. Instead let's gather the minimum needed to actually perform scrollback flushing properly in that one place.
While at it, let's document the vc_sw->con_switch() side effect being relied upon.
--- drivers/tty/vt/vt.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
drivers/tty/vt/vt.c +13 -2
@@ -936,10 +936,21 @@ static void flush_scrollback(struct vc_dWARN_CONSOLE_UNLOCKED ();set_origin (vc); -if (vc->vc_sw->con_flush_scrollback) +if (vc->vc_sw->con_flush_scrollback) { vc->vc_sw->con_flush_scrollback (vc); -else + }else if (con_is_visible (vc)) { +/* +* When no con_flush_scrollback method is provided then the +* legacy way for flushing the scrollback buffer is to use +* a side effect of the con_switch method. We do it only on +* the foreground console as background consoles have no +* scrollback buffers in that case and we obviously don't +* want to switch to them. +*/ +hide_cursor (vc); vc->vc_sw->con_switch (vc); +set_cursor (vc); + } }/*
Greg Kroah-Hartman
maintainerPATCH 18/135 vt: selection, handle pending signals in paste_selection
In reply to Greg Kroah-HartmanFrom: Jiri Slaby <[email protected]>
commit 687bff0cd08f790d540cfb7b2349f0d876cdddec upstream.
When pasting a selection to a vt, the task is set as INTERRUPTIBLE while waiting for a tty to unthrottle. But signals are not handled at all. Normally, this is not a problem as tty_ldisc_receive_buf receives all the goods and a user has no reason to interrupt the task.
There are two scenarios where this matters:
1) when the tty is throttled and a signal is sent to the process, it spins on a CPU until the tty is unthrottled. schedule() does not really echedule, but returns immediately, of course.
2) when the sel_buffer becomes invalid, KASAN prevents any reads from it and the loop simply does not proceed and spins forever (causing the tty to throttle, but the code never sleeps, the same as above). This sometimes happens as there is a race in the sel_buffer handling code.
So add signal handling to this ioctl (TIOCL_PASTESEL) and return -EINTR in case a signal is pending.
--- drivers/tty/vt/selection.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/tty/vt/selection.c +8 -1
@@ -29,6 +29,8 @@#include <linux/console.h> #include <linux/tty_flip.h> +#include <linux/sched/signal.h> +/* Don't take this from <ctype.h>: 011-015 on the screen aren't spaces */ #define isspace (c) ((c) == ' ')
@@ -350,6 +352,7 @@ int paste_selection(struct tty_struct *tunsigned int count;struct tty_ldisc *ld;DECLARE_WAITQUEUE (wait, current); +int ret =0 ;console_lock ();poke_blanked_console ();
@@ -363,6 +366,10 @@ int paste_selection(struct tty_struct *tadd_wait_queue (&vc->paste_wait, &wait);while (sel_buffer && sel_buffer_lth > pasted) {set_current_state (TASK_INTERRUPTIBLE ); +if (signal_pending (current)) { + ret = -EINTR ; +break ; + }if (tty_throttled (tty)) {schedule ();continue ;
@@ -378,6 +385,6 @@ int paste_selection(struct tty_struct *ttty_buffer_unlock_exclusive (&vc->port);tty_ldisc_deref (ld); -return 0 ; +return ret; }EXPORT_SYMBOL_GPL (paste_selection);
Greg Kroah-Hartman
maintainerPATCH 19/135 vt: selection, close sel_buffer race
In reply to Greg Kroah-HartmanFrom: Jiri Slaby <[email protected]>
commit 07e6124a1a46b4b5a9b3cacc0c306b50da87abf5 upstream.
syzkaller reported this UAF:
BUG: KASAN: use-after-free in n_tty_receive_buf_common+0x2481/0x2940 drivers/tty/n_tty.c:1741 Read of size 1 at addr ffff8880089e40e9 by task syz-executor.1/13184 CPU: 0 PID: 13184 Comm: syz-executor.1 Not tainted 5.4.7 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 Call Trace: ... kasan_report+0xe/0x20 mm/kasan/common.c:634 n_tty_receive_buf_common+0x2481/0x2940 drivers/tty/n_tty.c:1741 tty_ldisc_receive_buf+0xac/0x190 drivers/tty/tty_buffer.c:461 paste_selection+0x297/0x400 drivers/tty/vt/selection.c:372 tioclinux+0x20d/0x4e0 drivers/tty/vt/vt.c:3044 vt_ioctl+0x1bcf/0x28d0 drivers/tty/vt/vt_ioctl.c:364 tty_ioctl+0x525/0x15a0 drivers/tty/tty_io.c:2657 vfs_ioctl fs/ioctl.c:47 [inline]
It is due to a race between parallel paste_selection (TIOCL_PASTESEL) and set_selection_user (TIOCL_SETSEL) invocations. One uses sel_buffer, while the other frees it and reallocates a new one for another selection. Add a mutex to close this race.
The mutex takes care properly of sel_buffer and sel_buffer_lth only. The other selection global variables (like sel_start, sel_end, and sel_cons) are protected only in set_selection_user. The other functions need quite some more work to close the races of the variables there. This is going to happen later.
This likely fixes (I am unsure as there is no reproducer provided) bug 206361 too. It was marked as CVE-2020-8648.
--- drivers/tty/vt/selection.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-)
drivers/tty/vt/selection.c +17 -6
@@ -16,6 +16,7 @@#include <linux/tty.h> #include <linux/sched.h> #include <linux/mm.h> +#include <linux/mutex.h> #include <linux/slab.h> #include <linux/types.h>
@@ -45,6 +46,7 @@ static volatile int sel_start = -1; /*static int sel_end;static int sel_buffer_lth;static char *sel_buffer; +static DEFINE_MUTEX (sel_lock);/* clear_selection, highlight and highlight_pointer can be called from interrupt (via scrollback/front) */
@@ -186,7 +188,7 @@ int set_selection_kernel(struct tiocl_sechar *bp, *obp;int i, ps, pe, multiplier;u32 c; -int mode; +int mode, ret =0 ;poke_blanked_console ();
@@ -212,6 +214,7 @@ int set_selection_kernel(struct tiocl_seif (ps > pe)/* make sel_start <= sel_end */ swap (ps, pe); +mutex_lock (&sel_lock);if (sel_cons != vc_cons[fg_console].d) {clear_selection (); sel_cons = vc_cons[fg_console].d;
@@ -257,9 +260,10 @@ int set_selection_kernel(struct tiocl_sebreak ;case TIOCL_SELPOINTER :highlight_pointer (pe); -return 0 ; + goto unlock;default : -return -EINVAL ; + ret = -EINVAL ; + goto unlock; }/* remove the pointer */
@@ -281,7 +285,7 @@ int set_selection_kernel(struct tiocl_seelse if (new_sel_start == sel_start) {if (new_sel_end == sel_end)/* no action required */ -return 0 ; + goto unlock;else if (new_sel_end > sel_end)/* extend to right */ highlight (sel_end +2 , new_sel_end);else /* contract from right */
@@ -309,7 +313,8 @@ int set_selection_kernel(struct tiocl_seif (!bp) {printk (KERN_WARNING "selection: kmalloc() failed\n" );clear_selection (); -return -ENOMEM ; + ret = -ENOMEM ; + goto unlock; }kfree (sel_buffer); sel_buffer = bp;
@@ -334,7 +339,9 @@ int set_selection_kernel(struct tiocl_se } } sel_buffer_lth = bp - sel_buffer; -return 0 ; +unlock: +mutex_unlock (&sel_lock); +return ret; }EXPORT_SYMBOL_GPL (set_selection_kernel);
@@ -364,6 +371,7 @@ int paste_selection(struct tty_struct *ttty_buffer_lock_exclusive (&vc->port);add_wait_queue (&vc->paste_wait, &wait); +mutex_lock (&sel_lock);while (sel_buffer && sel_buffer_lth > pasted) {set_current_state (TASK_INTERRUPTIBLE );if (signal_pending (current)) {
@@ -371,7 +379,9 @@ int paste_selection(struct tty_struct *tbreak ; }if (tty_throttled (tty)) { +mutex_unlock (&sel_lock);schedule (); +mutex_lock (&sel_lock);continue ; }__set_current_state (TASK_RUNNING );
@@ -380,6 +390,7 @@ int paste_selection(struct tty_struct *t count); pasted += count; } +mutex_unlock (&sel_lock);remove_wait_queue (&vc->paste_wait, &wait);__set_current_state (TASK_RUNNING );
Greg Kroah-Hartman
maintainerPATCH 20/135 vt: vt_ioctl: fix race in VT_RESIZEX
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
commit 6cd1ed50efd88261298577cd92a14f2768eddeeb upstream.
We need to make sure vc_cons[i].d is not NULL after grabbing console_lock(), or risk a crash.
general protection fault, probably for non-canonical address 0xdffffc0000000068: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x0000000000000340-0x0000000000000347] CPU: 1 PID: 19462 Comm: syz-executor.5 Not tainted 5.5.0-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:vt_ioctl+0x1f96/0x26d0 drivers/tty/vt/vt_ioctl.c:883 Code: 74 41 e8 bd a6 84 fd 48 89 d8 48 c1 e8 03 42 80 3c 28 00 0f 85 e4 04 00 00 48 8b 03 48 8d b8 40 03 00 00 48 89 fa 48 c1 ea 03 <42> 0f b6 14 2a 84 d2 74 09 80 fa 03 0f 8e b1 05 00 00 44 89 b8 40 RSP: 0018:ffffc900086d7bb0 EFLAGS: 00010202 RAX: 0000000000000000 RBX: ffffffff8c34ee88 RCX: ffffc9001415c000 RDX: 0000000000000068 RSI: ffffffff83f0e6e3 RDI: 0000000000000340 RBP: ffffc900086d7cd0 R08: ffff888054ce0100 R09: fffffbfff16a2f6d R10: ffff888054ce0998 R11: ffff888054ce0100 R12: 000000000000001d R13: dffffc0000000000 R14: 1ffff920010daf79 R15: 000000000000ff7f FS: 00007f7d13c12700(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ffd477e3c38 CR3: 0000000095d0a000 CR4: 00000000001406e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: tty_ioctl+0xa37/0x14f0 drivers/tty/tty_io.c:2660 vfs_ioctl fs/ioctl.c:47 [inline] ksys_ioctl+0x123/0x180 fs/ioctl.c:763 __do_sys_ioctl fs/ioctl.c:772 [inline] __se_sys_ioctl fs/ioctl.c:770 [inline] __x64_sys_ioctl+0x73/0xb0 fs/ioctl.c:770 do_syscall_64+0xfa/0x790 arch/x86/entry/common.c:294 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x45b399 Code: ad b6 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 7b b6 fb ff c3 66 2e 0f 1f 84 00 00 00 00 RSP: 002b:00007f7d13c11c78 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007f7d13c126d4 RCX: 000000000045b399 RDX: 0000000020000080 RSI: 000000000000560a RDI: 0000000000000003 RBP: 000000000075bf20 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00000000ffffffff R13: 0000000000000666 R14: 00000000004c7f04 R15: 000000000075bf2c Modules linked in: ---[ end trace 80970faf7a67eb77 ]--- RIP: 0010:vt_ioctl+0x1f96/0x26d0 drivers/tty/vt/vt_ioctl.c:883 Code: 74 41 e8 bd a6 84 fd 48 89 d8 48 c1 e8 03 42 80 3c 28 00 0f 85 e4 04 00 00 48 8b 03 48 8d b8 40 03 00 00 48 89 fa 48 c1 ea 03 <42> 0f b6 14 2a 84 d2 74 09 80 fa 03 0f 8e b1 05 00 00 44 89 b8 40 RSP: 0018:ffffc900086d7bb0 EFLAGS: 00010202 RAX: 0000000000000000 RBX: ffffffff8c34ee88 RCX: ffffc9001415c000 RDX: 0000000000000068 RSI: ffffffff83f0e6e3 RDI: 0000000000000340 RBP: ffffc900086d7cd0 R08: ffff888054ce0100 R09: fffffbfff16a2f6d R10: ffff888054ce0998 R11: ffff888054ce0100 R12: 000000000000001d R13: dffffc0000000000 R14: 1ffff920010daf79 R15: 000000000000ff7f FS: 00007f7d13c12700(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ffd477e3c38 CR3: 0000000095d0a000 CR4: 00000000001406e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
--- drivers/tty/vt/vt_ioctl.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
drivers/tty/vt/vt_ioctl.c +11 -6
@@ -876,15 +876,20 @@ int vt_ioctl(struct tty_struct *tty,return -EINVAL ;for (i =0 ; i <MAX_NR_CONSOLES ; i++) { +struct vc_data *vcp; +if (!vc_cons[i].d)continue ;console_lock (); -if (v.v_vlin) - vc_cons[i].d->vc_scan_lines = v.v_vlin; -if (v.v_clin) - vc_cons[i].d->vc_font.height = v.v_clin; - vc_cons[i].d->vc_resize_user =1 ; -vc_resize (vc_cons[i].d, v.v_cols, v.v_rows); + vcp = vc_cons[i].d; +if (vcp) { +if (v.v_vlin) + vcp->vc_scan_lines = v.v_vlin; +if (v.v_clin) + vcp->vc_font.height = v.v_clin; + vcp->vc_resize_user =1 ; +vc_resize (vcp, v.v_cols, v.v_rows); + }console_unlock (); }break ;
Greg Kroah-Hartman
maintainerPATCH 21/135 staging: android: ashmem: Disallow ashmem memory from being remapped
In reply to Greg Kroah-HartmanFrom: Suren Baghdasaryan <[email protected]>
commit 6d67b0290b4b84c477e6a2fc6e005e174d3c7786 upstream.
When ashmem file is mmapped, the resulting vma->vm_file points to the backing shmem file with the generic fops that do not check ashmem permissions like fops of ashmem do. If an mremap is done on the ashmem region, then the permission checks will be skipped. Fix that by disallowing mapping operation on the backing shmem file.
--- drivers/staging/android/ashmem.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
drivers/staging/android/ashmem.c +28 -0
@@ -351,8 +351,23 @@ static inline vm_flags_t calc_vm_may_fla_calc_vm_trans (prot,PROT_EXEC ,VM_MAYEXEC ); } +static int ashmem_vmfile_mmap (struct file *file,struct vm_area_struct *vma) +{ +/* do not allow to mmap ashmem backing shmem file directly */ +return -EPERM ; +} + +static unsigned long +ashmem_vmfile_get_unmapped_area (struct file *file,unsigned long addr, +unsigned long len,unsigned long pgoff, +unsigned long flags) +{ +return current->mm->get_unmapped_area (file, addr, len, pgoff, flags); +} +static int ashmem_mmap (struct file *file,struct vm_area_struct *vma) { +static struct file_operations vmfile_fops;struct ashmem_area *asma = file->private_data;int ret =0 ;
@@ -393,6 +408,19 @@ static int ashmem_mmap(struct file *file } vmfile->f_mode |=FMODE_LSEEK ; asma->file = vmfile; +/* +* override mmap operation of the vmfile so that it can't be +* remapped which would lead to creation of a new vma with no +* asma permission checks. Have to override get_unmapped_area +* as well to prevent VM_BUG_ON check for f_ops modification. +*/ +if (!vmfile_fops.mmap) { + vmfile_fops = *vmfile->f_op; + vmfile_fops.mmap = ashmem_vmfile_mmap; + vmfile_fops.get_unmapped_area = + ashmem_vmfile_get_unmapped_area; + } + vmfile->f_op = &vmfile_fops; }get_file (asma->file);
Greg Kroah-Hartman
maintainerPATCH 22/135 staging: vt6656: fix sign of rx_dbm to bb_pre_ed_rssi.
In reply to Greg Kroah-HartmanFrom: Malcolm Priestley <[email protected]>
commit 93134df520f23f4e9998c425b8987edca7016817 upstream.
bb_pre_ed_rssi is an u8 rx_dm always returns negative signed values add minus operator to always yield positive.
fixes issue where rx sensitivity is always set to maximum because the unsigned numbers were always greater then 100.
--- drivers/staging/vt6656/dpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/vt6656/dpc.c +1 -1
@@ -130,7 +130,7 @@ int vnt_rx_data(struct vnt_private *privvnt_rf_rssi_to_dbm (priv, *rssi, &rx_dbm); - priv->bb_pre_ed_rssi = (u8 )rx_dbm +1 ; + priv->bb_pre_ed_rssi = (u8)-rx_dbm +1 ; priv->current_rssi = priv->bb_pre_ed_rssi;skb_pull (skb,8 );
Greg Kroah-Hartman
maintainerPATCH 23/135 xhci: Force Maximum Packet size for Full-speed bulk devices to valid range.
In reply to Greg Kroah-HartmanFrom: Mathias Nyman <[email protected]>
commit f148b9f402ef002b57bcff3964d45abc8ffb6c3f upstream.
A Full-speed bulk USB audio device (DJ-Tech CTRL) with a invalid Maximum Packet Size of 4 causes a xHC "Parameter Error" at enumeration.
This is because valid Maximum packet sizes for Full-speed bulk endpoints are 8, 16, 32 and 64 bytes. Hosts are not required to support other values than these. See usb 2 specs section 5.8.3 for details.
The device starts working after forcing the maximum packet size to 8. This is most likely the case with other devices as well, so force the maximum packet size to a valid range.
--- drivers/usb/host/xhci-mem.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
drivers/usb/host/xhci-mem.c +9 -3
@@ -1475,9 +1475,15 @@ int xhci_endpoint_init(struct xhci_hcd */* Allow 3 retries for everything but isoc, set CErr = 3 */ if (!usb_endpoint_xfer_isoc (&ep->desc)) err_count =3 ; -/* Some devices get this wrong */ -if (usb_endpoint_xfer_bulk (&ep->desc) && udev->speed ==USB_SPEED_HIGH ) - max_packet =512 ; +/* HS bulk max packet should be 512, FS bulk supports 8, 16, 32 or 64 */ +if (usb_endpoint_xfer_bulk (&ep->desc)) { +if (udev->speed ==USB_SPEED_HIGH ) + max_packet =512 ; +if (udev->speed ==USB_SPEED_FULL ) { + max_packet =rounddown_pow_of_two (max_packet); + max_packet =clamp_val (max_packet,8 ,64 ); + } + }/* xHCI 1.0 and 1.1 indicates that ctrl ep avg TRB Length should be 8 */ if (usb_endpoint_xfer_control (&ep->desc) && xhci->hci_version >=0x100 ) avg_trb_len =8 ;
Greg Kroah-Hartman
maintainerPATCH 24/135 xhci: fix runtime pm enabling for quirky Intel hosts
In reply to Greg Kroah-HartmanFrom: Mathias Nyman <[email protected]>
commit 024d411e9c5d49eb96c825af52a3ce2682895676 upstream.
Intel hosts that need the XHCI_PME_STUCK_QUIRK flag should enable runtime pm by calling xhci_pme_acpi_rtd3_enable() before usb_hcd_pci_probe() calls pci_dev_run_wake().
Otherwise usage count for the device won't be decreased, and runtime suspend is prevented.
usb_hcd_pci_probe() only decreases the usage count if device can generate run-time wake-up events, i.e. when pci_dev_run_wake() returns true.
This issue was exposed by pci_dev_run_wake() change in commit 8feaec33b986 ("PCI / PM: Always check PME wakeup capability for runtime wakeup support")
and should be backported to kernels with that change
--- drivers/usb/host/xhci-pci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/usb/host/xhci-pci.c +3 -3
@@ -302,6 +302,9 @@ static int xhci_pci_setup(struct usb_hcdif (!usb_hcd_is_primary_hcd (hcd))return 0 ; +if (xhci->quirks &XHCI_PME_STUCK_QUIRK ) +xhci_pme_acpi_rtd3_enable (pdev); +xhci_dbg (xhci,"Got SBRN %u\n" , (unsigned int ) xhci->sbrn);/* Find any debug ports */
@@ -359,9 +362,6 @@ static int xhci_pci_probe(struct pci_dev HCC_MAX_PSA(xhci->hcc_params) >= 4) xhci->shared_hcd->can_do_streams =1 ; -if (xhci->quirks &XHCI_PME_STUCK_QUIRK ) -xhci_pme_acpi_rtd3_enable (dev); -/* USB-2 and USB-3 roothubs initialized, allow runtime pm suspend */ pm_runtime_put_noidle (&dev->dev);
Greg Kroah-Hartman
maintainerPATCH 25/135 xhci: apply XHCI_PME_STUCK_QUIRK to Intel Comet Lake platforms
In reply to Greg Kroah-HartmanFrom: Mathias Nyman <[email protected]>
commit a3ae87dce3a5abe0b57c811bab02b2564b574106 upstream.
Intel Comet Lake based platform require the XHCI_PME_STUCK_QUIRK quirk as well. Without this xHC can not enter D3 in runtime suspend.
--- drivers/usb/host/xhci-pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/usb/host/xhci-pci.c +3 -1
@@ -49,6 +49,7 @@#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_XHCI 0x15ec#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_XHCI 0x15f0#define PCI_DEVICE_ID_INTEL_ICE_LAKE_XHCI 0x8a13 +#define PCI_DEVICE_ID_INTEL_CML_XHCI 0xa3af#define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9#define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba
@@ -187,7 +188,8 @@ static void xhci_pci_quirks(struct devic pdev->device ==PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI || pdev->device ==PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI || pdev->device ==PCI_DEVICE_ID_INTEL_APL_XHCI || - pdev->device == PCI_DEVICE_ID_INTEL_DNV_XHCI)) { + pdev->device ==PCI_DEVICE_ID_INTEL_DNV_XHCI || + pdev->device == PCI_DEVICE_ID_INTEL_CML_XHCI)) { xhci->quirks |= XHCI_PME_STUCK_QUIRK; } if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
Greg Kroah-Hartman
maintainerPATCH 26/135 xhci: Fix memory leak when caching protocol extended capability PSI tables - take 2
In reply to Greg Kroah-HartmanFrom: Mathias Nyman <[email protected]>
commit cf0ee7c60c89641f6e4d1d3c7867fe32b9e30300 upstream.
xhci driver assumed that xHC controllers have at most one custom supported speed table (PSI) for all usb 3.x ports.
Memory was allocated for one PSI table under the xhci hub structure.
Turns out this is not the case, some controllers have a separate "supported protocol capability" entry with a PSI table for each port. This means each usb3 roothub port can in theory support different custom speeds.
To solve this, cache all supported protocol capabilities with their PSI tables in an array, and add pointers to the xhci port structure so that every port points to its capability entry in the array.
When creating the SuperSpeedPlus USB Device Capability BOS descriptor for the xhci USB 3.1 roothub we for now will use only data from the first USB 3.1 capable protocol capability entry in the array. This could be improved later, this patch focuses resolving the memory leak.
--- drivers/usb/host/xhci-hub.c | 25 ++++++++++++------ drivers/usb/host/xhci-mem.c | 61 +++++++++++++++++++++++++++----------------- drivers/usb/host/xhci.h | 14 +++++++--- 3 files changed, 66 insertions(+), 34 deletions(-)
drivers/usb/host/xhci-hub.c +17 -8
@@ -55,6 +55,7 @@ static u8 usb_bos_descriptor [] = {static int xhci_create_usb3_bos_desc (struct xhci_hcd *xhci,char *buf,u16 wLength) { +struct xhci_port_cap *port_cap =NULL ;int i, ssa_count;u32 temp;u16 desc_size, ssp_cap_size, ssa_size =0 ;
@@ -64,16 +65,24 @@ static int xhci_create_usb3_bos_desc(str ssp_cap_size =sizeof (usb_bos_descriptor) - desc_size;/* does xhci support USB 3.1 Enhanced SuperSpeed */ -if (xhci->usb3_rhub.min_rev >=0x01 ) { +for (i =0 ; i < xhci->num_port_caps; i++) { +if (xhci->port_caps[i].maj_rev ==0x03 && + xhci->port_caps[i].min_rev >=0x01 ) { + usb3_1 = true; + port_cap = &xhci->port_caps[i]; +break ; + } + } + +if (usb3_1) {/* does xhci provide a PSI table for SSA speed attributes? */ -if (xhci->usb3_rhub.psi_count) { +if (port_cap->psi_count) {/* two SSA entries for each unique PSI ID, RX and TX */ - ssa_count = xhci->usb3_rhub.psi_uid_count *2 ; + ssa_count = port_cap->psi_uid_count *2 ; ssa_size = ssa_count *sizeof (u32); ssp_cap_size -=16 ;/* skip copying the default SSA */ } desc_size += ssp_cap_size; - usb3_1 = true; }memcpy (buf, &usb_bos_descriptor,min (desc_size, wLength));
@@ -99,7 +108,7 @@ static int xhci_create_usb3_bos_desc(str }/* If PSI table exists, add the custom speed attributes from it */ -if (usb3_1 && xhci->usb3_rhub.psi_count) { +if (usb3_1 && port_cap->psi_count) {u32 ssp_cap_base, bm_attrib, psi, psi_mant, psi_exp;int offset;
@@ -111,7 +120,7 @@ static int xhci_create_usb3_bos_desc(str/* attribute count SSAC bits 4:0 and ID count SSIC bits 8:5 */ bm_attrib = (ssa_count -1 ) &0x1f ; - bm_attrib |= (xhci->usb3_rhub.psi_uid_count -1 ) <<5 ; + bm_attrib |= (port_cap->psi_uid_count -1 ) <<5 ;put_unaligned_le32 (bm_attrib, &buf[ssp_cap_base +4 ]);if (wLength < desc_size + ssa_size)
@@ -124,8 +133,8 @@ static int xhci_create_usb3_bos_desc(str* USB 3.1 requires two SSA entries (RX and TX) for every link */ offset = desc_size; -for (i =0 ; i < xhci->usb3_rhub.psi_count; i++) { - psi = xhci->usb3_rhub.psi[i]; +for (i =0 ; i < port_cap->psi_count; i++) { + psi = port_cap->psi[i]; psi &= ~USB_SSP_SUBLINK_SPEED_RSVD ; psi_exp =XHCI_EXT_PORT_PSIE (psi); psi_mant =XHCI_EXT_PORT_PSIM (psi);
drivers/usb/host/xhci-mem.c +38 -23
104 lines not on this page · raw message
drivers/usb/host/xhci.h +11 -3
@@ -1702,12 +1702,20 @@ struct xhci_bus_state {* Intel Lynx Point LP xHCI host. */ #define XHCI_MAX_REXIT_TIMEOUT_MS 20 +struct xhci_port_cap { +u32 *psi;/* array of protocol speed ID entries */ +u8 psi_count; +u8 psi_uid_count; +u8 maj_rev; +u8 min_rev; +};struct xhci_port {__le32 __iomem *addr;int hw_portnum;int hcd_portnum;struct xhci_hub *rhub; +struct xhci_port_cap *port_cap; };struct xhci_hub {
@@ -1719,9 +1727,6 @@ struct xhci_hub {/* supported prococol extended capabiliy values */ u8 maj_rev;u8 min_rev; -u32 *psi;/* array of protocol speed ID entries */ -u8 psi_count; -u8 psi_uid_count; };/* There is one xhci_hcd structure per controller */
@@ -1880,6 +1885,9 @@ struct xhci_hcd {/* cached usb2 extened protocol capabilites */ u32 *ext_caps;unsigned int num_ext_caps; +/* cached extended protocol port capabilities */ +struct xhci_port_cap *port_caps; +unsigned int num_port_caps;/* Compliance Mode Recovery Data */ struct timer_list comp_mode_recovery_timer;u32 port_status_u0;
Greg Kroah-Hartman
maintainerPATCH 27/135 usb: host: xhci: update event ring dequeue pointer on purpose
In reply to Greg Kroah-HartmanFrom: Peter Chen <[email protected]>
commit dc0ffbea5729a3abafa577ebfce87f18b79e294b upstream.
On some situations, the software handles TRB events slower than adding TRBs, then xhci_handle_event can't return zero long time, the xHC will consider the event ring is full, and trigger "Event Ring Full" error, but in fact, the software has already finished lots of events, just no chance to update ERDP (event ring dequeue pointer).
In this commit, we force update ERDP if half of TRBS_PER_SEGMENT events have handled to avoid "Event Ring Full" error.
--- drivers/usb/host/xhci-ring.c | 60 ++++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 17 deletions(-)
drivers/usb/host/xhci-ring.c +43 -17
@@ -2741,6 +2741,42 @@ static int xhci_handle_event(struct xhci }/* +* Update Event Ring Dequeue Pointer: +* - When all events have finished +* - To avoid "Event Ring Full Error" condition +*/ +static void xhci_update_erst_dequeue (struct xhci_hcd *xhci, +union xhci_trb *event_ring_deq) +{ +u64 temp_64; +dma_addr_t deq; + + temp_64 =xhci_read_64 (xhci, &xhci->ir_set->erst_dequeue); +/* If necessary, update the HW's version of the event ring deq ptr. */ +if (event_ring_deq != xhci->event_ring->dequeue) { + deq =xhci_trb_virt_to_dma (xhci->event_ring->deq_seg, + xhci->event_ring->dequeue); +if (deq ==0 ) +xhci_warn (xhci,"WARN something wrong with SW event ring dequeue ptr\n" ); +/* +* Per 4.9.4, Software writes to the ERDP register shall +* always advance the Event Ring Dequeue Pointer value. +*/ +if ((temp_64 & (u64 ) ~ERST_PTR_MASK ) == + ((u64 ) deq & (u64 ) ~ERST_PTR_MASK )) +return ; + +/* Update HC event ring dequeue pointer */ + temp_64 &=ERST_PTR_MASK ; + temp_64 |= ((u64 ) deq & (u64 ) ~ERST_PTR_MASK ); + } + +/* Clear the event handler busy flag (RW1C) */ + temp_64 |=ERST_EHB ; +xhci_write_64 (xhci, temp_64, &xhci->ir_set->erst_dequeue); +} + +/* * xHCI spec says we can get an interrupt, and if the HC has an error condition, * we might get bad data out of the event ring. Section 4.10.2.7 has a list of * indicators of an event TRB error, but we check the status *first* to be safe.
@@ -2751,9 +2787,9 @@ irqreturn_t xhci_irq(struct usb_hcd *hcdunion xhci_trb *event_ring_deq;irqreturn_t ret =IRQ_NONE ;unsigned long flags; -dma_addr_t deq;u64 temp_64;u32 status; +int event_loop =0 ;spin_lock_irqsave (&xhci->lock, flags);/* Check if the xHC generated the interrupt, or the irq is shared */
@@ -2807,24 +2843,14 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd/* FIXME this should be a delayed service routine * that clears the EHB. */ -while (xhci_handle_event (xhci) >0 ) {} - - temp_64 =xhci_read_64 (xhci, &xhci->ir_set->erst_dequeue); -/* If necessary, update the HW's version of the event ring deq ptr. */ -if (event_ring_deq != xhci->event_ring->dequeue) { - deq =xhci_trb_virt_to_dma (xhci->event_ring->deq_seg, - xhci->event_ring->dequeue); -if (deq ==0 ) -xhci_warn (xhci,"WARN something wrong with SW event " -"ring dequeue ptr.\n" ); -/* Update HC event ring dequeue pointer */ - temp_64 &=ERST_PTR_MASK ; - temp_64 |= ((u64 ) deq & (u64 ) ~ERST_PTR_MASK ); +while (xhci_handle_event (xhci) >0 ) { +if (event_loop++ <TRBS_PER_SEGMENT /2 ) +continue ; +xhci_update_erst_dequeue (xhci, event_ring_deq); + event_loop =0 ; } -/* Clear the event handler busy flag (RW1C); event ring is empty. */ - temp_64 |=ERST_EHB ; -xhci_write_64 (xhci, temp_64, &xhci->ir_set->erst_dequeue); +xhci_update_erst_dequeue (xhci, event_ring_deq); ret =IRQ_HANDLED ; out:
Greg Kroah-Hartman
maintainerPATCH 28/135 USB: core: add endpoint-blacklist quirk
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 73f8bda9b5dc1c69df2bc55c0cbb24461a6391a9 upstream.
Add a new device quirk that can be used to blacklist endpoints.
Since commit 3e4f8e21c4f2 ("USB: core: fix check for duplicate endpoints") USB core ignores any duplicate endpoints found during descriptor parsing.
In order to handle devices where the first interfaces with duplicate endpoints are the ones that should have their endpoints ignored, we need to add a blacklist.
--- drivers/usb/core/config.c | 11 +++++++++++ drivers/usb/core/quirks.c | 32 ++++++++++++++++++++++++++++++++ drivers/usb/core/usb.h | 3 +++ include/linux/usb/quirks.h | 3 +++ 4 files changed, 49 insertions(+)
drivers/usb/core/config.c +11 -0
@@ -256,6 +256,7 @@ static int usb_parse_endpoint(struct dev struct usb_host_interface *ifp, int num_ep, unsigned char *buffer, int size) { + struct usb_device *udev = to_usb_device(ddev);unsigned char *buffer0 = buffer;struct usb_endpoint_descriptor *d;struct usb_host_endpoint *endpoint;
@@ -297,6 +298,16 @@ static int usb_parse_endpoint(struct dev goto skip_to_next_endpoint_or_interface_descriptor; } +/* Ignore blacklisted endpoints */ +if (udev->quirks &USB_QUIRK_ENDPOINT_BLACKLIST ) { +if (usb_endpoint_is_blacklisted (udev, ifp, d)) { +dev_warn (ddev,"config %d interface %d altsetting %d has a blacklisted endpoint with address 0x%X, skipping\n" , + cfgno, inum, asnum, + d->bEndpointAddress); + goto skip_to_next_endpoint_or_interface_descriptor; + } + } + endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints]; ++ifp->desc.bNumEndpoints;
drivers/usb/core/quirks.c +32 -0
@@ -472,6 +472,38 @@ static const struct usb_device_id usb_am { }/* terminating entry must be last */ }; +/* +* Entries for blacklisted endpoints that should be ignored when parsing +* configuration descriptors. +* +* Matched for devices with USB_QUIRK_ENDPOINT_BLACKLIST. +*/ +static const struct usb_device_id usb_endpoint_blacklist[] = { + { } +}; + +bool usb_endpoint_is_blacklisted (struct usb_device *udev, +struct usb_host_interface *intf, +struct usb_endpoint_descriptor *epd) +{ +const struct usb_device_id *id; +unsigned int address; + +for (id = usb_endpoint_blacklist; id->match_flags; ++id) { +if (!usb_match_device (udev, id)) +continue ; + +if (!usb_match_one_id_intf (udev, intf, id)) +continue ; + + address = id->driver_info; +if (address == epd->bEndpointAddress) +return true; + } + +return false; +} +static bool usb_match_any_interface (struct usb_device *udev,const struct usb_device_id *id) {
drivers/usb/core/usb.h +3 -0
@@ -37,6 +37,9 @@ extern void usb_authorize_interface(struextern void usb_detect_quirks (struct usb_device *udev);extern void usb_detect_interface_quirks (struct usb_device *udev);extern void usb_release_quirk_list (void ); +extern bool usb_endpoint_is_blacklisted (struct usb_device *udev, +struct usb_host_interface *intf, +struct usb_endpoint_descriptor *epd);extern int usb_remove_device (struct usb_device *udev); extern int usb_get_device_descriptor(struct usb_device *dev,
include/linux/usb/quirks.h +3 -0
@@ -69,4 +69,7 @@/* Hub needs extra delay after resetting its port. */ #define USB_QUIRK_HUB_SLOW_RESET BIT(14) +/* device has blacklisted endpoints */ +#define USB_QUIRK_ENDPOINT_BLACKLIST BIT(15) +#endif /* __LINUX_USB_QUIRKS_H */
Greg Kroah-Hartman
maintainerPATCH 29/135 USB: quirks: blacklist duplicate ep on Sound Devices USBPre2
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit bdd1b147b8026df0e4260b387026b251d888ed01 upstream.
This device has a broken vendor-specific altsetting for interface 1, where endpoint 0x85 is declared as an isochronous endpoint despite being used by interface 2 for audio capture.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
idVendor 0x0926
idProduct 0x0202
bcdDevice 1.00
iManufacturer 1 Sound Devices iProduct 2 USBPre2 iSerial 3 [...] bNumConfigurations 1
[...]
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 3
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x85 EP 5 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0126 1x 294 bytes
bInterval 1
[...]
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 0
AudioStreaming Interface Descriptor:
bLength 7
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 4
bDelay 1 frames
wFormatTag 0x0001 PCM
AudioStreaming Interface Descriptor:
bLength 26
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bNrChannels 2
bSubframeSize 2
bBitResolution 16
bSamFreqType 6 Discrete
tSamFreq[ 0] 8000
tSamFreq[ 1] 16000
tSamFreq[ 2] 24000
tSamFreq[ 3] 32000
tSamFreq[ 4] 44100
tSamFreq[ 5] 48000
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x85 EP 5 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0126 1x 294 bytes
bInterval 4
bRefresh 0
bSynchAddress 0
AudioStreaming Endpoint Descriptor:
bLength 7
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x01
Sampling Frequency
bLockDelayUnits 2 Decoded PCM samples
wLockDelay 0x0000
Since commit 3e4f8e21c4f2 ("USB: core: fix check for duplicate endpoints") USB core ignores any duplicate endpoints found during descriptor parsing, but in this case we need to ignore the first instance in order to avoid breaking the audio capture interface.
--- drivers/usb/core/quirks.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/usb/core/quirks.c +5 -0
@@ -354,6 +354,10 @@ static const struct usb_device_id usb_qu { USB_DEVICE(0x0904, 0x6103), .driver_info = USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL }, + /* Sound Devices USBPre2 */ + { USB_DEVICE(0x0926, 0x0202), .driver_info = + USB_QUIRK_ENDPOINT_BLACKLIST }, + /* Keytouch QWERTY Panel keyboard */ { USB_DEVICE(0x0926, 0x3333), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS },
@@ -479,6 +483,7 @@ static const struct usb_device_id usb_am* Matched for devices with USB_QUIRK_ENDPOINT_BLACKLIST. */ static const struct usb_device_id usb_endpoint_blacklist[] = { + {USB_DEVICE_INTERFACE_NUMBER (0x0926 ,0x0202 ,1 ), .driver_info =0x85 }, { } };
Greg Kroah-Hartman
maintainerPATCH 30/135 usb: uas: fix a plug & unplug racing
In reply to Greg Kroah-HartmanFrom: EJ Hsu <[email protected]>
commit 3e99862c05a9caa5a27969f41566b428696f5a9a upstream.
When a uas disk is plugged into an external hub, uas_probe() will be called by the hub thread to do the probe. It will first create a SCSI host and then do the scan for this host. During the scan, it will probe the LUN using SCSI INQUERY command which will be packed in the URB and submitted to uas disk.
There might be a chance that this external hub with uas disk attached is unplugged during the scan. In this case, uas driver will fail to submit the URB (due to the NOTATTACHED state of uas device) and try to put this SCSI command back to request queue waiting for next chance to run.
In normal case, this cycle will terminate when hub thread gets disconnection event and calls into uas_disconnect() accordingly. But in this case, uas_disconnect() will not be called because hub thread of external hub gets stuck waiting for the completion of this SCSI command. A deadlock happened.
In this fix, uas will call scsi_scan_host() asynchronously to avoid the blocking of hub thread.
--- drivers/usb/storage/uas.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-)
drivers/usb/storage/uas.c +22 -1
@@ -45,6 +45,7 @@ struct uas_dev_info {struct scsi_cmnd *cmnd[MAX_CMNDS ];spinlock_t lock;struct work_struct work; +struct work_struct scan_work;/* for async scanning */ };enum {
@@ -114,6 +115,17 @@ out:spin_unlock_irqrestore (&devinfo->lock, flags); } +static void uas_scan_work (struct work_struct *work) +{ +struct uas_dev_info *devinfo = + container_of(work, struct uas_dev_info, scan_work); +struct Scsi_Host *shost =usb_get_intfdata (devinfo->intf); + +dev_dbg (&devinfo->intf->dev,"starting scan\n" ); +scsi_scan_host (shost); +dev_dbg (&devinfo->intf->dev,"scan complete\n" ); +} +static void uas_add_work (struct uas_cmd_info *cmdinfo) {struct scsi_pointer *scp = (void *)cmdinfo;
@@ -983,6 +995,7 @@ static int uas_probe(struct usb_interfacinit_usb_anchor (&devinfo->data_urbs);spin_lock_init (&devinfo->lock);INIT_WORK (&devinfo->work, uas_do_work); +INIT_WORK (&devinfo->scan_work, uas_scan_work); result =uas_configure_endpoints (devinfo);if (result)
@@ -999,7 +1012,9 @@ static int uas_probe(struct usb_interfacif (result) goto free_streams; -scsi_scan_host (shost); +/* Submit the delayed_work for SCSI-device scanning */ +schedule_work (&devinfo->scan_work); +return result; free_streams:
@@ -1167,6 +1182,12 @@ static void uas_disconnect(struct usb_inusb_kill_anchored_urbs (&devinfo->data_urbs);uas_zap_pending (devinfo,DID_NO_CONNECT ); +/* +* Prevent SCSI scanning (if it hasn't started yet) +* or wait for the SCSI-scanning routine to stop. +*/ +cancel_work_sync (&devinfo->scan_work); +scsi_remove_host (shost);uas_free_streams (devinfo);scsi_host_put (shost);
Greg Kroah-Hartman
maintainerPATCH 31/135 USB: Fix novation SourceControl XL after suspend
In reply to Greg Kroah-HartmanFrom: Richard Dodd <[email protected]>
commit b692056db8ecc7f452b934f016c17348282b7699 upstream.
Currently, the SourceControl will stay in power-down mode after resuming from suspend. This patch resets the device after suspend to power it up.
--- drivers/usb/core/quirks.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/core/quirks.c +3 -0
@@ -449,6 +449,9 @@ static const struct usb_device_id usb_qu/* INTEL VALUE SSD */ { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, + /* novation SoundControl XL */ + { USB_DEVICE(0x1235, 0x0061), .driver_info = USB_QUIRK_RESET_RESUME }, + { }/* terminating entry must be last */ };
Greg Kroah-Hartman
maintainerPATCH 32/135 USB: hub: Dont record a connect-change event during reset-resume
In reply to Greg Kroah-HartmanFrom: Alan Stern <[email protected]>
commit 8099f58f1ecddf4f374f4828a3dff8397c7cbd74 upstream.
Paul Zimmerman reports that his USB Bluetooth adapter sometimes crashes following system resume, when it receives a Get-Device-Descriptor request while it is busy doing something else.
Such a request was added by commit a4f55d8b8c14 ("usb: hub: Check device descriptor before resusciation"). It gets sent when the hub driver's work thread checks whether a connect-change event on an enabled port really indicates a new device has been connected, as opposed to an old device momentarily disconnecting and then reconnecting (which can happen with xHCI host controllers, since they automatically enable connected ports).
The same kind of thing occurs when a port's power session is lost during system suspend. When the system wakes up it sees a connect-change event on the port, and if the child device's persist_enabled flag was set then hub_activate() sets the device's reset_resume flag as well as the port's bit in hub->change_bits. The reset-resume code then takes responsibility for checking that the same device is still attached to the port, and it does this as part of the device's resume pathway. By the time the hub driver's work thread starts up again, the device has already been fully reinitialized and is busy doing its own thing. There's no need for the work thread to do the same check a second time, and in fact this unnecessary check is what caused the problem that Paul observed.
Note that performing the unnecessary check is not actually a bug. Devices are supposed to be able to send descriptors back to the host even when they are busy doing something else. The underlying cause of Paul's problem lies in his Bluetooth adapter. Nevertheless, we shouldn't perform the same check twice in a row -- and as a nice side benefit, removing the extra check allows the Bluetooth adapter to work more reliably.
The work thread performs its check when it sees that the port's bit is set in hub->change_bits. In this situation that bit is interpreted as though a connect-change event had occurred on the port _after_ the reset-resume, which is not what actually happened.
One possible fix would be to make the reset-resume code clear the port's bit in hub->change_bits. But it seems simpler to just avoid setting the bit during hub_activate() in the first place. That's what this patch does.
(Proving that the patch is correct when CONFIG_PM is disabled requires a little thought. In that setting hub_activate() will be called only for initialization and resets, since there won't be any resumes or reset-resumes. During initialization and hub resets the hub doesn't have any child devices, and so this code path never gets executed.)
--- drivers/usb/core/hub.c | 5 ----- 1 file changed, 5 deletions(-)
drivers/usb/core/hub.c +0 -5
@@ -1216,11 +1216,6 @@ static void hub_activate(struct usb_hub#ifdef CONFIG_PM udev->reset_resume =1 ;#endif -/* Don't set the change_bits when the device -* was powered off. -*/ -if (test_bit (port1, hub->power_bits)) -set_bit (port1, hub->change_bits); }else {/* The power session is gone; tell hub_wq */
Greg Kroah-Hartman
maintainerPATCH 33/135 USB: hub: Fix the broken detection of USB3 device in SMSC hub
In reply to Greg Kroah-HartmanFrom: Hardik Gajjar <[email protected]>
commit 1208f9e1d758c991b0a46a1bd60c616b906bbe27 upstream.
Renesas R-Car H3ULCB + Kingfisher Infotainment Board is either not able to detect the USB3.0 mass storage devices or is detecting those as USB2.0 high speed devices.
The explanation given by Renesas is that, due to a HW issue, the XHCI driver does not wake up after going to sleep on connecting a USB3.0 device.
In order to mitigate that, disable the auto-suspend feature specifically for SMSC hubs from hub_probe() function, as a quirk.
Renesas Kingfisher Infotainment Board has two USB3.0 ports (CN2) which are connected via USB5534B 4-port SuperSpeed/Hi-Speed, low-power, configurable hub controller.
[1] SanDisk USB 3.0 device detected as USB-2.0 before the patch
[ 74.036390] usb 5-1.1: new high-speed USB device number 4 using xhci-hcd [ 74.061598] usb 5-1.1: New USB device found, idVendor=0781, idProduct=5581, bcdDevice= 1.00 [ 74.069976] usb 5-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [ 74.077303] usb 5-1.1: Product: Ultra [ 74.080980] usb 5-1.1: Manufacturer: SanDisk [ 74.085263] usb 5-1.1: SerialNumber: 4C530001110208116550
[2] SanDisk USB 3.0 device detected as USB-3.0 after the patch
[ 34.565078] usb 6-1.1: new SuperSpeed Gen 1 USB device number 3 using xhci-hcd [ 34.588719] usb 6-1.1: New USB device found, idVendor=0781, idProduct=5581, bcdDevice= 1.00 [ 34.597098] usb 6-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [ 34.604430] usb 6-1.1: Product: Ultra [ 34.608110] usb 6-1.1: Manufacturer: SanDisk [ 34.612397] usb 6-1.1: SerialNumber: 4C530001110208116550
--- drivers/usb/core/hub.c | 15 +++++++++++++++ drivers/usb/core/hub.h | 1 + 2 files changed, 16 insertions(+)
drivers/usb/core/hub.c +15 -0
@@ -37,7 +37,9 @@#include "otg_whitelist.h" #define USB_VENDOR_GENESYS_LOGIC 0x05e3 +#define USB_VENDOR_SMSC 0x0424#define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND 0x01 +#define HUB_QUIRK_DISABLE_AUTOSUSPEND 0x02#define USB_TP_TRANSMISSION_DELAY 40/* ns */ #define USB_TP_TRANSMISSION_DELAY_MAX 65535/* ns */
@@ -1725,6 +1727,10 @@ static void hub_disconnect(struct usb_inkfree (hub->buffer);pm_suspend_ignore_children (&intf->dev, false); + +if (hub->quirk_disable_autosuspend) +usb_autopm_put_interface (intf); +kref_put (&hub->kref, hub_release); }
@@ -1857,6 +1863,11 @@ static int hub_probe(struct usb_interfacif (id->driver_info &HUB_QUIRK_CHECK_PORT_AUTOSUSPEND ) hub->quirk_check_port_auto_suspend =1 ; +if (id->driver_info &HUB_QUIRK_DISABLE_AUTOSUSPEND ) { + hub->quirk_disable_autosuspend =1 ; +usb_autopm_get_interface (intf); + } +if (hub_configure (hub, &desc->endpoint[0 ].desc) >=0 )return 0 ;
@@ -5479,6 +5490,10 @@ out_hdev_lock: }static const struct usb_device_id hub_id_table[] = { + { .match_flags =USB_DEVICE_ID_MATCH_VENDOR |USB_DEVICE_ID_MATCH_INT_CLASS , + .idVendor =USB_VENDOR_SMSC , + .bInterfaceClass =USB_CLASS_HUB , + .driver_info =HUB_QUIRK_DISABLE_AUTOSUSPEND }, { .match_flags =USB_DEVICE_ID_MATCH_VENDOR |USB_DEVICE_ID_MATCH_INT_CLASS , .idVendor =USB_VENDOR_GENESYS_LOGIC ,
drivers/usb/core/hub.h +1 -0
@@ -61,6 +61,7 @@ struct usb_hub { unsigned quiescing:1; unsigned disconnected:1; unsigned in_reset:1; + unsigned quirk_disable_autosuspend:1; unsigned quirk_check_port_auto_suspend:1;
Greg Kroah-Hartman
maintainerPATCH 34/135 usb: dwc2: Fix SET/CLEAR_FEATURE and GET_STATUS flows
In reply to Greg Kroah-HartmanFrom: Minas Harutyunyan <[email protected]>
commit 9a0d6f7c0a83844baae1d6d85482863d2bf3b7a7 upstream.
SET/CLEAR_FEATURE for Remote Wakeup allowance not handled correctly. GET_STATUS handling provided not correct data on DATA Stage. Issue seen when gadget's dr_mode set to "otg" mode and connected to MacOS.
Both are fixed and tested using USBCV Ch.9 tests.
--- drivers/usb/dwc2/gadget.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-)
drivers/usb/dwc2/gadget.c +16 -12
@@ -1632,6 +1632,7 @@ static int dwc2_hsotg_process_req_statusstruct dwc2_hsotg_ep *ep0 = hsotg->eps_out[0 ];struct dwc2_hsotg_ep *ep;__le16 reply; +u16 status;int ret;dev_dbg (hsotg->dev,"%s: USB_REQ_GET_STATUS\n" , __func__);
@@ -1643,11 +1644,10 @@ static int dwc2_hsotg_process_req_statusswitch (ctrl->bRequestType &USB_RECIP_MASK ) {case USB_RECIP_DEVICE : -/* -* bit 0 => self powered -* bit 1 => remote wakeup -*/ - reply =cpu_to_le16 (0 ); + status =1 <<USB_DEVICE_SELF_POWERED ; + status |= hsotg->remote_wakeup_allowed << +USB_DEVICE_REMOTE_WAKEUP ; + reply =cpu_to_le16 (status);break ;case USB_RECIP_INTERFACE :
@@ -1758,7 +1758,10 @@ static int dwc2_hsotg_process_req_featurcase USB_RECIP_DEVICE :switch (wValue) {case USB_DEVICE_REMOTE_WAKEUP : - hsotg->remote_wakeup_allowed =1 ; +if (set) + hsotg->remote_wakeup_allowed =1 ; +else + hsotg->remote_wakeup_allowed =0 ;break ;case USB_DEVICE_TEST_MODE :
@@ -1768,16 +1771,17 @@ static int dwc2_hsotg_process_req_featurreturn -EINVAL ; hsotg->test_mode = wIndex >>8 ; - ret =dwc2_hsotg_send_reply (hsotg, ep0,NULL ,0 ); -if (ret) { -dev_err (hsotg->dev, -"%s: failed to send reply\n" , __func__); -return ret; - }break ;default :return -ENOENT ; } + + ret =dwc2_hsotg_send_reply (hsotg, ep0,NULL ,0 ); +if (ret) { +dev_err (hsotg->dev, +"%s: failed to send reply\n" , __func__); +return ret; + }break ;case USB_RECIP_ENDPOINT :
Greg Kroah-Hartman
maintainerPATCH 35/135 usb: dwc3: gadget: Check for IOC/LST bit in TRB->ctrl fields
In reply to Greg Kroah-HartmanFrom: Anurag Kumar Vulisha <[email protected]>
commit 5ee858975b13a9b40db00f456989a689fdbb296c upstream.
The current code in dwc3_gadget_ep_reclaim_completed_trb() will check for IOC/LST bit in the event->status and returns if IOC/LST bit is set. This logic doesn't work if multiple TRBs are queued per request and the IOC/LST bit is set on the last TRB of that request.
Consider an example where a queued request has multiple queued TRBs and IOC/LST bit is set only for the last TRB. In this case, the core generates XferComplete/XferInProgress events only for the last TRB (since IOC/LST are set only for the last TRB). As per the logic in dwc3_gadget_ep_reclaim_completed_trb() event->status is checked for IOC/LST bit and returns on the first TRB. This leaves the remaining TRBs left unhandled.
Similarly, if the gadget function enqueues an unaligned request with sglist already in it, it should fail the same way, since we will append another TRB to something that already uses more than one TRB.
To aviod this, this patch changes the code to check for IOC/LST bits in TRB->ctrl instead.
At a practical level, this patch resolves USB transfer stalls seen with adb on dwc3 based HiKey960 after functionfs gadget added scatter-gather support around v4.20.
[jstultz: forward ported to mainline, reworded commit log, reworked
to only check trb->ctrl as suggested by Felipe]
--- drivers/usb/dwc3/gadget.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/dwc3/gadget.c +2 -1
@@ -2426,7 +2426,8 @@ static int dwc3_gadget_ep_reclaim_compleif (event->status &DEPEVT_STATUS_SHORT && !chain)return 1 ; -if (event->status &DEPEVT_STATUS_IOC ) +if ((trb->ctrl &DWC3_TRB_CTRL_IOC ) || + (trb->ctrl &DWC3_TRB_CTRL_LST ))return 1 ;return 0 ;
Greg Kroah-Hartman
maintainerPATCH 36/135 usb: dwc3: debug: fix string position formatting mixup with ret and len
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
commit b32196e35bd7bbc8038db1aba1fbf022dc469b6a upstream.
Currently the string formatting is mixing up the offset of ret and len. Re-work the code to use just len, remove ret and use scnprintf instead of snprintf and len position accumulation where required. Remove the -ve return check since scnprintf never returns a failure -ve size. Also break overly long lines to clean up checkpatch warnings.
Addresses-Coverity: ("Unused value")
--- drivers/usb/dwc3/debug.h | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-)
drivers/usb/dwc3/debug.h +15 -24
@@ -256,86 +256,77 @@ static inline const char *dwc3_ep_event_u8 epnum = event->endpoint_number;size_t len;int status; -int ret; - ret =snprintf (str, size,"ep%d%s: " , epnum >>1 , + len =scnprintf (str, size,"ep%d%s: " , epnum >>1 , (epnum &1 ) ?"in" :"out" ); -if (ret <0 ) -return "UNKNOWN" ; status = event->status;switch (event->endpoint_event) {case DWC3_DEPEVT_XFERCOMPLETE : - len =strlen (str); -snprintf (str + len, size - len,"Transfer Complete (%c%c%c)" , + len +=scnprintf (str + len, size - len, +"Transfer Complete (%c%c%c)" , status &DEPEVT_STATUS_SHORT ?'S' :'s' , status &DEPEVT_STATUS_IOC ?'I' :'i' , status &DEPEVT_STATUS_LST ?'L' :'l' ); - len =strlen (str); -if (epnum <=1 ) -snprintf (str + len, size - len," [%s]" , +scnprintf (str + len, size - len," [%s]" ,dwc3_ep0_state_string (ep0state));break ;case DWC3_DEPEVT_XFERINPROGRESS : - len =strlen (str); - -snprintf (str + len, size - len,"Transfer In Progress [%d] (%c%c%c)" , +scnprintf (str + len, size - len, +"Transfer In Progress [%d] (%c%c%c)" , event->parameters, status &DEPEVT_STATUS_SHORT ?'S' :'s' , status &DEPEVT_STATUS_IOC ?'I' :'i' , status &DEPEVT_STATUS_LST ?'M' :'m' );break ;case DWC3_DEPEVT_XFERNOTREADY : - len =strlen (str); - -snprintf (str + len, size - len,"Transfer Not Ready [%d]%s" , + len +=scnprintf (str + len, size - len, +"Transfer Not Ready [%d]%s" , event->parameters, status &DEPEVT_STATUS_TRANSFER_ACTIVE ?" (Active)" :" (Not Active)" ); - len =strlen (str); -/* Control Endpoints */ if (epnum <=1 ) {int phase =DEPEVT_STATUS_CONTROL_PHASE (event->status);switch (phase) {case DEPEVT_STATUS_CONTROL_DATA : -snprintf (str + ret, size - ret, +scnprintf (str + len, size - len," [Data Phase]" );break ;case DEPEVT_STATUS_CONTROL_STATUS : -snprintf (str + ret, size - ret, +scnprintf (str + len, size - len," [Status Phase]" ); } }break ;case DWC3_DEPEVT_RXTXFIFOEVT : -snprintf (str + ret, size - ret,"FIFO" ); +scnprintf (str + len, size - len,"FIFO" );break ;case DWC3_DEPEVT_STREAMEVT : status = event->status;switch (status) {case DEPEVT_STREAMEVT_FOUND : -snprintf (str + ret, size - ret," Stream %d Found" , +scnprintf (str + len, size - len," Stream %d Found" , event->parameters);break ;case DEPEVT_STREAMEVT_NOTFOUND :default : -snprintf (str + ret, size - ret," Stream Not Found" ); +scnprintf (str + len, size - len," Stream Not Found" );break ; }break ;case DWC3_DEPEVT_EPCMDCMPLT : -snprintf (str + ret, size - ret,"Endpoint Command Complete" ); +scnprintf (str + len, size - len,"Endpoint Command Complete" );break ;default : -snprintf (str, size,"UNKNOWN" ); +scnprintf (str + len, size - len,"UNKNOWN" ); }return str;
Greg Kroah-Hartman
maintainerPATCH 37/135 scsi: Revert "target/core: Inline transport_lun_remove_cmd()"
In reply to Greg Kroah-HartmanFrom: Bart Van Assche <[email protected]>
commit c14335ebb92a98646ddbf447e6cacc66de5269ad upstream.
Commit 83f85b8ec305 postponed the percpu_ref_put(&se_cmd->se_lun->lun_ref) call from command completion to the time when the final command reference is dropped. That approach is not compatible with the iSCSI target driver because the iSCSI target driver keeps the command with the highest stat_sn after it has completed until the next command is received (see also iscsit_ack_from_expstatsn()). Fix this regression by reverting commit 83f85b8ec305.
--- drivers/target/target_core_transport.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-)
drivers/target/target_core_transport.c +28 -3
@@ -666,6 +666,11 @@ static int transport_cmd_check_stop_to_ftarget_remove_from_state_list (cmd); +/* +* Clear struct se_cmd->se_lun before the handoff to FE. +*/ + cmd->se_lun =NULL ; +spin_lock_irqsave (&cmd->t_state_lock, flags);/* * Determine if frontend context caller is requesting the stopping of
@@ -693,6 +698,17 @@ static int transport_cmd_check_stop_to_freturn cmd->se_tfo->check_stop_free (cmd); } +static void transport_lun_remove_cmd (struct se_cmd *cmd) +{ +struct se_lun *lun = cmd->se_lun; + +if (!lun) +return ; + +if (cmpxchg (&cmd->lun_ref_active, true, false)) +percpu_ref_put (&lun->lun_ref); +} +static void target_complete_failure_work (struct work_struct *work) { struct se_cmd *cmd = container_of(work, struct se_cmd, work);
@@ -783,6 +799,8 @@ static void target_handle_abort(struct sWARN_ON_ONCE (kref_read (&cmd->cmd_kref) ==0 ); +transport_lun_remove_cmd (cmd); +transport_cmd_check_stop_to_fabric (cmd); }
@@ -1695,6 +1713,7 @@ static void target_complete_tmr_failure( se_cmd->se_tmr_req->response =TMR_LUN_DOES_NOT_EXIST ; se_cmd->se_tfo->queue_tm_rsp (se_cmd); +transport_lun_remove_cmd (se_cmd);transport_cmd_check_stop_to_fabric (se_cmd); }
@@ -1885,6 +1904,7 @@ void transport_generic_request_failure(s goto queue_full; check_stop: +transport_lun_remove_cmd (cmd);transport_cmd_check_stop_to_fabric (cmd);return ;
@@ -2182,6 +2202,7 @@ queue_status:transport_handle_queue_full (cmd, cmd->se_dev, ret, false);return ; } +transport_lun_remove_cmd (cmd);transport_cmd_check_stop_to_fabric (cmd); }
@@ -2276,6 +2297,7 @@ static void target_complete_ok_work(struif (ret) goto queue_full; +transport_lun_remove_cmd (cmd);transport_cmd_check_stop_to_fabric (cmd);return ; }
@@ -2301,6 +2323,7 @@ static void target_complete_ok_work(struif (ret) goto queue_full; +transport_lun_remove_cmd (cmd);transport_cmd_check_stop_to_fabric (cmd);return ; }
@@ -2336,6 +2359,7 @@ queue_rsp:if (ret) goto queue_full; +transport_lun_remove_cmd (cmd);transport_cmd_check_stop_to_fabric (cmd);return ; }
@@ -2371,6 +2395,7 @@ queue_status:break ; } +transport_lun_remove_cmd (cmd);transport_cmd_check_stop_to_fabric (cmd);return ;
@@ -2697,6 +2722,9 @@ int transport_generic_free_cmd(struct se*/ if (cmd->state_active)target_remove_from_state_list (cmd); + +if (cmd->se_lun) +transport_lun_remove_cmd (cmd); }if (aborted) cmd->free_compl = &compl;
@@ -2768,9 +2796,6 @@ static void target_release_cmd_kref(strustruct completion *abrt_compl = se_cmd->abrt_compl;unsigned long flags; -if (se_cmd->lun_ref_active) -percpu_ref_put (&se_cmd->se_lun->lun_ref); -if (se_sess) {spin_lock_irqsave (&se_sess->sess_cmd_lock, flags);list_del_init (&se_cmd->se_cmd_list);
Greg Kroah-Hartman
maintainerPATCH 38/135 staging: rtl8188eu: Fix potential security hole
In reply to Greg Kroah-HartmanFrom: Larry Finger <[email protected]>
commit 499c405b2b80bb3a04425ba3541d20305e014d3e upstream.
In routine rtw_hostapd_ioctl(), the user-controlled p->length is assumed to be at least the size of struct ieee_param size, but this assumption is never checked. This could result in out-of-bounds read/write on kernel heap in case a p->length less than the size of struct ieee_param is specified by the user. If p->length is allowed to be greater than the size of the struct, then a malicious user could be wasting kernel memory. Fixes commit a2c60d42d97c ("Add files for new driver - part 16").
Reported by: Pietro Oliva <[email protected]>
--- drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +1 -1
@@ -2812,7 +2812,7 @@ static int rtw_hostapd_ioctl(struct net_ goto out; } -if (!p->pointer) { +if (!p->pointer || p->length !=sizeof (struct ieee_param )) { ret = -EINVAL ; goto out; }
Greg Kroah-Hartman
maintainerPATCH 39/135 staging: rtl8188eu: Fix potential overuse of kernel memory
In reply to Greg Kroah-HartmanFrom: Larry Finger <[email protected]>
commit 4ddf8ab8d15ddbc52eefb44eb64e38466ce1f70f upstream.
In routine wpa_supplicant_ioctl(), the user-controlled p->length is checked to be at least the size of struct ieee_param size, but the code does not detect the case where p->length is greater than the size of the struct, thus a malicious user could be wasting kernel memory. Fixes commit a2c60d42d97c ("Add files for new driver - part 16").
Reported by: Pietro Oliva <[email protected]>
Cc: Pietro Oliva <[email protected]>
Cc: Stable <[email protected]>
Fixes commit a2c60d42d97c ("Add files for new driver - part 16").
--- drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +1 -1
@@ -2025,7 +2025,7 @@ static int wpa_supplicant_ioctl(struct nstruct ieee_param *param;uint ret =0 ; -if (p->length <sizeof (struct ieee_param ) || !p->pointer) { +if (!p->pointer || p->length !=sizeof (struct ieee_param )) { ret = -EINVAL ; goto out; }
Greg Kroah-Hartman
maintainerPATCH 40/135 staging: rtl8723bs: Fix potential security hole
In reply to Greg Kroah-HartmanFrom: Larry Finger <[email protected]>
commit ac33597c0c0d1d819dccfe001bcd0acef7107e7c upstream.
In routine rtw_hostapd_ioctl(), the user-controlled p->length is assumed to be at least the size of struct ieee_param size, but this assumption is never checked. This could result in out-of-bounds read/write on kernel heap in case a p->length less than the size of struct ieee_param is specified by the user. If p->length is allowed to be greater than the size of the struct, then a malicious user could be wasting kernel memory. Fixes commit 554c0a3abf216 ("0taging: Add rtl8723bs sdio wifi driver").
Reported by: Pietro Oliva <[email protected]>
Cc: Pietro Oliva <[email protected]>
Cc: Stable <[email protected]>
Fixes 554c0a3abf216 ("0taging: Add rtl8723bs sdio wifi driver").
--- drivers/staging/rtl8723bs/os_dep/ioctl_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/rtl8723bs/os_dep/ioctl_linux.c +1 -1
@@ -4213,7 +4213,7 @@ static int rtw_hostapd_ioctl(struct net_/* if (p->length < sizeof(struct ieee_param) || !p->pointer) { */ -if (!p->pointer) { +if (!p->pointer || p->length !=sizeof (*param)) { ret = -EINVAL ; goto out; }
Greg Kroah-Hartman
maintainerPATCH 41/135 staging: rtl8723bs: Fix potential overuse of kernel memory
In reply to Greg Kroah-HartmanFrom: Larry Finger <[email protected]>
commit 23954cb078febfc63a755301fe77e06bccdb4d2a upstream.
In routine wpa_supplicant_ioctl(), the user-controlled p->length is checked to be at least the size of struct ieee_param size, but the code does not detect the case where p->length is greater than the size of the struct, thus a malicious user could be wasting kernel memory. Fixes commit 554c0a3abf216 ("staging: Add rtl8723bs sdio wifi driver").
Reported by: Pietro Oliva <[email protected]>
--- drivers/staging/rtl8723bs/os_dep/ioctl_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/rtl8723bs/os_dep/ioctl_linux.c +1 -1
@@ -3379,7 +3379,7 @@ static int wpa_supplicant_ioctl(struct n/* down(&ieee->wx_sem); */ -if (p->length <sizeof (struct ieee_param ) || !p->pointer) { +if (!p->pointer || p->length !=sizeof (struct ieee_param )) { ret = -EINVAL ; goto out; }
Greg Kroah-Hartman
maintainerPATCH 42/135 drm/panfrost: perfcnt: Reserve/use the AS attached to the perfcnt MMU context
In reply to Greg Kroah-HartmanFrom: Boris Brezillon <[email protected]>
commit dde2bb2da01e96c17f0a44b4a3cf72a30e66e3ef upstream.
We need to use the AS attached to the opened FD when dumping counters.
--- drivers/gpu/drm/panfrost/panfrost_mmu.c | 7 ++++++- drivers/gpu/drm/panfrost/panfrost_perfcnt.c | 11 ++++------- 2 files changed, 10 insertions(+), 8 deletions(-)
drivers/gpu/drm/panfrost/panfrost_mmu.c +6 -1
@@ -151,7 +151,12 @@ u32 panfrost_mmu_as_get(struct panfrost_ as = mmu->as;if (as >=0 ) {int en =atomic_inc_return (&mmu->as_count); -WARN_ON (en >=NUM_JOB_SLOTS ); + +/* +* AS can be retained by active jobs or a perfcnt context, +* hence the '+ 1' here. +*/ +WARN_ON (en >= (NUM_JOB_SLOTS +1 ));list_move (&mmu->list, &pfdev->as_lru_list); goto out;
drivers/gpu/drm/panfrost/panfrost_perfcnt.c +4 -7
@@ -73,7 +73,7 @@ static int panfrost_perfcnt_enable_lockestruct panfrost_file_priv *user = file_priv->driver_priv;struct panfrost_perfcnt *perfcnt = pfdev->perfcnt;struct drm_gem_shmem_object *bo; -u32 cfg; +u32 cfg, as;int ret;if (user == perfcnt->user)
@@ -126,12 +126,8 @@ static int panfrost_perfcnt_enable_locke perfcnt->user = user; -/* -* Always use address space 0 for now. -* FIXME: this needs to be updated when we start using different -* address space. -*/ - cfg =GPU_PERFCNT_CFG_AS (0 ) | + as =panfrost_mmu_as_get (pfdev, perfcnt->mapping->mmu); + cfg =GPU_PERFCNT_CFG_AS (as) |GPU_PERFCNT_CFG_MODE (GPU_PERFCNT_CFG_MODE_MANUAL );/*
@@ -195,6 +191,7 @@ static int panfrost_perfcnt_disable_lockdrm_gem_shmem_vunmap (&perfcnt->mapping->obj->base.base, perfcnt->buf); perfcnt->buf =NULL ;panfrost_gem_close (&perfcnt->mapping->obj->base.base, file_priv); +panfrost_mmu_as_put (pfdev, perfcnt->mapping->mmu);panfrost_gem_mapping_put (perfcnt->mapping); perfcnt->mapping =NULL ;pm_runtime_mark_last_busy (pfdev->dev);
Greg Kroah-Hartman
maintainerPATCH 43/135 powerpc/8xx: Fix clearing of bits 20-23 in ITLB miss
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
commit a4031afb9d10d97f4d0285844abbc0ab04245304 upstream.
In ITLB miss handled the line supposed to clear bits 20-23 on the L2 ITLB entry is buggy and does indeed nothing, leading to undefined value which could allow execution when it shouldn't.
Properly do the clearing with the relevant instruction.
--- arch/powerpc/kernel/head_8xx.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/kernel/head_8xx.S +1 -1
@@ -289,7 +289,7 @@ InstructionTLBMiss: * set. All other Linux PTE bits control the behavior * of the MMU. */ - rlwimi r10, r10, 0, 0x0f00 /* Clear bits 20-23 */ + rlwinm r10, r10, 0, ~0x0f00 /* Clear bits 20-23 */ rlwimi r10, r10, 4, 0x0400 /* Copy _PAGE_EXEC into bit 21 */ ori r10, r10, RPN_PATTERN | 0x200 /* Set 22 and 24-27 */ mtspr SPRN_MI_RPN, r10 /* Update TLB entry */
Greg Kroah-Hartman
maintainerPATCH 44/135 powerpc/eeh: Fix deadlock handling dead PHB
In reply to Greg Kroah-HartmanFrom: Sam Bobroff <[email protected]>
commit d4f194ed9eb9841a8f978710e4d24296f791a85b upstream.
Recovering a dead PHB can currently cause a deadlock as the PCI rescan/remove lock is taken twice.
This is caused as part of an existing bug in eeh_handle_special_event(). The pe is processed while traversing the PHBs even though the pe is unrelated to the loop. This causes the pe to be, incorrectly, processed more than once.
Untangling this section can move the pe processing out of the loop and also outside the locked section, correcting both problems.
--- arch/powerpc/kernel/eeh_driver.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
arch/powerpc/kernel/eeh_driver.c +11 -10
@@ -1200,6 +1200,17 @@ void eeh_handle_special_event(void)eeh_pe_state_mark (pe,EEH_PE_RECOVERING );eeh_handle_normal_event (pe); }else { +eeh_for_each_pe (pe, tmp_pe) +eeh_pe_for_each_dev (tmp_pe, edev, tmp_edev) + edev->mode &= ~EEH_DEV_NO_HANDLER ; + +/* Notify all devices to be down */ +eeh_pe_state_clear (pe,EEH_PE_PRI_BUS , true); +eeh_set_channel_state (pe, pci_channel_io_perm_failure); +eeh_pe_report ( +"error_detected(permanent failure)" , pe, + eeh_report_failure,NULL ); +pci_lock_rescan_remove ();list_for_each_entry (hose, &hose_list, list_node) { phb_pe =eeh_phb_pe_get (hose);
@@ -1208,16 +1219,6 @@ void eeh_handle_special_event(void) (phb_pe->state & EEH_PE_RECOVERING))continue ; -eeh_for_each_pe (pe, tmp_pe) -eeh_pe_for_each_dev (tmp_pe, edev, tmp_edev) - edev->mode &= ~EEH_DEV_NO_HANDLER ; - -/* Notify all devices to be down */ -eeh_pe_state_clear (pe,EEH_PE_PRI_BUS , true); -eeh_set_channel_state (pe, pci_channel_io_perm_failure); -eeh_pe_report ( -"error_detected(permanent failure)" , pe, - eeh_report_failure,NULL ); bus =eeh_pe_bus_get (phb_pe);if (!bus) { pr_err("%s: Cannot find PCI bus for "
Greg Kroah-Hartman
maintainerPATCH 45/135 powerpc/tm: Fix clearing MSR[TS] in current when reclaiming on signal delivery
In reply to Greg Kroah-HartmanFrom: Gustavo Luiz Duarte <[email protected]>
commit 2464cc4c345699adea52c7aef75707207cb8a2f6 upstream.
After a treclaim, we expect to be in non-transactional state. If we don't clear the current thread's MSR[TS] before we get preempted, then tm_recheckpoint_new_task() will recheckpoint and we get rescheduled in suspended transaction state.
When handling a signal caught in transactional state, handle_rt_signal64() calls get_tm_stackpointer() that treclaims the transaction using tm_reclaim_current() but without clearing the thread's MSR[TS]. This can cause the TM Bad Thing exception below if later we pagefault and get preempted trying to access the user's sigframe, using __put_user(). Afterwards, when we are rescheduled back into do_page_fault() (but now in suspended state since the thread's MSR[TS] was not cleared), upon executing 'rfid' after completion of the page fault handling, the exception is raised because a transition from suspended to non-transactional state is invalid.
Unexpected TM Bad Thing exception at c00000000000de44 (msr 0x8000000302a03031) tm_scratch=800000010280b033
Oops: Unrecoverable exception, sig: 6 [#1] LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries CPU: 25 PID: 15547 Comm: a.out Not tainted 5.4.0-rc2 #32 NIP: c00000000000de44 LR: c000000000034728 CTR: 0000000000000000 REGS: c00000003fe7bd70 TRAP: 0700 Not tainted (5.4.0-rc2) MSR: 8000000302a03031 <SF,VEC,VSX,FP,ME,IR,DR,LE,TM[SE]> CR: 44000884 XER: 00000000 CFAR: c00000000000dda4 IRQMASK: 0 PACATMSCRATCH: 800000010280b033 GPR00: c000000000034728 c000000f65a17c80 c000000001662800 00007fffacf3fd78 GPR04: 0000000000001000 0000000000001000 0000000000000000 c000000f611f8af0 GPR08: 0000000000000000 0000000078006001 0000000000000000 000c000000000000 GPR12: c000000f611f84b0 c00000003ffcb200 0000000000000000 0000000000000000 GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 GPR20: 0000000000000000 0000000000000000 0000000000000000 c000000f611f8140 GPR24: 0000000000000000 00007fffacf3fd68 c000000f65a17d90 c000000f611f7800 GPR28: c000000f65a17e90 c000000f65a17e90 c000000001685e18 00007fffacf3f000 NIP [c00000000000de44] fast_exception_return+0xf4/0x1b0 LR [c000000000034728] handle_rt_signal64+0x78/0xc50 Call Trace: [c000000f65a17c80] [c000000000034710] handle_rt_signal64+0x60/0xc50 (unreliable) [c000000f65a17d30] [c000000000023640] do_notify_resume+0x330/0x460 [c000000f65a17e20] [c00000000000dcc4] ret_from_except_lite+0x70/0x74 Instruction dump: 7c4ff120 e8410170 7c5a03a6 38400000 f8410060 e8010070 e8410080 e8610088 60000000 60000000 e8810090 e8210078 <4c000024> 48000000 e8610178 88ed0989 ---[ end trace 93094aa44b442f87 ]---
The simplified sequence of events that triggers the above exception is:
... # userspace in NON-TRANSACTIONAL state
tbegin # userspace in TRANSACTIONAL state
signal delivery # kernelspace in SUSPENDED state
handle_rt_signal64()
get_tm_stackpointer()
treclaim # kernelspace in NON-TRANSACTIONAL state
__put_user()
page fault happens. We will never get back here because of the TM Bad Thing exception.
page fault handling kicks in and we voluntarily preempt ourselves do_page_fault()
__schedule()
__switch_to(other_task) our task is rescheduled and we recheckpoint because the thread's MSR[TS] was not cleared __switch_to(our_task)
switch_to_tm()
tm_recheckpoint_new_task()
trechkpt # kernelspace in SUSPENDED state
The page fault handling resumes, but now we are in suspended transaction state
do_page_fault() completes
rfid <----- trying to get back where the page fault happened (we were non-transactional back then)
TM Bad Thing # illegal transition from suspended to non-transactional
This patch fixes that issue by clearing the current thread's MSR[TS] just after treclaim in get_tm_stackpointer() so that we stay in non-transactional state in case we are preempted. In order to make treclaim and clearing the thread's MSR[TS] atomic from a preemption perspective when CONFIG_PREEMPT is set, preempt_disable/enable() is used. It's also necessary to save the previous value of the thread's MSR before get_tm_stackpointer() is called so that it can be exposed to the signal handler later in setup_tm_sigcontexts() to inform the userspace MSR at the moment of the signal delivery.
Found with tm-signal-context-force-tm kernel selftest.
--- arch/powerpc/kernel/signal.c | 17 +++++++++++++++-- arch/powerpc/kernel/signal_32.c | 28 ++++++++++++++-------------- arch/powerpc/kernel/signal_64.c | 22 ++++++++++------------ 3 files changed, 39 insertions(+), 28 deletions(-)
arch/powerpc/kernel/signal.c +15 -2
@@ -200,14 +200,27 @@ unsigned long get_tm_stackpointer(struct* normal/non-checkpointed stack pointer. */ +unsigned long ret = tsk->thread.regs->gpr[1 ]; +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM BUG_ON (tsk != current);if (MSR_TM_ACTIVE (tsk->thread.regs->msr)) { +preempt_disable ();tm_reclaim_current (TM_CAUSE_SIGNAL );if (MSR_TM_TRANSACTIONAL (tsk->thread.regs->msr)) -return tsk->thread.ckpt_regs.gpr[1 ]; + ret = tsk->thread.ckpt_regs.gpr[1 ]; + +/* +* If we treclaim, we must clear the current thread's TM bits +* before re-enabling preemption. Otherwise we might be +* preempted and have the live MSR[TS] changed behind our back +* (tm_recheckpoint_new_task() would recheckpoint). Besides, we +* enter the signal handler in non-transactional state. +*/ + tsk->thread.regs->msr &= ~MSR_TS_MASK ; +preempt_enable (); }#endif -return tsk->thread.regs->gpr[1 ]; +return ret; }
arch/powerpc/kernel/signal_32.c +14 -14
@@ -489,19 +489,11 @@ static int save_user_regs(struct pt_regs*/ static int save_tm_user_regs (struct pt_regs *regs,struct mcontext __user *frame, -struct mcontext __user *tm_frame,int sigret) +struct mcontext __user *tm_frame,int sigret, +unsigned long msr) { -unsigned long msr = regs->msr; -WARN_ON (tm_suspend_disabled); -/* Remove TM bits from thread's MSR. The MSR in the sigcontext -* just indicates to userland that we were doing a transaction, but we -* don't want to return in transactional state. This also ensures -* that flush_fp_to_thread won't set TIF_RESTORE_TM again. -*/ - regs->msr &= ~MSR_TS_MASK ; -/* Save both sets of general registers */ if (save_general_regs (¤t->thread.ckpt_regs, frame) ||save_general_regs (regs, tm_frame))
@@ -912,6 +904,10 @@ int handle_rt_signal32(struct ksignal *kint sigret;unsigned long tramp;struct pt_regs *regs = tsk->thread.regs; +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +/* Save the thread's msr before get_tm_stackpointer() changes it */ +unsigned long msr = regs->msr; +#endif BUG_ON (tsk != current);
@@ -944,13 +940,13 @@ int handle_rt_signal32(struct ksignal *k#ifdef CONFIG_PPC_TRANSACTIONAL_MEM tm_frame = &rt_sf->uc_transact.uc_mcontext; -if (MSR_TM_ACTIVE (regs->msr)) { +if (MSR_TM_ACTIVE (msr)) {if (__put_user ((unsigned long )&rt_sf->uc_transact, &rt_sf->uc.uc_link) ||__put_user ((unsigned long )tm_frame, &rt_sf->uc_transact.uc_regs)) goto badframe; -if (save_tm_user_regs (regs, frame, tm_frame, sigret)) +if (save_tm_user_regs (regs, frame, tm_frame, sigret, msr)) goto badframe; }else
@@ -1369,6 +1365,10 @@ int handle_signal32(struct ksignal *ksigint sigret;unsigned long tramp;struct pt_regs *regs = tsk->thread.regs; +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +/* Save the thread's msr before get_tm_stackpointer() changes it */ +unsigned long msr = regs->msr; +#endif BUG_ON (tsk != current);
@@ -1402,9 +1402,9 @@ int handle_signal32(struct ksignal *ksig#ifdef CONFIG_PPC_TRANSACTIONAL_MEM tm_mctx = &frame->mctx_transact; -if (MSR_TM_ACTIVE (regs->msr)) { +if (MSR_TM_ACTIVE (msr)) {if (save_tm_user_regs (regs, &frame->mctx, &frame->mctx_transact, - sigret)) + sigret, msr)) goto badframe; }else
arch/powerpc/kernel/signal_64.c +10 -12
@@ -192,7 +192,8 @@ static long setup_sigcontext(struct sigcstatic long setup_tm_sigcontexts (struct sigcontext __user *sc,struct sigcontext __user *tm_sc,struct task_struct *tsk, -int signr,sigset_t *set,unsigned long handler) +int signr,sigset_t *set,unsigned long handler, +unsigned long msr) {/* When CONFIG_ALTIVEC is set, we _always_ setup v_regs even if the * process never used altivec yet (MSR_VEC is zero in pt_regs of
@@ -207,12 +208,11 @@ static long setup_tm_sigcontexts(structelf_vrreg_t __user *tm_v_regs =sigcontext_vmx_regs (tm_sc);#endif struct pt_regs *regs = tsk->thread.regs; -unsigned long msr = tsk->thread.regs->msr;long err =0 ;BUG_ON (tsk != current); -BUG_ON (!MSR_TM_ACTIVE (regs->msr)); +BUG_ON (!MSR_TM_ACTIVE (msr));WARN_ON (tm_suspend_disabled);
@@ -222,13 +222,6 @@ static long setup_tm_sigcontexts(struct*/ msr |= tsk->thread.ckpt_regs.msr & (MSR_FP |MSR_VEC |MSR_VSX ); -/* Remove TM bits from thread's MSR. The MSR in the sigcontext -* just indicates to userland that we were doing a transaction, but we -* don't want to return in transactional state. This also ensures -* that flush_fp_to_thread won't set TIF_RESTORE_TM again. -*/ - regs->msr &= ~MSR_TS_MASK ; -#ifdef CONFIG_ALTIVEC err |=__put_user (v_regs, &sc->v_regs); err |=__put_user (tm_v_regs, &tm_sc->v_regs);
@@ -824,6 +817,10 @@ int handle_rt_signal64(struct ksignal *kunsigned long newsp =0 ;long err =0 ;struct pt_regs *regs = tsk->thread.regs; +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM +/* Save the thread's msr before get_tm_stackpointer() changes it */ +unsigned long msr = regs->msr; +#endif BUG_ON (tsk != current);
@@ -841,7 +838,7 @@ int handle_rt_signal64(struct ksignal *k err |=__put_user (0 , &frame->uc.uc_flags); err |=__save_altstack (&frame->uc.uc_stack, regs->gpr[1 ]);#ifdef CONFIG_PPC_TRANSACTIONAL_MEM -if (MSR_TM_ACTIVE (regs->msr)) { +if (MSR_TM_ACTIVE (msr)) {/* The ucontext_t passed to userland points to the second * ucontext_t (for transactional state) with its uc_link ptr. */
@@ -849,7 +846,8 @@ int handle_rt_signal64(struct ksignal *k err |=setup_tm_sigcontexts (&frame->uc.uc_mcontext, &frame->uc_transact.uc_mcontext, tsk, ksig->sig,NULL , - (unsigned long )ksig->ka.sa.sa_handler); + (unsigned long )ksig->ka.sa.sa_handler, + msr); } else#endif {
Greg Kroah-Hartman
maintainerPATCH 46/135 powerpc/entry: Fix an #if which should be an #ifdef in entry_32.S
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
commit 9eb425b2e04e0e3006adffea5bf5f227a896f128 upstream.
--- arch/powerpc/kernel/entry_32.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/powerpc/kernel/entry_32.S +2 -2
@@ -778,7 +778,7 @@ fast_exception_return: 1: lis r3,exc_exit_restart_end@ha addi r3,r3,exc_exit_restart_end@l cmplw r12,r3 -#if CONFIG_PPC_BOOK3S_601 +#ifdef CONFIG_PPC_BOOK3S_601 bge 2b #else bge 3f
@@ -786,7 +786,7 @@ fast_exception_return: lis r4,exc_exit_restart@ha addi r4,r4,exc_exit_restart@l cmplw r12,r4 -#if CONFIG_PPC_BOOK3S_601 +#ifdef CONFIG_PPC_BOOK3S_601 blt 2b #else blt 3f
Greg Kroah-Hartman
maintainerPATCH 47/135 powerpc/hugetlb: Fix 512k hugepages on 8xx with 16k page size
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
commit f2b67ef90b0d5eca0f2255e02cf2f620bc0ddcdb upstream.
Commit 55c8fc3f4930 ("powerpc/8xx: reintroduce 16K pages with HW assistance") redefined pte_t as a struct of 4 pte_basic_t, because in 16K pages mode there are four identical entries in the page table. But the size of hugepage tables is calculated based of the size of (void *). Therefore, we end up with page tables of size 1k instead of 4k for 512k pages.
As 512k hugepage tables are the same size as standard page tables, ie 4k, use the standard page tables instead of PGT_CACHE tables.
--- arch/powerpc/mm/hugetlbpage.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-)
arch/powerpc/mm/hugetlbpage.c +18 -11
@@ -53,20 +53,24 @@ static int __hugepte_alloc(struct mm_strif (pshift >= pdshift) { cachep =PGT_CACHE (PTE_T_ORDER ); num_hugepd =1 << (pshift - pdshift); + new =NULL ; }else if (IS_ENABLED (CONFIG_PPC_8xx)) { - cachep =PGT_CACHE (PTE_INDEX_SIZE ); + cachep =NULL ; num_hugepd =1 ; + new =pte_alloc_one (mm); }else { cachep =PGT_CACHE (pdshift - pshift); num_hugepd =1 ; + new =NULL ; } -if (!cachep) { +if (!cachep && !new) {WARN_ONCE (1 ,"No page table cache created for hugetlb tables" );return -ENOMEM ; } - new =kmem_cache_alloc (cachep,pgtable_gfp_flags (mm,GFP_KERNEL )); +if (cachep) + new =kmem_cache_alloc (cachep,pgtable_gfp_flags (mm,GFP_KERNEL ));BUG_ON (pshift >HUGEPD_SHIFT_MASK );BUG_ON ((unsigned long )new &HUGEPD_SHIFT_MASK );
@@ -97,7 +101,10 @@ static int __hugepte_alloc(struct mm_strif (i < num_hugepd) {for (i = i -1 ; i >=0 ; i--, hpdp--) *hpdp =__hugepd (0 ); -kmem_cache_free (cachep, new); +if (cachep) +kmem_cache_free (cachep, new); +else +pte_free (mm, new); }else {kmemleak_ignore (new); }
@@ -324,8 +331,7 @@ static void free_hugepd_range(struct mmuif (shift >= pdshift)hugepd_free (tlb, hugepte);else if (IS_ENABLED (CONFIG_PPC_8xx)) -pgtable_free_tlb (tlb, hugepte, -get_hugepd_cache_index (PTE_INDEX_SIZE )); +pgtable_free_tlb (tlb, hugepte,0 );else pgtable_free_tlb (tlb, hugepte,get_hugepd_cache_index (pdshift - shift));
@@ -639,12 +645,13 @@ static int __init hugetlbpage_init(void)* if we have pdshift and shift value same, we don't * use pgt cache for hugepd. */ -if (pdshift > shift &&IS_ENABLED (CONFIG_PPC_8xx)) -pgtable_cache_add (PTE_INDEX_SIZE ); -else if (pdshift > shift) -pgtable_cache_add (pdshift - shift); -else if (IS_ENABLED (CONFIG_PPC_FSL_BOOK3E ) ||IS_ENABLED (CONFIG_PPC_8xx)) +if (pdshift > shift) { +if (!IS_ENABLED (CONFIG_PPC_8xx)) +pgtable_cache_add (pdshift - shift); + }else if (IS_ENABLED (CONFIG_PPC_FSL_BOOK3E ) || +IS_ENABLED (CONFIG_PPC_8xx)) {pgtable_cache_add (PTE_T_ORDER ); + } configured = true; }
Greg Kroah-Hartman
maintainerPATCH 48/135 powerpc/hugetlb: Fix 8M hugepages on 8xx
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
commit 50a175dd18de7a647e72aca7daf4744e3a5a81e3 upstream.
With HW assistance all page tables must be 4k aligned, the 8xx drops the last 12 bits during the walk.
Redefine HUGEPD_SHIFT_MASK to mask last 12 bits out. HUGEPD_SHIFT_MASK is used to for alignment of page table cache.
--- arch/powerpc/include/asm/page.h | 5 +++++ 1 file changed, 5 insertions(+)
arch/powerpc/include/asm/page.h +5 -0
@@ -295,8 +295,13 @@ static inline bool pfn_valid(unsigned lo/* * Some number of bits at the level of the page table that points to * a hugepte are used to encode the size. This masks those bits. +* On 8xx, HW assistance requires 4k alignment for the hugepte. */ +#ifdef CONFIG_PPC_8xx +#define HUGEPD_SHIFT_MASK 0xfff +#else #define HUGEPD_SHIFT_MASK 0x3f +#endif #ifndef __ASSEMBLY__
Greg Kroah-Hartman
maintainerPATCH 49/135 arm64: memory: Add missing brackets to untagged_addr() macro
In reply to Greg Kroah-HartmanFrom: Will Deacon <[email protected]>
commit d0022c0ef29b78bcbe8a5c5894bd2307143afce1 upstream.
Add brackets around the evaluation of the 'addr' parameter to the untagged_addr() macro so that the cast to 'u64' applies to the result of the expression.
--- arch/arm64/include/asm/memory.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/include/asm/memory.h +1 -1
@@ -219,7 +219,7 @@ static inline unsigned long kaslr_offset ((__force __typeof__(addr))sign_extend64((__force u64)(addr), 55))#define untagged_addr (addr) ({ \ - u64 __addr = (__force u64)addr; \ + u64 __addr = (__force u64)(addr); \ __addr &= __untagged_addr(__addr); \ (__force __typeof__(addr))__addr; \ })
Greg Kroah-Hartman
maintainerPATCH 50/135 jbd2: fix ocfs2 corrupt when clearing block group bits
In reply to Greg Kroah-HartmanFrom: wangyan <[email protected]>
commit 8eedabfd66b68a4623beec0789eac54b8c9d0fb6 upstream.
I found a NULL pointer dereference in ocfs2_block_group_clear_bits(). The running environment:
kernel version: 4.19
A cluster with two nodes, 5 luns mounted on two nodes, and do some file operations like dd/fallocate/truncate/rm on every lun with storage network disconnection.
The fallocate operation on dm-23-45 caused an null pointer dereference.
The information of NULL pointer dereference as follows:
[577992.878282] JBD2: Error -5 detected when updating journal superblock for dm-23-45. [577992.878290] Aborting journal on device dm-23-45. ... [577992.890778] JBD2: Error -5 detected when updating journal superblock for dm-24-46. [577992.890908] __journal_remove_journal_head: freeing b_committed_data [577992.890916] (fallocate,88392,52):ocfs2_extend_trans:474 ERROR: status = -30 [577992.890918] __journal_remove_journal_head: freeing b_committed_data [577992.890920] (fallocate,88392,52):ocfs2_rotate_tree_right:2500 ERROR: status = -30 [577992.890922] __journal_remove_journal_head: freeing b_committed_data [577992.890924] (fallocate,88392,52):ocfs2_do_insert_extent:4382 ERROR: status = -30 [577992.890928] (fallocate,88392,52):ocfs2_insert_extent:4842 ERROR: status = -30 [577992.890928] __journal_remove_journal_head: freeing b_committed_data [577992.890930] (fallocate,88392,52):ocfs2_add_clusters_in_btree:4947 ERROR: status = -30 [577992.890933] __journal_remove_journal_head: freeing b_committed_data [577992.890939] __journal_remove_journal_head: freeing b_committed_data [577992.890949] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000020 [577992.890950] Mem abort info: [577992.890951] ESR = 0x96000004 [577992.890952] Exception class = DABT (current EL), IL = 32 bits [577992.890952] SET = 0, FnV = 0 [577992.890953] EA = 0, S1PTW = 0 [577992.890954] Data abort info: [577992.890955] ISV = 0, ISS = 0x00000004 [577992.890956] CM = 0, WnR = 0 [577992.890958] user pgtable: 4k pages, 48-bit VAs, pgdp = 00000000f8da07a9 [577992.890960] [0000000000000020] pgd=0000000000000000 [577992.890964] Internal error: Oops: 96000004 [#1] SMP [577992.890965] Process fallocate (pid: 88392, stack limit = 0x00000000013db2fd) [577992.890968] CPU: 52 PID: 88392 Comm: fallocate Kdump: loaded Tainted: G W OE 4.19.36 #1 [577992.890969] Hardware name: Huawei TaiShan 2280 V2/BC82AMDD, BIOS 0.98 08/25/2019 [577992.890971] pstate: 60400009 (nZCv daif +PAN -UAO) [577992.891054] pc : _ocfs2_free_suballoc_bits+0x63c/0x968 [ocfs2] [577992.891082] lr : _ocfs2_free_suballoc_bits+0x618/0x968 [ocfs2] [577992.891084] sp : ffff0000c8e2b810 [577992.891085] x29: ffff0000c8e2b820 x28: 0000000000000000 [577992.891087] x27: 00000000000006f3 x26: ffffa07957b02e70 [577992.891089] x25: ffff807c59d50000 x24: 00000000000006f2 [577992.891091] x23: 0000000000000001 x22: ffff807bd39abc30 [577992.891093] x21: ffff0000811d9000 x20: ffffa07535d6a000 [577992.891097] x19: ffff000001681638 x18: ffffffffffffffff [577992.891098] x17: 0000000000000000 x16: ffff000080a03df0 [577992.891100] x15: ffff0000811d9708 x14: 203d207375746174 [577992.891101] x13: 73203a524f525245 x12: 20373439343a6565 [577992.891103] x11: 0000000000000038 x10: 0101010101010101 [577992.891106] x9 : ffffa07c68a85d70 x8 : 7f7f7f7f7f7f7f7f [577992.891109] x7 : 0000000000000000 x6 : 0000000000000080 [577992.891110] x5 : 0000000000000000 x4 : 0000000000000002 [577992.891112] x3 : ffff000001713390 x2 : 2ff90f88b1c22f00 [577992.891114] x1 : ffff807bd39abc30 x0 : 0000000000000000 [577992.891116] Call trace: [577992.891139] _ocfs2_free_suballoc_bits+0x63c/0x968 [ocfs2] [577992.891162] _ocfs2_free_clusters+0x100/0x290 [ocfs2] [577992.891185] ocfs2_free_clusters+0x50/0x68 [ocfs2] [577992.891206] ocfs2_add_clusters_in_btree+0x198/0x5e0 [ocfs2] [577992.891227] ocfs2_add_inode_data+0x94/0xc8 [ocfs2] [577992.891248] ocfs2_extend_allocation+0x1bc/0x7a8 [ocfs2] [577992.891269] ocfs2_allocate_extents+0x14c/0x338 [ocfs2] [577992.891290] __ocfs2_change_file_space+0x3f8/0x610 [ocfs2] [577992.891309] ocfs2_fallocate+0xe4/0x128 [ocfs2] [577992.891316] vfs_fallocate+0x11c/0x250 [577992.891317] ksys_fallocate+0x54/0x88 [577992.891319] __arm64_sys_fallocate+0x28/0x38 [577992.891323] el0_svc_common+0x78/0x130 [577992.891325] el0_svc_handler+0x38/0x78 [577992.891327] el0_svc+0x8/0xc
My analysis process as follows:ocfs2_fallocate
__ocfs2_change_file_space
ocfs2_allocate_extents
ocfs2_extend_allocation
ocfs2_add_inode_data
ocfs2_add_clusters_in_btree
ocfs2_insert_extent
ocfs2_do_insert_extent
ocfs2_rotate_tree_right
ocfs2_extend_rotate_transaction
ocfs2_extend_trans
jbd2_journal_restart
jbd2__journal_restart
/* handle->h_transaction is NULL,
* is_handle_aborted(handle) is true
*/
handle->h_transaction = NULL;
start_this_handle
return -EROFS;
ocfs2_free_clusters
_ocfs2_free_clusters
_ocfs2_free_suballoc_bits
ocfs2_block_group_clear_bits
ocfs2_journal_access_gd
__ocfs2_journal_access
jbd2_journal_get_undo_access
/* I think jbd2_write_access_granted() will
* return true, because do_get_write_access()
* will return -EROFS.
*/
if (jbd2_write_access_granted(...)) return 0;
do_get_write_access
/* handle->h_transaction is NULL, it will
* return -EROFS here, so do_get_write_access()
* was not called.
*/
if (is_handle_aborted(handle)) return -EROFS;
/* bh2jh(group_bh) is NULL, caused NULL
pointer dereference */
undo_bg = (struct ocfs2_group_desc *)
bh2jh(group_bh)->b_committed_data;If handle->h_transaction == NULL, then jbd2_write_access_granted() does not really guarantee that journal_head will stay around, not even speaking of its b_committed_data. The bh2jh(group_bh) can be removed after ocfs2_journal_access_gd() and before call "bh2jh(group_bh)->b_committed_data". So, we should move is_handle_aborted() check from do_get_write_access() into jbd2_journal_get_undo_access() and jbd2_journal_get_write_access() before the call to jbd2_write_access_granted().
--- fs/jbd2/transaction.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
fs/jbd2/transaction.c +6 -2
@@ -865,8 +865,6 @@ do_get_write_access(handle_t *handle, stchar *frozen_buffer =NULL ;unsigned long start_lock, time_lock; -if (is_handle_aborted (handle)) -return -EROFS ; journal = transaction->t_journal;jbd_debug (5 ,"journal_head %p, force_copy %d\n" , jh, force_copy);
@@ -1118,6 +1116,9 @@ int jbd2_journal_get_write_access(handlestruct journal_head *jh;int rc; +if (is_handle_aborted (handle)) +return -EROFS ; +if (jbd2_write_access_granted (handle, bh, false))return 0 ;
@@ -1255,6 +1256,9 @@ int jbd2_journal_get_undo_access(handle_struct journal_head *jh;char *committed_data =NULL ; +if (is_handle_aborted (handle)) +return -EROFS ; +if (jbd2_write_access_granted (handle, bh, true))return 0 ;
Greg Kroah-Hartman
maintainerPATCH 51/135 x86/ima: use correct identifier for SetupMode variable
In reply to Greg Kroah-HartmanFrom: Ard Biesheuvel <[email protected]>
commit ff5ac61ee83c13f516544d29847d28be093a40ee upstream.
The IMA arch code attempts to inspect the "SetupMode" EFI variable by populating a variable called efi_SetupMode_name with the string "SecureBoot" and passing that to the EFI GetVariable service, which obviously does not yield the expected result.
Given that the string is only referenced a single time, let's get rid of the intermediate variable, and pass the correct string as an immediate argument. While at it, do the same for "SecureBoot".
--- arch/x86/kernel/ima_arch.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
arch/x86/kernel/ima_arch.c +2 -4
@@ -10,8 +10,6 @@ extern struct boot_params boot_params;static enum efi_secureboot_mode get_sb_mode (void ) { -efi_char16_t efi_SecureBoot_name[] =L"SecureBoot" ; -efi_char16_t efi_SetupMode_name[] =L"SecureBoot" ;efi_guid_t efi_variable_guid =EFI_GLOBAL_VARIABLE_GUID ;efi_status_t status;unsigned long size;
@@ -25,7 +23,7 @@ static enum efi_secureboot_mode get_sb_m }/* Get variable contents into buffer */ - status = efi.get_variable (efi_SecureBoot_name, &efi_variable_guid, + status = efi.get_variable (L"SecureBoot" , &efi_variable_guid,NULL , &size, &secboot);if (status ==EFI_NOT_FOUND ) {pr_info ("ima: secureboot mode disabled\n" );
@@ -38,7 +36,7 @@ static enum efi_secureboot_mode get_sb_m } size =sizeof (setupmode); - status = efi.get_variable (efi_SetupMode_name, &efi_variable_guid, + status = efi.get_variable (L"SetupMode" , &efi_variable_guid,NULL , &size, &setupmode);if (status !=EFI_SUCCESS )/* ignore unknown SetupMode */
Greg Kroah-Hartman
maintainerPATCH 52/135 x86/mce/amd: Publish the bank pointer only after setup has succeeded
In reply to Greg Kroah-HartmanFrom: Borislav Petkov <[email protected]>
commit 6e5cf31fbe651bed7ba1df768f2e123531132417 upstream.
threshold_create_bank() creates a bank descriptor per MCA error thresholding counter which can be controlled over sysfs. It publishes the pointer to that bank in a per-CPU variable and then goes on to create additional thresholding blocks if the bank has such.
However, that creation of additional blocks in allocate_threshold_blocks() can fail, leading to a use-after-free through the per-CPU pointer.
Therefore, publish that pointer only after all blocks have been setup successfully.
--- arch/x86/kernel/cpu/mce/amd.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-)
arch/x86/kernel/cpu/mce/amd.c +16 -17
@@ -1196,8 +1196,9 @@ static const char *get_name(unsigned intreturn buf_mcatype; } -static int allocate_threshold_blocks (unsigned int cpu,unsigned int bank, -unsigned int block,u32 address) +static int allocate_threshold_blocks (unsigned int cpu,struct threshold_bank *tb, +unsigned int bank,unsigned int block, +u32 address) {struct threshold_block *b =NULL ;u32 low, high;
@@ -1241,16 +1242,12 @@ static int allocate_threshold_blocks(unsINIT_LIST_HEAD (&b->miscj); -if (per_cpu (threshold_banks, cpu)[bank]->blocks) { -list_add (&b->miscj, - &per_cpu (threshold_banks, cpu)[bank]->blocks->miscj); - }else { -per_cpu (threshold_banks, cpu)[bank]->blocks = b; - } +if (tb->blocks) +list_add (&b->miscj, &tb->blocks->miscj); +else + tb->blocks = b; - err =kobject_init_and_add (&b->kobj, &threshold_ktype, -per_cpu (threshold_banks, cpu)[bank]->kobj, -get_name (bank, b)); + err =kobject_init_and_add (&b->kobj, &threshold_ktype, tb->kobj,get_name (bank, b));if (err) goto out_free; recurse:
@@ -1258,7 +1255,7 @@ recurse:if (!address)return 0 ; - err =allocate_threshold_blocks (cpu, bank, block, address); + err =allocate_threshold_blocks (cpu, tb, bank, block, address);if (err) goto out_free;
@@ -1343,8 +1340,6 @@ static int threshold_create_bank(unsigne goto out_free; } -per_cpu (threshold_banks, cpu)[bank] = b; -if (is_shared_bank (bank)) {refcount_set (&b->cpus,1 );
@@ -1355,9 +1350,13 @@ static int threshold_create_bank(unsigne } } - err =allocate_threshold_blocks (cpu, bank,0 , msr_ops.misc (bank)); -if (!err) - goto out; + err =allocate_threshold_blocks (cpu, b, bank,0 , msr_ops.misc (bank)); +if (err) + goto out_free; + +per_cpu (threshold_banks, cpu)[bank] = b; + +return 0 ; out_free:kfree (b);
Greg Kroah-Hartman
maintainerPATCH 53/135 x86/mce/amd: Fix kobject lifetime
In reply to Greg Kroah-HartmanFrom: Thomas Gleixner <[email protected]>
commit 51dede9c05df2b78acd6dcf6a17d21f0877d2d7b upstream.
Accessing the MCA thresholding controls in sysfs concurrently with CPU hotplug can lead to a couple of KASAN-reported issues:
BUG: KASAN: use-after-free in sysfs_file_ops+0x155/0x180 Read of size 8 at addr ffff888367578940 by task grep/4019
and
BUG: KASAN: use-after-free in show_error_count+0x15c/0x180 Read of size 2 at addr ffff888368a05514 by task grep/4454
for example. Both result from the fact that the threshold block creation/teardown code frees the descriptor memory itself instead of defining proper ->release function and leaving it to the driver core to take care of that, after all sysfs accesses have completed.
Do that and get rid of the custom freeing code, fixing the above UAFs in the process.
[ bp: write commit message. ]
--- arch/x86/kernel/cpu/mce/amd.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
arch/x86/kernel/cpu/mce/amd.c +11 -6
@@ -1161,9 +1161,12 @@ static const struct sysfs_ops threshold_ .store = store, }; +static void threshold_block_release (struct kobject *kobj); +static struct kobj_type threshold_ktype = { .sysfs_ops = &threshold_ops, .default_attrs = default_attrs, + .release = threshold_block_release, };static const char *get_name (unsigned int bank,struct threshold_block *b)
@@ -1365,8 +1368,12 @@ static int threshold_create_bank(unsignereturn err; } -static void deallocate_threshold_block (unsigned int cpu, -unsigned int bank) +static void threshold_block_release (struct kobject *kobj) +{ +kfree (to_block (kobj)); +} + +static void deallocate_threshold_block (unsigned int cpu,unsigned int bank) {struct threshold_block *pos =NULL ;struct threshold_block *tmp =NULL ;
@@ -1376,13 +1383,11 @@ static void deallocate_threshold_block(ureturn ;list_for_each_entry_safe (pos, tmp, &head->blocks->miscj, miscj) { -kobject_put (&pos->kobj);list_del (&pos->miscj); -kfree (pos); +kobject_put (&pos->kobj); } -kfree (per_cpu (threshold_banks, cpu)[bank]->blocks); -per_cpu (threshold_banks, cpu)[bank]->blocks =NULL ; +kobject_put (&head->blocks->kobj); }static void __threshold_remove_blocks (struct threshold_bank *b)
Greg Kroah-Hartman
maintainerPATCH 54/135 x86/cpu/amd: Enable the fixed Instructions Retired counter IRPERF
In reply to Greg Kroah-HartmanFrom: Kim Phillips <[email protected]>
commit 21b5ee59ef18e27d85810584caf1f7ddc705ea83 upstream.
Commit
aaf248848db50 ("perf/x86/msr: Add AMD IRPERF (Instructions Retired)
performance counter")
added support for access to the free-running counter via 'perf -e msr/irperf/', but when exercised, it always returns a 0 count:
BEFORE:
$ perf stat -e instructions,msr/irperf/ true
Performance counter stats for 'true':
624,833 instructions
0 msr/irperf/Simply set its enable bit - HWCR bit 30 - to make it start counting.
Enablement is restricted to all machines advertising IRPERF capability, except those susceptible to an erratum that makes the IRPERF return bad values.
That erratum occurs in Family 17h models 00-1fh [1], but not in F17h models 20h and above [2].
AFTER (on a family 17h model 31h machine):
$ perf stat -e instructions,msr/irperf/ true
Performance counter stats for 'true':
621,690 instructions
622,490 msr/irperf/[1] Revision Guide for AMD Family 17h Models 00h-0Fh Processors
[2] Revision Guide for AMD Family 17h Models 30h-3Fh Processors
The revision guides are available from the bugzilla Link below.
[ bp: Massage commit message. ]
--- arch/x86/include/asm/msr-index.h | 2 ++ arch/x86/kernel/cpu/amd.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+)
arch/x86/include/asm/msr-index.h +2 -0
@@ -510,6 +510,8 @@#define MSR_K7_HWCR 0xc0010015#define MSR_K7_HWCR_SMMLOCK_BIT 0#define MSR_K7_HWCR_SMMLOCK BIT_ULL(MSR_K7_HWCR_SMMLOCK_BIT) +#define MSR_K7_HWCR_IRPERF_EN_BIT 30 +#define MSR_K7_HWCR_IRPERF_EN BIT_ULL(MSR_K7_HWCR_IRPERF_EN_BIT)#define MSR_K7_FID_VID_CTL 0xc0010041#define MSR_K7_FID_VID_STATUS 0xc0010042
arch/x86/kernel/cpu/amd.c +14 -0
@@ -28,6 +28,7 @@static const int amd_erratum_383[];static const int amd_erratum_400[]; +static const int amd_erratum_1054[];static bool cpu_has_amd_erratum (struct cpuinfo_x86 *cpu,const int *erratum);/*
@@ -978,6 +979,15 @@ static void init_amd(struct cpuinfo_x86/* AMD CPUs don't reset SS attributes on SYSRET, Xen does. */ if (!cpu_has (c,X86_FEATURE_XENPV ))set_cpu_bug (c,X86_BUG_SYSRET_SS_ATTRS ); + +/* +* Turn on the Instructions Retired free counter on machines not +* susceptible to erratum #1054 "Instructions Retired Performance +* Counter May Be Inaccurate". +*/ +if (cpu_has (c,X86_FEATURE_IRPERF ) && + !cpu_has_amd_erratum (c, amd_erratum_1054)) +msr_set_bit (MSR_K7_HWCR ,MSR_K7_HWCR_IRPERF_EN_BIT ); }#ifdef CONFIG_X86_32
@@ -1105,6 +1115,10 @@ static const int amd_erratum_400[] =static const int amd_erratum_383[] =AMD_OSVW_ERRATUM (3 ,AMD_MODEL_RANGE (0x10 ,0 ,0 ,0xff ,0xf )); +/* #1054: Instructions Retired Performance Counter May Be Inaccurate */ +static const int amd_erratum_1054[] = +AMD_OSVW_ERRATUM (0 ,AMD_MODEL_RANGE (0x17 ,0 ,0 ,0x2f ,0xf )); +static bool cpu_has_amd_erratum (struct cpuinfo_x86 *cpu,const int *erratum) {
Greg Kroah-Hartman
maintainerPATCH 55/135 serial: 8250: Check UPF_IRQ_SHARED in advance
In reply to Greg Kroah-HartmanFrom: Andy Shevchenko <[email protected]>
commit 7febbcbc48fc92e3f33863b32ed715ba4aff18c4 upstream.
The commit 54e53b2e8081
("tty: serial: 8250: pass IRQ shared flag to UART ports")
nicely explained the problem:
---8<---8<---
On some systems IRQ lines between multiple UARTs might be shared. If so, the irqflags have to be configured accordingly. The reason is: The 8250 port startup code performs IRQ tests *before* the IRQ handler for that particular port is registered. This is performed in serial8250_do_startup(). This function checks whether IRQF_SHARED is configured and only then disables the IRQ line while testing.
This test is performed upon each open() of the UART device. Imagine two UARTs share the same IRQ line: On is already opened and the IRQ is active. When the second UART is opened, the IRQ line has to be disabled while performing IRQ tests. Otherwise an IRQ might handler might be invoked, but the IRQ itself cannot be handled, because the corresponding handler isn't registered, yet. That's because the 8250 code uses a chain-handler and invokes the corresponding port's IRQ handling routines himself.
Unfortunately this IRQF_SHARED flag isn't configured for UARTs probed via device tree even if the IRQs are shared. This way, the actual and shared IRQ line isn't disabled while performing tests and the kernel correctly detects a spurious IRQ. So, adding this flag to the DT probe solves the issue.
Note: The UPF_SHARE_IRQ flag is configured unconditionally. Therefore, the IRQF_SHARED flag can be set unconditionally as well.
Example stack trace by performing echo 1 > /dev/ttyS2 on a non-patched system:
|irq 85: nobody cared (try booting with the "irqpoll" option) | [...] |handlers: |[<ffff0000080fc628>] irq_default_primary_handler threaded [<ffff00000855fbb8>] serial8250_interrupt |Disabling IRQ #85
---8<---8<---
But unfortunately didn't fix the root cause. Let's try again here by moving IRQ flag assignment from serial_link_irq_chain() to serial8250_do_startup().
This should fix the similar issue reported for 8250_pnp case.
Since this change we don't need to have custom solutions in 8250_aspeed_vuart and 8250_of drivers, thus, drop them.
--- drivers/tty/serial/8250/8250_aspeed_vuart.c | 1 - drivers/tty/serial/8250/8250_core.c | 5 ++--- drivers/tty/serial/8250/8250_of.c | 1 - drivers/tty/serial/8250/8250_port.c | 4 ++++ 4 files changed, 6 insertions(+), 5 deletions(-)
drivers/tty/serial/8250/8250_aspeed_vuart.c +0 -1
@@ -379,7 +379,6 @@ static int aspeed_vuart_probe(struct pla port.port.line = rc; port.port.irq =irq_of_parse_and_map (np,0 ); - port.port.irqflags =IRQF_SHARED ; port.port.handle_irq = aspeed_vuart_handle_irq; port.port.iotype =UPIO_MEM ; port.port.type =PORT_16550A ;
drivers/tty/serial/8250/8250_core.c +2 -3
@@ -174,7 +174,7 @@ static int serial_link_irq_chain(structstruct hlist_head *h;struct hlist_node *n;struct irq_info *i; -int ret, irq_flags = up->port.flags &UPF_SHARE_IRQ ?IRQF_SHARED :0 ; +int ret;mutex_lock (&hash_mutex);
@@ -209,9 +209,8 @@ static int serial_link_irq_chain(structINIT_LIST_HEAD (&up->list); i->head = &up->list;spin_unlock_irq (&i->lock); - irq_flags |= up->port.irqflags; ret =request_irq (up->port.irq, serial8250_interrupt, - irq_flags, up->port.name, i); + up->port.irqflags, up->port.name, i);if (ret <0 )serial_do_unlink (i, up); }
drivers/tty/serial/8250/8250_of.c +0 -1
@@ -172,7 +172,6 @@ static int of_platform_serial_setup(stru port->type = type; port->uartclk = clk; - port->irqflags |=IRQF_SHARED ;if (of_property_read_bool (np,"no-loopback-test" )) port->flags |=UPF_SKIP_TEST ;
drivers/tty/serial/8250/8250_port.c +4 -0
@@ -2192,6 +2192,10 @@ int serial8250_do_startup(struct uart_po } } +/* Check if we need to have shared IRQs */ +if (port->irq && (up->port.flags &UPF_SHARE_IRQ )) + up->port.irqflags |=IRQF_SHARED ; +if (port->irq && !(up->port.flags &UPF_NO_THRE_TEST )) {unsigned char iir1;/*
Greg Kroah-Hartman
maintainerPATCH 56/135 tty/serial: atmel: manage shutdown in case of RS485 or ISO7816 mode
In reply to Greg Kroah-HartmanFrom: Nicolas Ferre <[email protected]>
commit 04b5bfe3dc94e64d0590c54045815cb5183fb095 upstream.
In atmel_shutdown() we call atmel_stop_rx() and atmel_stop_tx() functions. Prevent the rx restart that is implemented in RS485 or ISO7816 modes when calling atmel_stop_tx() by using the atomic information tasklet_shutdown that is already in place for this purpose.
--- drivers/tty/serial/atmel_serial.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/tty/serial/atmel_serial.c +2 -1
@@ -574,7 +574,8 @@ static void atmel_stop_tx(struct uart_poatmel_uart_writel (port,ATMEL_US_IDR , atmel_port->tx_done_mask);if (atmel_uart_is_half_duplex (port)) -atmel_start_rx (port); +if (!atomic_read (&atmel_port->tasklet_shutdown)) +atmel_start_rx (port); }
Greg Kroah-Hartman
maintainerPATCH 57/135 tty: serial: imx: setup the correct sg entry for tx dma
In reply to Greg Kroah-HartmanFrom: Fugang Duan <[email protected]>
commit f76707831829530ffdd3888bebc108aecefccaa0 upstream.
There has oops as below happen on i.MX8MP EVK platform that has 6G bytes DDR memory.
when (xmit->tail < xmit->head) && (xmit->head == 0), it setups one sg entry with sg->length is zero:
sg_set_buf(sgl + 1, xmit->buf, xmit->head);
if xmit->buf is allocated from >4G address space, and SDMA only support <4G address space, then dma_map_sg() will call swiotlb_map() to do bounce buffer copying and mapping.
But swiotlb_map() don't allow sg entry's length is zero, otherwise report BUG_ON().
So the patch is to correct the tx DMA scatter list.
Oops:
[ 287.675715] kernel BUG at kernel/dma/swiotlb.c:497! [ 287.680592] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP [ 287.686075] Modules linked in: [ 287.689133] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.4.3-00016-g3fdc4e0-dirty #10 [ 287.696872] Hardware name: FSL i.MX8MP EVK (DT) [ 287.701402] pstate: 80000085 (Nzcv daIf -PAN -UAO) [ 287.706199] pc : swiotlb_tbl_map_single+0x1fc/0x310 [ 287.711076] lr : swiotlb_map+0x60/0x148 [ 287.714909] sp : ffff800010003c00 [ 287.718221] x29: ffff800010003c00 x28: 0000000000000000 [ 287.723533] x27: 0000000000000040 x26: ffff800011ae0000 [ 287.728844] x25: ffff800011ae09f8 x24: 0000000000000000 [ 287.734155] x23: 00000001b7af9000 x22: 0000000000000000 [ 287.739465] x21: ffff000176409c10 x20: 00000000001f7ffe [ 287.744776] x19: ffff000176409c10 x18: 000000000000002e [ 287.750087] x17: 0000000000000000 x16: 0000000000000000 [ 287.755397] x15: 0000000000000000 x14: 0000000000000000 [ 287.760707] x13: ffff00017f334000 x12: 0000000000000001 [ 287.766018] x11: 00000000001fffff x10: 0000000000000000 [ 287.771328] x9 : 0000000000000003 x8 : 0000000000000000 [ 287.776638] x7 : 0000000000000000 x6 : 0000000000000000 [ 287.781949] x5 : 0000000000200000 x4 : 0000000000000000 [ 287.787259] x3 : 0000000000000001 x2 : 00000001b7af9000 [ 287.792570] x1 : 00000000fbfff000 x0 : 0000000000000000 [ 287.797881] Call trace: [ 287.800328] swiotlb_tbl_map_single+0x1fc/0x310 [ 287.804859] swiotlb_map+0x60/0x148 [ 287.808347] dma_direct_map_page+0xf0/0x130 [ 287.812530] dma_direct_map_sg+0x78/0xe0 [ 287.816453] imx_uart_dma_tx+0x134/0x2f8 [ 287.820374] imx_uart_dma_tx_callback+0xd8/0x168 [ 287.824992] vchan_complete+0x194/0x200 [ 287.828828] tasklet_action_common.isra.0+0x154/0x1a0 [ 287.833879] tasklet_action+0x24/0x30 [ 287.837540] __do_softirq+0x120/0x23c [ 287.841202] irq_exit+0xb8/0xd8 [ 287.844343] __handle_domain_irq+0x64/0xb8 [ 287.848438] gic_handle_irq+0x5c/0x148 [ 287.852185] el1_irq+0xb8/0x180 [ 287.855327] cpuidle_enter_state+0x84/0x360 [ 287.859508] cpuidle_enter+0x34/0x48 [ 287.863083] call_cpuidle+0x18/0x38 [ 287.866571] do_idle+0x1e0/0x280 [ 287.869798] cpu_startup_entry+0x20/0x40 [ 287.873721] rest_init+0xd4/0xe0 [ 287.876949] arch_call_rest_init+0xc/0x14 [ 287.880958] start_kernel+0x420/0x44c [ 287.884622] Code: 9124c021 9417aff8 a94363f7 17ffffd5 (d4210000) [ 287.890718] ---[ end trace 5bc44c4ab6b009ce ]--- [ 287.895334] Kernel panic - not syncing: Fatal exception in interrupt [ 287.901686] SMP: stopping secondary CPUs [ 288.905607] SMP: failed to stop secondary CPUs 0-1 [ 288.910395] Kernel Offset: disabled [ 288.913882] CPU features: 0x0002,2000200c [ 288.917888] Memory Limit: none [ 288.920944] ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]---
--- drivers/tty/serial/imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/imx.c +1 -1
@@ -603,7 +603,7 @@ static void imx_uart_dma_tx(struct imx_p sport->tx_bytes =uart_circ_chars_pending (xmit); -if (xmit->tail < xmit->head) { +if (xmit->tail < xmit->head || xmit->head ==0 ) { sport->dma_tx_nents =1 ;sg_init_one (sgl, xmit->buf + xmit->tail, sport->tx_bytes); }else {
Greg Kroah-Hartman
maintainerPATCH 58/135 tty: serial: qcom_geni_serial: Fix RX cancel command failure
In reply to Greg Kroah-HartmanFrom: satya priya <[email protected]>
commit 679aac5ead2f18d223554a52b543e1195e181811 upstream.
RX cancel command fails when BT is switched on and off multiple times.
To handle this, poll for the cancel bit in SE_GENI_S_IRQ_STATUS register instead of SE_GENI_S_CMD_CTRL_REG.
As per the HPG update, handle the RX last bit after cancel command and flush out the RX FIFO buffer.
--- drivers/tty/serial/qcom_geni_serial.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
drivers/tty/serial/qcom_geni_serial.c +14 -4
@@ -125,6 +125,7 @@ static int handle_rx_console(struct uartstatic int handle_rx_uart (struct uart_port *uport,u32 bytes,bool drop);static unsigned int qcom_geni_serial_tx_empty (struct uart_port *port);static void qcom_geni_serial_stop_rx (struct uart_port *uport); +static void qcom_geni_serial_handle_rx (struct uart_port *uport,bool drop);static const unsigned long root_freq[] = {7372800 ,14745600 ,19200000 ,29491200 ,32000000 ,48000000 ,64000000 ,80000000 ,
@@ -615,7 +616,7 @@ static void qcom_geni_serial_stop_rx(stru32 irq_en;u32 status;struct qcom_geni_serial_port *port =to_dev_port (uport, uport); -u32 irq_clear =S_CMD_DONE_EN ; +u32 s_irq_status; irq_en =readl (uport->membase +SE_GENI_S_IRQ_EN ); irq_en &= ~(S_RX_FIFO_WATERMARK_EN |S_RX_FIFO_LAST_EN );
@@ -631,10 +632,19 @@ static void qcom_geni_serial_stop_rx(strreturn ;geni_se_cancel_s_cmd (&port->se); -qcom_geni_serial_poll_bit (uport,SE_GENI_S_CMD_CTRL_REG , -S_GENI_CMD_CANCEL , false); +qcom_geni_serial_poll_bit (uport,SE_GENI_S_IRQ_STATUS , +S_CMD_CANCEL_EN , true); +/* +* If timeout occurs secondary engine remains active +* and Abort sequence is executed. +*/ + s_irq_status =readl (uport->membase +SE_GENI_S_IRQ_STATUS ); +/* Flush the Rx buffer */ +if (s_irq_status &S_RX_FIFO_LAST_EN ) +qcom_geni_serial_handle_rx (uport, true); +writel (s_irq_status, uport->membase +SE_GENI_S_IRQ_CLEAR ); + status =readl (uport->membase +SE_GENI_STATUS ); -writel (irq_clear, uport->membase +SE_GENI_S_IRQ_CLEAR );if (status &S_GENI_CMD_ACTIVE )qcom_geni_serial_abort_rx (uport); }
Greg Kroah-Hartman
maintainerPATCH 59/135 serdev: ttyport: restore client ops on deregistration
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 0c5aae59270fb1f827acce182786094c9ccf598e upstream.
The serdev tty-port controller driver should reset the tty-port client operations also on deregistration to avoid a NULL-pointer dereference in case the port is later re-registered as a normal tty device.
Note that this can only happen with tty drivers such as 8250 which have statically allocated port structures that can end up being reused and where a later registration would not register a serdev controller (e.g. due to registration errors or if the devicetree has been changed in between).
Specifically, this can be an issue for any statically defined ports that would be registered by 8250 core when an 8250 driver is being unbound.
--- drivers/tty/serdev/serdev-ttyport.c | 6 ++---- drivers/tty/tty_port.c | 5 +++-- include/linux/tty.h | 2 ++ 3 files changed, 7 insertions(+), 6 deletions(-)
drivers/tty/serdev/serdev-ttyport.c +2 -4
@@ -265,7 +265,6 @@ struct device *serdev_tty_port_register(struct device *parent, struct tty_driver *drv, int idx) { - const struct tty_port_client_operations *old_ops; struct serdev_controller *ctrl;struct serport *serport;int ret;
@@ -284,7 +283,6 @@ struct device *serdev_tty_port_register( ctrl->ops = &ctrl_ops; - old_ops = port->client_ops; port->client_ops = &client_ops; port->client_data = ctrl;
@@ -297,7 +295,7 @@ struct device *serdev_tty_port_register( err_reset_data: port->client_data =NULL ; - port->client_ops = old_ops; + port->client_ops = &tty_port_default_client_ops;serdev_controller_put (ctrl);return ERR_PTR (ret);
@@ -312,8 +310,8 @@ int serdev_tty_port_unregister(struct ttreturn -ENODEV ;serdev_controller_remove (ctrl); - port->client_ops =NULL ; port->client_data =NULL ; + port->client_ops = &tty_port_default_client_ops;serdev_controller_put (ctrl);return 0 ;
drivers/tty/tty_port.c +3 -2
@@ -52,10 +52,11 @@ static void tty_port_default_wakeup(stru } } -static const struct tty_port_client_operations default_client_ops = { +const struct tty_port_client_operations tty_port_default_client_ops = { .receive_buf = tty_port_default_receive_buf, .write_wakeup = tty_port_default_wakeup, }; +EXPORT_SYMBOL_GPL (tty_port_default_client_ops);void tty_port_init (struct tty_port *port) {
@@ -68,7 +69,7 @@ void tty_port_init(struct tty_port *portspin_lock_init (&port->lock); port->close_delay = (50 *HZ ) /100 ; port->closing_wait = (3000 *HZ ) /100 ; - port->client_ops = &default_client_ops; + port->client_ops = &tty_port_default_client_ops;kref_init (&port->kref); }EXPORT_SYMBOL (tty_port_init);
include/linux/tty.h +2 -0
@@ -225,6 +225,8 @@ struct tty_port_client_operations {void (*write_wakeup)(struct tty_port *port); }; +extern const struct tty_port_client_operations tty_port_default_client_ops; +struct tty_port {struct tty_bufhead buf;/* Locked internally */ struct tty_struct *tty;/* Back pointer */
Greg Kroah-Hartman
maintainerPATCH 60/135 MAINTAINERS: Update drm/i915 bug filing URL
In reply to Greg Kroah-HartmanFrom: Jani Nikula <[email protected]>
commit 96228b7df33f8eb9006f8ae96949400aed9bd303 upstream.
We've moved from bugzilla to gitlab.
--- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
MAINTAINERS +1 -1
@@ -8201,7 +8201,7 @@ M: Joonas Lahtinen <joonas.lahtinen@linu M: Rodrigo Vivi <[email protected]> L: [email protected] W: https://01.org/linuxgraphics/ -B: https://01.org/linuxgraphics/documentation/how-report-bugs +B: https://gitlab.freedesktop.org/drm/intel/-/wikis/How-to-file-i915-bugs C: irc://chat.freenode.net/intel-gfx Q: http://patchwork.freedesktop.org/project/intel-gfx/ T: git git://anongit.freedesktop.org/drm-intel
Greg Kroah-Hartman
maintainerPATCH 61/135 ACPI: PM: s2idle: Check fixed wakeup events in acpi_s2idle_wake()
In reply to Greg Kroah-HartmanFrom: Rafael J. Wysocki <[email protected]>
commit 63fb9623427fbb44e3782233b6e4714057b76ff2 upstream.
Commit fdde0ff8590b ("ACPI: PM: s2idle: Prevent spurious SCIs from waking up the system") overlooked the fact that fixed events can wake up the system too and broke RTC wakeup from suspend-to-idle as a result.
Fix this issue by checking the fixed events in acpi_s2idle_wake() in addition to checking wakeup GPEs and break out of the suspend-to-idle loop if the status bits of any enabled fixed events are set then.
--- drivers/acpi/acpica/evevent.c | 45 ++++++++++++++++++++++++++++++++++++++++++ drivers/acpi/sleep.c | 7 ++++++ include/acpi/acpixf.h | 1 3 files changed, 53 insertions(+)
drivers/acpi/acpica/evevent.c +45 -0
@@ -265,4 +265,49 @@ static u32 acpi_ev_fixed_event_dispatch( handler) (acpi_gbl_fixed_event_handlers[event].context)); } +/******************************************************************************* +* +* FUNCTION: acpi_any_fixed_event_status_set +* +* PARAMETERS: None +* +* RETURN: TRUE or FALSE +* +* DESCRIPTION: Checks the PM status register for active fixed events +* +******************************************************************************/ + +u32 acpi_any_fixed_event_status_set (void ) +{ +acpi_status status; +u32 in_status; +u32 in_enable; +u32 i; + + status =acpi_hw_register_read (ACPI_REGISTER_PM1_ENABLE , &in_enable); +if (ACPI_FAILURE (status)) { +return (FALSE); + } + + status =acpi_hw_register_read (ACPI_REGISTER_PM1_STATUS , &in_status); +if (ACPI_FAILURE (status)) { +return (FALSE); + } + +/* +* Check for all possible Fixed Events and dispatch those that are active +*/ +for (i =0 ; i <ACPI_NUM_FIXED_EVENTS ; i++) { + +/* Both the status and enable bits must be on for this event */ + +if ((in_status & acpi_gbl_fixed_event_info[i].status_bit_mask) && + (in_enable & acpi_gbl_fixed_event_info[i].enable_bit_mask)) { +return (TRUE); + } + } + +return (FALSE); +} +#endif /* !ACPI_REDUCED_HARDWARE */
drivers/acpi/sleep.c +7 -0
@@ -993,6 +993,13 @@ static bool acpi_s2idle_wake(void)return true;/* +* If the status bit of any enabled fixed event is set, the +* wakeup is regarded as valid. +*/ +if (acpi_any_fixed_event_status_set ()) +return true; + +/* * If there are no EC events to process and at least one of the * other enabled GPEs is active, the wakeup is regarded as a * genuine one.
include/acpi/acpixf.h +1 -0
@@ -749,6 +749,7 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_sta ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable_all_runtime_gpes(void)) ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable_all_wakeup_gpes(void)) ACPI_HW_DEPENDENT_RETURN_UINT32(u32 acpi_any_gpe_status_set(void)) +ACPI_HW_DEPENDENT_RETURN_UINT32(u32 acpi_any_fixed_event_status_set(void)) ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_get_gpe_device(u32 gpe_index,
Greg Kroah-Hartman
maintainerPATCH 62/135 Revert "ipc,sem: remove uneeded sem_undo_list lock usage in exit_sem()"
In reply to Greg Kroah-HartmanFrom: Ioanna Alifieraki <[email protected]>
commit edf28f4061afe4c2d9eb1c3323d90e882c1d6800 upstream.
This reverts commit a97955844807e327df11aa33869009d14d6b7de0.
Commit a97955844807 ("ipc,sem: remove uneeded sem_undo_list lock usage in exit_sem()") removes a lock that is needed. This leads to a process looping infinitely in exit_sem() and can also lead to a crash. There is a reproducer available in [1] and with the commit reverted the issue does not reproduce anymore.
Using the reproducer found in [1] is fairly easy to reach a point where one of the child processes is looping infinitely in exit_sem between for(;;) and if (semid == -1) block, while it's trying to free its last sem_undo structure which has already been freed by freeary().
Each sem_undo struct is on two lists: one per semaphore set (list_id) and one per process (list_proc). The list_id list tracks undos by semaphore set, and the list_proc by process.
Undo structures are removed either by freeary() or by exit_sem(). The freeary function is invoked when the user invokes a syscall to remove a semaphore set. During this operation freeary() traverses the list_id associated with the semaphore set and removes the undo structures from both the list_id and list_proc lists.
For this case, exit_sem() is called at process exit. Each process contains a struct sem_undo_list (referred to as "ulp") which contains the head for the list_proc list. When the process exits, exit_sem() traverses this list to remove each sem_undo struct. As in freeary(), whenever a sem_undo struct is removed from list_proc, it is also removed from the list_id list.
Removing elements from list_id is safe for both exit_sem() and freeary() due to sem_lock(). Removing elements from list_proc is not safe; freeary() locks &un->ulp->lock when it performs list_del_rcu(&un->list_proc) but exit_sem() does not (locking was removed by commit a97955844807 ("ipc,sem: remove uneeded sem_undo_list lock usage in exit_sem()").
This can result in the following situation while executing the reproducer [1] : Consider a child process in exit_sem() and the parent in freeary() (because of semctl(sid[i], NSEM, IPC_RMID)).
- The list_proc for the child contains the last two undo structs A and B (the rest have been removed either by exit_sem() or freeary()).
- The semid for A is 1 and semid for B is 2.
- exit_sem() removes A and at the same time freeary() removes B.
- Since A and B have different semid sem_lock() will acquire different locks for each process and both can proceed.
The bug is that they remove A and B from the same list_proc at the same time because only freeary() acquires the ulp lock. When exit_sem() removes A it makes ulp->list_proc.next to point at B and at the same time freeary() removes B setting B->semid=-1.
At the next iteration of for(;;) loop exit_sem() will try to remove B.
The only way to break from for(;;) is for (&un->list_proc == &ulp->list_proc) to be true which is not. Then exit_sem() will check if B->semid=-1 which is and will continue looping in for(;;) until the memory for B is reallocated and the value at B->semid is changed.
At that point, exit_sem() will crash attempting to unlink B from the lists (this can be easily triggered by running the reproducer [1] a second time).
To prove this scenario instrumentation was added to keep information about each sem_undo (un) struct that is removed per process and per semaphore set (sma).
CPU0 CPU1
[caller holds sem_lock(sma for A)] ... freeary() exit_sem() ... ... ... sem_lock(sma for B) spin_lock(A->ulp->lock) ... list_del_rcu(un_A->list_proc) list_del_rcu(un_B->list_proc)
Undo structures A and B have different semid and sem_lock() operations proceed. However they belong to the same list_proc list and they are removed at the same time. This results into ulp->list_proc.next pointing to the address of B which is already removed.
After reverting commit a97955844807 ("ipc,sem: remove uneeded sem_undo_list lock usage in exit_sem()") the issue was no longer reproducible.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1694779
--- ipc/sem.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
ipc/sem.c +2 -4
@@ -2368,11 +2368,9 @@ void exit_sem(struct task_struct *tsk)ipc_assert_locked_object (&sma->sem_perm);list_del (&un->list_id); -/* we are the last process using this ulp, acquiring ulp->lock -* isn't required. Besides that, we are also protected against -* IPC_RMID as we hold sma->sem_perm lock now -*/ +spin_lock (&ulp->lock);list_del_rcu (&un->list_proc); +spin_unlock (&ulp->lock);/* perform adjustments registered in un */ for (i =0 ; i < sma->sem_nsems; i++) {
Greg Kroah-Hartman
maintainerPATCH 63/135 mm/memcontrol.c: lost css_put in memcg_expand_shrinker_maps()
In reply to Greg Kroah-HartmanFrom: Vasily Averin <[email protected]>
commit 75866af62b439859d5146b7093ceb6b482852683 upstream.
for_each_mem_cgroup() increases css reference counter for memory cgroup and requires to use mem_cgroup_iter_break() if the walk is cancelled.
--- mm/memcontrol.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
mm/memcontrol.c +3 -1
@@ -418,8 +418,10 @@ int memcg_expand_shrinker_maps(int new_iif (mem_cgroup_is_root (memcg))continue ; ret =memcg_expand_one_shrinker_map (memcg, size, old_size); -if (ret) +if (ret) { +mem_cgroup_iter_break (NULL , memcg); goto unlock; + } } unlock:if (!ret)
Greg Kroah-Hartman
maintainerPATCH 64/135 nvme-multipath: Fix memory leak with ana_log_buf
In reply to Greg Kroah-HartmanFrom: Logan Gunthorpe <[email protected]>
commit 3b7830904e17202524bad1974505a9bfc718d31f upstream.
kmemleak reports a memory leak with the ana_log_buf allocated by nvme_mpath_init():
unreferenced object 0xffff888120e94000 (size 8208):
comm "nvme", pid 6884, jiffies 4295020435 (age 78786.312s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................
01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<00000000e2360188>] kmalloc_order+0x97/0xc0
[<0000000079b18dd4>] kmalloc_order_trace+0x24/0x100
[<00000000f50c0406>] __kmalloc+0x24c/0x2d0
[<00000000f31a10b9>] nvme_mpath_init+0x23c/0x2b0
[<000000005802589e>] nvme_init_identify+0x75f/0x1600
[<0000000058ef911b>] nvme_loop_configure_admin_queue+0x26d/0x280
[<00000000673774b9>] nvme_loop_create_ctrl+0x2a7/0x710
[<00000000f1c7a233>] nvmf_dev_write+0xc66/0x10b9
[<000000004199f8d0>] __vfs_write+0x50/0xa0
[<0000000065466fef>] vfs_write+0xf3/0x280
[<00000000b0db9a8b>] ksys_write+0xc6/0x160
[<0000000082156b91>] __x64_sys_write+0x43/0x50
[<00000000c34fbb6d>] do_syscall_64+0x77/0x2f0
[<00000000bbc574c9>] entry_SYSCALL_64_after_hwframe+0x49/0xbenvme_mpath_init() is called by nvme_init_identify() which is called in multiple places (nvme_reset_work(), nvme_passthru_end(), etc). This means nvme_mpath_init() may be called multiple times before nvme_mpath_uninit() (which is only called on nvme_free_ctrl()).
When nvme_mpath_init() is called multiple times, it overwrites the ana_log_buf pointer with a new allocation, thus leaking the previous allocation.
To fix this, free ana_log_buf before allocating a new one.
--- drivers/nvme/host/multipath.c | 1 + 1 file changed, 1 insertion(+)
drivers/nvme/host/multipath.c +1 -0
@@ -711,6 +711,7 @@ int nvme_mpath_init(struct nvme_ctrl *ct }INIT_WORK (&ctrl->ana_work, nvme_ana_work); +kfree (ctrl->ana_log_buf); ctrl->ana_log_buf =kmalloc (ctrl->ana_log_size,GFP_KERNEL );if (!ctrl->ana_log_buf) { error = -ENOMEM ;
Greg Kroah-Hartman
maintainerPATCH 65/135 genirq/irqdomain: Make sure all irq domain flags are distinct
In reply to Greg Kroah-HartmanFrom: Zenghui Yu <[email protected]>
commit 2546287c5fb363a0165933ae2181c92f03e701d0 upstream.
This was noticed when printing debugfs for MSIs on my ARM64 server. The new dstate IRQD_MSI_NOMASK_QUIRK came out surprisingly while it should only be the x86 stuff for the time being...
The new MSI quirk flag uses the same bit as IRQ_DOMAIN_NAME_ALLOCATED which is oddly defined as bit 6 for no good reason.
Switch it to the non used bit 1.
--- include/linux/irqdomain.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/irqdomain.h +1 -1
@@ -191,7 +191,7 @@ enum {IRQ_DOMAIN_FLAG_HIERARCHY = (1 <<0 ),/* Irq domain name was allocated in __irq_domain_add() */ -IRQ_DOMAIN_NAME_ALLOCATED = (1 <<6 ), +IRQ_DOMAIN_NAME_ALLOCATED = (1 <<1 ),/* Irq domain is an IPI domain with virq per cpu */ IRQ_DOMAIN_FLAG_IPI_PER_CPU = (1 << 2),
Greg Kroah-Hartman
maintainerPATCH 66/135 mm/vmscan.c: dont round up scan size for online memory cgroup
In reply to Greg Kroah-HartmanFrom: Gavin Shan <[email protected]>
commit 76073c646f5f4999d763f471df9e38a5a912d70d upstream.
Commit 68600f623d69 ("mm: don't miss the last page because of round-off error") makes the scan size round up to @denominator regardless of the memory cgroup's state, online or offline. This affects the overall reclaiming behavior: the corresponding LRU list is eligible for reclaiming only when its size logically right shifted by @sc->priority is bigger than zero in the former formula.
For example, the inactive anonymous LRU list should have at least 0x4000 pages to be eligible for reclaiming when we have 60/12 for swappiness/priority and without taking scan/rotation ratio into account.
After the roundup is applied, the inactive anonymous LRU list becomes eligible for reclaiming when its size is bigger than or equal to 0x1000 in the same condition.
(0x4000 >> 12) * 60 / (60 + 140 + 1) = 1
((0x1000 >> 12) * 60) + 200) / (60 + 140 + 1) = 1aarch64 has 512MB huge page size when the base page size is 64KB. The memory cgroup that has a huge page is always eligible for reclaiming in that case.
The reclaiming is likely to stop after the huge page is reclaimed, meaing the further iteration on @sc->priority and the silbing and child memory cgroups will be skipped. The overall behaviour has been changed. This fixes the issue by applying the roundup to offlined memory cgroups only, to give more preference to reclaim memory from offlined memory cgroup. It sounds reasonable as those memory is unlikedly to be used by anyone.
The issue was found by starting up 8 VMs on a Ampere Mustang machine, which has 8 CPUs and 16 GB memory. Each VM is given with 2 vCPUs and 2GB memory. It took 264 seconds for all VMs to be completely up and 784MB swap is consumed after that. With this patch applied, it took 236 seconds and 60MB swap to do same thing. So there is 10% performance improvement for my case. Note that KSM is disable while THP is enabled in the testing.
total used free shared buff/cache available
Mem: 16196 10065 2049 16 4081 3749
Swap: 8175 784 7391
total used free shared buff/cache available
Mem: 16196 11324 3656 24 1215 2936
Swap: 8175 60 8115--- mm/vmscan.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
mm/vmscan.c +6 -3
@@ -2530,10 +2530,13 @@ out:/* * Scan types proportional to swappiness and * their relative recent reclaim efficiency. -* Make sure we don't miss the last page -* because of a round-off error. +* Make sure we don't miss the last page on +* the offlined memory cgroups because of a +* round-off error. */ - scan =DIV64_U64_ROUND_UP (scan * fraction[file], + scan =mem_cgroup_online (memcg) ? +div64_u64 (scan * fraction[file], denominator) : +DIV64_U64_ROUND_UP (scan * fraction[file], denominator);break ;case SCAN_FILE :
Greg Kroah-Hartman
maintainerPATCH 67/135 mm/sparsemem: pfn_to_page is not valid yet on SPARSEMEM
In reply to Greg Kroah-HartmanFrom: Wei Yang <[email protected]>
commit 18e19f195cd888f65643a77a0c6aee8f5be6439a upstream.
When we use SPARSEMEM instead of SPARSEMEM_VMEMMAP, pfn_to_page() doesn't work before sparse_init_one_section() is called.
This leads to a crash when hotplug memory:
BUG: unable to handle page fault for address: 0000000006400000
#PF: supervisor write access in kernel mode
#PF: error_code(0x0002) - not-present page
PGD 0 P4D 0
Oops: 0002 [#1] SMP PTI
CPU: 3 PID: 221 Comm: kworker/u16:1 Tainted: G W 5.5.0-next-20200205+ #343
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 0.0.0 02/06/2015
Workqueue: kacpi_hotplug acpi_hotplug_work_fn
RIP: 0010:__memset+0x24/0x30
Code: cc cc cc cc cc cc 0f 1f 44 00 00 49 89 f9 48 89 d1 83 e2 07 48 c1 e9 03 40 0f b6 f6 48 b8 01 01 01 01 01 01 01 01 48 0f af c6 <f3> 48 ab 89 d1 f3 aa 4c 89 c8 c3 90 49 89 f9 40 88 f0 48 89 d1 f3
RSP: 0018:ffffb43ac0373c80 EFLAGS: 00010a87
RAX: ffffffffffffffff RBX: ffff8a1518800000 RCX: 0000000000050000
RDX: 0000000000000000 RSI: 00000000000000ff RDI: 0000000006400000
RBP: 0000000000140000 R08: 0000000000100000 R09: 0000000006400000
R10: 0000000000000000 R11: 0000000000000002 R12: 0000000000000000
R13: 0000000000000028 R14: 0000000000000000 R15: ffff8a153ffd9280
FS: 0000000000000000(0000) GS:ffff8a153ab00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000006400000 CR3: 0000000136fca000 CR4: 00000000000006e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
sparse_add_section+0x1c9/0x26a
__add_pages+0xbf/0x150
add_pages+0x12/0x60
add_memory_resource+0xc8/0x210
__add_memory+0x62/0xb0
acpi_memory_device_add+0x13f/0x300
acpi_bus_attach+0xf6/0x200
acpi_bus_scan+0x43/0x90
acpi_device_hotplug+0x275/0x3d0
acpi_hotplug_work_fn+0x1a/0x30
process_one_work+0x1a7/0x370
worker_thread+0x30/0x380
kthread+0x112/0x130
ret_from_fork+0x35/0x40We should use memmap as it did.
On x86 the impact is limited to x86_32 builds, or x86_64 configurations that override the default setting for SPARSEMEM_VMEMMAP.
Other memory hotplug archs (arm64, ia64, and ppc) also default to SPARSEMEM_VMEMMAP=y.
[[email protected]: changelog update]
{[email protected]: changelog update]
--- mm/sparse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/sparse.c +1 -1
@@ -884,7 +884,7 @@ int __meminit sparse_add_section(int nid* Poison uninitialized struct pages in order to catch invalid flags * combinations. */ -page_init_poison (pfn_to_page (start_pfn),sizeof (struct page ) * nr_pages); +page_init_poison (memmap,sizeof (struct page ) * nr_pages); ms =__nr_to_section (section_nr);set_section_nid (section_nr, nid);
Greg Kroah-Hartman
maintainerPATCH 68/135 lib/stackdepot.c: fix global out-of-bounds in stack_slabs
In reply to Greg Kroah-HartmanFrom: Alexander Potapenko <[email protected]>
commit 305e519ce48e935702c32241f07d393c3c8fed3e upstream.
Walter Wu has reported a potential case in which init_stack_slab() is called after stack_slabs[STACK_ALLOC_MAX_SLABS - 1] has already been initialized. In that case init_stack_slab() will overwrite stack_slabs[STACK_ALLOC_MAX_SLABS], which may result in a memory corruption.
--- lib/stackdepot.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
lib/stackdepot.c +6 -2
@@ -83,15 +83,19 @@ static bool init_stack_slab(void **prealreturn true;if (stack_slabs[depot_index] ==NULL ) { stack_slabs[depot_index] = *prealloc; + *prealloc =NULL ; }else { - stack_slabs[depot_index +1 ] = *prealloc; +/* If this is the last depot slab, do not touch the next one. */ +if (depot_index +1 <STACK_ALLOC_MAX_SLABS ) { + stack_slabs[depot_index +1 ] = *prealloc; + *prealloc =NULL ; + }/* * This smp_store_release pairs with smp_load_acquire() from * |next_slab_inited| above and in stack_depot_save(). */ smp_store_release (&next_slab_inited,1 ); } - *prealloc =NULL ;return true; }
Greg Kroah-Hartman
maintainerPATCH 69/135 mm: Avoid creating virtual address aliases in brk()/mmap()/mremap()
In reply to Greg Kroah-HartmanFrom: Catalin Marinas <[email protected]>
commit dcde237319e626d1ec3c9d8b7613032f0fd4663a upstream.
Currently the arm64 kernel ignores the top address byte passed to brk(), mmap() and mremap(). When the user is not aware of the 56-bit address limit or relies on the kernel to return an error, untagging such pointers has the potential to create address aliases in user-space. Passing a tagged address to munmap(), madvise() is permitted since the tagged pointer is expected to be inside an existing mapping.
The current behaviour breaks the existing glibc malloc() implementation which relies on brk() with an address beyond 56-bit to be rejected by the kernel.
Remove untagging in the above functions by partially reverting commit ce18d171cb73 ("mm: untag user pointers in mmap/munmap/mremap/brk"). In addition, update the arm64 tagged-address-abi.rst document accordingly.
--- Documentation/arm64/tagged-address-abi.rst | 11 +++++++++-- mm/mmap.c | 4 ---- mm/mremap.c | 1 - 3 files changed, 9 insertions(+), 7 deletions(-)
Documentation/arm64/tagged-address-abi.rst +9 -2
@@ -44,8 +44,15 @@ The AArch64 Tagged Address ABI has two s how the user addresses are used by the kernel: 1. User addresses not accessed by the kernel but used for address space - management (e.g. ``mmap()``, ``mprotect()``, ``madvise()``). The use - of valid tagged pointers in this context is always allowed. + management (e.g. ``mprotect()``, ``madvise()``). The use of valid + tagged pointers in this context is allowed with the exception of + ``brk()``, ``mmap()`` and the ``new_address`` argument to + ``mremap()`` as these have the potential to alias with existing + user addresses. + + NOTE: This behaviour changed in v5.6 and so some earlier kernels may + incorrectly accept valid tagged pointers for the ``brk()``, + ``mmap()`` and ``mremap()`` system calls. 2. User addresses accessed by the kernel (e.g. ``write()``). This ABI relaxation is disabled by default and the application thread needs to
mm/mmap.c +0 -4
@@ -195,8 +195,6 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)bool downgraded = false;LIST_HEAD (uf); - brk =untagged_addr (brk); -if (down_write_killable (&mm->mmap_sem))return -EINTR ;
@@ -1583,8 +1581,6 @@ unsigned long ksys_mmap_pgoff(unsigned lstruct file *file =NULL ;unsigned long retval; - addr =untagged_addr (addr); -if (!(flags &MAP_ANONYMOUS )) {audit_mmap_fd (fd, flags); file =fget (fd);
mm/mremap.c +0 -1
@@ -607,7 +607,6 @@ SYSCALL_DEFINE5(mremap, unsigned long, aLIST_HEAD (uf_unmap); addr =untagged_addr (addr); - new_addr =untagged_addr (new_addr);if (flags & ~(MREMAP_FIXED |MREMAP_MAYMOVE ))return ret;
Greg Kroah-Hartman
maintainerPATCH 70/135 drm/amdgpu/soc15: fix xclk for raven
In reply to Greg Kroah-HartmanFrom: Alex Deucher <[email protected]>
commit c657b936ea98630ef5ba4f130ab1ad5c534d0165 upstream.
It's 25 Mhz (refclk / 4). This fixes the interpretation of the rlc clock counter.
--- drivers/gpu/drm/amd/amdgpu/soc15.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/soc15.c +6 -1
@@ -267,7 +267,12 @@ static u32 soc15_get_config_memsize(strustatic u32 soc15_get_xclk (struct amdgpu_device *adev) { -return adev->clock.spll.reference_freq; +u32 reference_clock = adev->clock.spll.reference_freq; + +if (adev->asic_type ==CHIP_RAVEN ) +return reference_clock /4 ; + +return reference_clock; }
Greg Kroah-Hartman
maintainerPATCH 71/135 drm/amdgpu/gfx9: disable gfxoff when reading rlc clock
In reply to Greg Kroah-HartmanFrom: Alex Deucher <[email protected]>
commit 120cf959308e1bda984e40a9edd25ee2d6262efd upstream.
Otherwise we readback all ones. Fixes rlc counter readback while gfxoff is active.
--- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +2 -0
@@ -4080,11 +4080,13 @@ static uint64_t gfx_v9_0_get_gpu_clock_c {uint64_t clock; +amdgpu_gfx_off_ctrl (adev, false);mutex_lock (&adev->gfx.gpu_clock_mutex);WREG32_SOC15 (GC ,0 , mmRLC_CAPTURE_GPU_CLOCK_COUNT,1 ); clock = (uint64_t )RREG32_SOC15 (GC ,0 , mmRLC_GPU_CLOCK_COUNT_LSB) | ((uint64_t )RREG32_SOC15 (GC ,0 , mmRLC_GPU_CLOCK_COUNT_MSB) <<32ULL );mutex_unlock (&adev->gfx.gpu_clock_mutex); +amdgpu_gfx_off_ctrl (adev, true);return clock; }
Greg Kroah-Hartman
maintainerPATCH 72/135 drm/amdgpu/gfx10: disable gfxoff when reading rlc clock
In reply to Greg Kroah-HartmanFrom: Alex Deucher <[email protected]>
commit b08c3ed609aabc4e76e74edc4404f0c26279d7ed upstream.
Otherwise we readback all ones. Fixes rlc counter readback while gfxoff is active.
--- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +2 -0
@@ -3977,11 +3977,13 @@ static uint64_t gfx_v10_0_get_gpu_clock_ {uint64_t clock; +amdgpu_gfx_off_ctrl (adev, false);mutex_lock (&adev->gfx.gpu_clock_mutex);WREG32_SOC15 (GC ,0 , mmRLC_CAPTURE_GPU_CLOCK_COUNT,1 ); clock = (uint64_t )RREG32_SOC15 (GC ,0 , mmRLC_GPU_CLOCK_COUNT_LSB) | ((uint64_t )RREG32_SOC15 (GC ,0 , mmRLC_GPU_CLOCK_COUNT_MSB) <<32ULL );mutex_unlock (&adev->gfx.gpu_clock_mutex); +amdgpu_gfx_off_ctrl (adev, true);return clock; }
Greg Kroah-Hartman
maintainerPATCH 73/135 drm/nouveau/kms/gv100-: Re-set LUT after clearing for modesets
In reply to Greg Kroah-HartmanFrom: Lyude Paul <[email protected]>
commit f287d3d19769b1d22cba4e51fa0487f2697713c9 upstream.
While certain modeset operations on gv100+ need us to temporarily disable the LUT, we make the mistake of sometimes neglecting to reprogram the LUT after such modesets. In particular, moving a head from one encoder to another seems to trigger this quite often. GV100+ is very picky about having a LUT in most scenarios, so this causes the display engine to hang with the following error code:
disp: chid 1 stat 00005080 reason 5 [INVALID_STATE] mthd 0200 data 00000001 code 0000002d)
So, fix this by always re-programming the LUT if we're clearing it in a state where the wndw is still visible, and has a XLUT handle programmed.
--- drivers/gpu/drm/nouveau/dispnv50/wndw.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/nouveau/dispnv50/wndw.c +2 -0
@@ -451,6 +451,8 @@ nv50_wndw_atomic_check(struct drm_plane asyw->clr.ntfy = armw->ntfy.handle !=0 ; asyw->clr.sema = armw->sema.handle !=0 ; asyw->clr.xlut = armw->xlut.handle !=0 ; +if (asyw->clr.xlut && asyw->visible) + asyw->set.xlut = asyw->xlut.handle !=0 ; asyw->clr.csc = armw->csc.valid;if (wndw->func->image_clr) asyw->clr.image = armw->image.handle[0 ] !=0 ;
Greg Kroah-Hartman
maintainerPATCH 74/135 drm/i915: Wean off drm_pci_alloc/drm_pci_free
In reply to Greg Kroah-HartmanFrom: Chris Wilson <[email protected]>
commit aa3146193ae25d0fe4b96d815169a135db2e8f01 upstream.
drm_pci_alloc and drm_pci_free are just very thin wrappers around dma_alloc_coherent, with a note that we should be removing them. Furthermore since
commit de09d31dd38a50fdce106c15abd68432eebbd014
Author: Kirill A. Shutemov <[email protected]> Date: Fri Jan 15 16:51:42 2016 -0800
page-flags: define PG_reserved behavior on compound pages
As far as I can see there's no users of PG_reserved on compound pages. Let's use PF_NO_COMPOUND here.
drm_pci_alloc has been declared broken since it mixes GFP_COMP and SetPageReserved. Avoid this conflict by weaning ourselves off using the abstraction and using the dma functions directly.
--- drivers/gpu/drm/i915/display/intel_display.c | 2 drivers/gpu/drm/i915/gem/i915_gem_object_types.h | 3 drivers/gpu/drm/i915/gem/i915_gem_phys.c | 98 +++++++++++------------ drivers/gpu/drm/i915/i915_gem.c | 8 - 4 files changed, 55 insertions(+), 56 deletions(-)
drivers/gpu/drm/i915/display/intel_display.c +1 -1
@@ -10510,7 +10510,7 @@ static u32 intel_cursor_base(const strucu32 base;if (INTEL_INFO (dev_priv)->display.cursor_needs_physical) - base = obj->phys_handle->busaddr; + base =sg_dma_address (obj->mm.pages->sgl);else base =intel_plane_ggtt_offset (plane_state);
drivers/gpu/drm/i915/gem/i915_gem_object_types.h +0 -3
@@ -240,9 +240,6 @@ struct drm_i915_gem_object {void *gvt_info; }; - -/** for phys allocated objects */ -struct drm_dma_handle *phys_handle; }; static inline struct drm_i915_gem_object *
drivers/gpu/drm/i915/gem/i915_gem_phys.c +50 -48
160 lines not on this page · raw message
drivers/gpu/drm/i915/i915_gem.c +4 -4
@@ -136,7 +136,7 @@ i915_gem_phys_pwrite(struct drm_i915_gemstruct drm_i915_gem_pwrite *args, struct drm_file *file) { - void *vaddr = obj->phys_handle->vaddr + args->offset; + void *vaddr = sg_page(obj->mm.pages->sgl) + args->offset;char __user *user_data =u64_to_user_ptr (args->data_ptr);/*
@@ -802,10 +802,10 @@ i915_gem_pwrite_ioctl(struct drm_device ret =i915_gem_gtt_pwrite_fast (obj, args);if (ret == -EFAULT || ret == -ENOSPC ) { -if (obj->phys_handle) - ret =i915_gem_phys_pwrite (obj, args, file); -else +if (i915_gem_object_has_struct_page (obj)) ret =i915_gem_shmem_pwrite (obj, args); +else + ret =i915_gem_phys_pwrite (obj, args, file); }i915_gem_object_unpin_pages (obj);
Greg Kroah-Hartman
maintainerPATCH 75/135 drm/i915: Update drm/i915 bug filing URL
In reply to Greg Kroah-HartmanFrom: Jani Nikula <[email protected]>
commit 7ddc7005a0aa2f43a826b71f5d6bd7d4b90f8f2a upstream.
We've moved from bugzilla to gitlab.
--- drivers/gpu/drm/i915/Kconfig | 5 ++--- drivers/gpu/drm/i915/i915_gpu_error.c | 3 ++- drivers/gpu/drm/i915/i915_utils.c | 5 ++--- 3 files changed, 6 insertions(+), 7 deletions(-)
drivers/gpu/drm/i915/Kconfig +2 -3
@@ -75,9 +75,8 @@ config DRM_I915_CAPTURE_ERROR help This option enables capturing the GPU state when a hang is detected. This information is vital for triaging hangs and assists in debugging. - Please report any hang to - https://bugs.freedesktop.org/enter_bug.cgi?product=DRI - for triaging. + Please report any hang for triaging according to: + https://gitlab.freedesktop.org/drm/intel/-/wikis/How-to-file-i915-bugs If in doubt, say "Y".
drivers/gpu/drm/i915/i915_gpu_error.c +2 -1
@@ -1768,7 +1768,8 @@ void i915_capture_error_state(struct drmif (!xchg (&warned, true) &&ktime_get_real_seconds () -DRIVER_TIMESTAMP <DAY_AS_SECONDS (180 )) {pr_info ("GPU hangs can indicate a bug anywhere in the entire gfx stack, including userspace.\n" ); -pr_info ("Please file a _new_ bug report on bugs.freedesktop.org against DRI -> DRM/Intel\n" ); +pr_info ("Please file a _new_ bug report at https://gitlab.freedesktop.org/drm/intel/issues/new.\n" ); +pr_info ("Please see https://gitlab.freedesktop.org/drm/intel/-/wikis/How-to-file-i915-bugs for details.\n" );pr_info ("drm/i915 developers can then reassign to the right component if it's not a kernel issue.\n" );pr_info ("The GPU crash dump is required to analyze GPU hangs, so please always attach it.\n" ); pr_info("GPU crash dump saved to /sys/class/drm/card%d/error\n",
drivers/gpu/drm/i915/i915_utils.c +2 -3
@@ -8,9 +8,8 @@#include "i915_drv.h" #include "i915_utils.h" -#define FDO_BUG_URL "https://bugs.freedesktop.org/enter_bug.cgi?product=DRI" -#define FDO_BUG_MSG "Please file a bug at " FDO_BUG_URL " against DRM/Intel " \ - "providing the dmesg log by booting with drm.debug=0xf" +#define FDO_BUG_URL "https://gitlab.freedesktop.org/drm/intel/-/wikis/How-to-file-i915-bugs" +#define FDO_BUG_MSG "Please file a bug on drm/i915; see " FDO_BUG_URL " for details." void __i915_printk(struct drm_i915_private *dev_priv, const char *level,
Greg Kroah-Hartman
maintainerPATCH 76/135 sched/psi: Fix OOB write when writing 0 bytes to PSI files
In reply to Greg Kroah-HartmanFrom: Suren Baghdasaryan <[email protected]>
commit 6fcca0fa48118e6d63733eb4644c6cd880c15b8f upstream.
Issuing write() with count parameter set to 0 on any file under /proc/pressure/ will cause an OOB write because of the access to buf[buf_size-1] when NUL-termination is performed. Fix this by checking for buf_size to be non-zero.
--- kernel/sched/psi.c | 3 +++ 1 file changed, 3 insertions(+)
kernel/sched/psi.c +3 -0
@@ -1199,6 +1199,9 @@ static ssize_t psi_write(struct file *fiif (static_branch_likely (&psi_disabled))return -EOPNOTSUPP ; +if (!nbytes) +return -EINVAL ; + buf_size =min (nbytes,sizeof (buf));if (copy_from_user (buf, user_buf, buf_size))return -EFAULT ;
Greg Kroah-Hartman
maintainerPATCH 77/135 KVM: nVMX: Dont emulate instructions in guest mode
In reply to Greg Kroah-HartmanFrom: Paolo Bonzini <[email protected]>
commit 07721feee46b4b248402133228235318199b05ec upstream.
vmx_check_intercept is not yet fully implemented. To avoid emulating instructions disallowed by the L1 hypervisor, refuse to emulate instructions by default.
--- arch/x86/kvm/vmx/vmx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/vmx/vmx.c +1 -1
@@ -7151,7 +7151,7 @@ static int vmx_check_intercept(struct kv }/* TODO: check more intercepts... */ -return X86EMUL_CONTINUE ; +return X86EMUL_UNHANDLEABLE ; }#ifdef CONFIG_X86_64
Greg Kroah-Hartman
maintainerPATCH 78/135 KVM: x86: dont notify userspace IOAPIC on edge-triggered interrupt EOI
In reply to Greg Kroah-HartmanFrom: Miaohe Lin <[email protected]>
commit 7455a8327674e1a7c9a1f5dd1b0743ab6713f6d1 upstream.
Commit 13db77347db1 ("KVM: x86: don't notify userspace IOAPIC on edge EOI") said, edge-triggered interrupts don't set a bit in TMR, which means that IOAPIC isn't notified on EOI. And var level indicates level-triggered interrupt.
But commit 3159d36ad799 ("KVM: x86: use generic function for MSI parsing") replace var level with irq.level by mistake. Fix it by changing irq.level to irq.trig_mode.
--- arch/x86/kvm/irq_comm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/irq_comm.c +1 -1
@@ -416,7 +416,7 @@ void kvm_scan_ioapic_routes(struct kvm_vkvm_set_msi_irq (vcpu->kvm, entry, &irq); -if (irq.level &&kvm_apic_match_dest (vcpu,NULL ,0 , +if (irq.trig_mode &&kvm_apic_match_dest (vcpu,NULL ,0 , irq.dest_id, irq.dest_mode))__set_bit (irq.vector, ioapic_handled_vectors); }
Greg Kroah-Hartman
maintainerPATCH 79/135 ext4: fix a data race in EXT4_I(inode)->i_disksize
In reply to Greg Kroah-HartmanFrom: Qian Cai <[email protected]>
commit 35df4299a6487f323b0aca120ea3f485dfee2ae3 upstream.
EXT4_I(inode)->i_disksize could be accessed concurrently as noticed by KCSAN,
BUG: KCSAN: data-race in ext4_write_end [ext4] / ext4_writepages [ext4]
write to 0xffff91c6713b00f8 of 8 bytes by task 49268 on cpu 127:
ext4_write_end+0x4e3/0x750 [ext4] ext4_update_i_disksize at fs/ext4/ext4.h:3032 (inlined by) ext4_update_inode_size at fs/ext4/ext4.h:3046 (inlined by) ext4_write_end at fs/ext4/inode.c:1287 generic_perform_write+0x208/0x2a0 ext4_buffered_write_iter+0x11f/0x210 [ext4] ext4_file_write_iter+0xce/0x9e0 [ext4] new_sync_write+0x29c/0x3b0 __vfs_write+0x92/0xa0 vfs_write+0x103/0x260 ksys_write+0x9d/0x130 __x64_sys_write+0x4c/0x60 do_syscall_64+0x91/0xb47 entry_SYSCALL_64_after_hwframe+0x49/0xbe
read to 0xffff91c6713b00f8 of 8 bytes by task 24872 on cpu 37:
ext4_writepages+0x10ac/0x1d00 [ext4] mpage_map_and_submit_extent at fs/ext4/inode.c:2468 (inlined by) ext4_writepages at fs/ext4/inode.c:2772 do_writepages+0x5e/0x130 __writeback_single_inode+0xeb/0xb20 writeback_sb_inodes+0x429/0x900 __writeback_inodes_wb+0xc4/0x150 wb_writeback+0x4bd/0x870 wb_workfn+0x6b4/0x960 process_one_work+0x54c/0xbe0 worker_thread+0x80/0x650 kthread+0x1e0/0x200 ret_from_fork+0x27/0x50
Reported by Kernel Concurrency Sanitizer on:
CPU: 37 PID: 24872 Comm: kworker/u261:2 Tainted: G W O L 5.5.0-next-20200204+ #5 Hardware name: HPE ProLiant DL385 Gen10/ProLiant DL385 Gen10, BIOS A40 07/10/2019 Workqueue: writeback wb_workfn (flush-7:0)
Since only the read is operating as lockless (outside of the "i_data_sem"), load tearing could introduce a logic bug. Fix it by adding READ_ONCE() for the read and WRITE_ONCE() for the write.
--- fs/ext4/ext4.h | 2 +- fs/ext4/inode.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
fs/ext4/ext4.h +1 -1
@@ -2969,7 +2969,7 @@ static inline void ext4_update_i_disksiz !inode_is_locked(inode));down_write (&EXT4_I (inode)->i_data_sem);if (newsize >EXT4_I (inode)->i_disksize) -EXT4_I (inode)->i_disksize = newsize; +WRITE_ONCE (EXT4_I (inode)->i_disksize, newsize);up_write (&EXT4_I (inode)->i_data_sem); }
fs/ext4/inode.c +1 -1
@@ -2573,7 +2573,7 @@ update_disksize:* truncate are avoided by checking i_size under i_data_sem. */ disksize = ((loff_t )mpd->first_page) <<PAGE_SHIFT ; -if (disksize >EXT4_I (inode)->i_disksize) { +if (disksize >READ_ONCE (EXT4_I (inode)->i_disksize)) {int err2;loff_t i_size;
Greg Kroah-Hartman
maintainerPATCH 80/135 ext4: add cond_resched() to __ext4_find_entry()
In reply to Greg Kroah-HartmanFrom: Shijie Luo <[email protected]>
commit 9424ef56e13a1f14c57ea161eed3ecfdc7b2770e upstream.
We tested a soft lockup problem in linux 4.19 which could also be found in linux 5.x.
When dir inode takes up a large number of blocks, and if the directory is growing when we are searching, it's possible the restart branch could be called many times, and the do while loop could hold cpu a long time.
Here is the call trace in linux 4.19.
[ 473.756186] Call trace: [ 473.756196] dump_backtrace+0x0/0x198 [ 473.756199] show_stack+0x24/0x30 [ 473.756205] dump_stack+0xa4/0xcc [ 473.756210] watchdog_timer_fn+0x300/0x3e8 [ 473.756215] __hrtimer_run_queues+0x114/0x358 [ 473.756217] hrtimer_interrupt+0x104/0x2d8 [ 473.756222] arch_timer_handler_virt+0x38/0x58 [ 473.756226] handle_percpu_devid_irq+0x90/0x248 [ 473.756231] generic_handle_irq+0x34/0x50 [ 473.756234] __handle_domain_irq+0x68/0xc0 [ 473.756236] gic_handle_irq+0x6c/0x150 [ 473.756238] el1_irq+0xb8/0x140 [ 473.756286] ext4_es_lookup_extent+0xdc/0x258 [ext4] [ 473.756310] ext4_map_blocks+0x64/0x5c0 [ext4] [ 473.756333] ext4_getblk+0x6c/0x1d0 [ext4] [ 473.756356] ext4_bread_batch+0x7c/0x1f8 [ext4] [ 473.756379] ext4_find_entry+0x124/0x3f8 [ext4] [ 473.756402] ext4_lookup+0x8c/0x258 [ext4] [ 473.756407] __lookup_hash+0x8c/0xe8 [ 473.756411] filename_create+0xa0/0x170 [ 473.756413] do_mkdirat+0x6c/0x140 [ 473.756415] __arm64_sys_mkdirat+0x28/0x38 [ 473.756419] el0_svc_common+0x78/0x130 [ 473.756421] el0_svc_handler+0x38/0x78 [ 473.756423] el0_svc+0x8/0xc [ 485.755156] watchdog: BUG: soft lockup - CPU#2 stuck for 22s! [tmp:5149]
Add cond_resched() to avoid soft lockup and to provide a better system responding.
--- fs/ext4/namei.c | 1 + 1 file changed, 1 insertion(+)
fs/ext4/namei.c +1 -0
@@ -1507,6 +1507,7 @@ restart:/* * We deal with the read-ahead logic here. */ +cond_resched ();if (ra_ptr >= ra_max) {/* Refill the readahead buffer */ ra_ptr =0 ;
Greg Kroah-Hartman
maintainerPATCH 81/135 ext4: fix potential race between online resizing and write operations
In reply to Greg Kroah-HartmanFrom: Theodore Ts'o <[email protected]>
commit 1d0c3924a92e69bfa91163bda83c12a994b4d106 upstream.
During an online resize an array of pointers to buffer heads gets replaced so it can get enlarged. If there is a racing block allocation or deallocation which uses the old array, and the old array has gotten reused this can lead to a GPF or some other random kernel memory getting modified.
--- fs/ext4/balloc.c | 14 +++++++++++--- fs/ext4/ext4.h | 20 +++++++++++++++++++- fs/ext4/resize.c | 55 ++++++++++++++++++++++++++++++++++++++++++++----------- fs/ext4/super.c | 33 +++++++++++++++++++++++---------- 4 files changed, 97 insertions(+), 25 deletions(-)
fs/ext4/balloc.c +11 -3
@@ -270,6 +270,7 @@ struct ext4_group_desc * ext4_get_group_ext4_group_t ngroups =ext4_get_groups_count (sb);struct ext4_group_desc *desc;struct ext4_sb_info *sbi =EXT4_SB (sb); +struct buffer_head *bh_p;if (block_group >= ngroups) { ext4_error(sb, "block_group >= groups_count - block_group = %u,"
@@ -280,7 +281,14 @@ struct ext4_group_desc * ext4_get_group_ group_desc = block_group >>EXT4_DESC_PER_BLOCK_BITS (sb); offset = block_group & (EXT4_DESC_PER_BLOCK (sb) -1 ); -if (!sbi->s_group_desc[group_desc]) { + bh_p =sbi_array_rcu_deref (sbi, s_group_desc, group_desc); +/* +* sbi_array_rcu_deref returns with rcu unlocked, this is ok since +* the pointer being dereferenced won't be dereferenced again. By +* looking at the usage in add_new_gdb() the value isn't modified, +* just the pointer, and so it remains valid. +*/ +if (!bh_p) {ext4_error (sb,"Group descriptor not loaded - " "block_group = %u, group_desc = %u, desc = %u" , block_group, group_desc, offset);
@@ -288,10 +296,10 @@ struct ext4_group_desc * ext4_get_group_ } desc = (struct ext4_group_desc *)( - (__u8 *)sbi->s_group_desc[group_desc]->b_data + + (__u8 *)bh_p->b_data + offset *EXT4_DESC_SIZE (sb));if (bh) - *bh = sbi->s_group_desc[group_desc]; + *bh = bh_p;return desc; }
fs/ext4/ext4.h +19 -1
@@ -1396,7 +1396,7 @@ struct ext4_sb_info {loff_t s_bitmap_maxbytes;/* max bytes for bitmap files */ struct buffer_head * s_sbh;/* Buffer containing the super block */ struct ext4_super_block *s_es;/* Pointer to the super block in the buffer */ -struct buffer_head **s_group_desc; +struct buffer_head *__rcu *s_group_desc;unsigned int s_mount_opt;unsigned int s_mount_opt2;unsigned int s_mount_flags;
@@ -1570,6 +1570,23 @@ static inline int ext4_valid_inum(struct }/* +* Returns: sbi->field[index] +* Used to access an array element from the following sbi fields which require +* rcu protection to avoid dereferencing an invalid pointer due to reassignment +* - s_group_desc +* - s_group_info +* - s_flex_group +*/ +#define sbi_array_rcu_deref (sbi, field, index) \ +({ \ + typeof(*((sbi)->field)) _v; \ + rcu_read_lock(); \ + _v = ((typeof(_v)*)rcu_dereference((sbi)->field))[index]; \ + rcu_read_unlock(); \ + _v; \ +}) + +/* * Inode dynamic state flags */ enum {
@@ -2666,6 +2683,7 @@ extern int ext4_generic_delete_entry(hanextern bool ext4_empty_dir (struct inode *inode);/* resize.c */ +extern void ext4_kvfree_array_rcu (void *to_free);extern int ext4_group_add (struct super_block *sb,struct ext4_new_group_data *input); extern int ext4_group_extend(struct super_block *sb,
fs/ext4/resize.c +44 -11
110 lines not on this page · raw message
fs/ext4/super.c +23 -10
@@ -970,6 +970,7 @@ static void ext4_put_super(struct super_ {struct ext4_sb_info *sbi =EXT4_SB (sb);struct ext4_super_block *es = sbi->s_es; +struct buffer_head **group_desc;int aborted =0 ;int i, err;
@@ -1000,9 +1001,12 @@ static void ext4_put_super(struct super_if (!sb_rdonly (sb))ext4_commit_super (sb,1 ); +rcu_read_lock (); + group_desc =rcu_dereference (sbi->s_group_desc);for (i =0 ; i < sbi->s_gdb_count; i++) -brelse (sbi->s_group_desc[i]); -kvfree (sbi->s_group_desc); +brelse (group_desc[i]); +kvfree (group_desc); +rcu_read_unlock ();kvfree (sbi->s_flex_groups);percpu_counter_destroy (&sbi->s_freeclusters_counter);percpu_counter_destroy (&sbi->s_freeinodes_counter);
@@ -3586,7 +3590,7 @@ static int ext4_fill_super(struct super_ {struct dax_device *dax_dev =fs_dax_get_by_bdev (sb->s_bdev);char *orig_data =kstrdup (data,GFP_KERNEL ); -struct buffer_head *bh; +struct buffer_head *bh, **group_desc;struct ext4_super_block *es =NULL ;struct ext4_sb_info *sbi =kzalloc (sizeof (*sbi),GFP_KERNEL );ext4_fsblk_t block;
@@ -4242,9 +4246,10 @@ static int ext4_fill_super(struct super_ goto failed_mount; } } - sbi->s_group_desc =kvmalloc_array (db_count, -sizeof (struct buffer_head *), -GFP_KERNEL ); +rcu_assign_pointer (sbi->s_group_desc, +kvmalloc_array (db_count, +sizeof (struct buffer_head *), +GFP_KERNEL ));if (sbi->s_group_desc ==NULL ) {ext4_msg (sb,KERN_ERR ,"not enough memory" ); ret = -ENOMEM ;
@@ -4260,14 +4265,19 @@ static int ext4_fill_super(struct super_ }for (i =0 ; i < db_count; i++) { +struct buffer_head *bh; + block =descriptor_loc (sb, logical_sb_block, i); - sbi->s_group_desc[i] =sb_bread_unmovable (sb, block); -if (!sbi->s_group_desc[i]) { + bh =sb_bread_unmovable (sb, block); +if (!bh) {ext4_msg (sb,KERN_ERR ,"can't read group descriptor %d" , i); db_count = i; goto failed_mount2; } +rcu_read_lock (); +rcu_dereference (sbi->s_group_desc)[i] = bh; +rcu_read_unlock (); } sbi->s_gdb_count = db_count;if (!ext4_check_descriptors (sb, logical_sb_block, &first_not_zeroed)) {
@@ -4676,9 +4686,12 @@ failed_mount3:if (sbi->s_mmp_tsk)kthread_stop (sbi->s_mmp_tsk); failed_mount2: +rcu_read_lock (); + group_desc =rcu_dereference (sbi->s_group_desc);for (i =0 ; i < db_count; i++) -brelse (sbi->s_group_desc[i]); -kvfree (sbi->s_group_desc); +brelse (group_desc[i]); +kvfree (group_desc); +rcu_read_unlock (); failed_mount:if (sbi->s_chksum_driver)crypto_free_shash (sbi->s_chksum_driver);
Greg Kroah-Hartman
maintainerPATCH 82/135 ext4: fix potential race between s_group_info online resizing and access
In reply to Greg Kroah-HartmanFrom: Suraj Jitindar Singh <[email protected]>
commit df3da4ea5a0fc5d115c90d5aa6caa4dd433750a7 upstream.
During an online resize an array of pointers to s_group_info gets replaced so it can get enlarged. If there is a concurrent access to the array in ext4_get_group_info() and this memory has been reused then this can lead to an invalid memory access.
--- fs/ext4/ext4.h | 8 ++++---- fs/ext4/mballoc.c | 52 +++++++++++++++++++++++++++++++++++----------------- 2 files changed, 39 insertions(+), 21 deletions(-)
fs/ext4/ext4.h +4 -4
@@ -1458,7 +1458,7 @@ struct ext4_sb_info {#endif /* for buddy allocator */ -struct ext4_group_info ***s_group_info; +struct ext4_group_info **__rcu *s_group_info;struct inode *s_buddy_cache;spinlock_t s_md_lock;unsigned short *s_mb_offsets;
@@ -2931,13 +2931,13 @@ static inlinestruct ext4_group_info *ext4_get_group_info (struct super_block *sb,ext4_group_t group) { -struct ext4_group_info ***grp_info; +struct ext4_group_info **grp_info;long indexv, indexh;BUG_ON (group >=EXT4_SB (sb)->s_groups_count); - grp_info =EXT4_SB (sb)->s_group_info; indexv = group >> (EXT4_DESC_PER_BLOCK_BITS (sb)); indexh = group & ((EXT4_DESC_PER_BLOCK (sb)) -1 ); -return grp_info[indexv][indexh]; + grp_info =sbi_array_rcu_deref (EXT4_SB (sb), s_group_info, indexv); +return grp_info[indexh]; }/*
fs/ext4/mballoc.c +35 -17
114 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 83/135 ext4: fix potential race between s_flex_groups online resizing and access
In reply to Greg Kroah-HartmanFrom: Suraj Jitindar Singh <[email protected]>
commit 7c990728b99ed6fbe9c75fc202fce1172d9916da upstream.
During an online resize an array of s_flex_groups structures gets replaced so it can get enlarged. If there is a concurrent access to the array and this memory has been reused then this can lead to an invalid memory access.
The s_flex_group array has been converted into an array of pointers rather than an array of structures. This is to ensure that the information contained in the structures cannot get out of sync during a resize due to an accessor updating the value in the old structure after it has been copied but before the array pointer is updated. Since the structures them- selves are no longer copied but only the pointers to them this case is mitigated.
--- fs/ext4/ext4.h | 2 - fs/ext4/ialloc.c | 23 ++++++++++------- fs/ext4/mballoc.c | 9 ++++-- fs/ext4/resize.c | 7 +++-- fs/ext4/super.c | 72 +++++++++++++++++++++++++++++++++++++----------------- 5 files changed, 76 insertions(+), 37 deletions(-)
fs/ext4/ext4.h +1 -1
@@ -1508,7 +1508,7 @@ struct ext4_sb_info {unsigned int s_extent_max_zeroout_kb;unsigned int s_log_groups_per_flex; -struct flex_groups *s_flex_groups; +struct flex_groups *__rcu *s_flex_groups;ext4_group_t s_flex_groups_allocated;/* workqueue for reserved extent conversions (buffered io) */
fs/ext4/ialloc.c +14 -9
@@ -325,11 +325,13 @@ void ext4_free_inode(handle_t *handle, spercpu_counter_inc (&sbi->s_freeinodes_counter);if (sbi->s_log_groups_per_flex) { -ext4_group_t f =ext4_flex_group (sbi, block_group); +struct flex_groups *fg; -atomic_inc (&sbi->s_flex_groups[f].free_inodes); + fg =sbi_array_rcu_deref (sbi, s_flex_groups, +ext4_flex_group (sbi, block_group)); +atomic_inc (&fg->free_inodes);if (is_directory) -atomic_dec (&sbi->s_flex_groups[f].used_dirs); +atomic_dec (&fg->used_dirs); }BUFFER_TRACE (bh2,"call ext4_handle_dirty_metadata" ); fatal =ext4_handle_dirty_metadata (handle,NULL , bh2);
@@ -365,12 +367,13 @@ static void get_orlov_stats(struct super int flex_size, struct orlov_stats *stats) { struct ext4_group_desc *desc; -struct flex_groups *flex_group =EXT4_SB (sb)->s_flex_groups;if (flex_size >1 ) { - stats->free_inodes =atomic_read (&flex_group[g].free_inodes); - stats->free_clusters =atomic64_read (&flex_group[g].free_clusters); - stats->used_dirs =atomic_read (&flex_group[g].used_dirs); +struct flex_groups *fg =sbi_array_rcu_deref (EXT4_SB (sb), + s_flex_groups, g); + stats->free_inodes =atomic_read (&fg->free_inodes); + stats->free_clusters =atomic64_read (&fg->free_clusters); + stats->used_dirs =atomic_read (&fg->used_dirs);return ; }
@@ -1051,7 +1054,8 @@ got:if (sbi->s_log_groups_per_flex) {ext4_group_t f =ext4_flex_group (sbi, group); -atomic_inc (&sbi->s_flex_groups[f].used_dirs); +atomic_inc (&sbi_array_rcu_deref (sbi, s_flex_groups, + f)->used_dirs); } }if (ext4_has_group_desc_csum (sb)) {
@@ -1074,7 +1078,8 @@ got:if (sbi->s_log_groups_per_flex) { flex_group =ext4_flex_group (sbi, group); -atomic_dec (&sbi->s_flex_groups[flex_group].free_inodes); +atomic_dec (&sbi_array_rcu_deref (sbi, s_flex_groups, + flex_group)->free_inodes); } inode->i_ino = ino + group *EXT4_INODES_PER_GROUP (sb);
fs/ext4/mballoc.c +6 -3
@@ -3038,7 +3038,8 @@ ext4_mb_mark_diskspace_used(struct ext4_ext4_group_t flex_group =ext4_flex_group (sbi, ac->ac_b_ex.fe_group);atomic64_sub (ac->ac_b_ex.fe_len, - &sbi->s_flex_groups[flex_group].free_clusters); + &sbi_array_rcu_deref (sbi, s_flex_groups, + flex_group)->free_clusters); } err =ext4_handle_dirty_metadata (handle,NULL , bitmap_bh);
@@ -4932,7 +4933,8 @@ do_more:if (sbi->s_log_groups_per_flex) {ext4_group_t flex_group =ext4_flex_group (sbi, block_group);atomic64_add (count_clusters, - &sbi->s_flex_groups[flex_group].free_clusters); + &sbi_array_rcu_deref (sbi, s_flex_groups, + flex_group)->free_clusters); }/*
@@ -5089,7 +5091,8 @@ int ext4_group_add_blocks(handle_t *handif (sbi->s_log_groups_per_flex) {ext4_group_t flex_group =ext4_flex_group (sbi, block_group);atomic64_add (clusters_freed, - &sbi->s_flex_groups[flex_group].free_clusters); + &sbi_array_rcu_deref (sbi, s_flex_groups, + flex_group)->free_clusters); }ext4_mb_unload_buddy (&e4b);
fs/ext4/resize.c +5 -2
@@ -1452,11 +1452,14 @@ static void ext4_update_super(struct sup percpu_counter_read(&sbi->s_freeclusters_counter));if (ext4_has_feature_flex_bg (sb) && sbi->s_log_groups_per_flex) {ext4_group_t flex_group; +struct flex_groups *fg; + flex_group =ext4_flex_group (sbi, group_data[0 ].group); + fg =sbi_array_rcu_deref (sbi, s_flex_groups, flex_group);atomic64_add (EXT4_NUM_B2C (sbi, free_blocks), - &sbi->s_flex_groups[flex_group].free_clusters); + &fg->free_clusters);atomic_add (EXT4_INODES_PER_GROUP (sb) * flex_gd->count, - &sbi->s_flex_groups[flex_group].free_inodes); + &fg->free_inodes); }/*
fs/ext4/super.c +50 -22
126 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 84/135 ext4: fix mount failure with quota configured as module
In reply to Greg Kroah-HartmanFrom: Jan Kara <[email protected]>
commit 9db176bceb5c5df4990486709da386edadc6bd1d upstream.
When CONFIG_QFMT_V2 is configured as a module, the test in ext4_feature_set_ok() fails and so mount of filesystems with quota or project features fails. Fix the test to use IS_ENABLED macro which works properly even for modules.
--- fs/ext4/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ext4/super.c +1 -1
@@ -2986,7 +2986,7 @@ static int ext4_feature_set_ok(struct sureturn 0 ; } -#if !defined(CONFIG_QUOTA ) || !defined(CONFIG_QFMT_V2 ) +#if !IS_ENABLED (CONFIG_QUOTA ) || !IS_ENABLED (CONFIG_QFMT_V2 )if (!readonly && (ext4_has_feature_quota (sb) ||ext4_has_feature_project (sb))) { ext4_msg(sb, KERN_ERR,
Greg Kroah-Hartman
maintainerPATCH 85/135 ext4: rename s_journal_flag_rwsem to s_writepages_rwsem
In reply to Greg Kroah-HartmanFrom: Eric Biggers <[email protected]>
commit bbd55937de8f2754adc5792b0f8e5ff7d9c0420e upstream.
In preparation for making s_journal_flag_rwsem synchronize ext4_writepages() with changes to both the EXTENTS and JOURNAL_DATA flags (rather than just JOURNAL_DATA as it does currently), rename it to s_writepages_rwsem.
--- fs/ext4/ext4.h | 2 +- fs/ext4/inode.c | 14 +++++++------- fs/ext4/super.c | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-)
fs/ext4/ext4.h +1 -1
@@ -1549,7 +1549,7 @@ struct ext4_sb_info {struct ratelimit_state s_msg_ratelimit_state;/* Barrier between changing inodes' journal flags and writepages ops. */ -struct percpu_rw_semaphore s_journal_flag_rwsem; +struct percpu_rw_semaphore s_writepages_rwsem;struct dax_device *s_daxdev; };
fs/ext4/inode.c +7 -7
@@ -2734,7 +2734,7 @@ static int ext4_writepages(struct addresif (unlikely (ext4_forced_shutdown (EXT4_SB (inode->i_sb))))return -EIO ; -percpu_down_read (&sbi->s_journal_flag_rwsem); +percpu_down_read (&sbi->s_writepages_rwsem);trace_ext4_writepages (inode, wbc);/*
@@ -2955,7 +2955,7 @@ unplug: out_writepages:trace_ext4_writepages_result (inode, wbc, ret, nr_to_write - wbc->nr_to_write); -percpu_up_read (&sbi->s_journal_flag_rwsem); +percpu_up_read (&sbi->s_writepages_rwsem);return ret; }
@@ -2970,13 +2970,13 @@ static int ext4_dax_writepages(struct adif (unlikely (ext4_forced_shutdown (EXT4_SB (inode->i_sb))))return -EIO ; -percpu_down_read (&sbi->s_journal_flag_rwsem); +percpu_down_read (&sbi->s_writepages_rwsem);trace_ext4_writepages (inode, wbc); ret =dax_writeback_mapping_range (mapping, inode->i_sb->s_bdev, wbc);trace_ext4_writepages_result (inode, wbc, ret, nr_to_write - wbc->nr_to_write); -percpu_up_read (&sbi->s_journal_flag_rwsem); +percpu_up_read (&sbi->s_writepages_rwsem);return ret; }
@@ -6185,7 +6185,7 @@ int ext4_change_inode_journal_flag(struc } } -percpu_down_write (&sbi->s_journal_flag_rwsem); +percpu_down_write (&sbi->s_writepages_rwsem);jbd2_journal_lock_updates (journal);/*
@@ -6202,7 +6202,7 @@ int ext4_change_inode_journal_flag(struc err =jbd2_journal_flush (journal);if (err <0 ) {jbd2_journal_unlock_updates (journal); -percpu_up_write (&sbi->s_journal_flag_rwsem); +percpu_up_write (&sbi->s_writepages_rwsem);return err; }ext4_clear_inode_flag (inode,EXT4_INODE_JOURNAL_DATA );
@@ -6210,7 +6210,7 @@ int ext4_change_inode_journal_flag(strucext4_set_aops (inode);jbd2_journal_unlock_updates (journal); -percpu_up_write (&sbi->s_journal_flag_rwsem); +percpu_up_write (&sbi->s_writepages_rwsem);if (val)up_write (&EXT4_I (inode)->i_mmap_sem);
fs/ext4/super.c +3 -3
@@ -1018,7 +1018,7 @@ static void ext4_put_super(struct super_percpu_counter_destroy (&sbi->s_freeinodes_counter);percpu_counter_destroy (&sbi->s_dirs_counter);percpu_counter_destroy (&sbi->s_dirtyclusters_counter); -percpu_free_rwsem (&sbi->s_journal_flag_rwsem); +percpu_free_rwsem (&sbi->s_writepages_rwsem);#ifdef CONFIG_QUOTA for (i =0 ; i <EXT4_MAXQUOTAS ; i++)kfree (get_qf_name (sb, sbi, i));
@@ -4585,7 +4585,7 @@ no_journal: err =percpu_counter_init (&sbi->s_dirtyclusters_counter,0 ,GFP_KERNEL );if (!err) - err =percpu_init_rwsem (&sbi->s_journal_flag_rwsem); + err =percpu_init_rwsem (&sbi->s_writepages_rwsem);if (err) {ext4_msg (sb,KERN_ERR ,"insufficient memory" );
@@ -4685,7 +4685,7 @@ failed_mount6:percpu_counter_destroy (&sbi->s_freeinodes_counter);percpu_counter_destroy (&sbi->s_dirs_counter);percpu_counter_destroy (&sbi->s_dirtyclusters_counter); -percpu_free_rwsem (&sbi->s_journal_flag_rwsem); +percpu_free_rwsem (&sbi->s_writepages_rwsem); failed_mount5:ext4_ext_release (sb);ext4_release_system_zone (sb);
Greg Kroah-Hartman
maintainerPATCH 86/135 ext4: fix race between writepages and enabling EXT4_EXTENTS_FL
In reply to Greg Kroah-HartmanFrom: Eric Biggers <[email protected]>
commit cb85f4d23f794e24127f3e562cb3b54b0803f456 upstream.
If EXT4_EXTENTS_FL is set on an inode while ext4_writepages() is running on it, the following warning in ext4_add_complete_io() can be hit:
WARNING: CPU: 1 PID: 0 at fs/ext4/page-io.c:234 ext4_put_io_end_defer+0xf0/0x120
Here's a minimal reproducer (not 100% reliable) (root isn't required):
while true; do
sync
done &
while true; do
rm -f file
touch file
chattr -e file
echo X >> file
chattr +e file
done
The problem is that in ext4_writepages(), ext4_should_dioread_nolock() (which only returns true on extent-based files) is checked once to set the number of reserved journal credits, and also again later to select the flags for ext4_map_blocks() and copy the reserved journal handle to ext4_io_end::handle. But if EXT4_EXTENTS_FL is being concurrently set, the first check can see dioread_nolock disabled while the later one can see it enabled, causing the reserved handle to unexpectedly be NULL.
Since changing EXT4_EXTENTS_FL is uncommon, and there may be other races related to doing so as well, fix this by synchronizing changing EXT4_EXTENTS_FL with ext4_writepages() via the existing s_writepages_rwsem (previously called s_journal_flag_rwsem).
This was originally reported by syzbot without a reproducer at
https://syzkaller.appspot.com/bug?extid=2202a584a00fffd19fbf,
but now that dioread_nolock is the default I also started seeing this when running syzkaller locally.
--- fs/ext4/ext4.h | 5 ++++- fs/ext4/migrate.c | 27 +++++++++++++++++++-------- 2 files changed, 23 insertions(+), 9 deletions(-)
fs/ext4/ext4.h +4 -1
@@ -1548,7 +1548,10 @@ struct ext4_sb_info {struct ratelimit_state s_warning_ratelimit_state;struct ratelimit_state s_msg_ratelimit_state; -/* Barrier between changing inodes' journal flags and writepages ops. */ +/* +* Barrier between writepages ops and changing any inode's JOURNAL_DATA +* or EXTENTS flag. +*/ struct percpu_rw_semaphore s_writepages_rwsem;struct dax_device *s_daxdev; };
fs/ext4/migrate.c +19 -8
@@ -427,6 +427,7 @@ static int free_ext_block(handle_t *handint ext4_ext_migrate (struct inode *inode) { +struct ext4_sb_info *sbi =EXT4_SB (inode->i_sb);handle_t *handle;int retval =0 , i;__le32 *i_data;
@@ -451,6 +452,8 @@ int ext4_ext_migrate(struct inode *inode*/ return retval; +percpu_down_write (&sbi->s_writepages_rwsem); +/* * Worst case we can touch the allocation bitmaps, a bgd * block, and a block to link in the orphan list. We do need
@@ -461,7 +464,7 @@ int ext4_ext_migrate(struct inode *inodeif (IS_ERR (handle)) { retval =PTR_ERR (handle); -return retval; + goto out_unlock; } goal = (((inode->i_ino -1 ) /EXT4_INODES_PER_GROUP (inode->i_sb)) *EXT4_INODES_PER_GROUP (inode->i_sb)) +1 ;
@@ -472,7 +475,7 @@ int ext4_ext_migrate(struct inode *inodeif (IS_ERR (tmp_inode)) { retval =PTR_ERR (tmp_inode);ext4_journal_stop (handle); -return retval; + goto out_unlock; }i_size_write (tmp_inode,i_size_read (inode));/*
@@ -514,7 +517,7 @@ int ext4_ext_migrate(struct inode *inode*/ ext4_orphan_del (NULL , tmp_inode); retval =PTR_ERR (handle); - goto out; + goto out_tmp_inode; } ei =EXT4_I (inode);
@@ -595,10 +598,11 @@ err_out:/* Reset the extent details */ ext4_ext_tree_init (handle, tmp_inode);ext4_journal_stop (handle); -out: +out_tmp_inode:unlock_new_inode (tmp_inode);iput (tmp_inode); - +out_unlock: +percpu_up_write (&sbi->s_writepages_rwsem);return retval; }
@@ -608,7 +612,8 @@ out:int ext4_ind_migrate (struct inode *inode) {struct ext4_extent_header *eh; -struct ext4_super_block *es =EXT4_SB (inode->i_sb)->s_es; +struct ext4_sb_info *sbi =EXT4_SB (inode->i_sb); +struct ext4_super_block *es = sbi->s_es;struct ext4_inode_info *ei =EXT4_I (inode);struct ext4_extent *ex;unsigned int i, len;
@@ -632,9 +637,13 @@ int ext4_ind_migrate(struct inode *inodeif (test_opt (inode->i_sb,DELALLOC ))ext4_alloc_da_blocks (inode); +percpu_down_write (&sbi->s_writepages_rwsem); + handle =ext4_journal_start (inode,EXT4_HT_MIGRATE ,1 ); -if (IS_ERR (handle)) -return PTR_ERR (handle); +if (IS_ERR (handle)) { + ret =PTR_ERR (handle); + goto out_unlock; + }down_write (&EXT4_I (inode)->i_data_sem); ret =ext4_ext_check_inode (inode);
@@ -669,5 +678,7 @@ int ext4_ind_migrate(struct inode *inode errout:ext4_journal_stop (handle);up_write (&EXT4_I (inode)->i_data_sem); +out_unlock: +percpu_up_write (&sbi->s_writepages_rwsem);return ret; }
Greg Kroah-Hartman
maintainerPATCH 87/135 KVM: nVMX: Refactor IO bitmap checks into helper function
In reply to Greg Kroah-HartmanFrom: Oliver Upton <[email protected]>
commit e71237d3ff1abf9f3388337cfebf53b96df2020d upstream.
Checks against the IO bitmap are useful for both instruction emulation and VM-exit reflection. Refactor the IO bitmap checks into a helper function.
--- arch/x86/kvm/vmx/nested.c | 39 +++++++++++++++++++++++++-------------- arch/x86/kvm/vmx/nested.h | 2 ++ 2 files changed, 27 insertions(+), 14 deletions(-)
arch/x86/kvm/vmx/nested.c +25 -14
@@ -5132,24 +5132,17 @@ fail:return 1 ; } - -static bool nested_vmx_exit_handled_io (struct kvm_vcpu *vcpu, -struct vmcs12 *vmcs12) +/* +* Return true if an IO instruction with the specified port and size should cause +* a VM-exit into L1. +*/ +bool nested_vmx_check_io_bitmaps (struct kvm_vcpu *vcpu,unsigned int port, +int size) { -unsigned long exit_qualification; +struct vmcs12 *vmcs12 =get_vmcs12 (vcpu);gpa_t bitmap, last_bitmap; -unsigned int port; -int size;u8 b; -if (!nested_cpu_has (vmcs12,CPU_BASED_USE_IO_BITMAPS )) -return nested_cpu_has (vmcs12,CPU_BASED_UNCOND_IO_EXITING ); - - exit_qualification =vmcs_readl (EXIT_QUALIFICATION ); - - port = exit_qualification >>16 ; - size = (exit_qualification &7 ) +1 ; - last_bitmap = (gpa_t)-1 ; b =-1 ;
@@ -5176,6 +5169,24 @@ static bool nested_vmx_exit_handled_io(sreturn false; } +static bool nested_vmx_exit_handled_io (struct kvm_vcpu *vcpu, +struct vmcs12 *vmcs12) +{ +unsigned long exit_qualification; +unsigned int port; +int size; + +if (!nested_cpu_has (vmcs12,CPU_BASED_USE_IO_BITMAPS )) +return nested_cpu_has (vmcs12,CPU_BASED_UNCOND_IO_EXITING ); + + exit_qualification =vmcs_readl (EXIT_QUALIFICATION ); + + port = exit_qualification >>16 ; + size = (exit_qualification &7 ) +1 ; + +return nested_vmx_check_io_bitmaps (vcpu, port, size); +} +/* * Return 1 if we should exit from L2 to L1 to handle an MSR access access, * rather than handle it ourselves in L0. I.e., check whether L1 expressed
arch/x86/kvm/vmx/nested.h +2 -0
@@ -33,6 +33,8 @@ int vmx_set_vmx_msr(struct kvm_vcpu *vcpint vmx_get_vmx_msr (struct nested_vmx_msrs *msrs,u32 msr_index,u64 *pdata);int get_vmx_mem_address (struct kvm_vcpu *vcpu,unsigned long exit_qualification,u32 vmx_instruction_info,bool wr,int len,gva_t *ret); +bool nested_vmx_check_io_bitmaps (struct kvm_vcpu *vcpu,unsigned int port, +int size);static inline struct vmcs12 *get_vmcs12 (struct kvm_vcpu *vcpu) {
Greg Kroah-Hartman
maintainerPATCH 88/135 KVM: nVMX: Check IO instruction VM-exit conditions
In reply to Greg Kroah-HartmanFrom: Oliver Upton <[email protected]>
commit 35a571346a94fb93b5b3b6a599675ef3384bc75c upstream.
Consult the 'unconditional IO exiting' and 'use IO bitmaps' VM-execution controls when checking instruction interception. If the 'use IO bitmaps' VM-execution control is 1, check the instruction access against the IO bitmaps to determine if the instruction causes a VM-exit.
--- arch/x86/kvm/vmx/nested.c | 2 - arch/x86/kvm/vmx/vmx.c | 57 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 52 insertions(+), 7 deletions(-)
arch/x86/kvm/vmx/nested.c +1 -1
@@ -5173,7 +5173,7 @@ static bool nested_vmx_exit_handled_io(s struct vmcs12 *vmcs12) {unsigned long exit_qualification; -unsigned int port; +unsigned short port;int size;if (!nested_cpu_has (vmcs12,CPU_BASED_USE_IO_BITMAPS ))
arch/x86/kvm/vmx/vmx.c +51 -6
75 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 89/135 KVM: nVMX: clear PIN_BASED_POSTED_INTR from nested pinbased_ctls only when apicv is globally disabled
In reply to Greg Kroah-HartmanFrom: Vitaly Kuznetsov <[email protected]>
commit a4443267800af240072280c44521caab61924e55 upstream.
When apicv is disabled on a vCPU (e.g. by enabling KVM_CAP_HYPERV_SYNIC*), nothing happens to VMX MSRs on the already existing vCPUs, however, all new ones are created with PIN_BASED_POSTED_INTR filtered out. This is very confusing and results in the following picture inside the guest:
$ rdmsr -ax 0x48d ff00000016 7f00000016 7f00000016 7f00000016
This is observed with QEMU and 4-vCPU guest: QEMU creates vCPU0, does KVM_CAP_HYPERV_SYNIC2 and then creates the remaining three.
L1 hypervisor may only check CPU0's controls to find out what features are available and it will be very confused later. Switch to setting PIN_BASED_POSTED_INTR control based on global 'enable_apicv' setting.
--- arch/x86/kvm/vmx/capabilities.h | 1 + arch/x86/kvm/vmx/nested.c | 5 ++--- arch/x86/kvm/vmx/nested.h | 3 +-- arch/x86/kvm/vmx/vmx.c | 10 ++++------ 4 files changed, 8 insertions(+), 11 deletions(-)
arch/x86/kvm/vmx/capabilities.h +1 -0
@@ -12,6 +12,7 @@ extern bool __read_mostly enable_ept;extern bool __read_mostly enable_unrestricted_guest;extern bool __read_mostly enable_ept_ad_bits;extern bool __read_mostly enable_pml; +extern bool __read_mostly enable_apicv;extern int __read_mostly pt_mode;#define PT_MODE_SYSTEM 0
arch/x86/kvm/vmx/nested.c +2 -3
@@ -5807,8 +5807,7 @@ void nested_vmx_vcpu_setup(void)* bit in the high half is on if the corresponding bit in the control field * may be on. See also vmx_control_verify(). */ -void nested_vmx_setup_ctls_msrs (struct nested_vmx_msrs *msrs,u32 ept_caps, -bool apicv) +void nested_vmx_setup_ctls_msrs (struct nested_vmx_msrs *msrs,u32 ept_caps) {/* * Note that as a general rule, the high half of the MSRs (bits in
@@ -5835,7 +5834,7 @@ void nested_vmx_setup_ctls_msrs(struct nPIN_BASED_EXT_INTR_MASK |PIN_BASED_NMI_EXITING |PIN_BASED_VIRTUAL_NMIS | - (apicv ?PIN_BASED_POSTED_INTR :0 ); + (enable_apicv ?PIN_BASED_POSTED_INTR :0 ); msrs->pinbased_ctls_high |=PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR |PIN_BASED_VMX_PREEMPTION_TIMER ;
arch/x86/kvm/vmx/nested.h +1 -2
@@ -17,8 +17,7 @@ enum nvmx_vmentry_status { };void vmx_leave_nested (struct kvm_vcpu *vcpu); -void nested_vmx_setup_ctls_msrs (struct nested_vmx_msrs *msrs,u32 ept_caps, -bool apicv); +void nested_vmx_setup_ctls_msrs (struct nested_vmx_msrs *msrs,u32 ept_caps);void nested_vmx_hardware_unsetup (void );__init int nested_vmx_hardware_setup (int (*exit_handlers[])(struct kvm_vcpu *));void nested_vmx_vcpu_setup (void );
arch/x86/kvm/vmx/vmx.c +4 -6
@@ -95,7 +95,7 @@ module_param(emulate_invalid_guest_statestatic bool __read_mostly fasteoi =1 ;module_param (fasteoi, bool,S_IRUGO ); -static bool __read_mostly enable_apicv =1 ; +bool __read_mostly enable_apicv =1 ;module_param (enable_apicv, bool,S_IRUGO );/*
@@ -6802,8 +6802,7 @@ static struct kvm_vcpu *vmx_create_vcpu(if (nested)nested_vmx_setup_ctls_msrs (&vmx->nested.msrs, - vmx_capability.ept, -kvm_vcpu_apicv_active (&vmx->vcpu)); + vmx_capability.ept);else memset (&vmx->nested.msrs,0 ,sizeof (vmx->nested.msrs));
@@ -6885,8 +6884,7 @@ static int __init vmx_check_processor_coif (setup_vmcs_config (&vmcs_conf, &vmx_cap) <0 )return -EIO ;if (nested) -nested_vmx_setup_ctls_msrs (&vmcs_conf.nested, vmx_cap.ept, - enable_apicv); +nested_vmx_setup_ctls_msrs (&vmcs_conf.nested, vmx_cap.ept);if (memcmp (&vmcs_config, &vmcs_conf,sizeof (struct vmcs_config )) !=0 ) {printk (KERN_ERR "kvm: CPU %d feature inconsistency!\n" ,smp_processor_id ());
@@ -7781,7 +7779,7 @@ static __init int hardware_setup(void)if (nested) {nested_vmx_setup_ctls_msrs (&vmcs_config.nested, - vmx_capability.ept, enable_apicv); + vmx_capability.ept); r =nested_vmx_hardware_setup (kvm_vmx_exit_handlers);if (r)
Greg Kroah-Hartman
maintainerPATCH 90/135 KVM: nVMX: handle nested posted interrupts when apicv is disabled for L1
In reply to Greg Kroah-HartmanFrom: Vitaly Kuznetsov <[email protected]>
commit 91a5f413af596ad01097e59bf487eb07cb3f1331 upstream.
Even when APICv is disabled for L1 it can (and, actually, is) still available for L2, this means we need to always call vmx_deliver_nested_posted_interrupt() when attempting an interrupt delivery.
--- arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kvm/lapic.c | 5 +---- arch/x86/kvm/svm.c | 7 ++++++- arch/x86/kvm/vmx/vmx.c | 13 +++++++++---- 4 files changed, 17 insertions(+), 10 deletions(-)
arch/x86/include/asm/kvm_host.h +1 -1
@@ -1098,7 +1098,7 @@ struct kvm_x86_ops {void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu,u64 *eoi_exit_bitmap);void (*set_virtual_apic_mode)(struct kvm_vcpu *vcpu);void (*set_apic_access_page_addr)(struct kvm_vcpu *vcpu,hpa_t hpa); -void (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu,int vector); +int (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu,int vector);int (*sync_pir_to_irr)(struct kvm_vcpu *vcpu);int (*set_tss_addr)(struct kvm *kvm,unsigned int addr);int (*set_identity_map_addr)(struct kvm *kvm,u64 ident_addr);
arch/x86/kvm/lapic.c +1 -4
@@ -1056,11 +1056,8 @@ static int __apic_accept_irq(struct kvm_ apic->regs + APIC_TMR); } -if (vcpu->arch.apicv_active) - kvm_x86_ops->deliver_posted_interrupt (vcpu, vector); -else { +if (kvm_x86_ops->deliver_posted_interrupt (vcpu, vector)) {kvm_lapic_set_irr (vector, apic); -kvm_make_request (KVM_REQ_EVENT , vcpu);kvm_vcpu_kick (vcpu); }
arch/x86/kvm/svm.c +6 -1
@@ -5141,8 +5141,11 @@ static void svm_load_eoi_exitmap(structreturn ; } -static void svm_deliver_avic_intr (struct kvm_vcpu *vcpu,int vec) +static int svm_deliver_avic_intr (struct kvm_vcpu *vcpu,int vec) { +if (!vcpu->arch.apicv_active) +return -1 ; +kvm_lapic_set_irr (vec, vcpu->arch.apic);smp_mb__after_atomic ();
@@ -5154,6 +5157,8 @@ static void svm_deliver_avic_intr(structput_cpu (); }else kvm_vcpu_wake_up (vcpu); + +return 0 ; }static bool svm_dy_apicv_has_pending_interrupt (struct kvm_vcpu *vcpu)
arch/x86/kvm/vmx/vmx.c +9 -4
@@ -3853,24 +3853,29 @@ static int vmx_deliver_nested_posted_int* 2. If target vcpu isn't running(root mode), kick it to pick up the * interrupt from PIR in next vmentry. */ -static void vmx_deliver_posted_interrupt (struct kvm_vcpu *vcpu,int vector) +static int vmx_deliver_posted_interrupt (struct kvm_vcpu *vcpu,int vector) {struct vcpu_vmx *vmx =to_vmx (vcpu);int r; r =vmx_deliver_nested_posted_interrupt (vcpu, vector);if (!r) -return ; +return 0 ; + +if (!vcpu->arch.apicv_active) +return -1 ;if (pi_test_and_set_pir (vector, &vmx->pi_desc)) -return ; +return 0 ;/* If a previous notification has sent the IPI, nothing to do. */ if (pi_test_and_set_on (&vmx->pi_desc)) -return ; +return 0 ;if (!kvm_vcpu_trigger_posted_interrupt (vcpu, false))kvm_vcpu_kick (vcpu); + +return 0 ; }/*
Greg Kroah-Hartman
maintainerPATCH 91/135 KVM: apic: avoid calculating pending eoi from an uninitialized val
In reply to Greg Kroah-HartmanFrom: Miaohe Lin <[email protected]>
commit 23520b2def95205f132e167cf5b25c609975e959 upstream.
When pv_eoi_get_user() fails, 'val' may remain uninitialized and the return value of pv_eoi_get_pending() becomes random. Fix the issue by initializing the variable.
--- arch/x86/kvm/lapic.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/x86/kvm/lapic.c +3 -1
@@ -637,9 +637,11 @@ static inline bool pv_eoi_enabled(structstatic bool pv_eoi_get_pending (struct kvm_vcpu *vcpu) {u8 val; -if (pv_eoi_get_user (vcpu, &val) <0 ) +if (pv_eoi_get_user (vcpu, &val) <0 ) {printk (KERN_WARNING "Can't read EOI MSR value: 0x%llx\n" , (unsigned long long )vcpu->arch.pv_eoi.msr_val); +return false; + }return val &0x1 ; }
Greg Kroah-Hartman
maintainerPATCH 92/135 btrfs: destroy qgroup extent records on transaction abort
In reply to Greg Kroah-HartmanFrom: Jeff Mahoney <[email protected]>
commit 81f7eb00ff5bb8326e82503a32809421d14abb8a upstream.
We clean up the delayed references when we abort a transaction but we leave the pending qgroup extent records behind, leaking memory.
This patch destroys the extent records when we destroy the delayed refs and makes sure ensure they're gone before releasing the transaction.
[ Rebased to latest upstream, remove to_qgroup() helper, use
rbtree_postorder_for_each_entry_safe() wrapper ]
--- fs/btrfs/disk-io.c | 1 + fs/btrfs/qgroup.c | 13 +++++++++++++ fs/btrfs/qgroup.h | 1 + fs/btrfs/transaction.c | 2 ++ 4 files changed, 17 insertions(+)
fs/btrfs/disk-io.c +1 -0
@@ -4293,6 +4293,7 @@ static int btrfs_destroy_delayed_refs(stcond_resched ();spin_lock (&delayed_refs->lock); } +btrfs_qgroup_destroy_extent_records (trans);spin_unlock (&delayed_refs->lock);
fs/btrfs/qgroup.c +13 -0
@@ -4018,3 +4018,16 @@ out: }return ret; } + +void btrfs_qgroup_destroy_extent_records (struct btrfs_transaction *trans) +{ +struct btrfs_qgroup_extent_record *entry; +struct btrfs_qgroup_extent_record *next; +struct rb_root *root; + + root = &trans->delayed_refs.dirty_extent_root; +rbtree_postorder_for_each_entry_safe (entry, next, root, node) { +ulist_free (entry->old_roots); +kfree (entry); + } +}
fs/btrfs/qgroup.h +1 -0
@@ -414,5 +414,6 @@ int btrfs_qgroup_add_swapped_blocks(stru u64 last_snapshot);int btrfs_qgroup_trace_subtree_after_cow (struct btrfs_trans_handle *trans,struct btrfs_root *root,struct extent_buffer *eb); +void btrfs_qgroup_destroy_extent_records (struct btrfs_transaction *trans);#endif
fs/btrfs/transaction.c +2 -0
@@ -51,6 +51,8 @@ void btrfs_put_transaction(struct btrfs_BUG_ON (!list_empty (&transaction->list));WARN_ON (!RB_EMPTY_ROOT ( &transaction->delayed_refs.href_root.rb_root)); +WARN_ON (!RB_EMPTY_ROOT ( + &transaction->delayed_refs.dirty_extent_root));if (transaction->delayed_refs.pending_csums) btrfs_err(transaction->fs_info, "pending csums is %llu",
Greg Kroah-Hartman
maintainerPATCH 93/135 btrfs: fix bytes_may_use underflow in prealloc error condtition
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
commit b778cf962d71a0e737923d55d0432f3bd287258e upstream.
I hit the following warning while running my error injection stress testing:
WARNING: CPU: 3 PID: 1453 at fs/btrfs/space-info.h:108 btrfs_free_reserved_data_space_noquota+0xfd/0x160 [btrfs] RIP: 0010:btrfs_free_reserved_data_space_noquota+0xfd/0x160 [btrfs] Call Trace: btrfs_free_reserved_data_space+0x4f/0x70 [btrfs] __btrfs_prealloc_file_range+0x378/0x470 [btrfs] elfcorehdr_read+0x40/0x40 ? elfcorehdr_read+0x40/0x40 ? btrfs_commit_transaction+0xca/0xa50 [btrfs] ? dput+0xb4/0x2a0 ? btrfs_log_dentry_safe+0x55/0x70 [btrfs] ? btrfs_sync_file+0x30e/0x420 [btrfs] ? do_fsync+0x38/0x70 ? __x64_sys_fdatasync+0x13/0x20 ? do_syscall_64+0x5b/0x1b0 ? entry_SYSCALL_64_after_hwframe+0x44/0xa9
This happens if we fail to insert our reserved file extent. At this point we've already converted our reservation from ->bytes_may_use to ->bytes_reserved. However once we break we will attempt to free everything from [cur_offset, end] from ->bytes_may_use, but our extent reservation will overlap part of this.
Fix this problem by adding ins.offset (our extent allocation size) to cur_offset so we remove the actual remaining part from ->bytes_may_use.
I validated this fix using my inject-error.py script
python inject-error.py -o should_fail_bio -t cache_save_setup -t \ __btrfs_prealloc_file_range \ -t insert_reserved_file_extent.constprop.0 \ -r "-5" ./run-fsstress.sh
where run-fsstress.sh simply mounts and runs fsstress on a disk.
--- fs/btrfs/inode.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
fs/btrfs/inode.c +13 -3
@@ -10464,6 +10464,7 @@ static int __btrfs_prealloc_file_range(sstruct btrfs_root *root =BTRFS_I (inode)->root;struct btrfs_key ins;u64 cur_offset = start; +u64 clear_offset = start;u64 i_size;u64 cur_bytes;u64 last_alloc = (u64)-1 ;
@@ -10498,6 +10499,15 @@ static int __btrfs_prealloc_file_range(sbtrfs_end_transaction (trans);break ; } + +/* +* We've reserved this space, and thus converted it from +* ->bytes_may_use to ->bytes_reserved. Any error that happens +* from here on out we will only need to clear our reservation +* for the remaining unreserved area, so advance our +* clear_offset by our extent size. +*/ + clear_offset += ins.offset;btrfs_dec_block_group_reservations (fs_info, ins.objectid); last_alloc = ins.offset;
@@ -10578,9 +10588,9 @@ next:if (own_trans)btrfs_end_transaction (trans); } -if (cur_offset < end) -btrfs_free_reserved_data_space (inode,NULL , cur_offset, - end - cur_offset +1 ); +if (clear_offset < end) +btrfs_free_reserved_data_space (inode,NULL , clear_offset, + end - clear_offset +1 );return ret; }
Greg Kroah-Hartman
maintainerPATCH 94/135 btrfs: reset fs_root to NULL on error in open_ctree
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
commit 315bf8ef914f31d51d084af950703aa1e09a728c upstream.
While running my error injection script I hit a panic when we tried to clean up the fs_root when freeing the fs_root. This is because fs_info->fs_root == PTR_ERR(-EIO), which isn't great. Fix this by setting fs_info->fs_root = NULL; if we fail to read the root.
--- fs/btrfs/disk-io.c | 1 + 1 file changed, 1 insertion(+)
fs/btrfs/disk-io.c +1 -0
@@ -3203,6 +3203,7 @@ retry_root_backup:if (IS_ERR (fs_info->fs_root)) { err =PTR_ERR (fs_info->fs_root);btrfs_warn (fs_info,"failed to read fs tree: %d" , err); + fs_info->fs_root =NULL ; goto fail_qgroup; }
Greg Kroah-Hartman
maintainerPATCH 95/135 btrfs: do not check delayed items are empty for single transaction cleanup
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
commit 1e90315149f3fe148e114a5de86f0196d1c21fa5 upstream.
btrfs_assert_delayed_root_empty() will check if the delayed root is completely empty, but this is a filesystem-wide check. On cleanup we may have allowed other transactions to begin, for whatever reason, and thus the delayed root is not empty.
So remove this check from cleanup_one_transation(). This however can stay in btrfs_cleanup_transaction(), because it checks only after all of the transactions have been properly cleaned up, and thus is valid.
--- fs/btrfs/disk-io.c | 1 - 1 file changed, 1 deletion(-)
fs/btrfs/disk-io.c +0 -1
@@ -4520,7 +4520,6 @@ void btrfs_cleanup_one_transaction(strucwake_up (&fs_info->transaction_wait);btrfs_destroy_delayed_inodes (fs_info); -btrfs_assert_delayed_root_empty (fs_info);btrfs_destroy_marked_extents (fs_info, &cur_trans->dirty_pages,EXTENT_DIRTY );
Greg Kroah-Hartman
maintainerPATCH 96/135 Btrfs: fix btrfs_wait_ordered_range() so that it waits for all ordered extents
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
commit e75fd33b3f744f644061a4f9662bd63f5434f806 upstream.
In btrfs_wait_ordered_range() once we find an ordered extent that has finished with an error we exit the loop and don't wait for any other ordered extents that might be still in progress.
All the users of btrfs_wait_ordered_range() expect that there are no more ordered extents in progress after that function returns. So past fixes such like the ones from the two following commits:
ff612ba7849964 ("btrfs: fix panic during relocation after ENOSPC before
writeback happens")
28aeeac1dd3080 ("Btrfs: fix panic when starting bg cache writeout after
IO error")
don't work when there are multiple ordered extents in the range.
Fix that by making btrfs_wait_ordered_range() wait for all ordered extents even after it finds one that had an error.
--- fs/btrfs/ordered-data.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
fs/btrfs/ordered-data.c +6 -1
@@ -690,10 +690,15 @@ int btrfs_wait_ordered_range(struct inod }btrfs_start_ordered_extent (inode, ordered,1 ); end = ordered->file_offset; +/* +* If the ordered extent had an error save the error but don't +* exit without waiting first for all other ordered extents in +* the range to complete. +*/ if (test_bit (BTRFS_ORDERED_IOERR , &ordered->flags)) ret = -EIO ;btrfs_put_ordered_extent (ordered); -if (ret || end ==0 || end == start) +if (end ==0 || end == start)break ; end--; }
Greg Kroah-Hartman
maintainerPATCH 97/135 Btrfs: fix race between shrinking truncate and fiemap
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
commit 28553fa992cb28be6a65566681aac6cafabb4f2d upstream.
When there is a fiemap executing in parallel with a shrinking truncate we can end up in a situation where we have extent maps for which we no longer have corresponding file extent items. This is generally harmless and at the moment the only consequences are missing file extent items representing holes after we expand the file size again after the truncate operation removed the prealloc extent items, and stale information for future fiemap calls (reporting extents that no longer exist or may have been reallocated to other files for example).
Consider the following example:
1) Our inode has a size of 128KiB, one 128KiB extent at file offset 0 and a 1MiB prealloc extent at file offset 128KiB;
2) Task A starts doing a shrinking truncate of our inode to reduce it to a size of 64KiB. Before it searches the subvolume tree for file extent items to delete, it drops all the extent maps in the range from 64KiB to (u64)-1 by calling btrfs_drop_extent_cache();
3) Task B starts doing a fiemap against our inode. When looking up for the inode's extent maps in the range from 128KiB to (u64)-1, it doesn't find any in the inode's extent map tree, since they were removed by task A. Because it didn't find any in the extent map tree, it scans the inode's subvolume tree for file extent items, and it finds the 1MiB prealloc extent at file offset 128KiB, then it creates an extent map based on that file extent item and adds it to inode's extent map tree (this ends up being done by btrfs_get_extent() <- btrfs_get_extent_fiemap() <- get_extent_skip_holes());
4) Task A then drops the prealloc extent at file offset 128KiB and shrinks the 128KiB extent file offset 0 to a length of 64KiB. The truncation operation finishes and we end up with an extent map representing a 1MiB prealloc extent at file offset 128KiB, despite we don't have any more that extent;
After this the two types of problems we have are:
1) Future calls to fiemap always report that a 1MiB prealloc extent exists at file offset 128KiB. This is stale information, no longer correct;
2) If the size of the file is increased, by a truncate operation that increases the file size or by a write into a file offset > 64KiB for example, we end up not inserting file extent items to represent holes for any range between 128KiB and 128KiB + 1MiB, since the hole expansion function, btrfs_cont_expand() will skip hole insertion for any range for which an extent map exists that represents a prealloc extent. This causes fsck to complain about missing file extent items when not using the NO_HOLES feature.
The second issue could be often triggered by test case generic/561 from fstests, which runs fsstress and duperemove in parallel, and duperemove does frequent fiemap calls.
Essentially the problems happens because fiemap does not acquire the inode's lock while truncate does, and fiemap locks the file range in the inode's iotree while truncate does not. So fix the issue by making btrfs_truncate_inode_items() lock the file range from the new file size to (u64)-1, so that it serializes with fiemap.
--- fs/btrfs/inode.c | 8 ++++++++ 1 file changed, 8 insertions(+)
fs/btrfs/inode.c +8 -0
@@ -4734,6 +4734,8 @@ int btrfs_truncate_inode_items(struct btu64 bytes_deleted =0 ;bool be_nice = false;bool should_throttle = false; +const u64 lock_start =ALIGN_DOWN (new_size, fs_info->sectorsize); +struct extent_state *cached_state =NULL ;BUG_ON (new_size >0 && min_type !=BTRFS_EXTENT_DATA_KEY );
@@ -4750,6 +4752,9 @@ int btrfs_truncate_inode_items(struct btreturn -ENOMEM ; path->reada =READA_BACK ; +lock_extent_bits (&BTRFS_I (inode)->io_tree, lock_start, (u64)-1 , + &cached_state); +/* * We want to drop from the next block forward in case this new size is * not block aligned since we will be keeping the last block of the
@@ -5016,6 +5021,9 @@ out:btrfs_ordered_update_i_size (inode, last_size,NULL ); } +unlock_extent_cached (&BTRFS_I (inode)->io_tree, lock_start, (u64)-1 , + &cached_state); +btrfs_free_path (path);return ret; }
Greg Kroah-Hartman
maintainerPATCH 98/135 btrfs: dont set path->leave_spinning for truncate
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
commit 52e29e331070cd7d52a64cbf1b0958212a340e28 upstream.
The only time we actually leave the path spinning is if we're truncating a small amount and don't actually free an extent, which is not a common occurrence. We have to set the path blocking in order to add the delayed ref anyway, so the first extent we find we set the path to blocking and stay blocking for the duration of the operation. With the upcoming file extent map stuff there will be another case that we have to have the path blocking, so just swap to blocking always.
Note: this patch also fixes a warning after 28553fa992cb ("Btrfs: fix race between shrinking truncate and fiemap") got merged that inserts extent locks around truncation so the path must not leave spinning locks after btrfs_search_slot.
[70.794783] BUG: sleeping function called from invalid context at mm/slab.h:565
[70.794834] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 1141, name: rsync
[70.794863] 5 locks held by rsync/1141:
[70.794876] #0: ffff888417b9c408 (sb_writers#17){.+.+}, at: mnt_want_write+0x20/0x50
[70.795030] #1: ffff888428de28e8 (&type->i_mutex_dir_key#13/1){+.+.}, at: lock_rename+0xf1/0x100
[70.795051] #2: ffff888417b9c608 (sb_internal#2){.+.+}, at: start_transaction+0x394/0x560
[70.795124] #3: ffff888403081768 (btrfs-fs-01){++++}, at: btrfs_try_tree_write_lock+0x2f/0x160
[70.795203] #4: ffff888403086568 (btrfs-fs-00){++++}, at: btrfs_try_tree_write_lock+0x2f/0x160
[70.795222] CPU: 5 PID: 1141 Comm: rsync Not tainted 5.6.0-rc2-backup+ #2
[70.795362] Call Trace:
[70.795374] dump_stack+0x71/0xa0
[70.795445] ___might_sleep.part.96.cold.106+0xa6/0xb6
[70.795459] kmem_cache_alloc+0x1d3/0x290
[70.795471] alloc_extent_state+0x22/0x1c0
[70.795544] __clear_extent_bit+0x3ba/0x580
[70.795557] ? _raw_spin_unlock_irq+0x24/0x30
[70.795569] btrfs_truncate_inode_items+0x339/0xe50
[70.795647] btrfs_evict_inode+0x269/0x540
[70.795659] ? dput.part.38+0x29/0x460
[70.795671] evict+0xcd/0x190
[70.795682] __dentry_kill+0xd6/0x180
[70.795754] dput.part.38+0x2ad/0x460
[70.795765] do_renameat2+0x3cb/0x540
[70.795777] __x64_sys_rename+0x1c/0x20--- fs/btrfs/inode.c | 2 -- 1 file changed, 2 deletions(-)
fs/btrfs/inode.c +0 -2
@@ -4791,7 +4791,6 @@ search_again: goto out; } - path->leave_spinning =1 ; ret =btrfs_search_slot (trans, root, &key, path,-1 ,1 );if (ret <0 ) goto out;
@@ -4943,7 +4942,6 @@ delete: root == fs_info->tree_root)) {struct btrfs_ref ref = {0 }; -btrfs_set_path_blocking (path); bytes_deleted += extent_num_bytes; btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF,
Greg Kroah-Hartman
maintainerPATCH 99/135 Btrfs: fix deadlock during fast fsync when logging prealloc extents beyond eof
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
commit a5ae50dea9111db63d30d700766dd5509602f7ad upstream.
While logging the prealloc extents of an inode during a fast fsync we call btrfs_truncate_inode_items(), through btrfs_log_prealloc_extents(), while holding a read lock on a leaf of the inode's root (not the log root, the fs/subvol root), and then that function locks the file range in the inode's iotree. This can lead to a deadlock when:
* the fsync is ranged
* the file has prealloc extents beyond eof
* writeback for a range different from the fsync range starts during the fsync
* the size of the file is not sector size aligned
Because when finishing an ordered extent we lock first a file range and then try to COW the fs/subvol tree to insert an extent item.
The following diagram shows how the deadlock can happen.
CPU 1 CPU 2
btrfs_sync_file()
--> for range [0, 1MiB)
--> inode has a size of
1MiB and has 1 prealloc
extent beyond the
i_size, starting at offset
4MiB
flushes all delalloc for the
range [0MiB, 1MiB) and waits
for the respective ordered
extents to complete
--> before task at CPU 1 locks the
inode, a write into file range [1MiB, 2MiB + 1KiB) is made
--> i_size is updated to 2MiB + 1KiB
--> writeback is started for that
range, [1MiB, 2MiB + 4KiB) --> end offset rounded up to
be sector size aligned
btrfs_log_dentry_safe()
btrfs_log_inode_parent()
btrfs_log_inode()
btrfs_log_changed_extents()
btrfs_log_prealloc_extents()
--> does a search on the
inode's root
--> holds a read lock on
leaf X
btrfs_finish_ordered_io()
--> locks range [1MiB, 2MiB + 4KiB)
--> end offset rounded up
to be sector size aligned
--> tries to cow leaf X, through
insert_reserved_file_extent() --> already locked by the
task at CPU 1
btrfs_truncate_inode_items()
--> gets an i_size of
2MiB + 1KiB, which is
not sector size
aligned
--> tries to lock file
range [2MiB, (u64)-1)
--> the start range
is rounded down
from 2MiB + 1K
to 2MiB to be sector
size aligned
--> but the subrange
[2MiB, 2MiB + 4KiB) is
already locked by
task at CPU 2 which
is waiting to get a
write lock on leaf X
for which we are
holding a read lock
*** deadlock ***
This results in a stack trace like the following, triggered by test case generic/561 from fstests:
[ 2779.973608] INFO: task kworker/u8:6:247 blocked for more than 120 seconds. [ 2779.979536] Not tainted 5.6.0-rc2-btrfs-next-53 #1 [ 2779.984503] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 2779.990136] kworker/u8:6 D 0 247 2 0x80004000 [ 2779.990457] Workqueue: btrfs-endio-write btrfs_work_helper [btrfs] [ 2779.990466] Call Trace: [ 2779.990491] ? __schedule+0x384/0xa30 [ 2779.990521] schedule+0x33/0xe0 [ 2779.990616] btrfs_tree_read_lock+0x19e/0x2e0 [btrfs] [ 2779.990632] ? remove_wait_queue+0x60/0x60 [ 2779.990730] btrfs_read_lock_root_node+0x2f/0x40 [btrfs] [ 2779.990782] btrfs_search_slot+0x510/0x1000 [btrfs] [ 2779.990869] btrfs_lookup_file_extent+0x4a/0x70 [btrfs] [ 2779.990944] __btrfs_drop_extents+0x161/0x1060 [btrfs] [ 2779.990987] ? mark_held_locks+0x6d/0xc0 [ 2779.990994] ? __slab_alloc.isra.49+0x99/0x100 [ 2779.991060] ? insert_reserved_file_extent.constprop.19+0x64/0x300 [btrfs] [ 2779.991145] insert_reserved_file_extent.constprop.19+0x97/0x300 [btrfs] [ 2779.991222] ? start_transaction+0xdd/0x5c0 [btrfs] [ 2779.991291] btrfs_finish_ordered_io+0x4f4/0x840 [btrfs] [ 2779.991405] btrfs_work_helper+0xaa/0x720 [btrfs] [ 2779.991432] process_one_work+0x26d/0x6a0 [ 2779.991460] worker_thread+0x4f/0x3e0 [ 2779.991481] ? process_one_work+0x6a0/0x6a0 [ 2779.991489] kthread+0x103/0x140 [ 2779.991499] ? kthread_create_worker_on_cpu+0x70/0x70 [ 2779.991515] ret_from_fork+0x3a/0x50 (...) [ 2780.026211] INFO: task fsstress:17375 blocked for more than 120 seconds. [ 2780.027480] Not tainted 5.6.0-rc2-btrfs-next-53 #1 [ 2780.028482] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 2780.030035] fsstress D 0 17375 17373 0x00004000 [ 2780.030038] Call Trace: [ 2780.030044] ? __schedule+0x384/0xa30 [ 2780.030052] schedule+0x33/0xe0 [ 2780.030075] lock_extent_bits+0x20c/0x320 [btrfs] [ 2780.030094] ? btrfs_truncate_inode_items+0xf4/0x1150 [btrfs] [ 2780.030098] ? rcu_read_lock_sched_held+0x59/0xa0 [ 2780.030102] ? remove_wait_queue+0x60/0x60 [ 2780.030122] btrfs_truncate_inode_items+0x133/0x1150 [btrfs] [ 2780.030151] ? btrfs_set_path_blocking+0xb2/0x160 [btrfs] [ 2780.030165] ? btrfs_search_slot+0x379/0x1000 [btrfs] [ 2780.030195] btrfs_log_changed_extents.isra.8+0x841/0x93e [btrfs] [ 2780.030202] ? do_raw_spin_unlock+0x49/0xc0 [ 2780.030215] ? btrfs_get_num_csums+0x10/0x10 [btrfs] [ 2780.030239] btrfs_log_inode+0xf83/0x1124 [btrfs] [ 2780.030251] ? __mutex_unlock_slowpath+0x45/0x2a0 [ 2780.030275] btrfs_log_inode_parent+0x2a0/0xe40 [btrfs] [ 2780.030282] ? dget_parent+0xa1/0x370 [ 2780.030309] btrfs_log_dentry_safe+0x4a/0x70 [btrfs] [ 2780.030329] btrfs_sync_file+0x3f3/0x490 [btrfs] [ 2780.030339] do_fsync+0x38/0x60 [ 2780.030343] __x64_sys_fdatasync+0x13/0x20 [ 2780.030345] do_syscall_64+0x5c/0x280 [ 2780.030348] entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 2780.030356] RIP: 0033:0x7f2d80f6d5f0 [ 2780.030361] Code: Bad RIP value. [ 2780.030362] RSP: 002b:00007ffdba3c8548 EFLAGS: 00000246 ORIG_RAX: 000000000000004b [ 2780.030364] RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007f2d80f6d5f0 [ 2780.030365] RDX: 00007ffdba3c84b0 RSI: 00007ffdba3c84b0 RDI: 0000000000000003 [ 2780.030367] RBP: 000000000000004a R08: 0000000000000001 R09: 00007ffdba3c855c [ 2780.030368] R10: 0000000000000078 R11: 0000000000000246 R12: 00000000000001f4 [ 2780.030369] R13: 0000000051eb851f R14: 00007ffdba3c85f0 R15: 0000557a49220d90
So fix this by making btrfs_truncate_inode_items() not lock the range in the inode's iotree when the target root is a log root, since it's not needed to lock the range for log roots as the protection from the inode's lock and log_mutex are all that's needed.
--- fs/btrfs/inode.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
fs/btrfs/inode.c +5 -5
@@ -4752,8 +4752,9 @@ int btrfs_truncate_inode_items(struct btreturn -ENOMEM ; path->reada =READA_BACK ; -lock_extent_bits (&BTRFS_I (inode)->io_tree, lock_start, (u64)-1 , - &cached_state); +if (root->root_key.objectid !=BTRFS_TREE_LOG_OBJECTID ) +lock_extent_bits (&BTRFS_I (inode)->io_tree, lock_start, (u64)-1 , + &cached_state);/* * We want to drop from the next block forward in case this new size is
@@ -5017,11 +5018,10 @@ out:if (!ret && last_size > new_size) last_size = new_size;btrfs_ordered_update_i_size (inode, last_size,NULL ); +unlock_extent_cached (&BTRFS_I (inode)->io_tree, lock_start, + (u64)-1 , &cached_state); } -unlock_extent_cached (&BTRFS_I (inode)->io_tree, lock_start, (u64)-1 , - &cached_state); -btrfs_free_path (path);return ret; }
Greg Kroah-Hartman
maintainerPATCH 100/135 Revert "dmaengine: imx-sdma: Fix memory leak"
In reply to Greg Kroah-HartmanFrom: Greg Kroah-Hartman <[email protected]>
This reverts commit 8a7aa4feeaeabc12181e1997a298eb73d2ed2d65 which is commit 02939cd167095f16328a1bd5cab5a90b550606df upstream.
Andreas writes:
This patch breaks our imx6 board with the attached trace. Reverting the patch makes it boot again.
--- drivers/dma/imx-sdma.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-)
drivers/dma/imx-sdma.c +8 -11
@@ -760,8 +760,12 @@ static void sdma_start_desc(struct sdma_return ; } sdmac->desc = desc =to_sdma_desc (&vd->tx); - -list_del (&vd->node); +/* +* Do not delete the node in desc_issued list in cyclic mode, otherwise +* the desc allocated will never be freed in vchan_dma_desc_free_list +*/ +if (!(sdmac->flags &IMX_DMA_SG_LOOP )) +list_del (&vd->node); sdma->channel_control[channel].base_bd_ptr = desc->bd_phys; sdma->channel_control[channel].current_bd_ptr = desc->bd_phys;
@@ -1067,6 +1071,7 @@ static void sdma_channel_terminate_work(spin_lock_irqsave (&sdmac->vc.lock, flags);vchan_get_all_descriptors (&sdmac->vc, &head); + sdmac->desc =NULL ;spin_unlock_irqrestore (&sdmac->vc.lock, flags);vchan_dma_desc_free_list (&sdmac->vc, &head); sdmac->context_loaded = false;
@@ -1075,19 +1080,11 @@ static void sdma_channel_terminate_work(static int sdma_disable_channel_async (struct dma_chan *chan) {struct sdma_channel *sdmac =to_sdma_chan (chan); -unsigned long flags; - -spin_lock_irqsave (&sdmac->vc.lock, flags);sdma_disable_channel (chan); -if (sdmac->desc) { -vchan_terminate_vdesc (&sdmac->desc->vd); - sdmac->desc =NULL ; +if (sdmac->desc)schedule_work (&sdmac->terminate_worker); - } - -spin_unlock_irqrestore (&sdmac->vc.lock, flags);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 101/135 drm/i915/gt: Detect if we miss WaIdleLiteRestore
In reply to Greg Kroah-HartmanFrom: Chris Wilson <[email protected]>
commit 82c69bf58650e644c61aa2bf5100b63a1070fd2f upstream.
In order to avoid confusing the HW, we must never submit an empty ring during lite-restore, that is we should always advance the RING_TAIL before submitting to stay ahead of the RING_HEAD.
Normally this is prevented by keeping a couple of spare NOPs in the request->wa_tail so that on resubmission we can advance the tail. This relies on the request only being resubmitted once, which is the normal condition as it is seen once for ELSP[1] and then later in ELSP[0]. On preemption, the requests are unwound and the tail reset back to the normal end point (as we know the request is incomplete and therefore its RING_HEAD is even earlier).
However, if this w/a should fail we would try and resubmit the request with the RING_TAIL already set to the location of this request's wa_tail potentially causing a GPU hang. We can spot when we do try and incorrectly resubmit without advancing the RING_TAIL and spare any embarrassment by forcing the context restore.
In the case of preempt-to-busy, we leave the requests running on the HW while we unwind. As the ring is still live, we cannot rewind our rq->tail without forcing a reload so leave it set to rq->wa_tail and only force a reload if we resubmit after a lite-restore. (Normally, the forced reload will be a part of the preemption event.)
--- drivers/gpu/drm/i915/gt/intel_lrc.c | 42 +++++++++++++++++------------------- 1 file changed, 20 insertions(+), 22 deletions(-)
drivers/gpu/drm/i915/gt/intel_lrc.c +20 -22
@@ -471,12 +471,6 @@ lrc_descriptor(struct intel_context *ce,return desc; } -static void unwind_wa_tail (struct i915_request *rq) -{ - rq->tail =intel_ring_wrap (rq->ring, rq->wa_tail -WA_TAIL_BYTES ); -assert_ring_tail_valid (rq->ring, rq->tail); -} -static struct i915_request *__unwind_incomplete_requests (struct intel_engine_cs *engine) {
@@ -495,7 +489,6 @@ __unwind_incomplete_requests(struct intecontinue ;/* XXX */ __i915_request_unsubmit (rq); -unwind_wa_tail (rq);/* * Push the request back into the queue for later resubmission.
@@ -650,13 +643,29 @@ execlists_schedule_out(struct i915_requei915_request_put (rq); } -static u64 execlists_update_context (const struct i915_request *rq) +static u64 execlists_update_context (struct i915_request *rq) {struct intel_context *ce = rq->hw_context; -u64 desc; +u64 desc = ce->lrc_desc; +u32 tail; - ce->lrc_reg_state[CTX_RING_TAIL +1 ] = -intel_ring_set_tail (rq->ring, rq->tail); +/* +* WaIdleLiteRestore:bdw,skl +* +* We should never submit the context with the same RING_TAIL twice +* just in case we submit an empty ring, which confuses the HW. +* +* We append a couple of NOOPs (gen8_emit_wa_tail) after the end of +* the normal request to be able to always advance the RING_TAIL on +* subsequent resubmissions (for lite restore). Should that fail us, +* and we try and submit the same tail again, force the context +* reload. +*/ + tail =intel_ring_set_tail (rq->ring, rq->tail); +if (unlikely (ce->lrc_reg_state[CTX_RING_TAIL +1 ] == tail)) + desc |=CTX_DESC_FORCE_RESTORE ; + ce->lrc_reg_state[CTX_RING_TAIL +1 ] = tail; + rq->tail = rq->wa_tail;/* * Make sure the context image is complete before we submit it to HW.
@@ -675,7 +684,6 @@ static u64 execlists_update_context(cons*/ mb (); - desc = ce->lrc_desc; ce->lrc_desc &= ~CTX_DESC_FORCE_RESTORE ;return desc;
@@ -1150,16 +1158,6 @@ static void execlists_dequeue(struct intif (!list_is_last (&last->sched.link, &engine->active.requests))return ; - -/* -* WaIdleLiteRestore:bdw,skl -* Apply the wa NOOPs to prevent -* ring:HEAD == rq:TAIL as we resubmit the -* request. See gen8_emit_fini_breadcrumb() for -* where we prepare the padding after the -* end of the request. -*/ - last->tail = last->wa_tail; } }
Greg Kroah-Hartman
maintainerPATCH 102/135 drm/i915/execlists: Always force a context reload when rewinding RING_TAIL
In reply to Greg Kroah-HartmanFrom: Chris Wilson <[email protected]>
commit b1339ecac661e1cf3e1dc78ac56bff3aeeaeb92c upstream.
If we rewind the RING_TAIL on a context, due to a preemption event, we must force the context restore for the RING_TAIL update to be properly handled. Rather than note which preemption events may cause us to rewind the tail, compare the new request's tail with the previously submitted RING_TAIL, as it turns out that timeslicing was causing unexpected rewinds.
<idle>-0 0d.s2 1280851190us : __execlists_submission_tasklet: 0000:00:02.0 rcs0: expired last=130:4698, prio=3, hint=3 <idle>-0 0d.s2 1280851192us : __i915_request_unsubmit: 0000:00:02.0 rcs0: fence 66:119966, current 119964 <idle>-0 0d.s2 1280851195us : __i915_request_unsubmit: 0000:00:02.0 rcs0: fence 130:4698, current 4695 <idle>-0 0d.s2 1280851198us : __i915_request_unsubmit: 0000:00:02.0 rcs0: fence 130:4696, current 4695
^---- Note we unwind 2 requests from the same context
<idle>-0 0d.s2 1280851208us : __i915_request_submit: 0000:00:02.0 rcs0: fence 130:4696, current 4695
<idle>-0 0d.s2 1280851213us : __i915_request_submit: 0000:00:02.0 rcs0: fence 134:1508, current 1506
^---- But to apply the new timeslice, we have to replay the first request
before the new client can start -- the unexpected RING_TAIL rewind
<idle>-0 0d.s2 1280851219us : trace_ports: 0000:00:02.0 rcs0: submit { 130:4696*, 134:1508 }
synmark2-5425 2..s. 1280851239us : process_csb: 0000:00:02.0 rcs0: cs-irq head=5, tail=0
synmark2-5425 2..s. 1280851240us : process_csb: 0000:00:02.0 rcs0: csb[0]: status=0x00008002:0x00000000^---- Preemption event for the ELSP update; note the lite-restore
synmark2-5425 2..s. 1280851243us : trace_ports: 0000:00:02.0 rcs0: preempted { 130:4698, 66:119966 }
synmark2-5425 2..s. 1280851246us : trace_ports: 0000:00:02.0 rcs0: promote { 130:4696*, 134:1508 }
synmark2-5425 2.... 1280851462us : __i915_request_commit: 0000:00:02.0 rcs0: fence 130:4700, current 4695
synmark2-5425 2.... 1280852111us : __i915_request_commit: 0000:00:02.0 rcs0: fence 130:4702, current 4695
synmark2-5425 2.Ns1 1280852296us : process_csb: 0000:00:02.0 rcs0: cs-irq head=0, tail=2
synmark2-5425 2.Ns1 1280852297us : process_csb: 0000:00:02.0 rcs0: csb[1]: status=0x00000814:0x00000000
synmark2-5425 2.Ns1 1280852299us : trace_ports: 0000:00:02.0 rcs0: completed { 130:4696!, 134:1508 }
synmark2-5425 2.Ns1 1280852301us : process_csb: 0000:00:02.0 rcs0: csb[2]: status=0x00000818:0x00000040
synmark2-5425 2.Ns1 1280852302us : trace_ports: 0000:00:02.0 rcs0: completed { 134:1508, 0:0 }
synmark2-5425 2.Ns1 1280852313us : process_csb: process_csb:2336 GEM_BUG_ON(!i915_request_completed(*execlists->active) && !reset_in_progress(execlists))Referenecs: 82c69bf58650 ("drm/i915/gt: Detect if we miss WaIdleLiteRestore")
--- drivers/gpu/drm/i915/gt/intel_engine.h | 8 ++++++++ drivers/gpu/drm/i915/gt/intel_engine_types.h | 1 + drivers/gpu/drm/i915/gt/intel_lrc.c | 18 ++++++++---------- drivers/gpu/drm/i915/gt/intel_ringbuffer.c | 2 ++ 4 files changed, 19 insertions(+), 10 deletions(-)
drivers/gpu/drm/i915/gt/intel_engine.h +8 -0
@@ -250,6 +250,14 @@ static inline u32 intel_ring_wrap(constreturn pos & (ring->size -1 ); } +static inline int intel_ring_direction (const struct intel_ring *ring, +u32 next,u32 prev) +{ +typecheck (typeof (ring->size), next); +typecheck (typeof (ring->size), prev); +return (next - prev) << ring->wrap; +} +static inline bool intel_ring_offset_valid (const struct intel_ring *ring,unsigned int pos)
drivers/gpu/drm/i915/gt/intel_engine_types.h +1 -0
@@ -107,6 +107,7 @@ struct intel_ring {u32 space;u32 size; +u32 wrap;u32 effective_size; };
drivers/gpu/drm/i915/gt/intel_lrc.c +8 -10
@@ -647,7 +647,7 @@ static u64 execlists_update_context(stru {struct intel_context *ce = rq->hw_context;u64 desc = ce->lrc_desc; -u32 tail; +u32 tail, prev;/* * WaIdleLiteRestore:bdw,skl
@@ -660,9 +660,15 @@ static u64 execlists_update_context(stru* subsequent resubmissions (for lite restore). Should that fail us, * and we try and submit the same tail again, force the context * reload. +* +* If we need to return to a preempted context, we need to skip the +* lite-restore and force it to reload the RING_TAIL. Otherwise, the +* HW has a tendency to ignore us rewinding the TAIL to the end of +* an earlier request. */ tail =intel_ring_set_tail (rq->ring, rq->tail); -if (unlikely (ce->lrc_reg_state[CTX_RING_TAIL +1 ] == tail)) + prev = ce->lrc_reg_state[CTX_RING_TAIL +1 ]; +if (unlikely (intel_ring_direction (rq->ring, tail, prev) <=0 )) desc |=CTX_DESC_FORCE_RESTORE ; ce->lrc_reg_state[CTX_RING_TAIL +1 ] = tail; rq->tail = rq->wa_tail;
@@ -1110,14 +1116,6 @@ static void execlists_dequeue(struct int*/ __unwind_incomplete_requests (engine); -/* -* If we need to return to the preempted context, we -* need to skip the lite-restore and force it to -* reload the RING_TAIL. Otherwise, the HW has a -* tendency to ignore us rewinding the TAIL to the -* end of an earlier request. -*/ - last->hw_context->lrc_desc |=CTX_DESC_FORCE_RESTORE ; last =NULL ; }else if (need_timeslice (engine, last) && !timer_pending (&engine->execlists.timer)) {
drivers/gpu/drm/i915/gt/intel_ringbuffer.c +2 -0
@@ -1312,6 +1312,8 @@ intel_engine_create_ring(struct intel_enkref_init (&ring->ref); ring->size = size; + ring->wrap =BITS_PER_TYPE (ring->size) -ilog2 (size); +/* Workaround an erratum on the i830 which causes a hang if * the TAIL pointer points to within the last 2 cachelines * of the buffer.
Greg Kroah-Hartman
maintainerPATCH 103/135 drm/i915/gvt: more locking for ppgtt mm LRU list
In reply to Greg Kroah-HartmanFrom: Igor Druzhinin <[email protected]>
commit 0e9d7bb293f3f9c3ee376b126141407efb265f31 upstream.
When the lock was introduced in commit 72aabfb862e40 ("drm/i915/gvt: Add mutual lock for ppgtt mm LRU list") one place got lost.
--- drivers/gpu/drm/i915/gvt/gtt.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/gpu/drm/i915/gvt/gtt.c +4 -0
@@ -1956,7 +1956,11 @@ void _intel_vgpu_mm_release(struct krefif (mm->type ==INTEL_GVT_MM_PPGTT ) {list_del (&mm->ppgtt_mm.list); + +mutex_lock (&mm->vgpu->gvt->gtt.ppgtt_mm_lock);list_del (&mm->ppgtt_mm.lru_list); +mutex_unlock (&mm->vgpu->gvt->gtt.ppgtt_mm_lock); +invalidate_ppgtt_mm (mm); }else {vfree (mm->ggtt_mm.virtual_ggtt);
Greg Kroah-Hartman
maintainerPATCH 104/135 drm/bridge: tc358767: fix poll timeouts
In reply to Greg Kroah-HartmanFrom: Tomi Valkeinen <[email protected]>
commit 8a6483ac634acda3f599f50082c652d2d37199c7 upstream.
Link training fails with:
Link training timeout waiting for LT_LOOPDONE!
main link enable error: -110
This is caused by too tight timeouts, which were changed recently in aa92213f388b ("drm/bridge: tc358767: Simplify polling in tc_link_training()").
With a quick glance, the commit does not change the timeouts. However, the method of delaying/sleeping is different, and as the timeout in the previous implementation was not explicit, the new version in practice has much tighter timeout.
The same change was made to other parts in the driver, but the link training timeout is the only one I have seen causing issues. Nevertheless, 1 us sleep is not very sane, and the timeouts look pretty tight, so lets fix all the timeouts.
One exception was the aux busy poll, where the poll sleep was much longer than necessary (or optimal).
I measured the times on my setup, and now the sleep times are set to such values that they result in multiple loops, but not too many (say, 5-10 loops). The timeouts were all increased to 100ms, which should be more than enough for all of these, but in case of bad errors, shouldn't stop the driver as multi-second timeouts could do.
--- drivers/gpu/drm/bridge/tc358767.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/bridge/tc358767.c +4 -4
@@ -294,7 +294,7 @@ static inline int tc_poll_timeout(structstatic int tc_aux_wait_busy (struct tc_data *tc) { -return tc_poll_timeout (tc,DP0_AUXSTATUS ,AUX_BUSY ,0 ,1000 ,100000 ); +return tc_poll_timeout (tc,DP0_AUXSTATUS ,AUX_BUSY ,0 ,100 ,100000 ); } static int tc_aux_write_data(struct tc_data *tc, const void *data,
@@ -637,7 +637,7 @@ static int tc_aux_link_setup(struct tc_dif (ret) goto err; - ret =tc_poll_timeout (tc,DP_PHY_CTRL ,PHY_RDY ,PHY_RDY ,1 ,1000 ); + ret =tc_poll_timeout (tc,DP_PHY_CTRL ,PHY_RDY ,PHY_RDY ,100 ,100000 );if (ret == -ETIMEDOUT ) {dev_err (tc->dev,"Timeout waiting for PHY to become ready" );return ret;
@@ -861,7 +861,7 @@ static int tc_wait_link_training(structint ret; ret =tc_poll_timeout (tc,DP0_LTSTAT ,LT_LOOPDONE , -LT_LOOPDONE ,1 ,1000 ); +LT_LOOPDONE ,500 ,100000 );if (ret) {dev_err (tc->dev,"Link training timeout waiting for LT_LOOPDONE!\n" );return ret;
@@ -934,7 +934,7 @@ static int tc_main_link_enable(struct tc dp_phy_ctrl &= ~(DP_PHY_RST |PHY_M1_RST |PHY_M0_RST ); ret =regmap_write (tc->regmap,DP_PHY_CTRL , dp_phy_ctrl); - ret =tc_poll_timeout (tc,DP_PHY_CTRL ,PHY_RDY ,PHY_RDY ,1 ,1000 ); + ret =tc_poll_timeout (tc,DP_PHY_CTRL ,PHY_RDY ,PHY_RDY ,500 ,100000 );if (ret) {dev_err (dev,"timeout waiting for phy become ready" );return ret;
Greg Kroah-Hartman
maintainerPATCH 105/135 drm/i915/gt: Protect defer_request() from new waiters
In reply to Greg Kroah-HartmanFrom: Chris Wilson <[email protected]>
commit 19b5f3b419a61808ff2713f1f30b8a88fe14ac9b upstream.
Mika spotted
<4>[17436.705441] general protection fault: 0000 [#1] PREEMPT SMP PTI <4>[17436.705447] CPU: 2 PID: 0 Comm: swapper/2 Not tainted 5.5.0+ #1 <4>[17436.705449] Hardware name: System manufacturer System Product Name/Z170M-PLUS, BIOS 3805 05/16/2018 <4>[17436.705512] RIP: 0010:__execlists_submission_tasklet+0xc4d/0x16e0 [i915] <4>[17436.705516] Code: c5 4c 8d 60 e0 75 17 e9 8c 07 00 00 49 8b 44 24 20 49 39 c5 4c 8d 60 e0 0f 84 7a 07 00 00 49 8b 5c 24 08 49 8b 87 80 00 00 00 <48> 39 83 d8 fe ff ff 75 d9 48 8b 83 88 fe ff ff a8 01 0f 84 b6 05 <4>[17436.705518] RSP: 0018:ffffc9000012ce80 EFLAGS: 00010083 <4>[17436.705521] RAX: ffff88822ae42000 RBX: 5a5a5a5a5a5a5a5a RCX: dead000000000122 <4>[17436.705523] RDX: ffff88822ae42588 RSI: ffff8881e32a7908 RDI: ffff8881c429fd48 <4>[17436.705525] RBP: ffffc9000012cf00 R08: ffff88822ae42588 R09: 00000000fffffffe <4>[17436.705527] R10: ffff8881c429fb80 R11: 00000000a677cf08 R12: ffff8881c42a0aa8 <4>[17436.705529] R13: ffff8881c429fd38 R14: ffff88822ae42588 R15: ffff8881c429fb80 <4>[17436.705532] FS: 0000000000000000(0000) GS:ffff88822ed00000(0000) knlGS:0000000000000000 <4>[17436.705534] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 <4>[17436.705536] CR2: 00007f858c76d000 CR3: 0000000005610003 CR4: 00000000003606e0 <4>[17436.705538] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 <4>[17436.705540] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 <4>[17436.705542] Call Trace: <4>[17436.705545] <IRQ> <4>[17436.705603] execlists_submission_tasklet+0xc0/0x130 [i915]
which is us consuming a partially initialised new waiter in defer_requests(). We can prevent this by initialising the i915_dependency prior to making it visible, and since we are using a concurrent list_add/iterator mark them up to the compiler.
--- drivers/gpu/drm/i915/gt/intel_lrc.c | 7 ++++++- drivers/gpu/drm/i915/i915_scheduler.c | 6 ++++-- 2 files changed, 10 insertions(+), 3 deletions(-)
drivers/gpu/drm/i915/gt/intel_lrc.c +6 -1
@@ -933,6 +933,11 @@ last_active(const struct intel_engine_exreturn *last; } +#define for_each_waiter (p__, rq__) \ + list_for_each_entry_lockless(p__, \ + &(rq__)->sched.waiters_list, \ + wait_link) +static void defer_request (struct i915_request *rq,struct list_head *const pl) {LIST_HEAD (list);
@@ -950,7 +955,7 @@ static void defer_request(struct i915_reGEM_BUG_ON (i915_request_is_active (rq));list_move_tail (&rq->sched.link, pl); -list_for_each_entry (p, &rq->sched.waiters_list, wait_link) { +for_each_waiter (p, rq) {struct i915_request *w =container_of (p->waiter,typeof (*w), sched);
drivers/gpu/drm/i915/i915_scheduler.c +4 -2
@@ -418,8 +418,6 @@ bool __i915_sched_node_add_dependency(stif (!node_signaled (signal)) {INIT_LIST_HEAD (&dep->dfs_link); -list_add (&dep->wait_link, &signal->waiters_list); -list_add (&dep->signal_link, &node->signalers_list); dep->signaler = signal; dep->waiter = node; dep->flags = flags;
@@ -429,6 +427,10 @@ bool __i915_sched_node_add_dependency(st !node_started(signal)) node->flags |=I915_SCHED_HAS_SEMAPHORE_CHAIN ; +/* All set, now publish. Beware the lockless walkers. */ +list_add (&dep->signal_link, &node->signalers_list); +list_add_rcu (&dep->wait_link, &signal->waiters_list); +/* * As we do not allow WAIT to preempt inflight requests, * once we have executed a request, along with triggering
Greg Kroah-Hartman
maintainerPATCH 106/135 drm/msm/dpu: fix BGR565 vs RGB565 confusion
In reply to Greg Kroah-HartmanFrom: Rob Clark <[email protected]>
commit 8fc7036ee652207ca992fbb9abb64090c355a9e0 upstream.
The component order between the two was swapped, resulting in incorrect color when games with 565 visual hit the overlay path instead of GPU composition.
--- drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c +2 -2
@@ -255,13 +255,13 @@ static const struct dpu_format dpu_formaINTERLEAVED_RGB_FMT (RGB565 ,0 ,COLOR_5BIT ,COLOR_6BIT ,COLOR_5BIT , - C2_R_Cr,C0_G_Y , C1_B_Cb,0 ,3 , + C1_B_Cb,C0_G_Y , C2_R_Cr,0 ,3 , false,2 ,0 ,DPU_FETCH_LINEAR ,1 ),INTERLEAVED_RGB_FMT (BGR565 ,0 ,COLOR_5BIT ,COLOR_6BIT ,COLOR_5BIT , - C1_B_Cb,C0_G_Y , C2_R_Cr,0 ,3 , + C2_R_Cr,C0_G_Y , C1_B_Cb,0 ,3 , false,2 ,0 , DPU_FETCH_LINEAR, 1),
Greg Kroah-Hartman
maintainerPATCH 107/135 scsi: Revert "RDMA/isert: Fix a recently introduced regression related to logout"
In reply to Greg Kroah-HartmanFrom: Bart Van Assche <[email protected]>
commit 76261ada16dcc3be610396a46d35acc3efbda682 upstream.
Since commit 04060db41178 introduces soft lockups when toggling network interfaces, revert it.
--- drivers/infiniband/ulp/isert/ib_isert.c | 12 ++++++++++++ drivers/target/iscsi/iscsi_target.c | 6 +++--- 2 files changed, 15 insertions(+), 3 deletions(-)
drivers/infiniband/ulp/isert/ib_isert.c +12 -0
@@ -2575,6 +2575,17 @@ isert_wait4logout(struct isert_conn *ise } } +static void +isert_wait4cmds (struct iscsi_conn *conn) +{ +isert_info ("iscsi_conn %p\n" , conn); + +if (conn->sess) { +target_sess_cmd_list_set_waiting (conn->sess->se_sess); +target_wait_for_sess_cmds (conn->sess->se_sess); + } +} +/** * isert_put_unsol_pending_cmds() - Drop commands waiting for * unsolicitate dataout
@@ -2622,6 +2633,7 @@ static void isert_wait_conn(struct iscsiib_drain_qp (isert_conn->qp);isert_put_unsol_pending_cmds (conn); +isert_wait4cmds (conn);isert_wait4logout (isert_conn);queue_work (isert_release_wq, &isert_conn->release_work);
drivers/target/iscsi/iscsi_target.c +3 -3
@@ -4151,6 +4151,9 @@ int iscsit_close_connection(iscsit_stop_nopin_response_timer (conn);iscsit_stop_nopin_timer (conn); +if (conn->conn_transport->iscsit_wait_conn) + conn->conn_transport->iscsit_wait_conn (conn); +/* * During Connection recovery drop unacknowledged out of order * commands for this connection, and prepare the other commands
@@ -4236,9 +4239,6 @@ int iscsit_close_connection(target_sess_cmd_list_set_waiting (sess->se_sess);target_wait_for_sess_cmds (sess->se_sess); -if (conn->conn_transport->iscsit_wait_conn) - conn->conn_transport->iscsit_wait_conn (conn); -ahash_request_free (conn->conn_tx_hash);if (conn->conn_rx_hash) {struct crypto_ahash *tfm;
Greg Kroah-Hartman
maintainerPATCH 108/135 scsi: Revert "target: iscsi: Wait for all commands to finish before freeing a session"
In reply to Greg Kroah-HartmanFrom: Bart Van Assche <[email protected]>
commit 807b9515b7d044cf77df31f1af9d842a76ecd5cb upstream.
Since commit e9d3009cb936 introduced a regression and since the fix for that regression was not perfect, revert this commit.
--- drivers/target/iscsi/iscsi_target.c | 10 ++-------- include/scsi/iscsi_proto.h | 1 - 2 files changed, 2 insertions(+), 9 deletions(-)
drivers/target/iscsi/iscsi_target.c +2 -8
@@ -1165,9 +1165,7 @@ int iscsit_setup_scsi_cmd(struct iscsi_c hdr->cmdsn,be32_to_cpu (hdr->data_length), payload_length, conn->cid); -if (target_get_sess_cmd (&cmd->se_cmd, true) <0 ) -return iscsit_add_reject_cmd (cmd, -ISCSI_REASON_WAITING_FOR_LOGOUT , buf); +target_get_sess_cmd (&cmd->se_cmd, true); cmd->sense_reason =transport_lookup_cmd_lun (&cmd->se_cmd,scsilun_to_int (&hdr->lun));
@@ -2004,9 +2002,7 @@ iscsit_handle_task_mgt_cmd(struct iscsi_ conn->sess->se_sess,0 ,DMA_NONE , TCM_SIMPLE_TAG, cmd->sense_buffer + 2); -if (target_get_sess_cmd (&cmd->se_cmd, true) <0 ) -return iscsit_add_reject_cmd (cmd, -ISCSI_REASON_WAITING_FOR_LOGOUT , buf); +target_get_sess_cmd (&cmd->se_cmd, true);/* * TASK_REASSIGN for ERL=2 / connection stays inside of
@@ -4236,8 +4232,6 @@ int iscsit_close_connection(* must wait until they have completed. */ iscsit_check_conn_usage_count (conn); -target_sess_cmd_list_set_waiting (sess->se_sess); -target_wait_for_sess_cmds (sess->se_sess);ahash_request_free (conn->conn_tx_hash);if (conn->conn_rx_hash) {
include/scsi/iscsi_proto.h +0 -1
@@ -627,7 +627,6 @@ struct iscsi_reject {#define ISCSI_REASON_BOOKMARK_INVALID 9#define ISCSI_REASON_BOOKMARK_NO_RESOURCES 10#define ISCSI_REASON_NEGOTIATION_RESET 11 -#define ISCSI_REASON_WAITING_FOR_LOGOUT 12/* Max. number of Key=Value pairs in a text message */ #define MAX_KEY_VALUE_PAIRS 8192
Greg Kroah-Hartman
maintainerPATCH 109/135 usb: gadget: composite: Fix bMaxPower for SuperSpeedPlus
In reply to Greg Kroah-HartmanFrom: Jack Pham <[email protected]>
commit c724417baf162bd3e035659e22cdf990cfb0d917 upstream.
SuperSpeedPlus peripherals must report their bMaxPower of the configuration descriptor in units of 8mA as per the USB 3.2 specification. The current switch statement in encode_bMaxPower() only checks for USB_SPEED_SUPER but not USB_SPEED_SUPER_PLUS so the latter falls back to USB 2.0 encoding which uses 2mA units. Replace the switch with a simple if/else.
--- drivers/usb/gadget/composite.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
drivers/usb/gadget/composite.c +3 -5
@@ -437,12 +437,10 @@ static u8 encode_bMaxPower(enum usb_devi val =CONFIG_USB_GADGET_VBUS_DRAW ;if (!val)return 0 ; -switch (speed) { -case USB_SPEED_SUPER : -return DIV_ROUND_UP (val,8 ); -default : +if (speed <USB_SPEED_SUPER )return DIV_ROUND_UP (val,2 ); - } +else +return DIV_ROUND_UP (val,8 ); } static int config_buf(struct usb_configuration *config,
Greg Kroah-Hartman
maintainerPATCH 110/135 usb: dwc2: Fix in ISOC request length checking
In reply to Greg Kroah-HartmanFrom: Minas Harutyunyan <[email protected]>
commit 860ef6cd3f90b84a1832f8a6485c90c34d3b588b upstream.
Moved ISOC request length checking from dwc2_hsotg_start_req() function to dwc2_hsotg_ep_queue().
--- drivers/usb/dwc2/gadget.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/usb/dwc2/gadget.c +7 -5
@@ -1083,11 +1083,6 @@ static void dwc2_hsotg_start_req(structelse packets =1 ;/* send one packet if length is zero. */ -if (hs_ep->isochronous && length > (hs_ep->mc * hs_ep->ep.maxpacket)) { -dev_err (hsotg->dev,"req length > maxpacket*mc\n" ); -return ; - } -if (dir_in && index !=0 )if (hs_ep->isochronous) epsize =DXEPTSIZ_MC (packets);
@@ -1391,6 +1386,13 @@ static int dwc2_hsotg_ep_queue(struct us req->actual =0 ; req->status = -EINPROGRESS ; +/* Don't queue ISOC request if length greater than mps*mc */ +if (hs_ep->isochronous && + req->length > (hs_ep->mc * hs_ep->ep.maxpacket)) { +dev_err (hs->dev,"req length > maxpacket*mc\n" ); +return -EINVAL ; + } +/* In DDMA mode for ISOC's don't queue request if length greater * than descriptor limits. */
Greg Kroah-Hartman
maintainerPATCH 111/135 staging: rtl8723bs: fix copy of overlapping memory
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
commit 8ae9a588ca35eb9c32dc03299c5e1f4a1e9a9617 upstream.
Currently the rtw_sprintf prints the contents of thread_name onto thread_name and this can lead to a potential copy of a string over itself. Avoid this by printing the literal string RTWHALXT instread of the contents of thread_name.
Addresses-Coverity: ("copy of overlapping memory")
--- drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c +2 -3
@@ -476,14 +476,13 @@ int rtl8723bs_xmit_thread(void *context)s32 ret;struct adapter *padapter;struct xmit_priv *pxmitpriv; -u8 thread_name[20 ] ="RTWHALXT" ; - +u8 thread_name[20 ]; ret = _SUCCESS; padapter = context; pxmitpriv = &padapter->xmitpriv; -rtw_sprintf (thread_name,20 ,"%s-" ADPT_FMT , thread_name,ADPT_ARG (padapter)); +rtw_sprintf (thread_name,20 ,"RTWHALXT-" ADPT_FMT ,ADPT_ARG (padapter));thread_enter (thread_name);DBG_871X ("start " FUNC_ADPT_FMT "\n" ,FUNC_ADPT_ARG (padapter));
Greg Kroah-Hartman
maintainerPATCH 112/135 staging: greybus: use after free in gb_audio_manager_remove_all()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit b7db58105b80fa9232719c8329b995b3addfab55 upstream.
When we call kobject_put() and it's the last reference to the kobject then it calls gb_audio_module_release() and frees module. We dereference "module" on the next line which is a use after free.
--- drivers/staging/greybus/audio_manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/greybus/audio_manager.c +1 -1
@@ -92,8 +92,8 @@ void gb_audio_manager_remove_all(void)list_for_each_entry_safe (module, next, &modules_list, list) {list_del (&module->list); -kobject_put (&module->kobj);ida_simple_remove (&module_id, module->id); +kobject_put (&module->kobj); } is_empty =list_empty (&modules_list);
Greg Kroah-Hartman
maintainerPATCH 113/135 ASoC: atmel: fix atmel_ssc_set_audio link failure
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
commit 9437bfda00f3b26eb5f475737ddaaf4dc07fee4f upstream.
The ssc audio driver can call into both pdc and dma backends. With the latest rework, the logic to do this in a safe way avoiding link errors was removed, bringing back link errors that were fixed long ago in commit 061981ff8cc8 ("ASoC: atmel: properly select dma driver state") such as
sound/soc/atmel/atmel_ssc_dai.o: In function `atmel_ssc_set_audio':
atmel_ssc_dai.c:(.text+0xac): undefined reference to `atmel_pcm_pdc_platform_register'
Fix it this time using Makefile hacks and a comment to prevent this from accidentally getting removed again rather than Kconfig hacks.
--- sound/soc/atmel/Kconfig | 4 ++-- sound/soc/atmel/Makefile | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-)
sound/soc/atmel/Kconfig +2 -2
@@ -10,11 +10,11 @@ config SND_ATMEL_SOC if SND_ATMEL_SOC config SND_ATMEL_SOC_PDC - tristate + bool depends on HAS_DMA config SND_ATMEL_SOC_DMA - tristate + bool select SND_SOC_GENERIC_DMAENGINE_PCM config SND_ATMEL_SOC_SSC
sound/soc/atmel/Makefile +8 -2
@@ -6,8 +6,14 @@ snd-soc-atmel_ssc_dai-objs := atmel_ssc_ snd-soc-atmel-i2s-objs := atmel-i2s.o snd-soc-mchp-i2s-mcc-objs := mchp-i2s-mcc.o -obj-$(CONFIG_SND_ATMEL_SOC_PDC) += snd-soc-atmel-pcm-pdc.o -obj-$(CONFIG_SND_ATMEL_SOC_DMA) += snd-soc-atmel-pcm-dma.o +# pdc and dma need to both be built-in if any user of +# ssc is built-in. +ifdef CONFIG_SND_ATMEL_SOC_PDC +obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel-pcm-pdc.o +endif +ifdef CONFIG_SND_ATMEL_SOC_DMA +obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel-pcm-dma.o +endif obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o obj-$(CONFIG_SND_ATMEL_SOC_I2S) += snd-soc-atmel-i2s.o obj-$(CONFIG_SND_MCHP_SOC_I2S_MCC) += snd-soc-mchp-i2s-mcc.o
Greg Kroah-Hartman
maintainerPATCH 114/135 ASoC: fsl_sai: Fix exiting path on probing failure
In reply to Greg Kroah-HartmanFrom: Oleksandr Suvorov <[email protected]>
commit d1520889782dff58610c0b6b54d4cf3211ceb690 upstream.
If the imx-sdma driver is built as a module, the fsl-sai device doesn't disable on probing failure, which causes the warning in the next probing:
==================================================================
fsl-sai 308a0000.sai: Unbalanced pm_runtime_enable! fsl-sai 308a0000.sai: Unbalanced pm_runtime_enable! fsl-sai 308a0000.sai: Unbalanced pm_runtime_enable! fsl-sai 308a0000.sai: Unbalanced pm_runtime_enable! fsl-sai 308a0000.sai: Unbalanced pm_runtime_enable! fsl-sai 308a0000.sai: Unbalanced pm_runtime_enable!
==================================================================
Disabling the device properly fixes the issue.
--- sound/soc/fsl/fsl_sai.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-)
sound/soc/fsl/fsl_sai.c +17 -5
@@ -1019,12 +1019,24 @@ static int fsl_sai_probe(struct platform ret =devm_snd_soc_register_component (&pdev->dev, &fsl_component, &fsl_sai_dai,1 );if (ret) -return ret; + goto err_pm_disable; -if (sai->soc_data->use_imx_pcm) -return imx_pcm_dma_init (pdev,IMX_SAI_DMABUF_SIZE ); -else -return devm_snd_dmaengine_pcm_register (&pdev->dev,NULL ,0 ); +if (sai->soc_data->use_imx_pcm) { + ret =imx_pcm_dma_init (pdev,IMX_SAI_DMABUF_SIZE ); +if (ret) + goto err_pm_disable; + }else { + ret =devm_snd_dmaengine_pcm_register (&pdev->dev,NULL ,0 ); +if (ret) + goto err_pm_disable; + } + +return ret; + +err_pm_disable: +pm_runtime_disable (&pdev->dev); + +return ret; }static int fsl_sai_remove (struct platform_device *pdev)
Greg Kroah-Hartman
maintainerPATCH 115/135 ecryptfs: replace BUG_ON with error handling code
In reply to Greg Kroah-HartmanFrom: Aditya Pakki <[email protected]>
commit 2c2a7552dd6465e8fde6bc9cccf8d66ed1c1eb72 upstream.
In crypt_scatterlist, if the crypt_stat argument is not set up correctly, the kernel crashes. Instead, by returning an error code upstream, the error is handled safely.
The issue is detected via a static analysis tool written by us.
--- fs/ecryptfs/crypto.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
fs/ecryptfs/crypto.c +4 -2
@@ -311,8 +311,10 @@ static int crypt_scatterlist(struct ecrystruct extent_crypt_result ecr;int rc =0 ; -BUG_ON (!crypt_stat || !crypt_stat->tfm - || !(crypt_stat->flags &ECRYPTFS_STRUCT_INITIALIZED )); +if (!crypt_stat || !crypt_stat->tfm + || !(crypt_stat->flags &ECRYPTFS_STRUCT_INITIALIZED )) +return -EINVAL ; +if (unlikely (ecryptfs_verbosity >0 )) {ecryptfs_printk (KERN_DEBUG ,"Key size [%zd]; key:\n" , crypt_stat->key_size);
Greg Kroah-Hartman
maintainerPATCH 116/135 iommu/vt-d: Fix compile warning from intel-svm.h
In reply to Greg Kroah-HartmanFrom: Joerg Roedel <[email protected]>
commit e7598fac323aad0e502415edeffd567315994dd6 upstream.
The intel_svm_is_pasid_valid() needs to be marked inline, otherwise it causes the compile warning below:
CC [M] drivers/dma/idxd/cdev.o
In file included from drivers/dma/idxd/cdev.c:9:0:./include/linux/intel-svm.h:125:12: warning: ‘intel_svm_is_pasid_valid’ defined but not used [-Wunused-function]
static int intel_svm_is_pasid_valid(struct device *dev, int pasid)
^~~~~~~~~~~~~~~~~~~~~~~~
--- include/linux/intel-svm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/intel-svm.h +1 -1
@@ -122,7 +122,7 @@ static inline int intel_svm_unbind_mm(stBUG (); } -static int intel_svm_is_pasid_valid (struct device *dev,int pasid) +static inline int intel_svm_is_pasid_valid (struct device *dev,int pasid) {return -EINVAL ; }
Greg Kroah-Hartman
maintainerPATCH 117/135 crypto: rename sm3-256 to sm3 in hash_algo_name
In reply to Greg Kroah-HartmanFrom: Tianjia Zhang <[email protected]>
commit 6a30e1b1dcad0ba94fae757f797812d7d8dcb72c upstream.
The name sm3-256 is defined in hash_algo_name in hash_info, but the algorithm name implemented in sm3_generic.c is sm3, which will cause the sm3-256 algorithm to be not found in some application scenarios of the hash algorithm, and an ENOENT error will occur. For example, IMA, keys, and other subsystems that reference hash_algo_name all use the hash algorithm of sm3.
--- crypto/hash_info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
crypto/hash_info.c +1 -1
@@ -26,7 +26,7 @@ const char *const hash_algo_name[HASH_AL [HASH_ALGO_TGR_128] = "tgr128", [HASH_ALGO_TGR_160] = "tgr160", [HASH_ALGO_TGR_192] = "tgr192", - [HASH_ALGO_SM3_256] = "sm3-256", + [HASH_ALGO_SM3_256] = "sm3", [HASH_ALGO_STREEBOG_256] = "streebog256", [HASH_ALGO_STREEBOG_512] = "streebog512", };
Greg Kroah-Hartman
maintainerPATCH 118/135 genirq/proc: Reject invalid affinity masks (again)
In reply to Greg Kroah-HartmanFrom: Thomas Gleixner <[email protected]>
commit cba6437a1854fde5934098ec3bd0ee83af3129f5 upstream.
Qian Cai reported that the WARN_ON() in the x86/msi affinity setting code, which catches cases where the affinity setting is not done on the CPU which is the current target of the interrupt, triggers during CPU hotplug stress testing.
It turns out that the warning which was added with the commit addressing the MSI affinity race unearthed yet another long standing bug.
If user space writes a bogus affinity mask, i.e. it contains no online CPUs, then it calls irq_select_affinity_usr(). This was introduced for ALPHA in
eee45269b0f5 ("[PATCH] Alpha: convert to generic irq framework (generic part)")
and subsequently made available for all architectures in
18404756765c ("genirq: Expose default irq affinity mask (take 3)")
which introduced the circumvention of the affinity setting restrictions for interrupt which cannot be moved in process context.
The whole exercise is bogus in various aspects:
1) If the interrupt is already started up then there is absolutely no point to honour a bogus interrupt affinity setting from user space. The interrupt is already assigned to an online CPU and it does not make any sense to reassign it to some other randomly chosen online CPU.
2) If the interupt is not yet started up then there is no point either. A subsequent startup of the interrupt will invoke irq_setup_affinity() anyway which will chose a valid target CPU.
So the only correct solution is to just return -EINVAL in case user space wrote an affinity mask which does not contain any online CPUs, except for ALPHA which has it's own magic sauce for this.
--- kernel/irq/internals.h | 2 -- kernel/irq/manage.c | 18 ++---------------- kernel/irq/proc.c | 22 ++++++++++++++++++++++ 3 files changed, 24 insertions(+), 18 deletions(-)
kernel/irq/internals.h +0 -2
@@ -128,8 +128,6 @@ static inline void unregister_handler_prextern bool irq_can_set_affinity_usr (unsigned int irq); -extern int irq_select_affinity_usr (unsigned int irq); -extern void irq_set_thread_affinity (struct irq_desc *desc); extern int irq_do_set_affinity(struct irq_data *data,
kernel/irq/manage.c +2 -16
@@ -442,23 +442,9 @@ int irq_setup_affinity(struct irq_desc * {return irq_select_affinity (irq_desc_get_irq (desc)); } -#endif +#endif /* CONFIG_AUTO_IRQ_AFFINITY */ +#endif /* CONFIG_SMP */ -/* -* Called when a bogus affinity is set via /proc/irq -*/ -int irq_select_affinity_usr (unsigned int irq) -{ -struct irq_desc *desc =irq_to_desc (irq); -unsigned long flags; -int ret; - -raw_spin_lock_irqsave (&desc->lock, flags); - ret =irq_setup_affinity (desc); -raw_spin_unlock_irqrestore (&desc->lock, flags); -return ret; -} -#endif /** * irq_set_vcpu_affinity - Set vcpu affinity for the interrupt
kernel/irq/proc.c +22 -0
@@ -111,6 +111,28 @@ static int irq_affinity_list_proc_show(sreturn show_irq_affinity (AFFINITY_LIST , m); } +#ifndef CONFIG_AUTO_IRQ_AFFINITY +static inline int irq_select_affinity_usr (unsigned int irq) +{ +/* +* If the interrupt is started up already then this fails. The +* interrupt is assigned to an online CPU already. There is no +* point to move it around randomly. Tell user space that the +* selected mask is bogus. +* +* If not then any change to the affinity is pointless because the +* startup code invokes irq_setup_affinity() which will select +* a online CPU anyway. +*/ +return -EINVAL ; +} +#else +/* ALPHA magic affinity auto selector. Keep it for historical reasons. */ +static inline int irq_select_affinity_usr (unsigned int irq) +{ +return irq_select_affinity (irq); +} +#endif static ssize_t write_irq_affinity (int type,struct file *file,const char __user *buffer,size_t count,loff_t *pos)
Greg Kroah-Hartman
maintainerPATCH 119/135 bpf, offload: Replace bitwise AND by logical AND in bpf_prog_offload_info_fill
In reply to Greg Kroah-HartmanFrom: Johannes Krude <[email protected]>
commit e20d3a055a457a10a4c748ce5b7c2ed3173a1324 upstream.
This if guards whether user-space wants a copy of the offload-jited bytecode and whether this bytecode exists. By erroneously doing a bitwise AND instead of a logical AND on user- and kernel-space buffer-size can lead to no data being copied to user-space especially when user-space size is a power of two and bigger then the kernel-space buffer.
--- kernel/bpf/offload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/bpf/offload.c +1 -1
@@ -321,7 +321,7 @@ int bpf_prog_offload_info_fill(struct bp ulen = info->jited_prog_len; info->jited_prog_len = aux->offload->jited_len; -if (info->jited_prog_len & ulen) { +if (info->jited_prog_len && ulen) { uinsns =u64_to_user_ptr (info->jited_prog_insns); ulen =min_t (u32, info->jited_prog_len, ulen);if (copy_to_user (uinsns, aux->offload->jited_image, ulen)) {
Greg Kroah-Hartman
maintainerPATCH 120/135 arm64: lse: Fix LSE atomics with LLVM
In reply to Greg Kroah-HartmanFrom: Vincenzo Frascino <[email protected]>
commit dd1f6308b28edf0452dd5dc7877992903ec61e69 upstream.
Commit e0d5896bd356 ("arm64: lse: fix LSE atomics with LLVM's integrated assembler") broke the build when clang is used in connjunction with the binutils assembler ("-no-integrated-as"). This happens because __LSE_PREAMBLE is defined as ".arch armv8-a+lse", which overrides the version of the CPU architecture passed via the "-march" paramter to gas:
$ aarch64-none-linux-gnu-as -EL -I ./arch/arm64/include
-I ./arch/arm64/include/generated
-I ./include -I ./include
-I ./arch/arm64/include/uapi
-I ./arch/arm64/include/generated/uapi
-I ./include/uapi -I ./include/generated/uapi
-I ./init -I ./init
-march=armv8.3-a -o init/do_mounts.o
/tmp/do_mounts-d7992a.s
/tmp/do_mounts-d7992a.s: Assembler messages:
/tmp/do_mounts-d7992a.s:1959: Error: selected processor does not support `autiasp'
/tmp/do_mounts-d7992a.s:2021: Error: selected processor does not support `paciasp'
/tmp/do_mounts-d7992a.s:2157: Error: selected processor does not support `autiasp'
/tmp/do_mounts-d7992a.s:2175: Error: selected processor does not support `paciasp'
/tmp/do_mounts-d7992a.s:2494: Error: selected processor does not support `autiasp'Fix the issue by replacing ".arch armv8-a+lse" with ".arch_extension lse". Sami confirms that the clang integrated assembler does now support the '.arch_extension' directive, so this change will be fine even for LTO builds in future.
--- arch/arm64/include/asm/lse.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/include/asm/lse.h +1 -1
@@ -6,7 +6,7 @@#if defined(CONFIG_AS_LSE ) && defined(CONFIG_ARM64_LSE_ATOMICS ) -#define __LSE_PREAMBLE ".arch armv8-a+lse\n" +#define __LSE_PREAMBLE ".arch_extension lse\n"#include <linux/compiler_types.h> #include <linux/export.h>
Greg Kroah-Hartman
maintainerPATCH 121/135 io_uring: fix __io_iopoll_check deadlock in io_sq_thread
In reply to Greg Kroah-HartmanFrom: Xiaoguang Wang <[email protected]>
commit c7849be9cc2dd2754c48ddbaca27c2de6d80a95d upstream.
Since commit a3a0e43fd770 ("io_uring: don't enter poll loop if we have CQEs pending"), if we already events pending, we won't enter poll loop. In case SETUP_IOPOLL and SETUP_SQPOLL are both enabled, if app has been terminated and don't reap pending events which are already in cq ring, and there are some reqs in poll_list, io_sq_thread will enter __io_iopoll_check(), and find pending events, then return, this loop will never have a chance to exit.
I have seen this issue in fio stress tests, to fix this issue, let io_sq_thread call io_iopoll_getevents() with argument 'min' being zero, and remove __io_iopoll_check().
--- fs/io_uring.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-)
fs/io_uring.c +9 -18
@@ -882,11 +882,17 @@ static void io_iopoll_reap_events(structmutex_unlock (&ctx->uring_lock); } -static int __io_iopoll_check (struct io_ring_ctx *ctx,unsigned *nr_events, -long min) +static int io_iopoll_check (struct io_ring_ctx *ctx,unsigned *nr_events, +long min) {int iters =0 , ret =0 ; +/* +* We disallow the app entering submit/complete with polling, but we +* still need to lock the ring to prevent racing with polled issue +* that got punted to a workqueue. +*/ +mutex_lock (&ctx->uring_lock); do { int tmin = 0;
@@ -922,21 +928,6 @@ static int __io_iopoll_check(struct io_r ret =0 ; }while (min && !*nr_events && !need_resched ()); -return ret; -} - -static int io_iopoll_check (struct io_ring_ctx *ctx,unsigned *nr_events, -long min) -{ -int ret; - -/* -* We disallow the app entering submit/complete with polling, but we -* still need to lock the ring to prevent racing with polled issue -* that got punted to a workqueue. -*/ -mutex_lock (&ctx->uring_lock); - ret =__io_iopoll_check (ctx, nr_events, min);mutex_unlock (&ctx->uring_lock);return ret; }
@@ -2721,7 +2712,7 @@ static int io_sq_thread(void *data)*/ mutex_lock (&ctx->uring_lock);if (!list_empty (&ctx->poll_list)) -__io_iopoll_check (ctx, &nr_events,0 ); +io_iopoll_getevents (ctx, &nr_events,0 );else inflight =0 ;mutex_unlock (&ctx->uring_lock);
Greg Kroah-Hartman
maintainerPATCH 122/135 ALSA: rawmidi: Avoid bit fields for state flags
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit dfa9a5efe8b932a84b3b319250aa3ac60c20f876 upstream.
The rawmidi state flags (opened, append, active_sensing) are stored in bit fields that can be potentially racy when concurrently accessed without any locks. Although the current code should be fine, there is also no any real benefit by keeping the bitfields for this kind of short number of members.
This patch changes those bit fields flags to the simple bool fields. There should be no size increase of the snd_rawmidi_substream by this change.
--- include/sound/rawmidi.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
include/sound/rawmidi.h +3 -3
@@ -77,9 +77,9 @@ struct snd_rawmidi_substream {struct list_head list;/* list of all substream for given stream */ int stream;/* direction */ int number;/* substream number */ - unsigned int opened: 1, /* open flag */ - append: 1, /* append flag (merge more streams) */ - active_sensing: 1; /* send active sensing when close */ +bool opened;/* open flag */ +bool append;/* append flag (merge more streams) */ +bool active_sensing;/* send active sensing when close */ int use_count;/* use counter (for output) */ size_t bytes;struct snd_rawmidi *rmidi;
Greg Kroah-Hartman
maintainerPATCH 123/135 ALSA: seq: Avoid concurrent access to queue flags
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit bb51e669fa49feb5904f452b2991b240ef31bc97 upstream.
The queue flags are represented in bit fields and the concurrent access may result in unexpected results. Although the current code should be mostly OK as it's only reading a field while writing other fields as KCSAN reported, it's safer to cover both with a proper spinlock protection.
This patch fixes the possible concurrent read by protecting with q->owner_lock. Also the queue owner field is protected as well since it's the field to be protected by the lock itself.
--- sound/core/seq/seq_queue.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
sound/core/seq/seq_queue.c +16 -4
@@ -392,6 +392,7 @@ int snd_seq_queue_check_access(int queueint snd_seq_queue_set_owner (int queueid,int client,int locked) {struct snd_seq_queue *q =queueptr (queueid); +unsigned long flags;if (q ==NULL )return -EINVAL ;
@@ -401,8 +402,10 @@ int snd_seq_queue_set_owner(int queueid,return -EPERM ; } +spin_lock_irqsave (&q->owner_lock, flags); q->locked = locked ?1 :0 ; q->owner = client; +spin_unlock_irqrestore (&q->owner_lock, flags);queue_access_unlock (q);queuefree (q);
@@ -539,15 +542,17 @@ void snd_seq_queue_client_termination(inunsigned long flags;int i;struct snd_seq_queue *q; +bool matched;for (i =0 ; i <SNDRV_SEQ_MAX_QUEUES ; i++) {if ((q =queueptr (i)) ==NULL )continue ;spin_lock_irqsave (&q->owner_lock, flags); -if (q->owner == client) + matched = (q->owner == client); +if (matched) q->klocked =1 ;spin_unlock_irqrestore (&q->owner_lock, flags); -if (q->owner == client) { +if (matched) {if (q->timer->running)snd_seq_timer_stop (q->timer);snd_seq_timer_reset (q->timer);
@@ -739,6 +744,8 @@ void snd_seq_info_queues_read(struct sndint i, bpm;struct snd_seq_queue *q;struct snd_seq_timer *tmr; +bool locked; +int owner;for (i =0 ; i <SNDRV_SEQ_MAX_QUEUES ; i++) {if ((q =queueptr (i)) ==NULL )
@@ -750,9 +757,14 @@ void snd_seq_info_queues_read(struct sndelse bpm =0 ; +spin_lock_irq (&q->owner_lock); + locked = q->locked; + owner = q->owner; +spin_unlock_irq (&q->owner_lock); +snd_iprintf (buffer,"queue %d: [%s]\n" , q->queue, q->name); -snd_iprintf (buffer,"owned by client : %d\n" , q->owner); -snd_iprintf (buffer,"lock status : %s\n" , q->locked ?"Locked" :"Free" ); +snd_iprintf (buffer,"owned by client : %d\n" , owner); +snd_iprintf (buffer,"lock status : %s\n" , locked ?"Locked" :"Free" );snd_iprintf (buffer,"queued time events : %d\n" ,snd_seq_prioq_avail (q->timeq));snd_iprintf (buffer,"queued tick events : %d\n" ,snd_seq_prioq_avail (q->tickq));snd_iprintf (buffer,"timer state : %s\n" , tmr->running ?"Running" :"Stopped" );
Greg Kroah-Hartman
maintainerPATCH 124/135 ALSA: seq: Fix concurrent access to queue current tick/time
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit dc7497795e014d84699c3b8809ed6df35352dd74 upstream.
snd_seq_check_queue() passes the current tick and time of the given queue as a pointer to snd_seq_prioq_cell_out(), but those might be updated concurrently by the seq timer update.
Fix it by retrieving the current tick and time via the proper helper functions at first, and pass those values to snd_seq_prioq_cell_out() later in the loops.
snd_seq_timer_get_cur_time() takes a new argument and adjusts with the current system time only when it's requested so; this update isn't needed for snd_seq_check_queue(), as it's called either from the interrupt handler or right after queuing.
Also, snd_seq_timer_get_cur_tick() is changed to read the value in the spinlock for the concurrency, too.
--- sound/core/seq/seq_clientmgr.c | 4 ++-- sound/core/seq/seq_queue.c | 9 ++++++--- sound/core/seq/seq_timer.c | 13 ++++++++++--- sound/core/seq/seq_timer.h | 3 ++- 4 files changed, 20 insertions(+), 9 deletions(-)
sound/core/seq/seq_clientmgr.c +2 -2
@@ -580,7 +580,7 @@ static int update_timestamp_of_queue(str event->queue = queue; event->flags &= ~SNDRV_SEQ_TIME_STAMP_MASK ;if (real_time) { - event->time.time =snd_seq_timer_get_cur_time (q->timer); + event->time.time =snd_seq_timer_get_cur_time (q->timer, true); event->flags |=SNDRV_SEQ_TIME_STAMP_REAL ; }else { event->time.tick =snd_seq_timer_get_cur_tick (q->timer);
@@ -1659,7 +1659,7 @@ static int snd_seq_ioctl_get_queue_statu tmr = queue->timer; status->events = queue->tickq->cells + queue->timeq->cells; - status->time =snd_seq_timer_get_cur_time (tmr); + status->time =snd_seq_timer_get_cur_time (tmr, true); status->tick =snd_seq_timer_get_cur_tick (tmr); status->running = tmr->running;
sound/core/seq/seq_queue.c +6 -3
@@ -238,6 +238,8 @@ void snd_seq_check_queue(struct snd_seq_ {unsigned long flags;struct snd_seq_event_cell *cell; +snd_seq_tick_time_t cur_tick; +snd_seq_real_time_t cur_time;if (q ==NULL )return ;
@@ -254,17 +256,18 @@ void snd_seq_check_queue(struct snd_seq_ __again:/* Process tick queue... */ + cur_tick =snd_seq_timer_get_cur_tick (q->timer);for (;;) { - cell =snd_seq_prioq_cell_out (q->tickq, - &q->timer->tick.cur_tick); + cell =snd_seq_prioq_cell_out (q->tickq, &cur_tick);if (!cell)break ;snd_seq_dispatch_event (cell, atomic, hop); }/* Process time queue... */ + cur_time =snd_seq_timer_get_cur_time (q->timer, false);for (;;) { - cell =snd_seq_prioq_cell_out (q->timeq, &q->timer->cur_time); + cell =snd_seq_prioq_cell_out (q->timeq, &cur_time);if (!cell)break ;snd_seq_dispatch_event (cell, atomic, hop);
sound/core/seq/seq_timer.c +10 -3
@@ -422,14 +422,15 @@ int snd_seq_timer_continue(struct snd_se }/* return current 'real' time. use timeofday() to get better granularity. */ -snd_seq_real_time_t snd_seq_timer_get_cur_time (struct snd_seq_timer *tmr) +snd_seq_real_time_t snd_seq_timer_get_cur_time (struct snd_seq_timer *tmr, +bool adjust_ktime) {snd_seq_real_time_t cur_time;unsigned long flags;spin_lock_irqsave (&tmr->lock, flags); cur_time = tmr->cur_time; -if (tmr->running) { +if (adjust_ktime && tmr->running) {struct timespec64 tm;ktime_get_ts64 (&tm);
@@ -446,7 +447,13 @@ snd_seq_real_time_t snd_seq_timer_get_cuhigh PPQ values) */ snd_seq_tick_time_t snd_seq_timer_get_cur_tick (struct snd_seq_timer *tmr) { -return tmr->tick.cur_tick; +snd_seq_tick_time_t cur_tick; +unsigned long flags; + +spin_lock_irqsave (&tmr->lock, flags); + cur_tick = tmr->tick.cur_tick; +spin_unlock_irqrestore (&tmr->lock, flags); +return cur_tick; }
sound/core/seq/seq_timer.h +2 -1
@@ -120,7 +120,8 @@ int snd_seq_timer_set_tempo_ppq(struct sint snd_seq_timer_set_position_tick (struct snd_seq_timer *tmr,snd_seq_tick_time_t position);int snd_seq_timer_set_position_time (struct snd_seq_timer *tmr,snd_seq_real_time_t position);int snd_seq_timer_set_skew (struct snd_seq_timer *tmr,unsigned int skew,unsigned int base); -snd_seq_real_time_t snd_seq_timer_get_cur_time (struct snd_seq_timer *tmr); +snd_seq_real_time_t snd_seq_timer_get_cur_time (struct snd_seq_timer *tmr, +bool adjust_ktime);snd_seq_tick_time_t snd_seq_timer_get_cur_tick (struct snd_seq_timer *tmr);extern int seq_default_timer_class;
Greg Kroah-Hartman
maintainerPATCH 125/135 netfilter: xt_hashlimit: limit the max size of hashtable
In reply to Greg Kroah-HartmanFrom: Cong Wang <[email protected]>
commit 8d0015a7ab76b8b1e89a3e5f5710a6e5103f2dd5 upstream.
The user-specified hashtable size is unbound, this could easily lead to an OOM or a hung task as we hold the global mutex while allocating and initializing the new hashtable.
Add a max value to cap both cfg->size and cfg->max, as suggested by Florian.
--- net/netfilter/xt_hashlimit.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
net/netfilter/xt_hashlimit.c +10 -0
@@ -851,6 +851,8 @@ hashlimit_mt(const struct sk_buff *skb,return hashlimit_mt_common (skb, par, hinfo, &info->cfg,3 ); } +#define HASHLIMIT_MAX_SIZE 1048576 + static int hashlimit_mt_check_common(const struct xt_mtchk_param *par, struct xt_hashlimit_htable **hinfo, struct hashlimit_cfg3 *cfg,
@@ -861,6 +863,14 @@ static int hashlimit_mt_check_common(conif (cfg->gc_interval ==0 || cfg->expire ==0 )return -EINVAL ; +if (cfg->size >HASHLIMIT_MAX_SIZE ) { + cfg->size =HASHLIMIT_MAX_SIZE ; +pr_info_ratelimited ("size too large, truncated to %u\n" , cfg->size); + } +if (cfg->max >HASHLIMIT_MAX_SIZE ) { + cfg->max =HASHLIMIT_MAX_SIZE ; +pr_info_ratelimited ("max too large, truncated to %u\n" , cfg->max); + }if (par->family ==NFPROTO_IPV4 ) {if (cfg->srcmask >32 || cfg->dstmask >32 )return -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 126/135 rxrpc: Fix call RCU cleanup using non-bh-safe locks
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
commit 963485d436ccc2810177a7b08af22336ec2af67b upstream.
rxrpc_rcu_destroy_call(), which is called as an RCU callback to clean up a put call, calls rxrpc_put_connection() which, deep in its bowels, takes a number of spinlocks in a non-BH-safe way, including rxrpc_conn_id_lock and local->client_conns_lock. RCU callbacks, however, are normally called from softirq context, which can cause lockdep to notice the locking inconsistency.
To get lockdep to detect this, it's necessary to have the connection cleaned up on the put at the end of the last of its calls, though normally the clean up is deferred. This can be induced, however, by starting a call on an AF_RXRPC socket and then closing the socket without reading the reply.
Fix this by having rxrpc_rcu_destroy_call() punt the destruction to a workqueue if in softirq-mode and defer the destruction to process context.
Note that another way to fix this could be to add a bunch of bh-disable annotations to the spinlocks concerned - and there might be more than just those two - but that means spending more time with BHs disabled.
Note also that some of these places were covered by bh-disable spinlocks belonging to the rxrpc_transport object, but these got removed without the _bh annotation being retained on the next lock in.
--- net/rxrpc/call_object.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-)
net/rxrpc/call_object.c +19 -3
@@ -562,11 +562,11 @@ void rxrpc_put_call(struct rxrpc_call *c }/* -* Final call destruction under RCU. +* Final call destruction - but must be done in process context. */ -static void rxrpc_rcu_destroy_call (struct rcu_head *rcu) +static void rxrpc_destroy_call (struct work_struct *work) { - struct rxrpc_call *call = container_of(rcu, struct rxrpc_call, rcu); + struct rxrpc_call *call = container_of(work, struct rxrpc_call, processor);struct rxrpc_net *rxnet = call->rxnet;rxrpc_put_connection (call->conn);
@@ -579,6 +579,22 @@ static void rxrpc_rcu_destroy_call(struc }/* +* Final call destruction under RCU. +*/ +static void rxrpc_rcu_destroy_call (struct rcu_head *rcu) +{ + struct rxrpc_call *call = container_of(rcu, struct rxrpc_call, rcu); + +if (in_softirq ()) { +INIT_WORK (&call->processor, rxrpc_destroy_call); +if (!rxrpc_queue_work (&call->processor)) +BUG (); + }else { +rxrpc_destroy_call (&call->processor); + } +} + +/* * clean up a call */ void rxrpc_cleanup_call (struct rxrpc_call *call)
Greg Kroah-Hartman
maintainerPATCH 127/135 io_uring: prevent sq_thread from spinning when it should stop
In reply to Greg Kroah-HartmanFrom: Stefano Garzarella <[email protected]>
commit 7143b5ac5750f404ff3a594b34fdf3fc2f99f828 upstream.
This patch drops 'cur_mm' before calling cond_resched(), to prevent the sq_thread from spinning even when the user process is finished.
Before this patch, if the user process ended without closing the io_uring fd, the sq_thread continues to spin until the 'sq_thread_idle' timeout ends.
In the worst case where the 'sq_thread_idle' parameter is bigger than INT_MAX, the sq_thread will spin forever.
--- fs/io_uring.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
fs/io_uring.c +10 -10
@@ -2732,16 +2732,6 @@ static int io_sq_thread(void *data) to_submit =io_sqring_entries (ctx);if (!to_submit) {/* -* We're polling. If we're within the defined idle -* period, then let us spin without work before going -* to sleep. -*/ -if (inflight || !time_after (jiffies, timeout)) { -cond_resched (); -continue ; - } - -/* * Drop cur_mm before scheduling, we can't hold it for * long periods (or over schedule()). Do this before * adding ourselves to the waitqueue, as the unuse/drop
@@ -2753,6 +2743,16 @@ static int io_sq_thread(void *data) cur_mm =NULL ; } +/* +* We're polling. If we're within the defined idle +* period, then let us spin without work before going +* to sleep. +*/ +if (inflight || !time_after (jiffies, timeout)) { +cond_resched (); +continue ; + } +prepare_to_wait (&ctx->sqo_wait, &wait,TASK_INTERRUPTIBLE );
Greg Kroah-Hartman
maintainerPATCH 128/135 ata: ahci: Add shutdown to freeze hardware resources of ahci
In reply to Greg Kroah-HartmanFrom: Prabhakar Kushwaha <[email protected]>
commit 10a663a1b15134a5a714aa515e11425a44d4fdf7 upstream.
device_shutdown() called from reboot or power_shutdown expect all devices to be shutdown. Same is true for even ahci pci driver. As no ahci shutdown function is implemented, the ata subsystem always remains alive with DMA & interrupt support. File system related calls should not be honored after device_shutdown().
So defining ahci pci driver shutdown to freeze hardware (mask interrupt, stop DMA engine and free DMA resources).
--- drivers/ata/ahci.c | 7 +++++++ drivers/ata/libata-core.c | 21 +++++++++++++++++++++ include/linux/libata.h | 1 + 3 files changed, 29 insertions(+)
drivers/ata/ahci.c +7 -0
@@ -80,6 +80,7 @@ enum board_ids {static int ahci_init_one (struct pci_dev *pdev,const struct pci_device_id *ent);static void ahci_remove_one (struct pci_dev *dev); +static void ahci_shutdown_one (struct pci_dev *dev);static int ahci_vt8251_hardreset (struct ata_link *link,unsigned int *class,unsigned long deadline); static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
@@ -593,6 +594,7 @@ static struct pci_driver ahci_pci_driver .id_table = ahci_pci_tbl, .probe = ahci_init_one, .remove = ahci_remove_one, + .shutdown = ahci_shutdown_one, .driver = { .pm = &ahci_pci_pm_ops, },
@@ -1864,6 +1866,11 @@ static int ahci_init_one(struct pci_devreturn 0 ; } +static void ahci_shutdown_one (struct pci_dev *pdev) +{ +ata_pci_shutdown_one (pdev); +} +static void ahci_remove_one (struct pci_dev *pdev) {pm_runtime_get_noresume (&pdev->dev);
drivers/ata/libata-core.c +21 -0
@@ -6762,6 +6762,26 @@ void ata_pci_remove_one(struct pci_dev *ata_host_detach (host); } +void ata_pci_shutdown_one (struct pci_dev *pdev) +{ +struct ata_host *host =pci_get_drvdata (pdev); +int i; + +for (i =0 ; i < host->n_ports; i++) { +struct ata_port *ap = host->ports[i]; + + ap->pflags |=ATA_PFLAG_FROZEN ; + +/* Disable port interrupts */ +if (ap->ops->freeze) + ap->ops->freeze (ap); + +/* Stop the port DMA engines */ +if (ap->ops->port_stop) + ap->ops->port_stop (ap); + } +} +/* move to PCI subsystem */ int pci_test_config_bits (struct pci_dev *pdev,const struct pci_bits *bits) {
@@ -7382,6 +7402,7 @@ EXPORT_SYMBOL_GPL(ata_timing_cycle2mode)#ifdef CONFIG_PCI EXPORT_SYMBOL_GPL (pci_test_config_bits); +EXPORT_SYMBOL_GPL (ata_pci_shutdown_one);EXPORT_SYMBOL_GPL (ata_pci_remove_one);#ifdef CONFIG_PM EXPORT_SYMBOL_GPL (ata_pci_device_do_suspend);
include/linux/libata.h +1 -0
@@ -1220,6 +1220,7 @@ struct pci_bits { };extern int pci_test_config_bits (struct pci_dev *pdev,const struct pci_bits *bits); +extern void ata_pci_shutdown_one (struct pci_dev *pdev);extern void ata_pci_remove_one (struct pci_dev *pdev);#ifdef CONFIG_PM
Greg Kroah-Hartman
maintainerPATCH 129/135 xen: Enable interrupts when calling _cond_resched()
In reply to Greg Kroah-HartmanFrom: Thomas Gleixner <[email protected]>
commit 8645e56a4ad6dcbf504872db7f14a2f67db88ef2 upstream.
xen_maybe_preempt_hcall() is called from the exception entry point xen_do_hypervisor_callback with interrupts disabled.
_cond_resched() evades the might_sleep() check in cond_resched() which would have caught that and schedule_debug() unfortunately lacks a check for irqs_disabled().
Enable interrupts around the call and use cond_resched() to catch future issues.
--- drivers/xen/preempt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/xen/preempt.c +3 -1
@@ -33,7 +33,9 @@ asmlinkage __visible void xen_maybe_pree* cpu. */ __this_cpu_write (xen_in_preemptible_hcall, false); -_cond_resched (); +local_irq_enable (); +cond_resched (); +local_irq_disable ();__this_cpu_write (xen_in_preemptible_hcall, true); } }
Greg Kroah-Hartman
maintainerPATCH 130/135 net/mlx5e: Reset RQ doorbell counter before moving RQ state from RST to RDY
In reply to Greg Kroah-HartmanFrom: Aya Levin <[email protected]>
commit 5ee090ed0da649b1febae2b7c285ac77d1e55a0c upstream.
Initialize RQ doorbell counters to zero prior to moving an RQ from RST to RDY state. Per HW spec, when RQ is back to RDY state, the descriptor ID on the completion is reset. The doorbell record must comply.
--- drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h | 8 ++++ drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 3 + drivers/net/ethernet/mellanox/mlx5/core/wq.c | 39 ++++++++++++++++------ drivers/net/ethernet/mellanox/mlx5/core/wq.h | 2 + 4 files changed, 43 insertions(+), 9 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h +8 -0
@@ -179,6 +179,14 @@ mlx5e_tx_dma_unmap(struct device *pdev, } } +static inline void mlx5e_rqwq_reset (struct mlx5e_rq *rq) +{ +if (rq->wq_type ==MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ ) +mlx5_wq_ll_reset (&rq->mpwqe.wq); +else +mlx5_wq_cyc_reset (&rq->wqe.wq); +} +/* SW parser related functions */ struct mlx5e_swp_spec {
drivers/net/ethernet/mellanox/mlx5/core/en_main.c +3 -0
@@ -723,6 +723,9 @@ int mlx5e_modify_rq_state(struct mlx5e_rif (!in)return -ENOMEM ; +if (curr_state ==MLX5_RQC_STATE_RST && next_state ==MLX5_RQC_STATE_RDY ) +mlx5e_rqwq_reset (rq); + rqc =MLX5_ADDR_OF (modify_rq_in, in, ctx);MLX5_SET (modify_rq_in, in, rq_state, curr_state);
drivers/net/ethernet/mellanox/mlx5/core/wq.c +30 -9
@@ -96,6 +96,13 @@ err_db_free:return err; } +void mlx5_wq_cyc_reset (struct mlx5_wq_cyc *wq) +{ + wq->wqe_ctr =0 ; + wq->cur_sz =0 ; +mlx5_wq_cyc_update_db_record (wq); +} +int mlx5_wq_qp_create (struct mlx5_core_dev *mdev,struct mlx5_wq_param *param,void *qpc,struct mlx5_wq_qp *wq,struct mlx5_wq_ctrl *wq_ctrl)
@@ -194,6 +201,19 @@ err_db_free:return err; } +static void mlx5_wq_ll_init_list (struct mlx5_wq_ll *wq) +{ +struct mlx5_wqe_srq_next_seg *next_seg; +int i; + +for (i =0 ; i < wq->fbc.sz_m1; i++) { + next_seg =mlx5_wq_ll_get_wqe (wq, i); + next_seg->next_wqe_index =cpu_to_be16 (i +1 ); + } + next_seg =mlx5_wq_ll_get_wqe (wq, i); + wq->tail_next = &next_seg->next_wqe_index; +} +int mlx5_wq_ll_create (struct mlx5_core_dev *mdev,struct mlx5_wq_param *param,void *wqc,struct mlx5_wq_ll *wq,struct mlx5_wq_ctrl *wq_ctrl)
@@ -201,9 +221,7 @@ int mlx5_wq_ll_create(struct mlx5_core_du8 log_wq_stride =MLX5_GET (wq, wqc, log_wq_stride);u8 log_wq_sz =MLX5_GET (wq, wqc, log_wq_sz);struct mlx5_frag_buf_ctrl *fbc = &wq->fbc; -struct mlx5_wqe_srq_next_seg *next_seg;int err; -int i; err =mlx5_db_alloc_node (mdev, &wq_ctrl->db, param->db_numa_node);if (err) {
@@ -222,13 +240,7 @@ int mlx5_wq_ll_create(struct mlx5_core_dmlx5_init_fbc (wq_ctrl->buf.frags, log_wq_stride, log_wq_sz, fbc); -for (i =0 ; i < fbc->sz_m1; i++) { - next_seg =mlx5_wq_ll_get_wqe (wq, i); - next_seg->next_wqe_index =cpu_to_be16 (i +1 ); - } - next_seg =mlx5_wq_ll_get_wqe (wq, i); - wq->tail_next = &next_seg->next_wqe_index; - +mlx5_wq_ll_init_list (wq); wq_ctrl->mdev = mdev;return 0 ;
@@ -239,6 +251,15 @@ err_db_free:return err; } +void mlx5_wq_ll_reset (struct mlx5_wq_ll *wq) +{ + wq->head =0 ; + wq->wqe_ctr =0 ; + wq->cur_sz =0 ; +mlx5_wq_ll_init_list (wq); +mlx5_wq_ll_update_db_record (wq); +} +void mlx5_wq_destroy (struct mlx5_wq_ctrl *wq_ctrl) {mlx5_frag_buf_free (wq_ctrl->mdev, &wq_ctrl->buf);
drivers/net/ethernet/mellanox/mlx5/core/wq.h +2 -0
@@ -80,10 +80,12 @@ int mlx5_wq_cyc_create(struct mlx5_core_ void *wqc, struct mlx5_wq_cyc *wq, struct mlx5_wq_ctrl *wq_ctrl);u32 mlx5_wq_cyc_get_size (struct mlx5_wq_cyc *wq); +void mlx5_wq_cyc_reset (struct mlx5_wq_cyc *wq);int mlx5_wq_qp_create (struct mlx5_core_dev *mdev,struct mlx5_wq_param *param,void *qpc,struct mlx5_wq_qp *wq,struct mlx5_wq_ctrl *wq_ctrl); +void mlx5_wq_ll_reset (struct mlx5_wq_ll *wq); int mlx5_cqwq_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, void *cqc, struct mlx5_cqwq *wq,
Greg Kroah-Hartman
maintainerPATCH 131/135 net/mlx5: Fix sleep while atomic in mlx5_eswitch_get_vepa
In reply to Greg Kroah-HartmanFrom: Huy Nguyen <[email protected]>
commit 3d9c5e023a0dbf3e117bb416cfefd9405bf5af0c upstream.
rtnl_bridge_getlink is protected by rcu lock, so mlx5_eswitch_get_vepa cannot take mutex lock. Two possible issues can happen:
1. User at the same time change vepa mode via RTM_SETLINK command.
2. User at the same time change the switchdev mode via devlink netlink interface.
Case 1 cannot happen because rtnl executes one message in order. Case 2 can happen but we do not expect user to change the switchdev mode when changing vepa. Even if a user does it, so he will read a value which is no longer valid.
--- drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +3 -11
@@ -2319,25 +2319,17 @@ out:int mlx5_eswitch_get_vepa (struct mlx5_eswitch *esw,u8 *setting) { -int err =0 ; -if (!esw)return -EOPNOTSUPP ;if (!ESW_ALLOWED (esw))return -EPERM ; -mutex_lock (&esw->state_lock); -if (esw->mode !=MLX5_ESWITCH_LEGACY ) { - err = -EOPNOTSUPP ; - goto out; - } +if (esw->mode !=MLX5_ESWITCH_LEGACY ) +return -EOPNOTSUPP ; *setting = esw->fdb_table.legacy.vepa_uplink_rule ?1 :0 ; - -out: -mutex_unlock (&esw->state_lock); -return err; +return 0 ; } int mlx5_eswitch_set_vport_trust(struct mlx5_eswitch *esw,
Greg Kroah-Hartman
maintainerPATCH 132/135 net/mlx5e: Fix crash in recovery flow without devlink reporter
In reply to Greg Kroah-HartmanFrom: Aya Levin <[email protected]>
commit 1ad6c43c6a7b8627240c6cc19c69e31fedc596a7 upstream.
When health reporters are not supported, recovery function is invoked directly, not via devlink health reporters.
In this direct flow, the recover function input parameter was passed incorrectly and is causing a kernel oops. This patch is fixing the input parameter.
Following call trace is observed on rx error health reporting.
Internal error: Oops: 96000007 [#1] PREEMPT SMP Process kworker/u16:4 (pid: 4584, stack limit = 0x00000000c9e45703) Call trace: mlx5e_rx_reporter_err_rq_cqe_recover+0x30/0x164 [mlx5_core] mlx5e_health_report+0x60/0x6c [mlx5_core] mlx5e_reporter_rq_cqe_err+0x6c/0x90 [mlx5_core] mlx5e_rq_err_cqe_work+0x20/0x2c [mlx5_core] process_one_work+0x168/0x3d0 worker_thread+0x58/0x3d0 kthread+0x108/0x134
--- drivers/net/ethernet/mellanox/mlx5/core/en/health.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/en/health.c +1 -1
@@ -200,7 +200,7 @@ int mlx5e_health_report(struct mlx5e_prinetdev_err (priv->netdev, err_str);if (!reporter) -return err_ctx->recover (&err_ctx->ctx); +return err_ctx->recover (err_ctx->ctx);return devlink_health_report (reporter, err_str, err_ctx); }
Greg Kroah-Hartman
maintainerPATCH 133/135 s390/kaslr: Fix casts in get_random
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
commit 788d671517b5c81efbed9310ccbadb8cca86a08e upstream.
Clang warns:
../arch/s390/boot/kaslr.c:78:25: warning: passing 'char *' to parameter of type 'const u8 *' (aka 'const unsigned char *') converts between pointers to integer
types with different sign [-Wpointer-sign]
(char *) entropy, (char *) entropy,
^~~~~~~~~~~~~~~~../arch/s390/include/asm/cpacf.h:280:28: note: passing argument to parameter 'src' here
u8 *dest, const u8 *src, long src_len)
^
2 warnings generated.
Fix the cast to match what else is done in this function.
--- arch/s390/boot/kaslr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/s390/boot/kaslr.c +1 -1
@@ -75,7 +75,7 @@ static unsigned long get_random(unsigned *(unsigned long *) prng.parm_block ^= seed;for (i =0 ; i <16 ; i++) {cpacf_kmc (CPACF_KMC_PRNG , prng.parm_block, - (char *) entropy, (char *) entropy, + (u8 *) entropy, (u8 *) entropy,sizeof (entropy));memcpy (prng.parm_block, entropy,sizeof (entropy)); }
Greg Kroah-Hartman
maintainerPATCH 134/135 s390/mm: Explicitly compare PAGE_DEFAULT_KEY against zero in storage_key_init_range
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
commit 380324734956c64cd060e1db4304f3117ac15809 upstream.
Clang warns:
In file included from ../arch/s390/purgatory/purgatory.c:10:
In file included from ../include/linux/kexec.h:18:
In file included from ../include/linux/crash_core.h:6:
In file included from ../include/linux/elfcore.h:5:
In file included from ../include/linux/user.h:1:
In file included from ../arch/s390/include/asm/user.h:11:
../arch/s390/include/asm/page.h:45:6: warning: converting the result of '<<' to a boolean always evaluates to false [-Wtautological-constant-compare]
if (PAGE_DEFAULT_KEY)
^
../arch/s390/include/asm/page.h:23:44: note: expanded from macro
'PAGE_DEFAULT_KEY'
#define PAGE_DEFAULT_KEY (PAGE_DEFAULT_ACC << 4)
^1 warning generated.
Explicitly compare this against zero to silence the warning as it is intended to be used in a boolean context.
--- arch/s390/include/asm/page.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/s390/include/asm/page.h +1 -1
@@ -42,7 +42,7 @@ void __storage_key_init_range(unsigned lstatic inline void storage_key_init_range (unsigned long start,unsigned long end) { -if (PAGE_DEFAULT_KEY ) +if (PAGE_DEFAULT_KEY !=0 )__storage_key_init_range (start, end); }
Greg Kroah-Hartman
maintainerPATCH 135/135 bpf: Selftests build error in sockmap_basic.c
In reply to Greg Kroah-HartmanFrom: John Fastabend <[email protected]>
commit f2e97dc126b712c0d21219ed0c42710006c1cf52 upstream.
Fix following build error. We could push a tcp.h header into one of the include paths, but I think its easy enough to simply pull in the three defines we need here. If we end up using more of tcp.h at some point we can pull it in later.
/home/john/git/bpf/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c: In function ‘connected_socket_v4’:/home/john/git/bpf/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c:20:11: error: ‘TCP_REPAIR_ON’ undeclared (first use in this function)
repair = TCP_REPAIR_ON;
^/home/john/git/bpf/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c:20:11: note: each undeclared identifier is reported only once for each function it appears in /home/john/git/bpf/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c:29:11: error: ‘TCP_REPAIR_OFF_NO_WP’ undeclared (first use in this function)
repair = TCP_REPAIR_OFF_NO_WP;
Then with fix,
$ ./test_progs -n 44 #44/1 sockmap create_update_free:OK #44/2 sockhash create_update_free:OK #44 sockmap_basic:OK
--- tools/testing/selftests/bpf/prog_tests/sockmap_basic.c | 5 +++++ 1 file changed, 5 insertions(+)
tools/testing/selftests/bpf/prog_tests/sockmap_basic.c +5 -0
@@ -3,6 +3,11 @@#include "test_progs.h" +#define TCP_REPAIR 19/* TCP sock is under repair right now */ + +#define TCP_REPAIR_ON 1 +#define TCP_REPAIR_OFF_NO_WP -1/* Turn off without window probes */ +static int connected_socket_v4 (void ) {struct sockaddr_in addr = {
Jon Hunter
maintainerQuoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.23 release. There are 135 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 Sat, 29 Feb 2020 13:21:24 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.23-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.4.y
and the diffstat can be found below.thanks,
greg k-h
All tests are passing for Tegra ...
Test results for stable-v5.4:
13 builds: 13 pass, 0 fail
22 boots: 22 pass, 0 fail
40 tests: 40 pass, 0 failLinux version: 5.4.23-rc1-g8550aa6c7855
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra194-p2972-0000, tegra20-ventana,
tegra210-p2371-2180, tegra210-p3450-0000,
tegra30-cardhu-a04Cheers
Jon
Signature · 1 line
nvpublic
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.23 release. There are 135 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 Sat, 29 Feb 2020 13:21:24 +0000. Anything received after that time might be too late.
Build results:
total: 158 pass: 158 fail: 0 Qemu test results: total: 415 pass: 415 fail: 0
Guenter
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.23 release. There are 135 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 Sat, 29 Feb 2020 13:21:24 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.23-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.4.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.23 release. There are 135 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 Sat, 29 Feb 2020 13:21:24 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.23-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.4.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
Summary
------------------------------------------------------------------------
kernel: 5.4.23-rc1
git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
git branch: linux-5.4.y
git commit: 8550aa6c78553db799becfc53c7e7890602862d6
git describe: v5.4.22-136-g8550aa6c7855
Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-5.4-oe/build/v5.4.22-136-g8550aa6c7855
No regressions (compared to build v5.4.22)
No fixes (compared to build v5.4.22)
Ran 30904 total tests in the following environments and test suites.
Environments
--------------
- dragonboard-410c
- hi6220-hikey
- i386
- juno-r2
- nxp-ls2088
- qemu_arm
- qemu_arm64
- qemu_i386
- qemu_x86_64
- x15
- x86
Test Suites
-----------
* build
* install-android-platform-tools-r2600
* kselftest
* libgpiod
* libhugetlbfs
* linux-log-parser
* ltp-cap_bounds-tests
* ltp-commands-tests
* ltp-containers-tests
* ltp-cpuhotplug-tests
* ltp-cve-tests
* ltp-dio-tests
* ltp-fcntl-locktests-tests
* ltp-filecaps-tests
* ltp-fs_bind-tests
* ltp-fs_perms_simple-tests
* ltp-fsx-tests
* ltp-hugetlb-tests
* ltp-io-tests
* ltp-ipc-tests
* ltp-math-tests
* ltp-mm-tests
* ltp-nptl-tests
* ltp-pty-tests
* ltp-sched-tests
* ltp-securebits-tests
* ltp-syscalls-tests
* perf
* spectre-meltdown-checker-test
* v4l2-compliance
* ltp-fs-tests
* network-basic-tests
* ltp-open-posix-tests
* kvm-unit-tests
* ltp-cap_bounds-64k-page_size-tests
* ltp-cap_bounds-kasan-tests
* ltp-commands-64k-page_size-tests
* ltp-commands-kasan-tests
* ltp-containers-64k-page_size-tests
* ltp-containers-kasan-tests
* ltp-cpuhotplug-64k-page_size-tests
* ltp-cpuhotplug-kasan-tests
* ltp-crypto-64k-page_size-tests
* ltp-crypto-kasan-tests
* ltp-crypto-tests
* ltp-cve-64k-page_size-tests
* ltp-cve-kasan-tests
* ltp-dio-64k-page_size-tests
* ltp-dio-kasan-tests
* ltp-fcntl-locktests-64k-page_size-tests
* ltp-fcntl-locktests-kasan-tests
* ltp-filecaps-64k-page_size-tests
* ltp-filecaps-kasan-tests
* ltp-fs-64k-page_size-tests
* ltp-fs-kasan-tests
* ltp-fs_bind-64k-page_size-tests
* ltp-fs_bind-kasan-tests
* ltp-fs_perms_simple-64k-page_size-tests
* ltp-fs_perms_simple-kasan-tests
* ltp-fsx-64k-page_size-tests
* ltp-fsx-kasan-tests
* ltp-hugetlb-64k-page_size-tests
* ltp-io-64k-page_size-tests
* ltp-io-kasan-tests
* ltp-ipc-64k-page_size-tests
* ltp-ipc-kasan-tests
* ltp-math-64k-page_size-tests
* ltp-math-kasan-tests
* ltp-nptl-64k-page_size-tests
* ltp-nptl-kasan-tests
* ltp-pty-64k-page_size-tests
* ltp-pty-kasan-tests
* ltp-sched-64k-page_size-tests
* ltp-sched-kasan-tests
* ltp-securebits-64k-page_size-tests
* ltp-securebits-kasan-tests
* ltp-syscalls-64k-page_size-tests
* ltp-syscalls-compat-tests
* ltp-syscalls-kasan-tests
* kselftest-vsyscall-mode-native
* kselftest-vsyscall-mode-none
* ssuite
Signature · 2 lines
Linaro LKFT https://lkft.linaro.org