Skip to contentSkip to conversation

5.5.3-stable review

PATCH In review Greg Kroah-Hartman 10 participants 385 messages Feb 10, 2020 – Feb 12, 2020 Page 1 of 3

Subsystems (3)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 5.5.3-stable review

This is the start of the stable review cycle for the 5.5.3 release. There are 367 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Wed, 12 Feb 2020 12:18:57 +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.5.3-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.5.y
and the diffstat can be found below.

thanks,

greg k-h

-------------
Pseudo-Shortlog of commits:

Greg Kroah-Hartman <[email protected]>

    Linux 5.5.3-rc1

Christophe Leroy <[email protected]>
powerpc/kuap: Fix set direction in allow/prevent_user_access()

Stephen Rothwell <[email protected]>
regulator fix for "regulator: core: Add regulator_is_equal() helper"

Tudor Ambarus <[email protected]>
crypto: atmel-tdes - Map driver data flags to Mode Register

Tudor Ambarus <[email protected]>
crypto: atmel-aes - Fix CTR counter overflow when multiple fragments

Tudor Ambarus <[email protected]>
crypto: atmel-aes - Fix saving of IV for CTR mode

Tudor Ambarus <[email protected]>
crypto: atmel-{aes,tdes} - Do not save IV for ECB mode

Arnd Bergmann <[email protected]>
IB/core: Fix build failure without hugepages

David Howells <[email protected]>
rxrpc: Fix service call disconnection

Sean Christopherson <[email protected]>
KVM: Play nice with read-only memslots when querying host page size

Sean Christopherson <[email protected]>

    KVM: Use vcpu-specific gva->hva translation when querying host page size

Miaohe Lin <[email protected]>
KVM: nVMX: vmread should not set rflags to specify success in case of #PF

Marios Pomonis <[email protected]>
KVM: x86: Protect exit_reason from being used in Spectre-v1/L1TF attacks

Jens Axboe <[email protected]>
io_uring: prevent potential eventfd recursion on poll

Sasha Levin <[email protected]>
io_uring: enable option to only trigger eventfd for async completions

Wayne Lin <[email protected]>
drm/dp_mst: Remove VCPI while disabling topology mgr

Song Liu <[email protected]>
perf/cgroups: Install cgroup events to correct cpuctx

Song Liu <[email protected]>
perf/core: Fix mlock accounting in perf_mmap()

Konstantin Khlebnikov <[email protected]>
clocksource: Prevent double add_timer_on() for watchdog_timer

Thomas Gleixner <[email protected]>
x86/apic/msi: Plug non-maskable MSI affinity race

Aurelien Aptel <[email protected]>
cifs: fix mode bits from dir listing when mounted with modefromsid

Ronnie Sahlberg <[email protected]>
cifs: fail i/o on soft mounts if sessionsetup errors out

Tariq Toukan <[email protected]>
net/mlx5e: TX, Error completion is for last WQE in batch

Heiner Kallweit <[email protected]>
r8169: fix performance regression related to PCIe max read request size

Tariq Toukan <[email protected]>
net/mlx5: Deprecate usage of generic TLS HW capability bit

Maor Gottlieb <[email protected]>
net/mlx5: Fix deadlock in fs_core

Ido Schimmel <[email protected]>
drop_monitor: Do not cancel uninitialized work item

Sudarsana Reddy Kalluru <[email protected]>
qed: Fix timestamping issue for L2 unicast ptp packets.

Eric Dumazet <[email protected]>
ipv6/addrconf: fix potential NULL deref in inet6_set_link_af()

Vinicius Costa Gomes <[email protected]>
taprio: Fix dropping packets when using taprio + ETF offloading

Vinicius Costa Gomes <[email protected]>
taprio: Use taprio_reset_tc() to reset Traffic Classes configuration

Vinicius Costa Gomes <[email protected]>
taprio: Add missing policy validation for flags

Vinicius Costa Gomes <[email protected]>
taprio: Fix still allowing changing the flags during runtime

Vinicius Costa Gomes <[email protected]>
taprio: Fix enabling offload with wrong number of traffic classes

Voon Weifeng <[email protected]>
net: stmmac: update pci platform data to use phy_interface

Tan, Tee Min <[email protected]>
net: stmmac: xgmac: fix missing IFF_MULTICAST checki in dwxgmac2_set_filter

Verma, Aashish <[email protected]>
net: stmmac: fix missing IFF_MULTICAST check in dwmac4_set_filter

Ong Boon Leong <[email protected]>
net: stmmac: xgmac: fix incorrect XGMAC_VLAN_TAG register writting

Tan, Tee Min <[email protected]>
net: stmmac: fix incorrect GMAC_VLAN_TAG register writting in GMAC4+

Harini Katakam <[email protected]>
net: macb: Limit maximum GEM TX length in TSO

Harini Katakam <[email protected]>
net: macb: Remove unnecessary alignment check for TSO

Raed Salem <[email protected]>
net/mlx5: IPsec, fix memory leak at mlx5_fpga_ipsec_delete_sa_ctx

Raed Salem <[email protected]>
net/mlx5: IPsec, Fix esp modify function attribute

Florian Fainelli <[email protected]>
net: systemport: Avoid RBUF stuck in Wake-on-LAN mode

Dejin Zheng <[email protected]>
net: stmmac: fix a possible endless loop

Cong Wang <[email protected]>
net_sched: fix a resource leak in tcindex_set_parms()

Lorenzo Bianconi <[email protected]>
net: mvneta: move rx_dropped and rx_errors in per-cpu stats

Razvan Stefanescu <[email protected]>
net: dsa: microchip: enable module autoprobe

Florian Fainelli <[email protected]>
net: dsa: bcm_sf2: Only 7278 supports 2Gb/sec IMP port

Florian Fainelli <[email protected]>

    net: dsa: b53: Always use dev->vlan_enabled in b53_configure_vlan()

Madalin Bucur <[email protected]>
dpaa_eth: support all modes with rate adapting PHYs

Jacob Keller <[email protected]>
devlink: report 0 after hitting end in region read

Eric Dumazet <[email protected]>
bonding/alb: properly access headers in bond_alb_xmit()

Thomas Gleixner <[email protected]>
x86/timer: Don't skip PIT setup when APIC is disabled or in legacy mode

Andrii Nakryiko <[email protected]>
libbpf: Extract and generalize CPU mask parsing logic

Alexei Starovoitov <[email protected]>
bpf: Fix trampoline usage in preempt

Linus Walleij <[email protected]>

    mfd: ab8500: Fix ab8500-clk typo

Matti Vaittinen <[email protected]>
mfd: bd70528: Fix hour register mask

Andreas Kemnade <[email protected]>
mfd: rn5t618: Mark ADC control register volatile

Marco Felsch <[email protected]>
mfd: da9062: Fix watchdog compatible string

Cezary Rojewski <[email protected]>
ASoC: Intel: skl_hda_dsp_common: Fix global-out-of-bounds bug

Marek Vasut <[email protected]>
ASoC: sgtl5000: Fix VDDA and VDDIO comparison

Marek Vasut <[email protected]>
regulator: core: Add regulator_is_equal() helper

Quanyang Wang <[email protected]>

    ubifs: Fix memory leak from c->sup_node

Dan Carpenter <[email protected]>
ubi: Fix an error pointer dereference in error handling code

Sascha Hauer <[email protected]>
ubi: fastmap: Fix inverted logic in seen selfcheck

David Hildenbrand <[email protected]>
virtio_balloon: Fix memory leaks on errors in virtballoon_probe()

David Hildenbrand <[email protected]>
virtio-balloon: Fix memory leak when unloading while hinting is in progress

Trond Myklebust <[email protected]>
nfsd: Return the correct number of bytes written to the file

Arnd Bergmann <[email protected]>
nfsd: fix jiffies/time_t mixup in LRU list

Arnd Bergmann <[email protected]>
nfsd: fix delay timer on 32-bit architectures

Jérôme Pouiller <[email protected]>
staging: wfx: revert unexpected change in debugfs output

Yishai Hadas <[email protected]>
IB/core: Fix ODP with IB_ACCESS_HUGETLB handling

Yishai Hadas <[email protected]>
IB/core: Fix ODP get user pages flow

Prabhath Sajeepa <[email protected]>
IB/mlx5: Fix outstanding_pi index for GSI qps

Nathan Chancellor <[email protected]>
net: tulip: Adjust indentation in {dmfe, uli526x}_init_module

Nathan Chancellor <[email protected]>
net: smc911x: Adjust indentation in smc911x_phy_configure

Nathan Chancellor <[email protected]>
ppp: Adjust indentation into ppp_async_input

Nathan Chancellor <[email protected]>
NFC: pn544: Adjust indentation in pn544_hci_check_presence

Nathan Chancellor <[email protected]>
drm: msm: mdp4: Adjust indentation in mdp4_dsi_encoder_enable

Nathan Chancellor <[email protected]>
powerpc/44x: Adjust indentation in ibm4xx_denali_fixup_memsize

Nathan Chancellor <[email protected]>
ext2: Adjust indentation in ext2_fill_super

Nathan Chancellor <[email protected]>
phy: qualcomm: Adjust indentation in read_poll_timeout

Vignesh Raghavendra <[email protected]>

    mtd: spi-nor: Split mt25qu512a (n25q512a) entry into two

Arnd Bergmann <[email protected]>
compat: scsi: sg: fix v3 compat read/write interface

Asutosh Das <[email protected]>
scsi: ufs: Recheck bkops level if bkops is disabled

Nathan Chancellor <[email protected]>
scsi: qla4xxx: Adjust indentation in qla4xxx_mem_free

Nathan Chancellor <[email protected]>
scsi: csiostor: Adjust indentation in csio_device_reset

Bart Van Assche <[email protected]>
scsi: qla2xxx: Fix the endianness of the qla82xx_get_fw_size() return type

Jerome Brunet <[email protected]>
ASoC: meson: axg-fifo: fix fifo threshold setup

Erdem Aktas <[email protected]>
percpu: Separate decrypted varaibles anytime encryption can be enabled

Casey Schaufler <[email protected]>
broken ping to ipv6 linklocal addresses on debian buster

Miklos Szeredi <[email protected]>
fix up iter on short count in fuse_direct_io()

Daniel Verkamp <[email protected]>
virtio-pci: check name when counting MSI-X vectors

Daniel Verkamp <[email protected]>
virtio-balloon: initialize all vq callbacks

Matt Coffin <[email protected]>
drm/amdgpu/smu_v11_0: Correct behavior of restoring default tables (v2)

Alex Deucher <[email protected]>
drm/amdgpu/navi10: add OD_RANGE for navi overclocking

Alex Deucher <[email protected]>
drm/amdgpu: fetch default VDDC curve voltages (v2)

Lyude Paul <[email protected]>
drm/amd/dm/mst: Ignore payload update failures

Evan Quan <[email protected]>
drm/amd/powerplay: fix navi10 system intermittent reboot issue V2

Thierry Reding <[email protected]>
drm/tegra: Reuse IOVA mapping where possible

Thierry Reding <[email protected]>
drm/tegra: Relax IOMMU usage criteria on old Tegra

Alex Deucher <[email protected]>
drm/amdgpu/navi: fix index for OD MCLK

Stephen Warren <[email protected]>
clk: tegra: Mark fuse clock as critical

Peter Zijlstra <[email protected]>
mm/mmu_gather: invalidate TLB correctly on batch allocation failure and flush

Niklas Cassel <[email protected]>
arm64: dts: qcom: qcs404-evb: Set vdd_apc regulator in high power mode

David Hildenbrand <[email protected]>
mm/page_alloc.c: fix uninitialized memmaps on a partially populated last section

Gang He <[email protected]>
ocfs2: fix oops when writing cloned file

Paolo Bonzini <[email protected]>
KVM: x86: use raw clock values consistently

Paolo Bonzini <[email protected]>
KVM: x86: reorganize pvclock_gtod_data members

Christian Borntraeger <[email protected]>
KVM: s390: do not clobber registers during guest reset/store status

Sean Christopherson <[email protected]>
KVM: x86: Revert "KVM: X86: Fix fpu state crash in kvm guest"

Sean Christopherson <[email protected]>
KVM: x86: Ensure guest's FPU state is loaded when accessing for emulation

Sean Christopherson <[email protected]>
KVM: x86: Handle TIF_NEED_FPU_LOAD in kvm_{load,put}_guest_fpu()

Paolo Bonzini <[email protected]>
KVM: x86: fix overlap between SPTE_MMIO_MASK and generation

Sean Christopherson <[email protected]>
KVM: x86: Free wbinvd_dirty_mask if vCPU creation fails

Sean Christopherson <[email protected]>
KVM: x86: Don't let userspace set host-reserved cr4 bits

Sean Christopherson <[email protected]>
KVM: VMX: Add non-canonical check on writes to RTIT address MSRs

Sean Christopherson <[email protected]>
KVM: x86: Use gpa_t for cr2/gpa to fix TDP support on 32-bit KVM

Boris Ostrovsky <[email protected]>
x86/KVM: Clean up host's steal time structure

Boris Ostrovsky <[email protected]>
x86/kvm: Cache gfn to pfn translation

Boris Ostrovsky <[email protected]>
x86/KVM: Make sure KVM_VCPU_FLUSH_TLB flag is not missed

Boris Ostrovsky <[email protected]>

    x86/kvm: Introduce kvm_(un)map_gfn()

Paolo Bonzini <[email protected]>
KVM: x86: use CPUID to locate host page table reserved bits

Boris Ostrovsky <[email protected]>
x86/kvm: Be careful not to clear KVM_VCPU_FLUSH_TLB bit

Sean Christopherson <[email protected]>
KVM: x86/mmu: Apply max PA check for MMIO sptes to 32-bit KVM

John Allen <[email protected]>
kvm/svm: PKU not currently supported

Sean Christopherson <[email protected]>
KVM: PPC: Book3S PR: Free shared page if mmu initialization fails

Sean Christopherson <[email protected]>
KVM: PPC: Book3S HV: Uninit vCPU if vcore creation fails

Sean Christopherson <[email protected]>
KVM: x86: Fix potential put_fpu() w/o load_fpu() on MPX platform

Marios Pomonis <[email protected]>
KVM: x86: Protect MSR-based index computations in fixed_msr_to_seg_unit() from Spectre-v1/L1TF attacks

Marios Pomonis <[email protected]>
KVM: x86: Protect x86_decode_insn from Spectre-v1/L1TF attacks

Marios Pomonis <[email protected]>
KVM: x86: Protect MSR-based index computations from Spectre-v1/L1TF attacks in x86.c

Marios Pomonis <[email protected]>
KVM: x86: Protect ioapic_read_indirect() from Spectre-v1/L1TF attacks

Marios Pomonis <[email protected]>
KVM: x86: Protect MSR-based index computations in pmu.h from Spectre-v1/L1TF attacks

Marios Pomonis <[email protected]>
KVM: x86: Protect ioapic_write_indirect() from Spectre-v1/L1TF attacks

Marios Pomonis <[email protected]>
KVM: x86: Protect kvm_hv_msr_[get|set]_crash_data() from Spectre-v1/L1TF attacks

Marios Pomonis <[email protected]>
KVM: x86: Protect kvm_lapic_reg_write() from Spectre-v1/L1TF attacks

Marios Pomonis <[email protected]>
KVM: x86: Protect DR-based index computations from Spectre-v1/L1TF attacks

Marios Pomonis <[email protected]>
KVM: x86: Protect pmu_intel.c from Spectre-v1/L1TF attacks

Marios Pomonis <[email protected]>
KVM: x86: Refactor prefix decoding to prevent Spectre-v1/L1TF attacks

Marios Pomonis <[email protected]>
KVM: x86: Refactor picdev_write() to prevent Spectre-v1/L1TF attacks

Jens Axboe <[email protected]>
aio: prevent potential eventfd recursion on poll

Jens Axboe <[email protected]>
eventfd: track eventfd_signal() recursion depth

Jens Axboe <[email protected]>
io_uring: spin for sq thread to idle on shutdown

Jens Axboe <[email protected]>
io_uring: don't map read/write iovec potentially twice

Coly Li <[email protected]>
bcache: add readahead cache policy options via sysfs interface

Vladis Dronov <[email protected]>
watchdog: fix UAF in reboot notifier handling in watchdog core code

Boris Ostrovsky <[email protected]>
xen/gntdev: Do not use mm notifiers with autotranslating guests

Juergen Gross <[email protected]>
xen/balloon: Support xend-based toolstack take two

Gavin Shan <[email protected]>
tools/kvm_stat: Fix kvm_exit filter name

Sean Young <[email protected]>
media: rc: ensure lirc is initialized before registering input device

Johan Hovold <[email protected]>
media: iguanair: fix endpoint sanity check

Ville Syrjälä <[email protected]>
drm/rect: Avoid division by zero

Peter Rosin <[email protected]>
drm: atmel-hlcdc: prefer a lower pixel-clock than requested

Claudiu Beznea <[email protected]>
drm: atmel-hlcdc: enable clock before configuring timing engine

Claudiu Beznea <[email protected]>
drm: atmel-hlcdc: use double rate for pixel clock only if supported

Andreas Gruenbacher <[email protected]>
gfs2: fix O_SYNC write handling

Christoph Hellwig <[email protected]>

    gfs2: move setting current->backing_dev_info

Abhi Das <[email protected]>
gfs2: fix gfs2_find_jhead that returns uninitialized jhead with seq 0

Roberto Bergantinos Corpas <[email protected]>
sunrpc: expiry_time should be seconds not timeval

Brian Norris <[email protected]>
mwifiex: fix unbalanced locking in mwifiex_process_country_ie()

Luca Coelho <[email protected]>
iwlwifi: don't throw error when trying to remove IGTK

Stephen Warren <[email protected]>
ARM: tegra: Enable PLLP bypass during Tegra124 LP1

Filipe Manana <[email protected]>
Btrfs: send, fix emission of invalid clone operations within the same file

Nikolay Borisov <[email protected]>
btrfs: Correctly handle empty trees in find_first_clear_extent_bit

Josef Bacik <[email protected]>
btrfs: flush write bio if we loop in extent_write_cache_pages

Filipe Manana <[email protected]>
Btrfs: fix race between adding and putting tree mod seq elements and nodes

Josef Bacik <[email protected]>
btrfs: free block groups after free'ing fs trees

Josef Bacik <[email protected]>
btrfs: drop log root for dropped roots

Josef Bacik <[email protected]>

    btrfs: set trans->drity in btrfs_commit_transaction

Filipe Manana <[email protected]>
Btrfs: fix infinite loop during fsync after rename operations

Filipe Manana <[email protected]>
Btrfs: make deduplication with range including the last block work

Filipe Manana <[email protected]>
Btrfs: fix missing hole after hole punching and fsync when using NO_HOLES

Eric Biggers <[email protected]>

    ext4: fix race conditions in ->d_compare() and ->d_hash()

Eric Biggers <[email protected]>
ext4: fix deadlock allocating crypto bounce page from mempool

Vasily Averin <[email protected]>
jbd2_seq_info_next should increase position index

Trond Myklebust <[email protected]>
nfsd: fix filecache lookup

Trond Myklebust <[email protected]>
NFS: Directory page cache pages need to be locked when read

Trond Myklebust <[email protected]>
NFS: Fix memory leaks and corruption in readdir

Arun Easi <[email protected]>
scsi: qla2xxx: Fix unbound NVME response length

Michael Ellerman <[email protected]>
powerpc/futex: Fix incorrect user access blocking

Chuhong Yuan <[email protected]>
crypto: picoxcell - adjust the position of tasklet_init and fix missed tasklet_kill

Herbert Xu <[email protected]>
crypto: api - Fix race condition in crypto_spawn_alg

Tudor Ambarus <[email protected]>
crypto: atmel-aes - Fix counter overflow in CTR mode

Eric Biggers <[email protected]>
crypto: hisilicon - select CRYPTO_SKCIPHER, not CRYPTO_BLKCIPHER

Herbert Xu <[email protected]>
crypto: pcrypt - Do not clear MAY_SLEEP flag in original request

Ard Biesheuvel <[email protected]>
crypto: arm64/ghash-neon - bump priority to 150

Ard Biesheuvel <[email protected]>
crypto: ccp - set max RSA modulus size for v3 platform devices as well

Jonathan Cameron <[email protected]>
crypto: hisilicon - Use the offset fields in sqe to avoid need to split scatterlists

Jonathan Cameron <[email protected]>
crypto: hisilicon - Fix issue with wrong number of sg elements after dma map

Herbert Xu <[email protected]>
crypto: api - fix unexpectedly getting generic implementation

Corentin Labbe <[email protected]>
crypto: sun8i-ce - fix removal of module

Corentin Labbe <[email protected]>
crypto: amlogic - fix removal of module

Corentin Labbe <[email protected]>
crypto: sun8i-ss - fix removal of module

Lorenz Bauer <[email protected]>
selftests: bpf: Ignore FIN packets for reuseport tests

Lorenz Bauer <[email protected]>
selftests: bpf: Use a temporary file in test_sockmap

Hangbin Liu <[email protected]>
selftests/bpf: Skip perf hw events test if the setup disabled it

Alexei Starovoitov <[email protected]>
selftests/bpf: Fix test_attach_probe

Prashant Bhole <[email protected]>
samples/bpf: Reintroduce missed build targets

Jesper Dangaard Brouer <[email protected]>
samples/bpf: Xdp_redirect_cpu fix missing tracepoint attach

Toke Høiland-Jørgensen <[email protected]>
samples/bpf: Don't try to remove user's homedir on clean

Davide Caratti <[email protected]>
tc-testing: fix eBPF tests failure on linux fresh clones

Andrii Nakryiko <[email protected]>
libbpf: Fix realloc usage in bpf_core_find_cands

Toke Høiland-Jørgensen <[email protected]>
libbpf: Add missing newline in opts validation macro

Amol Grover <[email protected]>
bpf, devmap: Pass lockdep expression to RCU lists

Yoshiki Komachi <[email protected]>
flow_dissector: Fix to use new variables for port ranges in bpf hook

Andrii Nakryiko <[email protected]>
selftests/bpf: Fix perf_buffer test on systems w/ offline CPUs

Andrii Nakryiko <[email protected]>
libbpf: Don't attach perf_buffer to offline/missing CPUs

Andrii Nakryiko <[email protected]>
libbpf: Fix printf compilation warnings on ppc64le arch

Thadeu Lima de Souza Cascardo <[email protected]>
libbpf: Fix readelf output parsing for Fedora

Björn Töpel <[email protected]>
riscv, bpf: Fix broken BPF tail calls

Nikolay Borisov <[email protected]>
btrfs: Handle another split brain scenario with metadata uuid feature

Josef Bacik <[email protected]>
btrfs: fix improper setting of scanned for range cyclic write cache pages

Herbert Xu <[email protected]>
crypto: pcrypt - Avoid deadlock by using per-instance padata queues

Steven Rostedt (VMware) <[email protected]>
ftrace: Protect ftrace_graph_hash with ftrace_sync

Steven Rostedt (VMware) <[email protected]>
ftrace: Add comment to why rcu_dereference_sched() is open coded

Amol Grover <[email protected]>
tracing: Annotate ftrace_graph_notrace_hash pointer with __rcu

Amol Grover <[email protected]>
tracing: Annotate ftrace_graph_hash pointer with __rcu

Pierre-Louis Bossart <[email protected]>
ASoC: SOF: core: release resources on errors in probe_continue

Ranjani Sridharan <[email protected]>
ASoC: SOF: Introduce state machine for FW boot

Mike Snitzer <[email protected]>

    dm: fix potential for q->make_request_fn NULL pointer

Mike Snitzer <[email protected]>
dm thin: fix use-after-free in metadata_pre_commit_callback

Mike Snitzer <[email protected]>
dm thin metadata: use pool locking at end of dm_pool_metadata_close

Milan Broz <[email protected]>
dm crypt: fix benbi IV constructor crash if used in authenticated mode

Mikulas Patocka <[email protected]>
dm crypt: fix GFP flags passed to skcipher_request_alloc()

Mikulas Patocka <[email protected]>
dm writecache: fix incorrect flush sequence when doing SSD mode commit

Joe Thornber <[email protected]>
dm space map common: fix to ensure new block isn't already in use

Dmitry Fomichev <[email protected]>
dm zoned: support zone sizes smaller than 128MiB

Chen-Yu Tsai <[email protected]>
ARM: dma-api: fix max_pfn off-by-one error in __dma_supported()

Michael Ellerman <[email protected]>
of: Add OF_DMA_DEFAULT_COHERENT & select it on powerpc

Rafael J. Wysocki <[email protected]>
cpufreq: Avoid creating excessively large stack frames

Rafael J. Wysocki <[email protected]>
PM: core: Fix handling of devices deleted during system-wide resume

Eric Biggers <[email protected]>

    f2fs: fix race conditions in ->d_compare() and ->d_hash()

Eric Biggers <[email protected]>
f2fs: fix dcache lookup of !casefolded directories

Chengguang Xu <[email protected]>
f2fs: code cleanup for f2fs_statfs_project()

Chengguang Xu <[email protected]>
f2fs: fix miscounted block limit in f2fs_statfs_project()

Miklos Szeredi <[email protected]>
ovl: fix lseek overflow on 32bit

Amir Goldstein <[email protected]>
ovl: fix wrong WARN_ON() in ovl_cache_update_ino()

Sven Van Asbroeck <[email protected]>
power: supply: ltc2941-battery-gauge: fix use-after-free

Samuel Holland <[email protected]>

    power: supply: axp20x_ac_power: Fix reporting online status

Thomas Renninger <[email protected]>
cpupower: Revert library ABI changes from commit ae2917093fb60bdc1ed3e

Quinn Tran <[email protected]>
scsi: qla2xxx: Fix mtcp dump collection failure

Quinn Tran <[email protected]>
scsi: qla2xxx: Fix stuck login session using prli_pend_timer

Anand Lodnoor <[email protected]>
scsi: megaraid_sas: Do not initiate OCR if controller is not in ready state

Gao Xiang <[email protected]>
erofs: fix out-of-bound read for shifted uncompressed block

Geert Uytterhoeven <[email protected]>
scripts/find-unused-docs: Fix massive false positives

Filipe Manana <[email protected]>
fs: allow deduplication of eof block into the end of the destination file

Herbert Xu <[email protected]>
padata: Remove broken queue flushing

Gilad Ben-Yossef <[email protected]>
crypto: ccree - fix PM race condition

Ofir Drang <[email protected]>
crypto: ccree - fix FDE descriptor sequence

Gilad Ben-Yossef <[email protected]>
crypto: ccree - fix pm wrongful error reporting

Gilad Ben-Yossef <[email protected]>
crypto: ccree - fix AEAD decrypt auth fail

Gilad Ben-Yossef <[email protected]>
crypto: ccree - fix backlog memory leak

Herbert Xu <[email protected]>

    crypto: api - Check spawn->alg under lock in crypto_drop_spawn

Bitan Biswas <[email protected]>
nvmem: core: fix memory abort in cleanup path

Peng Fan <[email protected]>
nvmem: imx: scu: fix write SIP

Samuel Holland <[email protected]>

    mfd: axp20x: Mark AXP20X_VBUS_IPSOUT_MGMT as volatile

Tianyu Lan <[email protected]>
hv_balloon: Balloon up according to request page number

Pierre-Louis Bossart <[email protected]>
ASoC: SOF: core: free trace on errors

Jaroslav Kysela <[email protected]>

    ASoC: topology: fix soc_tplg_fe_link_create() - link->dobj initialization order

Jon Hunter <[email protected]>
ASoC: tegra: Revert 24 and 32 bit support

Michał Mirosław <[email protected]>
mmc: sdhci-of-at91: fix memleak on clk_get failure

Zhihao Cheng <[email protected]>
ubifs: Fix deadlock in concurrent bulk-read and writepage

Eric Biggers <[email protected]>
ubifs: Fix FS_IOC_SETFLAGS unexpectedly clearing encrypt flag

Sascha Hauer <[email protected]>
ubifs: Fix wrong memory allocation

Eric Biggers <[email protected]>
ubifs: don't trigger assertion on invalid no-key filename

Eric Biggers <[email protected]>
fscrypt: don't print name of busy file when removing key

Stephen Boyd <[email protected]>
alarmtimer: Unregister wakeup source when module get fails

Steve French <[email protected]>
smb3: fix default permissions on new files when mounting with modefromsid

Hans de Goede <[email protected]>
ACPI / battery: Deal better with neither design nor full capacity not being reported

Hans de Goede <[email protected]>
ACPI / battery: Use design-cap for capacity calculations if full-cap is not available

Hans de Goede <[email protected]>
ACPI / battery: Deal with design or full capacity being reported as -1

Hans de Goede <[email protected]>
ACPI: video: Do not export a non working backlight interface on MSI MS-7721 boards

Linus Walleij <[email protected]>
mmc: spi: Toggle SPI polarity, do not hardcode it

Kishon Vijay Abraham I <[email protected]>
PCI: keystone: Fix error handling when "num-viewport" DT property is not populated

Yurii Monakov <[email protected]>
PCI: keystone: Fix link training retries initiation

Yurii Monakov <[email protected]>
PCI: keystone: Fix outbound region mapping

David Engraf <[email protected]>
PCI: tegra: Fix return value check of pm_runtime_get_sync()

Kuppuswamy Sathyanarayanan <[email protected]>
PCI/ATS: Use PF PASID for VFs

Christophe Leroy <[email protected]>
powerpc/32s: Fix CPU wake-up from sleep mode

Christophe Leroy <[email protected]>
powerpc/32s: Fix bad_kuap_fault()

Pingfan Liu <[email protected]>
powerpc/pseries: Advance pfn if section is not present in lmb_is_removable()

Sukadev Bhattiprolu <[email protected]>
powerpc/xmon: don't access ASDR in VMs

Christophe Leroy <[email protected]>
powerpc/ptdump: Fix W+X verification

Aneesh Kumar K.V <[email protected]>
powerpc/mmu_gather: enable RCU_TABLE_FREE even for !SMP case

Gerald Schaefer <[email protected]>
s390/mm: fix dynamic pagetable upgrade for hugetlbfs

Wang Xuerui <[email protected]>
MIPS: asm: local: add barriers for Loongson

Thomas Bogendoerfer <[email protected]>
MIPS: SGI-IP30: Check for valid pointer before using it

Alexander Lobakin <[email protected]>
MIPS: boot: fix typo in 'vmlinux.lzma.its' target

Alexander Lobakin <[email protected]>
MIPS: fix indentation of the 'RELOCS' message

Alexander Lobakin <[email protected]>
MIPS: syscalls: fix indentation of the 'SYSNR' message

Christoffer Dall <[email protected]>
KVM: arm64: Only sign-extend MMIO up to register width

Mark Rutland <[email protected]>
KVM: arm/arm64: Correct AArch32 SPSR on exception entry

Mark Rutland <[email protected]>
KVM: arm/arm64: Correct CPSR on exception entry

Mark Rutland <[email protected]>
KVM: arm64: Correct PSTATE on exception entry

Mark Rutland <[email protected]>
arm64: acpi: fix DAIF manipulation with pNMI

Nikhil Mahale <[email protected]>
ALSA: hda - Fix DP-MST support for NVIDIA codecs

Yong Zhi <[email protected]>
ALSA: hda: Add JasperLake PCI ID and codec vid

Hans de Goede <[email protected]>
ALSA: hda: Add Clevo W65_67SB the power_save blacklist

Takashi Iwai <[email protected]>
ALSA: hda: Apply aligned MMIO access only conditionally

Mika Westerberg <[email protected]>
platform/x86: intel_scu_ipc: Fix interrupt support

Pawan Gupta <[email protected]>
x86/cpu: Update cached HLE state on write to TSX_CTRL_CPUID_CLEAR

Kevin Hao <[email protected]>
irqdomain: Fix a memory leak in irq_domain_push_irq()

Gustavo A. R. Silva <[email protected]>
lib/test_kasan.c: fix memory leak in kmalloc_oob_krealloc_more()

Helen Koike <[email protected]>
media: v4l2-rect.h: fix v4l2_rect_map_inside() top/left adjustments

Arnd Bergmann <[email protected]>
media: v4l2-core: compat: ignore native command codes

John Hubbard <[email protected]>
media/v4l2-core: set pages dirty upon releasing DMA buffers

Yang Shi <[email protected]>
mm: move_pages: report the number of non-attempted pages

Wei Yang <[email protected]>
mm: thp: don't need care deferred split queue in memcg charge move path

Dan Williams <[email protected]>
mm/memory_hotplug: fix remove_memory() lockdep splat

Wei Yang <[email protected]>
mm/migrate.c: also overwrite error when it is bigger than zero

Amir Goldstein <[email protected]>
utimes: Clamp the timestamps in notify_change()

Pingfan Liu <[email protected]>
mm/sparse.c: reset section's mem_map when fully deactivated

Theodore Ts'o <[email protected]>
memcg: fix a crash in wb_workfn when a device disappears

Takashi Iwai <[email protected]>
ALSA: dummy: Fix PCM format loop in proc output

Takashi Iwai <[email protected]>
ALSA: usb-audio: Annotate endianess in Scarlett gen2 quirk

Takashi Iwai <[email protected]>
ALSA: usb-audio: Fix endianess in descriptor validation

Bryan O'Donoghue <[email protected]>
usb: gadget: f_ecm: Use atomic_t to track in-flight request

Bryan O'Donoghue <[email protected]>
usb: gadget: f_ncm: Use atomic_t to track in-flight request

Roger Quadros <[email protected]>
usb: gadget: legacy: set max_speed to super-speed

Peter Chen <[email protected]>

    usb: gadget: f_fs: set req->num_sgs as 0 for non-sg transfer

Olof Johansson <[email protected]>
objtool: Silence build output

Jun Li <[email protected]>
usb: typec: tcpci: mask event interrupts when remove driver

Thinh Nguyen <[email protected]>
usb: dwc3: gadget: Delay starting transfer

Thinh Nguyen <[email protected]>
usb: dwc3: gadget: Check END_TRANSFER completion

Navid Emamdoost <[email protected]>
brcmfmac: Fix memory leak in brcmf_usbdev_qinit

Kai-Heng Feng <[email protected]>
Bluetooth: btusb: Disable runtime suspend on Realtek devices

Colin Ian King <[email protected]>
Bluetooth: btusb: fix memory leak on fw

Israel Rukshin <[email protected]>
nvmet: Fix controller use after free

Israel Rukshin <[email protected]>
nvmet: Fix error print message at nvmet_install_queue function

Paul E. McKenney <[email protected]>

    rcu: Use READ_ONCE() for ->expmask in rcu_read_unlock_special()

Paul E. McKenney <[email protected]>

    srcu: Apply *_ONCE() to ->srcu_last_gp_end

Eric Dumazet <[email protected]>
rcu: Avoid data-race in rcu_gp_fqs_check_wake()

Paul E. McKenney <[email protected]>

    rcu: Use *_ONCE() to protect lockless ->expmask accesses

Mathieu Desnoyers <[email protected]>
tracing: Fix sched switch start/stop refcount racy updates

Steven Rostedt (VMware) <[email protected]>
tracing/kprobes: Have uname use __get_str() in print_fmt

Lu Shuaibing <[email protected]>
ipc/msg.c: consolidate all xxxctl_down() functions

Takashi Iwai <[email protected]>
ALSA: pcm: Fix memory leak at closing a stream without hw_free

Kadlecsik József <[email protected]>
netfilter: ipset: fix suspicious RCU usage in find_set_and_id

Oliver Neukum <[email protected]>
mfd: dln2: More sanity checking for endpoints

Will Deacon <[email protected]>
media: uvcvideo: Avoid cyclic entity chains due to malformed USB descriptors

Vasundhara Volam <[email protected]>
bnxt_en: Fix logic that disables Bus Master during firmware reset.

Taehee Yoo <[email protected]>
netdevsim: fix stack-out-of-bounds in nsim_dev_debugfs_init()

Lukas Bulwahn <[email protected]>
MAINTAINERS: correct entries for ISDN/mISDN section

Shannon Nelson <[email protected]>
ionic: fix rxq comp packet type mask

Michael Chan <[email protected]>
bnxt_en: Fix RDMA driver failure with SRIOV after firmware reset.

Michael Walle <[email protected]>
net: phy: at803x: disable vddio regulator

Michael Chan <[email protected]>
bnxt_en: Refactor logic to re-enable SRIOV after firmware reset detected.

David Howells <[email protected]>

    rxrpc: Fix NULL pointer deref due to call->conn being cleared on disconnect

David Howells <[email protected]>
rxrpc: Fix missing active use pinning of rxrpc_local object

David Howells <[email protected]>
rxrpc: Fix insufficient receive notification generation

David Howells <[email protected]>
rxrpc: Fix use-after-free in rxrpc_put_local()

Eric Dumazet <[email protected]>
cls_rsvp: fix rsvp_policy

Eric Dumazet <[email protected]>

    tcp: clear tp->segs_{in|out} in tcp_disconnect()

Eric Dumazet <[email protected]>

    tcp: clear tp->data_segs{in|out} in tcp_disconnect()

Eric Dumazet <[email protected]>

    tcp: clear tp->delivered in tcp_disconnect()

Eric Dumazet <[email protected]>

    tcp: clear tp->total_retrans in tcp_disconnect()

Nicolin Chen <[email protected]>
net: stmmac: Delete txtimer in suspend()

Michael Chan <[email protected]>
bnxt_en: Fix TC queue mapping.

Lorenzo Bianconi <[email protected]>
net: mvneta: fix XDP support if sw bm is used as fallback

Leon Romanovsky <[email protected]>
net/core: Do not clear VF index for node/port GUIDs query

Cong Wang <[email protected]>
net_sched: fix an OOB access in cls_tcindex

Eric Dumazet <[email protected]>
net: hsr: fix possible NULL deref in hsr_handle_frame()

Ridge Kennedy <[email protected]>
l2tp: Allow duplicate session creation with UDP

Taehee Yoo <[email protected]>
gtp: use __GFP_NOWARN to avoid memalloc warning

Vasundhara Volam <[email protected]>
bnxt_en: Move devlink_register before registering netdev

Arnd Bergmann <[email protected]>
sparc32: fix struct ipc64_perm type definition

-------------

Diffstat:

 MAINTAINERS                                        |   6 +-
 Makefile                                           |   4 +-
 arch/Kconfig                                       |   3 -
 arch/arm/include/asm/kvm_emulate.h                 |  22 ++
 arch/arm/include/asm/kvm_mmio.h                    |   2 +
 arch/arm/mach-tegra/sleep-tegra30.S                |  11 +
 arch/arm/mm/dma-mapping.c                          |   2 +-
 arch/arm64/boot/dts/qcom/qcs404-evb.dtsi           |   1 +
 arch/arm64/crypto/ghash-ce-glue.c                  |   2 +-
 arch/arm64/include/asm/daifflags.h                 |  11 +-
 arch/arm64/include/asm/kvm_emulate.h               |  37 ++
 arch/arm64/include/asm/kvm_mmio.h                  |   6 +-
 arch/arm64/include/asm/ptrace.h                    |   1 +
 arch/arm64/include/uapi/asm/ptrace.h               |   1 +
 arch/arm64/kernel/acpi.c                           |   2 +-
 arch/arm64/kvm/inject_fault.c                      |  70 +++-
 arch/mips/Makefile.postlink                        |   2 +-
 arch/mips/boot/Makefile                            |   2 +-
 arch/mips/include/asm/local.h                      |   4 +
 arch/mips/kernel/syscalls/Makefile                 |   2 +-
 arch/mips/sgi-ip30/ip30-irq.c                      |   5 +-
 arch/powerpc/Kconfig                               |   4 +-
 arch/powerpc/boot/4xx.c                            |   2 +-
 arch/powerpc/include/asm/book3s/32/kup.h           |  22 +-
 arch/powerpc/include/asm/book3s/32/pgalloc.h       |   8 -
 arch/powerpc/include/asm/book3s/64/kup-radix.h     |  14 +-
 arch/powerpc/include/asm/book3s/64/pgalloc.h       |   2 -
 arch/powerpc/include/asm/futex.h                   |  10 +-
 arch/powerpc/include/asm/kup.h                     |  36 +-
 arch/powerpc/include/asm/nohash/32/kup-8xx.h       |   7 +-
 arch/powerpc/include/asm/nohash/pgalloc.h          |   8 -
 arch/powerpc/include/asm/tlb.h                     |  11 +
 arch/powerpc/include/asm/uaccess.h                 |   4 +-
 arch/powerpc/kernel/entry_32.S                     |   3 +-
 arch/powerpc/kvm/book3s_hv.c                       |   4 +-
 arch/powerpc/kvm/book3s_pr.c                       |   4 +-
 arch/powerpc/kvm/book3s_xive_native.c              |   2 +-
 arch/powerpc/mm/book3s64/pgtable.c                 |   7 -
 arch/powerpc/mm/fault.c                            |   2 +-
 arch/powerpc/mm/ptdump/ptdump.c                    |   4 +-
 arch/powerpc/platforms/pseries/hotplug-memory.c    |   4 +-
 arch/powerpc/xmon/xmon.c                           |   9 +-
 arch/riscv/net/bpf_jit_comp.c                      |  13 +-
 arch/s390/include/asm/page.h                       |   2 +
 arch/s390/kvm/kvm-s390.c                           |   6 +-
 arch/s390/mm/hugetlbpage.c                         | 100 ++++-
 arch/sparc/Kconfig                                 |   1 -
 arch/sparc/include/asm/tlb_64.h                    |   9 +
 arch/sparc/include/uapi/asm/ipcbuf.h               |  22 +-
 arch/x86/include/asm/apic.h                        |  10 +
 arch/x86/include/asm/kvm_host.h                    |  13 +-
 arch/x86/include/asm/x86_init.h                    |   2 +
 arch/x86/kernel/apic/apic.c                        |  23 +-
 arch/x86/kernel/apic/msi.c                         | 128 +++++-
 arch/x86/kernel/cpu/tsx.c                          |  13 +-
 arch/x86/kernel/time.c                             |  12 +-
 arch/x86/kernel/x86_init.c                         |   1 +
 arch/x86/kvm/cpuid.c                               |   4 +-
 arch/x86/kvm/emulate.c                             |  66 +++-
 arch/x86/kvm/hyperv.c                              |  10 +-
 arch/x86/kvm/i8259.c                               |   6 +-
 arch/x86/kvm/ioapic.c                              |  15 +-
 arch/x86/kvm/lapic.c                               |  13 +-
 arch/x86/kvm/mmu/mmu.c                             | 107 ++---
 arch/x86/kvm/mmu/paging_tmpl.h                     |  25 +-
 arch/x86/kvm/mmutrace.h                            |  12 +-
 arch/x86/kvm/mtrr.c                                |   8 +-
 arch/x86/kvm/pmu.h                                 |  18 +-
 arch/x86/kvm/svm.c                                 |   6 +
 arch/x86/kvm/vmx/capabilities.h                    |   5 +
 arch/x86/kvm/vmx/nested.c                          |   4 +-
 arch/x86/kvm/vmx/pmu_intel.c                       |  24 +-
 arch/x86/kvm/vmx/vmx.c                             |  58 +--
 arch/x86/kvm/x86.c                                 | 263 ++++++++-----
 arch/x86/kvm/x86.h                                 |   2 +-
 arch/x86/xen/enlighten_pv.c                        |   1 +
 block/scsi_ioctl.c                                 |  29 +-
 crypto/algapi.c                                    |  46 ++-
 crypto/api.c                                       |   7 +-
 crypto/internal.h                                  |   1 -
 crypto/pcrypt.c                                    |  37 +-
 drivers/acpi/battery.c                             |  75 +++-
 drivers/acpi/video_detect.c                        |  13 +
 drivers/base/power/main.c                          |  42 +-
 drivers/bluetooth/btusb.c                          |   6 +-
 drivers/clk/tegra/clk-tegra-periph.c               |   6 +-
 drivers/cpufreq/cppc_cpufreq.c                     |   2 +-
 drivers/cpufreq/cpufreq-nforce2.c                  |   2 +-
 drivers/cpufreq/cpufreq.c                          | 147 ++++---
 drivers/cpufreq/freq_table.c                       |   4 +-
 drivers/cpufreq/gx-suspmod.c                       |   2 +-
 drivers/cpufreq/intel_pstate.c                     |  38 +-
 drivers/cpufreq/longrun.c                          |   6 +-
 drivers/cpufreq/pcc-cpufreq.c                      |   2 +-
 drivers/cpufreq/sh-cpufreq.c                       |   2 +-
 drivers/cpufreq/unicore2-cpufreq.c                 |   2 +-
 drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c  |   4 +-
 drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c  |   4 +-
 drivers/crypto/amlogic/amlogic-gxl-core.c          |   4 +-
 drivers/crypto/atmel-aes.c                         |  87 +++--
 drivers/crypto/atmel-tdes.c                        | 151 +++----
 drivers/crypto/ccp/ccp-dev-v3.c                    |   1 +
 drivers/crypto/ccree/cc_aead.c                     |   2 +-
 drivers/crypto/ccree/cc_cipher.c                   |  48 ++-
 drivers/crypto/ccree/cc_driver.h                   |   1 +
 drivers/crypto/ccree/cc_pm.c                       |  30 +-
 drivers/crypto/ccree/cc_request_mgr.c              |  51 +--
 drivers/crypto/ccree/cc_request_mgr.h              |   8 -
 drivers/crypto/hisilicon/Kconfig                   |   3 +-
 drivers/crypto/hisilicon/sgl.c                     |  13 +-
 drivers/crypto/hisilicon/zip/zip.h                 |   4 +
 drivers/crypto/hisilicon/zip/zip_crypto.c          |  92 ++---
 drivers/crypto/picoxcell_crypto.c                  |  15 +-
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c  |  13 +-
 drivers/gpu/drm/amd/powerplay/amdgpu_smu.c         |  18 +
 drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h     |   2 +
 drivers/gpu/drm/amd/powerplay/inc/smu_types.h      |   2 +
 .../gpu/drm/amd/powerplay/inc/smu_v11_0_ppsmc.h    |   5 +-
 drivers/gpu/drm/amd/powerplay/navi10_ppt.c         | 176 ++++++++-
 drivers/gpu/drm/amd/powerplay/smu_internal.h       |   3 +
 drivers/gpu/drm/amd/powerplay/smu_v11_0.c          |   6 +
 drivers/gpu/drm/amd/powerplay/vega20_ppt.c         |  28 +-
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c     |  18 +-
 drivers/gpu/drm/drm_dp_mst_topology.c              |  12 +
 drivers/gpu/drm/drm_rect.c                         |   7 +-
 drivers/gpu/drm/msm/disp/mdp4/mdp4_dsi_encoder.c   |   2 +-
 drivers/gpu/drm/tegra/drm.c                        |  49 ++-
 drivers/gpu/drm/tegra/gem.c                        |  10 +-
 drivers/gpu/drm/tegra/plane.c                      |  44 ++-
 drivers/gpu/host1x/job.c                           |  32 +-
 drivers/hv/hv_balloon.c                            |  13 +-
 drivers/infiniband/core/umem_odp.c                 |  22 +-
 drivers/infiniband/hw/mlx5/gsi.c                   |   3 +-
 drivers/md/bcache/bcache.h                         |   3 +
 drivers/md/bcache/request.c                        |  17 +-
 drivers/md/bcache/sysfs.c                          |  22 ++
 drivers/md/dm-crypt.c                              |  12 +-
 drivers/md/dm-thin-metadata.c                      |  10 +-
 drivers/md/dm-thin.c                               |   7 +-
 drivers/md/dm-writecache.c                         |  42 +-
 drivers/md/dm-zoned-metadata.c                     |  23 +-
 drivers/md/dm.c                                    |   9 +-
 drivers/md/persistent-data/dm-space-map-common.c   |  27 ++
 drivers/md/persistent-data/dm-space-map-common.h   |   2 +
 drivers/md/persistent-data/dm-space-map-disk.c     |   6 +-
 drivers/md/persistent-data/dm-space-map-metadata.c |   5 +-
 drivers/media/rc/iguanair.c                        |   2 +-
 drivers/media/rc/rc-main.c                         |  27 +-
 drivers/media/usb/uvc/uvc_driver.c                 |  12 +
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c      | 148 +++----
 drivers/media/v4l2-core/videobuf-dma-sg.c          |   5 +-
 drivers/mfd/ab8500-core.c                          |   4 +-
 drivers/mfd/axp20x.c                               |   2 +-
 drivers/mfd/da9062-core.c                          |   2 +-
 drivers/mfd/dln2.c                                 |  13 +-
 drivers/mfd/rn5t618.c                              |   1 +
 drivers/mmc/host/mmc_spi.c                         |  11 +-
 drivers/mmc/host/sdhci-of-at91.c                   |   9 +-
 drivers/mtd/spi-nor/spi-nor.c                      |   9 +-
 drivers/mtd/ubi/fastmap.c                          |  23 +-
 drivers/net/bonding/bond_alb.c                     |  44 ++-
 drivers/net/dsa/b53/b53_common.c                   |   2 +-
 drivers/net/dsa/bcm_sf2.c                          |   4 +-
 drivers/net/dsa/microchip/ksz9477_spi.c            |   6 +
 drivers/net/ethernet/broadcom/bcmsysport.c         |   3 +
 drivers/net/ethernet/broadcom/bnxt/bnxt.c          |  49 ++-
 drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c  |   1 -
 drivers/net/ethernet/cadence/macb_main.c           |  14 +-
 drivers/net/ethernet/dec/tulip/dmfe.c              |   7 +-
 drivers/net/ethernet/dec/tulip/uli526x.c           |   4 +-
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c     |  14 +-
 drivers/net/ethernet/marvell/mvneta.c              |  41 +-
 .../net/ethernet/mellanox/mlx5/core/accel/tls.h    |   2 +-
 .../mellanox/mlx5/core/en_accel/tls_rxtx.c         |   2 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_rx.c    |  16 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_tx.c    |  33 +-
 .../net/ethernet/mellanox/mlx5/core/fpga/ipsec.c   |   3 +-
 drivers/net/ethernet/mellanox/mlx5/core/fs_core.c  |  15 +-
 drivers/net/ethernet/mellanox/mlx5/core/fw.c       |   2 +-
 drivers/net/ethernet/pensando/ionic/ionic_if.h     |   2 +-
 drivers/net/ethernet/qlogic/qed/qed_ptp.c          |   4 +-
 drivers/net/ethernet/realtek/r8169_main.c          |   6 +
 drivers/net/ethernet/smsc/smc911x.c                |   2 +-
 .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    |   1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c  |   9 +-
 .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c    |  10 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |   4 +
 drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c   |  14 +-
 drivers/net/gtp.c                                  |   4 +-
 drivers/net/netdevsim/dev.c                        |   2 +-
 drivers/net/phy/at803x.c                           |  11 +
 drivers/net/ppp/ppp_async.c                        |  18 +-
 .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c |   1 +
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c       |  10 +-
 drivers/net/wireless/marvell/mwifiex/sta_ioctl.c   |   1 +
 drivers/nfc/pn544/pn544.c                          |   2 +-
 drivers/nvme/target/fabrics-cmd.c                  |  15 +-
 drivers/nvmem/core.c                               |   8 +-
 drivers/nvmem/imx-ocotp-scu.c                      |   6 +-
 drivers/of/Kconfig                                 |   4 +
 drivers/of/address.c                               |   6 +-
 drivers/pci/ats.c                                  |   6 +-
 drivers/pci/controller/dwc/pci-keystone.c          |   6 +-
 drivers/pci/controller/pci-tegra.c                 |   2 +-
 drivers/phy/qualcomm/phy-qcom-apq8064-sata.c       |   2 +-
 drivers/platform/x86/intel_scu_ipc.c               |  21 +-
 drivers/power/supply/axp20x_ac_power.c             |  31 +-
 drivers/power/supply/ltc2941-battery-gauge.c       |   2 +-
 drivers/regulator/helpers.c                        |  14 +
 drivers/scsi/csiostor/csio_scsi.c                  |   2 +-
 drivers/scsi/megaraid/megaraid_sas_base.c          |   3 +-
 drivers/scsi/megaraid/megaraid_sas_fusion.c        |   3 +-
 drivers/scsi/megaraid/megaraid_sas_fusion.h        |   1 +
 drivers/scsi/qla2xxx/qla_dbg.c                     |   6 -
 drivers/scsi/qla2xxx/qla_dbg.h                     |   6 +
 drivers/scsi/qla2xxx/qla_def.h                     |   5 +
 drivers/scsi/qla2xxx/qla_init.c                    |  34 +-
 drivers/scsi/qla2xxx/qla_isr.c                     |  12 +
 drivers/scsi/qla2xxx/qla_mbx.c                     |   3 +-
 drivers/scsi/qla2xxx/qla_nx.c                      |   7 +-
 drivers/scsi/qla2xxx/qla_target.c                  |   1 +
 drivers/scsi/qla4xxx/ql4_os.c                      |   2 +-
 drivers/scsi/sg.c                                  | 126 +++---
 drivers/scsi/ufs/ufshcd.c                          |   3 +
 drivers/staging/wfx/debug.c                        |   2 +-
 drivers/usb/dwc3/core.h                            |   2 +
 drivers/usb/dwc3/ep0.c                             |   4 +-
 drivers/usb/dwc3/gadget.c                          |  17 +-
 drivers/usb/gadget/function/f_ecm.c                |  16 +-
 drivers/usb/gadget/function/f_fs.c                 |   2 +
 drivers/usb/gadget/function/f_ncm.c                |  17 +-
 drivers/usb/gadget/legacy/cdc2.c                   |   2 +-
 drivers/usb/gadget/legacy/g_ffs.c                  |   2 +-
 drivers/usb/gadget/legacy/multi.c                  |   2 +-
 drivers/usb/gadget/legacy/ncm.c                    |   2 +-
 drivers/usb/typec/tcpm/tcpci.c                     |   6 +
 drivers/virtio/virtio_balloon.c                    |  19 +-
 drivers/virtio/virtio_pci_common.c                 |   2 +-
 drivers/watchdog/watchdog_core.c                   |  35 ++
 drivers/watchdog/watchdog_dev.c                    |  36 +-
 drivers/xen/gntdev.c                               |  24 +-
 drivers/xen/xen-balloon.c                          |   2 +-
 fs/aio.c                                           |  20 +-
 fs/attr.c                                          |  23 +-
 fs/btrfs/ctree.c                                   |   8 +-
 fs/btrfs/ctree.h                                   |   6 +-
 fs/btrfs/delayed-ref.c                             |   8 +-
 fs/btrfs/disk-io.c                                 |  12 +-
 fs/btrfs/extent_io.c                               |  55 ++-
 fs/btrfs/ioctl.c                                   |   3 +-
 fs/btrfs/send.c                                    |   3 +-
 fs/btrfs/tests/btrfs-tests.c                       |   1 -
 fs/btrfs/tests/extent-io-tests.c                   |   9 +
 fs/btrfs/transaction.c                             |  30 +-
 fs/btrfs/tree-log.c                                | 432 +++++++--------------
 fs/btrfs/volumes.c                                 |  17 +-
 fs/cifs/cifsacl.c                                  |  20 +
 fs/cifs/cifsproto.h                                |   1 +
 fs/cifs/readdir.c                                  |   3 +-
 fs/cifs/smb2pdu.c                                  |  21 +-
 fs/configfs/inode.c                                |   9 +-
 fs/crypto/keyring.c                                |  15 +-
 fs/erofs/decompressor.c                            |  22 +-
 fs/eventfd.c                                       |  15 +
 fs/ext2/super.c                                    |   6 +-
 fs/ext4/dir.c                                      |   9 +-
 fs/ext4/page-io.c                                  |  19 +-
 fs/f2fs/dir.c                                      |  11 +-
 fs/f2fs/file.c                                     |  18 +-
 fs/f2fs/super.c                                    |  18 +-
 fs/fs-writeback.c                                  |   2 +-
 fs/fuse/file.c                                     |   5 +-
 fs/gfs2/file.c                                     |  72 ++--
 fs/gfs2/lops.c                                     |   2 +-
 fs/io_uring.c                                      |  71 +++-
 fs/jbd2/journal.c                                  |   1 +
 fs/nfs/dir.c                                       |  47 ++-
 fs/nfsd/filecache.c                                |   6 +
 fs/nfsd/nfs4layouts.c                              |   2 +-
 fs/nfsd/nfs4state.c                                |   2 +-
 fs/nfsd/state.h                                    |   2 +-
 fs/nfsd/vfs.c                                      |   1 +
 fs/ntfs/inode.c                                    |  18 +-
 fs/ocfs2/file.c                                    |  14 +-
 fs/overlayfs/file.c                                |   2 +-
 fs/overlayfs/readdir.c                             |   8 +-
 fs/read_write.c                                    |  10 +-
 fs/ubifs/dir.c                                     |   2 +
 fs/ubifs/file.c                                    |  22 +-
 fs/ubifs/ioctl.c                                   |   3 +-
 fs/ubifs/sb.c                                      |   2 +-
 fs/ubifs/super.c                                   |   2 +
 fs/utimes.c                                        |   4 +-
 include/asm-generic/tlb.h                          |  22 +-
 include/linux/backing-dev.h                        |  10 +
 include/linux/cpufreq.h                            |  32 +-
 include/linux/eventfd.h                            |  14 +
 include/linux/irq.h                                |  18 +
 include/linux/irqdomain.h                          |   7 +
 include/linux/kvm_host.h                           |  13 +-
 include/linux/kvm_types.h                          |   9 +-
 include/linux/mfd/rohm-bd70528.h                   |   2 +-
 include/linux/mlx5/mlx5_ifc.h                      |   7 +-
 include/linux/padata.h                             |  34 +-
 include/linux/percpu-defs.h                        |   3 +-
 include/linux/regulator/consumer.h                 |   7 +
 include/media/v4l2-rect.h                          |   8 +-
 include/net/ipx.h                                  |   5 -
 include/scsi/sg.h                                  |  30 ++
 include/sound/hdaudio.h                            |  77 ++--
 include/trace/events/writeback.h                   |  37 +-
 include/uapi/linux/io_uring.h                      |   1 +
 ipc/msg.c                                          |  19 +-
 kernel/bpf/devmap.c                                |   3 +-
 kernel/bpf/trampoline.c                            |  10 +
 kernel/events/core.c                               |  17 +-
 kernel/irq/debugfs.c                               |   1 +
 kernel/irq/irqdomain.c                             |   1 +
 kernel/irq/msi.c                                   |   5 +-
 kernel/padata.c                                    | 275 ++++++++-----
 kernel/rcu/srcutree.c                              |   7 +-
 kernel/rcu/tree_exp.h                              |  19 +-
 kernel/rcu/tree_plugin.h                           |  13 +-
 kernel/time/alarmtimer.c                           |   8 +-
 kernel/time/clocksource.c                          |  11 +-
 kernel/trace/ftrace.c                              |  15 +-
 kernel/trace/trace.h                               |  29 +-
 kernel/trace/trace_probe.c                         |   6 +-
 kernel/trace/trace_sched_switch.c                  |   4 +-
 lib/test_kasan.c                                   |   1 +
 mm/backing-dev.c                                   |   1 +
 mm/memcontrol.c                                    |  18 -
 mm/memory_hotplug.c                                |   9 +-
 mm/migrate.c                                       |  27 +-
 mm/mmu_gather.c                                    |  16 +-
 mm/page_alloc.c                                    |  14 +-
 mm/sparse.c                                        |   2 +-
 net/core/devlink.c                                 |   6 +
 net/core/drop_monitor.c                            |   4 +-
 net/core/flow_dissector.c                          |  11 +-
 net/core/rtnetlink.c                               |   4 +-
 net/hsr/hsr_slave.c                                |   2 +
 net/ipv4/tcp.c                                     |   6 +
 net/ipv6/addrconf.c                                |   3 +
 net/l2tp/l2tp_core.c                               |   7 +-
 net/netfilter/ipset/ip_set_core.c                  |  41 +-
 net/rxrpc/af_rxrpc.c                               |   2 +
 net/rxrpc/ar-internal.h                            |  11 +
 net/rxrpc/call_object.c                            |   4 +-
 net/rxrpc/conn_client.c                            |   3 +-
 net/rxrpc/conn_event.c                             |  30 +-
 net/rxrpc/conn_object.c                            |   3 +-
 net/rxrpc/input.c                                  |   6 +-
 net/rxrpc/local_object.c                           |  23 +-
 net/rxrpc/output.c                                 |  27 +-
 net/rxrpc/peer_event.c                             |  42 +-
 net/sched/cls_rsvp.h                               |   6 +-
 net/sched/cls_tcindex.c                            |  43 +-
 net/sched/sch_taprio.c                             |  92 +++--
 net/sunrpc/auth_gss/svcauth_gss.c                  |   4 +
 samples/bpf/Makefile                               |   4 +-
 samples/bpf/xdp_redirect_cpu_user.c                |  59 ++-
 scripts/find-unused-docs.sh                        |   2 +-
 security/smack/smack_lsm.c                         |  41 +-
 sound/core/pcm_native.c                            |  24 +-
 sound/drivers/dummy.c                              |   2 +-
 sound/pci/hda/hda_intel.c                          |   4 +
 sound/pci/hda/hda_tegra.c                          |   1 +
 sound/pci/hda/patch_hdmi.c                         |  95 +++--
 sound/soc/codecs/sgtl5000.c                        |   3 +-
 sound/soc/intel/boards/skl_hda_dsp_common.c        |  21 +-
 sound/soc/meson/axg-fifo.c                         |  27 +-
 sound/soc/meson/axg-fifo.h                         |   6 +-
 sound/soc/meson/axg-frddr.c                        |  24 +-
 sound/soc/meson/axg-toddr.c                        |  21 +-
 sound/soc/soc-topology.c                           |   7 +-
 sound/soc/sof/core.c                               |  87 +++--
 sound/soc/sof/intel/hda-loader.c                   |   1 -
 sound/soc/sof/intel/hda.c                          |   4 +-
 sound/soc/sof/ipc.c                                |  17 +-
 sound/soc/sof/loader.c                             |  19 +-
 sound/soc/sof/pm.c                                 |  25 +-
 sound/soc/sof/sof-priv.h                           |  11 +-
 sound/soc/tegra/tegra30_i2s.c                      |  25 +-
 sound/usb/mixer_scarlett_gen2.c                    |  46 +--
 sound/usb/validate.c                               |   6 +-
 tools/kvm/kvm_stat/kvm_stat                        |   8 +-
 tools/lib/bpf/Makefile                             |   2 +
 tools/lib/bpf/libbpf.c                             | 198 ++++++----
 tools/lib/bpf/libbpf_internal.h                    |   4 +-
 tools/objtool/sync-check.sh                        |   2 -
 tools/power/cpupower/lib/cpufreq.c                 |  78 +++-
 tools/power/cpupower/lib/cpufreq.h                 |  20 +-
 tools/power/cpupower/utils/cpufreq-info.c          |  12 +-
 .../selftests/bpf/prog_tests/attach_probe.c        |   7 +-
 .../testing/selftests/bpf/prog_tests/perf_buffer.c |  29 +-
 .../bpf/prog_tests/stacktrace_build_id_nmi.c       |   8 +-
 .../bpf/progs/test_select_reuseport_kern.c         |   6 +
 tools/testing/selftests/bpf/test_sockmap.c         |  15 +-
 .../tc-testing/plugin-lib/buildebpfPlugin.py       |   2 +-
 virt/kvm/arm/aarch32.c                             | 117 +++++-
 virt/kvm/arm/mmio.c                                |   6 +
 virt/kvm/async_pf.c                                |  10 +-
 virt/kvm/kvm_main.c                                | 117 +++++-
 404 files changed, 5002 insertions(+), 2744 deletions(-)
author maintainer
#1 lore raw

PATCH 1/367 sparc32: fix struct ipc64_perm type definition

From: Arnd Bergmann <[email protected]>

[ Upstream commit 34ca70ef7d3a9fa7e89151597db5e37ae1d429b4 ]

As discussed in the strace issue tracker, it appears that the sparc32 sysvipc support has been broken for the past 11 years. It was however working in compat mode, which is how it must have escaped most of the regular testing.

The problem is that a cleanup patch inadvertently changed the uid/gid fields in struct ipc64_perm from 32-bit types to 16-bit types in uapi headers.

Both glibc and uclibc-ng still use the original types, so they should work fine with compat mode, but not natively. Change the definitions to use __kernel_uid32_t and __kernel_gid32_t again.

Fixes 83c86984bff2 ("sparc: unify ipcbuf.h")
Cc <[email protected]> # v2.6.29
Cc Sam Ravnborg <[email protected]>
Cc "Dmitry V . Levin" <[email protected]>
Cc Rich Felker <[email protected]>
---
 arch/sparc/include/uapi/asm/ipcbuf.h |   22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)
arch/sparc/include/uapi/asm/ipcbuf.h +11 -11
@@ -17,19 +17,19 @@
 
 struct ipc64_perm
 {
-	__kernel_key_t	key;
-	__kernel_uid_t	uid;
-	__kernel_gid_t	gid;
-	__kernel_uid_t	cuid;
-	__kernel_gid_t	cgid;
+	__kernel_key_t		key;
+	__kernel_uid32_t	uid;
+	__kernel_gid32_t	gid;
+	__kernel_uid32_t	cuid;
+	__kernel_gid32_t	cgid;
 #ifndef __arch64__
-	unsigned short	__pad0;
+	unsigned short		__pad0;
 #endif
-	__kernel_mode_t	mode;
-	unsigned short	__pad1;
-	unsigned short	seq;
-	unsigned long long __unused1;
-	unsigned long long __unused2;
+	__kernel_mode_t		mode;
+	unsigned short		__pad1;
+	unsigned short		seq;
+	unsigned long long	__unused1;
+	unsigned long long	__unused2;
 };
 
 #endif /* __SPARC_IPCBUF_H */
author maintainer
#2 lore raw

PATCH 2/367 bnxt_en: Move devlink_register before registering netdev

In reply to Greg Kroah-Hartman

From: Vasundhara Volam <[email protected]>

[ Upstream commit cda2cab0771183932d6ba73c5ac63bb63decdadf ]

Latest kernels get the phys_port_name via devlink, if ndo_get_phys_port_name is not defined. To provide the phys_port_name correctly, register devlink before registering netdev.

Also call devlink_port_type_eth_set() after registering netdev as devlink port updates the netdev structure and notifies user.

---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c         |   12 ++++++++----
 drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c |    1 -
 2 files changed, 8 insertions(+), 5 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +8 -4
@@ -11433,9 +11433,9 @@ static void bnxt_remove_one(struct pci_d
 		bnxt_sriov_disable(bp);
 
 	bnxt_dl_fw_reporters_destroy(bp, true);
-	bnxt_dl_unregister(bp);
 	pci_disable_pcie_error_reporting(pdev);
 	unregister_netdev(dev);
+	bnxt_dl_unregister(bp);
 	bnxt_shutdown_tc(bp);
 	bnxt_cancel_sp_work(bp);
 	bp->sp_event = 0;
@@ -11905,11 +11905,14 @@ static int bnxt_init_one(struct pci_dev
 		bnxt_init_tc(bp);
 	}
 
+	bnxt_dl_register(bp);
+
 	rc = register_netdev(dev);
 	if (rc)
-		goto init_err_cleanup_tc;
+		goto init_err_cleanup;
 
-	bnxt_dl_register(bp);
+	if (BNXT_PF(bp))
+		devlink_port_type_eth_set(&bp->dl_port, bp->dev);
 	bnxt_dl_fw_reporters_create(bp);
 
 	netdev_info(dev, "%s found at mem %lx, node addr %pM\n",
@@ -11919,7 +11922,8 @@ static int bnxt_init_one(struct pci_dev
 
 	return 0;
 
-init_err_cleanup_tc:
+init_err_cleanup:
+	bnxt_dl_unregister(bp);
 	bnxt_shutdown_tc(bp);
 	bnxt_clear_int_mode(bp);
 
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c +0 -1
@@ -526,7 +526,6 @@ int bnxt_dl_register(struct bnxt *bp)
 		netdev_err(bp->dev, "devlink_port_register failed");
 		goto err_dl_param_unreg;
 	}
-	devlink_port_type_eth_set(&bp->dl_port, bp->dev);
 
 	rc = devlink_port_params_register(&bp->dl_port, bnxt_dl_port_params,
 					  ARRAY_SIZE(bnxt_dl_port_params));
author maintainer
#3 lore raw

PATCH 3/367 gtp: use __GFP_NOWARN to avoid memalloc warning

In reply to Greg Kroah-Hartman

From: Taehee Yoo <[email protected]>

[ Upstream commit bd5cd35b782abf5437fbd01dfaee12437d20e832 ]

gtp hashtable size is received by user-space.
So, this hashtable size could be too large. If so, kmalloc will internally print a warning message.
This warning message is actually not necessary for the gtp module. So, this patch adds __GFP_NOWARN to avoid this message.

Splat looks like:

[ 2171.200049][ T1860] WARNING: CPU: 1 PID: 1860 at mm/page_alloc.c:4713 __alloc_pages_nodemask+0x2f3/0x740
[ 2171.238885][ T1860] Modules linked in: gtp veth openvswitch nsh nf_conncount nf_nat nf_conntrack nf_defrag_ipv]
[ 2171.262680][ T1860] CPU: 1 PID: 1860 Comm: gtp-link Not tainted 5.5.0+ #321
[ 2171.263567][ T1860] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
[ 2171.264681][ T1860] RIP: 0010:__alloc_pages_nodemask+0x2f3/0x740
[ 2171.265332][ T1860] Code: 64 fe ff ff 65 48 8b 04 25 c0 0f 02 00 48 05 f0 12 00 00 41 be 01 00 00 00 49 89 47 0
[ 2171.267301][ T1860] RSP: 0018:ffff8880b51af1f0 EFLAGS: 00010246
[ 2171.268320][ T1860] RAX: ffffed1016a35e43 RBX: 0000000000000000 RCX: 0000000000000000
[ 2171.269517][ T1860] RDX: 0000000000000000 RSI: 000000000000000b RDI: 0000000000000000
[ 2171.270305][ T1860] RBP: 0000000000040cc0 R08: ffffed1018893109 R09: dffffc0000000000
[ 2171.275973][ T1860] R10: 0000000000000001 R11: ffffed1018893108 R12: 1ffff11016a35e43
[ 2171.291039][ T1860] R13: 000000000000000b R14: 000000000000000b R15: 00000000000f4240
[ 2171.292328][ T1860] FS:  00007f53cbc83740(0000) GS:ffff8880da000000(0000) knlGS:0000000000000000
[ 2171.293409][ T1860] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 2171.294586][ T1860] CR2: 000055f540014508 CR3: 00000000b49f2004 CR4: 00000000000606e0
[ 2171.295424][ T1860] Call Trace:
[ 2171.295756][ T1860]  ? mark_held_locks+0xa5/0xe0
[ 2171.296659][ T1860]  ? __alloc_pages_slowpath+0x21b0/0x21b0
[ 2171.298283][ T1860]  ? gtp_encap_enable_socket+0x13e/0x400 [gtp]
[ 2171.298962][ T1860]  ? alloc_pages_current+0xc1/0x1a0
[ 2171.299475][ T1860]  kmalloc_order+0x22/0x80
[ 2171.299936][ T1860]  kmalloc_order_trace+0x1d/0x140
[ 2171.300437][ T1860]  __kmalloc+0x302/0x3a0
[ 2171.300896][ T1860]  gtp_newlink+0x293/0xba0 [gtp]

[ ... ]

Fixes 459aa660eb1d ("gtp: add initial driver for datapath of GPRS Tunneling Protocol (GTP-U)")
---
 drivers/net/gtp.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/gtp.c +2 -2
@@ -767,12 +767,12 @@ static int gtp_hashtable_new(struct gtp_
 	int i;
 
 	gtp->addr_hash = kmalloc_array(hsize, sizeof(struct hlist_head),
-				       GFP_KERNEL);
+				       GFP_KERNEL | __GFP_NOWARN);
 	if (gtp->addr_hash == NULL)
 		return -ENOMEM;
 
 	gtp->tid_hash = kmalloc_array(hsize, sizeof(struct hlist_head),
-				      GFP_KERNEL);
+				      GFP_KERNEL | __GFP_NOWARN);
 	if (gtp->tid_hash == NULL)
 		goto err1;
 
author maintainer
#4 lore raw

PATCH 4/367 l2tp: Allow duplicate session creation with UDP

In reply to Greg Kroah-Hartman

From: Ridge Kennedy <[email protected]>

[ Upstream commit 0d0d9a388a858e271bb70e71e99e7fe2a6fd6f64 ]

In the past it was possible to create multiple L2TPv3 sessions with the same session id as long as the sessions belonged to different tunnels. The resulting sessions had issues when used with IP encapsulated tunnels, but worked fine with UDP encapsulated ones. Some applications began to rely on this behaviour to avoid having to negotiate unique session ids.

Some time ago a change was made to require session ids to be unique across all tunnels, breaking the applications making use of this "feature".

This change relaxes the duplicate session id check to allow duplicates if both of the colliding sessions belong to UDP encapsulated tunnels.

Fixes dbdbc73b4478 ("l2tp: fix duplicate session creation")
---
 net/l2tp/l2tp_core.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
net/l2tp/l2tp_core.c +6 -1
@@ -322,8 +322,13 @@ int l2tp_session_register(struct l2tp_se
 
 		spin_lock_bh(&pn->l2tp_session_hlist_lock);
 
+		/* IP encap expects session IDs to be globally unique, while
+		 * UDP encap doesn't.
+		 */
 		hlist_for_each_entry(session_walk, g_head, global_hlist)
-			if (session_walk->session_id == session->session_id) {
+			if (session_walk->session_id == session->session_id &&
+			    (session_walk->tunnel->encap == L2TP_ENCAPTYPE_IP ||
+			     tunnel->encap == L2TP_ENCAPTYPE_IP)) {
 				err = -EEXIST;
 				goto err_tlock_pnlock;
 			}
author maintainer
#5 lore raw

PATCH 5/367 net: hsr: fix possible NULL deref in hsr_handle_frame()

In reply to Greg Kroah-Hartman

From: Eric Dumazet <[email protected]>

[ Upstream commit 2b5b8251bc9fe2f9118411f037862ee17cf81e97 ]

hsr_port_get_rcu() can return NULL, so we need to be careful.

general protection fault, probably for non-canonical address 0xdffffc0000000006: 0000 [#1] PREEMPT SMP KASAN
KASAN: null-ptr-deref in range [0x0000000000000030-0x0000000000000037]
CPU: 1 PID: 10249 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:__read_once_size include/linux/compiler.h:199 [inline]
RIP: 0010:hsr_addr_is_self+0x86/0x330 net/hsr/hsr_framereg.c:44
Code: 04 00 f3 f3 f3 65 48 8b 04 25 28 00 00 00 48 89 45 d0 31 c0 e8 6b ff 94 f9 4c 89 f2 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 03 <80> 3c 02 00 0f 85 75 02 00 00 48 8b 43 30 49 39 c6 49 89 47 c0 0f
RSP: 0018:ffffc90000da8a90 EFLAGS: 00010206
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffff87e0cc33
RDX: 0000000000000006 RSI: ffffffff87e035d5 RDI: 0000000000000000
RBP: ffffc90000da8b20 R08: ffff88808e7de040 R09: ffffed1015d2707c
R10: ffffed1015d2707b R11: ffff8880ae9383db R12: ffff8880a689bc5e
R13: 1ffff920001b5153 R14: 0000000000000030 R15: ffffc90000da8af8
FS:  00007fd7a42be700(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000001b32338000 CR3: 00000000a928c000 CR4: 00000000001406e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 <IRQ>
 hsr_handle_frame+0x1c5/0x630 net/hsr/hsr_slave.c:31
 __netif_receive_skb_core+0xfbc/0x30b0 net/core/dev.c:5099
 __netif_receive_skb_one_core+0xa8/0x1a0 net/core/dev.c:5196
 __netif_receive_skb+0x2c/0x1d0 net/core/dev.c:5312
 process_backlog+0x206/0x750 net/core/dev.c:6144
 napi_poll net/core/dev.c:6582 [inline]
 net_rx_action+0x508/0x1120 net/core/dev.c:6650
 __do_softirq+0x262/0x98c kernel/softirq.c:292
 do_softirq_own_stack+0x2a/0x40 arch/x86/entry/entry_64.S:1082
 </IRQ>
Fixes c5a759117210 ("net/hsr: Use list_head (and rcu) instead of array for slave devices.")
---
 net/hsr/hsr_slave.c |    2 ++
 1 file changed, 2 insertions(+)
net/hsr/hsr_slave.c +2 -0
@@ -27,6 +27,8 @@ static rx_handler_result_t hsr_handle_fr
 
 	rcu_read_lock(); /* hsr->node_db, hsr->ports */
 	port = hsr_port_get_rcu(skb->dev);
+	if (!port)
+		goto finish_pass;
 
 	if (hsr_addr_is_self(port->hsr, eth_hdr(skb)->h_source)) {
 		/* Directly kill frames sent by ourselves */
author maintainer
#6 lore raw

PATCH 6/367 net_sched: fix an OOB access in cls_tcindex

In reply to Greg Kroah-Hartman

From: Cong Wang <[email protected]>

[ Upstream commit 599be01ee567b61f4471ee8078870847d0a11e8e ]

As Eric noticed, tcindex_alloc_perfect_hash() uses cp->hash to compute the size of memory allocation, but cp->hash is set again after the allocation, this caused an out-of-bound access.

So we have to move all cp->hash initialization and computation before the memory allocation. Move cp->mask and cp->shift together as cp->hash may need them for computation too.

Reported-and-tested-by [email protected]
Fixes 331b72922c5f ("net: sched: RCU cls_tcindex")
Cc Eric Dumazet <[email protected]>
Cc John Fastabend <[email protected]>
Cc Jamal Hadi Salim <[email protected]>
Cc Jiri Pirko <[email protected]>
Cc Jakub Kicinski <[email protected]>
---
 net/sched/cls_tcindex.c |   40 ++++++++++++++++++++--------------------
 1 file changed, 20 insertions(+), 20 deletions(-)
net/sched/cls_tcindex.c +20 -20
@@ -333,12 +333,31 @@ tcindex_set_parms(struct net *net, struc
 	cp->fall_through = p->fall_through;
 	cp->tp = tp;
 
+	if (tb[TCA_TCINDEX_HASH])
+		cp->hash = nla_get_u32(tb[TCA_TCINDEX_HASH]);
+
+	if (tb[TCA_TCINDEX_MASK])
+		cp->mask = nla_get_u16(tb[TCA_TCINDEX_MASK]);
+
+	if (tb[TCA_TCINDEX_SHIFT])
+		cp->shift = nla_get_u32(tb[TCA_TCINDEX_SHIFT]);
+
+	if (!cp->hash) {
+		/* Hash not specified, use perfect hash if the upper limit
+		 * of the hashing index is below the threshold.
+		 */
+		if ((cp->mask >> cp->shift) < PERFECT_HASH_THRESHOLD)
+			cp->hash = (cp->mask >> cp->shift) + 1;
+		else
+			cp->hash = DEFAULT_HASH_SIZE;
+	}
+
 	if (p->perfect) {
 		int i;
 
 		if (tcindex_alloc_perfect_hash(net, cp) < 0)
 			goto errout;
-		for (i = 0; i < cp->hash; i++)
+		for (i = 0; i < min(cp->hash, p->hash); i++)
 			cp->perfect[i].res = p->perfect[i].res;
 		balloc = 1;
 	}
@@ -350,15 +369,6 @@ tcindex_set_parms(struct net *net, struc
 	if (old_r)
 		cr = r->res;
 
-	if (tb[TCA_TCINDEX_HASH])
-		cp->hash = nla_get_u32(tb[TCA_TCINDEX_HASH]);
-
-	if (tb[TCA_TCINDEX_MASK])
-		cp->mask = nla_get_u16(tb[TCA_TCINDEX_MASK]);
-
-	if (tb[TCA_TCINDEX_SHIFT])
-		cp->shift = nla_get_u32(tb[TCA_TCINDEX_SHIFT]);
-
 	err = -EBUSY;
 
 	/* Hash already allocated, make sure that we still meet the
@@ -376,16 +386,6 @@ tcindex_set_parms(struct net *net, struc
 	if (tb[TCA_TCINDEX_FALL_THROUGH])
 		cp->fall_through = nla_get_u32(tb[TCA_TCINDEX_FALL_THROUGH]);
 
-	if (!cp->hash) {
-		/* Hash not specified, use perfect hash if the upper limit
-		 * of the hashing index is below the threshold.
-		 */
-		if ((cp->mask >> cp->shift) < PERFECT_HASH_THRESHOLD)
-			cp->hash = (cp->mask >> cp->shift) + 1;
-		else
-			cp->hash = DEFAULT_HASH_SIZE;
-	}
-
 	if (!cp->perfect && !cp->h)
 		cp->alloc_hash = cp->hash;
 
author maintainer
#7 lore raw

PATCH 7/367 net/core: Do not clear VF index for node/port GUIDs query

In reply to Greg Kroah-Hartman

From: Leon Romanovsky <[email protected]>

[ Upstream commit 9fbf082f569980ddd7cab348e0a118678db0e47e ]

VF numbers were assigned to node_guid and port_guid, but cleared right before such query calls were issued. It caused to return node/port GUIDs of VF index 0 for all VFs.

Fixes 30aad41721e0 ("net/core: Add support for getting VF GUIDs")
---
 net/core/rtnetlink.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/core/rtnetlink.c +2 -2
@@ -1241,6 +1241,8 @@ static noinline_for_stack int rtnl_fill_
 		return 0;
 
 	memset(&vf_vlan_info, 0, sizeof(vf_vlan_info));
+	memset(&node_guid, 0, sizeof(node_guid));
+	memset(&port_guid, 0, sizeof(port_guid));
 
 	vf_mac.vf =
 		vf_vlan.vf =
@@ -1289,8 +1291,6 @@ static noinline_for_stack int rtnl_fill_
 		    sizeof(vf_trust), &vf_trust))
 		goto nla_put_vf_failure;
 
-	memset(&node_guid, 0, sizeof(node_guid));
-	memset(&port_guid, 0, sizeof(port_guid));
 	if (dev->netdev_ops->ndo_get_vf_guid &&
 	    !dev->netdev_ops->ndo_get_vf_guid(dev, vfs_num, &node_guid,
 					      &port_guid)) {
author maintainer
#8 lore raw

PATCH 8/367 net: mvneta: fix XDP support if sw bm is used as fallback

In reply to Greg Kroah-Hartman

From: Lorenzo Bianconi <[email protected]>

[ Upstream commit 44efc78d0e464ce70b45b165c005f8bedc17952e ]

In order to fix XDP support if sw buffer management is used as fallback for hw bm devices, define MVNETA_SKB_HEADROOM as maximum between XDP_PACKET_HEADROOM and NET_SKB_PAD and let the hw aligns the IP header to 4-byte boundary.
Fix rx_offset_correction initialization if mvneta_bm_port_init fails in mvneta_resume routine

Fixes 0db51da7a8e9 ("net: mvneta: add basic XDP support")
---
 drivers/net/ethernet/marvell/mvneta.c |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
drivers/net/ethernet/marvell/mvneta.c +7 -3
@@ -324,8 +324,7 @@
 	      ETH_HLEN + ETH_FCS_LEN,			     \
 	      cache_line_size())
 
-#define MVNETA_SKB_HEADROOM	(max(XDP_PACKET_HEADROOM, NET_SKB_PAD) + \
-				 NET_IP_ALIGN)
+#define MVNETA_SKB_HEADROOM	max(XDP_PACKET_HEADROOM, NET_SKB_PAD)
 #define MVNETA_SKB_PAD	(SKB_DATA_ALIGN(sizeof(struct skb_shared_info) + \
 			 MVNETA_SKB_HEADROOM))
 #define MVNETA_SKB_SIZE(len)	(SKB_DATA_ALIGN(len) + MVNETA_SKB_PAD)
@@ -1167,6 +1166,7 @@ bm_mtu_err:
 	mvneta_bm_pool_destroy(pp->bm_priv, pp->pool_short, 1 << pp->id);
 
 	pp->bm_priv = NULL;
+	pp->rx_offset_correction = MVNETA_SKB_HEADROOM;
 	mvreg_write(pp, MVNETA_ACC_MODE, MVNETA_ACC_MODE_EXT1);
 	netdev_info(pp->dev, "fail to update MTU, fall back to software BM\n");
 }
@@ -4948,7 +4948,6 @@ static int mvneta_probe(struct platform_
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	pp->id = global_port_id++;
-	pp->rx_offset_correction = MVNETA_SKB_HEADROOM;
 
 	/* Obtain access to BM resources if enabled and already initialized */
 	bm_node = of_parse_phandle(dn, "buffer-manager", 0);
@@ -4973,6 +4972,10 @@ static int mvneta_probe(struct platform_
 	}
 	of_node_put(bm_node);
 
+	/* sw buffer management */
+	if (!pp->bm_priv)
+		pp->rx_offset_correction = MVNETA_SKB_HEADROOM;
+
 	err = mvneta_init(&pdev->dev, pp);
 	if (err < 0)
 		goto err_netdev;
@@ -5130,6 +5133,7 @@ static int mvneta_resume(struct device *
 		err = mvneta_bm_port_init(pdev, pp);
 		if (err < 0) {
 			dev_info(&pdev->dev, "use SW buffer management\n");
+			pp->rx_offset_correction = MVNETA_SKB_HEADROOM;
 			pp->bm_priv = NULL;
 		}
 	}
author maintainer
#9 lore raw

PATCH 9/367 bnxt_en: Fix TC queue mapping.

In reply to Greg Kroah-Hartman

From: Michael Chan <[email protected]>

[ Upstream commit 18e4960c18f484ac288f41b43d0e6c4c88e6ea78 ]

The driver currently only calls netdev_set_tc_queue when the number of TCs is greater than 1. Instead, the comparison should be greater than or equal to 1. Even with 1 TC, we need to set the queue mapping.

This bug can cause warnings when the number of TCs is changed back to 1.

Fixes 7809592d3e2e ("bnxt_en: Enable MSIX early in bnxt_init_one().")
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +1 -1
@@ -7892,7 +7892,7 @@ static void bnxt_setup_msix(struct bnxt
 	int tcs, i;
 
 	tcs = netdev_get_num_tc(dev);
-	if (tcs > 1) {
+	if (tcs) {
 		int i, off, count;
 
 		for (i = 0; i < tcs; i++) {
author maintainer
#10 lore raw

PATCH 10/367 net: stmmac: Delete txtimer in suspend()

In reply to Greg Kroah-Hartman

From: Nicolin Chen <[email protected]>

[ Upstream commit 14b41a2959fbaa50932699d32ceefd6643abacc6 ]

When running v5.5 with a rootfs on NFS, memory abort may happen in the system resume stage:

 Unable to handle kernel paging request at virtual address dead00000000012a
 [dead00000000012a] address between user and kernel address ranges
 pc : run_timer_softirq+0x334/0x3d8
 lr : run_timer_softirq+0x244/0x3d8
 x1 : ffff800011cafe80 x0 : dead000000000122
 Call trace:
  run_timer_softirq+0x334/0x3d8
  efi_header_end+0x114/0x234
  irq_exit+0xd0/0xd8
  __handle_domain_irq+0x60/0xb0
  gic_handle_irq+0x58/0xa8
  el1_irq+0xb8/0x180
  arch_cpu_idle+0x10/0x18
  do_idle+0x1d8/0x2b0
  cpu_startup_entry+0x24/0x40
  secondary_start_kernel+0x1b4/0x208
 Code: f9000693 a9400660 f9000020 b4000040 (f9000401)
 ---[ end trace bb83ceeb4c482071 ]---
 Kernel panic - not syncing: Fatal exception in interrupt
 SMP: stopping secondary CPUs
 SMP: failed to stop secondary CPUs 2-3
 Kernel Offset: disabled
 CPU features: 0x00002,2300aa30
 Memory Limit: none
 ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]---

It's found that stmmac_xmit() and stmmac_resume() sometimes might run concurrently, possibly resulting in a race condition between mod_timer() and setup_timer(), being called by stmmac_xmit() and stmmac_resume() respectively.

Since the resume() runs setup_timer() every time, it'd be safer to have del_timer_sync() in the suspend() as the counterpart.

---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |    4 ++++
 1 file changed, 4 insertions(+)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +4 -0
@@ -4860,6 +4860,7 @@ int stmmac_suspend(struct device *dev)
 {
 	struct net_device *ndev = dev_get_drvdata(dev);
 	struct stmmac_priv *priv = netdev_priv(ndev);
+	u32 chan;
 
 	if (!ndev || !netif_running(ndev))
 		return 0;
@@ -4873,6 +4874,9 @@ int stmmac_suspend(struct device *dev)
 
 	stmmac_disable_all_queues(priv);
 
+	for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
+		del_timer_sync(&priv->tx_queue[chan].txtimer);
+
 	/* Stop TX/RX DMA */
 	stmmac_stop_all_dma(priv);
 
author maintainer
#11 lore raw

PATCH 11/367 tcp: clear tp->total_retrans in tcp_disconnect()

In reply to Greg Kroah-Hartman

From: Eric Dumazet <[email protected]>

[ Upstream commit c13c48c00a6bc1febc73902505bdec0967bd7095 ]

total_retrans needs to be cleared in tcp_disconnect().

tcp_disconnect() is rarely used, but it is worth fixing it.

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc SeongJae Park <[email protected]>
---
 net/ipv4/tcp.c |    1 +
 1 file changed, 1 insertion(+)
net/ipv4/tcp.c +1 -0
@@ -2625,6 +2625,7 @@ int tcp_disconnect(struct sock *sk, int
 	tcp_set_ca_state(sk, TCP_CA_Open);
 	tp->is_sack_reneg = 0;
 	tcp_clear_retrans(tp);
+	tp->total_retrans = 0;
 	inet_csk_delack_init(sk);
 	/* Initialize rcv_mss to TCP_MIN_MSS to avoid division by 0
 	 * issue in __tcp_select_window()
author maintainer
#12 lore raw

PATCH 12/367 tcp: clear tp->delivered in tcp_disconnect()

In reply to Greg Kroah-Hartman

From: Eric Dumazet <[email protected]>

[ Upstream commit 2fbdd56251b5c62f96589f39eded277260de7267 ]

tp->delivered needs to be cleared in tcp_disconnect().

tcp_disconnect() is rarely used, but it is worth fixing it.

---
 net/ipv4/tcp.c |    1 +
 1 file changed, 1 insertion(+)
net/ipv4/tcp.c +1 -0
@@ -2621,6 +2621,7 @@ int tcp_disconnect(struct sock *sk, int
 	tp->snd_cwnd = TCP_INIT_CWND;
 	tp->snd_cwnd_cnt = 0;
 	tp->window_clamp = 0;
+	tp->delivered = 0;
 	tp->delivered_ce = 0;
 	tcp_set_ca_state(sk, TCP_CA_Open);
 	tp->is_sack_reneg = 0;
author maintainer
#13 lore raw

PATCH 13/367 tcp: clear tp->data_segs{in|out} in tcp_disconnect()

In reply to Greg Kroah-Hartman

From: Eric Dumazet <[email protected]>

[ Upstream commit db7ffee6f3eb3683cdcaeddecc0a630a14546fe3 ]

tp->data_segs_in and tp->data_segs_out need to be cleared in tcp_disconnect().

tcp_disconnect() is rarely used, but it is worth fixing it.

Fixes a44d6eacdaf5 ("tcp: Add RFC4898 tcpEStatsPerfDataSegsOut/In")
Cc Martin KaFai Lau <[email protected]>
Cc Yuchung Cheng <[email protected]>
Cc Neal Cardwell <[email protected]>
---
 net/ipv4/tcp.c |    2 ++
 1 file changed, 2 insertions(+)
net/ipv4/tcp.c +2 -0
@@ -2642,6 +2642,8 @@ int tcp_disconnect(struct sock *sk, int
 	tp->bytes_acked = 0;
 	tp->bytes_received = 0;
 	tp->bytes_retrans = 0;
+	tp->data_segs_in = 0;
+	tp->data_segs_out = 0;
 	tp->duplicate_sack[0].start_seq = 0;
 	tp->duplicate_sack[0].end_seq = 0;
 	tp->dsack_dups = 0;
author maintainer
#14 lore raw

PATCH 14/367 tcp: clear tp->segs_{in|out} in tcp_disconnect()

In reply to Greg Kroah-Hartman

From: Eric Dumazet <[email protected]>

[ Upstream commit 784f8344de750a41344f4bbbebb8507a730fc99c ]

tp->segs_in and tp->segs_out need to be cleared in tcp_disconnect().

tcp_disconnect() is rarely used, but it is worth fixing it.

Fixes 2efd055c53c0 ("tcp: add tcpi_segs_in and tcpi_segs_out to tcp_info")
Cc Marcelo Ricardo Leitner <[email protected]>
Cc Yuchung Cheng <[email protected]>
Cc Neal Cardwell <[email protected]>
---
 net/ipv4/tcp.c |    2 ++
 1 file changed, 2 insertions(+)
net/ipv4/tcp.c +2 -0
@@ -2638,6 +2638,8 @@ int tcp_disconnect(struct sock *sk, int
 	sk->sk_rx_dst = NULL;
 	tcp_saved_syn_free(tp);
 	tp->compressed_ack = 0;
+	tp->segs_in = 0;
+	tp->segs_out = 0;
 	tp->bytes_sent = 0;
 	tp->bytes_acked = 0;
 	tp->bytes_received = 0;
author maintainer
#15 lore raw

PATCH 15/367 cls_rsvp: fix rsvp_policy

In reply to Greg Kroah-Hartman

From: Eric Dumazet <[email protected]>

[ Upstream commit cb3c0e6bdf64d0d124e94ce43cbe4ccbb9b37f51 ]

NLA_BINARY can be confusing, since .len value represents the max size of the blob.

cls_rsvp really wants user space to provide long enough data for TCA_RSVP_DST and TCA_RSVP_SRC attributes.

BUG: KMSAN: uninit-value in rsvp_get net/sched/cls_rsvp.h:258 [inline]
BUG: KMSAN: uninit-value in gen_handle net/sched/cls_rsvp.h:402 [inline]
BUG: KMSAN: uninit-value in rsvp_change+0x1ae9/0x4220 net/sched/cls_rsvp.h:572
CPU: 1 PID: 13228 Comm: syz-executor.1 Not tainted 5.5.0-rc5-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
 __dump_stack lib/dump_stack.c:77 [inline]
 dump_stack+0x1c9/0x220 lib/dump_stack.c:118
 kmsan_report+0xf7/0x1e0 mm/kmsan/kmsan_report.c:118
 __msan_warning+0x58/0xa0 mm/kmsan/kmsan_instr.c:215
 rsvp_get net/sched/cls_rsvp.h:258 [inline]
 gen_handle net/sched/cls_rsvp.h:402 [inline]
 rsvp_change+0x1ae9/0x4220 net/sched/cls_rsvp.h:572
 tc_new_tfilter+0x31fe/0x5010 net/sched/cls_api.c:2104
 rtnetlink_rcv_msg+0xcb7/0x1570 net/core/rtnetlink.c:5415
 netlink_rcv_skb+0x451/0x650 net/netlink/af_netlink.c:2477
 rtnetlink_rcv+0x50/0x60 net/core/rtnetlink.c:5442
 netlink_unicast_kernel net/netlink/af_netlink.c:1302 [inline]
 netlink_unicast+0xf9e/0x1100 net/netlink/af_netlink.c:1328
 netlink_sendmsg+0x1248/0x14d0 net/netlink/af_netlink.c:1917
 sock_sendmsg_nosec net/socket.c:639 [inline]
 sock_sendmsg net/socket.c:659 [inline]
 ____sys_sendmsg+0x12b6/0x1350 net/socket.c:2330
 ___sys_sendmsg net/socket.c:2384 [inline]
 __sys_sendmsg+0x451/0x5f0 net/socket.c:2417
 __do_sys_sendmsg net/socket.c:2426 [inline]
 __se_sys_sendmsg+0x97/0xb0 net/socket.c:2424
 __x64_sys_sendmsg+0x4a/0x70 net/socket.c:2424
 do_syscall_64+0xb8/0x160 arch/x86/entry/common.c:296
 entry_SYSCALL_64_after_hwframe+0x44/0xa9
RIP: 0033:0x45b349
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:00007f269d43dc78 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 00007f269d43e6d4 RCX: 000000000045b349
RDX: 0000000000000000 RSI: 00000000200001c0 RDI: 0000000000000003
RBP: 000000000075bfc8 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00000000ffffffff
R13: 00000000000009c2 R14: 00000000004cb338 R15: 000000000075bfd4

Uninit was created at:

 kmsan_save_stack_with_flags mm/kmsan/kmsan.c:144 [inline]
 kmsan_internal_poison_shadow+0x66/0xd0 mm/kmsan/kmsan.c:127
 kmsan_slab_alloc+0x8a/0xe0 mm/kmsan/kmsan_hooks.c:82
 slab_alloc_node mm/slub.c:2774 [inline]
 __kmalloc_node_track_caller+0xb40/0x1200 mm/slub.c:4382
 __kmalloc_reserve net/core/skbuff.c:141 [inline]
 __alloc_skb+0x2fd/0xac0 net/core/skbuff.c:209
 alloc_skb include/linux/skbuff.h:1049 [inline]
 netlink_alloc_large_skb net/netlink/af_netlink.c:1174 [inline]
 netlink_sendmsg+0x7d3/0x14d0 net/netlink/af_netlink.c:1892
 sock_sendmsg_nosec net/socket.c:639 [inline]
 sock_sendmsg net/socket.c:659 [inline]
 ____sys_sendmsg+0x12b6/0x1350 net/socket.c:2330
 ___sys_sendmsg net/socket.c:2384 [inline]
 __sys_sendmsg+0x451/0x5f0 net/socket.c:2417
 __do_sys_sendmsg net/socket.c:2426 [inline]
 __se_sys_sendmsg+0x97/0xb0 net/socket.c:2424
 __x64_sys_sendmsg+0x4a/0x70 net/socket.c:2424
 do_syscall_64+0xb8/0x160 arch/x86/entry/common.c:296
 entry_SYSCALL_64_after_hwframe+0x44/0xa9
Fixes 6fa8c0144b77 ("[NET_SCHED]: Use nla_policy for attribute validation in classifiers")
---
 net/sched/cls_rsvp.h |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
net/sched/cls_rsvp.h +2 -4
@@ -463,10 +463,8 @@ static u32 gen_tunnel(struct rsvp_head *
 
 static const struct nla_policy rsvp_policy[TCA_RSVP_MAX + 1] = {
 	[TCA_RSVP_CLASSID]	= { .type = NLA_U32 },
-	[TCA_RSVP_DST]		= { .type = NLA_BINARY,
-				    .len = RSVP_DST_LEN * sizeof(u32) },
-	[TCA_RSVP_SRC]		= { .type = NLA_BINARY,
-				    .len = RSVP_DST_LEN * sizeof(u32) },
+	[TCA_RSVP_DST]		= { .len = RSVP_DST_LEN * sizeof(u32) },
+	[TCA_RSVP_SRC]		= { .len = RSVP_DST_LEN * sizeof(u32) },
 	[TCA_RSVP_PINFO]	= { .len = sizeof(struct tc_rsvp_pinfo) },
 };
 
author maintainer
#16 lore raw

PATCH 16/367 rxrpc: Fix use-after-free in rxrpc_put_local()

In reply to Greg Kroah-Hartman

From: David Howells <[email protected]>

[ Upstream commit fac20b9e738523fc884ee3ea5be360a321cd8bad ]

Fix rxrpc_put_local() to not access local->debug_id after calling atomic_dec_return() as, unless that returned n==0, we no longer have the right to access the object.

Fixes 06d9532fa6b3 ("rxrpc: Fix read-after-free in rxrpc_queue_local()")
---
 net/rxrpc/local_object.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
net/rxrpc/local_object.c +4 -1
@@ -364,11 +364,14 @@ void rxrpc_queue_local(struct rxrpc_loca
 void rxrpc_put_local(struct rxrpc_local *local)
 {
 	const void *here = __builtin_return_address(0);
+	unsigned int debug_id;
 	int n;
 
 	if (local) {
+		debug_id = local->debug_id;
+
 		n = atomic_dec_return(&local->usage);
-		trace_rxrpc_local(local->debug_id, rxrpc_local_put, n, here);
+		trace_rxrpc_local(debug_id, rxrpc_local_put, n, here);
 
 		if (n == 0)
 			call_rcu(&local->rcu, rxrpc_local_rcu);
author maintainer
#17 lore raw

PATCH 17/367 rxrpc: Fix insufficient receive notification generation

In reply to Greg Kroah-Hartman

From: David Howells <[email protected]>

[ Upstream commit f71dbf2fb28489a79bde0dca1c8adfb9cdb20a6b ]

In rxrpc_input_data(), rxrpc_notify_socket() is called if the base sequence number of the packet is immediately following the hard-ack point at the end of the function. However, this isn't sufficient, since the recvmsg side may have been advancing the window and then overrun the position in which we're adding - at which point rx_hard_ack >= seq0 and no notification is generated.

Fix this by always generating a notification at the end of the input function.

Without this, a long call may stall, possibly indefinitely.

Fixes 248f219cb8bc ("rxrpc: Rewrite the data and ack handling code")
---
 net/rxrpc/input.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
net/rxrpc/input.c +2 -4
@@ -599,10 +599,8 @@ ack:
 				  false, true,
 				  rxrpc_propose_ack_input_data);
 
-	if (seq0 == READ_ONCE(call->rx_hard_ack) + 1) {
-		trace_rxrpc_notify_socket(call->debug_id, serial);
-		rxrpc_notify_socket(call);
-	}
+	trace_rxrpc_notify_socket(call->debug_id, serial);
+	rxrpc_notify_socket(call);
 
 unlock:
 	spin_unlock(&call->input_lock);
author maintainer
#18 lore raw

PATCH 18/367 rxrpc: Fix missing active use pinning of rxrpc_local object

In reply to Greg Kroah-Hartman

From: David Howells <[email protected]>

[ Upstream commit 04d36d748fac349b068ef621611f454010054c58 ]

The introduction of a split between the reference count on rxrpc_local objects and the usage count didn't quite go far enough. A number of kernel work items need to make use of the socket to perform transmission. These also need to get an active count on the local object to prevent the socket from being closed.

Fix this by getting the active count in those places.

Also split out the raw active count get/put functions as these places tend to hold refs on the rxrpc_local object already, so getting and putting an extra object ref is just a waste of time.

The problem can lead to symptoms like:

    BUG: kernel NULL pointer dereference, address: 0000000000000018
    ..
    CPU: 2 PID: 818 Comm: kworker/u9:0 Not tainted 5.5.0-fscache+ #51
    ...
    RIP: 0010:selinux_socket_sendmsg+0x5/0x13
    ...
    Call Trace:
     security_socket_sendmsg+0x2c/0x3e
     sock_sendmsg+0x1a/0x46
     rxrpc_send_keepalive+0x131/0x1ae
     rxrpc_peer_keepalive_worker+0x219/0x34b
     process_one_work+0x18e/0x271
     worker_thread+0x1a3/0x247
     kthread+0xe6/0xeb
     ret_from_fork+0x1f/0x30
Fixes 730c5fd42c1e ("rxrpc: Fix local endpoint refcounting")
---
 net/rxrpc/af_rxrpc.c     |    2 ++
 net/rxrpc/ar-internal.h  |   10 ++++++++++
 net/rxrpc/conn_event.c   |   30 ++++++++++++++++++++----------
 net/rxrpc/local_object.c |   18 +++++++-----------
 net/rxrpc/peer_event.c   |   40 ++++++++++++++++++++++------------------
 5 files changed, 61 insertions(+), 39 deletions(-)
net/rxrpc/af_rxrpc.c +2 -0
@@ -194,6 +194,7 @@ static int rxrpc_bind(struct socket *soc
 service_in_use:
 	write_unlock(&local->services_lock);
 	rxrpc_unuse_local(local);
+	rxrpc_put_local(local);
 	ret = -EADDRINUSE;
 error_unlock:
 	release_sock(&rx->sk);
@@ -899,6 +900,7 @@ static int rxrpc_release_sock(struct soc
 	rxrpc_purge_queue(&sk->sk_receive_queue);
 
 	rxrpc_unuse_local(rx->local);
+	rxrpc_put_local(rx->local);
 	rx->local = NULL;
 	key_put(rx->key);
 	rx->key = NULL;
net/rxrpc/ar-internal.h +10 -0
@@ -1021,6 +1021,16 @@ void rxrpc_unuse_local(struct rxrpc_loca
 void rxrpc_queue_local(struct rxrpc_local *);
 void rxrpc_destroy_all_locals(struct rxrpc_net *);
 
+static inline bool __rxrpc_unuse_local(struct rxrpc_local *local)
+{
+	return atomic_dec_return(&local->active_users) == 0;
+}
+
+static inline bool __rxrpc_use_local(struct rxrpc_local *local)
+{
+	return atomic_fetch_add_unless(&local->active_users, 1, 0) != 0;
+}
+
 /*
  * misc.c
  */
net/rxrpc/conn_event.c +20 -10
@@ -438,16 +438,12 @@ again:
 /*
  * connection-level event processor
  */
-void rxrpc_process_connection(struct work_struct *work)
+static void rxrpc_do_process_connection(struct rxrpc_connection *conn)
 {
-	struct rxrpc_connection *conn =
-		container_of(work, struct rxrpc_connection, processor);
 	struct sk_buff *skb;
 	u32 abort_code = RX_PROTOCOL_ERROR;
 	int ret;
 
-	rxrpc_see_connection(conn);
-
 	if (test_and_clear_bit(RXRPC_CONN_EV_CHALLENGE, &conn->events))
 		rxrpc_secure_connection(conn);
 
@@ -475,18 +471,32 @@ void rxrpc_process_connection(struct wor
 		}
 	}
 
-out:
-	rxrpc_put_connection(conn);
-	_leave("");
 	return;
 
 requeue_and_leave:
 	skb_queue_head(&conn->rx_queue, skb);
-	goto out;
+	return;
 
 protocol_error:
 	if (rxrpc_abort_connection(conn, ret, abort_code) < 0)
 		goto requeue_and_leave;
 	rxrpc_free_skb(skb, rxrpc_skb_freed);
-	goto out;
+	return;
+}
+
+void rxrpc_process_connection(struct work_struct *work)
+{
+	struct rxrpc_connection *conn =
+		container_of(work, struct rxrpc_connection, processor);
+
+	rxrpc_see_connection(conn);
+
+	if (__rxrpc_use_local(conn->params.local)) {
+		rxrpc_do_process_connection(conn);
+		rxrpc_unuse_local(conn->params.local);
+	}
+
+	rxrpc_put_connection(conn);
+	_leave("");
+	return;
 }
net/rxrpc/local_object.c +7 -11
@@ -383,14 +383,11 @@ void rxrpc_put_local(struct rxrpc_local
  */
 struct rxrpc_local *rxrpc_use_local(struct rxrpc_local *local)
 {
-	unsigned int au;
-
 	local = rxrpc_get_local_maybe(local);
 	if (!local)
 		return NULL;
 
-	au = atomic_fetch_add_unless(&local->active_users, 1, 0);
-	if (au == 0) {
+	if (!__rxrpc_use_local(local)) {
 		rxrpc_put_local(local);
 		return NULL;
 	}
@@ -404,14 +401,11 @@ struct rxrpc_local *rxrpc_use_local(stru
  */
 void rxrpc_unuse_local(struct rxrpc_local *local)
 {
-	unsigned int au;
-
 	if (local) {
-		au = atomic_dec_return(&local->active_users);
-		if (au == 0)
+		if (__rxrpc_unuse_local(local)) {
+			rxrpc_get_local(local);
 			rxrpc_queue_local(local);
-		else
-			rxrpc_put_local(local);
+		}
 	}
 }
 
@@ -468,7 +462,7 @@ static void rxrpc_local_processor(struct
 
 	do {
 		again = false;
-		if (atomic_read(&local->active_users) == 0) {
+		if (!__rxrpc_use_local(local)) {
 			rxrpc_local_destroyer(local);
 			break;
 		}
@@ -482,6 +476,8 @@ static void rxrpc_local_processor(struct
 			rxrpc_process_local_events(local);
 			again = true;
 		}
+
+		__rxrpc_unuse_local(local);
 	} while (again);
 
 	rxrpc_put_local(local);
net/rxrpc/peer_event.c +22 -18
@@ -364,27 +364,31 @@ static void rxrpc_peer_keepalive_dispatc
 		if (!rxrpc_get_peer_maybe(peer))
 			continue;
 
-		spin_unlock_bh(&rxnet->peer_hash_lock);
+		if (__rxrpc_use_local(peer->local)) {
+			spin_unlock_bh(&rxnet->peer_hash_lock);
 
-		keepalive_at = peer->last_tx_at + RXRPC_KEEPALIVE_TIME;
-		slot = keepalive_at - base;
-		_debug("%02x peer %u t=%d {%pISp}",
-		       cursor, peer->debug_id, slot, &peer->srx.transport);
+			keepalive_at = peer->last_tx_at + RXRPC_KEEPALIVE_TIME;
+			slot = keepalive_at - base;
+			_debug("%02x peer %u t=%d {%pISp}",
+			       cursor, peer->debug_id, slot, &peer->srx.transport);
 
-		if (keepalive_at <= base ||
-		    keepalive_at > base + RXRPC_KEEPALIVE_TIME) {
-			rxrpc_send_keepalive(peer);
-			slot = RXRPC_KEEPALIVE_TIME;
-		}
+			if (keepalive_at <= base ||
+			    keepalive_at > base + RXRPC_KEEPALIVE_TIME) {
+				rxrpc_send_keepalive(peer);
+				slot = RXRPC_KEEPALIVE_TIME;
+			}
 
-		/* A transmission to this peer occurred since last we examined
-		 * it so put it into the appropriate future bucket.
-		 */
-		slot += cursor;
-		slot &= mask;
-		spin_lock_bh(&rxnet->peer_hash_lock);
-		list_add_tail(&peer->keepalive_link,
-			      &rxnet->peer_keepalive[slot & mask]);
+			/* A transmission to this peer occurred since last we
+			 * examined it so put it into the appropriate future
+			 * bucket.
+			 */
+			slot += cursor;
+			slot &= mask;
+			spin_lock_bh(&rxnet->peer_hash_lock);
+			list_add_tail(&peer->keepalive_link,
+				      &rxnet->peer_keepalive[slot & mask]);
+			rxrpc_unuse_local(peer->local);
+		}
 		rxrpc_put_peer_locked(peer);
 	}
 
author maintainer
#19 lore raw

PATCH 19/367 rxrpc: Fix NULL pointer deref due to call->conn being cleared on disconnect

In reply to Greg Kroah-Hartman

From: David Howells <[email protected]>

[ Upstream commit 5273a191dca65a675dc0bcf3909e59c6933e2831 ]

When a call is disconnected, the connection pointer from the call is cleared to make sure it isn't used again and to prevent further attempted transmission for the call. Unfortunately, there might be a daemon trying to use it at the same time to transmit a packet.

Fix this by keeping call->conn set, but setting a flag on the call to indicate disconnection instead.

Remove also the bits in the transmission functions where the conn pointer is checked and a ref taken under spinlock as this is now redundant.

Fixes 8d94aa381dab ("rxrpc: Calls shouldn't hold socket refs")
---
 net/rxrpc/ar-internal.h |    1 +
 net/rxrpc/call_object.c |    4 ++--
 net/rxrpc/conn_client.c |    3 +--
 net/rxrpc/conn_object.c |    4 ++--
 net/rxrpc/output.c      |   27 +++++++++------------------
 5 files changed, 15 insertions(+), 24 deletions(-)
net/rxrpc/ar-internal.h +1 -0
@@ -490,6 +490,7 @@ enum rxrpc_call_flag {
 	RXRPC_CALL_RX_HEARD,		/* The peer responded at least once to this call */
 	RXRPC_CALL_RX_UNDERRUN,		/* Got data underrun */
 	RXRPC_CALL_IS_INTR,		/* The call is interruptible */
+	RXRPC_CALL_DISCONNECTED,	/* The call has been disconnected */
 };
 
 /*
net/rxrpc/call_object.c +2 -2
@@ -493,7 +493,7 @@ void rxrpc_release_call(struct rxrpc_soc
 
 	_debug("RELEASE CALL %p (%d CONN %p)", call, call->debug_id, conn);
 
-	if (conn)
+	if (conn && !test_bit(RXRPC_CALL_DISCONNECTED, &call->flags))
 		rxrpc_disconnect_call(call);
 	if (call->security)
 		call->security->free_call_crypto(call);
@@ -569,6 +569,7 @@ static void rxrpc_rcu_destroy_call(struc
 	struct rxrpc_call *call = container_of(rcu, struct rxrpc_call, rcu);
 	struct rxrpc_net *rxnet = call->rxnet;
 
+	rxrpc_put_connection(call->conn);
 	rxrpc_put_peer(call->peer);
 	kfree(call->rxtx_buffer);
 	kfree(call->rxtx_annotations);
@@ -590,7 +591,6 @@ void rxrpc_cleanup_call(struct rxrpc_cal
 
 	ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);
 	ASSERT(test_bit(RXRPC_CALL_RELEASED, &call->flags));
-	ASSERTCMP(call->conn, ==, NULL);
 
 	rxrpc_cleanup_ring(call);
 	rxrpc_free_skb(call->tx_pending, rxrpc_skb_cleaned);
net/rxrpc/conn_client.c +1 -2
@@ -785,6 +785,7 @@ void rxrpc_disconnect_client_call(struct
 	u32 cid;
 
 	spin_lock(&conn->channel_lock);
+	set_bit(RXRPC_CALL_DISCONNECTED, &call->flags);
 
 	cid = call->cid;
 	if (cid) {
@@ -792,7 +793,6 @@ void rxrpc_disconnect_client_call(struct
 		chan = &conn->channels[channel];
 	}
 	trace_rxrpc_client(conn, channel, rxrpc_client_chan_disconnect);
-	call->conn = NULL;
 
 	/* Calls that have never actually been assigned a channel can simply be
 	 * discarded.  If the conn didn't get used either, it will follow
@@ -908,7 +908,6 @@ out:
 	spin_unlock(&rxnet->client_conn_cache_lock);
 out_2:
 	spin_unlock(&conn->channel_lock);
-	rxrpc_put_connection(conn);
 	_leave("");
 	return;
 
net/rxrpc/conn_object.c +2 -2
@@ -171,6 +171,8 @@ void __rxrpc_disconnect_call(struct rxrp
 
 	_enter("%d,%x", conn->debug_id, call->cid);
 
+	set_bit(RXRPC_CALL_DISCONNECTED, &call->flags);
+
 	if (rcu_access_pointer(chan->call) == call) {
 		/* Save the result of the call so that we can repeat it if necessary
 		 * through the channel, whilst disposing of the actual call record.
@@ -223,9 +225,7 @@ void rxrpc_disconnect_call(struct rxrpc_
 	__rxrpc_disconnect_call(conn, call);
 	spin_unlock(&conn->channel_lock);
 
-	call->conn = NULL;
 	conn->idle_timestamp = jiffies;
-	rxrpc_put_connection(conn);
 }
 
 /*
net/rxrpc/output.c +9 -18
@@ -129,7 +129,7 @@ static size_t rxrpc_fill_out_ack(struct
 int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping,
 			  rxrpc_serial_t *_serial)
 {
-	struct rxrpc_connection *conn = NULL;
+	struct rxrpc_connection *conn;
 	struct rxrpc_ack_buffer *pkt;
 	struct msghdr msg;
 	struct kvec iov[2];
@@ -139,18 +139,14 @@ int rxrpc_send_ack_packet(struct rxrpc_c
 	int ret;
 	u8 reason;
 
-	spin_lock_bh(&call->lock);
-	if (call->conn)
-		conn = rxrpc_get_connection_maybe(call->conn);
-	spin_unlock_bh(&call->lock);
-	if (!conn)
+	if (test_bit(RXRPC_CALL_DISCONNECTED, &call->flags))
 		return -ECONNRESET;
 
 	pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
-	if (!pkt) {
-		rxrpc_put_connection(conn);
+	if (!pkt)
 		return -ENOMEM;
-	}
+
+	conn = call->conn;
 
 	msg.msg_name	= &call->peer->srx.transport;
 	msg.msg_namelen	= call->peer->srx.transport_len;
@@ -244,7 +240,6 @@ int rxrpc_send_ack_packet(struct rxrpc_c
 	}
 
 out:
-	rxrpc_put_connection(conn);
 	kfree(pkt);
 	return ret;
 }
@@ -254,7 +249,7 @@ out:
  */
 int rxrpc_send_abort_packet(struct rxrpc_call *call)
 {
-	struct rxrpc_connection *conn = NULL;
+	struct rxrpc_connection *conn;
 	struct rxrpc_abort_buffer pkt;
 	struct msghdr msg;
 	struct kvec iov[1];
@@ -271,13 +266,11 @@ int rxrpc_send_abort_packet(struct rxrpc
 	    test_bit(RXRPC_CALL_TX_LAST, &call->flags))
 		return 0;
 
-	spin_lock_bh(&call->lock);
-	if (call->conn)
-		conn = rxrpc_get_connection_maybe(call->conn);
-	spin_unlock_bh(&call->lock);
-	if (!conn)
+	if (test_bit(RXRPC_CALL_DISCONNECTED, &call->flags))
 		return -ECONNRESET;
 
+	conn = call->conn;
+
 	msg.msg_name	= &call->peer->srx.transport;
 	msg.msg_namelen	= call->peer->srx.transport_len;
 	msg.msg_control	= NULL;
@@ -312,8 +305,6 @@ int rxrpc_send_abort_packet(struct rxrpc
 		trace_rxrpc_tx_packet(call->debug_id, &pkt.whdr,
 				      rxrpc_tx_point_call_abort);
 	rxrpc_tx_backoff(call, ret);
-
-	rxrpc_put_connection(conn);
 	return ret;
 }
 
author maintainer
#20 lore raw

PATCH 20/367 bnxt_en: Refactor logic to re-enable SRIOV after firmware reset detected.

In reply to Greg Kroah-Hartman

From: Michael Chan <[email protected]>

[ Upstream commit c16d4ee0e397163fe7ceac281eaa952e63fadec7 ]

Put the current logic in bnxt_open() to re-enable SRIOV after detecting firmware reset into a new function bnxt_reenable_sriov(). This call needs to be invoked in the firmware reset path also in the next patch.

---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c |   19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +12 -7
@@ -9240,6 +9240,17 @@ void bnxt_half_close_nic(struct bnxt *bp
 	bnxt_free_mem(bp, false);
 }
 
+static void bnxt_reenable_sriov(struct bnxt *bp)
+{
+	if (BNXT_PF(bp)) {
+		struct bnxt_pf_info *pf = &bp->pf;
+		int n = pf->active_vfs;
+
+		if (n)
+			bnxt_cfg_hw_sriov(bp, &n, true);
+	}
+}
+
 static int bnxt_open(struct net_device *dev)
 {
 	struct bnxt *bp = netdev_priv(dev);
@@ -9258,13 +9269,7 @@ static int bnxt_open(struct net_device *
 		bnxt_hwrm_if_change(bp, false);
 	} else {
 		if (test_and_clear_bit(BNXT_STATE_FW_RESET_DET, &bp->state)) {
-			if (BNXT_PF(bp)) {
-				struct bnxt_pf_info *pf = &bp->pf;
-				int n = pf->active_vfs;
-
-				if (n)
-					bnxt_cfg_hw_sriov(bp, &n, true);
-			}
+			bnxt_reenable_sriov(bp);
 			if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state))
 				bnxt_ulp_start(bp, 0);
 		}
author maintainer
#21 lore raw

PATCH 21/367 net: phy: at803x: disable vddio regulator

In reply to Greg Kroah-Hartman

From: Michael Walle <[email protected]>

[ Upstream commit 2318ca8aef3877da2b16b92edce47a497370a86e ]

The probe() might enable a VDDIO regulator, which needs to be disabled again before calling regulator_put(). Add a remove() function.

Fixes 2f664823a470 ("net: phy: at803x: add device tree binding")
---
 drivers/net/phy/at803x.c |   11 +++++++++++
 1 file changed, 11 insertions(+)
drivers/net/phy/at803x.c +11 -0
@@ -489,6 +489,14 @@ static int at803x_probe(struct phy_devic
 	return at803x_parse_dt(phydev);
 }
 
+static void at803x_remove(struct phy_device *phydev)
+{
+	struct at803x_priv *priv = phydev->priv;
+
+	if (priv->vddio)
+		regulator_disable(priv->vddio);
+}
+
 static int at803x_clk_out_config(struct phy_device *phydev)
 {
 	struct at803x_priv *priv = phydev->priv;
@@ -711,6 +719,7 @@ static struct phy_driver at803x_driver[]
 	.name			= "Qualcomm Atheros AR8035",
 	.phy_id_mask		= AT803X_PHY_ID_MASK,
 	.probe			= at803x_probe,
+	.remove			= at803x_remove,
 	.config_init		= at803x_config_init,
 	.set_wol		= at803x_set_wol,
 	.get_wol		= at803x_get_wol,
@@ -726,6 +735,7 @@ static struct phy_driver at803x_driver[]
 	.name			= "Qualcomm Atheros AR8030",
 	.phy_id_mask		= AT803X_PHY_ID_MASK,
 	.probe			= at803x_probe,
+	.remove			= at803x_remove,
 	.config_init		= at803x_config_init,
 	.link_change_notify	= at803x_link_change_notify,
 	.set_wol		= at803x_set_wol,
@@ -741,6 +751,7 @@ static struct phy_driver at803x_driver[]
 	.name			= "Qualcomm Atheros AR8031/AR8033",
 	.phy_id_mask		= AT803X_PHY_ID_MASK,
 	.probe			= at803x_probe,
+	.remove			= at803x_remove,
 	.config_init		= at803x_config_init,
 	.set_wol		= at803x_set_wol,
 	.get_wol		= at803x_get_wol,
author maintainer
#22 lore raw

PATCH 22/367 bnxt_en: Fix RDMA driver failure with SRIOV after firmware reset.

In reply to Greg Kroah-Hartman

From: Michael Chan <[email protected]>

[ Upstream commit 12de2eadf87825c3990c1aa68b5e93101ca2f043 ]

bnxt_ulp_start() needs to be called before SRIOV is re-enabled after firmware reset. Re-enabling SRIOV may consume all the resources and may cause the RDMA driver to fail to get MSIX and other resources. Fix it by calling bnxt_ulp_start() first before calling bnxt_reenable_sriov().

We re-arrange the logic so that we call bnxt_ulp_start() and bnxt_reenable_sriov() in proper sequence in bnxt_fw_reset_task() and bnxt_open(). The former is the normal coordinated firmware reset sequence and the latter is firmware reset while the function is down. This new logic is now more straight forward and will now fix both scenarios.

Fixes f3a6d206c25a ("bnxt_en: Call bnxt_ulp_stop()/bnxt_ulp_start() during error recovery.")
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +5 -2
@@ -9269,9 +9269,10 @@ static int bnxt_open(struct net_device *
 		bnxt_hwrm_if_change(bp, false);
 	} else {
 		if (test_and_clear_bit(BNXT_STATE_FW_RESET_DET, &bp->state)) {
-			bnxt_reenable_sriov(bp);
-			if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state))
+			if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) {
 				bnxt_ulp_start(bp, 0);
+				bnxt_reenable_sriov(bp);
+			}
 		}
 		bnxt_hwmon_open(bp);
 	}
@@ -10827,6 +10828,8 @@ static void bnxt_fw_reset_task(struct wo
 		smp_mb__before_atomic();
 		clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
 		bnxt_ulp_start(bp, rc);
+		if (!rc)
+			bnxt_reenable_sriov(bp);
 		bnxt_dl_health_status_update(bp, true);
 		rtnl_unlock();
 		break;
author maintainer
#23 lore raw

PATCH 23/367 ionic: fix rxq comp packet type mask

In reply to Greg Kroah-Hartman

From: Shannon Nelson <[email protected]>

[ Upstream commit b5ce31b5e11b768b7d685b2bab7db09ad5549493 ]

Be sure to include all the packet type bits in the mask.

Fixes fbfb8031533c ("ionic: Add hardware init and device commands")
---
 drivers/net/ethernet/pensando/ionic/ionic_if.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/pensando/ionic/ionic_if.h +1 -1
@@ -862,7 +862,7 @@ struct ionic_rxq_comp {
 #define IONIC_RXQ_COMP_CSUM_F_VLAN	0x40
 #define IONIC_RXQ_COMP_CSUM_F_CALC	0x80
 	u8     pkt_type_color;
-#define IONIC_RXQ_COMP_PKT_TYPE_MASK	0x0f
+#define IONIC_RXQ_COMP_PKT_TYPE_MASK	0x7f
 };
 
 enum ionic_pkt_type {
author maintainer
#24 lore raw

PATCH 24/367 MAINTAINERS: correct entries for ISDN/mISDN section

In reply to Greg Kroah-Hartman

From: Lukas Bulwahn <[email protected]>

[ Upstream commit dff6bc1bfd462b76dc13ec19dedc2c134a62ac59 ]

Commit 6d97985072dc ("isdn: move capi drivers to staging") cleaned up the isdn drivers and split the MAINTAINERS section for ISDN, but missed to add the terminal slash for the two directories mISDN and hardware. Hence, all files in those directories were not part of the new ISDN/mISDN SUBSYSTEM, but were considered to be part of "THE REST".

Rectify the situation, and while at it, also complete the section with two further build files that belong to that subsystem.

This was identified with a small script that finds all files belonging to "THE REST" according to the current MAINTAINERS file, and I investigated upon its output.

Fixes 6d97985072dc ("isdn: move capi drivers to staging")
---
 MAINTAINERS |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
MAINTAINERS +4 -2
@@ -8808,8 +8808,10 @@ L:	[email protected] (su
 L:	[email protected]
 W:	http://www.isdn4linux.de
 S:	Maintained
-F:	drivers/isdn/mISDN
-F:	drivers/isdn/hardware
+F:	drivers/isdn/mISDN/
+F:	drivers/isdn/hardware/
+F:	drivers/isdn/Kconfig
+F:	drivers/isdn/Makefile
 
 ISDN/CAPI SUBSYSTEM
 M:	Karsten Keil <[email protected]>
author maintainer
#25 lore raw

PATCH 25/367 netdevsim: fix stack-out-of-bounds in nsim_dev_debugfs_init()

In reply to Greg Kroah-Hartman

From: Taehee Yoo <[email protected]>

[ Upstream commit 6fb8852b1298200da39bd85788bc5755d1d56f32 ]

When netdevsim dev is being created, a debugfs directory is created. The variable "dev_ddir_name" is 16bytes device name pointer and device name is "netdevsim<dev id>".
The maximum dev id length is 10.
So, 16bytes for device name isn't enough.

Test commands:

    modprobe netdevsim
    echo "1000000000 0" > /sys/bus/netdevsim/new_device

Splat looks like:

[  249.622710][  T900] BUG: KASAN: stack-out-of-bounds in number+0x824/0x880
[  249.623658][  T900] Write of size 1 at addr ffff88804c527988 by task bash/900
[  249.624521][  T900]
[  249.624830][  T900] CPU: 1 PID: 900 Comm: bash Not tainted 5.5.0+ #322
[  249.625691][  T900] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
[  249.626712][  T900] Call Trace:
[  249.627103][  T900]  dump_stack+0x96/0xdb
[  249.627639][  T900]  ? number+0x824/0x880
[  249.628173][  T900]  print_address_description.constprop.5+0x1be/0x360
[  249.629022][  T900]  ? number+0x824/0x880
[  249.629569][  T900]  ? number+0x824/0x880
[  249.630105][  T900]  __kasan_report+0x12a/0x170
[  249.630717][  T900]  ? number+0x824/0x880
[  249.631201][  T900]  kasan_report+0xe/0x20
[  249.631723][  T900]  number+0x824/0x880
[  249.632235][  T900]  ? put_dec+0xa0/0xa0
[  249.632716][  T900]  ? rcu_read_lock_sched_held+0x90/0xc0
[  249.633392][  T900]  vsnprintf+0x63c/0x10b0
[  249.633983][  T900]  ? pointer+0x5b0/0x5b0
[  249.634543][  T900]  ? mark_lock+0x11d/0xc40
[  249.635200][  T900]  sprintf+0x9b/0xd0
[  249.635750][  T900]  ? scnprintf+0xe0/0xe0
[  249.636370][  T900]  nsim_dev_probe+0x63c/0xbf0 [netdevsim]

[ ... ]

Fixes ab1d0cc004d7 ("netdevsim: change debugfs tree topology")
---
 drivers/net/netdevsim/dev.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/netdevsim/dev.c +1 -1
@@ -73,7 +73,7 @@ static const struct file_operations nsim
 
 static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
 {
-	char dev_ddir_name[16];
+	char dev_ddir_name[sizeof(DRV_NAME) + 10];
 
 	sprintf(dev_ddir_name, DRV_NAME "%u", nsim_dev->nsim_bus_dev->dev.id);
 	nsim_dev->ddir = debugfs_create_dir(dev_ddir_name, nsim_dev_ddir);
author maintainer
#26 lore raw

PATCH 26/367 bnxt_en: Fix logic that disables Bus Master during firmware reset.

In reply to Greg Kroah-Hartman

From: Vasundhara Volam <[email protected]>

[ Upstream commit d407302895d3f3ca3a333c711744a95e0b1b0150 ]

The current logic that calls pci_disable_device() in __bnxt_close_nic() during firmware reset is flawed. If firmware is still alive, we're disabling the device too early, causing some firmware commands to not reach the firmware.

Fix it by moving the logic to bnxt_reset_close(). If firmware is in fatal condition, we call pci_disable_device() before we free any of the rings to prevent DMA corruption of the freed rings. If firmware is still alive, we call pci_disable_device() after the last firmware message has been sent.

Fixes 3bc7d4a352ef ("bnxt_en: Add BNXT_STATE_IN_FW_RESET state.")
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c |   11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +7 -4
@@ -9312,10 +9312,6 @@ static void __bnxt_close_nic(struct bnxt
 	bnxt_debug_dev_exit(bp);
 	bnxt_disable_napi(bp);
 	del_timer_sync(&bp->timer);
-	if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state) &&
-	    pci_is_enabled(bp->pdev))
-		pci_disable_device(bp->pdev);
-
 	bnxt_free_skbs(bp);
 
 	/* Save ring stats before shutdown */
@@ -10093,9 +10089,16 @@ static void bnxt_reset(struct bnxt *bp,
 static void bnxt_fw_reset_close(struct bnxt *bp)
 {
 	bnxt_ulp_stop(bp);
+	/* When firmware is fatal state, disable PCI device to prevent
+	 * any potential bad DMAs before freeing kernel memory.
+	 */
+	if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state))
+		pci_disable_device(bp->pdev);
 	__bnxt_close_nic(bp, true, false);
 	bnxt_clear_int_mode(bp);
 	bnxt_hwrm_func_drv_unrgtr(bp);
+	if (pci_is_enabled(bp->pdev))
+		pci_disable_device(bp->pdev);
 	bnxt_free_ctx_mem(bp);
 	kfree(bp->ctx);
 	bp->ctx = NULL;
author maintainer
#27 lore raw

PATCH 27/367 media: uvcvideo: Avoid cyclic entity chains due to malformed USB descriptors

In reply to Greg Kroah-Hartman

From: Will Deacon <[email protected]>

commit 68035c80e129c4cfec659aac4180354530b26527 upstream.

Way back in 2017, fuzzing the 4.14-rc2 USB stack with syzkaller kicked up the following WARNING from the UVC chain scanning code:

  | list_add double add: new=ffff880069084010, prev=ffff880069084010,
  | next=ffff880067d22298.
  | ------------[ cut here ]------------
  | WARNING: CPU: 1 PID: 1846 at lib/list_debug.c:31 __list_add_valid+0xbd/0xf0
  | Modules linked in:
  | CPU: 1 PID: 1846 Comm: kworker/1:2 Not tainted
  | 4.14.0-rc2-42613-g1488251d1a98 #238
  | Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
  | Workqueue: usb_hub_wq hub_event
  | task: ffff88006b01ca40 task.stack: ffff880064358000
  | RIP: 0010:__list_add_valid+0xbd/0xf0 lib/list_debug.c:29
  | RSP: 0018:ffff88006435ddd0 EFLAGS: 00010286
  | RAX: 0000000000000058 RBX: ffff880067d22298 RCX: 0000000000000000
  | RDX: 0000000000000058 RSI: ffffffff85a58800 RDI: ffffed000c86bbac
  | RBP: ffff88006435dde8 R08: 1ffff1000c86ba52 R09: 0000000000000000
  | R10: 0000000000000002 R11: 0000000000000000 R12: ffff880069084010
  | R13: ffff880067d22298 R14: ffff880069084010 R15: ffff880067d222a0
  | FS:  0000000000000000(0000) GS:ffff88006c900000(0000) knlGS:0000000000000000
  | CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  | CR2: 0000000020004ff2 CR3: 000000006b447000 CR4: 00000000000006e0
  | Call Trace:
  |  __list_add ./include/linux/list.h:59
  |  list_add_tail+0x8c/0x1b0 ./include/linux/list.h:92
  |  uvc_scan_chain_forward.isra.8+0x373/0x416
  | drivers/media/usb/uvc/uvc_driver.c:1471
  |  uvc_scan_chain drivers/media/usb/uvc/uvc_driver.c:1585
  |  uvc_scan_device drivers/media/usb/uvc/uvc_driver.c:1769
  |  uvc_probe+0x77f2/0x8f00 drivers/media/usb/uvc/uvc_driver.c:2104

Looking into the output from usbmon, the interesting part is the following data packet:

ffff880069c63e00 30710169 C Ci:1:002:0 0 143 = 09028f00 01030080 00090403 00000e01 00000924 03000103 7c003328 010204db

If we drop the lead configuration and interface descriptors, we're left with an output terminal descriptor describing a generic display:

/* Output terminal descriptor */
buf[0] 09
buf[1] 24
buf[2] 03 /* UVC_VC_OUTPUT_TERMINAL */
buf[3] 00 /* ID */
buf[4] 01 /* type == 0x0301 (UVC_OTT_DISPLAY) */
buf[5] 03
buf[6] 7c
buf[7] 00 /* source ID refers to self! */
buf[8] 33

The problem with this descriptor is that it is self-referential: the source ID of 0 matches itself! This causes the 'struct uvc_entity' representing the display to be added to its chain list twice during 'uvc_scan_chain()': once via 'uvc_scan_chain_entity()' when it is processed directly from the 'dev->entities' list and then again immediately afterwards when trying to follow the source ID in 'uvc_scan_chain_forward()'

Add a check before adding an entity to a chain list to ensure that the entity is not already part of a chain.

---
 drivers/media/usb/uvc/uvc_driver.c |   12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/media/usb/uvc/uvc_driver.c +12 -0
@@ -1493,6 +1493,11 @@ static int uvc_scan_chain_forward(struct
 			break;
 		if (forward == prev)
 			continue;
+		if (forward->chain.next || forward->chain.prev) {
+			uvc_trace(UVC_TRACE_DESCR, "Found reference to "
+				"entity %d already in chain.\n", forward->id);
+			return -EINVAL;
+		}
 
 		switch (UVC_ENTITY_TYPE(forward)) {
 		case UVC_VC_EXTENSION_UNIT:
@@ -1574,6 +1579,13 @@ static int uvc_scan_chain_backward(struc
 				return -1;
 			}
 
+			if (term->chain.next || term->chain.prev) {
+				uvc_trace(UVC_TRACE_DESCR, "Found reference to "
+					"entity %d already in chain.\n",
+					term->id);
+				return -EINVAL;
+			}
+
 			if (uvc_trace_param & UVC_TRACE_PROBE)
 				printk(KERN_CONT " %d", term->id);
 
author maintainer
#28 lore raw

PATCH 28/367 mfd: dln2: More sanity checking for endpoints

In reply to Greg Kroah-Hartman

From: Oliver Neukum <[email protected]>

commit 2b8bd606b1e60ca28c765f69c1eedd7d2a2e9dca upstream.

It is not enough to check for the number of endpoints. The types must also be correct.

---
 drivers/mfd/dln2.c |   13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)
drivers/mfd/dln2.c +11 -2
@@ -722,6 +722,8 @@ static int dln2_probe(struct usb_interfa
 		      const struct usb_device_id *usb_id)
 {
 	struct usb_host_interface *hostif = interface->cur_altsetting;
+	struct usb_endpoint_descriptor *epin;
+	struct usb_endpoint_descriptor *epout;
 	struct device *dev = &interface->dev;
 	struct dln2_dev *dln2;
 	int ret;
@@ -731,12 +733,19 @@ static int dln2_probe(struct usb_interfa
 	    hostif->desc.bNumEndpoints < 2)
 		return -ENODEV;
 
+	epin = &hostif->endpoint[0].desc;
+	epout = &hostif->endpoint[1].desc;
+	if (!usb_endpoint_is_bulk_out(epout))
+		return -ENODEV;
+	if (!usb_endpoint_is_bulk_in(epin))
+		return -ENODEV;
+
 	dln2 = kzalloc(sizeof(*dln2), GFP_KERNEL);
 	if (!dln2)
 		return -ENOMEM;
 
-	dln2->ep_out = hostif->endpoint[0].desc.bEndpointAddress;
-	dln2->ep_in = hostif->endpoint[1].desc.bEndpointAddress;
+	dln2->ep_out = epout->bEndpointAddress;
+	dln2->ep_in = epin->bEndpointAddress;
 	dln2->usb_dev = usb_get_dev(interface_to_usbdev(interface));
 	dln2->interface = interface;
 	usb_set_intfdata(interface, dln2);
author maintainer
#29 lore raw

PATCH 29/367 netfilter: ipset: fix suspicious RCU usage in find_set_and_id

In reply to Greg Kroah-Hartman

From: Kadlecsik József <[email protected]>

commit 5038517119d50ed0240059b1d7fc2faa92371c08 upstream.

find_set_and_id() is called when the NFNL_SUBSYS_IPSET mutex is held. However, in the error path there can be a follow-up recvmsg() without the mutex held. Use the start() function of struct netlink_dump_control instead of dump() to verify and report if the specified set does not exist.

Thanks to Pablo Neira Ayuso for helping me to understand the subleties of the netlink protocol.

---
 net/netfilter/ipset/ip_set_core.c |   41 +++++++++++++++++++-------------------
 1 file changed, 21 insertions(+), 20 deletions(-)
net/netfilter/ipset/ip_set_core.c +21 -20
@@ -1483,31 +1483,34 @@ ip_set_dump_policy[IPSET_ATTR_CMD_MAX +
 };
 
 static int
-dump_init(struct netlink_callback *cb, struct ip_set_net *inst)
+ip_set_dump_start(struct netlink_callback *cb)
 {
 	struct nlmsghdr *nlh = nlmsg_hdr(cb->skb);
 	int min_len = nlmsg_total_size(sizeof(struct nfgenmsg));
 	struct nlattr *cda[IPSET_ATTR_CMD_MAX + 1];
 	struct nlattr *attr = (void *)nlh + min_len;
+	struct sk_buff *skb = cb->skb;
+	struct ip_set_net *inst = ip_set_pernet(sock_net(skb->sk));
 	u32 dump_type;
-	ip_set_id_t index;
 	int ret;
 
 	ret = nla_parse(cda, IPSET_ATTR_CMD_MAX, attr,
 			nlh->nlmsg_len - min_len,
 			ip_set_dump_policy, NULL);
 	if (ret)
-		return ret;
+		goto error;
 
 	cb->args[IPSET_CB_PROTO] = nla_get_u8(cda[IPSET_ATTR_PROTOCOL]);
 	if (cda[IPSET_ATTR_SETNAME]) {
+		ip_set_id_t index;
 		struct ip_set *set;
 
 		set = find_set_and_id(inst, nla_data(cda[IPSET_ATTR_SETNAME]),
 				      &index);
-		if (!set)
-			return -ENOENT;
-
+		if (!set) {
+			ret = -ENOENT;
+			goto error;
+		}
 		dump_type = DUMP_ONE;
 		cb->args[IPSET_CB_INDEX] = index;
 	} else {
@@ -1523,10 +1526,17 @@ dump_init(struct netlink_callback *cb, s
 	cb->args[IPSET_CB_DUMP] = dump_type;
 
 	return 0;
+
+error:
+	/* We have to create and send the error message manually :-( */
+	if (nlh->nlmsg_flags & NLM_F_ACK) {
+		netlink_ack(cb->skb, nlh, ret, NULL);
+	}
+	return ret;
 }
 
 static int
-ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb)
+ip_set_dump_do(struct sk_buff *skb, struct netlink_callback *cb)
 {
 	ip_set_id_t index = IPSET_INVALID_ID, max;
 	struct ip_set *set = NULL;
@@ -1537,18 +1547,8 @@ ip_set_dump_start(struct sk_buff *skb, s
 	bool is_destroyed;
 	int ret = 0;
 
-	if (!cb->args[IPSET_CB_DUMP]) {
-		ret = dump_init(cb, inst);
-		if (ret < 0) {
-			nlh = nlmsg_hdr(cb->skb);
-			/* We have to create and send the error message
-			 * manually :-(
-			 */
-			if (nlh->nlmsg_flags & NLM_F_ACK)
-				netlink_ack(cb->skb, nlh, ret, NULL);
-			return ret;
-		}
-	}
+	if (!cb->args[IPSET_CB_DUMP])
+		return -EINVAL;
 
 	if (cb->args[IPSET_CB_INDEX] >= inst->ip_set_max)
 		goto out;
@@ -1684,7 +1684,8 @@ static int ip_set_dump(struct net *net,
 
 	{
 		struct netlink_dump_control c = {
-			.dump = ip_set_dump_start,
+			.start = ip_set_dump_start,
+			.dump = ip_set_dump_do,
 			.done = ip_set_dump_done,
 		};
 		return netlink_dump_start(ctnl, skb, nlh, &c);
author maintainer
#30 lore raw

PATCH 30/367 ALSA: pcm: Fix memory leak at closing a stream without hw_free

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 66f2d19f8116e16898f8d82e28573a384ddc430d upstream.

ALSA PCM core recently introduced a new managed PCM buffer allocation mode that does allocate / free automatically at hw_params and hw_free. However, it overlooked the code path directly calling hw_free PCM ops at releasing the PCM substream, and it may result in a memory leak as spotted by syzkaller when no buffer preallocation is used (e.g. vmalloc buffer).

This patch papers over it with a slight refactoring. The hw_free ops call and relevant tasks are unified in a new helper function, and call it from both places.

Fixes 0dba808eae26 ("ALSA: pcm: Introduce managed buffer allocation mode")
Reported-by [email protected]
---
 sound/core/pcm_native.c |   24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)
sound/core/pcm_native.c +15 -9
@@ -785,10 +785,22 @@ end:
 	return err;
 }
 
+static int do_hw_free(struct snd_pcm_substream *substream)
+{
+	int result = 0;
+
+	snd_pcm_sync_stop(substream);
+	if (substream->ops->hw_free)
+		result = substream->ops->hw_free(substream);
+	if (substream->managed_buffer_alloc)
+		snd_pcm_lib_free_pages(substream);
+	return result;
+}
+
 static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime;
-	int result = 0;
+	int result;
 
 	if (PCM_RUNTIME_CHECK(substream))
 		return -ENXIO;
@@ -805,11 +817,7 @@ static int snd_pcm_hw_free(struct snd_pc
 	snd_pcm_stream_unlock_irq(substream);
 	if (atomic_read(&substream->mmap_count))
 		return -EBADFD;
-	snd_pcm_sync_stop(substream);
-	if (substream->ops->hw_free)
-		result = substream->ops->hw_free(substream);
-	if (substream->managed_buffer_alloc)
-		snd_pcm_lib_free_pages(substream);
+	result = do_hw_free(substream);
 	snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
 	pm_qos_remove_request(&substream->latency_pm_qos_req);
 	return result;
@@ -2466,9 +2474,7 @@ void snd_pcm_release_substream(struct sn
 
 	snd_pcm_drop(substream);
 	if (substream->hw_opened) {
-		if (substream->ops->hw_free &&
-		    substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
-			substream->ops->hw_free(substream);
+		do_hw_free(substream);
 		substream->ops->close(substream);
 		substream->hw_opened = 0;
 	}
author maintainer
#31 lore raw

PATCH 31/367 ipc/msg.c: consolidate all xxxctl_down() functions

In reply to Greg Kroah-Hartman

From: Lu Shuaibing <[email protected]>

commit 889b331724c82c11e15ba0a60979cf7bded0a26c upstream.

A use of uninitialized memory in msgctl_down() because msqid64 in ksys_msgctl hasn't been initialized. The local | msqid64 | is created in ksys_msgctl() and then passed into msgctl_down(). Along the way msqid64 is never initialized before msgctl_down() checks msqid64->msg_qbytes.

KUMSAN(KernelUninitializedMemorySantizer, a new error detection tool) reports:

==================================================================

BUG: KUMSAN: use of uninitialized memory in msgctl_down+0x94/0x300
Read of size 8 at addr ffff88806bb97eb8 by task syz-executor707/2022

CPU: 0 PID: 2022 Comm: syz-executor707 Not tainted 5.2.0-rc4+ #63
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
Call Trace:
 dump_stack+0x75/0xae
 __kumsan_report+0x17c/0x3e6
 kumsan_report+0xe/0x20
 msgctl_down+0x94/0x300
 ksys_msgctl.constprop.14+0xef/0x260
 do_syscall_64+0x7e/0x1f0
 entry_SYSCALL_64_after_hwframe+0x44/0xa9
RIP: 0033:0x4400e9
Code: 18 89 d0 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 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 fb 13 fc ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007ffd869e0598 EFLAGS: 00000246 ORIG_RAX: 0000000000000047
RAX: ffffffffffffffda RBX: 00000000004002c8 RCX: 00000000004400e9
RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: 00000000006ca018 R08: 0000000000000000 R09: 0000000000000000
R10: 00000000ffffffff R11: 0000000000000246 R12: 0000000000401970
R13: 0000000000401a00 R14: 0000000000000000 R15: 0000000000000000

The buggy address belongs to the page:
page:ffffea0001aee5c0 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0
flags: 0x100000000000000()
raw: 0100000000000000 0000000000000000 ffffffff01ae0101 0000000000000000
raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
page dumped because: kumsan: bad access detected
==================================================================

Syzkaller reproducer:
msgctl$IPC_RMID(0x0, 0x0)

C reproducer:
// autogenerated by syzkaller (https://github.com/google/syzkaller)

int main(void)
{
syscall(__NR_mmap, 0x20000000, 0x1000000, 3, 0x32, -1, 0); syscall(__NR_msgctl, 0, 0, 0);
return 0;
}

From: Andrew Morton <[email protected]>
Subject: [PATCH 5.5 031/367] ipc/msg.c: consolidate all xxxctl_down() functions

Each line here overflows 80 cols by exactly one character. Delete one tab per line to fix.

---
 ipc/msg.c |   19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)
ipc/msg.c +10 -9
@@ -377,7 +377,7 @@ copy_msqid_from_user(struct msqid64_ds *
  * NOTE: no locks must be held, the rwsem is taken inside this function.
  */
 static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
-			struct msqid64_ds *msqid64)
+			struct ipc64_perm *perm, int msg_qbytes)
 {
 	struct kern_ipc_perm *ipcp;
 	struct msg_queue *msq;
@@ -387,7 +387,7 @@ static int msgctl_down(struct ipc_namesp
 	rcu_read_lock();
 
 	ipcp = ipcctl_obtain_check(ns, &msg_ids(ns), msqid, cmd,
-				      &msqid64->msg_perm, msqid64->msg_qbytes);
+				      perm, msg_qbytes);
 	if (IS_ERR(ipcp)) {
 		err = PTR_ERR(ipcp);
 		goto out_unlock1;
@@ -409,18 +409,18 @@ static int msgctl_down(struct ipc_namesp
 	{
 		DEFINE_WAKE_Q(wake_q);
 
-		if (msqid64->msg_qbytes > ns->msg_ctlmnb &&
+		if (msg_qbytes > ns->msg_ctlmnb &&
 		    !capable(CAP_SYS_RESOURCE)) {
 			err = -EPERM;
 			goto out_unlock1;
 		}
 
 		ipc_lock_object(&msq->q_perm);
-		err = ipc_update_perm(&msqid64->msg_perm, ipcp);
+		err = ipc_update_perm(perm, ipcp);
 		if (err)
 			goto out_unlock0;
 
-		msq->q_qbytes = msqid64->msg_qbytes;
+		msq->q_qbytes = msg_qbytes;
 
 		msq->q_ctime = ktime_get_real_seconds();
 		/*
@@ -601,9 +601,10 @@ static long ksys_msgctl(int msqid, int c
 	case IPC_SET:
 		if (copy_msqid_from_user(&msqid64, buf, version))
 			return -EFAULT;
-		/* fallthru */
+		return msgctl_down(ns, msqid, cmd, &msqid64.msg_perm,
+				   msqid64.msg_qbytes);
 	case IPC_RMID:
-		return msgctl_down(ns, msqid, cmd, &msqid64);
+		return msgctl_down(ns, msqid, cmd, NULL, 0);
 	default:
 		return  -EINVAL;
 	}
@@ -735,9 +736,9 @@ static long compat_ksys_msgctl(int msqid
 	case IPC_SET:
 		if (copy_compat_msqid_from_user(&msqid64, uptr, version))
 			return -EFAULT;
-		/* fallthru */
+		return msgctl_down(ns, msqid, cmd, &msqid64.msg_perm, msqid64.msg_qbytes);
 	case IPC_RMID:
-		return msgctl_down(ns, msqid, cmd, &msqid64);
+		return msgctl_down(ns, msqid, cmd, NULL, 0);
 	default:
 		return -EINVAL;
 	}
author maintainer
#32 lore raw

PATCH 32/367 tracing/kprobes: Have uname use __get_str() in print_fmt

In reply to Greg Kroah-Hartman

From: Steven Rostedt (VMware) <[email protected]>

commit 20279420ae3a8ef4c5d9fedc360a2c37a1dbdf1b upstream.

Thomas Richter reported:

Quoted 8 lines

Test case 66 'Use vfs_getname probe to get syscall args filenames' is broken on s390, but works on x86. The test case fails with:

[root@m35lp76 perf]# perf test -F 66
66: Use vfs_getname probe to get syscall args filenames
:Recording open file:
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.004 MB /tmp/__perf_test.perf.data.TCdYj\

Quoted 4 lines
	 (20 samples) ]

Looking at perf.data file for vfs_getname records for the file we touched:
FAILED!
[root@m35lp76 perf]#

The root cause was the print_fmt of the kprobe event that referenced the "ustring"

Quoted 10 lines

Setting up the kprobe event using perf command:

 # ./perf probe "vfs_getname=getname_flags:72 pathname=filename:ustring"

generates this format file:
[root@m35lp76 perf]# cat /sys/kernel/debug/tracing/events/probe/\
vfs_getname/format
name: vfs_getname
ID: 1172
format:

Quoted 9 lines
    field:unsigned short common_type; offset:0; size:2; signed:0;
    field:unsigned char common_flags; offset:2; size:1; signed:0;
    field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
    field:int common_pid; offset:4; size:4; signed:1;

    field:unsigned long __probe_ip; offset:8; size:8; signed:0;
    field:__data_loc char[] pathname; offset:16; size:4; signed:1;

    print fmt: "(%lx) pathname=\"%s\"", REC->__probe_ip, REC->pathname

Instead of using "__get_str(pathname)" it referenced it directly.

---
 kernel/trace/trace_probe.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
kernel/trace/trace_probe.c +4 -2
@@ -876,7 +876,8 @@ static int __set_print_fmt(struct trace_
 	for (i = 0; i < tp->nr_args; i++) {
 		parg = tp->args + i;
 		if (parg->count) {
-			if (strcmp(parg->type->name, "string") == 0)
+			if ((strcmp(parg->type->name, "string") == 0) ||
+			    (strcmp(parg->type->name, "ustring") == 0))
 				fmt = ", __get_str(%s[%d])";
 			else
 				fmt = ", REC->%s[%d]";
@@ -884,7 +885,8 @@ static int __set_print_fmt(struct trace_
 				pos += snprintf(buf + pos, LEN_OR_ZERO,
 						fmt, parg->name, j);
 		} else {
-			if (strcmp(parg->type->name, "string") == 0)
+			if ((strcmp(parg->type->name, "string") == 0) ||
+			    (strcmp(parg->type->name, "ustring") == 0))
 				fmt = ", __get_str(%s)";
 			else
 				fmt = ", REC->%s";
author maintainer
#33 lore raw

PATCH 33/367 tracing: Fix sched switch start/stop refcount racy updates

In reply to Greg Kroah-Hartman

From: Mathieu Desnoyers <[email protected]>

commit 64ae572bc7d0060429e40e1c8d803ce5eb31a0d6 upstream.

Reading the sched_cmdline_ref and sched_tgid_ref initial state within tracing_start_sched_switch without holding the sched_register_mutex is racy against concurrent updates, which can lead to tracepoint probes being registered more than once (and thus trigger warnings within tracepoint.c).

[ May be the fix for this bug ]
CC Steven Rostedt (VMware) <[email protected]>
CC Joel Fernandes (Google) <[email protected]>
CC Peter Zijlstra <[email protected]>
CC Thomas Gleixner <[email protected]>
CC Paul E. McKenney <[email protected]>
Reported-by [email protected]
Fixes d914ba37d7145 ("tracing: Add support for recording tgid of tasks")
---
 kernel/trace/trace_sched_switch.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
kernel/trace/trace_sched_switch.c +3 -1
@@ -89,8 +89,10 @@ static void tracing_sched_unregister(voi
 
 static void tracing_start_sched_switch(int ops)
 {
-	bool sched_register = (!sched_cmdline_ref && !sched_tgid_ref);
+	bool sched_register;
+
 	mutex_lock(&sched_register_mutex);
+	sched_register = (!sched_cmdline_ref && !sched_tgid_ref);
 
 	switch (ops) {
 	case RECORD_CMDLINE:
author maintainer
#34 lore raw

PATCH 34/367 rcu: Use *_ONCE() to protect lockless ->expmask accesses

In reply to Greg Kroah-Hartman

From: Paul E. McKenney <[email protected]>

commit 15c7c972cd26d89a26788e609c53b5a465324a6c upstream.

The rcu_node structure's ->expmask field is accessed locklessly when starting a new expedited grace period and when reporting an expedited RCU CPU stall warning. This commit therefore handles the former by taking a snapshot of ->expmask while the lock is held and the latter by applying READ_ONCE() to lockless reads and WRITE_ONCE() to the corresponding updates.

---
 kernel/rcu/tree_exp.h |   19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)
kernel/rcu/tree_exp.h +9 -10
@@ -134,7 +134,7 @@ static void __maybe_unused sync_exp_rese
 	rcu_for_each_node_breadth_first(rnp) {
 		raw_spin_lock_irqsave_rcu_node(rnp, flags);
 		WARN_ON_ONCE(rnp->expmask);
-		rnp->expmask = rnp->expmaskinit;
+		WRITE_ONCE(rnp->expmask, rnp->expmaskinit);
 		raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
 	}
 }
@@ -211,7 +211,7 @@ static void __rcu_report_exp_rnp(struct
 		rnp = rnp->parent;
 		raw_spin_lock_rcu_node(rnp); /* irqs already disabled */
 		WARN_ON_ONCE(!(rnp->expmask & mask));
-		rnp->expmask &= ~mask;
+		WRITE_ONCE(rnp->expmask, rnp->expmask & ~mask);
 	}
 }
 
@@ -241,7 +241,7 @@ static void rcu_report_exp_cpu_mult(stru
 		raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
 		return;
 	}
-	rnp->expmask &= ~mask;
+	WRITE_ONCE(rnp->expmask, rnp->expmask & ~mask);
 	__rcu_report_exp_rnp(rnp, wake, flags); /* Releases rnp->lock. */
 }
 
@@ -372,12 +372,10 @@ static void sync_rcu_exp_select_node_cpu
 	raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
 
 	/* IPI the remaining CPUs for expedited quiescent state. */
-	for_each_leaf_node_cpu_mask(rnp, cpu, rnp->expmask) {
+	for_each_leaf_node_cpu_mask(rnp, cpu, mask_ofl_ipi) {
 		unsigned long mask = leaf_node_cpu_bit(rnp, cpu);
 		struct rcu_data *rdp = per_cpu_ptr(&rcu_data, cpu);
 
-		if (!(mask_ofl_ipi & mask))
-			continue;
 retry_ipi:
 		if (rcu_dynticks_in_eqs_since(rdp, rdp->exp_dynticks_snap)) {
 			mask_ofl_test |= mask;
@@ -491,7 +489,7 @@ static void synchronize_sched_expedited_
 				struct rcu_data *rdp;
 
 				mask = leaf_node_cpu_bit(rnp, cpu);
-				if (!(rnp->expmask & mask))
+				if (!(READ_ONCE(rnp->expmask) & mask))
 					continue;
 				ndetected++;
 				rdp = per_cpu_ptr(&rcu_data, cpu);
@@ -503,7 +501,8 @@ static void synchronize_sched_expedited_
 		}
 		pr_cont(" } %lu jiffies s: %lu root: %#lx/%c\n",
 			jiffies - jiffies_start, rcu_state.expedited_sequence,
-			rnp_root->expmask, ".T"[!!rnp_root->exp_tasks]);
+			READ_ONCE(rnp_root->expmask),
+			".T"[!!rnp_root->exp_tasks]);
 		if (ndetected) {
 			pr_err("blocking rcu_node structures:");
 			rcu_for_each_node_breadth_first(rnp) {
@@ -513,7 +512,7 @@ static void synchronize_sched_expedited_
 					continue;
 				pr_cont(" l=%u:%d-%d:%#lx/%c",
 					rnp->level, rnp->grplo, rnp->grphi,
-					rnp->expmask,
+					READ_ONCE(rnp->expmask),
 					".T"[!!rnp->exp_tasks]);
 			}
 			pr_cont("\n");
@@ -521,7 +520,7 @@ static void synchronize_sched_expedited_
 		rcu_for_each_leaf_node(rnp) {
 			for_each_leaf_node_possible_cpu(rnp, cpu) {
 				mask = leaf_node_cpu_bit(rnp, cpu);
-				if (!(rnp->expmask & mask))
+				if (!(READ_ONCE(rnp->expmask) & mask))
 					continue;
 				dump_cpu_task(cpu);
 			}
author maintainer
#35 lore raw

PATCH 35/367 rcu: Avoid data-race in rcu_gp_fqs_check_wake()

In reply to Greg Kroah-Hartman

From: Eric Dumazet <[email protected]>

commit 6935c3983b246d5fbfebd3b891c825e65c118f2d upstream.

The rcu_gp_fqs_check_wake() function uses rcu_preempt_blocked_readers_cgp() to read ->gp_tasks while other cpus might overwrite this field.

We need READ_ONCE()/WRITE_ONCE() pairs to avoid compiler tricks and KCSAN splats like the following :

BUG: KCSAN: data-race in rcu_gp_fqs_check_wake / rcu_preempt_deferred_qs_irqrestore

write to 0xffffffff85a7f190 of 8 bytes by task 7317 on cpu 0:

 rcu_preempt_deferred_qs_irqrestore+0x43d/0x580 kernel/rcu/tree_plugin.h:507
 rcu_read_unlock_special+0xec/0x370 kernel/rcu/tree_plugin.h:659
 __rcu_read_unlock+0xcf/0xe0 kernel/rcu/tree_plugin.h:394
 rcu_read_unlock include/linux/rcupdate.h:645 [inline]
 __ip_queue_xmit+0x3b0/0xa40 net/ipv4/ip_output.c:533
 ip_queue_xmit+0x45/0x60 include/net/ip.h:236
 __tcp_transmit_skb+0xdeb/0x1cd0 net/ipv4/tcp_output.c:1158
 __tcp_send_ack+0x246/0x300 net/ipv4/tcp_output.c:3685
 tcp_send_ack+0x34/0x40 net/ipv4/tcp_output.c:3691
 tcp_cleanup_rbuf+0x130/0x360 net/ipv4/tcp.c:1575
 tcp_recvmsg+0x633/0x1a30 net/ipv4/tcp.c:2179
 inet_recvmsg+0xbb/0x250 net/ipv4/af_inet.c:838
 sock_recvmsg_nosec net/socket.c:871 [inline]
 sock_recvmsg net/socket.c:889 [inline]
 sock_recvmsg+0x92/0xb0 net/socket.c:885
 sock_read_iter+0x15f/0x1e0 net/socket.c:967
 call_read_iter include/linux/fs.h:1864 [inline]
 new_sync_read+0x389/0x4f0 fs/read_write.c:414

read to 0xffffffff85a7f190 of 8 bytes by task 10 on cpu 1:

 rcu_gp_fqs_check_wake kernel/rcu/tree.c:1556 [inline]
 rcu_gp_fqs_check_wake+0x93/0xd0 kernel/rcu/tree.c:1546
 rcu_gp_fqs_loop+0x36c/0x580 kernel/rcu/tree.c:1611
 rcu_gp_kthread+0x143/0x220 kernel/rcu/tree.c:1768
 kthread+0x1d4/0x200 drivers/block/aoe/aoecmd.c:1253
 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:352

Reported by Kernel Concurrency Sanitizer on:

CPU: 1 PID: 10 Comm: rcu_preempt Not tainted 5.3.0+ #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
[ paulmck: Added another READ_ONCE() for RCU CPU stall warnings. ]
---
 kernel/rcu/tree_plugin.h |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
kernel/rcu/tree_plugin.h +6 -5
@@ -220,7 +220,7 @@ static void rcu_preempt_ctxt_queue(struc
 	 * blocked tasks.
 	 */
 	if (!rnp->gp_tasks && (blkd_state & RCU_GP_BLKD)) {
-		rnp->gp_tasks = &t->rcu_node_entry;
+		WRITE_ONCE(rnp->gp_tasks, &t->rcu_node_entry);
 		WARN_ON_ONCE(rnp->completedqs == rnp->gp_seq);
 	}
 	if (!rnp->exp_tasks && (blkd_state & RCU_EXP_BLKD))
@@ -340,7 +340,7 @@ EXPORT_SYMBOL_GPL(rcu_note_context_switc
  */
 static int rcu_preempt_blocked_readers_cgp(struct rcu_node *rnp)
 {
-	return rnp->gp_tasks != NULL;
+	return READ_ONCE(rnp->gp_tasks) != NULL;
 }
 
 /* Bias and limit values for ->rcu_read_lock_nesting. */
@@ -493,7 +493,7 @@ rcu_preempt_deferred_qs_irqrestore(struc
 		trace_rcu_unlock_preempted_task(TPS("rcu_preempt"),
 						rnp->gp_seq, t->pid);
 		if (&t->rcu_node_entry == rnp->gp_tasks)
-			rnp->gp_tasks = np;
+			WRITE_ONCE(rnp->gp_tasks, np);
 		if (&t->rcu_node_entry == rnp->exp_tasks)
 			rnp->exp_tasks = np;
 		if (IS_ENABLED(CONFIG_RCU_BOOST)) {
@@ -663,7 +663,7 @@ static void rcu_preempt_check_blocked_ta
 		dump_blkd_tasks(rnp, 10);
 	if (rcu_preempt_has_tasks(rnp) &&
 	    (rnp->qsmaskinit || rnp->wait_blkd_tasks)) {
-		rnp->gp_tasks = rnp->blkd_tasks.next;
+		WRITE_ONCE(rnp->gp_tasks, rnp->blkd_tasks.next);
 		t = container_of(rnp->gp_tasks, struct task_struct,
 				 rcu_node_entry);
 		trace_rcu_unlock_preempted_task(TPS("rcu_preempt-GPS"),
@@ -757,7 +757,8 @@ dump_blkd_tasks(struct rcu_node *rnp, in
 		pr_info("%s: %d:%d ->qsmask %#lx ->qsmaskinit %#lx ->qsmaskinitnext %#lx\n",
 			__func__, rnp1->grplo, rnp1->grphi, rnp1->qsmask, rnp1->qsmaskinit, rnp1->qsmaskinitnext);
 	pr_info("%s: ->gp_tasks %p ->boost_tasks %p ->exp_tasks %p\n",
-		__func__, rnp->gp_tasks, rnp->boost_tasks, rnp->exp_tasks);
+		__func__, READ_ONCE(rnp->gp_tasks), rnp->boost_tasks,
+		rnp->exp_tasks);
 	pr_info("%s: ->blkd_tasks", __func__);
 	i = 0;
 	list_for_each(lhp, &rnp->blkd_tasks) {
author maintainer
#36 lore raw

PATCH 36/367 srcu: Apply *_ONCE() to ->srcu_last_gp_end

In reply to Greg Kroah-Hartman

From: Paul E. McKenney <[email protected]>

commit 844a378de3372c923909681706d62336d702531e upstream.

The ->srcu_last_gp_end field is accessed from any CPU at any time by synchronize_srcu(), so non-initialization references need to use READ_ONCE() and WRITE_ONCE(). This commit therefore makes that change.

---
 kernel/rcu/srcutree.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
kernel/rcu/srcutree.c +4 -3
@@ -530,7 +530,7 @@ static void srcu_gp_end(struct srcu_stru
 	idx = rcu_seq_state(ssp->srcu_gp_seq);
 	WARN_ON_ONCE(idx != SRCU_STATE_SCAN2);
 	cbdelay = srcu_get_delay(ssp);
-	ssp->srcu_last_gp_end = ktime_get_mono_fast_ns();
+	WRITE_ONCE(ssp->srcu_last_gp_end, ktime_get_mono_fast_ns());
 	rcu_seq_end(&ssp->srcu_gp_seq);
 	gpseq = rcu_seq_current(&ssp->srcu_gp_seq);
 	if (ULONG_CMP_LT(ssp->srcu_gp_seq_needed_exp, gpseq))
@@ -762,6 +762,7 @@ static bool srcu_might_be_idle(struct sr
 	unsigned long flags;
 	struct srcu_data *sdp;
 	unsigned long t;
+	unsigned long tlast;
 
 	/* If the local srcu_data structure has callbacks, not idle.  */
 	local_irq_save(flags);
@@ -780,9 +781,9 @@ static bool srcu_might_be_idle(struct sr
 
 	/* First, see if enough time has passed since the last GP. */
 	t = ktime_get_mono_fast_ns();
+	tlast = READ_ONCE(ssp->srcu_last_gp_end);
 	if (exp_holdoff == 0 ||
-	    time_in_range_open(t, ssp->srcu_last_gp_end,
-			       ssp->srcu_last_gp_end + exp_holdoff))
+	    time_in_range_open(t, tlast, tlast + exp_holdoff))
 		return false; /* Too soon after last GP. */
 
 	/* Next, check for probable idleness. */
author maintainer
#37 lore raw

PATCH 37/367 rcu: Use READ_ONCE() for ->expmask in rcu_read_unlock_special()

In reply to Greg Kroah-Hartman

From: Paul E. McKenney <[email protected]>

commit c51f83c315c392d9776c33eb16a2fe1349d65c7f upstream.

The rcu_node structure's ->expmask field is updated only when holding the ->lock, but is also accessed locklessly. This means that all ->expmask updates must use WRITE_ONCE() and all reads carried out without holding ->lock must use READ_ONCE(). This commit therefore changes the lockless ->expmask read in rcu_read_unlock_special() to use READ_ONCE().

---
 kernel/rcu/tree_plugin.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/rcu/tree_plugin.h +1 -1
@@ -612,7 +612,7 @@ static void rcu_read_unlock_special(stru
 
 		t->rcu_read_unlock_special.b.exp_hint = false;
 		exp = (t->rcu_blocked_node && t->rcu_blocked_node->exp_tasks) ||
-		      (rdp->grpmask & rnp->expmask) ||
+		      (rdp->grpmask & READ_ONCE(rnp->expmask)) ||
 		      tick_nohz_full_cpu(rdp->cpu);
 		// Need to defer quiescent state until everything is enabled.
 		if (irqs_were_disabled && use_softirq &&
author maintainer
#38 lore raw

PATCH 38/367 nvmet: Fix error print message at nvmet_install_queue function

In reply to Greg Kroah-Hartman

From: Israel Rukshin <[email protected]>

commit 0b87a2b795d66be7b54779848ef0f3901c5e46fc upstream.

Place the arguments in the correct order.

Fixes 1672ddb8d691 ("nvmet: Add install_queue callout")
---
 drivers/nvme/target/fabrics-cmd.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/nvme/target/fabrics-cmd.c +1 -1
@@ -136,7 +136,7 @@ static u16 nvmet_install_queue(struct nv
 
 		if (ret) {
 			pr_err("failed to install queue %d cntlid %d ret %x\n",
-				qid, ret, ctrl->cntlid);
+				qid, ctrl->cntlid, ret);
 			return ret;
 		}
 	}
author maintainer
#39 lore raw

PATCH 39/367 nvmet: Fix controller use after free

In reply to Greg Kroah-Hartman

From: Israel Rukshin <[email protected]>

commit 1a3f540d63152b8db0a12de508bfa03776217d83 upstream.

After nvmet_install_queue() sets sq->ctrl calling to nvmet_sq_destroy() reduces the controller refcount. In case nvmet_install_queue() fails, calling to nvmet_ctrl_put() is done twice (at nvmet_sq_destroy and nvmet_execute_io_connect/nvmet_execute_admin_connect) instead of once for the queue which leads to use after free of the controller. Fix this by set NULL at sq->ctrl in case of a failure at nvmet_install_queue().

The bug leads to the following Call Trace:

[65857.994862] refcount_t: underflow; use-after-free.
[65858.108304] Workqueue: events nvmet_rdma_release_queue_work [nvmet_rdma]
[65858.115557] RIP: 0010:refcount_warn_saturate+0xe5/0xf0
[65858.208141] Call Trace:
[65858.211203]  nvmet_sq_destroy+0xe1/0xf0 [nvmet]
[65858.216383]  nvmet_rdma_release_queue_work+0x37/0xf0 [nvmet_rdma]
[65858.223117]  process_one_work+0x167/0x370
[65858.227776]  worker_thread+0x49/0x3e0
[65858.232089]  kthread+0xf5/0x130
[65858.235895]  ? max_active_store+0x80/0x80
[65858.240504]  ? kthread_bind+0x10/0x10
[65858.244832]  ret_from_fork+0x1f/0x30
[65858.249074] ---[ end trace f82d59250b54beb7 ]---
Fixes bb1cc74790eb ("nvmet: implement valid sqhd values in completions")
Fixes 1672ddb8d691 ("nvmet: Add install_queue callout")
---
 drivers/nvme/target/fabrics-cmd.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/nvme/target/fabrics-cmd.c +9 -4
@@ -109,6 +109,7 @@ static u16 nvmet_install_queue(struct nv
 	u16 qid = le16_to_cpu(c->qid);
 	u16 sqsize = le16_to_cpu(c->sqsize);
 	struct nvmet_ctrl *old;
+	u16 ret;
 
 	old = cmpxchg(&req->sq->ctrl, NULL, ctrl);
 	if (old) {
@@ -119,7 +120,8 @@ static u16 nvmet_install_queue(struct nv
 	if (!sqsize) {
 		pr_warn("queue size zero!\n");
 		req->error_loc = offsetof(struct nvmf_connect_command, sqsize);
-		return NVME_SC_CONNECT_INVALID_PARAM | NVME_SC_DNR;
+		ret = NVME_SC_CONNECT_INVALID_PARAM | NVME_SC_DNR;
+		goto err;
 	}
 
 	/* note: convert queue size from 0's-based value to 1's-based value */
@@ -132,16 +134,19 @@ static u16 nvmet_install_queue(struct nv
 	}
 
 	if (ctrl->ops->install_queue) {
-		u16 ret = ctrl->ops->install_queue(req->sq);
-
+		ret = ctrl->ops->install_queue(req->sq);
 		if (ret) {
 			pr_err("failed to install queue %d cntlid %d ret %x\n",
 				qid, ctrl->cntlid, ret);
-			return ret;
+			goto err;
 		}
 	}
 
 	return 0;
+
+err:
+	req->sq->ctrl = NULL;
+	return ret;
 }
 
 static void nvmet_execute_admin_connect(struct nvmet_req *req)
author maintainer
#40 lore raw

PATCH 40/367 Bluetooth: btusb: fix memory leak on fw

In reply to Greg Kroah-Hartman

From: Colin Ian King <[email protected]>

commit 3168c19d7eb17a0108a3b60ad8e8c1b18ea05c63 upstream.

Currently the error return path when the call to btusb_mtk_hci_wmt_sync fails does not free fw. Fix this by returning via the error_release_fw label that performs the free'ing.

Addresses-Coverity: ("Resource leak")

Fixes a1c49c434e15 ("Bluetooth: btusb: Add protocol support for MediaTek MT7668U USB devices")
---
 drivers/bluetooth/btusb.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/bluetooth/btusb.c +1 -1
@@ -2867,7 +2867,7 @@ static int btusb_mtk_setup_firmware(stru
 	err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params);
 	if (err < 0) {
 		bt_dev_err(hdev, "Failed to send wmt rst (%d)", err);
-		return err;
+		goto err_release_fw;
 	}
 
 	/* Wait a few moments for firmware activation done */
author maintainer
#41 lore raw

PATCH 41/367 Bluetooth: btusb: Disable runtime suspend on Realtek devices

In reply to Greg Kroah-Hartman

From: Kai-Heng Feng <[email protected]>

commit 7ecacafc240638148567742cca41aa7144b4fe1e upstream.

After commit 9e45524a0111 ("Bluetooth: btusb: Fix suspend issue for Realtek devices") both WiFi and Bluetooth stop working after reboot:

[   34.322617] usb 1-8: reset full-speed USB device number 3 using xhci_hcd
[   34.450401] usb 1-8: device descriptor read/64, error -71
[   34.694375] usb 1-8: device descriptor read/64, error -71
...
[   44.599111] rtw_pci 0000:02:00.0: failed to poll offset=0x5 mask=0x3 value=0x0
[   44.599113] rtw_pci 0000:02:00.0: mac power on failed
[   44.599114] rtw_pci 0000:02:00.0: failed to power on mac
[   44.599114] rtw_pci 0000:02:00.0: leave idle state failed
[   44.599492] rtw_pci 0000:02:00.0: failed to leave ips state
[   44.599493] rtw_pci 0000:02:00.0: failed to leave idle state

That commit removed USB_QUIRK_RESET_RESUME, which not only resets the USB device after resume, it also prevents the device from being runtime suspended by USB core. My experiment shows if the Realtek btusb device ever runtime suspends once, the entire wireless module becomes useless after reboot.

So let's explicitly disable runtime suspend on Realtek btusb device for now.

Fixes 9e45524a0111 ("Bluetooth: btusb: Fix suspend issue for Realtek devices")
---
 drivers/bluetooth/btusb.c |    4 ++++
 1 file changed, 4 insertions(+)
drivers/bluetooth/btusb.c +4 -0
@@ -3832,6 +3832,10 @@ static int btusb_probe(struct usb_interf
 		 * (DEVICE_REMOTE_WAKEUP)
 		 */
 		set_bit(BTUSB_WAKEUP_DISABLE, &data->flags);
+
+		err = usb_autopm_get_interface(intf);
+		if (err < 0)
+			goto out_free_dev;
 	}
 
 	if (id->driver_info & BTUSB_AMP) {
author maintainer
#42 lore raw

PATCH 42/367 brcmfmac: Fix memory leak in brcmf_usbdev_qinit

In reply to Greg Kroah-Hartman

From: Navid Emamdoost <[email protected]>

commit 4282dc057d750c6a7dd92953564b15c26b54c22c upstream.

In the implementation of brcmf_usbdev_qinit() the allocated memory for reqs is leaking if usb_alloc_urb() fails. Release reqs in the error handling path.

Fixes 71bb244ba2fd ("brcm80211: fmac: add USB support for bcm43235/6/8 chipsets")
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c |    1 +
 1 file changed, 1 insertion(+)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +1 -0
@@ -430,6 +430,7 @@ fail:
 			usb_free_urb(req->urb);
 		list_del(q->next);
 	}
+	kfree(reqs);
 	return NULL;
 
 }
author maintainer
#43 lore raw

PATCH 43/367 usb: dwc3: gadget: Check END_TRANSFER completion

In reply to Greg Kroah-Hartman

From: Thinh Nguyen <[email protected]>

commit c58d8bfc77a2c7f6ff6339b58c9fca7ae6f57e70 upstream.

While the END_TRANSFER command is sent but not completed, any request dequeue during this time will cause the driver to issue the END_TRANSFER command. The driver needs to submit the command only once to stop the controller from processing further. The controller may take more time to process the same command multiple times unnecessarily. Let's add a flag DWC3_EP_END_TRANSFER_PENDING to check for this condition.

Fixes 3aec99154db3 ("usb: dwc3: gadget: remove DWC3_EP_END_TRANSFER_PENDING")
---
 drivers/usb/dwc3/core.h   |    1 +
 drivers/usb/dwc3/ep0.c    |    4 +++-
 drivers/usb/dwc3/gadget.c |    6 +++++-
 3 files changed, 9 insertions(+), 2 deletions(-)
drivers/usb/dwc3/core.h +1 -0
@@ -688,6 +688,7 @@ struct dwc3_ep {
 #define DWC3_EP_STALL		BIT(1)
 #define DWC3_EP_WEDGE		BIT(2)
 #define DWC3_EP_TRANSFER_STARTED BIT(3)
+#define DWC3_EP_END_TRANSFER_PENDING BIT(4)
 #define DWC3_EP_PENDING_REQUEST	BIT(5)
 
 	/* This last one is specific to EP0 */
drivers/usb/dwc3/ep0.c +3 -1
@@ -1136,8 +1136,10 @@ void dwc3_ep0_interrupt(struct dwc3 *dwc
 	case DWC3_DEPEVT_EPCMDCMPLT:
 		cmd = DEPEVT_PARAMETER_CMD(event->parameters);
 
-		if (cmd == DWC3_DEPCMD_ENDTRANSFER)
+		if (cmd == DWC3_DEPCMD_ENDTRANSFER) {
+			dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
 			dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
+		}
 		break;
 	}
 }
drivers/usb/dwc3/gadget.c +5 -1
@@ -2625,6 +2625,7 @@ static void dwc3_endpoint_interrupt(stru
 		cmd = DEPEVT_PARAMETER_CMD(event->parameters);
 
 		if (cmd == DWC3_DEPCMD_ENDTRANSFER) {
+			dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
 			dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
 			dwc3_gadget_ep_cleanup_cancelled_requests(dep);
 		}
@@ -2683,7 +2684,8 @@ static void dwc3_stop_active_transfer(st
 	u32 cmd;
 	int ret;
 
-	if (!(dep->flags & DWC3_EP_TRANSFER_STARTED))
+	if (!(dep->flags & DWC3_EP_TRANSFER_STARTED) ||
+	    (dep->flags & DWC3_EP_END_TRANSFER_PENDING))
 		return;
 
 	/*
@@ -2728,6 +2730,8 @@ static void dwc3_stop_active_transfer(st
 
 	if (!interrupt)
 		dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
+	else
+		dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
 
 	if (dwc3_is_usb31(dwc) || dwc->revision < DWC3_REVISION_310A)
 		udelay(100);
author maintainer
#44 lore raw

PATCH 44/367 usb: dwc3: gadget: Delay starting transfer

In reply to Greg Kroah-Hartman

From: Thinh Nguyen <[email protected]>

commit da10bcdd6f70dc9977f2cf18f4783cf78520623a upstream.

If the END_TRANSFER command hasn't completed yet, then don't send the START_TRANSFER command. The controller may not be able to start if that's the case. Some controller revisions depend on this. See commit 76a638f8ac0d ("usb: dwc3: gadget: wait for End Transfer to complete"). Let's only send START_TRANSFER command after the END_TRANSFER command had completed.

Fixes 3aec99154db3 ("usb: dwc3: gadget: remove DWC3_EP_END_TRANSFER_PENDING")
---
 drivers/usb/dwc3/core.h   |    1 +
 drivers/usb/dwc3/gadget.c |   11 +++++++++++
 2 files changed, 12 insertions(+)
drivers/usb/dwc3/core.h +1 -0
@@ -690,6 +690,7 @@ struct dwc3_ep {
 #define DWC3_EP_TRANSFER_STARTED BIT(3)
 #define DWC3_EP_END_TRANSFER_PENDING BIT(4)
 #define DWC3_EP_PENDING_REQUEST	BIT(5)
+#define DWC3_EP_DELAY_START	BIT(6)
 
 	/* This last one is specific to EP0 */
 #define DWC3_EP0_DIR_IN		BIT(31)
drivers/usb/dwc3/gadget.c +11 -0
@@ -1447,6 +1447,12 @@ static int __dwc3_gadget_ep_queue(struct
 	list_add_tail(&req->list, &dep->pending_list);
 	req->status = DWC3_REQUEST_STATUS_QUEUED;
 
+	/* Start the transfer only after the END_TRANSFER is completed */
+	if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) {
+		dep->flags |= DWC3_EP_DELAY_START;
+		return 0;
+	}
+
 	/*
 	 * NOTICE: Isochronous endpoints should NEVER be prestarted. We must
 	 * wait for a XferNotReady event so we will know what's the current
@@ -2628,6 +2634,11 @@ static void dwc3_endpoint_interrupt(stru
 			dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
 			dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
 			dwc3_gadget_ep_cleanup_cancelled_requests(dep);
+			if ((dep->flags & DWC3_EP_DELAY_START) &&
+			    !usb_endpoint_xfer_isoc(dep->endpoint.desc))
+				__dwc3_gadget_kick_transfer(dep);
+
+			dep->flags &= ~DWC3_EP_DELAY_START;
 		}
 		break;
 	case DWC3_DEPEVT_STREAMEVT:
author maintainer
#45 lore raw

PATCH 45/367 usb: typec: tcpci: mask event interrupts when remove driver

In reply to Greg Kroah-Hartman

From: Jun Li <[email protected]>

commit 3ba76256fc4e2a0d7fb26cc95459041ea0e88972 upstream.

This is to prevent any possible events generated while unregister tpcm port.

Fixes 74e656d6b055 ("staging: typec: Type-C Port Controller Interface driver (tcpci)")
---
 drivers/usb/typec/tcpm/tcpci.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/usb/typec/tcpm/tcpci.c +6 -0
@@ -591,6 +591,12 @@ static int tcpci_probe(struct i2c_client
 static int tcpci_remove(struct i2c_client *client)
 {
 	struct tcpci_chip *chip = i2c_get_clientdata(client);
+	int err;
+
+	/* Disable chip interrupts before unregistering port */
+	err = tcpci_write16(chip->tcpci, TCPC_ALERT_MASK, 0);
+	if (err < 0)
+		return err;
 
 	tcpci_unregister_port(chip->tcpci);
 
author maintainer
#46 lore raw

PATCH 46/367 objtool: Silence build output

In reply to Greg Kroah-Hartman

From: Olof Johansson <[email protected]>

commit 6ec14aa7a58a1c2fb303692f8cb1ff82d9abd10a upstream.

The sync-check.sh script prints out the path due to a "cd -" at the end of the script, even on silent builds. This isn't even needed, since the script is executed in our build instead of sourced (so it won't change the working directory of the surrounding build anyway).

Just remove the cd to make the build silent.

---
 tools/objtool/sync-check.sh |    2 --
 1 file changed, 2 deletions(-)
tools/objtool/sync-check.sh +0 -2
@@ -48,5 +48,3 @@ check arch/x86/include/asm/inat.h     '-
 check arch/x86/include/asm/insn.h     '-I "^#include [\"<]\(asm/\)*inat.h[\">]"'
 check arch/x86/lib/inat.c             '-I "^#include [\"<]\(../include/\)*asm/insn.h[\">]"'
 check arch/x86/lib/insn.c             '-I "^#include [\"<]\(../include/\)*asm/in\(at\|sn\).h[\">]" -I "^#include [\"<]\(../include/\)*asm/emulate_prefix.h[\">]"'
-
-cd -
author maintainer
#47 lore raw

PATCH 47/367 usb: gadget: f_fs: set req->num_sgs as 0 for non-sg transfer

In reply to Greg Kroah-Hartman

From: Peter Chen <[email protected]>

commit d2450c6937018d40d4111fe830fa48d4ddceb8d0 upstream.

The UDC core uses req->num_sgs to judge if scatter buffer list is used.
Eg: usb_gadget_map_request_by_dev. For f_fs sync io mode, the request is re-used for each request, so if the 1st request->length > PAGE_SIZE, and the 2nd request->length is <= PAGE_SIZE, the f_fs uses the 1st req->num_sgs for the 2nd request, it causes the UDC core get the wrong req->num_sgs value (The 2nd request doesn't use sg). For f_fs async io mode, it is not harm to initialize req->num_sgs as 0 either, in case, the UDC driver doesn't zeroed request structure.

Cc Jun Li <[email protected]>
Cc stable <[email protected]>
Fixes 772a7a724f69 ("usb: gadget: f_fs: Allow scatter-gather buffers")
---
 drivers/usb/gadget/function/f_fs.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/usb/gadget/function/f_fs.c +2 -0
@@ -1062,6 +1062,7 @@ static ssize_t ffs_epfile_io(struct file
 			req->num_sgs = io_data->sgt.nents;
 		} else {
 			req->buf = data;
+			req->num_sgs = 0;
 		}
 		req->length = data_len;
 
@@ -1105,6 +1106,7 @@ static ssize_t ffs_epfile_io(struct file
 			req->num_sgs = io_data->sgt.nents;
 		} else {
 			req->buf = data;
+			req->num_sgs = 0;
 		}
 		req->length = data_len;
 
author maintainer
#48 lore raw

PATCH 48/367 usb: gadget: legacy: set max_speed to super-speed

In reply to Greg Kroah-Hartman

From: Roger Quadros <[email protected]>

commit 463f67aec2837f981b0a0ce8617721ff59685c00 upstream.

These interfaces do support super-speed so let's not limit maximum speed to high-speed.

---
 drivers/usb/gadget/legacy/cdc2.c  |    2 +-
 drivers/usb/gadget/legacy/g_ffs.c |    2 +-
 drivers/usb/gadget/legacy/multi.c |    2 +-
 drivers/usb/gadget/legacy/ncm.c   |    2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)
drivers/usb/gadget/legacy/cdc2.c +1 -1
@@ -225,7 +225,7 @@ static struct usb_composite_driver cdc_d
 	.name		= "g_cdc",
 	.dev		= &device_desc,
 	.strings	= dev_strings,
-	.max_speed	= USB_SPEED_HIGH,
+	.max_speed	= USB_SPEED_SUPER,
 	.bind		= cdc_bind,
 	.unbind		= cdc_unbind,
 };
drivers/usb/gadget/legacy/g_ffs.c +1 -1
@@ -149,7 +149,7 @@ static struct usb_composite_driver gfs_d
 	.name		= DRIVER_NAME,
 	.dev		= &gfs_dev_desc,
 	.strings	= gfs_dev_strings,
-	.max_speed	= USB_SPEED_HIGH,
+	.max_speed	= USB_SPEED_SUPER,
 	.bind		= gfs_bind,
 	.unbind		= gfs_unbind,
 };
drivers/usb/gadget/legacy/multi.c +1 -1
@@ -482,7 +482,7 @@ static struct usb_composite_driver multi
 	.name		= "g_multi",
 	.dev		= &device_desc,
 	.strings	= dev_strings,
-	.max_speed	= USB_SPEED_HIGH,
+	.max_speed	= USB_SPEED_SUPER,
 	.bind		= multi_bind,
 	.unbind		= multi_unbind,
 	.needs_serial	= 1,
drivers/usb/gadget/legacy/ncm.c +1 -1
@@ -197,7 +197,7 @@ static struct usb_composite_driver ncm_d
 	.name		= "g_ncm",
 	.dev		= &device_desc,
 	.strings	= dev_strings,
-	.max_speed	= USB_SPEED_HIGH,
+	.max_speed	= USB_SPEED_SUPER,
 	.bind		= gncm_bind,
 	.unbind		= gncm_unbind,
 };
author maintainer
#49 lore raw

PATCH 49/367 usb: gadget: f_ncm: Use atomic_t to track in-flight request

In reply to Greg Kroah-Hartman

From: Bryan O'Donoghue <[email protected]>

commit 5b24c28cfe136597dc3913e1c00b119307a20c7e upstream.

Currently ncm->notify_req is used to flag when a request is in-flight. ncm->notify_req is set to NULL and when a request completes it is subsequently reset.

This is fundamentally buggy in that the unbind logic of the NCM driver will unconditionally free ncm->notify_req leading to a NULL pointer dereference.

Fixes 40d133d7f542 ("usb: gadget: f_ncm: convert to new function interface with backward compatibility")
Cc stable <[email protected]>
---
 drivers/usb/gadget/function/f_ncm.c |   17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
drivers/usb/gadget/function/f_ncm.c +13 -4
@@ -53,6 +53,7 @@ struct f_ncm {
 	struct usb_ep			*notify;
 	struct usb_request		*notify_req;
 	u8				notify_state;
+	atomic_t			notify_count;
 	bool				is_open;
 
 	const struct ndp_parser_opts	*parser_opts;
@@ -547,7 +548,7 @@ static void ncm_do_notify(struct f_ncm *
 	int				status;
 
 	/* notification already in flight? */
-	if (!req)
+	if (atomic_read(&ncm->notify_count))
 		return;
 
 	event = req->buf;
@@ -587,7 +588,8 @@ static void ncm_do_notify(struct f_ncm *
 	event->bmRequestType = 0xA1;
 	event->wIndex = cpu_to_le16(ncm->ctrl_id);
 
-	ncm->notify_req = NULL;
+	atomic_inc(&ncm->notify_count);
+
 	/*
 	 * In double buffering if there is a space in FIFO,
 	 * completion callback can be called right after the call,
@@ -597,7 +599,7 @@ static void ncm_do_notify(struct f_ncm *
 	status = usb_ep_queue(ncm->notify, req, GFP_ATOMIC);
 	spin_lock(&ncm->lock);
 	if (status < 0) {
-		ncm->notify_req = req;
+		atomic_dec(&ncm->notify_count);
 		DBG(cdev, "notify --> %d\n", status);
 	}
 }
@@ -632,17 +634,19 @@ static void ncm_notify_complete(struct u
 	case 0:
 		VDBG(cdev, "Notification %02x sent\n",
 		     event->bNotificationType);
+		atomic_dec(&ncm->notify_count);
 		break;
 	case -ECONNRESET:
 	case -ESHUTDOWN:
+		atomic_set(&ncm->notify_count, 0);
 		ncm->notify_state = NCM_NOTIFY_NONE;
 		break;
 	default:
 		DBG(cdev, "event %02x --> %d\n",
 			event->bNotificationType, req->status);
+		atomic_dec(&ncm->notify_count);
 		break;
 	}
-	ncm->notify_req = req;
 	ncm_do_notify(ncm);
 	spin_unlock(&ncm->lock);
 }
@@ -1649,6 +1653,11 @@ static void ncm_unbind(struct usb_config
 	ncm_string_defs[0].id = 0;
 	usb_free_all_descriptors(f);
 
+	if (atomic_read(&ncm->notify_count)) {
+		usb_ep_dequeue(ncm->notify, ncm->notify_req);
+		atomic_set(&ncm->notify_count, 0);
+	}
+
 	kfree(ncm->notify_req->buf);
 	usb_ep_free_request(ncm->notify, ncm->notify_req);
 }
author maintainer
#50 lore raw

PATCH 50/367 usb: gadget: f_ecm: Use atomic_t to track in-flight request

In reply to Greg Kroah-Hartman

From: Bryan O'Donoghue <[email protected]>

commit d710562e01c48d59be3f60d58b7a85958b39aeda upstream.

Currently ecm->notify_req is used to flag when a request is in-flight. ecm->notify_req is set to NULL and when a request completes it is subsequently reset.

This is fundamentally buggy in that the unbind logic of the ECM driver will unconditionally free ecm->notify_req leading to a NULL pointer dereference.

Fixes da741b8c56d6 ("usb ethernet gadget: split CDC Ethernet function")
Cc stable <[email protected]>
---
 drivers/usb/gadget/function/f_ecm.c |   16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)
drivers/usb/gadget/function/f_ecm.c +12 -4
@@ -52,6 +52,7 @@ struct f_ecm {
 	struct usb_ep			*notify;
 	struct usb_request		*notify_req;
 	u8				notify_state;
+	atomic_t			notify_count;
 	bool				is_open;
 
 	/* FIXME is_open needs some irq-ish locking
@@ -380,7 +381,7 @@ static void ecm_do_notify(struct f_ecm *
 	int				status;
 
 	/* notification already in flight? */
-	if (!req)
+	if (atomic_read(&ecm->notify_count))
 		return;
 
 	event = req->buf;
@@ -420,10 +421,10 @@ static void ecm_do_notify(struct f_ecm *
 	event->bmRequestType = 0xA1;
 	event->wIndex = cpu_to_le16(ecm->ctrl_id);
 
-	ecm->notify_req = NULL;
+	atomic_inc(&ecm->notify_count);
 	status = usb_ep_queue(ecm->notify, req, GFP_ATOMIC);
 	if (status < 0) {
-		ecm->notify_req = req;
+		atomic_dec(&ecm->notify_count);
 		DBG(cdev, "notify --> %d\n", status);
 	}
 }
@@ -448,17 +449,19 @@ static void ecm_notify_complete(struct u
 	switch (req->status) {
 	case 0:
 		/* no fault */
+		atomic_dec(&ecm->notify_count);
 		break;
 	case -ECONNRESET:
 	case -ESHUTDOWN:
+		atomic_set(&ecm->notify_count, 0);
 		ecm->notify_state = ECM_NOTIFY_NONE;
 		break;
 	default:
 		DBG(cdev, "event %02x --> %d\n",
 			event->bNotificationType, req->status);
+		atomic_dec(&ecm->notify_count);
 		break;
 	}
-	ecm->notify_req = req;
 	ecm_do_notify(ecm);
 }
 
@@ -907,6 +910,11 @@ static void ecm_unbind(struct usb_config
 
 	usb_free_all_descriptors(f);
 
+	if (atomic_read(&ecm->notify_count)) {
+		usb_ep_dequeue(ecm->notify, ecm->notify_req);
+		atomic_set(&ecm->notify_count, 0);
+	}
+
 	kfree(ecm->notify_req->buf);
 	usb_ep_free_request(ecm->notify, ecm->notify_req);
 }
author maintainer
#51 lore raw

PATCH 51/367 ALSA: usb-audio: Fix endianess in descriptor validation

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit f8e5f90b3a53bb75f05124ed19156388379a337d upstream.

I overlooked that some fields are words and need the converts from LE in the recently added USB descriptor validation code. This patch fixes those with the proper macro usages.

Fixes 57f8770620e9 ("ALSA: usb-audio: More validations of descriptor units")
---
 sound/usb/validate.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
sound/usb/validate.c +3 -3
@@ -110,7 +110,7 @@ static bool validate_processing_unit(con
 	default:
 		if (v->type == UAC1_EXTENSION_UNIT)
 			return true; /* OK */
-		switch (d->wProcessType) {
+		switch (le16_to_cpu(d->wProcessType)) {
 		case UAC_PROCESS_UP_DOWNMIX:
 		case UAC_PROCESS_DOLBY_PROLOGIC:
 			if (d->bLength < len + 1) /* bNrModes */
@@ -125,7 +125,7 @@ static bool validate_processing_unit(con
 	case UAC_VERSION_2:
 		if (v->type == UAC2_EXTENSION_UNIT_V2)
 			return true; /* OK */
-		switch (d->wProcessType) {
+		switch (le16_to_cpu(d->wProcessType)) {
 		case UAC2_PROCESS_UP_DOWNMIX:
 		case UAC2_PROCESS_DOLBY_PROLOCIC: /* SiC! */
 			if (d->bLength < len + 1) /* bNrModes */
@@ -142,7 +142,7 @@ static bool validate_processing_unit(con
 			len += 2; /* wClusterDescrID */
 			break;
 		}
-		switch (d->wProcessType) {
+		switch (le16_to_cpu(d->wProcessType)) {
 		case UAC3_PROCESS_UP_DOWNMIX:
 			if (d->bLength < len + 1) /* bNrModes */
 				return false;
author maintainer
#52 lore raw

PATCH 52/367 ALSA: usb-audio: Annotate endianess in Scarlett gen2 quirk

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit d8f489355cff55b30731354317739a00cf1238bd upstream.

The Scarlett gen2 mixer quirk code defines a few record types to communicate via USB hub, and those must be all little-endian. This patch changes the field types to LE to annotate endianess properly. It also fixes the incorrect usage of leXX_to_cpu() in a couple of places, which was caught by sparse after this change.

Fixes 9e4d5c1be21f ("ALSA: usb-audio: Scarlett Gen 2 mixer interface")
---
 sound/usb/mixer_scarlett_gen2.c |   46 ++++++++++++++++++++--------------------
 1 file changed, 23 insertions(+), 23 deletions(-)
sound/usb/mixer_scarlett_gen2.c +23 -23
@@ -558,11 +558,11 @@ static const struct scarlett2_config
 
 /* proprietary request/response format */
 struct scarlett2_usb_packet {
-	u32 cmd;
-	u16 size;
-	u16 seq;
-	u32 error;
-	u32 pad;
+	__le32 cmd;
+	__le16 size;
+	__le16 seq;
+	__le32 error;
+	__le32 pad;
 	u8 data[];
 };
 
@@ -664,11 +664,11 @@ static int scarlett2_usb(
 			"Scarlett Gen 2 USB invalid response; "
 			   "cmd tx/rx %d/%d seq %d/%d size %d/%d "
 			   "error %d pad %d\n",
-			le16_to_cpu(req->cmd), le16_to_cpu(resp->cmd),
+			le32_to_cpu(req->cmd), le32_to_cpu(resp->cmd),
 			le16_to_cpu(req->seq), le16_to_cpu(resp->seq),
 			resp_size, le16_to_cpu(resp->size),
-			le16_to_cpu(resp->error),
-			le16_to_cpu(resp->pad));
+			le32_to_cpu(resp->error),
+			le32_to_cpu(resp->pad));
 		err = -EINVAL;
 		goto unlock;
 	}
@@ -687,7 +687,7 @@ error:
 /* Send SCARLETT2_USB_DATA_CMD SCARLETT2_USB_CONFIG_SAVE */
 static void scarlett2_config_save(struct usb_mixer_interface *mixer)
 {
-	u32 req = cpu_to_le32(SCARLETT2_USB_CONFIG_SAVE);
+	__le32 req = cpu_to_le32(SCARLETT2_USB_CONFIG_SAVE);
 
 	scarlett2_usb(mixer, SCARLETT2_USB_DATA_CMD,
 		      &req, sizeof(u32),
@@ -713,11 +713,11 @@ static int scarlett2_usb_set_config(
 	const struct scarlett2_config config_item =
 	       scarlett2_config_items[config_item_num];
 	struct {
-		u32 offset;
-		u32 bytes;
-		s32 value;
+		__le32 offset;
+		__le32 bytes;
+		__le32 value;
 	} __packed req;
-	u32 req2;
+	__le32 req2;
 	int err;
 	struct scarlett2_mixer_data *private = mixer->private_data;
 
@@ -753,8 +753,8 @@ static int scarlett2_usb_get(
 	int offset, void *buf, int size)
 {
 	struct {
-		u32 offset;
-		u32 size;
+		__le32 offset;
+		__le32 size;
 	} __packed req;
 
 	req.offset = cpu_to_le32(offset);
@@ -794,8 +794,8 @@ static int scarlett2_usb_set_mix(struct
 	const struct scarlett2_device_info *info = private->info;
 
 	struct {
-		u16 mix_num;
-		u16 data[SCARLETT2_INPUT_MIX_MAX];
+		__le16 mix_num;
+		__le16 data[SCARLETT2_INPUT_MIX_MAX];
 	} __packed req;
 
 	int i, j;
@@ -850,9 +850,9 @@ static int scarlett2_usb_set_mux(struct
 	};
 
 	struct {
-		u16 pad;
-		u16 num;
-		u32 data[SCARLETT2_MUX_MAX];
+		__le16 pad;
+		__le16 num;
+		__le32 data[SCARLETT2_MUX_MAX];
 	} __packed req;
 
 	req.pad = 0;
@@ -911,9 +911,9 @@ static int scarlett2_usb_get_meter_level
 					  u16 *levels)
 {
 	struct {
-		u16 pad;
-		u16 num_meters;
-		u32 magic;
+		__le16 pad;
+		__le16 num_meters;
+		__le32 magic;
 	} __packed req;
 	u32 resp[SCARLETT2_NUM_METERS];
 	int i, err;
author maintainer
#53 lore raw

PATCH 53/367 ALSA: dummy: Fix PCM format loop in proc output

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 2acf25f13ebe8beb40e97a1bbe76f36277c64f1e upstream.

The loop termination for iterating over all formats should contain SNDRV_PCM_FORMAT_LAST, not less than it.

---
 sound/drivers/dummy.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/drivers/dummy.c +1 -1
@@ -915,7 +915,7 @@ static void print_formats(struct snd_dum
 {
 	int i;
 
-	for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {
+	for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
 		if (dummy->pcm_hw.formats & (1ULL << i))
 			snd_iprintf(buffer, " %s", snd_pcm_format_name(i));
 	}
author maintainer
#54 lore raw

PATCH 54/367 memcg: fix a crash in wb_workfn when a device disappears

In reply to Greg Kroah-Hartman

From: Theodore Ts'o <[email protected]>

commit 68f23b89067fdf187763e75a56087550624fdbee upstream.

Without memcg, there is a one-to-one mapping between the bdi and bdi_writeback structures. In this world, things are fairly straightforward; the first thing bdi_unregister() does is to shutdown the bdi_writeback structure (or wb), and part of that writeback ensures that no other work queued against the wb, and that the wb is fully drained.

With memcg, however, there is a one-to-many relationship between the bdi and bdi_writeback structures; that is, there are multiple wb objects which can all point to a single bdi. There is a refcount which prevents the bdi object from being released (and hence, unregistered). So in theory, the bdi_unregister() *should* only get called once its refcount goes to zero (bdi_put will drop the refcount, and when it is zero, release_bdi gets called, which calls bdi_unregister).

Unfortunately, del_gendisk() in block/gen_hd.c never got the memo about the Brave New memcg World, and calls bdi_unregister directly. It does this without informing the file system, or the memcg code, or anything else. This causes the root wb associated with the bdi to be unregistered, but none of the memcg-specific wb's are shutdown. So when one of these wb's are woken up to do delayed work, they try to dereference their wb->bdi->dev to fetch the device name, but unfortunately bdi->dev is now NULL, thanks to the bdi_unregister() called by del_gendisk(). As a result, *boom*.

Fortunately, it looks like the rest of the writeback path is perfectly happy with bdi->dev and bdi->owner being NULL, so the simplest fix is to create a bdi_dev_name() function which can handle bdi->dev being NULL. This also allows us to bulletproof the writeback tracepoints to prevent them from dereferencing a NULL pointer and crashing the kernel if one is tracing with memcg's enabled, and an iSCSI device dies or a USB storage stick is pulled.

The most common way of triggering this will be hotremoval of a device while writeback with memcg enabled is going on. It was triggering several times a day in a heavily loaded production environment.

Google Bug Id: 145475544

---
 fs/fs-writeback.c                |    2 +-
 include/linux/backing-dev.h      |   10 ++++++++++
 include/trace/events/writeback.h |   37 +++++++++++++++++--------------------
 mm/backing-dev.c                 |    1 +
 4 files changed, 29 insertions(+), 21 deletions(-)
fs/fs-writeback.c +1 -1
@@ -2063,7 +2063,7 @@ void wb_workfn(struct work_struct *work)
 						struct bdi_writeback, dwork);
 	long pages_written;
 
-	set_worker_desc("flush-%s", dev_name(wb->bdi->dev));
+	set_worker_desc("flush-%s", bdi_dev_name(wb->bdi));
 	current->flags |= PF_SWAPWRITE;
 
 	if (likely(!current_is_workqueue_rescuer() ||
include/linux/backing-dev.h +10 -0
@@ -13,6 +13,7 @@
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/blkdev.h>
+#include <linux/device.h>
 #include <linux/writeback.h>
 #include <linux/blk-cgroup.h>
 #include <linux/backing-dev-defs.h>
@@ -504,4 +505,13 @@ static inline int bdi_rw_congested(struc
 				  (1 << WB_async_congested));
 }
 
+extern const char *bdi_unknown_name;
+
+static inline const char *bdi_dev_name(struct backing_dev_info *bdi)
+{
+	if (!bdi || !bdi->dev)
+		return bdi_unknown_name;
+	return dev_name(bdi->dev);
+}
+
 #endif	/* _LINUX_BACKING_DEV_H */
include/trace/events/writeback.h +17 -20
@@ -67,8 +67,8 @@ DECLARE_EVENT_CLASS(writeback_page_templ
 
 	TP_fast_assign(
 		strscpy_pad(__entry->name,
-			    mapping ? dev_name(inode_to_bdi(mapping->host)->dev) : "(unknown)",
-			    32);
+			    bdi_dev_name(mapping ? inode_to_bdi(mapping->host) :
+					 NULL), 32);
 		__entry->ino = mapping ? mapping->host->i_ino : 0;
 		__entry->index = page->index;
 	),
@@ -111,8 +111,7 @@ DECLARE_EVENT_CLASS(writeback_dirty_inod
 		struct backing_dev_info *bdi = inode_to_bdi(inode);
 
 		/* may be called for files on pseudo FSes w/ unregistered bdi */
-		strscpy_pad(__entry->name,
-			    bdi->dev ? dev_name(bdi->dev) : "(unknown)", 32);
+		strscpy_pad(__entry->name, bdi_dev_name(bdi), 32);
 		__entry->ino		= inode->i_ino;
 		__entry->state		= inode->i_state;
 		__entry->flags		= flags;
@@ -193,7 +192,7 @@ TRACE_EVENT(inode_foreign_history,
 	),
 
 	TP_fast_assign(
-		strncpy(__entry->name, dev_name(inode_to_bdi(inode)->dev), 32);
+		strncpy(__entry->name, bdi_dev_name(inode_to_bdi(inode)), 32);
 		__entry->ino		= inode->i_ino;
 		__entry->cgroup_ino	= __trace_wbc_assign_cgroup(wbc);
 		__entry->history	= history;
@@ -222,7 +221,7 @@ TRACE_EVENT(inode_switch_wbs,
 	),
 
 	TP_fast_assign(
-		strncpy(__entry->name,	dev_name(old_wb->bdi->dev), 32);
+		strncpy(__entry->name,	bdi_dev_name(old_wb->bdi), 32);
 		__entry->ino		= inode->i_ino;
 		__entry->old_cgroup_ino	= __trace_wb_assign_cgroup(old_wb);
 		__entry->new_cgroup_ino	= __trace_wb_assign_cgroup(new_wb);
@@ -255,7 +254,7 @@ TRACE_EVENT(track_foreign_dirty,
 		struct address_space *mapping = page_mapping(page);
 		struct inode *inode = mapping ? mapping->host : NULL;
 
-		strncpy(__entry->name,	dev_name(wb->bdi->dev), 32);
+		strncpy(__entry->name,	bdi_dev_name(wb->bdi), 32);
 		__entry->bdi_id		= wb->bdi->id;
 		__entry->ino		= inode ? inode->i_ino : 0;
 		__entry->memcg_id	= wb->memcg_css->id;
@@ -288,7 +287,7 @@ TRACE_EVENT(flush_foreign,
 	),
 
 	TP_fast_assign(
-		strncpy(__entry->name,	dev_name(wb->bdi->dev), 32);
+		strncpy(__entry->name,	bdi_dev_name(wb->bdi), 32);
 		__entry->cgroup_ino	= __trace_wb_assign_cgroup(wb);
 		__entry->frn_bdi_id	= frn_bdi_id;
 		__entry->frn_memcg_id	= frn_memcg_id;
@@ -318,7 +317,7 @@ DECLARE_EVENT_CLASS(writeback_write_inod
 
 	TP_fast_assign(
 		strscpy_pad(__entry->name,
-			    dev_name(inode_to_bdi(inode)->dev), 32);
+			    bdi_dev_name(inode_to_bdi(inode)), 32);
 		__entry->ino		= inode->i_ino;
 		__entry->sync_mode	= wbc->sync_mode;
 		__entry->cgroup_ino	= __trace_wbc_assign_cgroup(wbc);
@@ -361,9 +360,7 @@ DECLARE_EVENT_CLASS(writeback_work_class
 		__field(ino_t, cgroup_ino)
 	),
 	TP_fast_assign(
-		strscpy_pad(__entry->name,
-			    wb->bdi->dev ? dev_name(wb->bdi->dev) :
-			    "(unknown)", 32);
+		strscpy_pad(__entry->name, bdi_dev_name(wb->bdi), 32);
 		__entry->nr_pages = work->nr_pages;
 		__entry->sb_dev = work->sb ? work->sb->s_dev : 0;
 		__entry->sync_mode = work->sync_mode;
@@ -416,7 +413,7 @@ DECLARE_EVENT_CLASS(writeback_class,
 		__field(ino_t, cgroup_ino)
 	),
 	TP_fast_assign(
-		strscpy_pad(__entry->name, dev_name(wb->bdi->dev), 32);
+		strscpy_pad(__entry->name, bdi_dev_name(wb->bdi), 32);
 		__entry->cgroup_ino = __trace_wb_assign_cgroup(wb);
 	),
 	TP_printk("bdi %s: cgroup_ino=%lu",
@@ -438,7 +435,7 @@ TRACE_EVENT(writeback_bdi_register,
 		__array(char, name, 32)
 	),
 	TP_fast_assign(
-		strscpy_pad(__entry->name, dev_name(bdi->dev), 32);
+		strscpy_pad(__entry->name, bdi_dev_name(bdi), 32);
 	),
 	TP_printk("bdi %s",
 		__entry->name
@@ -463,7 +460,7 @@ DECLARE_EVENT_CLASS(wbc_class,
 	),
 
 	TP_fast_assign(
-		strscpy_pad(__entry->name, dev_name(bdi->dev), 32);
+		strscpy_pad(__entry->name, bdi_dev_name(bdi), 32);
 		__entry->nr_to_write	= wbc->nr_to_write;
 		__entry->pages_skipped	= wbc->pages_skipped;
 		__entry->sync_mode	= wbc->sync_mode;
@@ -514,7 +511,7 @@ TRACE_EVENT(writeback_queue_io,
 	),
 	TP_fast_assign(
 		unsigned long *older_than_this = work->older_than_this;
-		strscpy_pad(__entry->name, dev_name(wb->bdi->dev), 32);
+		strscpy_pad(__entry->name, bdi_dev_name(wb->bdi), 32);
 		__entry->older	= older_than_this ?  *older_than_this : 0;
 		__entry->age	= older_than_this ?
 				  (jiffies - *older_than_this) * 1000 / HZ : -1;
@@ -600,7 +597,7 @@ TRACE_EVENT(bdi_dirty_ratelimit,
 	),
 
 	TP_fast_assign(
-		strscpy_pad(__entry->bdi, dev_name(wb->bdi->dev), 32);
+		strscpy_pad(__entry->bdi, bdi_dev_name(wb->bdi), 32);
 		__entry->write_bw	= KBps(wb->write_bandwidth);
 		__entry->avg_write_bw	= KBps(wb->avg_write_bandwidth);
 		__entry->dirty_rate	= KBps(dirty_rate);
@@ -665,7 +662,7 @@ TRACE_EVENT(balance_dirty_pages,
 
 	TP_fast_assign(
 		unsigned long freerun = (thresh + bg_thresh) / 2;
-		strscpy_pad(__entry->bdi, dev_name(wb->bdi->dev), 32);
+		strscpy_pad(__entry->bdi, bdi_dev_name(wb->bdi), 32);
 
 		__entry->limit		= global_wb_domain.dirty_limit;
 		__entry->setpoint	= (global_wb_domain.dirty_limit +
@@ -726,7 +723,7 @@ TRACE_EVENT(writeback_sb_inodes_requeue,
 
 	TP_fast_assign(
 		strscpy_pad(__entry->name,
-			    dev_name(inode_to_bdi(inode)->dev), 32);
+			    bdi_dev_name(inode_to_bdi(inode)), 32);
 		__entry->ino		= inode->i_ino;
 		__entry->state		= inode->i_state;
 		__entry->dirtied_when	= inode->dirtied_when;
@@ -800,7 +797,7 @@ DECLARE_EVENT_CLASS(writeback_single_ino
 
 	TP_fast_assign(
 		strscpy_pad(__entry->name,
-			    dev_name(inode_to_bdi(inode)->dev), 32);
+			    bdi_dev_name(inode_to_bdi(inode)), 32);
 		__entry->ino		= inode->i_ino;
 		__entry->state		= inode->i_state;
 		__entry->dirtied_when	= inode->dirtied_when;
mm/backing-dev.c +1 -0
@@ -21,6 +21,7 @@ struct backing_dev_info noop_backing_dev
 EXPORT_SYMBOL_GPL(noop_backing_dev_info);
 
 static struct class *bdi_class;
+const char *bdi_unknown_name = "(unknown)";
 
 /*
  * bdi_lock protects bdi_tree and updates to bdi_list. bdi_list has RCU
author maintainer
#55 lore raw

PATCH 55/367 mm/sparse.c: reset sections mem_map when fully deactivated

In reply to Greg Kroah-Hartman

From: Pingfan Liu <[email protected]>

commit 1f503443e7df8dc8366608b4d810ce2d6669827c upstream.

After commit ba72b4c8cf60 ("mm/sparsemem: support sub-section hotplug"), when a mem section is fully deactivated, section_mem_map still records the section's start pfn, which is not used any more and will be reassigned during re-addition.

In analogy with alloc/free pattern, it is better to clear all fields of section_mem_map.

Beside this, it breaks the user space tool "makedumpfile" [1], which makes assumption that a hot-removed section has mem_map as NULL, instead of checking directly against SECTION_MARKED_PRESENT bit. (makedumpfile will be better to change the assumption, and need a patch)

The bug can be reproduced on IBM POWERVM by "drmgr -c mem -r -q 5" , trigger a crash, and save vmcore by makedumpfile

[1]: makedumpfile, commit e73016540293 ("[v1.6.7] Update version")

---
 mm/sparse.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
mm/sparse.c +1 -1
@@ -789,7 +789,7 @@ static void section_deactivate(unsigned
 			ms->usage = NULL;
 		}
 		memmap = sparse_decode_mem_map(ms->section_mem_map, section_nr);
-		ms->section_mem_map = sparse_encode_mem_map(NULL, section_nr);
+		ms->section_mem_map = (unsigned long)NULL;
 	}
 
 	if (section_is_early && memmap)
author maintainer
#56 lore raw

PATCH 56/367 utimes: Clamp the timestamps in notify_change()

In reply to Greg Kroah-Hartman

From: Amir Goldstein <[email protected]>

commit eb31e2f63d85d1bec4f7b136f317e03c03db5503 upstream.

Push clamping timestamps into notify_change(), so in-kernel callers like nfsd and overlayfs will get similar timestamp set behavior as utimes.

AV: get rid of clamping in ->setattr() instances; we don't need to bother with that there, with notify_change() doing normalization in all cases now (it already did for implicit case, since current_time() clamps).

Fixes 42e729b9ddbb ("utimes: Clamp the timestamps before update")
Cc Deepa Dinamani <[email protected]>
Cc Jeff Layton <[email protected]>
---
 fs/attr.c           |   23 +++++++++++------------
 fs/configfs/inode.c |    9 +++------
 fs/f2fs/file.c      |   18 ++++++------------
 fs/ntfs/inode.c     |   18 ++++++------------
 fs/ubifs/file.c     |   18 ++++++------------
 fs/utimes.c         |    4 ++--
 6 files changed, 34 insertions(+), 56 deletions(-)
fs/attr.c +11 -12
@@ -183,18 +183,12 @@ void setattr_copy(struct inode *inode, c
 		inode->i_uid = attr->ia_uid;
 	if (ia_valid & ATTR_GID)
 		inode->i_gid = attr->ia_gid;
-	if (ia_valid & ATTR_ATIME) {
-		inode->i_atime = timestamp_truncate(attr->ia_atime,
-						  inode);
-	}
-	if (ia_valid & ATTR_MTIME) {
-		inode->i_mtime = timestamp_truncate(attr->ia_mtime,
-						  inode);
-	}
-	if (ia_valid & ATTR_CTIME) {
-		inode->i_ctime = timestamp_truncate(attr->ia_ctime,
-						  inode);
-	}
+	if (ia_valid & ATTR_ATIME)
+		inode->i_atime = attr->ia_atime;
+	if (ia_valid & ATTR_MTIME)
+		inode->i_mtime = attr->ia_mtime;
+	if (ia_valid & ATTR_CTIME)
+		inode->i_ctime = attr->ia_ctime;
 	if (ia_valid & ATTR_MODE) {
 		umode_t mode = attr->ia_mode;
 
@@ -268,8 +262,13 @@ int notify_change(struct dentry * dentry
 	attr->ia_ctime = now;
 	if (!(ia_valid & ATTR_ATIME_SET))
 		attr->ia_atime = now;
+	else
+		attr->ia_atime = timestamp_truncate(attr->ia_atime, inode);
 	if (!(ia_valid & ATTR_MTIME_SET))
 		attr->ia_mtime = now;
+	else
+		attr->ia_mtime = timestamp_truncate(attr->ia_mtime, inode);
+
 	if (ia_valid & ATTR_KILL_PRIV) {
 		error = security_inode_need_killpriv(dentry);
 		if (error < 0)
fs/configfs/inode.c +3 -6
@@ -76,14 +76,11 @@ int configfs_setattr(struct dentry * den
 	if (ia_valid & ATTR_GID)
 		sd_iattr->ia_gid = iattr->ia_gid;
 	if (ia_valid & ATTR_ATIME)
-		sd_iattr->ia_atime = timestamp_truncate(iattr->ia_atime,
-						      inode);
+		sd_iattr->ia_atime = iattr->ia_atime;
 	if (ia_valid & ATTR_MTIME)
-		sd_iattr->ia_mtime = timestamp_truncate(iattr->ia_mtime,
-						      inode);
+		sd_iattr->ia_mtime = iattr->ia_mtime;
 	if (ia_valid & ATTR_CTIME)
-		sd_iattr->ia_ctime = timestamp_truncate(iattr->ia_ctime,
-						      inode);
+		sd_iattr->ia_ctime = iattr->ia_ctime;
 	if (ia_valid & ATTR_MODE) {
 		umode_t mode = iattr->ia_mode;
 
fs/f2fs/file.c +6 -12
@@ -754,18 +754,12 @@ static void __setattr_copy(struct inode
 		inode->i_uid = attr->ia_uid;
 	if (ia_valid & ATTR_GID)
 		inode->i_gid = attr->ia_gid;
-	if (ia_valid & ATTR_ATIME) {
-		inode->i_atime = timestamp_truncate(attr->ia_atime,
-						  inode);
-	}
-	if (ia_valid & ATTR_MTIME) {
-		inode->i_mtime = timestamp_truncate(attr->ia_mtime,
-						  inode);
-	}
-	if (ia_valid & ATTR_CTIME) {
-		inode->i_ctime = timestamp_truncate(attr->ia_ctime,
-						  inode);
-	}
+	if (ia_valid & ATTR_ATIME)
+		inode->i_atime = attr->ia_atime;
+	if (ia_valid & ATTR_MTIME)
+		inode->i_mtime = attr->ia_mtime;
+	if (ia_valid & ATTR_CTIME)
+		inode->i_ctime = attr->ia_ctime;
 	if (ia_valid & ATTR_MODE) {
 		umode_t mode = attr->ia_mode;
 
fs/ntfs/inode.c +6 -12
@@ -2899,18 +2899,12 @@ int ntfs_setattr(struct dentry *dentry,
 			ia_valid |= ATTR_MTIME | ATTR_CTIME;
 		}
 	}
-	if (ia_valid & ATTR_ATIME) {
-		vi->i_atime = timestamp_truncate(attr->ia_atime,
-					       vi);
-	}
-	if (ia_valid & ATTR_MTIME) {
-		vi->i_mtime = timestamp_truncate(attr->ia_mtime,
-					       vi);
-	}
-	if (ia_valid & ATTR_CTIME) {
-		vi->i_ctime = timestamp_truncate(attr->ia_ctime,
-					       vi);
-	}
+	if (ia_valid & ATTR_ATIME)
+		vi->i_atime = attr->ia_atime;
+	if (ia_valid & ATTR_MTIME)
+		vi->i_mtime = attr->ia_mtime;
+	if (ia_valid & ATTR_CTIME)
+		vi->i_ctime = attr->ia_ctime;
 	mark_inode_dirty(vi);
 out:
 	return err;
fs/ubifs/file.c +6 -12
@@ -1078,18 +1078,12 @@ static void do_attr_changes(struct inode
 		inode->i_uid = attr->ia_uid;
 	if (attr->ia_valid & ATTR_GID)
 		inode->i_gid = attr->ia_gid;
-	if (attr->ia_valid & ATTR_ATIME) {
-		inode->i_atime = timestamp_truncate(attr->ia_atime,
-						  inode);
-	}
-	if (attr->ia_valid & ATTR_MTIME) {
-		inode->i_mtime = timestamp_truncate(attr->ia_mtime,
-						  inode);
-	}
-	if (attr->ia_valid & ATTR_CTIME) {
-		inode->i_ctime = timestamp_truncate(attr->ia_ctime,
-						  inode);
-	}
+	if (attr->ia_valid & ATTR_ATIME)
+		inode->i_atime = attr->ia_atime;
+	if (attr->ia_valid & ATTR_MTIME)
+		inode->i_mtime = attr->ia_mtime;
+	if (attr->ia_valid & ATTR_CTIME)
+		inode->i_ctime = attr->ia_ctime;
 	if (attr->ia_valid & ATTR_MODE) {
 		umode_t mode = attr->ia_mode;
 
fs/utimes.c +2 -2
@@ -36,14 +36,14 @@ static int utimes_common(const struct pa
 		if (times[0].tv_nsec == UTIME_OMIT)
 			newattrs.ia_valid &= ~ATTR_ATIME;
 		else if (times[0].tv_nsec != UTIME_NOW) {
-			newattrs.ia_atime = timestamp_truncate(times[0], inode);
+			newattrs.ia_atime = times[0];
 			newattrs.ia_valid |= ATTR_ATIME_SET;
 		}
 
 		if (times[1].tv_nsec == UTIME_OMIT)
 			newattrs.ia_valid &= ~ATTR_MTIME;
 		else if (times[1].tv_nsec != UTIME_NOW) {
-			newattrs.ia_mtime = timestamp_truncate(times[1], inode);
+			newattrs.ia_mtime = times[1];
 			newattrs.ia_valid |= ATTR_MTIME_SET;
 		}
 		/*
author maintainer
#57 lore raw

PATCH 57/367 mm/migrate.c: also overwrite error when it is bigger than zero

In reply to Greg Kroah-Hartman

From: Wei Yang <[email protected]>

commit dfe9aa23cab7880a794db9eb2d176c00ed064eb6 upstream.

If we get here after successfully adding page to list, err would be 1 to indicate the page is queued in the list.

Current code has two problems:

* on success, 0 is not returned
* on error, if add_page_for_migratioin() return 1, and the following err1 from do_move_pages_to_node() is set, the err1 is not returned since err is 1

And these behaviors break the user interface.

Fixes e0153fc2c760 ("mm: move_pages: return valid node id in status if the page is already on the target node").
Cc John Hubbard <[email protected]>
Cc Vlastimil Babka <[email protected]>
Cc Christoph Lameter <[email protected]>
Cc Michal Hocko <[email protected]>
---
 mm/migrate.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
mm/migrate.c +1 -1
@@ -1676,7 +1676,7 @@ out_flush:
 	err1 = do_move_pages_to_node(mm, &pagelist, current_node);
 	if (!err1)
 		err1 = store_status(status, start, current_node, i - start);
-	if (!err)
+	if (err >= 0)
 		err = err1;
 out:
 	return err;
author maintainer
#58 lore raw

PATCH 58/367 mm/memory_hotplug: fix remove_memory() lockdep splat

In reply to Greg Kroah-Hartman

From: Dan Williams <[email protected]>

commit f1037ec0cc8ac1a450974ad9754e991f72884f48 upstream.

The daxctl unit test for the dax_kmem driver currently triggers the (false positive) lockdep splat below. It results from the fact that remove_memory_block_devices() is invoked under the mem_hotplug_lock() causing lockdep entanglements with cpu_hotplug_lock() and sysfs (kernfs active state tracking). It is a false positive because the sysfs attribute path triggering the memory remove is not the same attribute path associated with memory-block device.

sysfs_break_active_protection() is not applicable since there is no real deadlock conflict, instead move memory-block device removal outside the lock. The mem_hotplug_lock() is not needed to synchronize the memory-block device removal vs the page online state, that is already handled by lock_device_hotplug(). Specifically, lock_device_hotplug() is sufficient to allow try_remove_memory() to check the offline state of the memblocks and be assured that any in progress online attempts are flushed / blocked by kernfs_drain() / attribute removal.

The add_memory() path safely creates memblock devices under the mem_hotplug_lock(). There is no kernfs active state synchronization in the memblock device_register() path, so nothing to fix there.

This change is only possible thanks to the recent change that refactored memory block device removal out of arch_remove_memory() (commit 4c4b7f9ba948 "mm/memory_hotplug: remove memory block devices before arch_remove_memory()"), and David's due diligence tracking down the guarantees afforded by kernfs_drain(). Not flagged for -stable since this only impacts ongoing development and lockdep validation, not a runtime issue.

    ======================================================
    WARNING: possible circular locking dependency detected
    5.5.0-rc3+ #230 Tainted: G           OE
    ------------------------------------------------------
    lt-daxctl/6459 is trying to acquire lock:
    ffff99c7f0003510 (kn->count#241){++++}, at: kernfs_remove_by_name_ns+0x41/0x80

    but task is already holding lock:
    ffffffffa76a5450 (mem_hotplug_lock.rw_sem){++++}, at: percpu_down_write+0x20/0xe0

    which lock already depends on the new lock.

    the existing dependency chain (in reverse order) is:

    -> #2 (mem_hotplug_lock.rw_sem){++++}:
           __lock_acquire+0x39c/0x790
           lock_acquire+0xa2/0x1b0
           get_online_mems+0x3e/0xb0
           kmem_cache_create_usercopy+0x2e/0x260
           kmem_cache_create+0x12/0x20
           ptlock_cache_init+0x20/0x28
           start_kernel+0x243/0x547
           secondary_startup_64+0xb6/0xc0

    -> #1 (cpu_hotplug_lock.rw_sem){++++}:
           __lock_acquire+0x39c/0x790
           lock_acquire+0xa2/0x1b0
           cpus_read_lock+0x3e/0xb0
           online_pages+0x37/0x300
           memory_subsys_online+0x17d/0x1c0
           device_online+0x60/0x80
           state_store+0x65/0xd0
           kernfs_fop_write+0xcf/0x1c0
           vfs_write+0xdb/0x1d0
           ksys_write+0x65/0xe0
           do_syscall_64+0x5c/0xa0
           entry_SYSCALL_64_after_hwframe+0x49/0xbe

    -> #0 (kn->count#241){++++}:
           check_prev_add+0x98/0xa40
           validate_chain+0x576/0x860
           __lock_acquire+0x39c/0x790
           lock_acquire+0xa2/0x1b0
           __kernfs_remove+0x25f/0x2e0
           kernfs_remove_by_name_ns+0x41/0x80
           remove_files.isra.0+0x30/0x70
           sysfs_remove_group+0x3d/0x80
           sysfs_remove_groups+0x29/0x40
           device_remove_attrs+0x39/0x70
           device_del+0x16a/0x3f0
           device_unregister+0x16/0x60
           remove_memory_block_devices+0x82/0xb0
           try_remove_memory+0xb5/0x130
           remove_memory+0x26/0x40
           dev_dax_kmem_remove+0x44/0x6a [kmem]
           device_release_driver_internal+0xe4/0x1c0
           unbind_store+0xef/0x120
           kernfs_fop_write+0xcf/0x1c0
           vfs_write+0xdb/0x1d0
           ksys_write+0x65/0xe0
           do_syscall_64+0x5c/0xa0
           entry_SYSCALL_64_after_hwframe+0x49/0xbe

    other info that might help us debug this:

    Chain exists of:
      kn->count#241 --> cpu_hotplug_lock.rw_sem --> mem_hotplug_lock.rw_sem

     Possible unsafe locking scenario:

           CPU0                    CPU1
           ----                    ----
      lock(mem_hotplug_lock.rw_sem);
                                   lock(cpu_hotplug_lock.rw_sem);
                                   lock(mem_hotplug_lock.rw_sem);
      lock(kn->count#241);

     *** DEADLOCK ***

No fixes tag as this has been a long standing issue that predated the addition of kernfs lockdep annotations.

---
 mm/memory_hotplug.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
mm/memory_hotplug.c +6 -3
@@ -1764,8 +1764,6 @@ static int __ref try_remove_memory(int n
 
 	BUG_ON(check_hotplug_memory_range(start, size));
 
-	mem_hotplug_begin();
-
 	/*
 	 * All memory blocks must be offlined before removing memory.  Check
 	 * whether all memory blocks in question are offline and return error
@@ -1778,9 +1776,14 @@ static int __ref try_remove_memory(int n
 	/* remove memmap entry */
 	firmware_map_remove(start, start + size, "System RAM");
 
-	/* remove memory block devices before removing memory */
+	/*
+	 * Memory block device removal under the device_hotplug_lock is
+	 * a barrier against racing online attempts.
+	 */
 	remove_memory_block_devices(start, size);
 
+	mem_hotplug_begin();
+
 	arch_remove_memory(nid, start, size, NULL);
 	memblock_free(start, size);
 	memblock_remove(start, size);
author maintainer
#59 lore raw

PATCH 59/367 mm: thp: dont need care deferred split queue in memcg charge move path

In reply to Greg Kroah-Hartman

From: Wei Yang <[email protected]>

commit fac0516b5534897bf4c4a88daa06a8cfa5611b23 upstream.

If compound is true, this means it is a PMD mapped THP. Which implies the page is not linked to any defer list. So the first code chunk will not be executed.

Also with this reason, it would not be proper to add this page to a defer list. So the second code chunk is not correct.

Based on this, we should remove the defer list related code.

[[email protected]: better patch title]
Fixes 87eaceb3faa5 ("mm: thp: make deferred split shrinker memcg aware")
Cc David Rientjes <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Kirill A. Shutemov <[email protected]>
Cc Johannes Weiner <[email protected]>
Cc Vladimir Davydov <[email protected]>
Cc <[email protected]> [5.4+]
---
 mm/memcontrol.c |   18 ------------------
 1 file changed, 18 deletions(-)
mm/memcontrol.c +0 -18
@@ -5340,14 +5340,6 @@ static int mem_cgroup_move_account(struc
 		__mod_lruvec_state(to_vec, NR_WRITEBACK, nr_pages);
 	}
 
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-	if (compound && !list_empty(page_deferred_list(page))) {
-		spin_lock(&from->deferred_split_queue.split_queue_lock);
-		list_del_init(page_deferred_list(page));
-		from->deferred_split_queue.split_queue_len--;
-		spin_unlock(&from->deferred_split_queue.split_queue_lock);
-	}
-#endif
 	/*
 	 * It is safe to change page->mem_cgroup here because the page
 	 * is referenced, charged, and isolated - we can't race with
@@ -5357,16 +5349,6 @@ static int mem_cgroup_move_account(struc
 	/* caller should have done css_get */
 	page->mem_cgroup = to;
 
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-	if (compound && list_empty(page_deferred_list(page))) {
-		spin_lock(&to->deferred_split_queue.split_queue_lock);
-		list_add_tail(page_deferred_list(page),
-			      &to->deferred_split_queue.split_queue);
-		to->deferred_split_queue.split_queue_len++;
-		spin_unlock(&to->deferred_split_queue.split_queue_lock);
-	}
-#endif
-
 	spin_unlock_irqrestore(&from->move_lock, flags);
 
 	ret = 0;
author maintainer
#60 lore raw

PATCH 60/367 mm: move_pages: report the number of non-attempted pages

In reply to Greg Kroah-Hartman

From: Yang Shi <[email protected]>

commit 5984fabb6e82d9ab4e6305cb99694c85d46de8ae upstream.

Since commit a49bd4d71637 ("mm, numa: rework do_pages_move"), the semantic of move_pages() has changed to return the number of non-migrated pages if they were result of a non-fatal reasons (usually a busy page).

This was an unintentional change that hasn't been noticed except for LTP tests which checked for the documented behavior.

There are two ways to go around this change. We can even get back to the original behavior and return -EAGAIN whenever migrate_pages is not able to migrate pages due to non-fatal reasons. Another option would be to simply continue with the changed semantic and extend move_pages documentation to clarify that -errno is returned on an invalid input or when migration simply cannot succeed (e.g. -ENOMEM, -EBUSY) or the number of pages that couldn't have been migrated due to ephemeral reasons (e.g. page is pinned or locked for other reasons).

This patch implements the second option because this behavior is in place for some time without anybody complaining and possibly new users depending on it. Also it allows to have a slightly easier error handling as the caller knows that it is worth to retry when err > 0.

But since the new semantic would be aborted immediately if migration is failed due to ephemeral reasons, need include the number of non-attempted pages in the return value too.

---
 mm/migrate.c |   25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)
mm/migrate.c +23 -2
@@ -1627,8 +1627,19 @@ static int do_pages_move(struct mm_struc
 			start = i;
 		} else if (node != current_node) {
 			err = do_move_pages_to_node(mm, &pagelist, current_node);
-			if (err)
+			if (err) {
+				/*
+				 * Positive err means the number of failed
+				 * pages to migrate.  Since we are going to
+				 * abort and return the number of non-migrated
+				 * pages, so need to incude the rest of the
+				 * nr_pages that have not been attempted as
+				 * well.
+				 */
+				if (err > 0)
+					err += nr_pages - i - 1;
 				goto out;
+			}
 			err = store_status(status, start, current_node, i - start);
 			if (err)
 				goto out;
@@ -1659,8 +1670,11 @@ static int do_pages_move(struct mm_struc
 			goto out_flush;
 
 		err = do_move_pages_to_node(mm, &pagelist, current_node);
-		if (err)
+		if (err) {
+			if (err > 0)
+				err += nr_pages - i - 1;
 			goto out;
+		}
 		if (i > start) {
 			err = store_status(status, start, current_node, i - start);
 			if (err)
@@ -1674,6 +1688,13 @@ out_flush:
 
 	/* Make sure we do not overwrite the existing error */
 	err1 = do_move_pages_to_node(mm, &pagelist, current_node);
+	/*
+	 * Don't have to report non-attempted pages here since:
+	 *     - If the above loop is done gracefully all pages have been
+	 *       attempted.
+	 *     - If the above loop is aborted it means a fatal error
+	 *       happened, should return ret.
+	 */
 	if (!err1)
 		err1 = store_status(status, start, current_node, i - start);
 	if (err >= 0)
author maintainer
#61 lore raw

PATCH 61/367 media/v4l2-core: set pages dirty upon releasing DMA buffers

In reply to Greg Kroah-Hartman

From: John Hubbard <[email protected]>

commit 3c7470b6f68434acae459482ab920d1e3fabd1c7 upstream.

After DMA is complete, and the device and CPU caches are synchronized, it's still required to mark the CPU pages as dirty, if the data was coming from the device. However, this driver was just issuing a bare put_page() call, without any set_page_dirty*() call.

Fix the problem, by calling set_page_dirty_lock() if the CPU pages were potentially receiving data from the device.

Cc Mauro Carvalho Chehab <[email protected]>
Cc Alex Williamson <[email protected]>
Cc Aneesh Kumar K.V <[email protected]>
Cc Björn Töpel <[email protected]>
Cc Daniel Vetter <[email protected]>
Cc Dan Williams <[email protected]>
Cc Ira Weiny <[email protected]>
Cc Jan Kara <[email protected]>
Cc Jason Gunthorpe <[email protected]>
Cc Jason Gunthorpe <[email protected]>
Cc Jens Axboe <[email protected]>
Cc Jerome Glisse <[email protected]>
Cc Jonathan Corbet <[email protected]>
Cc Kirill A. Shutemov <[email protected]>
Cc Leon Romanovsky <[email protected]>
Cc Mike Rapoport <[email protected]>
---
 drivers/media/v4l2-core/videobuf-dma-sg.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/media/v4l2-core/videobuf-dma-sg.c +4 -1
@@ -349,8 +349,11 @@ int videobuf_dma_free(struct videobuf_dm
 	BUG_ON(dma->sglen);
 
 	if (dma->pages) {
-		for (i = 0; i < dma->nr_pages; i++)
+		for (i = 0; i < dma->nr_pages; i++) {
+			if (dma->direction == DMA_FROM_DEVICE)
+				set_page_dirty_lock(dma->pages[i]);
 			put_page(dma->pages[i]);
+		}
 		kfree(dma->pages);
 		dma->pages = NULL;
 	}
author maintainer
#62 lore raw

PATCH 62/367 media: v4l2-core: compat: ignore native command codes

In reply to Greg Kroah-Hartman

From: Arnd Bergmann <[email protected]>

commit 4a873f3fa5d6ca52e446d306dd7194dd86a09422 upstream.

The do_video_ioctl() compat handler converts the compat command codes into the native ones before processing further, but this causes problems for 32-bit user applications that pass a command code that matches a 64-bit native number, which will then be handled the same way.

Specifically, this breaks VIDIOC_DQEVENT_TIME from user space applications with 64-bit time_t, as the structure layout is the same as the native 64-bit layout on many architectures (x86 being the notable exception).

Change the handler to use the converted command code only for passing into the native ioctl handler, not for deciding on the conversion, in order to make the compat behavior match the native behavior.

Actual support for the 64-bit time_t version of VIDIOC_DQEVENT_TIME and other commands still needs to be added in a separate patch.

---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c |  148 +++++++++++++-------------
 1 file changed, 75 insertions(+), 73 deletions(-)
drivers/media/v4l2-core/v4l2-compat-ioctl32.c +75 -73
@@ -1183,36 +1183,38 @@ static long do_video_ioctl(struct file *
 	u32 aux_space;
 	int compatible_arg = 1;
 	long err = 0;
+	unsigned int ncmd;
 
 	/*
 	 * 1. When struct size is different, converts the command.
 	 */
 	switch (cmd) {
-	case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break;
-	case VIDIOC_S_FMT32: cmd = VIDIOC_S_FMT; break;
-	case VIDIOC_QUERYBUF32: cmd = VIDIOC_QUERYBUF; break;
-	case VIDIOC_G_FBUF32: cmd = VIDIOC_G_FBUF; break;
-	case VIDIOC_S_FBUF32: cmd = VIDIOC_S_FBUF; break;
-	case VIDIOC_QBUF32: cmd = VIDIOC_QBUF; break;
-	case VIDIOC_DQBUF32: cmd = VIDIOC_DQBUF; break;
-	case VIDIOC_ENUMSTD32: cmd = VIDIOC_ENUMSTD; break;
-	case VIDIOC_ENUMINPUT32: cmd = VIDIOC_ENUMINPUT; break;
-	case VIDIOC_TRY_FMT32: cmd = VIDIOC_TRY_FMT; break;
-	case VIDIOC_G_EXT_CTRLS32: cmd = VIDIOC_G_EXT_CTRLS; break;
-	case VIDIOC_S_EXT_CTRLS32: cmd = VIDIOC_S_EXT_CTRLS; break;
-	case VIDIOC_TRY_EXT_CTRLS32: cmd = VIDIOC_TRY_EXT_CTRLS; break;
-	case VIDIOC_DQEVENT32: cmd = VIDIOC_DQEVENT; break;
-	case VIDIOC_OVERLAY32: cmd = VIDIOC_OVERLAY; break;
-	case VIDIOC_STREAMON32: cmd = VIDIOC_STREAMON; break;
-	case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break;
-	case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break;
-	case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
-	case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break;
-	case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
-	case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break;
-	case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break;
-	case VIDIOC_G_EDID32: cmd = VIDIOC_G_EDID; break;
-	case VIDIOC_S_EDID32: cmd = VIDIOC_S_EDID; break;
+	case VIDIOC_G_FMT32: ncmd = VIDIOC_G_FMT; break;
+	case VIDIOC_S_FMT32: ncmd = VIDIOC_S_FMT; break;
+	case VIDIOC_QUERYBUF32: ncmd = VIDIOC_QUERYBUF; break;
+	case VIDIOC_G_FBUF32: ncmd = VIDIOC_G_FBUF; break;
+	case VIDIOC_S_FBUF32: ncmd = VIDIOC_S_FBUF; break;
+	case VIDIOC_QBUF32: ncmd = VIDIOC_QBUF; break;
+	case VIDIOC_DQBUF32: ncmd = VIDIOC_DQBUF; break;
+	case VIDIOC_ENUMSTD32: ncmd = VIDIOC_ENUMSTD; break;
+	case VIDIOC_ENUMINPUT32: ncmd = VIDIOC_ENUMINPUT; break;
+	case VIDIOC_TRY_FMT32: ncmd = VIDIOC_TRY_FMT; break;
+	case VIDIOC_G_EXT_CTRLS32: ncmd = VIDIOC_G_EXT_CTRLS; break;
+	case VIDIOC_S_EXT_CTRLS32: ncmd = VIDIOC_S_EXT_CTRLS; break;
+	case VIDIOC_TRY_EXT_CTRLS32: ncmd = VIDIOC_TRY_EXT_CTRLS; break;
+	case VIDIOC_DQEVENT32: ncmd = VIDIOC_DQEVENT; break;
+	case VIDIOC_OVERLAY32: ncmd = VIDIOC_OVERLAY; break;
+	case VIDIOC_STREAMON32: ncmd = VIDIOC_STREAMON; break;
+	case VIDIOC_STREAMOFF32: ncmd = VIDIOC_STREAMOFF; break;
+	case VIDIOC_G_INPUT32: ncmd = VIDIOC_G_INPUT; break;
+	case VIDIOC_S_INPUT32: ncmd = VIDIOC_S_INPUT; break;
+	case VIDIOC_G_OUTPUT32: ncmd = VIDIOC_G_OUTPUT; break;
+	case VIDIOC_S_OUTPUT32: ncmd = VIDIOC_S_OUTPUT; break;
+	case VIDIOC_CREATE_BUFS32: ncmd = VIDIOC_CREATE_BUFS; break;
+	case VIDIOC_PREPARE_BUF32: ncmd = VIDIOC_PREPARE_BUF; break;
+	case VIDIOC_G_EDID32: ncmd = VIDIOC_G_EDID; break;
+	case VIDIOC_S_EDID32: ncmd = VIDIOC_S_EDID; break;
+	default: ncmd = cmd; break;
 	}
 
 	/*
@@ -1221,11 +1223,11 @@ static long do_video_ioctl(struct file *
 	 * argument into it.
 	 */
 	switch (cmd) {
-	case VIDIOC_OVERLAY:
-	case VIDIOC_STREAMON:
-	case VIDIOC_STREAMOFF:
-	case VIDIOC_S_INPUT:
-	case VIDIOC_S_OUTPUT:
+	case VIDIOC_OVERLAY32:
+	case VIDIOC_STREAMON32:
+	case VIDIOC_STREAMOFF32:
+	case VIDIOC_S_INPUT32:
+	case VIDIOC_S_OUTPUT32:
 		err = alloc_userspace(sizeof(unsigned int), 0, &new_p64);
 		if (!err && assign_in_user((unsigned int __user *)new_p64,
 					   (compat_uint_t __user *)p32))
@@ -1233,23 +1235,23 @@ static long do_video_ioctl(struct file *
 		compatible_arg = 0;
 		break;
 
-	case VIDIOC_G_INPUT:
-	case VIDIOC_G_OUTPUT:
+	case VIDIOC_G_INPUT32:
+	case VIDIOC_G_OUTPUT32:
 		err = alloc_userspace(sizeof(unsigned int), 0, &new_p64);
 		compatible_arg = 0;
 		break;
 
-	case VIDIOC_G_EDID:
-	case VIDIOC_S_EDID:
+	case VIDIOC_G_EDID32:
+	case VIDIOC_S_EDID32:
 		err = alloc_userspace(sizeof(struct v4l2_edid), 0, &new_p64);
 		if (!err)
 			err = get_v4l2_edid32(new_p64, p32);
 		compatible_arg = 0;
 		break;
 
-	case VIDIOC_G_FMT:
-	case VIDIOC_S_FMT:
-	case VIDIOC_TRY_FMT:
+	case VIDIOC_G_FMT32:
+	case VIDIOC_S_FMT32:
+	case VIDIOC_TRY_FMT32:
 		err = bufsize_v4l2_format(p32, &aux_space);
 		if (!err)
 			err = alloc_userspace(sizeof(struct v4l2_format),
@@ -1262,7 +1264,7 @@ static long do_video_ioctl(struct file *
 		compatible_arg = 0;
 		break;
 
-	case VIDIOC_CREATE_BUFS:
+	case VIDIOC_CREATE_BUFS32:
 		err = bufsize_v4l2_create(p32, &aux_space);
 		if (!err)
 			err = alloc_userspace(sizeof(struct v4l2_create_buffers),
@@ -1275,10 +1277,10 @@ static long do_video_ioctl(struct file *
 		compatible_arg = 0;
 		break;
 
-	case VIDIOC_PREPARE_BUF:
-	case VIDIOC_QUERYBUF:
-	case VIDIOC_QBUF:
-	case VIDIOC_DQBUF:
+	case VIDIOC_PREPARE_BUF32:
+	case VIDIOC_QUERYBUF32:
+	case VIDIOC_QBUF32:
+	case VIDIOC_DQBUF32:
 		err = bufsize_v4l2_buffer(p32, &aux_space);
 		if (!err)
 			err = alloc_userspace(sizeof(struct v4l2_buffer),
@@ -1291,7 +1293,7 @@ static long do_video_ioctl(struct file *
 		compatible_arg = 0;
 		break;
 
-	case VIDIOC_S_FBUF:
+	case VIDIOC_S_FBUF32:
 		err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0,
 				      &new_p64);
 		if (!err)
@@ -1299,13 +1301,13 @@ static long do_video_ioctl(struct file *
 		compatible_arg = 0;
 		break;
 
-	case VIDIOC_G_FBUF:
+	case VIDIOC_G_FBUF32:
 		err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0,
 				      &new_p64);
 		compatible_arg = 0;
 		break;
 
-	case VIDIOC_ENUMSTD:
+	case VIDIOC_ENUMSTD32:
 		err = alloc_userspace(sizeof(struct v4l2_standard), 0,
 				      &new_p64);
 		if (!err)
@@ -1313,16 +1315,16 @@ static long do_video_ioctl(struct file *
 		compatible_arg = 0;
 		break;
 
-	case VIDIOC_ENUMINPUT:
+	case VIDIOC_ENUMINPUT32:
 		err = alloc_userspace(sizeof(struct v4l2_input), 0, &new_p64);
 		if (!err)
 			err = get_v4l2_input32(new_p64, p32);
 		compatible_arg = 0;
 		break;
 
-	case VIDIOC_G_EXT_CTRLS:
-	case VIDIOC_S_EXT_CTRLS:
-	case VIDIOC_TRY_EXT_CTRLS:
+	case VIDIOC_G_EXT_CTRLS32:
+	case VIDIOC_S_EXT_CTRLS32:
+	case VIDIOC_TRY_EXT_CTRLS32:
 		err = bufsize_v4l2_ext_controls(p32, &aux_space);
 		if (!err)
 			err = alloc_userspace(sizeof(struct v4l2_ext_controls),
@@ -1334,7 +1336,7 @@ static long do_video_ioctl(struct file *
 		}
 		compatible_arg = 0;
 		break;
-	case VIDIOC_DQEVENT:
+	case VIDIOC_DQEVENT32:
 		err = alloc_userspace(sizeof(struct v4l2_event), 0, &new_p64);
 		compatible_arg = 0;
 		break;
@@ -1352,9 +1354,9 @@ static long do_video_ioctl(struct file *
 	 * Otherwise, it will pass the newly allocated @new_p64 argument.
 	 */
 	if (compatible_arg)
-		err = native_ioctl(file, cmd, (unsigned long)p32);
+		err = native_ioctl(file, ncmd, (unsigned long)p32);
 	else
-		err = native_ioctl(file, cmd, (unsigned long)new_p64);
+		err = native_ioctl(file, ncmd, (unsigned long)new_p64);
 
 	if (err == -ENOTTY)
 		return err;
@@ -1370,13 +1372,13 @@ static long do_video_ioctl(struct file *
 	 * the blocks to maximum allowed value.
 	 */
 	switch (cmd) {
-	case VIDIOC_G_EXT_CTRLS:
-	case VIDIOC_S_EXT_CTRLS:
-	case VIDIOC_TRY_EXT_CTRLS:
+	case VIDIOC_G_EXT_CTRLS32:
+	case VIDIOC_S_EXT_CTRLS32:
+	case VIDIOC_TRY_EXT_CTRLS32:
 		if (put_v4l2_ext_controls32(file, new_p64, p32))
 			err = -EFAULT;
 		break;
-	case VIDIOC_S_EDID:
+	case VIDIOC_S_EDID32:
 		if (put_v4l2_edid32(new_p64, p32))
 			err = -EFAULT;
 		break;
@@ -1389,49 +1391,49 @@ static long do_video_ioctl(struct file *
 	 * the original 32 bits structure.
 	 */
 	switch (cmd) {
-	case VIDIOC_S_INPUT:
-	case VIDIOC_S_OUTPUT:
-	case VIDIOC_G_INPUT:
-	case VIDIOC_G_OUTPUT:
+	case VIDIOC_S_INPUT32:
+	case VIDIOC_S_OUTPUT32:
+	case VIDIOC_G_INPUT32:
+	case VIDIOC_G_OUTPUT32:
 		if (assign_in_user((compat_uint_t __user *)p32,
 				   ((unsigned int __user *)new_p64)))
 			err = -EFAULT;
 		break;
 
-	case VIDIOC_G_FBUF:
+	case VIDIOC_G_FBUF32:
 		err = put_v4l2_framebuffer32(new_p64, p32);
 		break;
 
-	case VIDIOC_DQEVENT:
+	case VIDIOC_DQEVENT32:
 		err = put_v4l2_event32(new_p64, p32);
 		break;
 
-	case VIDIOC_G_EDID:
+	case VIDIOC_G_EDID32:
 		err = put_v4l2_edid32(new_p64, p32);
 		break;
 
-	case VIDIOC_G_FMT:
-	case VIDIOC_S_FMT:
-	case VIDIOC_TRY_FMT:
+	case VIDIOC_G_FMT32:
+	case VIDIOC_S_FMT32:
+	case VIDIOC_TRY_FMT32:
 		err = put_v4l2_format32(new_p64, p32);
 		break;
 
-	case VIDIOC_CREATE_BUFS:
+	case VIDIOC_CREATE_BUFS32:
 		err = put_v4l2_create32(new_p64, p32);
 		break;
 
-	case VIDIOC_PREPARE_BUF:
-	case VIDIOC_QUERYBUF:
-	case VIDIOC_QBUF:
-	case VIDIOC_DQBUF:
+	case VIDIOC_PREPARE_BUF32:
+	case VIDIOC_QUERYBUF32:
+	case VIDIOC_QBUF32:
+	case VIDIOC_DQBUF32:
 		err = put_v4l2_buffer32(new_p64, p32);
 		break;
 
-	case VIDIOC_ENUMSTD:
+	case VIDIOC_ENUMSTD32:
 		err = put_v4l2_standard32(new_p64, p32);
 		break;
 
-	case VIDIOC_ENUMINPUT:
+	case VIDIOC_ENUMINPUT32:
 		err = put_v4l2_input32(new_p64, p32);
 		break;
 	}
author maintainer
#63 lore raw

PATCH 63/367 media: v4l2-rect.h: fix v4l2_rect_map_inside() top/left adjustments

In reply to Greg Kroah-Hartman

From: Helen Koike <[email protected]>

commit f51e50db4c20d46930b33be3f208851265694f3e upstream.

boundary->width and boundary->height are sizes relative to boundary->left and boundary->top coordinates, but they were not being taken into consideration to adjust r->left and r->top, leading to the following error:

Consider the follow as initial values for boundary and r:

struct v4l2_rect boundary = {
	.left = 100,
	.top = 100,
	.width = 800,
	.height = 600,
}
struct v4l2_rect r = {
	.left = 0,
	.top = 0,
	.width = 1920,
	.height = 960,
}

calling v4l2_rect_map_inside(&r, &boundary) was modifying r to:

r = {
	.left = 0,
	.top = 0,
	.width = 800,
	.height = 600,
}

Which is wrongly outside the boundary rectangle, because:

	v4l2_rect_set_max_size(r, boundary); // r->width = 800, r->height = 600
	...
	if (r->left + r->width > boundary->width) // true
		r->left = boundary->width - r->width; // r->left = 800 - 800
	if (r->top + r->height > boundary->height) // true
		r->top = boundary->height - r->height; // r->height = 600 - 600

Fix this by considering top/left coordinates from boundary.

Fixes ac49de8c49d7 ("[media] v4l2-rect.h: new header with struct v4l2_rect helper functions")
Cc <[email protected]> # for v4.7 and up
---
 include/media/v4l2-rect.h |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
include/media/v4l2-rect.h +4 -4
@@ -63,10 +63,10 @@ static inline void v4l2_rect_map_inside(
 		r->left = boundary->left;
 	if (r->top < boundary->top)
 		r->top = boundary->top;
-	if (r->left + r->width > boundary->width)
-		r->left = boundary->width - r->width;
-	if (r->top + r->height > boundary->height)
-		r->top = boundary->height - r->height;
+	if (r->left + r->width > boundary->left + boundary->width)
+		r->left = boundary->left + boundary->width - r->width;
+	if (r->top + r->height > boundary->top + boundary->height)
+		r->top = boundary->top + boundary->height - r->height;
 }
 
 /**
author maintainer
#64 lore raw

PATCH 64/367 lib/test_kasan.c: fix memory leak in kmalloc_oob_krealloc_more()

In reply to Greg Kroah-Hartman

From: Gustavo A. R. Silva <[email protected]>

commit 3e21d9a501bf99aee2e5835d7f34d8c823f115b5 upstream.

In case memory resources for _ptr2_ were allocated, release them before return.

Notice that in case _ptr1_ happens to be NULL, krealloc() behaves exactly like kmalloc().

Addresses-Coverity-ID: 1490594 ("Resource leak")

---
 lib/test_kasan.c |    1 +
 1 file changed, 1 insertion(+)
lib/test_kasan.c +1 -0
@@ -158,6 +158,7 @@ static noinline void __init kmalloc_oob_
 	if (!ptr1 || !ptr2) {
 		pr_err("Allocation failed\n");
 		kfree(ptr1);
+		kfree(ptr2);
 		return;
 	}
 
author maintainer
#65 lore raw

PATCH 65/367 irqdomain: Fix a memory leak in irq_domain_push_irq()

In reply to Greg Kroah-Hartman

From: Kevin Hao <[email protected]>

commit 0f394daef89b38d58c91118a2b08b8a1b316703b upstream.

Fix a memory leak reported by kmemleak:
unreferenced object 0xffff000bc6f50e80 (size 128):
comm "kworker/23:2", pid 201, jiffies 4294894947 (age 942.132s) hex dump (first 32 bytes):

    00 00 00 00 41 00 00 00 86 c0 03 00 00 00 00 00  ....A...........
    00 a0 b2 c6 0b 00 ff ff 40 51 fd 10 00 80 ff ff  ........@Q......
  backtrace:
    [<00000000e62d2240>] kmem_cache_alloc_trace+0x1a4/0x320
    [<00000000279143c9>] irq_domain_push_irq+0x7c/0x188
    [<00000000d9f4c154>] thunderx_gpio_probe+0x3ac/0x438
    [<00000000fd09ec22>] pci_device_probe+0xe4/0x198
    [<00000000d43eca75>] really_probe+0xdc/0x320
    [<00000000d3ebab09>] driver_probe_device+0x5c/0xf0
    [<000000005b3ecaa0>] __device_attach_driver+0x88/0xc0
    [<000000004e5915f5>] bus_for_each_drv+0x7c/0xc8
    [<0000000079d4db41>] __device_attach+0xe4/0x140
    [<00000000883bbda9>] device_initial_probe+0x18/0x20
    [<000000003be59ef6>] bus_probe_device+0x98/0xa0
    [<0000000039b03d3f>] deferred_probe_work_func+0x74/0xa8
    [<00000000870934ce>] process_one_work+0x1c8/0x470
    [<00000000e3cce570>] worker_thread+0x1f8/0x428
    [<000000005d64975e>] kthread+0xfc/0x128
    [<00000000f0eaa764>] ret_from_fork+0x10/0x18
Fixes 495c38d3001f ("irqdomain: Add irq_domain_{push,pop}_irq() functions")
---
 kernel/irq/irqdomain.c |    1 +
 1 file changed, 1 insertion(+)
kernel/irq/irqdomain.c +1 -0
@@ -1459,6 +1459,7 @@ int irq_domain_push_irq(struct irq_domai
 	if (rv) {
 		/* Restore the original irq_data. */
 		*root_irq_data = *child_irq_data;
+		kfree(child_irq_data);
 		goto error;
 	}
 
author maintainer
#66 lore raw

PATCH 66/367 x86/cpu: Update cached HLE state on write to TSX_CTRL_CPUID_CLEAR

In reply to Greg Kroah-Hartman

From: Pawan Gupta <[email protected]>

commit 5efc6fa9044c3356d6046c6e1da6d02572dbed6b upstream.

/proc/cpuinfo currently reports Hardware Lock Elision (HLE) feature to be present on boot cpu even if it was disabled during the bootup. This is because cpuinfo_x86->x86_capability HLE bit is not updated after TSX state is changed via the new MSR IA32_TSX_CTRL.

Update the cached HLE bit also since it is expected to change after an update to CPUID_CLEAR bit in MSR IA32_TSX_CTRL.

---
 arch/x86/kernel/cpu/tsx.c |   13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
arch/x86/kernel/cpu/tsx.c +7 -6
@@ -115,11 +115,12 @@ void __init tsx_init(void)
 		tsx_disable();
 
 		/*
-		 * tsx_disable() will change the state of the
-		 * RTM CPUID bit.  Clear it here since it is now
-		 * expected to be not set.
+		 * tsx_disable() will change the state of the RTM and HLE CPUID
+		 * bits. Clear them here since they are now expected to be not
+		 * set.
 		 */
 		setup_clear_cpu_cap(X86_FEATURE_RTM);
+		setup_clear_cpu_cap(X86_FEATURE_HLE);
 	} else if (tsx_ctrl_state == TSX_CTRL_ENABLE) {
 
 		/*
@@ -131,10 +132,10 @@ void __init tsx_init(void)
 		tsx_enable();
 
 		/*
-		 * tsx_enable() will change the state of the
-		 * RTM CPUID bit.  Force it here since it is now
-		 * expected to be set.
+		 * tsx_enable() will change the state of the RTM and HLE CPUID
+		 * bits. Force them here since they are now expected to be set.
 		 */
 		setup_force_cpu_cap(X86_FEATURE_RTM);
+		setup_force_cpu_cap(X86_FEATURE_HLE);
 	}
 }
author maintainer
#67 lore raw

PATCH 67/367 platform/x86: intel_scu_ipc: Fix interrupt support

In reply to Greg Kroah-Hartman

From: Mika Westerberg <[email protected]>

commit e48b72a568bbd641c91dad354138d3c17d03ee6f upstream.

Currently the driver has disabled interrupt support for Tangier but actually interrupt works just fine if the command is not written twice in a row. Also we need to ack the interrupt in the handler.

---
 drivers/platform/x86/intel_scu_ipc.c |   21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)
drivers/platform/x86/intel_scu_ipc.c +8 -13
@@ -67,26 +67,22 @@
 struct intel_scu_ipc_pdata_t {
 	u32 i2c_base;
 	u32 i2c_len;
-	u8 irq_mode;
 };
 
 static const struct intel_scu_ipc_pdata_t intel_scu_ipc_lincroft_pdata = {
 	.i2c_base = 0xff12b000,
 	.i2c_len = 0x10,
-	.irq_mode = 0,
 };
 
 /* Penwell and Cloverview */
 static const struct intel_scu_ipc_pdata_t intel_scu_ipc_penwell_pdata = {
 	.i2c_base = 0xff12b000,
 	.i2c_len = 0x10,
-	.irq_mode = 1,
 };
 
 static const struct intel_scu_ipc_pdata_t intel_scu_ipc_tangier_pdata = {
 	.i2c_base  = 0xff00d000,
 	.i2c_len = 0x10,
-	.irq_mode = 0,
 };
 
 struct intel_scu_ipc_dev {
@@ -99,6 +95,9 @@ struct intel_scu_ipc_dev {
 
 static struct intel_scu_ipc_dev  ipcdev; /* Only one for now */
 
+#define IPC_STATUS		0x04
+#define IPC_STATUS_IRQ		BIT(2)
+
 /*
  * IPC Read Buffer (Read Only):
  * 16 byte buffer for receiving data from SCU, if IPC command
@@ -120,11 +119,8 @@ static DEFINE_MUTEX(ipclock); /* lock us
  */
 static inline void ipc_command(struct intel_scu_ipc_dev *scu, u32 cmd)
 {
-	if (scu->irq_mode) {
-		reinit_completion(&scu->cmd_complete);
-		writel(cmd | IPC_IOC, scu->ipc_base);
-	}
-	writel(cmd, scu->ipc_base);
+	reinit_completion(&scu->cmd_complete);
+	writel(cmd | IPC_IOC, scu->ipc_base);
 }
 
 /*
@@ -610,9 +606,10 @@ EXPORT_SYMBOL(intel_scu_ipc_i2c_cntrl);
 static irqreturn_t ioc(int irq, void *dev_id)
 {
 	struct intel_scu_ipc_dev *scu = dev_id;
+	int status = ipc_read_status(scu);
 
-	if (scu->irq_mode)
-		complete(&scu->cmd_complete);
+	writel(status | IPC_STATUS_IRQ, scu->ipc_base + IPC_STATUS);
+	complete(&scu->cmd_complete);
 
 	return IRQ_HANDLED;
 }
@@ -638,8 +635,6 @@ static int ipc_probe(struct pci_dev *pde
 	if (!pdata)
 		return -ENODEV;
 
-	scu->irq_mode = pdata->irq_mode;
-
 	err = pcim_enable_device(pdev);
 	if (err)
 		return err;
author maintainer
#68 lore raw

PATCH 68/367 ALSA: hda: Apply aligned MMIO access only conditionally

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit 4d024fe8f806e20e577cc934204c5784c7063293 upstream.

It turned out that the recent simplification of HD-audio bus access helpers caused a regression on the virtual HD-audio device on QEMU with ARM platforms. The driver got a CORB/RIRB timeout and couldn't probe any codecs.

The essential difference that caused a problem was the enforced aligned MMIO accesses by simplification. Since snd-hda-tegra driver is enabled on ARM, it enables CONFIG_SND_HDA_ALIGNED_MMIO, which makes the all HD-audio drivers using the aligned MMIO accesses. While this is mandatory for snd-hda-tegra, it seems that snd-hda-intel on ARM gets broken by this access pattern.

For addressing the regression, this patch introduces a new flag, aligned_mmio, to hdac_bus object, and applies the aligned MMIO only when this flag is set. This change affects only platforms with CONFIG_SND_HDA_ALIGNED_MMIO set, i.e. mostly only for ARM platforms.

Unfortunately the patch became a big bigger than it should be, just because the former calls didn't take hdac_bus object in the argument, hence we had to extend the call patterns.

---
 include/sound/hdaudio.h   |   77 +++++++++++++++++++++++++++++++---------------
 sound/pci/hda/hda_tegra.c |    1 
 2 files changed, 54 insertions(+), 24 deletions(-)
include/sound/hdaudio.h +53 -24
@@ -8,6 +8,7 @@
 
 #include <linux/device.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/pm_runtime.h>
 #include <linux/timecounter.h>
 #include <sound/core.h>
@@ -330,6 +331,7 @@ struct hdac_bus {
 	bool chip_init:1;		/* h/w initialized */
 
 	/* behavior flags */
+	bool aligned_mmio:1;		/* aligned MMIO access */
 	bool sync_write:1;		/* sync after verb write */
 	bool use_posbuf:1;		/* use position buffer */
 	bool snoop:1;			/* enable snooping */
@@ -405,34 +407,61 @@ void snd_hdac_bus_free_stream_pages(stru
 unsigned int snd_hdac_aligned_read(void __iomem *addr, unsigned int mask);
 void snd_hdac_aligned_write(unsigned int val, void __iomem *addr,
 			    unsigned int mask);
-#define snd_hdac_reg_writeb(v, addr)	snd_hdac_aligned_write(v, addr, 0xff)
-#define snd_hdac_reg_writew(v, addr)	snd_hdac_aligned_write(v, addr, 0xffff)
-#define snd_hdac_reg_readb(addr)	snd_hdac_aligned_read(addr, 0xff)
-#define snd_hdac_reg_readw(addr)	snd_hdac_aligned_read(addr, 0xffff)
-#else /* CONFIG_SND_HDA_ALIGNED_MMIO */
-#define snd_hdac_reg_writeb(val, addr)	writeb(val, addr)
-#define snd_hdac_reg_writew(val, addr)	writew(val, addr)
-#define snd_hdac_reg_readb(addr)	readb(addr)
-#define snd_hdac_reg_readw(addr)	readw(addr)
-#endif /* CONFIG_SND_HDA_ALIGNED_MMIO */
-#define snd_hdac_reg_writel(val, addr)	writel(val, addr)
-#define snd_hdac_reg_readl(addr)	readl(addr)
+#define snd_hdac_aligned_mmio(bus)	(bus)->aligned_mmio
+#else
+#define snd_hdac_aligned_mmio(bus)	false
+#define snd_hdac_aligned_read(addr, mask)	0
+#define snd_hdac_aligned_write(val, addr, mask) do {} while (0)
+#endif
+
+static inline void snd_hdac_reg_writeb(struct hdac_bus *bus, void __iomem *addr,
+				       u8 val)
+{
+	if (snd_hdac_aligned_mmio(bus))
+		snd_hdac_aligned_write(val, addr, 0xff);
+	else
+		writeb(val, addr);
+}
+
+static inline void snd_hdac_reg_writew(struct hdac_bus *bus, void __iomem *addr,
+				       u16 val)
+{
+	if (snd_hdac_aligned_mmio(bus))
+		snd_hdac_aligned_write(val, addr, 0xffff);
+	else
+		writew(val, addr);
+}
+
+static inline u8 snd_hdac_reg_readb(struct hdac_bus *bus, void __iomem *addr)
+{
+	return snd_hdac_aligned_mmio(bus) ?
+		snd_hdac_aligned_read(addr, 0xff) : readb(addr);
+}
+
+static inline u16 snd_hdac_reg_readw(struct hdac_bus *bus, void __iomem *addr)
+{
+	return snd_hdac_aligned_mmio(bus) ?
+		snd_hdac_aligned_read(addr, 0xffff) : readw(addr);
+}
+
+#define snd_hdac_reg_writel(bus, addr, val)	writel(val, addr)
+#define snd_hdac_reg_readl(bus, addr)	readl(addr)
 
 /*
  * macros for easy use
  */
 #define _snd_hdac_chip_writeb(chip, reg, value) \
-	snd_hdac_reg_writeb(value, (chip)->remap_addr + (reg))
+	snd_hdac_reg_writeb(chip, (chip)->remap_addr + (reg), value)
 #define _snd_hdac_chip_readb(chip, reg) \
-	snd_hdac_reg_readb((chip)->remap_addr + (reg))
+	snd_hdac_reg_readb(chip, (chip)->remap_addr + (reg))
 #define _snd_hdac_chip_writew(chip, reg, value) \
-	snd_hdac_reg_writew(value, (chip)->remap_addr + (reg))
+	snd_hdac_reg_writew(chip, (chip)->remap_addr + (reg), value)
 #define _snd_hdac_chip_readw(chip, reg) \
-	snd_hdac_reg_readw((chip)->remap_addr + (reg))
+	snd_hdac_reg_readw(chip, (chip)->remap_addr + (reg))
 #define _snd_hdac_chip_writel(chip, reg, value) \
-	snd_hdac_reg_writel(value, (chip)->remap_addr + (reg))
+	snd_hdac_reg_writel(chip, (chip)->remap_addr + (reg), value)
 #define _snd_hdac_chip_readl(chip, reg) \
-	snd_hdac_reg_readl((chip)->remap_addr + (reg))
+	snd_hdac_reg_readl(chip, (chip)->remap_addr + (reg))
 
 /* read/write a register, pass without AZX_REG_ prefix */
 #define snd_hdac_chip_writel(chip, reg, value) \
@@ -540,17 +569,17 @@ int snd_hdac_get_stream_stripe_ctl(struc
  */
 /* read/write a register, pass without AZX_REG_ prefix */
 #define snd_hdac_stream_writel(dev, reg, value) \
-	snd_hdac_reg_writel(value, (dev)->sd_addr + AZX_REG_ ## reg)
+	snd_hdac_reg_writel((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg, value)
 #define snd_hdac_stream_writew(dev, reg, value) \
-	snd_hdac_reg_writew(value, (dev)->sd_addr + AZX_REG_ ## reg)
+	snd_hdac_reg_writew((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg, value)
 #define snd_hdac_stream_writeb(dev, reg, value) \
-	snd_hdac_reg_writeb(value, (dev)->sd_addr + AZX_REG_ ## reg)
+	snd_hdac_reg_writeb((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg, value)
 #define snd_hdac_stream_readl(dev, reg) \
-	snd_hdac_reg_readl((dev)->sd_addr + AZX_REG_ ## reg)
+	snd_hdac_reg_readl((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg)
 #define snd_hdac_stream_readw(dev, reg) \
-	snd_hdac_reg_readw((dev)->sd_addr + AZX_REG_ ## reg)
+	snd_hdac_reg_readw((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg)
 #define snd_hdac_stream_readb(dev, reg) \
-	snd_hdac_reg_readb((dev)->sd_addr + AZX_REG_ ## reg)
+	snd_hdac_reg_readb((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg)
 
 /* update a register, pass without AZX_REG_ prefix */
 #define snd_hdac_stream_updatel(dev, reg, mask, val) \
sound/pci/hda/hda_tegra.c +1 -0
@@ -398,6 +398,7 @@ static int hda_tegra_create(struct snd_c
 		return err;
 
 	chip->bus.needs_damn_long_delay = 1;
+	chip->bus.core.aligned_mmio = 1;
 
 	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
 	if (err < 0) {
author maintainer
#69 lore raw

PATCH 69/367 ALSA: hda: Add Clevo W65_67SB the power_save blacklist

In reply to Greg Kroah-Hartman

From: Hans de Goede <[email protected]>

commit d8feb6080bb0c9f4d799a423d9453048fdd06990 upstream.

Using HDA power-saving on the Clevo W65_67SB causes the first 0.5 seconds of audio to be missing every time audio starts playing.

This commit adds the Clevo W65_67SB the power_save blacklist to avoid this issue.

---
 sound/pci/hda/hda_intel.c |    2 ++
 1 file changed, 2 insertions(+)
sound/pci/hda/hda_intel.c +2 -0
@@ -2188,6 +2188,8 @@ static struct snd_pci_quirk power_save_b
 	/* https://bugzilla.redhat.com/show_bug.cgi?id=1581607 */
 	SND_PCI_QUIRK(0x1558, 0x3501, "Clevo W35xSS_370SS", 0),
 	/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
+	SND_PCI_QUIRK(0x1558, 0x6504, "Clevo W65_67SB", 0),
+	/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
 	SND_PCI_QUIRK(0x1028, 0x0497, "Dell Precision T3600", 0),
 	/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
 	/* Note the P55A-UD3 and Z87-D3HP share the subsys id for the HDA dev */
author maintainer
#70 lore raw

PATCH 70/367 ALSA: hda: Add JasperLake PCI ID and codec vid

In reply to Greg Kroah-Hartman

From: Yong Zhi <[email protected]>

commit 78be2228c15dd45865b102b29d72e721f0ace9b1 upstream.

Add HD Audio Device PCI ID and codec vendor_id for the Intel JasperLake REV2/A0 silicon.

---
 sound/pci/hda/hda_intel.c  |    2 ++
 sound/pci/hda/patch_hdmi.c |    1 +
 2 files changed, 3 insertions(+)
sound/pci/hda/hda_intel.c +2 -0
@@ -2449,6 +2449,8 @@ static const struct pci_device_id azx_id
 	/* Jasperlake */
 	{ PCI_DEVICE(0x8086, 0x38c8),
 	  .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
+	{ PCI_DEVICE(0x8086, 0x4dc8),
+	  .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
 	/* Tigerlake */
 	{ PCI_DEVICE(0x8086, 0xa0c8),
 	  .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
sound/pci/hda/patch_hdmi.c +1 -0
@@ -4250,6 +4250,7 @@ HDA_CODEC_ENTRY(0x8086280c, "Cannonlake
 HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI",	patch_i915_glk_hdmi),
 HDA_CODEC_ENTRY(0x8086280f, "Icelake HDMI",	patch_i915_icl_hdmi),
 HDA_CODEC_ENTRY(0x80862812, "Tigerlake HDMI",	patch_i915_tgl_hdmi),
+HDA_CODEC_ENTRY(0x8086281a, "Jasperlake HDMI",	patch_i915_icl_hdmi),
 HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI",	patch_generic_hdmi),
 HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI",	patch_i915_byt_hdmi),
 HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI",	patch_i915_byt_hdmi),
author maintainer
#71 lore raw

PATCH 71/367 ALSA: hda - Fix DP-MST support for NVIDIA codecs

In reply to Greg Kroah-Hartman

From: Nikhil Mahale <[email protected]>

commit c7e661a1c2ae98a4754db6a85fc686b4a89322ad upstream.

If dyn_pcm_assign is set, different jack objects are being created for pcm and pins.

If dyn_pcm_assign is set, generic_hdmi_build_jack() calls into add_hdmi_jack_kctl() to create and track separate jack object for pcm. Like sync_eld_via_acomp(), hdmi_present_sense_via_verbs() also need to report status change of the pcm jack.

Rename pin_idx_to_jack() to pin_idx_to_pcm_jack(). Update hdmi_present_sense_via_verbs() to report plug state of pcm jack object. Unlike sync_eld_via_acomp(), for !acomp drivers the pcm jack's plug state must be consistent with plug state of pin's jack.

---
 sound/pci/hda/patch_hdmi.c |   94 ++++++++++++++++++++++++++++++---------------
 1 file changed, 63 insertions(+), 31 deletions(-)
sound/pci/hda/patch_hdmi.c +63 -31
@@ -1547,6 +1547,34 @@ static bool update_eld(struct hda_codec
 	return eld_changed;
 }
 
+static struct snd_jack *pin_idx_to_pcm_jack(struct hda_codec *codec,
+					    struct hdmi_spec_per_pin *per_pin)
+{
+	struct hdmi_spec *spec = codec->spec;
+	struct snd_jack *jack = NULL;
+	struct hda_jack_tbl *jack_tbl;
+
+	/* if !dyn_pcm_assign, get jack from hda_jack_tbl
+	 * in !dyn_pcm_assign case, spec->pcm_rec[].jack is not
+	 * NULL even after snd_hda_jack_tbl_clear() is called to
+	 * free snd_jack. This may cause access invalid memory
+	 * when calling snd_jack_report
+	 */
+	if (per_pin->pcm_idx >= 0 && spec->dyn_pcm_assign) {
+		jack = spec->pcm_rec[per_pin->pcm_idx].jack;
+	} else if (!spec->dyn_pcm_assign) {
+		/*
+		 * jack tbl doesn't support DP MST
+		 * DP MST will use dyn_pcm_assign,
+		 * so DP MST will never come here
+		 */
+		jack_tbl = snd_hda_jack_tbl_get_mst(codec, per_pin->pin_nid,
+						    per_pin->dev_id);
+		if (jack_tbl)
+			jack = jack_tbl->jack;
+	}
+	return jack;
+}
 /* update ELD and jack state via HD-audio verbs */
 static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
 					 int repoll)
@@ -1568,6 +1596,7 @@ static bool hdmi_present_sense_via_verbs
 	int present;
 	bool ret;
 	bool do_repoll = false;
+	struct snd_jack *pcm_jack = NULL;
 
 	present = snd_hda_jack_pin_sense(codec, pin_nid, dev_id);
 
@@ -1595,10 +1624,19 @@ static bool hdmi_present_sense_via_verbs
 			do_repoll = true;
 	}
 
-	if (do_repoll)
+	if (do_repoll) {
 		schedule_delayed_work(&per_pin->work, msecs_to_jiffies(300));
-	else
+	} else {
+		/*
+		 * pcm_idx >=0 before update_eld() means it is in monitor
+		 * disconnected event. Jack must be fetched before
+		 * update_eld().
+		 */
+		pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
 		update_eld(codec, per_pin, eld);
+		if (!pcm_jack)
+			pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
+	}
 
 	ret = !repoll || !eld->monitor_present || eld->eld_valid;
 
@@ -1607,38 +1645,32 @@ static bool hdmi_present_sense_via_verbs
 		jack->block_report = !ret;
 		jack->pin_sense = (eld->monitor_present && eld->eld_valid) ?
 			AC_PINSENSE_PRESENCE : 0;
-	}
-	mutex_unlock(&per_pin->lock);
-	return ret;
-}
 
-static struct snd_jack *pin_idx_to_jack(struct hda_codec *codec,
-				 struct hdmi_spec_per_pin *per_pin)
-{
-	struct hdmi_spec *spec = codec->spec;
-	struct snd_jack *jack = NULL;
-	struct hda_jack_tbl *jack_tbl;
+		if (spec->dyn_pcm_assign && pcm_jack && !do_repoll) {
+			int state = 0;
+
+			if (jack->pin_sense & AC_PINSENSE_PRESENCE)
+				state = SND_JACK_AVOUT;
+			snd_jack_report(pcm_jack, state);
+		}
 
-	/* if !dyn_pcm_assign, get jack from hda_jack_tbl
-	 * in !dyn_pcm_assign case, spec->pcm_rec[].jack is not
-	 * NULL even after snd_hda_jack_tbl_clear() is called to
-	 * free snd_jack. This may cause access invalid memory
-	 * when calling snd_jack_report
-	 */
-	if (per_pin->pcm_idx >= 0 && spec->dyn_pcm_assign)
-		jack = spec->pcm_rec[per_pin->pcm_idx].jack;
-	else if (!spec->dyn_pcm_assign) {
 		/*
-		 * jack tbl doesn't support DP MST
-		 * DP MST will use dyn_pcm_assign,
-		 * so DP MST will never come here
+		 * snd_hda_jack_pin_sense() call at the beginning of this
+		 * function, updates jack->pins_sense and clears
+		 * jack->jack_dirty, therefore snd_hda_jack_report_sync() will
+		 * not override the jack->pin_sense.
+		 *
+		 * snd_hda_jack_report_sync() is superfluous for dyn_pcm_assign
+		 * case. The jack->pin_sense update was already performed, and
+		 * hda_jack->jack is NULL for dyn_pcm_assign.
+		 *
+		 * Don't call snd_hda_jack_report_sync() for
+		 * dyn_pcm_assign.
 		 */
-		jack_tbl = snd_hda_jack_tbl_get_mst(codec, per_pin->pin_nid,
-						    per_pin->dev_id);
-		if (jack_tbl)
-			jack = jack_tbl->jack;
+		ret = ret && !spec->dyn_pcm_assign;
 	}
-	return jack;
+	mutex_unlock(&per_pin->lock);
+	return ret;
 }
 
 /* update ELD and jack state via audio component */
@@ -1674,10 +1706,10 @@ static void sync_eld_via_acomp(struct hd
 	/* pcm_idx >=0 before update_eld() means it is in monitor
 	 * disconnected event. Jack must be fetched before update_eld()
 	 */
-	jack = pin_idx_to_jack(codec, per_pin);
+	jack = pin_idx_to_pcm_jack(codec, per_pin);
 	changed = update_eld(codec, per_pin, eld);
 	if (jack == NULL)
-		jack = pin_idx_to_jack(codec, per_pin);
+		jack = pin_idx_to_pcm_jack(codec, per_pin);
 	if (changed && jack)
 		snd_jack_report(jack,
 				(eld->monitor_present && eld->eld_valid) ?
author maintainer
#72 lore raw

PATCH 72/367 arm64: acpi: fix DAIF manipulation with pNMI

In reply to Greg Kroah-Hartman

From: Mark Rutland <[email protected]>

commit e533dbe9dcb199bb637a2c465f3a6e70564994fe upstream.

Since commit:

d44f1b8dd7e66d80 ("arm64: KVM/mm: Move SEA handling behind a single 'claim' interface")

... the top-level APEI SEA handler has the shape:

1. current_flags = arch_local_save_flags()
2. local_daif_restore(DAIF_ERRCTX)
3. <GHES handler>
4. local_daif_restore(current_flags)

However, since commit:

4a503217ce37e1f4 ("arm64: irqflags: Use ICC_PMR_EL1 for interrupt masking")

... when pseudo-NMIs (pNMIs) are in use, arch_local_save_flags() will save the PMR value rather than the DAIF flags.

The combination of these two commits means that the APEI SEA handler will erroneously attempt to restore the PMR value into DAIF. Fix this by factoring local_daif_save_flags() out of local_daif_save(), so that we can consistently save DAIF in step #1, regardless of whether pNMIs are in use.

Both commits were introduced concurrently in v5.0.

Fixes 4a503217ce37e1f4 ("arm64: irqflags: Use ICC_PMR_EL1 for interrupt masking")
Fixes d44f1b8dd7e66d80 ("arm64: KVM/mm: Move SEA handling behind a single 'claim' interface")
Cc Catalin Marinas <[email protected]>
Cc James Morse <[email protected]>
Cc Julien Thierry <[email protected]>
Cc Will Deacon <[email protected]>
---
 arch/arm64/include/asm/daifflags.h |   11 ++++++++++-
 arch/arm64/kernel/acpi.c           |    2 +-
 2 files changed, 11 insertions(+), 2 deletions(-)
arch/arm64/include/asm/daifflags.h +10 -1
@@ -38,7 +38,7 @@ static inline void local_daif_mask(void)
 	trace_hardirqs_off();
 }
 
-static inline unsigned long local_daif_save(void)
+static inline unsigned long local_daif_save_flags(void)
 {
 	unsigned long flags;
 
@@ -50,6 +50,15 @@ static inline unsigned long local_daif_s
 			flags |= PSR_I_BIT;
 	}
 
+	return flags;
+}
+
+static inline unsigned long local_daif_save(void)
+{
+	unsigned long flags;
+
+	flags = local_daif_save_flags();
+
 	local_daif_mask();
 
 	return flags;
arch/arm64/kernel/acpi.c +1 -1
@@ -274,7 +274,7 @@ int apei_claim_sea(struct pt_regs *regs)
 	if (!IS_ENABLED(CONFIG_ACPI_APEI_GHES))
 		return err;
 
-	current_flags = arch_local_save_flags();
+	current_flags = local_daif_save_flags();
 
 	/*
 	 * SEA can interrupt SError, mask it and describe this as an NMI so
author maintainer
#73 lore raw

PATCH 73/367 KVM: arm64: Correct PSTATE on exception entry

In reply to Greg Kroah-Hartman

From: Mark Rutland <[email protected]>

commit a425372e733177eb0779748956bc16c85167af48 upstream.

When KVM injects an exception into a guest, it generates the PSTATE value from scratch, configuring PSTATE.{M[4:0],DAIF}, and setting all other bits to zero.

This isn't correct, as the architecture specifies that some PSTATE bits are (conditionally) cleared or set upon an exception, and others are unchanged from the original context.

This patch adds logic to match the architectural behaviour. To make this simple to follow/audit/extend, documentation references are provided, and bits are configured in order of their layout in SPSR_EL2. This layout can be seen in the diagram on ARM DDI 0487E.a page C5-429.

---
 arch/arm64/include/uapi/asm/ptrace.h |    1 
 arch/arm64/kvm/inject_fault.c        |   70 ++++++++++++++++++++++++++++++++---
 2 files changed, 66 insertions(+), 5 deletions(-)
arch/arm64/include/uapi/asm/ptrace.h +1 -0
@@ -49,6 +49,7 @@
 #define PSR_SSBS_BIT	0x00001000
 #define PSR_PAN_BIT	0x00400000
 #define PSR_UAO_BIT	0x00800000
+#define PSR_DIT_BIT	0x01000000
 #define PSR_V_BIT	0x10000000
 #define PSR_C_BIT	0x20000000
 #define PSR_Z_BIT	0x40000000
arch/arm64/kvm/inject_fault.c +65 -5

94 lines not on this page · raw message

author maintainer
#74 lore raw

PATCH 74/367 KVM: arm/arm64: Correct CPSR on exception entry

In reply to Greg Kroah-Hartman

From: Mark Rutland <[email protected]>

commit 3c2483f15499b877ccb53250d88addb8c91da147 upstream.

When KVM injects an exception into a guest, it generates the CPSR value from scratch, configuring CPSR.{M,A,I,T,E}, and setting all other bits to zero.

This isn't correct, as the architecture specifies that some CPSR bits are (conditionally) cleared or set upon an exception, and others are unchanged from the original context.

This patch adds logic to match the architectural behaviour. To make this simple to follow/audit/extend, documentation references are provided, and bits are configured in order of their layout in SPSR_EL2. This layout can be seen in the diagram on ARM DDI 0487E.a page C5-426.

Note that this code is used by both arm and arm64, and is intended to fuction with the SPSR_EL2 and SPSR_HYP layouts.

---
 arch/arm/include/asm/kvm_emulate.h |   12 ++++
 arch/arm64/include/asm/ptrace.h    |    1 
 virt/kvm/arm/aarch32.c             |  111 +++++++++++++++++++++++++++++++++----
 3 files changed, 114 insertions(+), 10 deletions(-)
arch/arm/include/asm/kvm_emulate.h +12 -0
@@ -14,13 +14,25 @@
 #include <asm/cputype.h>
 
 /* arm64 compatibility macros */
+#define PSR_AA32_MODE_FIQ	FIQ_MODE
+#define PSR_AA32_MODE_SVC	SVC_MODE
 #define PSR_AA32_MODE_ABT	ABT_MODE
 #define PSR_AA32_MODE_UND	UND_MODE
 #define PSR_AA32_T_BIT		PSR_T_BIT
+#define PSR_AA32_F_BIT		PSR_F_BIT
 #define PSR_AA32_I_BIT		PSR_I_BIT
 #define PSR_AA32_A_BIT		PSR_A_BIT
 #define PSR_AA32_E_BIT		PSR_E_BIT
 #define PSR_AA32_IT_MASK	PSR_IT_MASK
+#define PSR_AA32_GE_MASK	0x000f0000
+#define PSR_AA32_DIT_BIT	0x00200000
+#define PSR_AA32_PAN_BIT	0x00400000
+#define PSR_AA32_SSBS_BIT	0x00800000
+#define PSR_AA32_Q_BIT		PSR_Q_BIT
+#define PSR_AA32_V_BIT		PSR_V_BIT
+#define PSR_AA32_C_BIT		PSR_C_BIT
+#define PSR_AA32_Z_BIT		PSR_Z_BIT
+#define PSR_AA32_N_BIT		PSR_N_BIT
 
 unsigned long *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num);
 
arch/arm64/include/asm/ptrace.h +1 -0
@@ -62,6 +62,7 @@
 #define PSR_AA32_I_BIT		0x00000080
 #define PSR_AA32_A_BIT		0x00000100
 #define PSR_AA32_E_BIT		0x00000200
+#define PSR_AA32_PAN_BIT	0x00400000
 #define PSR_AA32_SSBS_BIT	0x00800000
 #define PSR_AA32_DIT_BIT	0x01000000
 #define PSR_AA32_Q_BIT		0x08000000
virt/kvm/arm/aarch32.c +101 -10

136 lines not on this page · raw message

author maintainer
#75 lore raw

PATCH 75/367 KVM: arm/arm64: Correct AArch32 SPSR on exception entry

In reply to Greg Kroah-Hartman

From: Mark Rutland <[email protected]>

commit 1cfbb484de158e378e8971ac40f3082e53ecca55 upstream.

Confusingly, there are three SPSR layouts that a kernel may need to deal with:

(1) An AArch64 SPSR_ELx view of an AArch64 pstate
(2) An AArch64 SPSR_ELx view of an AArch32 pstate
(3) An AArch32 SPSR_* view of an AArch32 pstate

When the KVM AArch32 support code deals with SPSR_{EL2,HYP}, it's either dealing with #2 or #3 consistently. On arm64 the PSR_AA32_* definitions match the AArch64 SPSR_ELx view, and on arm the PSR_AA32_* definitions match the AArch32 SPSR_* view.

However, when we inject an exception into an AArch32 guest, we have to synthesize the AArch32 SPSR_* that the guest will see. Thus, an AArch64 host needs to synthesize layout #3 from layout #2.

This patch adds a new host_spsr_to_spsr32() helper for this, and makes use of it in the KVM AArch32 support code. For arm64 we need to shuffle the DIT bit around, and remove the SS bit, while for arm we can use the value as-is.

I've open-coded the bit manipulation for now to avoid having to rework the existing PSR_* definitions into PSR64_AA32_* and PSR32_AA32_* definitions. I hope to perform a more thorough refactoring in future so that we can handle pstate view manipulation more consistently across the kernel tree.

---
 arch/arm/include/asm/kvm_emulate.h   |    5 +++++
 arch/arm64/include/asm/kvm_emulate.h |   32 ++++++++++++++++++++++++++++++++
 virt/kvm/arm/aarch32.c               |    6 +++---
 3 files changed, 40 insertions(+), 3 deletions(-)
arch/arm/include/asm/kvm_emulate.h +5 -0
@@ -53,6 +53,11 @@ static inline void vcpu_write_spsr(struc
 	*__vcpu_spsr(vcpu) = v;
 }
 
+static inline unsigned long host_spsr_to_spsr32(unsigned long spsr)
+{
+	return spsr;
+}
+
 static inline unsigned long vcpu_get_reg(struct kvm_vcpu *vcpu,
 					 u8 reg_num)
 {
arch/arm64/include/asm/kvm_emulate.h +32 -0
@@ -219,6 +219,38 @@ static inline void vcpu_write_spsr(struc
 		vcpu_gp_regs(vcpu)->spsr[KVM_SPSR_EL1] = v;
 }
 
+/*
+ * The layout of SPSR for an AArch32 state is different when observed from an
+ * AArch64 SPSR_ELx or an AArch32 SPSR_*. This function generates the AArch32
+ * view given an AArch64 view.
+ *
+ * In ARM DDI 0487E.a see:
+ *
+ * - The AArch64 view (SPSR_EL2) in section C5.2.18, page C5-426
+ * - The AArch32 view (SPSR_abt) in section G8.2.126, page G8-6256
+ * - The AArch32 view (SPSR_und) in section G8.2.132, page G8-6280
+ *
+ * Which show the following differences:
+ *
+ * | Bit | AA64 | AA32 | Notes                       |
+ * +-----+------+------+-----------------------------|
+ * | 24  | DIT  | J    | J is RES0 in ARMv8          |
+ * | 21  | SS   | DIT  | SS doesn't exist in AArch32 |
+ *
+ * ... and all other bits are (currently) common.
+ */
+static inline unsigned long host_spsr_to_spsr32(unsigned long spsr)
+{
+	const unsigned long overlap = BIT(24) | BIT(21);
+	unsigned long dit = !!(spsr & PSR_AA32_DIT_BIT);
+
+	spsr &= ~overlap;
+
+	spsr |= dit << 21;
+
+	return spsr;
+}
+
 static inline bool vcpu_mode_priv(const struct kvm_vcpu *vcpu)
 {
 	u32 mode;
virt/kvm/arm/aarch32.c +3 -3
@@ -129,15 +129,15 @@ static unsigned long get_except32_cpsr(s
 
 static void prepare_fault32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset)
 {
-	unsigned long new_spsr_value = *vcpu_cpsr(vcpu);
-	bool is_thumb = (new_spsr_value & PSR_AA32_T_BIT);
+	unsigned long spsr = *vcpu_cpsr(vcpu);
+	bool is_thumb = (spsr & PSR_AA32_T_BIT);
 	u32 return_offset = return_offsets[vect_offset >> 2][is_thumb];
 	u32 sctlr = vcpu_cp15(vcpu, c1_SCTLR);
 
 	*vcpu_cpsr(vcpu) = get_except32_cpsr(vcpu, mode);
 
 	/* Note: These now point to the banked copies */
-	vcpu_write_spsr(vcpu, new_spsr_value);
+	vcpu_write_spsr(vcpu, host_spsr_to_spsr32(spsr));
 	*vcpu_reg32(vcpu, 14) = *vcpu_pc(vcpu) + return_offset;
 
 	/* Branch to exception vector */
author maintainer
#76 lore raw

PATCH 76/367 KVM: arm64: Only sign-extend MMIO up to register width

In reply to Greg Kroah-Hartman

From: Christoffer Dall <[email protected]>

commit b6ae256afd32f96bec0117175b329d0dd617655e upstream.

On AArch64 you can do a sign-extended load to either a 32-bit or 64-bit register, and we should only sign extend the register up to the width of the register as specified in the operation (by using the 32-bit Wn or 64-bit Xn register specifier).

As it turns out, the architecture provides this decoding information in the SF ("Sixty-Four" -- how cute...) bit.

Let's take advantage of this with the usual 32-bit/64-bit header file dance and do the right thing on AArch64 hosts.

---
 arch/arm/include/asm/kvm_emulate.h   |    5 +++++
 arch/arm/include/asm/kvm_mmio.h      |    2 ++
 arch/arm64/include/asm/kvm_emulate.h |    5 +++++
 arch/arm64/include/asm/kvm_mmio.h    |    6 ++----
 virt/kvm/arm/mmio.c                  |    6 ++++++
 5 files changed, 20 insertions(+), 4 deletions(-)
arch/arm/include/asm/kvm_emulate.h +5 -0
@@ -199,6 +199,11 @@ static inline bool kvm_vcpu_dabt_issext(
 	return kvm_vcpu_get_hsr(vcpu) & HSR_SSE;
 }
 
+static inline bool kvm_vcpu_dabt_issf(const struct kvm_vcpu *vcpu)
+{
+	return false;
+}
+
 static inline int kvm_vcpu_dabt_get_rd(struct kvm_vcpu *vcpu)
 {
 	return (kvm_vcpu_get_hsr(vcpu) & HSR_SRT_MASK) >> HSR_SRT_SHIFT;
arch/arm/include/asm/kvm_mmio.h +2 -0
@@ -14,6 +14,8 @@
 struct kvm_decode {
 	unsigned long rt;
 	bool sign_extend;
+	/* Not used on 32-bit arm */
+	bool sixty_four;
 };
 
 void kvm_mmio_write_buf(void *buf, unsigned int len, unsigned long data);
arch/arm64/include/asm/kvm_emulate.h +5 -0
@@ -315,6 +315,11 @@ static inline bool kvm_vcpu_dabt_issext(
 	return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_SSE);
 }
 
+static inline bool kvm_vcpu_dabt_issf(const struct kvm_vcpu *vcpu)
+{
+	return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_SF);
+}
+
 static inline int kvm_vcpu_dabt_get_rd(const struct kvm_vcpu *vcpu)
 {
 	return (kvm_vcpu_get_hsr(vcpu) & ESR_ELx_SRT_MASK) >> ESR_ELx_SRT_SHIFT;
arch/arm64/include/asm/kvm_mmio.h +2 -4
@@ -10,13 +10,11 @@
 #include <linux/kvm_host.h>
 #include <asm/kvm_arm.h>
 
-/*
- * This is annoying. The mmio code requires this, even if we don't
- * need any decoding. To be fixed.
- */
 struct kvm_decode {
 	unsigned long rt;
 	bool sign_extend;
+	/* Witdth of the register accessed by the faulting instruction is 64-bits */
+	bool sixty_four;
 };
 
 void kvm_mmio_write_buf(void *buf, unsigned int len, unsigned long data);
virt/kvm/arm/mmio.c +6 -0
@@ -105,6 +105,9 @@ int kvm_handle_mmio_return(struct kvm_vc
 			data = (data ^ mask) - mask;
 		}
 
+		if (!vcpu->arch.mmio_decode.sixty_four)
+			data = data & 0xffffffff;
+
 		trace_kvm_mmio(KVM_TRACE_MMIO_READ, len, run->mmio.phys_addr,
 			       &data);
 		data = vcpu_data_host_to_guest(vcpu, data, len);
@@ -125,6 +128,7 @@ static int decode_hsr(struct kvm_vcpu *v
 	unsigned long rt;
 	int access_size;
 	bool sign_extend;
+	bool sixty_four;
 
 	if (kvm_vcpu_dabt_iss1tw(vcpu)) {
 		/* page table accesses IO mem: tell guest to fix its TTBR */
@@ -138,11 +142,13 @@ static int decode_hsr(struct kvm_vcpu *v
 
 	*is_write = kvm_vcpu_dabt_iswrite(vcpu);
 	sign_extend = kvm_vcpu_dabt_issext(vcpu);
+	sixty_four = kvm_vcpu_dabt_issf(vcpu);
 	rt = kvm_vcpu_dabt_get_rd(vcpu);
 
 	*len = access_size;
 	vcpu->arch.mmio_decode.sign_extend = sign_extend;
 	vcpu->arch.mmio_decode.rt = rt;
+	vcpu->arch.mmio_decode.sixty_four = sixty_four;
 
 	return 0;
 }
author maintainer
#77 lore raw

PATCH 77/367 MIPS: syscalls: fix indentation of the SYSNR message

In reply to Greg Kroah-Hartman

From: Alexander Lobakin <[email protected]>

commit 4f29ad200f7b40fbcf73cd65f95087535ba78380 upstream.

It also lacks a whitespace (copy'n'paste error?) and also messes up the output:

  SYSHDR  arch/mips/include/generated/uapi/asm/unistd_n32.h
  SYSHDR  arch/mips/include/generated/uapi/asm/unistd_n64.h
  SYSHDR  arch/mips/include/generated/uapi/asm/unistd_o32.h
  SYSNR  arch/mips/include/generated/uapi/asm/unistd_nr_n32.h
  SYSNR  arch/mips/include/generated/uapi/asm/unistd_nr_n64.h
  SYSNR  arch/mips/include/generated/uapi/asm/unistd_nr_o32.h

WRAP arch/mips/include/generated/uapi/asm/bpf_perf_event.h
WRAP arch/mips/include/generated/uapi/asm/ipcbuf.h

After:

  SYSHDR  arch/mips/include/generated/uapi/asm/unistd_n32.h
  SYSHDR  arch/mips/include/generated/uapi/asm/unistd_n64.h
  SYSHDR  arch/mips/include/generated/uapi/asm/unistd_o32.h
  SYSNR   arch/mips/include/generated/uapi/asm/unistd_nr_n32.h
  SYSNR   arch/mips/include/generated/uapi/asm/unistd_nr_n64.h
  SYSNR   arch/mips/include/generated/uapi/asm/unistd_nr_o32.h
  WRAP    arch/mips/include/generated/uapi/asm/bpf_perf_event.h
  WRAP    arch/mips/include/generated/uapi/asm/ipcbuf.h

Present since day 0 of syscall table generation introduction for MIPS.

Fixes 9bcbf97c6293 ("mips: add system call table generation support")
Cc <[email protected]> # v5.0+
Cc Ralf Baechle <[email protected]>
Cc James Hogan <[email protected]>
Cc Masahiro Yamada <[email protected]>
Cc Rob Herring <[email protected]>
---
 arch/mips/kernel/syscalls/Makefile |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/kernel/syscalls/Makefile +1 -1
@@ -18,7 +18,7 @@ quiet_cmd_syshdr = SYSHDR  $@
 		   '$(syshdr_pfx_$(basetarget))'		\
 		   '$(syshdr_offset_$(basetarget))'
 
-quiet_cmd_sysnr = SYSNR  $@
+quiet_cmd_sysnr = SYSNR   $@
       cmd_sysnr = $(CONFIG_SHELL) '$(sysnr)' '$<' '$@'		\
 		  '$(sysnr_abis_$(basetarget))'			\
 		  '$(sysnr_pfx_$(basetarget))'			\
author maintainer
#78 lore raw

PATCH 78/367 MIPS: fix indentation of the RELOCS message

In reply to Greg Kroah-Hartman

From: Alexander Lobakin <[email protected]>

commit a53998802e178451701d59d38e36f551422977ba upstream.

quiet_cmd_relocs lacks a whitespace which results in:

  LD      vmlinux
  SORTEX  vmlinux
  SYSMAP  System.map

RELOCS vmlinux
Building modules, stage 2.
MODPOST 64 modules

After this patch:

  LD      vmlinux
  SORTEX  vmlinux
  SYSMAP  System.map
  RELOCS  vmlinux

Building modules, stage 2.
MODPOST 64 modules

Typo is present in kernel tree since the introduction of relocatable kernel support in commit e818fac595ab ("MIPS: Generate relocation table when CONFIG_RELOCATABLE"), but the relocation scripts were moved to Makefile.postlink later with commit 44079d3509ae ("MIPS: Use Makefile.postlink to insert relocations into vmlinux").

Fixes 44079d3509ae ("MIPS: Use Makefile.postlink to insert relocations into vmlinux")
Cc <[email protected]> # v4.11+
[[email protected]: Fixup commit references in commit message.]
Cc Ralf Baechle <[email protected]>
Cc James Hogan <[email protected]>
Cc Masahiro Yamada <[email protected]>
Cc Rob Herring <[email protected]>
---
 arch/mips/Makefile.postlink |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/Makefile.postlink +1 -1
@@ -17,7 +17,7 @@ quiet_cmd_ls3_llsc = LLSCCHK $@
       cmd_ls3_llsc = $(CMD_LS3_LLSC) $@
 
 CMD_RELOCS = arch/mips/boot/tools/relocs
-quiet_cmd_relocs = RELOCS $@
+quiet_cmd_relocs = RELOCS  $@
       cmd_relocs = $(CMD_RELOCS) $@
 
 # `@true` prevents complaint when there is nothing to be done
author maintainer
#79 lore raw

PATCH 79/367 MIPS: boot: fix typo in vmlinux.lzma.its target

In reply to Greg Kroah-Hartman

From: Alexander Lobakin <[email protected]>

commit 16202c09577f3d0c533274c0410b7de05fb0d458 upstream.

Commit 92b34a976348 ("MIPS: boot: add missing targets for vmlinux.*.its") fixed constant rebuild of *.its files on every make invocation, but due to typo ("lzmo") it made no sense for vmlinux.lzma.its.

Fixes 92b34a976348 ("MIPS: boot: add missing targets for vmlinux.*.its")
Cc <[email protected]> # v4.19+
[[email protected]: s/invokation/invocation/]
Cc Ralf Baechle <[email protected]>
Cc James Hogan <[email protected]>
Cc Masahiro Yamada <[email protected]>
Cc Rob Herring <[email protected]>
---
 arch/mips/boot/Makefile |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/boot/Makefile +1 -1
@@ -123,7 +123,7 @@ $(obj)/vmlinux.its.S: $(addprefix $(srct
 targets += vmlinux.its
 targets += vmlinux.gz.its
 targets += vmlinux.bz2.its
-targets += vmlinux.lzmo.its
+targets += vmlinux.lzma.its
 targets += vmlinux.lzo.its
 
 quiet_cmd_cpp_its_S = ITS     $@
author maintainer
#80 lore raw

PATCH 80/367 MIPS: SGI-IP30: Check for valid pointer before using it

In reply to Greg Kroah-Hartman

From: Thomas Bogendoerfer <[email protected]>

commit c0e79fd89749b0cda1c72049e2772dd2eeada86f upstream.

Fix issue detected by Smatch:

./arch/mips/sgi-ip30/ip30-irq.c:236 heart_domain_free()
warn: variable dereferenced before check 'irqd' (see line 235)

Fixes 7505576d1c1a ("MIPS: add support for SGI Octane (IP30)")
Cc Ralf Baechle <[email protected]>
Cc James Hogan <[email protected]>
Cc <[email protected]> # v5.5+
---
 arch/mips/sgi-ip30/ip30-irq.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
arch/mips/sgi-ip30/ip30-irq.c +3 -2
@@ -232,9 +232,10 @@ static void heart_domain_free(struct irq
 		return;
 
 	irqd = irq_domain_get_irq_data(domain, virq);
-	clear_bit(irqd->hwirq, heart_irq_map);
-	if (irqd && irqd->chip_data)
+	if (irqd) {
+		clear_bit(irqd->hwirq, heart_irq_map);
 		kfree(irqd->chip_data);
+	}
 }
 
 static const struct irq_domain_ops heart_domain_ops = {
author maintainer
#81 lore raw

PATCH 81/367 MIPS: asm: local: add barriers for Loongson

In reply to Greg Kroah-Hartman

From: Wang Xuerui <[email protected]>

commit 3e86460ebe2340df6a33b35a55312cc369bdcbd0 upstream.

Somehow these LL/SC usages are not taken care of, breaking Loongson builds. Add the SYNCs appropriately.

---
 arch/mips/include/asm/local.h |    4 ++++
 1 file changed, 4 insertions(+)
arch/mips/include/asm/local.h +4 -0
@@ -37,6 +37,7 @@ static __inline__ long local_add_return(
 		__asm__ __volatile__(
 		"	.set	push					\n"
 		"	.set	arch=r4000				\n"
+			__SYNC(full, loongson3_war) "			\n"
 		"1:"	__LL	"%1, %2		# local_add_return	\n"
 		"	addu	%0, %1, %3				\n"
 			__SC	"%0, %2					\n"
@@ -52,6 +53,7 @@ static __inline__ long local_add_return(
 		__asm__ __volatile__(
 		"	.set	push					\n"
 		"	.set	"MIPS_ISA_ARCH_LEVEL"			\n"
+			__SYNC(full, loongson3_war) "			\n"
 		"1:"	__LL	"%1, %2		# local_add_return	\n"
 		"	addu	%0, %1, %3				\n"
 			__SC	"%0, %2					\n"
@@ -84,6 +86,7 @@ static __inline__ long local_sub_return(
 		__asm__ __volatile__(
 		"	.set	push					\n"
 		"	.set	arch=r4000				\n"
+			__SYNC(full, loongson3_war) "			\n"
 		"1:"	__LL	"%1, %2		# local_sub_return	\n"
 		"	subu	%0, %1, %3				\n"
 			__SC	"%0, %2					\n"
@@ -99,6 +102,7 @@ static __inline__ long local_sub_return(
 		__asm__ __volatile__(
 		"	.set	push					\n"
 		"	.set	"MIPS_ISA_ARCH_LEVEL"			\n"
+			__SYNC(full, loongson3_war) "			\n"
 		"1:"	__LL	"%1, %2		# local_sub_return	\n"
 		"	subu	%0, %1, %3				\n"
 			__SC	"%0, %2					\n"
author maintainer
#82 lore raw

PATCH 82/367 s390/mm: fix dynamic pagetable upgrade for hugetlbfs

In reply to Greg Kroah-Hartman

From: Gerald Schaefer <[email protected]>

commit 5f490a520bcb393389a4d44bec90afcb332eb112 upstream.

Commit ee71d16d22bb ("s390/mm: make TASK_SIZE independent from the number of page table levels") changed the logic of TASK_SIZE and also removed the arch_mmap_check() implementation for s390. This combination has a subtle effect on how get_unmapped_area() for hugetlbfs pages works. It is now possible that a user process establishes a hugetlbfs mapping at an address above 4 TB, without triggering a dynamic pagetable upgrade from 3 to 4 levels.

This is because hugetlbfs mappings will not use mm->get_unmapped_area, but rather file->f_op->get_unmapped_area, which currently is the generic implementation of hugetlb_get_unmapped_area() that does not know about s390 dynamic pagetable upgrades, but with the new definition of TASK_SIZE, it will now allow mappings above 4 TB.

Subsequent access to such a mapped address above 4 TB will result in a page fault loop, because the CPU cannot translate such a large address with 3 pagetable levels. The fault handler will try to map in a hugepage at the address, but due to the folded pagetable logic it will end up with creating entries in the 3 level pagetable, possibly overwriting existing mappings, and then it all repeats when the access is retried.

Apart from the page fault loop, this can have various nasty effects, e.g. kernel panic from one of the BUG_ON() checks in memory management code, or even data loss if an existing mapping gets overwritten.

Fix this by implementing HAVE_ARCH_HUGETLB_UNMAPPED_AREA support for s390, providing an s390 version for hugetlb_get_unmapped_area() with pagetable upgrade support similar to arch_get_unmapped_area(), which will then be used instead of the generic version.

Fixes ee71d16d22bb ("s390/mm: make TASK_SIZE independent from the number of page table levels")
Cc <[email protected]> # 4.12+
---
 arch/s390/include/asm/page.h |    2 
 arch/s390/mm/hugetlbpage.c   |  100 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 101 insertions(+), 1 deletion(-)
arch/s390/include/asm/page.h +2 -0
@@ -33,6 +33,8 @@
 #define ARCH_HAS_PREPARE_HUGEPAGE
 #define ARCH_HAS_HUGEPAGE_CLEAR_FLUSH
 
+#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
+
 #include <asm/setup.h>
 #ifndef __ASSEMBLY__
 
arch/s390/mm/hugetlbpage.c +99 -1

115 lines not on this page · raw message

author maintainer
#83 lore raw

PATCH 83/367 powerpc/mmu_gather: enable RCU_TABLE_FREE even for !SMP case

In reply to Greg Kroah-Hartman

From: Aneesh Kumar K.V <[email protected]>

commit 12e4d53f3f04e81f9e83d6fc10edc7314ab9f6b9 upstream.

Patch series "Fixup page directory freeing", v4.

This is a repost of patch series from Peter with the arch specific changes except ppc64 dropped. ppc64 changes are added here because we are redoing the patch series on top of ppc64 changes. This makes it easy to backport these changes. Only the first 2 patches need to be backported to stable.

The thing is, on anything SMP, freeing page directories should observe the exact same order as normal page freeing:

1) unhook page/directory
2) TLB invalidate
3) free page/directory

Without this, any concurrent page-table walk could end up with a Use-after-Free. This is esp. trivial for anything that has software page-table walkers (HAVE_FAST_GUP / software TLB fill) or the hardware caches partial page-walks (ie. caches page directories).

Even on UP this might give issues since mmu_gather is preemptible these days. An interrupt or preempted task accessing user pages might stumble into the free page if the hardware caches page directories.

This patch series fixes ppc64 and add generic MMU_GATHER changes to support the conversion of other architectures. I haven't added patches w.r.t other architecture because they are yet to be acked.

This patch (of 9):

A followup patch is going to make sure we correctly invalidate page walk cache before we free page table pages. In order to keep things simple enable RCU_TABLE_FREE even for !SMP so that we don't have to fixup the !SMP case differently in the followup patch

!SMP case is right now broken for radix translation w.r.t page walk cache flush. We can get interrupted in between page table free and that would imply we have page walk cache entries pointing to tables which got freed already. Michael said "both our platforms that run on Power9 force SMP on in Kconfig, so the !SMP case is unlikely to be a problem for anyone in practice, unless they've hacked their kernel to build it !SMP."

---
 arch/powerpc/Kconfig                         |    2 +-
 arch/powerpc/include/asm/book3s/32/pgalloc.h |    8 --------
 arch/powerpc/include/asm/book3s/64/pgalloc.h |    2 --
 arch/powerpc/include/asm/nohash/pgalloc.h    |    8 --------
 arch/powerpc/mm/book3s64/pgtable.c           |    7 -------
 5 files changed, 1 insertion(+), 26 deletions(-)
arch/powerpc/Kconfig +1 -1
@@ -222,7 +222,7 @@ config PPC
 	select HAVE_HARDLOCKUP_DETECTOR_PERF	if PERF_EVENTS && HAVE_PERF_EVENTS_NMI && !HAVE_HARDLOCKUP_DETECTOR_ARCH
 	select HAVE_PERF_REGS
 	select HAVE_PERF_USER_STACK_DUMP
-	select HAVE_RCU_TABLE_FREE		if SMP
+	select HAVE_RCU_TABLE_FREE
 	select HAVE_RCU_TABLE_NO_INVALIDATE	if HAVE_RCU_TABLE_FREE
 	select HAVE_MMU_GATHER_PAGE_SIZE
 	select HAVE_REGS_AND_STACK_ACCESS_API
arch/powerpc/include/asm/book3s/32/pgalloc.h +0 -8
@@ -49,7 +49,6 @@ static inline void pgtable_free(void *ta
 
 #define get_hugepd_cache_index(x)  (x)
 
-#ifdef CONFIG_SMP
 static inline void pgtable_free_tlb(struct mmu_gather *tlb,
 				    void *table, int shift)
 {
@@ -66,13 +65,6 @@ static inline void __tlb_remove_table(vo
 
 	pgtable_free(table, shift);
 }
-#else
-static inline void pgtable_free_tlb(struct mmu_gather *tlb,
-				    void *table, int shift)
-{
-	pgtable_free(table, shift);
-}
-#endif
 
 static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,
 				  unsigned long address)
arch/powerpc/include/asm/book3s/64/pgalloc.h +0 -2
@@ -19,9 +19,7 @@ extern struct vmemmap_backing *vmemmap_l
 extern pmd_t *pmd_fragment_alloc(struct mm_struct *, unsigned long);
 extern void pmd_fragment_free(unsigned long *);
 extern void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift);
-#ifdef CONFIG_SMP
 extern void __tlb_remove_table(void *_table);
-#endif
 void pte_frag_destroy(void *pte_frag);
 
 static inline pgd_t *radix__pgd_alloc(struct mm_struct *mm)
arch/powerpc/include/asm/nohash/pgalloc.h +0 -8
@@ -46,7 +46,6 @@ static inline void pgtable_free(void *ta
 
 #define get_hugepd_cache_index(x)	(x)
 
-#ifdef CONFIG_SMP
 static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift)
 {
 	unsigned long pgf = (unsigned long)table;
@@ -64,13 +63,6 @@ static inline void __tlb_remove_table(vo
 	pgtable_free(table, shift);
 }
 
-#else
-static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift)
-{
-	pgtable_free(table, shift);
-}
-#endif
-
 static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,
 				  unsigned long address)
 {
arch/powerpc/mm/book3s64/pgtable.c +0 -7
@@ -378,7 +378,6 @@ static inline void pgtable_free(void *ta
 	}
 }
 
-#ifdef CONFIG_SMP
 void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int index)
 {
 	unsigned long pgf = (unsigned long)table;
@@ -395,12 +394,6 @@ void __tlb_remove_table(void *_table)
 
 	return pgtable_free(table, index);
 }
-#else
-void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int index)
-{
-	return pgtable_free(table, index);
-}
-#endif
 
 #ifdef CONFIG_PROC_FS
 atomic_long_t direct_pages_count[MMU_PAGE_COUNT];
author maintainer
#84 lore raw

PATCH 84/367 powerpc/ptdump: Fix W+X verification

In reply to Greg Kroah-Hartman

From: Christophe Leroy <[email protected]>

commit d80ae83f1f932ab7af47b54d0d3bef4f4dba489f upstream.

Verification cannot rely on simple bit checking because on some platforms PAGE_RW is 0, checking that a page is not W means checking that PAGE_RO is set instead of checking that PAGE_RW is not set.

Use pte helpers instead of checking bits.

---
 arch/powerpc/mm/ptdump/ptdump.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
arch/powerpc/mm/ptdump/ptdump.c +3 -1
@@ -173,10 +173,12 @@ static void dump_addr(struct pg_state *s
 
 static void note_prot_wx(struct pg_state *st, unsigned long addr)
 {
+	pte_t pte = __pte(st->current_flags);
+
 	if (!IS_ENABLED(CONFIG_PPC_DEBUG_WX) || !st->check_wx)
 		return;
 
-	if (!((st->current_flags & pgprot_val(PAGE_KERNEL_X)) == pgprot_val(PAGE_KERNEL_X)))
+	if (!pte_write(pte) || !pte_exec(pte))
 		return;
 
 	WARN_ONCE(1, "powerpc/mm: Found insecure W+X mapping at address %p/%pS\n",
author maintainer
#85 lore raw

PATCH 85/367 powerpc/xmon: dont access ASDR in VMs

In reply to Greg Kroah-Hartman

From: Sukadev Bhattiprolu <[email protected]>

commit c2a20711fc181e7f22ee5c16c28cb9578af84729 upstream.

ASDR is HV-privileged and must only be accessed in HV-mode. Fixes a Program Check (0x700) when xmon in a VM dumps SPRs.

---
 arch/powerpc/xmon/xmon.c |    9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)
arch/powerpc/xmon/xmon.c +4 -5
@@ -1949,15 +1949,14 @@ static void dump_300_sprs(void)
 
 	printf("pidr   = %.16lx  tidr  = %.16lx\n",
 		mfspr(SPRN_PID), mfspr(SPRN_TIDR));
-	printf("asdr   = %.16lx  psscr = %.16lx\n",
-		mfspr(SPRN_ASDR), hv ? mfspr(SPRN_PSSCR)
-					: mfspr(SPRN_PSSCR_PR));
+	printf("psscr  = %.16lx\n",
+		hv ? mfspr(SPRN_PSSCR) : mfspr(SPRN_PSSCR_PR));
 
 	if (!hv)
 		return;
 
-	printf("ptcr   = %.16lx\n",
-		mfspr(SPRN_PTCR));
+	printf("ptcr   = %.16lx  asdr  = %.16lx\n",
+		mfspr(SPRN_PTCR), mfspr(SPRN_ASDR));
 #endif
 }
 
author maintainer
#86 lore raw

PATCH 86/367 powerpc/pseries: Advance pfn if section is not present in lmb_is_removable()

In reply to Greg Kroah-Hartman

From: Pingfan Liu <[email protected]>

commit fbee6ba2dca30d302efe6bddb3a886f5e964a257 upstream.

In lmb_is_removable(), if a section is not present, it should continue to test the rest of the sections in the block. But the current code fails to do so.

Fixes 51925fb3c5c9 ("powerpc/pseries: Implement memory hotplug remove in the kernel")
---
 arch/powerpc/platforms/pseries/hotplug-memory.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
arch/powerpc/platforms/pseries/hotplug-memory.c +3 -1
@@ -360,8 +360,10 @@ static bool lmb_is_removable(struct drme
 
 	for (i = 0; i < scns_per_block; i++) {
 		pfn = PFN_DOWN(phys_addr);
-		if (!pfn_present(pfn))
+		if (!pfn_present(pfn)) {
+			phys_addr += MIN_MEMORY_BLOCK_SIZE;
 			continue;
+		}
 
 		rc = rc && is_mem_section_removable(pfn, PAGES_PER_SECTION);
 		phys_addr += MIN_MEMORY_BLOCK_SIZE;
author maintainer
#87 lore raw

PATCH 87/367 powerpc/32s: Fix bad_kuap_fault()

In reply to Greg Kroah-Hartman

From: Christophe Leroy <[email protected]>

commit 6ec20aa2e510b6297906c45f009aa08b2d97269a upstream.

At the moment, bad_kuap_fault() reports a fault only if a bad access to userspace occurred while access to userspace was not granted.

But if a fault occurs for a write outside the allowed userspace segment(s) that have been unlocked, bad_kuap_fault() fails to detect it and the kernel loops forever in do_page_fault().

Fix it by checking that the accessed address is within the allowed range.

---
 arch/powerpc/include/asm/book3s/32/kup.h       |    9 +++++++--
 arch/powerpc/include/asm/book3s/64/kup-radix.h |    3 ++-
 arch/powerpc/include/asm/kup.h                 |    6 +++++-
 arch/powerpc/include/asm/nohash/32/kup-8xx.h   |    3 ++-
 arch/powerpc/mm/fault.c                        |    2 +-
 5 files changed, 17 insertions(+), 6 deletions(-)
arch/powerpc/include/asm/book3s/32/kup.h +7 -2
@@ -131,12 +131,17 @@ static inline void prevent_user_access(v
 	kuap_update_sr(mfsrin(addr) | SR_KS, addr, end);	/* set Ks */
 }
 
-static inline bool bad_kuap_fault(struct pt_regs *regs, bool is_write)
+static inline bool
+bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
 {
+	unsigned long begin = regs->kuap & 0xf0000000;
+	unsigned long end = regs->kuap << 28;
+
 	if (!is_write)
 		return false;
 
-	return WARN(!regs->kuap, "Bug: write fault blocked by segment registers !");
+	return WARN(address < begin || address >= end,
+		    "Bug: write fault blocked by segment registers !");
 }
 
 #endif /* CONFIG_PPC_KUAP */
arch/powerpc/include/asm/book3s/64/kup-radix.h +2 -1
@@ -95,7 +95,8 @@ static inline void prevent_user_access(v
 	set_kuap(AMR_KUAP_BLOCKED);
 }
 
-static inline bool bad_kuap_fault(struct pt_regs *regs, bool is_write)
+static inline bool
+bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
 {
 	return WARN(mmu_has_feature(MMU_FTR_RADIX_KUAP) &&
 		    (regs->kuap & (is_write ? AMR_KUAP_BLOCK_WRITE : AMR_KUAP_BLOCK_READ)),
arch/powerpc/include/asm/kup.h +5 -1
@@ -45,7 +45,11 @@ static inline void allow_user_access(voi
 				     unsigned long size) { }
 static inline void prevent_user_access(void __user *to, const void __user *from,
 				       unsigned long size) { }
-static inline bool bad_kuap_fault(struct pt_regs *regs, bool is_write) { return false; }
+static inline bool
+bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
+{
+	return false;
+}
 #endif /* CONFIG_PPC_KUAP */
 
 static inline void allow_read_from_user(const void __user *from, unsigned long size)
arch/powerpc/include/asm/nohash/32/kup-8xx.h +2 -1
@@ -46,7 +46,8 @@ static inline void prevent_user_access(v
 	mtspr(SPRN_MD_AP, MD_APG_KUAP);
 }
 
-static inline bool bad_kuap_fault(struct pt_regs *regs, bool is_write)
+static inline bool
+bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
 {
 	return WARN(!((regs->kuap ^ MD_APG_KUAP) & 0xf0000000),
 		    "Bug: fault blocked by AP register !");
arch/powerpc/mm/fault.c +1 -1
@@ -233,7 +233,7 @@ static bool bad_kernel_fault(struct pt_r
 
 	// Read/write fault in a valid region (the exception table search passed
 	// above), but blocked by KUAP is bad, it can never succeed.
-	if (bad_kuap_fault(regs, is_write))
+	if (bad_kuap_fault(regs, address, is_write))
 		return true;
 
 	// What's left? Kernel fault on user in well defined regions (extable
author maintainer
#88 lore raw

PATCH 88/367 powerpc/32s: Fix CPU wake-up from sleep mode

In reply to Greg Kroah-Hartman

From: Christophe Leroy <[email protected]>

commit 9933819099c4600b41a042f27a074470a43cf6b9 upstream.

Commit f7354ccac844 ("powerpc/32: Remove CURRENT_THREAD_INFO and rename TI_CPU") broke the CPU wake-up from sleep mode (i.e. when _TLF_SLEEPING is set) by delaying the tovirt(r2, r2).

This is because r2 is not restored by fast_exception_return. It used to work (by chance ?) because CPU wake-up interrupt never comes from user, so r2 is expected to point to 'current' on return.

Commit e2fb9f544431 ("powerpc/32: Prepare for Kernel Userspace Access Protection") broke it even more by clobbering r0 which is not restored by fast_exception_return either.

Use r6 instead of r0. This is possible because r3-r6 are restored by fast_exception_return and only r3-r5 are used for exception arguments.

For r2 it could be converted back to virtual address, but stay on the safe side and restore it from the stack instead. It should be live in the cache at that moment, so loading from the stack should make no difference compared to converting it from phys to virt.

Fixes f7354ccac844 ("powerpc/32: Remove CURRENT_THREAD_INFO and rename TI_CPU")
Fixes e2fb9f544431 ("powerpc/32: Prepare for Kernel Userspace Access Protection")
---
 arch/powerpc/kernel/entry_32.S |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/powerpc/kernel/entry_32.S +2 -1
@@ -179,7 +179,7 @@ transfer_to_handler:
 2:	/* if from kernel, check interrupted DOZE/NAP mode and
          * check for stack overflow
          */
-	kuap_save_and_lock r11, r12, r9, r2, r0
+	kuap_save_and_lock r11, r12, r9, r2, r6
 	addi	r2, r12, -THREAD
 	lwz	r9,KSP_LIMIT(r12)
 	cmplw	r1,r9			/* if r1 <= ksp_limit */
@@ -284,6 +284,7 @@ reenable_mmu:
 	rlwinm	r9,r9,0,~MSR_EE
 	lwz	r12,_LINK(r11)		/* and return to address in LR */
 	kuap_restore r11, r2, r3, r4, r5
+	lwz	r2, GPR2(r11)
 	b	fast_exception_return
 #endif
 
author maintainer
#89 lore raw

PATCH 89/367 PCI/ATS: Use PF PASID for VFs

In reply to Greg Kroah-Hartman

From: Kuppuswamy Sathyanarayanan <[email protected]>

commit 2e34673be0bd6bb0c6c496a861cbc3f7431e7ce3 upstream.

Per PCIe r5.0, sec 9.3.7.14, if a PF implements the PASID Capability, the PF PASID configuration is shared by its VFs, and VFs must not implement their own PASID Capability. But commit 751035b8dc06 ("PCI/ATS: Cache PASID Capability offset") changed pci_max_pasids() and pci_pasid_features() to use the PASID Capability of the VF device instead of the associated PF device. This leads to IOMMU bind failures when pci_max_pasids() and pci_pasid_features() are called for VFs.

In pci_max_pasids() and pci_pasid_features(), always use the PF PASID Capability.

---
 drivers/pci/ats.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/pci/ats.c +4 -2
@@ -424,11 +424,12 @@ void pci_restore_pasid_state(struct pci_
 int pci_pasid_features(struct pci_dev *pdev)
 {
 	u16 supported;
-	int pasid = pdev->pasid_cap;
+	int pasid;
 
 	if (pdev->is_virtfn)
 		pdev = pci_physfn(pdev);
 
+	pasid = pdev->pasid_cap;
 	if (!pasid)
 		return -EINVAL;
 
@@ -451,11 +452,12 @@ int pci_pasid_features(struct pci_dev *p
 int pci_max_pasids(struct pci_dev *pdev)
 {
 	u16 supported;
-	int pasid = pdev->pasid_cap;
+	int pasid;
 
 	if (pdev->is_virtfn)
 		pdev = pci_physfn(pdev);
 
+	pasid = pdev->pasid_cap;
 	if (!pasid)
 		return -EINVAL;
 
author maintainer
#90 lore raw

PATCH 90/367 PCI: tegra: Fix return value check of pm_runtime_get_sync()

In reply to Greg Kroah-Hartman

From: David Engraf <[email protected]>

commit 885199148442f56b880995d703d2ed03b6481a3c upstream.

pm_runtime_get_sync() returns the device's usage counter. This might be >0 if the device is already powered up or CONFIG_PM is disabled.

Abort probe function on real error only.

---
 drivers/pci/controller/pci-tegra.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/controller/pci-tegra.c +1 -1
@@ -2798,7 +2798,7 @@ static int tegra_pcie_probe(struct platf
 
 	pm_runtime_enable(pcie->dev);
 	err = pm_runtime_get_sync(pcie->dev);
-	if (err) {
+	if (err < 0) {
 		dev_err(dev, "fail to enable pcie controller: %d\n", err);
 		goto teardown_msi;
 	}
author maintainer
#91 lore raw

PATCH 91/367 PCI: keystone: Fix outbound region mapping

In reply to Greg Kroah-Hartman

From: Yurii Monakov <[email protected]>

commit 2d0c3fbe43fa0e6fcb7a6c755c5f4cd702c0d2f4 upstream.

The Keystone outbound Address Translation Unit (ATU) maps PCI MMIO space in 8 MB windows. When programming the ATU windows, we previously incremented the starting address by 8, not 8 MB, so all the windows were mapped to the first 8 MB. Therefore, only 8 MB of MMIO space was accessible.

Update the loop so it increments the starting address by 8 MB, not 8, so more MMIO space is accessible.

---
 drivers/pci/controller/dwc/pci-keystone.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/controller/dwc/pci-keystone.c +1 -1
@@ -422,7 +422,7 @@ static void ks_pcie_setup_rc_app_regs(st
 				   lower_32_bits(start) | OB_ENABLEN);
 		ks_pcie_app_writel(ks_pcie, OB_OFFSET_HI(i),
 				   upper_32_bits(start));
-		start += OB_WIN_SIZE;
+		start += OB_WIN_SIZE * SZ_1M;
 	}
 
 	val = ks_pcie_app_readl(ks_pcie, CMD_STATUS);
author maintainer
#92 lore raw

PATCH 92/367 PCI: keystone: Fix link training retries initiation

In reply to Greg Kroah-Hartman

From: Yurii Monakov <[email protected]>

commit 6df19872d881641e6394f93ef2938cffcbdae5bb upstream.

ks_pcie_stop_link() function does not clear LTSSM_EN_VAL bit so link training was not triggered more than once after startup. In configurations where link can be unstable during early boot, for example, under low temperature, it will never be established.

Fixes 0c4ffcfe1fbc ("PCI: keystone: Add TI Keystone PCIe driver")
---
 drivers/pci/controller/dwc/pci-keystone.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/controller/dwc/pci-keystone.c +1 -1
@@ -510,7 +510,7 @@ static void ks_pcie_stop_link(struct dw_
 	/* Disable Link training */
 	val = ks_pcie_app_readl(ks_pcie, CMD_STATUS);
 	val &= ~LTSSM_EN_VAL;
-	ks_pcie_app_writel(ks_pcie, CMD_STATUS, LTSSM_EN_VAL | val);
+	ks_pcie_app_writel(ks_pcie, CMD_STATUS, val);
 }
 
 static int ks_pcie_start_link(struct dw_pcie *pci)
author maintainer
#93 lore raw

PATCH 93/367 PCI: keystone: Fix error handling when "num-viewport" DT property is not populated

In reply to Greg Kroah-Hartman

From: Kishon Vijay Abraham I <[email protected]>

commit b0de922af53eede340986a2d05b6cd4b6d6efa43 upstream.

Fix error handling when "num-viewport" DT property is not populated.

Fixes 23284ad677a9 ("PCI: keystone: Add support for PCIe EP in AM654x Platforms")
---
 drivers/pci/controller/dwc/pci-keystone.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/controller/dwc/pci-keystone.c +1 -1
@@ -1354,7 +1354,7 @@ static int __init ks_pcie_probe(struct p
 		ret = of_property_read_u32(np, "num-viewport", &num_viewport);
 		if (ret < 0) {
 			dev_err(dev, "unable to read *num-viewport* property\n");
-			return ret;
+			goto err_get_sync;
 		}
 
 		/*
author maintainer
#94 lore raw

PATCH 94/367 mmc: spi: Toggle SPI polarity, do not hardcode it

In reply to Greg Kroah-Hartman

From: Linus Walleij <[email protected]>

commit af3ed119329cf9690598c5a562d95dfd128e91d6 upstream.

The code in mmc_spi_initsequence() tries to send a burst with high chipselect and for this reason hardcodes the device into SPI_CS_HIGH.

This is not good because the SPI_CS_HIGH flag indicates logical "asserted" CS not always the physical level. In some cases the signal is inverted in the GPIO library and in that case SPI_CS_HIGH is already set, and enforcing SPI_CS_HIGH again will actually drive it low.

Instead of hard-coding this, toggle the polarity so if the default is LOW it goes high to assert chipselect but if it is already high then toggle it low instead.

---
 drivers/mmc/host/mmc_spi.c |   11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/mmc/host/mmc_spi.c +8 -3
@@ -1134,17 +1134,22 @@ static void mmc_spi_initsequence(struct
 	 * SPI protocol.  Another is that when chipselect is released while
 	 * the card returns BUSY status, the clock must issue several cycles
 	 * with chipselect high before the card will stop driving its output.
+	 *
+	 * SPI_CS_HIGH means "asserted" here. In some cases like when using
+	 * GPIOs for chip select, SPI_CS_HIGH is set but this will be logically
+	 * inverted by gpiolib, so if we want to ascertain to drive it high
+	 * we should toggle the default with an XOR as we do here.
 	 */
-	host->spi->mode |= SPI_CS_HIGH;
+	host->spi->mode ^= SPI_CS_HIGH;
 	if (spi_setup(host->spi) != 0) {
 		/* Just warn; most cards work without it. */
 		dev_warn(&host->spi->dev,
 				"can't change chip-select polarity\n");
-		host->spi->mode &= ~SPI_CS_HIGH;
+		host->spi->mode ^= SPI_CS_HIGH;
 	} else {
 		mmc_spi_readbytes(host, 18);
 
-		host->spi->mode &= ~SPI_CS_HIGH;
+		host->spi->mode ^= SPI_CS_HIGH;
 		if (spi_setup(host->spi) != 0) {
 			/* Wot, we can't get the same setup we had before? */
 			dev_err(&host->spi->dev,
author maintainer
#95 lore raw

PATCH 95/367 ACPI: video: Do not export a non working backlight interface on MSI MS-7721 boards

In reply to Greg Kroah-Hartman

From: Hans de Goede <[email protected]>

commit d21a91629f4b8e794fc4c0e0c17c85cedf1d806c upstream.

Despite our heuristics to not wrongly export a non working ACPI backlight interface on desktop machines, we still end up exporting one on desktops using a motherboard from the MSI MS-7721 series.

I've looked at improving the heuristics, but in this case a quirk seems to be the only way to solve this.

While at it also add a comment to separate the video_detect_force_none entries in the video_detect_dmi_table from other type of entries, as we already do for the other entry types.

---
 drivers/acpi/video_detect.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)
drivers/acpi/video_detect.c +13 -0
@@ -336,6 +336,11 @@ static const struct dmi_system_id video_
 		DMI_MATCH(DMI_PRODUCT_NAME, "Precision 7510"),
 		},
 	},
+
+	/*
+	 * Desktops which falsely report a backlight and which our heuristics
+	 * for this do not catch.
+	 */
 	{
 	 .callback = video_detect_force_none,
 	 .ident = "Dell OptiPlex 9020M",
@@ -344,6 +349,14 @@ static const struct dmi_system_id video_
 		DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 9020M"),
 		},
 	},
+	{
+	 .callback = video_detect_force_none,
+	 .ident = "MSI MS-7721",
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "MSI"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "MS-7721"),
+		},
+	},
 	{ },
 };
 
author maintainer
#96 lore raw

PATCH 96/367 ACPI / battery: Deal with design or full capacity being reported as -1

In reply to Greg Kroah-Hartman

From: Hans de Goede <[email protected]>

commit cc99f0ad52467028cb1251160f23ad4bb65baf20 upstream.

Commit b41901a2cf06 ("ACPI / battery: Do not export energy_full[_design] on devices without full_charge_capacity") added support for some (broken) devices which always report 0 for both design- and full_charge-capacity.

This assumes that if the capacity is not being reported it is 0. The ThunderSoft TS178 tablet's _BIX implementation falsifies this assumption. It reports ACPI_BATTERY_VALUE_UNKNOWN (-1) as full_charge_capacity, which we treat as a valid value which causes several problems.

This commit fixes this by adding a new ACPI_BATTERY_CAPACITY_VALID() helper which checks that the value is not 0 and not -1; and using this whenever we need to test if either design_capacity or full_charge_capacity is valid.

Fixes b41901a2cf06 ("ACPI / battery: Do not export energy_full[_design] on devices without full_charge_capacity")
Cc 4.19+ <[email protected]> # 4.19+
---
 drivers/acpi/battery.c |   19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)
drivers/acpi/battery.c +12 -7
@@ -38,6 +38,8 @@
 #define PREFIX "ACPI: "
 
 #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
+#define ACPI_BATTERY_CAPACITY_VALID(capacity) \
+	((capacity) != 0 && (capacity) != ACPI_BATTERY_VALUE_UNKNOWN)
 
 #define ACPI_BATTERY_DEVICE_NAME	"Battery"
 
@@ -192,7 +194,8 @@ static int acpi_battery_is_charged(struc
 
 static bool acpi_battery_is_degraded(struct acpi_battery *battery)
 {
-	return battery->full_charge_capacity && battery->design_capacity &&
+	return ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) &&
+		ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity) &&
 		battery->full_charge_capacity < battery->design_capacity;
 }
 
@@ -263,14 +266,14 @@ static int acpi_battery_get_property(str
 		break;
 	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
 	case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
-		if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+		if (!ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity))
 			ret = -ENODEV;
 		else
 			val->intval = battery->design_capacity * 1000;
 		break;
 	case POWER_SUPPLY_PROP_CHARGE_FULL:
 	case POWER_SUPPLY_PROP_ENERGY_FULL:
-		if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+		if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity))
 			ret = -ENODEV;
 		else
 			val->intval = battery->full_charge_capacity * 1000;
@@ -283,11 +286,12 @@ static int acpi_battery_get_property(str
 			val->intval = battery->capacity_now * 1000;
 		break;
 	case POWER_SUPPLY_PROP_CAPACITY:
-		if (battery->capacity_now && battery->full_charge_capacity)
+		if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN ||
+		    !ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity))
+			ret = -ENODEV;
+		else
 			val->intval = battery->capacity_now * 100/
 					battery->full_charge_capacity;
-		else
-			val->intval = 0;
 		break;
 	case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
 		if (battery->state & ACPI_BATTERY_STATE_CRITICAL)
@@ -799,7 +803,8 @@ static int sysfs_add_battery(struct acpi
 		battery->bat_desc.properties = charge_battery_props;
 		battery->bat_desc.num_properties =
 			ARRAY_SIZE(charge_battery_props);
-	} else if (battery->full_charge_capacity == 0) {
+	} else if (!ACPI_BATTERY_CAPACITY_VALID(
+					battery->full_charge_capacity)) {
 		battery->bat_desc.properties =
 			energy_battery_full_cap_broken_props;
 		battery->bat_desc.num_properties =
author maintainer
#97 lore raw

PATCH 97/367 ACPI / battery: Use design-cap for capacity calculations if full-cap is not available

In reply to Greg Kroah-Hartman

From: Hans de Goede <[email protected]>

commit 5b74d1d16e2f5753fcbdecd6771b2d8370dda414 upstream.

The ThunderSoft TS178 tablet's _BIX implementation reports design_capacity but not full_charge_capacity.

Before this commit this would cause us to return -ENODEV for the capacity attribute, which userspace does not like. Specifically upower does this:

        if (sysfs_file_exists (native_path, "capacity")) {
                percentage = sysfs_get_double (native_path, "capacity");

Where the sysfs_get_double() helper returns 0 when we return -ENODEV, so the battery always reads 0% if we return -ENODEV.

This commit fixes this by using the design-capacity instead of the full-charge-capacity when the full-charge-capacity is not available.

Fixes b41901a2cf06 ("ACPI / battery: Do not export energy_full[_design] on devices without full_charge_capacity")
Cc 4.19+ <[email protected]> # 4.19+
---
 drivers/acpi/battery.c |   11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/acpi/battery.c +8 -3
@@ -217,7 +217,7 @@ static int acpi_battery_get_property(str
 				     enum power_supply_property psp,
 				     union power_supply_propval *val)
 {
-	int ret = 0;
+	int full_capacity = ACPI_BATTERY_VALUE_UNKNOWN, ret = 0;
 	struct acpi_battery *battery = to_acpi_battery(psy);
 
 	if (acpi_battery_present(battery)) {
@@ -286,12 +286,17 @@ static int acpi_battery_get_property(str
 			val->intval = battery->capacity_now * 1000;
 		break;
 	case POWER_SUPPLY_PROP_CAPACITY:
+		if (ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity))
+			full_capacity = battery->full_charge_capacity;
+		else if (ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity))
+			full_capacity = battery->design_capacity;
+
 		if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN ||
-		    !ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity))
+		    full_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
 			ret = -ENODEV;
 		else
 			val->intval = battery->capacity_now * 100/
-					battery->full_charge_capacity;
+					full_capacity;
 		break;
 	case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
 		if (battery->state & ACPI_BATTERY_STATE_CRITICAL)
author maintainer
#98 lore raw

PATCH 98/367 ACPI / battery: Deal better with neither design nor full capacity not being reported

In reply to Greg Kroah-Hartman

From: Hans de Goede <[email protected]>

commit ff3154d1d89a2343fd5f82e65bc0cf1d4e6659b3 upstream.

Commit b41901a2cf06 ("ACPI / battery: Do not export energy_full[_design] on devices without full_charge_capacity") added support for some (broken) devices which always report 0 for both design_capacity and full_charge_capacity.

Since the device that commit was written as a fix for is not reporting any form of "full" capacity we cannot calculate the value for the POWER_SUPPLY_PROP_CAPACITY, this is worked around by using an alternative array of available properties which does not contain this property.

This is necessary because userspace (upower) treats us returning -ENODEV as 0 and then typically will trigger an emergency shutdown because of that. Userspace does not do this if the capacity sysfs attribute is not present at all.

There are two potential problems with that commit:
1) It assumes that both full_charge- and design-capacity are broken at the same time and only checks if full_charge- is broken.
2) It assumes that this only ever happens for devices which report energy units rather then charge units.

This commit fixes both issues by only using the alternative array of available properties if both full_charge- and design-capacity are broken and by also adding an alternative array of available properties for devices using mA units.

Fixes b41901a2cf06 ("ACPI / battery: Do not export energy_full[_design] on devices without full_charge_capacity")
Cc 4.19+ <[email protected]> # 4.19+
---
 drivers/acpi/battery.c |   51 +++++++++++++++++++++++++++++++++++++------------
 1 file changed, 39 insertions(+), 12 deletions(-)
drivers/acpi/battery.c +39 -12
@@ -342,6 +342,20 @@ static enum power_supply_property charge
 	POWER_SUPPLY_PROP_SERIAL_NUMBER,
 };
 
+static enum power_supply_property charge_battery_full_cap_broken_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_CYCLE_COUNT,
+	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_CHARGE_NOW,
+	POWER_SUPPLY_PROP_MODEL_NAME,
+	POWER_SUPPLY_PROP_MANUFACTURER,
+	POWER_SUPPLY_PROP_SERIAL_NUMBER,
+};
+
 static enum power_supply_property energy_battery_props[] = {
 	POWER_SUPPLY_PROP_STATUS,
 	POWER_SUPPLY_PROP_PRESENT,
@@ -803,21 +817,34 @@ static void __exit battery_hook_exit(voi
 static int sysfs_add_battery(struct acpi_battery *battery)
 {
 	struct power_supply_config psy_cfg = { .drv_data = battery, };
+	bool full_cap_broken = false;
+
+	if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) &&
+	    !ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity))
+		full_cap_broken = true;
 
 	if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) {
-		battery->bat_desc.properties = charge_battery_props;
-		battery->bat_desc.num_properties =
-			ARRAY_SIZE(charge_battery_props);
-	} else if (!ACPI_BATTERY_CAPACITY_VALID(
-					battery->full_charge_capacity)) {
-		battery->bat_desc.properties =
-			energy_battery_full_cap_broken_props;
-		battery->bat_desc.num_properties =
-			ARRAY_SIZE(energy_battery_full_cap_broken_props);
+		if (full_cap_broken) {
+			battery->bat_desc.properties =
+			    charge_battery_full_cap_broken_props;
+			battery->bat_desc.num_properties =
+			    ARRAY_SIZE(charge_battery_full_cap_broken_props);
+		} else {
+			battery->bat_desc.properties = charge_battery_props;
+			battery->bat_desc.num_properties =
+			    ARRAY_SIZE(charge_battery_props);
+		}
 	} else {
-		battery->bat_desc.properties = energy_battery_props;
-		battery->bat_desc.num_properties =
-			ARRAY_SIZE(energy_battery_props);
+		if (full_cap_broken) {
+			battery->bat_desc.properties =
+			    energy_battery_full_cap_broken_props;
+			battery->bat_desc.num_properties =
+			    ARRAY_SIZE(energy_battery_full_cap_broken_props);
+		} else {
+			battery->bat_desc.properties = energy_battery_props;
+			battery->bat_desc.num_properties =
+			    ARRAY_SIZE(energy_battery_props);
+		}
 	}
 
 	battery->bat_desc.name = acpi_device_bid(battery->device);
author maintainer
#99 lore raw

PATCH 99/367 smb3: fix default permissions on new files when mounting with modefromsid

In reply to Greg Kroah-Hartman

From: Steve French <[email protected]>

commit 643fbceef48e5b22bf8e0905f903e908b5d2ba69 upstream.

When mounting with "modefromsid" mount parm most servers will require that some default permissions are given to users in the ACL on newly created files, files created with the new 'sd context' - when passing in an sd context on create, permissions are not inherited from the parent directory, so in addition to the ACE with the special SID which contains the mode, we also must pass in an ACE allowing users to access the file (GENERIC_ALL for authenticated users seemed like a reasonable default, although later we could allow a mount option or config switch to make it GENERIC_ALL for EVERYONE special sid).

---
 fs/cifs/cifsacl.c   |   20 ++++++++++++++++++++
 fs/cifs/cifsproto.h |    1 +
 fs/cifs/smb2pdu.c   |   11 ++++++++---
 3 files changed, 29 insertions(+), 3 deletions(-)
fs/cifs/cifsacl.c +20 -0
@@ -802,6 +802,26 @@ static void parse_dacl(struct cifs_acl *
 	return;
 }
 
+unsigned int setup_authusers_ACE(struct cifs_ace *pntace)
+{
+	int i;
+	unsigned int ace_size = 20;
+
+	pntace->type = ACCESS_ALLOWED_ACE_TYPE;
+	pntace->flags = 0x0;
+	pntace->access_req = cpu_to_le32(GENERIC_ALL);
+	pntace->sid.num_subauth = 1;
+	pntace->sid.revision = 1;
+	for (i = 0; i < NUM_AUTHS; i++)
+		pntace->sid.authority[i] =  sid_authusers.authority[i];
+
+	pntace->sid.sub_auth[0] =  sid_authusers.sub_auth[0];
+
+	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
+	pntace->size = cpu_to_le16(ace_size);
+	return ace_size;
+}
+
 /*
  * Fill in the special SID based on the mode. See
  * http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
fs/cifs/cifsproto.h +1 -0
@@ -213,6 +213,7 @@ extern struct cifs_ntsd *get_cifs_acl_by
 						const struct cifs_fid *, u32 *);
 extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *,
 				const char *, int);
+extern unsigned int setup_authusers_ACE(struct cifs_ace *pace);
 extern unsigned int setup_special_mode_ACE(struct cifs_ace *pace, __u64 nmode);
 
 extern void dequeue_mid(struct mid_q_entry *mid, bool malformed);
fs/cifs/smb2pdu.c +8 -3
@@ -2199,13 +2199,14 @@ create_sd_buf(umode_t mode, unsigned int
 	struct cifs_ace *pace;
 	unsigned int sdlen, acelen;
 
-	*len = roundup(sizeof(struct crt_sd_ctxt) + sizeof(struct cifs_ace), 8);
+	*len = roundup(sizeof(struct crt_sd_ctxt) + sizeof(struct cifs_ace) * 2,
+			8);
 	buf = kzalloc(*len, GFP_KERNEL);
 	if (buf == NULL)
 		return buf;
 
 	sdlen = sizeof(struct smb3_sd) + sizeof(struct smb3_acl) +
-		 sizeof(struct cifs_ace);
+		 2 * sizeof(struct cifs_ace);
 
 	buf->ccontext.DataOffset = cpu_to_le16(offsetof
 					(struct crt_sd_ctxt, sd));
@@ -2232,8 +2233,12 @@ create_sd_buf(umode_t mode, unsigned int
 	/* create one ACE to hold the mode embedded in reserved special SID */
 	pace = (struct cifs_ace *)(sizeof(struct crt_sd_ctxt) + (char *)buf);
 	acelen = setup_special_mode_ACE(pace, (__u64)mode);
+	/* and one more ACE to allow access for authenticated users */
+	pace = (struct cifs_ace *)(acelen + (sizeof(struct crt_sd_ctxt) +
+		(char *)buf));
+	acelen += setup_authusers_ACE(pace);
 	buf->acl.AclSize = cpu_to_le16(sizeof(struct cifs_acl) + acelen);
-	buf->acl.AceCount = cpu_to_le16(1);
+	buf->acl.AceCount = cpu_to_le16(2);
 	return buf;
 }
 
author maintainer
#100 lore raw

PATCH 100/367 alarmtimer: Unregister wakeup source when module get fails

In reply to Greg Kroah-Hartman

From: Stephen Boyd <[email protected]>

commit 6b6d188aae79a630957aefd88ff5c42af6553ee3 upstream.

The alarmtimer_rtc_add_device() function creates a wakeup source and then tries to grab a module reference. If that fails the function returns early with an error code, but fails to remove the wakeup source.

Cleanup this exit path so there is no dangling wakeup source, which is named 'alarmtime' left allocated which will conflict with another RTC device that may be registered later.

---
 kernel/time/alarmtimer.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
kernel/time/alarmtimer.c +5 -3
@@ -88,6 +88,7 @@ static int alarmtimer_rtc_add_device(str
 	unsigned long flags;
 	struct rtc_device *rtc = to_rtc_device(dev);
 	struct wakeup_source *__ws;
+	int ret = 0;
 
 	if (rtcdev)
 		return -EBUSY;
@@ -102,8 +103,8 @@ static int alarmtimer_rtc_add_device(str
 	spin_lock_irqsave(&rtcdev_lock, flags);
 	if (!rtcdev) {
 		if (!try_module_get(rtc->owner)) {
-			spin_unlock_irqrestore(&rtcdev_lock, flags);
-			return -1;
+			ret = -1;
+			goto unlock;
 		}
 
 		rtcdev = rtc;
@@ -112,11 +113,12 @@ static int alarmtimer_rtc_add_device(str
 		ws = __ws;
 		__ws = NULL;
 	}
+unlock:
 	spin_unlock_irqrestore(&rtcdev_lock, flags);
 
 	wakeup_source_unregister(__ws);
 
-	return 0;
+	return ret;
 }
 
 static inline void alarmtimer_rtc_timer_init(void)
author maintainer
#101 lore raw

PATCH 101/367 fscrypt: dont print name of busy file when removing key

In reply to Greg Kroah-Hartman

From: Eric Biggers <[email protected]>

commit 13a10da94615d81087e718517794f2868a8b3fab upstream.

When an encryption key can't be fully removed due to file(s) protected by it still being in-use, we shouldn't really print the path to one of these files to the kernel log, since parts of this path are likely to be encrypted on-disk, and (depending on how the system is set up) the confidentiality of this path might be lost by printing it to the log.

This is a trade-off: a single file path often doesn't matter at all, especially if it's a directory; the kernel log might still be protected in some way; and I had originally hoped that any "inode(s) still busy" bugs (which are security weaknesses in their own right) would be quickly fixed and that to do so it would be super helpful to always know the file path and not have to run 'find dir -inum $inum' after the fact.

But in practice, these bugs can be hard to fix (e.g. due to asynchronous process killing that is difficult to eliminate, for performance reasons), and also not tied to specific files, so knowing a file path doesn't necessarily help.

So to be safe, for now let's just show the inode number, not the path. If someone really wants to know a path they can use 'find -inum'.

Fixes b1c0ec3599f4 ("fscrypt: add FS_IOC_REMOVE_ENCRYPTION_KEY ioctl")
Cc <[email protected]> # v5.4+
---
 fs/crypto/keyring.c |   15 ++-------------
 1 file changed, 2 insertions(+), 13 deletions(-)
fs/crypto/keyring.c +2 -13
@@ -666,9 +666,6 @@ static int check_for_busy_inodes(struct
 	struct list_head *pos;
 	size_t busy_count = 0;
 	unsigned long ino;
-	struct dentry *dentry;
-	char _path[256];
-	char *path = NULL;
 
 	spin_lock(&mk->mk_decrypted_inodes_lock);
 
@@ -687,22 +684,14 @@ static int check_for_busy_inodes(struct
 					 struct fscrypt_info,
 					 ci_master_key_link)->ci_inode;
 		ino = inode->i_ino;
-		dentry = d_find_alias(inode);
 	}
 	spin_unlock(&mk->mk_decrypted_inodes_lock);
 
-	if (dentry) {
-		path = dentry_path(dentry, _path, sizeof(_path));
-		dput(dentry);
-	}
-	if (IS_ERR_OR_NULL(path))
-		path = "(unknown)";
-
 	fscrypt_warn(NULL,
-		     "%s: %zu inode(s) still busy after removing key with %s %*phN, including ino %lu (%s)",
+		     "%s: %zu inode(s) still busy after removing key with %s %*phN, including ino %lu",
 		     sb->s_id, busy_count, master_key_spec_type(&mk->mk_spec),
 		     master_key_spec_len(&mk->mk_spec), (u8 *)&mk->mk_spec.u,
-		     ino, path);
+		     ino);
 	return -EBUSY;
 }
 
author maintainer
#102 lore raw

PATCH 102/367 ubifs: dont trigger assertion on invalid no-key filename

In reply to Greg Kroah-Hartman

From: Eric Biggers <[email protected]>

commit f0d07a98a070bb5e443df19c3aa55693cbca9341 upstream.

If userspace provides an invalid fscrypt no-key filename which encodes a hash value with any of the UBIFS node type bits set (i.e. the high 3 bits), gracefully report ENOENT rather than triggering ubifs_assert().

Test case with kvm-xfstests shell:

. fs/ubifs/config
. ~/xfstests/common/encrypt dev=$(__blkdev_to_ubi_volume /dev/vdc) ubiupdatevol $dev -t
mount $dev /mnt -t ubifs
mkdir /mnt/edir
xfs_io -c set_encpolicy /mnt/edir
rm /mnt/edir/_,,,,,DAAAAAAAAAAAAAAAAAAAAAAAAAA

With the bug, the following assertion fails on the 'rm' command:

    [   19.066048] UBIFS error (ubi0:0 pid 379): ubifs_assert_failed: UBIFS assert failed: !(hash & ~UBIFS_S_KEY_HASH_MASK), in fs/ubifs/key.h:170
Fixes f4f61d2cc6d8 ("ubifs: Implement encrypted filenames")
Cc <[email protected]> # v4.10+
---
 fs/ubifs/dir.c |    2 ++
 1 file changed, 2 insertions(+)
fs/ubifs/dir.c +2 -0
@@ -228,6 +228,8 @@ static struct dentry *ubifs_lookup(struc
 	if (nm.hash) {
 		ubifs_assert(c, fname_len(&nm) == 0);
 		ubifs_assert(c, fname_name(&nm) == NULL);
+		if (nm.hash & ~UBIFS_S_KEY_HASH_MASK)
+			goto done; /* ENOENT */
 		dent_key_init_hash(c, &key, dir->i_ino, nm.hash);
 		err = ubifs_tnc_lookup_dh(c, &key, dent, nm.minor_hash);
 	} else {
author maintainer
#103 lore raw

PATCH 103/367 ubifs: Fix wrong memory allocation

In reply to Greg Kroah-Hartman

From: Sascha Hauer <[email protected]>

commit edec51374bce779f37fc209a228139c55d90ec8d upstream.

In create_default_filesystem() when we allocate the idx node we must use the idx_node_size we calculated just one line before, not tmp, which contains completely other data.

---
 fs/ubifs/sb.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ubifs/sb.c +1 -1
@@ -161,7 +161,7 @@ static int create_default_filesystem(str
 	sup = kzalloc(ALIGN(UBIFS_SB_NODE_SZ, c->min_io_size), GFP_KERNEL);
 	mst = kzalloc(c->mst_node_alsz, GFP_KERNEL);
 	idx_node_size = ubifs_idx_node_sz(c, 1);
-	idx = kzalloc(ALIGN(tmp, c->min_io_size), GFP_KERNEL);
+	idx = kzalloc(ALIGN(idx_node_size, c->min_io_size), GFP_KERNEL);
 	ino = kzalloc(ALIGN(UBIFS_INO_NODE_SZ, c->min_io_size), GFP_KERNEL);
 	cs = kzalloc(ALIGN(UBIFS_CS_NODE_SZ, c->min_io_size), GFP_KERNEL);
 
author maintainer
#104 lore raw

PATCH 104/367 ubifs: Fix FS_IOC_SETFLAGS unexpectedly clearing encrypt flag

In reply to Greg Kroah-Hartman

From: Eric Biggers <[email protected]>

commit 2b57067a7778484c10892fa191997bfda29fea13 upstream.

UBIFS's implementation of FS_IOC_SETFLAGS fails to preserve existing inode flags that aren't settable by FS_IOC_SETFLAGS, namely the encrypt flag. This causes the encrypt flag to be unexpectedly cleared.

Fix it by preserving existing unsettable flags, like ext4 and f2fs do.

Test case with kvm-xfstests shell:

FSTYP=ubifs KEYCTL_PROG=keyctl
. fs/ubifs/config
. ~/xfstests/common/encrypt
dev=$(__blkdev_to_ubi_volume /dev/vdc)
ubiupdatevol -t $dev
mount $dev /mnt -t ubifs
k=$(_generate_session_encryption_key)
mkdir /mnt/edir
xfs_io -c "set_encpolicy $k" /mnt/edir
echo contents > /mnt/edir/file
chattr +i /mnt/edir/file
chattr -i /mnt/edir/file

With the bug, the following errors occur on the last command:

    [   18.081559] fscrypt (ubifs, inode 67): Inconsistent encryption context (parent directory: 65)
    chattr: Operation not permitted while reading flags on /mnt/edir/file
Fixes d475a507457b ("ubifs: Add skeleton for fscrypto")
Cc <[email protected]> # v4.10+
---
 fs/ubifs/ioctl.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
fs/ubifs/ioctl.c +2 -1
@@ -113,7 +113,8 @@ static int setflags(struct inode *inode,
 	if (err)
 		goto out_unlock;
 
-	ui->flags = ioctl2ubifs(flags);
+	ui->flags &= ~ioctl2ubifs(UBIFS_SUPPORTED_IOCTL_FLAGS);
+	ui->flags |= ioctl2ubifs(flags);
 	ubifs_set_inode_flags(inode);
 	inode->i_ctime = current_time(inode);
 	release = ui->dirty;
author maintainer
#105 lore raw

PATCH 105/367 ubifs: Fix deadlock in concurrent bulk-read and writepage

In reply to Greg Kroah-Hartman

From: Zhihao Cheng <[email protected]>

commit f5de5b83303e61b1f3fb09bd77ce3ac2d7a475f2 upstream.

In ubifs, concurrent execution of writepage and bulk read on the same file may cause ABBA deadlock, for example (Reproduce method see Link):

Process A(Bulk-read starts from page4) Process B(write page4 back)

  vfs_read                                       wb_workfn or fsync
  ...                                            ...
  generic_file_buffered_read                     write_cache_pages

ubifs_readpage LOCK(page4)

ubifs_bulk_read ubifs_writepage
LOCK(ui->ui_mutex) ubifs_write_inode

ubifs_do_bulk_read LOCK(ui->ui_mutex)
find_or_create_page(alloc page4) ↑
LOCK(page4) <-- ABBA deadlock occurs!

In order to ensure the serialization execution of bulk read, we can't remove the big lock 'ui->ui_mutex' in ubifs_bulk_read(). Instead, we allow ubifs_do_bulk_read() to lock page failed by replacing find_or_create_page(FGP_LOCK) with pagecache_get_page(FGP_LOCK | FGP_NOWAIT).

---
 fs/ubifs/file.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
fs/ubifs/file.c +3 -1
@@ -786,7 +786,9 @@ static int ubifs_do_bulk_read(struct ubi
 
 		if (page_offset > end_index)
 			break;
-		page = find_or_create_page(mapping, page_offset, ra_gfp_mask);
+		page = pagecache_get_page(mapping, page_offset,
+				 FGP_LOCK|FGP_ACCESSED|FGP_CREAT|FGP_NOWAIT,
+				 ra_gfp_mask);
 		if (!page)
 			break;
 		if (!PageUptodate(page))
author maintainer
#106 lore raw

PATCH 106/367 mmc: sdhci-of-at91: fix memleak on clk_get failure

In reply to Greg Kroah-Hartman

From: Michał Mirosław <[email protected]>

[ Upstream commit a04184ce777b46e92c2b3c93c6dcb2754cb005e1 ]

sdhci_alloc_host() does its work not using managed infrastructure, so needs explicit free on error path. Add it where needed.

---
 drivers/mmc/host/sdhci-of-at91.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/mmc/host/sdhci-of-at91.c +6 -3
index 5959e394b416f..99d82c1874d62 100644
@@ -335,19 +335,22 @@ static int sdhci_at91_probe(struct platform_device *pdev)
 	priv->mainck = devm_clk_get(&pdev->dev, "baseclk");
 	if (IS_ERR(priv->mainck)) {
 		dev_err(&pdev->dev, "failed to get baseclk\n");
-		return PTR_ERR(priv->mainck);
+		ret = PTR_ERR(priv->mainck);
+		goto sdhci_pltfm_free;
 	}
 
 	priv->hclock = devm_clk_get(&pdev->dev, "hclock");
 	if (IS_ERR(priv->hclock)) {
 		dev_err(&pdev->dev, "failed to get hclock\n");
-		return PTR_ERR(priv->hclock);
+		ret = PTR_ERR(priv->hclock);
+		goto sdhci_pltfm_free;
 	}
 
 	priv->gck = devm_clk_get(&pdev->dev, "multclk");
 	if (IS_ERR(priv->gck)) {
 		dev_err(&pdev->dev, "failed to get multclk\n");
-		return PTR_ERR(priv->gck);
+		ret = PTR_ERR(priv->gck);
+		goto sdhci_pltfm_free;
 	}
 
 	ret = sdhci_at91_set_clks_presets(&pdev->dev);
Signature · 1 line
2.20.1
author maintainer
#107 lore raw

PATCH 107/367 ASoC: tegra: Revert 24 and 32 bit support

In reply to Greg Kroah-Hartman

From: Jon Hunter <[email protected]>

commit 961b91a93ea27495022b2bdc3ca0f608f2c97b5f upstream.

Commit f3ee99087c8ca0ecfdd549ef5a94f557c42d5428 ("ASoC: tegra: Allow 24bit and 32bit samples") added 24-bit and 32-bit support for to the Tegra30 I2S driver. However, there are two additional commits that are also needed to get 24-bit and 32-bit support to work correctly. These commits are not yet applied because there are still some review comments that need to be addressed. With only this change applied, 24-bit and 32-bit support is advertised by the I2S driver, but it does not work and the audio is distorted. Therefore, revert this patch for now until the other changes are also ready.

Furthermore, a clock issue with 24-bit support has been identified with this change and so if we revert this now, we can also fix that in the updated version.

---
 sound/soc/tegra/tegra30_i2s.c |   25 +++++--------------------
 1 file changed, 5 insertions(+), 20 deletions(-)
sound/soc/tegra/tegra30_i2s.c +5 -20
@@ -127,7 +127,7 @@ static int tegra30_i2s_hw_params(struct
 	struct device *dev = dai->dev;
 	struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 	unsigned int mask, val, reg;
-	int ret, sample_size, srate, i2sclock, bitcnt, audio_bits;
+	int ret, sample_size, srate, i2sclock, bitcnt;
 	struct tegra30_ahub_cif_conf cif_conf;
 
 	if (params_channels(params) != 2)
@@ -137,19 +137,8 @@ static int tegra30_i2s_hw_params(struct
 	switch (params_format(params)) {
 	case SNDRV_PCM_FORMAT_S16_LE:
 		val = TEGRA30_I2S_CTRL_BIT_SIZE_16;
-		audio_bits = TEGRA30_AUDIOCIF_BITS_16;
 		sample_size = 16;
 		break;
-	case SNDRV_PCM_FORMAT_S24_LE:
-		val = TEGRA30_I2S_CTRL_BIT_SIZE_24;
-		audio_bits = TEGRA30_AUDIOCIF_BITS_24;
-		sample_size = 24;
-		break;
-	case SNDRV_PCM_FORMAT_S32_LE:
-		val = TEGRA30_I2S_CTRL_BIT_SIZE_32;
-		audio_bits = TEGRA30_AUDIOCIF_BITS_32;
-		sample_size = 32;
-		break;
 	default:
 		return -EINVAL;
 	}
@@ -181,8 +170,8 @@ static int tegra30_i2s_hw_params(struct
 	cif_conf.threshold = 0;
 	cif_conf.audio_channels = 2;
 	cif_conf.client_channels = 2;
-	cif_conf.audio_bits = audio_bits;
-	cif_conf.client_bits = audio_bits;
+	cif_conf.audio_bits = TEGRA30_AUDIOCIF_BITS_16;
+	cif_conf.client_bits = TEGRA30_AUDIOCIF_BITS_16;
 	cif_conf.expand = 0;
 	cif_conf.stereo_conv = 0;
 	cif_conf.replicate = 0;
@@ -317,18 +306,14 @@ static const struct snd_soc_dai_driver t
 		.channels_min = 2,
 		.channels_max = 2,
 		.rates = SNDRV_PCM_RATE_8000_96000,
-		.formats = SNDRV_PCM_FMTBIT_S32_LE |
-			   SNDRV_PCM_FMTBIT_S24_LE |
-			   SNDRV_PCM_FMTBIT_S16_LE,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
 	},
 	.capture = {
 		.stream_name = "Capture",
 		.channels_min = 2,
 		.channels_max = 2,
 		.rates = SNDRV_PCM_RATE_8000_96000,
-		.formats = SNDRV_PCM_FMTBIT_S32_LE |
-			   SNDRV_PCM_FMTBIT_S24_LE |
-			   SNDRV_PCM_FMTBIT_S16_LE,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
 	},
 	.ops = &tegra30_i2s_dai_ops,
 	.symmetric_rates = 1,
author maintainer
#108 lore raw

PATCH 108/367 ASoC: topology: fix soc_tplg_fe_link_create() - link->dobj initialization order

In reply to Greg Kroah-Hartman

From: Jaroslav Kysela <[email protected]>

commit 8ce1cbd6ce0b1bda0c980c64fee4c1e1378355f1 upstream.

The code which checks the return value for snd_soc_add_dai_link() call in soc_tplg_fe_link_create() moved the snd_soc_add_dai_link() call before link->dobj members initialization.

While it does not affect the latest kernels, the old soc-core.c code in the stable kernels is affected. The snd_soc_add_dai_link() function uses the link->dobj.type member to check, if the link structure is valid.

Reorder the link->dobj initialization to make things work again. It's harmless for the recent code (and the structure should be properly initialized before other calls anyway).

The problem is in stable linux-5.4.y since version 5.4.11 when the upstream commit 76d270364932 was applied.

Fixes 76d270364932 ("ASoC: topology: Check return value for snd_soc_add_dai_link()")
Cc Dragos Tarcatu <[email protected]>
Cc Pierre-Louis Bossart <[email protected]>
Cc Ranjani Sridharan <[email protected]>
Cc Mark Brown <[email protected]>
---
 sound/soc/soc-topology.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
sound/soc/soc-topology.c +4 -3
@@ -1906,6 +1906,10 @@ static int soc_tplg_fe_link_create(struc
 	link->num_codecs = 1;
 	link->num_platforms = 1;
 
+	link->dobj.index = tplg->index;
+	link->dobj.ops = tplg->ops;
+	link->dobj.type = SND_SOC_DOBJ_DAI_LINK;
+
 	if (strlen(pcm->pcm_name)) {
 		link->name = kstrdup(pcm->pcm_name, GFP_KERNEL);
 		link->stream_name = kstrdup(pcm->pcm_name, GFP_KERNEL);
@@ -1942,9 +1946,6 @@ static int soc_tplg_fe_link_create(struc
 		goto err;
 	}
 
-	link->dobj.index = tplg->index;
-	link->dobj.ops = tplg->ops;
-	link->dobj.type = SND_SOC_DOBJ_DAI_LINK;
 	list_add(&link->dobj.list, &tplg->comp->dobj_list);
 
 	return 0;
author maintainer
#109 lore raw

PATCH 109/367 ASoC: SOF: core: free trace on errors

In reply to Greg Kroah-Hartman

From: Pierre-Louis Bossart <[email protected]>

commit 37e97e6faeabda405d0c4319f8419dcc3da14b2b upstream.

free_trace() is not called on probe errors, fix

---
 sound/soc/sof/core.c |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
sound/soc/sof/core.c +5 -2
@@ -394,7 +394,7 @@ static int sof_probe_continue(struct snd
 	if (ret < 0) {
 		dev_err(sdev->dev,
 			"error: failed to register DSP DAI driver %d\n", ret);
-		goto fw_run_err;
+		goto fw_trace_err;
 	}
 
 	drv_name = plat_data->machine->drv_name;
@@ -408,7 +408,7 @@ static int sof_probe_continue(struct snd
 
 	if (IS_ERR(plat_data->pdev_mach)) {
 		ret = PTR_ERR(plat_data->pdev_mach);
-		goto fw_run_err;
+		goto fw_trace_err;
 	}
 
 	dev_dbg(sdev->dev, "created machine %s\n",
@@ -420,6 +420,8 @@ static int sof_probe_continue(struct snd
 	return 0;
 
 #if !IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)
+fw_trace_err:
+	snd_sof_free_trace(sdev);
 fw_run_err:
 	snd_sof_fw_unload(sdev);
 fw_load_err:
@@ -437,6 +439,7 @@ dbg_err:
 	 * snd_sof_device_remove() when the PCI/ACPI device is removed
 	 */
 
+fw_trace_err:
 fw_run_err:
 fw_load_err:
 ipc_err:
author maintainer
#110 lore raw

PATCH 110/367 hv_balloon: Balloon up according to request page number

In reply to Greg Kroah-Hartman

From: Tianyu Lan <[email protected]>

commit d33c240d47dab4fd15123d9e73fc8810cbc6ed6a upstream.

Current code has assumption that balloon request memory size aligns with 2MB. But actually Hyper-V doesn't guarantee such alignment. When balloon driver receives non-aligned balloon request, it produces warning and balloon up more memory than requested in order to keep 2MB alignment. Remove the warning and balloon up memory according to actual requested memory size.

Fixes f6712238471a ("hv: hv_balloon: avoid memory leak on alloc_error of 2MB memory block")
---
 drivers/hv/hv_balloon.c |   13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)
drivers/hv/hv_balloon.c +3 -10
@@ -1217,10 +1217,7 @@ static unsigned int alloc_balloon_pages(
 	unsigned int i, j;
 	struct page *pg;
 
-	if (num_pages < alloc_unit)
-		return 0;
-
-	for (i = 0; (i * alloc_unit) < num_pages; i++) {
+	for (i = 0; i < num_pages / alloc_unit; i++) {
 		if (bl_resp->hdr.size + sizeof(union dm_mem_page_range) >
 			HV_HYP_PAGE_SIZE)
 			return i * alloc_unit;
@@ -1258,7 +1255,7 @@ static unsigned int alloc_balloon_pages(
 
 	}
 
-	return num_pages;
+	return i * alloc_unit;
 }
 
 static void balloon_up(struct work_struct *dummy)
@@ -1273,9 +1270,6 @@ static void balloon_up(struct work_struc
 	long avail_pages;
 	unsigned long floor;
 
-	/* The host balloons pages in 2M granularity. */
-	WARN_ON_ONCE(num_pages % PAGES_IN_2M != 0);
-
 	/*
 	 * We will attempt 2M allocations. However, if we fail to
 	 * allocate 2M chunks, we will go back to PAGE_SIZE allocations.
@@ -1285,14 +1279,13 @@ static void balloon_up(struct work_struc
 	avail_pages = si_mem_available();
 	floor = compute_balloon_floor();
 
-	/* Refuse to balloon below the floor, keep the 2M granularity. */
+	/* Refuse to balloon below the floor. */
 	if (avail_pages < num_pages || avail_pages - num_pages < floor) {
 		pr_warn("Balloon request will be partially fulfilled. %s\n",
 			avail_pages < num_pages ? "Not enough memory." :
 			"Balloon floor reached.");
 
 		num_pages = avail_pages > floor ? (avail_pages - floor) : 0;
-		num_pages -= num_pages % PAGES_IN_2M;
 	}
 
 	while (!done) {
author maintainer
#111 lore raw

PATCH 111/367 mfd: axp20x: Mark AXP20X_VBUS_IPSOUT_MGMT as volatile

In reply to Greg Kroah-Hartman

From: Samuel Holland <[email protected]>

commit dc91c3b6fe66a13ac76f6cb3b2100c0779cd3350 upstream.

On AXP288 and newer PMICs, bit 7 of AXP20X_VBUS_IPSOUT_MGMT can be set to prevent using the VBUS input. However, when the VBUS unplugged and plugged back in, the bit automatically resets to zero.

We need to set the register as volatile to prevent regmap from caching that bit. Otherwise, regcache will think the bit is already set and not write the register.

Fixes cd53216625a0 ("mfd: axp20x: Fix axp288 volatile ranges")
---
 drivers/mfd/axp20x.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mfd/axp20x.c +1 -1
@@ -126,7 +126,7 @@ static const struct regmap_range axp288_
 static const struct regmap_range axp288_volatile_ranges[] = {
 	regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP288_POWER_REASON),
 	regmap_reg_range(AXP288_BC_GLOBAL, AXP288_BC_GLOBAL),
-	regmap_reg_range(AXP288_BC_DET_STAT, AXP288_BC_DET_STAT),
+	regmap_reg_range(AXP288_BC_DET_STAT, AXP20X_VBUS_IPSOUT_MGMT),
 	regmap_reg_range(AXP20X_CHRG_BAK_CTRL, AXP20X_CHRG_BAK_CTRL),
 	regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IPSOUT_V_HIGH_L),
 	regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL),
author maintainer
#112 lore raw

PATCH 112/367 nvmem: imx: scu: fix write SIP

In reply to Greg Kroah-Hartman

From: Peng Fan <[email protected]>

commit 40bb95dbb8acca35f8d52a833393ddbb01cfa2db upstream.

SIP number 0xC200000A is for reading, 0xC200000B is for writing. And the following two args for write are word index, data to write.

---
 drivers/nvmem/imx-ocotp-scu.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/nvmem/imx-ocotp-scu.c +2 -4
@@ -15,8 +15,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 
-#define IMX_SIP_OTP			0xC200000A
-#define IMX_SIP_OTP_WRITE		0x2
+#define IMX_SIP_OTP_WRITE		0xc200000B
 
 enum ocotp_devtype {
 	IMX8QXP,
@@ -212,8 +211,7 @@ static int imx_scu_ocotp_write(void *con
 
 	mutex_lock(&scu_ocotp_mutex);
 
-	arm_smccc_smc(IMX_SIP_OTP, IMX_SIP_OTP_WRITE, index, *buf,
-		      0, 0, 0, 0, &res);
+	arm_smccc_smc(IMX_SIP_OTP_WRITE, index, *buf, 0, 0, 0, 0, 0, &res);
 
 	mutex_unlock(&scu_ocotp_mutex);
 
author maintainer
#113 lore raw

PATCH 113/367 nvmem: core: fix memory abort in cleanup path

In reply to Greg Kroah-Hartman

From: Bitan Biswas <[email protected]>

commit 16bb7abc4a6b9defffa294e4dc28383e62a1dbcf upstream.

nvmem_cell_info_to_nvmem_cell implementation has static allocation of name. nvmem_add_cells_from_of() call may return error and kfree name results in memory abort. Use kstrdup_const() and kfree_const calls for name alloc and free.

Unable to handle kernel paging request at virtual address ffffffffffe44888

Mem abort info:
ESR = 0x96000006
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
Data abort info:
ISV = 0, ISS = 0x00000006
CM = 0, WnR = 0
swapper pgtable: 64k pages, 48-bit VAs, pgdp=00000000815d0000 [ffffffffffe44888] pgd=0000000081d30803, pud=0000000081d30803, pmd=0000000000000000

Internal error: Oops: 96000006 [#1] PREEMPT SMP
Modules linked in:
CPU: 2 PID: 43 Comm: kworker/2:1 Tainted
Hardware name: quill (DT)
Workqueue: events deferred_probe_work_func
pstate: a0000005 (NzCv daif -PAN -UAO)
pc : kfree+0x38/0x278
lr : nvmem_cell_drop+0x68/0x80

sp : ffff80001284f9d0
x29: ffff80001284f9d0 x28: ffff0001f677e830
x27: ffff800011b0b000 x26: ffff0001c36e1008
x25: ffff8000112ad000 x24: ffff8000112c9000
x23: ffffffffffffffea x22: ffff800010adc7f0
x21: ffffffffffe44880 x20: ffff800011b0b068
x19: ffff80001122d380 x18: ffffffffffffffff
x17: 00000000d5cb4756 x16: 0000000070b193b8
x15: ffff8000119538c8 x14: 0720072007200720
x13: 07200720076e0772 x12: 07750762072d0765
x11: 0773077507660765 x10: 072f073007300730
x9 : 0730073207380733 x8 : 0000000000000151
x7 : 07660765072f0720 x6 : ffff0001c00e0f00
x5 : 0000000000000000 x4 : ffff0001c0b43800
x3 : ffff800011b0b068 x2 : 0000000000000000
x1 : 0000000000000000 x0 : ffffffdfffe00000

Call trace:
 kfree+0x38/0x278
 nvmem_cell_drop+0x68/0x80
 nvmem_device_remove_all_cells+0x2c/0x50
 nvmem_register.part.9+0x520/0x628
 devm_nvmem_register+0x48/0xa0
 tegra_fuse_probe+0x140/0x1f0
 platform_drv_probe+0x50/0xa0
 really_probe+0x108/0x348
 driver_probe_device+0x58/0x100
 __device_attach_driver+0x90/0xb0
 bus_for_each_drv+0x64/0xc8
 __device_attach+0xd8/0x138
 device_initial_probe+0x10/0x18
 bus_probe_device+0x90/0x98
 deferred_probe_work_func+0x74/0xb0
 process_one_work+0x1e0/0x358
 worker_thread+0x208/0x488
 kthread+0x118/0x120
 ret_from_fork+0x10/0x18
Code: d350feb5 f2dffbe0 aa1e03f6 8b151815 (f94006a0)
---[ end trace 49b1303c6b83198e ]---
Fixes badcdff107cbf ("nvmem: Convert to using %pOFn instead of device_node.name")
Cc stable <[email protected]>
---
 drivers/nvmem/core.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/nvmem/core.c +5 -3
@@ -83,7 +83,7 @@ static void nvmem_cell_drop(struct nvmem
 	list_del(&cell->node);
 	mutex_unlock(&nvmem_mutex);
 	of_node_put(cell->np);
-	kfree(cell->name);
+	kfree_const(cell->name);
 	kfree(cell);
 }
 
@@ -110,7 +110,9 @@ static int nvmem_cell_info_to_nvmem_cell
 	cell->nvmem = nvmem;
 	cell->offset = info->offset;
 	cell->bytes = info->bytes;
-	cell->name = info->name;
+	cell->name = kstrdup_const(info->name, GFP_KERNEL);
+	if (!cell->name)
+		return -ENOMEM;
 
 	cell->bit_offset = info->bit_offset;
 	cell->nbits = info->nbits;
@@ -300,7 +302,7 @@ static int nvmem_add_cells_from_of(struc
 			dev_err(dev, "cell %s unaligned to nvmem stride %d\n",
 				cell->name, nvmem->stride);
 			/* Cells already added will be freed later. */
-			kfree(cell->name);
+			kfree_const(cell->name);
 			kfree(cell);
 			return -EINVAL;
 		}
author maintainer
#114 lore raw

PATCH 114/367 crypto: api - Check spawn->alg under lock in crypto_drop_spawn

In reply to Greg Kroah-Hartman

From: Herbert Xu <[email protected]>

commit 7db3b61b6bba4310f454588c2ca6faf2958ad79f upstream.

We need to check whether spawn->alg is NULL under lock as otherwise the algorithm could be removed from under us after we have checked it and found it to be non-NULL. This could cause us to remove the spawn from a non-existent list.

Fixes 7ede5a5ba55a ("crypto: api - Fix crypto_drop_spawn crash...")
---
 crypto/algapi.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
crypto/algapi.c +2 -4
@@ -669,11 +669,9 @@ EXPORT_SYMBOL_GPL(crypto_grab_spawn);
 
 void crypto_drop_spawn(struct crypto_spawn *spawn)
 {
-	if (!spawn->alg)
-		return;
-
 	down_write(&crypto_alg_sem);
-	list_del(&spawn->list);
+	if (spawn->alg)
+		list_del(&spawn->list);
 	up_write(&crypto_alg_sem);
 }
 EXPORT_SYMBOL_GPL(crypto_drop_spawn);
author maintainer
#115 lore raw

PATCH 115/367 crypto: ccree - fix backlog memory leak

In reply to Greg Kroah-Hartman

From: Gilad Ben-Yossef <[email protected]>

commit 4df2ef25b3b3618fd708ab484fe6239abd130fec upstream.

Fix brown paper bag bug of not releasing backlog list item buffer when backlog was consumed causing a memory leak when backlog is used.

---
 drivers/crypto/ccree/cc_request_mgr.c |    1 +
 1 file changed, 1 insertion(+)
drivers/crypto/ccree/cc_request_mgr.c +1 -0
@@ -404,6 +404,7 @@ static void cc_proc_backlog(struct cc_dr
 		spin_lock(&mgr->bl_lock);
 		list_del(&bli->list);
 		--mgr->bl_len;
+		kfree(bli);
 	}
 
 	spin_unlock(&mgr->bl_lock);
author maintainer
#116 lore raw

PATCH 116/367 crypto: ccree - fix AEAD decrypt auth fail

In reply to Greg Kroah-Hartman

From: Gilad Ben-Yossef <[email protected]>

commit 2a6bc713f1cef32e39e3c4e6f2e1a9849da6379c upstream.

On AEAD decryption authentication failure we are suppose to zero out the output plaintext buffer. However, we've missed skipping the optional associated data that may prefix the ciphertext. This commit fixes this issue.

Fixes e88b27c8eaa8 ("crypto: ccree - use std api sg_zero_buffer")
---
 drivers/crypto/ccree/cc_aead.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/crypto/ccree/cc_aead.c +1 -1
@@ -237,7 +237,7 @@ static void cc_aead_complete(struct devi
 			 * revealed the decrypted message --> zero its memory.
 			 */
 			sg_zero_buffer(areq->dst, sg_nents(areq->dst),
-				       areq->cryptlen, 0);
+				       areq->cryptlen, areq->assoclen);
 			err = -EBADMSG;
 		}
 	/*ENCRYPT*/
author maintainer
#117 lore raw

PATCH 117/367 crypto: ccree - fix pm wrongful error reporting

In reply to Greg Kroah-Hartman

From: Gilad Ben-Yossef <[email protected]>

commit cedca59fae5834af8445b403c66c9953754375d7 upstream.

pm_runtime_get_sync() can return 1 as a valid (none error) return code. Treat it as such.

---
 drivers/crypto/ccree/cc_pm.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/crypto/ccree/cc_pm.c +1 -1
@@ -85,7 +85,7 @@ int cc_pm_get(struct device *dev)
 	else
 		pm_runtime_get_noresume(dev);
 
-	return rc;
+	return (rc == 1 ? 0 : rc);
 }
 
 int cc_pm_put_suspend(struct device *dev)
author maintainer
#118 lore raw

PATCH 118/367 crypto: ccree - fix FDE descriptor sequence

In reply to Greg Kroah-Hartman

From: Ofir Drang <[email protected]>

commit 5c83e8ec4d51ac4cc58482ed04297e6882b32a09 upstream.

In FDE mode (xts, essiv and bitlocker) the cryptocell hardware requires that the the XEX key will be loaded after Key1.

---
 drivers/crypto/ccree/cc_cipher.c |   48 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 45 insertions(+), 3 deletions(-)
drivers/crypto/ccree/cc_cipher.c +45 -3
@@ -523,6 +523,7 @@ static void cc_setup_readiv_desc(struct
 	}
 }
 
+
 static void cc_setup_state_desc(struct crypto_tfm *tfm,
 				 struct cipher_req_ctx *req_ctx,
 				 unsigned int ivsize, unsigned int nbytes,
@@ -534,8 +535,6 @@ static void cc_setup_state_desc(struct c
 	int cipher_mode = ctx_p->cipher_mode;
 	int flow_mode = ctx_p->flow_mode;
 	int direction = req_ctx->gen_ctx.op_type;
-	dma_addr_t key_dma_addr = ctx_p->user.key_dma_addr;
-	unsigned int key_len = ctx_p->keylen;
 	dma_addr_t iv_dma_addr = req_ctx->gen_ctx.iv_dma_addr;
 	unsigned int du_size = nbytes;
 
@@ -571,6 +570,47 @@ static void cc_setup_state_desc(struct c
 	case DRV_CIPHER_XTS:
 	case DRV_CIPHER_ESSIV:
 	case DRV_CIPHER_BITLOCKER:
+		break;
+	default:
+		dev_err(dev, "Unsupported cipher mode (%d)\n", cipher_mode);
+	}
+}
+
+
+static void cc_setup_xex_state_desc(struct crypto_tfm *tfm,
+				 struct cipher_req_ctx *req_ctx,
+				 unsigned int ivsize, unsigned int nbytes,
+				 struct cc_hw_desc desc[],
+				 unsigned int *seq_size)
+{
+	struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm);
+	struct device *dev = drvdata_to_dev(ctx_p->drvdata);
+	int cipher_mode = ctx_p->cipher_mode;
+	int flow_mode = ctx_p->flow_mode;
+	int direction = req_ctx->gen_ctx.op_type;
+	dma_addr_t key_dma_addr = ctx_p->user.key_dma_addr;
+	unsigned int key_len = ctx_p->keylen;
+	dma_addr_t iv_dma_addr = req_ctx->gen_ctx.iv_dma_addr;
+	unsigned int du_size = nbytes;
+
+	struct cc_crypto_alg *cc_alg =
+		container_of(tfm->__crt_alg, struct cc_crypto_alg,
+			     skcipher_alg.base);
+
+	if (cc_alg->data_unit)
+		du_size = cc_alg->data_unit;
+
+	switch (cipher_mode) {
+	case DRV_CIPHER_ECB:
+		break;
+	case DRV_CIPHER_CBC:
+	case DRV_CIPHER_CBC_CTS:
+	case DRV_CIPHER_CTR:
+	case DRV_CIPHER_OFB:
+		break;
+	case DRV_CIPHER_XTS:
+	case DRV_CIPHER_ESSIV:
+	case DRV_CIPHER_BITLOCKER:
 		/* load XEX key */
 		hw_desc_init(&desc[*seq_size]);
 		set_cipher_mode(&desc[*seq_size], cipher_mode);
@@ -881,12 +921,14 @@ static int cc_cipher_process(struct skci
 
 	/* STAT_PHASE_2: Create sequence */
 
-	/* Setup IV and XEX key used */
+	/* Setup state (IV)  */
 	cc_setup_state_desc(tfm, req_ctx, ivsize, nbytes, desc, &seq_len);
 	/* Setup MLLI line, if needed */
 	cc_setup_mlli_desc(tfm, req_ctx, dst, src, nbytes, req, desc, &seq_len);
 	/* Setup key */
 	cc_setup_key_desc(tfm, req_ctx, nbytes, desc, &seq_len);
+	/* Setup state (IV and XEX key)  */
+	cc_setup_xex_state_desc(tfm, req_ctx, ivsize, nbytes, desc, &seq_len);
 	/* Data processing */
 	cc_setup_flow_desc(tfm, req_ctx, dst, src, nbytes, desc, &seq_len);
 	/* Read next IV */
author maintainer
#119 lore raw

PATCH 119/367 crypto: ccree - fix PM race condition

In reply to Greg Kroah-Hartman

From: Gilad Ben-Yossef <[email protected]>

commit 15fd2566bf54ee4d4781d8f170acfc9472a1541f upstream.

The PM code was racy, possibly causing the driver to submit requests to a powered down device. Fix the race and while at it simplify the PM code.

Fixes 1358c13a48c4 ("crypto: ccree - fix resume race condition on init")
---
 drivers/crypto/ccree/cc_driver.h      |    1 
 drivers/crypto/ccree/cc_pm.c          |   28 ++++---------------
 drivers/crypto/ccree/cc_request_mgr.c |   50 ----------------------------------
 drivers/crypto/ccree/cc_request_mgr.h |    8 -----
 4 files changed, 7 insertions(+), 80 deletions(-)
drivers/crypto/ccree/cc_driver.h +1 -0
@@ -161,6 +161,7 @@ struct cc_drvdata {
 	int std_bodies;
 	bool sec_disabled;
 	u32 comp_mask;
+	bool pm_on;
 };
 
 struct cc_crypto_alg {
drivers/crypto/ccree/cc_pm.c +6 -22
@@ -22,14 +22,8 @@ const struct dev_pm_ops ccree_pm = {
 int cc_pm_suspend(struct device *dev)
 {
 	struct cc_drvdata *drvdata = dev_get_drvdata(dev);
-	int rc;
 
 	dev_dbg(dev, "set HOST_POWER_DOWN_EN\n");
-	rc = cc_suspend_req_queue(drvdata);
-	if (rc) {
-		dev_err(dev, "cc_suspend_req_queue (%x)\n", rc);
-		return rc;
-	}
 	fini_cc_regs(drvdata);
 	cc_iowrite(drvdata, CC_REG(HOST_POWER_DOWN_EN), POWER_DOWN_ENABLE);
 	cc_clk_off(drvdata);
@@ -63,13 +57,6 @@ int cc_pm_resume(struct device *dev)
 	/* check if tee fips error occurred during power down */
 	cc_tee_handle_fips_error(drvdata);
 
-	rc = cc_resume_req_queue(drvdata);
-	if (rc) {
-		dev_err(dev, "cc_resume_req_queue (%x)\n", rc);
-		return rc;
-	}
-
-	/* must be after the queue resuming as it uses the HW queue*/
 	cc_init_hash_sram(drvdata);
 
 	return 0;
@@ -80,10 +67,8 @@ int cc_pm_get(struct device *dev)
 	int rc = 0;
 	struct cc_drvdata *drvdata = dev_get_drvdata(dev);
 
-	if (cc_req_queue_suspended(drvdata))
+	if (drvdata->pm_on)
 		rc = pm_runtime_get_sync(dev);
-	else
-		pm_runtime_get_noresume(dev);
 
 	return (rc == 1 ? 0 : rc);
 }
@@ -93,14 +78,11 @@ int cc_pm_put_suspend(struct device *dev
 	int rc = 0;
 	struct cc_drvdata *drvdata = dev_get_drvdata(dev);
 
-	if (!cc_req_queue_suspended(drvdata)) {
+	if (drvdata->pm_on) {
 		pm_runtime_mark_last_busy(dev);
 		rc = pm_runtime_put_autosuspend(dev);
-	} else {
-		/* Something wrong happens*/
-		dev_err(dev, "request to suspend already suspended queue");
-		rc = -EBUSY;
 	}
+
 	return rc;
 }
 
@@ -117,7 +99,7 @@ int cc_pm_init(struct cc_drvdata *drvdat
 	/* must be before the enabling to avoid resdundent suspending */
 	pm_runtime_set_autosuspend_delay(dev, CC_SUSPEND_TIMEOUT);
 	pm_runtime_use_autosuspend(dev);
-	/* activate the PM module */
+	/* set us as active - note we won't do PM ops until cc_pm_go()! */
 	return pm_runtime_set_active(dev);
 }
 
@@ -125,9 +107,11 @@ int cc_pm_init(struct cc_drvdata *drvdat
 void cc_pm_go(struct cc_drvdata *drvdata)
 {
 	pm_runtime_enable(drvdata_to_dev(drvdata));
+	drvdata->pm_on = true;
 }
 
 void cc_pm_fini(struct cc_drvdata *drvdata)
 {
 	pm_runtime_disable(drvdata_to_dev(drvdata));
+	drvdata->pm_on = false;
 }
drivers/crypto/ccree/cc_request_mgr.c +0 -50

59 lines not on this page · raw message

drivers/crypto/ccree/cc_request_mgr.h +0 -8
@@ -40,12 +40,4 @@ void complete_request(struct cc_drvdata
 
 void cc_req_mgr_fini(struct cc_drvdata *drvdata);
 
-#if defined(CONFIG_PM)
-int cc_resume_req_queue(struct cc_drvdata *drvdata);
-
-int cc_suspend_req_queue(struct cc_drvdata *drvdata);
-
-bool cc_req_queue_suspended(struct cc_drvdata *drvdata);
-#endif
-
 #endif /*__REQUEST_MGR_H__*/
author maintainer
#120 lore raw

PATCH 120/367 padata: Remove broken queue flushing

In reply to Greg Kroah-Hartman

From: Herbert Xu <[email protected]>

commit 07928d9bfc81640bab36f5190e8725894d93b659 upstream.

The function padata_flush_queues is fundamentally broken because it cannot force padata users to complete the request that is underway. IOW padata has to passively wait for the completion of any outstanding work.

As it stands flushing is used in two places. Its use in padata_stop is simply unnecessary because nothing depends on the queues to be flushed afterwards.

The other use in padata_replace is more substantial as we depend on it to free the old pd structure. This patch instead uses the pd->refcnt to dynamically free the pd structure once all requests are complete.

Fixes 2b73b07ab8a4 ("padata: Flush the padata queues actively")
---
 kernel/padata.c |   43 ++++++++++++-------------------------------
 1 file changed, 12 insertions(+), 31 deletions(-)
kernel/padata.c +12 -31
@@ -35,6 +35,8 @@
 
 #define MAX_OBJ_NUM 1000
 
+static void padata_free_pd(struct parallel_data *pd);
+
 static int padata_index_to_cpu(struct parallel_data *pd, int cpu_index)
 {
 	int cpu, target_cpu;
@@ -283,6 +285,7 @@ static void padata_serial_worker(struct
 	struct padata_serial_queue *squeue;
 	struct parallel_data *pd;
 	LIST_HEAD(local_list);
+	int cnt;
 
 	local_bh_disable();
 	squeue = container_of(serial_work, struct padata_serial_queue, work);
@@ -292,6 +295,8 @@ static void padata_serial_worker(struct
 	list_replace_init(&squeue->serial.list, &local_list);
 	spin_unlock(&squeue->serial.lock);
 
+	cnt = 0;
+
 	while (!list_empty(&local_list)) {
 		struct padata_priv *padata;
 
@@ -301,9 +306,12 @@ static void padata_serial_worker(struct
 		list_del_init(&padata->list);
 
 		padata->serial(padata);
-		atomic_dec(&pd->refcnt);
+		cnt++;
 	}
 	local_bh_enable();
+
+	if (atomic_sub_and_test(cnt, &pd->refcnt))
+		padata_free_pd(pd);
 }
 
 /**
@@ -440,7 +448,7 @@ static struct parallel_data *padata_allo
 	padata_init_squeues(pd);
 	atomic_set(&pd->seq_nr, -1);
 	atomic_set(&pd->reorder_objects, 0);
-	atomic_set(&pd->refcnt, 0);
+	atomic_set(&pd->refcnt, 1);
 	spin_lock_init(&pd->lock);
 	pd->cpu = cpumask_first(pd->cpumask.pcpu);
 	INIT_WORK(&pd->reorder_work, invoke_padata_reorder);
@@ -466,29 +474,6 @@ static void padata_free_pd(struct parall
 	kfree(pd);
 }
 
-/* Flush all objects out of the padata queues. */
-static void padata_flush_queues(struct parallel_data *pd)
-{
-	int cpu;
-	struct padata_parallel_queue *pqueue;
-	struct padata_serial_queue *squeue;
-
-	for_each_cpu(cpu, pd->cpumask.pcpu) {
-		pqueue = per_cpu_ptr(pd->pqueue, cpu);
-		flush_work(&pqueue->work);
-	}
-
-	if (atomic_read(&pd->reorder_objects))
-		padata_reorder(pd);
-
-	for_each_cpu(cpu, pd->cpumask.cbcpu) {
-		squeue = per_cpu_ptr(pd->squeue, cpu);
-		flush_work(&squeue->work);
-	}
-
-	BUG_ON(atomic_read(&pd->refcnt) != 0);
-}
-
 static void __padata_start(struct padata_instance *pinst)
 {
 	pinst->flags |= PADATA_INIT;
@@ -502,10 +487,6 @@ static void __padata_stop(struct padata_
 	pinst->flags &= ~PADATA_INIT;
 
 	synchronize_rcu();
-
-	get_online_cpus();
-	padata_flush_queues(pinst->pd);
-	put_online_cpus();
 }
 
 /* Replace the internal control structure with a new one. */
@@ -526,8 +507,8 @@ static void padata_replace(struct padata
 	if (!cpumask_equal(pd_old->cpumask.cbcpu, pd_new->cpumask.cbcpu))
 		notification_mask |= PADATA_CPU_SERIAL;
 
-	padata_flush_queues(pd_old);
-	padata_free_pd(pd_old);
+	if (atomic_dec_and_test(&pd_old->refcnt))
+		padata_free_pd(pd_old);
 
 	if (notification_mask)
 		blocking_notifier_call_chain(&pinst->cpumask_change_notifier,
author maintainer
#121 lore raw

PATCH 121/367 fs: allow deduplication of eof block into the end of the destination file

In reply to Greg Kroah-Hartman

From: Filipe Manana <[email protected]>

commit a5e6ea18e3d132be4716eb5fdd520c2c234e3003 upstream.

We always round down, to a multiple of the filesystem's block size, the length to deduplicate at generic_remap_check_len(). However this is only needed if an attempt to deduplicate the last block into the middle of the destination file is requested, since that leads into a corruption if the length of the source file is not block size aligned. When an attempt to deduplicate the last block into the end of the destination file is requested, we should allow it because it is safe to do it - there's no stale data exposure and we are prepared to compare the data ranges for a length not aligned to the block (or page) size - in fact we even do the data compare before adjusting the deduplication length.

After btrfs was updated to use the generic helpers from VFS (by commit 34a28e3d77535e ("Btrfs: use generic_remap_file_range_prep() for cloning and deduplication")) we started to have user reports of deduplication not reflinking the last block anymore, and whence users getting lower deduplication scores. The main use case is deduplication of entire files that have a size not aligned to the block size of the filesystem.

We already allow cloning the last block to the end (and beyond) of the destination file, so allow for deduplication as well.

---
 fs/read_write.c |   10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)
fs/read_write.c +4 -6
@@ -1777,10 +1777,9 @@ static int remap_verify_area(struct file
  * else.  Assume that the offsets have already been checked for block
  * alignment.
  *
- * For deduplication we always scale down to the previous block because we
- * can't meaningfully compare post-EOF contents.
- *
- * For clone we only link a partial EOF block above the destination file's EOF.
+ * For clone we only link a partial EOF block above or at the destination file's
+ * EOF.  For deduplication we accept a partial EOF block only if it ends at the
+ * destination file's EOF (can not link it into the middle of a file).
  *
  * Shorten the request if possible.
  */
@@ -1796,8 +1795,7 @@ static int generic_remap_check_len(struc
 	if ((*len & blkmask) == 0)
 		return 0;
 
-	if ((remap_flags & REMAP_FILE_DEDUP) ||
-	    pos_out + *len < i_size_read(inode_out))
+	if (pos_out + *len < i_size_read(inode_out))
 		new_len &= ~blkmask;
 
 	if (new_len == *len)
author maintainer
#122 lore raw

PATCH 122/367 scripts/find-unused-docs: Fix massive false positives

In reply to Greg Kroah-Hartman

From: Geert Uytterhoeven <[email protected]>

commit 1630146db2111412e7524d05d812ff8f2c75977e upstream.

scripts/find-unused-docs.sh invokes scripts/kernel-doc to find out if a source file contains kerneldoc or not.

However, as it passes the no longer supported "-text" option to scripts/kernel-doc, the latter prints out its help text, causing all files to be considered containing kerneldoc.

Get rid of these false positives by removing the no longer supported "-text" option from the scripts/kernel-doc invocation.

Fixes b05142675310d2ac ("scripts: kernel-doc: get rid of unused output formats")
---
 scripts/find-unused-docs.sh |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/find-unused-docs.sh +1 -1
@@ -54,7 +54,7 @@ for file in `find $1 -name '*.c'`; do
 	if [[ ${FILES_INCLUDED[$file]+_} ]]; then
 	continue;
 	fi
-	str=$(scripts/kernel-doc -text -export "$file" 2>/dev/null)
+	str=$(scripts/kernel-doc -export "$file" 2>/dev/null)
 	if [[ -n "$str" ]]; then
 	echo "$file"
 	fi
author maintainer
#123 lore raw

PATCH 123/367 erofs: fix out-of-bound read for shifted uncompressed block

In reply to Greg Kroah-Hartman

From: Gao Xiang <[email protected]>

commit 4d2024370d877f9ac8b98694bcff666da6a5d333 upstream.

rq->out[1] should be valid before accessing. Otherwise, in very rare cases, out-of-bound dirty onstack rq->out[1] can equal to *in and lead to unintended memmove behavior.

Fixes 7fc45dbc938a ("staging: erofs: introduce generic decompression backend")
Cc <[email protected]> # 5.3+
---
 fs/erofs/decompressor.c |   22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)
fs/erofs/decompressor.c +10 -12
@@ -306,24 +306,22 @@ static int z_erofs_shifted_transform(con
 	}
 
 	src = kmap_atomic(*rq->in);
-	if (!rq->out[0]) {
-		dst = NULL;
-	} else {
+	if (rq->out[0]) {
 		dst = kmap_atomic(rq->out[0]);
 		memcpy(dst + rq->pageofs_out, src, righthalf);
+		kunmap_atomic(dst);
 	}
 
-	if (rq->out[1] == *rq->in) {
-		memmove(src, src + righthalf, rq->pageofs_out);
-	} else if (nrpages_out == 2) {
-		if (dst)
-			kunmap_atomic(dst);
+	if (nrpages_out == 2) {
 		DBG_BUGON(!rq->out[1]);
-		dst = kmap_atomic(rq->out[1]);
-		memcpy(dst, src + righthalf, rq->pageofs_out);
+		if (rq->out[1] == *rq->in) {
+			memmove(src, src + righthalf, rq->pageofs_out);
+		} else {
+			dst = kmap_atomic(rq->out[1]);
+			memcpy(dst, src + righthalf, rq->pageofs_out);
+			kunmap_atomic(dst);
+		}
 	}
-	if (dst)
-		kunmap_atomic(dst);
 	kunmap_atomic(src);
 	return 0;
 }
author maintainer
#124 lore raw

PATCH 124/367 scsi: megaraid_sas: Do not initiate OCR if controller is not in ready state

In reply to Greg Kroah-Hartman

From: Anand Lodnoor <[email protected]>

commit 6d7537270e3283b92f9b327da9d58a4de40fe8d0 upstream.

Driver initiates OCR if a DCMD command times out. But there is a deadlock if the driver attempts to invoke another OCR before the mutex lock (reset_mutex) is released from the previous session of OCR.

This patch takes care of the above scenario using new flag MEGASAS_FUSION_OCR_NOT_POSSIBLE to indicate if OCR is possible.

---
 drivers/scsi/megaraid/megaraid_sas_base.c   |    3 ++-
 drivers/scsi/megaraid/megaraid_sas_fusion.c |    3 ++-
 drivers/scsi/megaraid/megaraid_sas_fusion.h |    1 +
 3 files changed, 5 insertions(+), 2 deletions(-)
drivers/scsi/megaraid/megaraid_sas_base.c +2 -1
@@ -4392,7 +4392,8 @@ dcmd_timeout_ocr_possible(struct megasas
 	if (instance->adapter_type == MFI_SERIES)
 		return KILL_ADAPTER;
 	else if (instance->unload ||
-			test_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags))
+			test_bit(MEGASAS_FUSION_OCR_NOT_POSSIBLE,
+				 &instance->reset_flags))
 		return IGNORE_TIMEOUT;
 	else
 		return INITIATE_OCR;
drivers/scsi/megaraid/megaraid_sas_fusion.c +2 -1
@@ -4847,6 +4847,7 @@ int megasas_reset_fusion(struct Scsi_Hos
 	if (instance->requestorId && !instance->skip_heartbeat_timer_del)
 		del_timer_sync(&instance->sriov_heartbeat_timer);
 	set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
+	set_bit(MEGASAS_FUSION_OCR_NOT_POSSIBLE, &instance->reset_flags);
 	atomic_set(&instance->adprecovery, MEGASAS_ADPRESET_SM_POLLING);
 	instance->instancet->disable_intr(instance);
 	megasas_sync_irqs((unsigned long)instance);
@@ -5046,7 +5047,7 @@ kill_hba:
 	instance->skip_heartbeat_timer_del = 1;
 	retval = FAILED;
 out:
-	clear_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
+	clear_bit(MEGASAS_FUSION_OCR_NOT_POSSIBLE, &instance->reset_flags);
 	mutex_unlock(&instance->reset_mutex);
 	return retval;
 }
drivers/scsi/megaraid/megaraid_sas_fusion.h +1 -0
@@ -89,6 +89,7 @@ enum MR_RAID_FLAGS_IO_SUB_TYPE {
 
 #define MEGASAS_FP_CMD_LEN	16
 #define MEGASAS_FUSION_IN_RESET 0
+#define MEGASAS_FUSION_OCR_NOT_POSSIBLE 1
 #define RAID_1_PEER_CMDS 2
 #define JBOD_MAPS_COUNT	2
 #define MEGASAS_REDUCE_QD_COUNT 64
author maintainer
#125 lore raw

PATCH 125/367 scsi: qla2xxx: Fix stuck login session using prli_pend_timer

In reply to Greg Kroah-Hartman

From: Quinn Tran <[email protected]>

commit 8aaac2d7da873aebeba92c666f82c00bbd74aaf9 upstream.

Session is stuck if driver sees FW has received a PRLI. Driver allows FW to finish with processing of PRLI by checking back with FW at a later time to see if the PRLI has finished. Instead, driver failed to push forward after re-checking PRLI completion.

---
 drivers/scsi/qla2xxx/qla_def.h    |    5 +++++
 drivers/scsi/qla2xxx/qla_init.c   |   34 ++++++++++++++++++++++++++--------
 drivers/scsi/qla2xxx/qla_target.c |    1 +
 3 files changed, 32 insertions(+), 8 deletions(-)
drivers/scsi/qla2xxx/qla_def.h +5 -0
@@ -2402,6 +2402,7 @@ typedef struct fc_port {
 	unsigned int scan_needed:1;
 	unsigned int n2n_flag:1;
 	unsigned int explicit_logout:1;
+	unsigned int prli_pend_timer:1;
 
 	struct completion nvme_del_done;
 	uint32_t nvme_prli_service_param;
@@ -2428,6 +2429,7 @@ typedef struct fc_port {
 	struct work_struct free_work;
 	struct work_struct reg_work;
 	uint64_t jiffies_at_registration;
+	unsigned long prli_expired;
 	struct qlt_plogi_ack_t *plogi_link[QLT_PLOGI_LINK_MAX];
 
 	uint16_t tgt_id;
@@ -4845,6 +4847,9 @@ struct sff_8247_a0 {
 	(ha->fc4_type_priority == FC4_PRIORITY_NVME)) || \
 	NVME_ONLY_TARGET(fcport)) \
 
+#define PRLI_PHASE(_cls) \
+	((_cls == DSC_LS_PRLI_PEND) || (_cls == DSC_LS_PRLI_COMP))
+
 #include "qla_target.h"
 #include "qla_gbl.h"
 #include "qla_dbg.h"
drivers/scsi/qla2xxx/qla_init.c +26 -8
@@ -685,7 +685,7 @@ static void qla24xx_handle_gnl_done_even
 	port_id_t id;
 	u64 wwn;
 	u16 data[2];
-	u8 current_login_state;
+	u8 current_login_state, nvme_cls;
 
 	fcport = ea->fcport;
 	ql_dbg(ql_dbg_disc, vha, 0xffff,
@@ -744,10 +744,17 @@ static void qla24xx_handle_gnl_done_even
 
 		loop_id = le16_to_cpu(e->nport_handle);
 		loop_id = (loop_id & 0x7fff);
-		if (NVME_TARGET(vha->hw, fcport))
-			current_login_state = e->current_login_state >> 4;
-		else
-			current_login_state = e->current_login_state & 0xf;
+		nvme_cls = e->current_login_state >> 4;
+		current_login_state = e->current_login_state & 0xf;
+
+		if (PRLI_PHASE(nvme_cls)) {
+			current_login_state = nvme_cls;
+			fcport->fc4_type &= ~FS_FC4TYPE_FCP;
+			fcport->fc4_type |= FS_FC4TYPE_NVME;
+		} else if (PRLI_PHASE(current_login_state)) {
+			fcport->fc4_type |= FS_FC4TYPE_FCP;
+			fcport->fc4_type &= ~FS_FC4TYPE_NVME;
+		}
 
 		ql_dbg(ql_dbg_disc, vha, 0x20e2,
 		    "%s found %8phC CLS [%x|%x] fc4_type %d ID[%06x|%06x] lid[%d|%d]\n",
@@ -1216,12 +1223,19 @@ qla24xx_async_prli(struct scsi_qla_host
 	struct srb_iocb *lio;
 	int rval = QLA_FUNCTION_FAILED;
 
-	if (!vha->flags.online)
+	if (!vha->flags.online) {
+		ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d %8phC exit\n",
+		    __func__, __LINE__, fcport->port_name);
 		return rval;
+	}
 
-	if (fcport->fw_login_state == DSC_LS_PLOGI_PEND ||
-	    fcport->fw_login_state == DSC_LS_PRLI_PEND)
+	if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND ||
+	    fcport->fw_login_state == DSC_LS_PRLI_PEND) &&
+	    qla_dual_mode_enabled(vha)) {
+		ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d %8phC exit\n",
+		    __func__, __LINE__, fcport->port_name);
 		return rval;
+	}
 
 	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
 	if (!sp)
@@ -1600,6 +1614,10 @@ int qla24xx_fcport_handle_login(struct s
 			break;
 		default:
 			if (fcport->login_pause) {
+				ql_dbg(ql_dbg_disc, vha, 0x20d8,
+				    "%s %d %8phC exit\n",
+				    __func__, __LINE__,
+				    fcport->port_name);
 				fcport->last_rscn_gen = fcport->rscn_gen;
 				fcport->last_login_gen = fcport->login_gen;
 				set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
drivers/scsi/qla2xxx/qla_target.c +1 -0
@@ -1257,6 +1257,7 @@ void qlt_schedule_sess_for_deletion(stru
 	sess->deleted = QLA_SESS_DELETION_IN_PROGRESS;
 	spin_unlock_irqrestore(&sess->vha->work_lock, flags);
 
+	sess->prli_pend_timer = 0;
 	sess->disc_state = DSC_DELETE_PEND;
 
 	qla24xx_chk_fcp_state(sess);
author maintainer
#126 lore raw

PATCH 126/367 scsi: qla2xxx: Fix mtcp dump collection failure

In reply to Greg Kroah-Hartman

From: Quinn Tran <[email protected]>

commit 641e0efddcbde52461e017136acd3ce7f2ef0c14 upstream.

MTCP dump failed due to MB Reg 10 was picking garbage data from stack memory.

---
 drivers/scsi/qla2xxx/qla_mbx.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/scsi/qla2xxx/qla_mbx.c +1 -2
@@ -6152,9 +6152,8 @@ qla2x00_dump_mctp_data(scsi_qla_host_t *
 	mcp->mb[7] = LSW(MSD(req_dma));
 	mcp->mb[8] = MSW(addr);
 	/* Setting RAM ID to valid */
-	mcp->mb[10] |= BIT_7;
 	/* For MCTP RAM ID is 0x40 */
-	mcp->mb[10] |= 0x40;
+	mcp->mb[10] = BIT_7 | 0x40;
 
 	mcp->out_mb |= MBX_10|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
 	    MBX_0;
author maintainer
#127 lore raw

PATCH 127/367 cpupower: Revert library ABI changes from commit ae2917093fb60bdc1ed3e

In reply to Greg Kroah-Hartman

From: Thomas Renninger <[email protected]>

commit 41ddb7e1f79693d904502ae9bea609837973eff8 upstream.

Commit ae2917093fb6 ("tools/power/cpupower: Display boost frequency separately") modified the library function:

struct cpufreq_available_frequencies *cpufreq_get_available_frequencies(unsigned int cpu)

to
struct cpufreq_frequencies *cpufreq_get_frequencies(const char *type, unsigned int cpu)

This patch recovers the old API and implements the new functionality in a newly introduce method:
struct cpufreq_boost_frequencies *cpufreq_get_available_frequencies(unsigned int cpu)

This one should get merged into stable kernels back to 5.0 when the above had been introduced.

Fixes ae2917093fb6 ("tools/power/cpupower: Display boost frequency separately")
---
 tools/power/cpupower/lib/cpufreq.c        |   78 ++++++++++++++++++++++++++----
 tools/power/cpupower/lib/cpufreq.h        |   20 +++++--
 tools/power/cpupower/utils/cpufreq-info.c |   12 ++--
 3 files changed, 87 insertions(+), 23 deletions(-)
tools/power/cpupower/lib/cpufreq.c +68 -10
@@ -332,21 +332,74 @@ void cpufreq_put_available_governors(str
 }
 
 
-struct cpufreq_frequencies
-*cpufreq_get_frequencies(const char *type, unsigned int cpu)
+struct cpufreq_available_frequencies
+*cpufreq_get_available_frequencies(unsigned int cpu)
 {
-	struct cpufreq_frequencies *first = NULL;
-	struct cpufreq_frequencies *current = NULL;
+	struct cpufreq_available_frequencies *first = NULL;
+	struct cpufreq_available_frequencies *current = NULL;
 	char one_value[SYSFS_PATH_MAX];
 	char linebuf[MAX_LINE_LEN];
-	char fname[MAX_LINE_LEN];
 	unsigned int pos, i;
 	unsigned int len;
 
-	snprintf(fname, MAX_LINE_LEN, "scaling_%s_frequencies", type);
+	len = sysfs_cpufreq_read_file(cpu, "scaling_available_frequencies",
+				      linebuf, sizeof(linebuf));
+	if (len == 0)
+		return NULL;
+
+	pos = 0;
+	for (i = 0; i < len; i++) {
+		if (linebuf[i] == ' ' || linebuf[i] == '\n') {
+			if (i - pos < 2)
+				continue;
+			if (i - pos >= SYSFS_PATH_MAX)
+				goto error_out;
+			if (current) {
+				current->next = malloc(sizeof(*current));
+				if (!current->next)
+					goto error_out;
+				current = current->next;
+			} else {
+				first = malloc(sizeof(*first));
+				if (!first)
+					goto error_out;
+				current = first;
+			}
+			current->first = first;
+			current->next = NULL;
+
+			memcpy(one_value, linebuf + pos, i - pos);
+			one_value[i - pos] = '\0';
+			if (sscanf(one_value, "%lu", &current->frequency) != 1)
+				goto error_out;
+
+			pos = i + 1;
+		}
+	}
+
+	return first;
+
+ error_out:
+	while (first) {
+		current = first->next;
+		free(first);
+		first = current;
+	}
+	return NULL;
+}
 
-	len = sysfs_cpufreq_read_file(cpu, fname,
-				linebuf, sizeof(linebuf));
+struct cpufreq_available_frequencies
+*cpufreq_get_boost_frequencies(unsigned int cpu)
+{
+	struct cpufreq_available_frequencies *first = NULL;
+	struct cpufreq_available_frequencies *current = NULL;
+	char one_value[SYSFS_PATH_MAX];
+	char linebuf[MAX_LINE_LEN];
+	unsigned int pos, i;
+	unsigned int len;
+
+	len = sysfs_cpufreq_read_file(cpu, "scaling_boost_frequencies",
+				      linebuf, sizeof(linebuf));
 	if (len == 0)
 		return NULL;
 
@@ -391,9 +444,9 @@ struct cpufreq_frequencies
 	return NULL;
 }
 
-void cpufreq_put_frequencies(struct cpufreq_frequencies *any)
+void cpufreq_put_available_frequencies(struct cpufreq_available_frequencies *any)
 {
-	struct cpufreq_frequencies *tmp, *next;
+	struct cpufreq_available_frequencies *tmp, *next;
 
 	if (!any)
 		return;
@@ -406,6 +459,11 @@ void cpufreq_put_frequencies(struct cpuf
 	}
 }
 
+void cpufreq_put_boost_frequencies(struct cpufreq_available_frequencies *any)
+{
+	cpufreq_put_available_frequencies(any);
+}
+
 static struct cpufreq_affected_cpus *sysfs_get_cpu_list(unsigned int cpu,
 							const char *file)
 {
tools/power/cpupower/lib/cpufreq.h +13 -7
@@ -20,10 +20,10 @@ struct cpufreq_available_governors {
 	struct cpufreq_available_governors *first;
 };
 
-struct cpufreq_frequencies {
+struct cpufreq_available_frequencies {
 	unsigned long frequency;
-	struct cpufreq_frequencies *next;
-	struct cpufreq_frequencies *first;
+	struct cpufreq_available_frequencies *next;
+	struct cpufreq_available_frequencies *first;
 };
 
 
@@ -124,11 +124,17 @@ void cpufreq_put_available_governors(
  * cpufreq_put_frequencies after use.
  */
 
-struct cpufreq_frequencies
-*cpufreq_get_frequencies(const char *type, unsigned int cpu);
+struct cpufreq_available_frequencies
+*cpufreq_get_available_frequencies(unsigned int cpu);
 
-void cpufreq_put_frequencies(
-		struct cpufreq_frequencies *first);
+void cpufreq_put_available_frequencies(
+		struct cpufreq_available_frequencies *first);
+
+struct cpufreq_available_frequencies
+*cpufreq_get_boost_frequencies(unsigned int cpu);
+
+void cpufreq_put_boost_frequencies(
+		struct cpufreq_available_frequencies *first);
 
 
 /* determine affected CPUs
tools/power/cpupower/utils/cpufreq-info.c +6 -6
@@ -244,14 +244,14 @@ static int get_boost_mode_x86(unsigned i
 
 static int get_boost_mode(unsigned int cpu)
 {
-	struct cpufreq_frequencies *freqs;
+	struct cpufreq_available_frequencies *freqs;
 
 	if (cpupower_cpu_info.vendor == X86_VENDOR_AMD ||
 	    cpupower_cpu_info.vendor == X86_VENDOR_HYGON ||
 	    cpupower_cpu_info.vendor == X86_VENDOR_INTEL)
 		return get_boost_mode_x86(cpu);
 
-	freqs = cpufreq_get_frequencies("boost", cpu);
+	freqs = cpufreq_get_boost_frequencies(cpu);
 	if (freqs) {
 		printf(_("  boost frequency steps: "));
 		while (freqs->next) {
@@ -261,7 +261,7 @@ static int get_boost_mode(unsigned int c
 		}
 		print_speed(freqs->frequency);
 		printf("\n");
-		cpufreq_put_frequencies(freqs);
+		cpufreq_put_available_frequencies(freqs);
 	}
 
 	return 0;
@@ -475,7 +475,7 @@ static int get_latency(unsigned int cpu,
 
 static void debug_output_one(unsigned int cpu)
 {
-	struct cpufreq_frequencies *freqs;
+	struct cpufreq_available_frequencies *freqs;
 
 	get_driver(cpu);
 	get_related_cpus(cpu);
@@ -483,7 +483,7 @@ static void debug_output_one(unsigned in
 	get_latency(cpu, 1);
 	get_hardware_limits(cpu, 1);
 
-	freqs = cpufreq_get_frequencies("available", cpu);
+	freqs = cpufreq_get_available_frequencies(cpu);
 	if (freqs) {
 		printf(_("  available frequency steps:  "));
 		while (freqs->next) {
@@ -493,7 +493,7 @@ static void debug_output_one(unsigned in
 		}
 		print_speed(freqs->frequency);
 		printf("\n");
-		cpufreq_put_frequencies(freqs);
+		cpufreq_put_available_frequencies(freqs);
 	}
 
 	get_available_governors(cpu);
author maintainer
#128 lore raw

PATCH 128/367 power: supply: axp20x_ac_power: Fix reporting online status

In reply to Greg Kroah-Hartman

From: Samuel Holland <[email protected]>

commit 1c51aad8475d670ad58ae60adc9d32342381df8d upstream.

AXP803/AXP813 have a flag that enables/disables the AC power supply input. This flag does not affect the status bits in PWR_INPUT_STATUS. Its effect can be verified by checking the battery charge/discharge state (bit 2 of PWR_INPUT_STATUS), or by examining the current draw on the AC input.

Take this flag into account when getting the ONLINE property of the AC input, on PMICs where this flag is present.

Fixes 7693b5643fd2 ("power: supply: add AC power supply driver for AXP813")
---
 drivers/power/supply/axp20x_ac_power.c |   31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)
drivers/power/supply/axp20x_ac_power.c +25 -6
@@ -23,6 +23,8 @@
 #define AXP20X_PWR_STATUS_ACIN_PRESENT	BIT(7)
 #define AXP20X_PWR_STATUS_ACIN_AVAIL	BIT(6)
 
+#define AXP813_ACIN_PATH_SEL		BIT(7)
+
 #define AXP813_VHOLD_MASK		GENMASK(5, 3)
 #define AXP813_VHOLD_UV_TO_BIT(x)	((((x) / 100000) - 40) << 3)
 #define AXP813_VHOLD_REG_TO_UV(x)	\
@@ -40,6 +42,7 @@ struct axp20x_ac_power {
 	struct power_supply *supply;
 	struct iio_channel *acin_v;
 	struct iio_channel *acin_i;
+	bool has_acin_path_sel;
 };
 
 static irqreturn_t axp20x_ac_power_irq(int irq, void *devid)
@@ -86,6 +89,17 @@ static int axp20x_ac_power_get_property(
 			return ret;
 
 		val->intval = !!(reg & AXP20X_PWR_STATUS_ACIN_AVAIL);
+
+		/* ACIN_PATH_SEL disables ACIN even if ACIN_AVAIL is set. */
+		if (val->intval && power->has_acin_path_sel) {
+			ret = regmap_read(power->regmap, AXP813_ACIN_PATH_CTRL,
+					  &reg);
+			if (ret)
+				return ret;
+
+			val->intval = !!(reg & AXP813_ACIN_PATH_SEL);
+		}
+
 		return 0;
 
 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
@@ -224,21 +238,25 @@ static const struct power_supply_desc ax
 struct axp_data {
 	const struct power_supply_desc	*power_desc;
 	bool				acin_adc;
+	bool				acin_path_sel;
 };
 
 static const struct axp_data axp20x_data = {
-	.power_desc = &axp20x_ac_power_desc,
-	.acin_adc = true,
+	.power_desc	= &axp20x_ac_power_desc,
+	.acin_adc	= true,
+	.acin_path_sel	= false,
 };
 
 static const struct axp_data axp22x_data = {
-	.power_desc = &axp22x_ac_power_desc,
-	.acin_adc = false,
+	.power_desc	= &axp22x_ac_power_desc,
+	.acin_adc	= false,
+	.acin_path_sel	= false,
 };
 
 static const struct axp_data axp813_data = {
-	.power_desc = &axp813_ac_power_desc,
-	.acin_adc = false,
+	.power_desc	= &axp813_ac_power_desc,
+	.acin_adc	= false,
+	.acin_path_sel	= true,
 };
 
 static int axp20x_ac_power_probe(struct platform_device *pdev)
@@ -282,6 +300,7 @@ static int axp20x_ac_power_probe(struct
 	}
 
 	power->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	power->has_acin_path_sel = axp_data->acin_path_sel;
 
 	platform_set_drvdata(pdev, power);
 
author maintainer
#129 lore raw

PATCH 129/367 power: supply: ltc2941-battery-gauge: fix use-after-free

In reply to Greg Kroah-Hartman

From: Sven Van Asbroeck <[email protected]>

commit a60ec78d306c6548d4adbc7918b587a723c555cc upstream.

This driver's remove path calls cancel_delayed_work(). However, that function does not wait until the work function finishes. This could mean that the work function is still running after the driver's remove function has finished, which would result in a use-after-free.

Fix by calling cancel_delayed_work_sync(), which ensures that that the work is properly cancelled, no longer running, and unable to re-schedule itself.

This issue was detected with the help of Coccinelle.

---
 drivers/power/supply/ltc2941-battery-gauge.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/power/supply/ltc2941-battery-gauge.c +1 -1
@@ -449,7 +449,7 @@ static int ltc294x_i2c_remove(struct i2c
 {
 	struct ltc294x_info *info = i2c_get_clientdata(client);
 
-	cancel_delayed_work(&info->work);
+	cancel_delayed_work_sync(&info->work);
 	power_supply_unregister(info->supply);
 	return 0;
 }
author maintainer
#130 lore raw

PATCH 130/367 ovl: fix wrong WARN_ON() in ovl_cache_update_ino()

In reply to Greg Kroah-Hartman

From: Amir Goldstein <[email protected]>

commit 4c37e71b713ecffe81f8e6273c6835e54306d412 upstream.

The WARN_ON() that child entry is always on overlay st_dev became wrong when we allowed this function to update d_ino in non-samefs setup with xino enabled.

It is not true in case of xino bits overflow on a non-dir inode. Leave the WARN_ON() only for directories, where assertion is still true.

Fixes adbf4f7ea834 ("ovl: consistent d_ino for non-samefs with xino")
Cc <[email protected]> # v4.17+
---
 fs/overlayfs/readdir.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
fs/overlayfs/readdir.c +7 -1
@@ -504,7 +504,13 @@ get:
 		if (err)
 			goto fail;
 
-		WARN_ON_ONCE(dir->d_sb->s_dev != stat.dev);
+		/*
+		 * Directory inode is always on overlay st_dev.
+		 * Non-dir with ovl_same_dev() could be on pseudo st_dev in case
+		 * of xino bits overflow.
+		 */
+		WARN_ON_ONCE(S_ISDIR(stat.mode) &&
+			     dir->d_sb->s_dev != stat.dev);
 		ino = stat.ino;
 	} else if (xinobits && !OVL_TYPE_UPPER(type)) {
 		ino = ovl_remap_lower_ino(ino, xinobits,
author maintainer
#131 lore raw

PATCH 131/367 ovl: fix lseek overflow on 32bit

In reply to Greg Kroah-Hartman

From: Miklos Szeredi <[email protected]>

commit a4ac9d45c0cd14a2adc872186431c79804b77dbf upstream.

ovl_lseek() is using ssize_t to return the value from vfs_llseek(). On a 32-bit kernel ssize_t is a 32-bit signed int, which overflows above 2 GB.

Assign the return value of vfs_llseek() to loff_t to fix this.

Fixes 9e46b840c705 ("ovl: support stacked SEEK_HOLE/SEEK_DATA")
Cc <[email protected]> # v4.19
---
 fs/overlayfs/file.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/overlayfs/file.c +1 -1
@@ -146,7 +146,7 @@ static loff_t ovl_llseek(struct file *fi
 	struct inode *inode = file_inode(file);
 	struct fd real;
 	const struct cred *old_cred;
-	ssize_t ret;
+	loff_t ret;
 
 	/*
 	 * The two special cases below do not need to involve real fs,
author maintainer
#132 lore raw

PATCH 132/367 f2fs: fix miscounted block limit in f2fs_statfs_project()

In reply to Greg Kroah-Hartman

From: Chengguang Xu <[email protected]>

commit acdf2172172a511f97fa21ed0ee7609a6d3b3a07 upstream.

statfs calculates Total/Used/Avail disk space in block unit, so we should translate soft/hard prjquota limit to block unit as well.

Below testing result shows the block/inode numbers of Total/Used/Avail from df command are all correct afer applying this patch.

[root@localhost quota-tools]\# ./repquota -P /dev/sdb1

---
 fs/f2fs/super.c |    2 ++
 1 file changed, 2 insertions(+)
fs/f2fs/super.c +2 -0
@@ -1219,6 +1219,8 @@ static int f2fs_statfs_project(struct su
 	if (dquot->dq_dqb.dqb_bhardlimit &&
 			(!limit || dquot->dq_dqb.dqb_bhardlimit < limit))
 		limit = dquot->dq_dqb.dqb_bhardlimit;
+	if (limit)
+		limit >>= sb->s_blocksize_bits;
 
 	if (limit && buf->f_blocks > limit) {
 		curblock = dquot->dq_dqb.dqb_curspace >> sb->s_blocksize_bits;
author maintainer
#133 lore raw

PATCH 133/367 f2fs: code cleanup for f2fs_statfs_project()

In reply to Greg Kroah-Hartman

From: Chengguang Xu <[email protected]>

commit bf2cbd3c57159c2b639ee8797b52ab5af180bf83 upstream.

Calling min_not_zero() to simplify complicated prjquota limit comparison in f2fs_statfs_project().

---
 fs/f2fs/super.c |   16 ++++------------
 1 file changed, 4 insertions(+), 12 deletions(-)
fs/f2fs/super.c +4 -12
@@ -1213,12 +1213,8 @@ static int f2fs_statfs_project(struct su
 		return PTR_ERR(dquot);
 	spin_lock(&dquot->dq_dqb_lock);
 
-	limit = 0;
-	if (dquot->dq_dqb.dqb_bsoftlimit)
-		limit = dquot->dq_dqb.dqb_bsoftlimit;
-	if (dquot->dq_dqb.dqb_bhardlimit &&
-			(!limit || dquot->dq_dqb.dqb_bhardlimit < limit))
-		limit = dquot->dq_dqb.dqb_bhardlimit;
+	limit = min_not_zero(dquot->dq_dqb.dqb_bsoftlimit,
+					dquot->dq_dqb.dqb_bhardlimit);
 	if (limit)
 		limit >>= sb->s_blocksize_bits;
 
@@ -1230,12 +1226,8 @@ static int f2fs_statfs_project(struct su
 			 (buf->f_blocks - curblock) : 0;
 	}
 
-	limit = 0;
-	if (dquot->dq_dqb.dqb_isoftlimit)
-		limit = dquot->dq_dqb.dqb_isoftlimit;
-	if (dquot->dq_dqb.dqb_ihardlimit &&
-			(!limit || dquot->dq_dqb.dqb_ihardlimit < limit))
-		limit = dquot->dq_dqb.dqb_ihardlimit;
+	limit = min_not_zero(dquot->dq_dqb.dqb_isoftlimit,
+					dquot->dq_dqb.dqb_ihardlimit);
 
 	if (limit && buf->f_files > limit) {
 		buf->f_files = limit;
author maintainer
#134 lore raw

PATCH 134/367 f2fs: fix dcache lookup of !casefolded directories

In reply to Greg Kroah-Hartman

From: Eric Biggers <[email protected]>

commit 5515eae647426169e4b7969271fb207881eba7f6 upstream.

Do the name comparison for non-casefolded directories correctly.

This is analogous to ext4's commit 66883da1eee8 ("ext4: fix dcache lookup of !casefolded directories").

Fixes 2c2eb7a300cd ("f2fs: Support case-insensitive file name lookups")
Cc <[email protected]> # v5.4+
---
 fs/f2fs/dir.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/f2fs/dir.c +1 -1
@@ -1073,7 +1073,7 @@ static int f2fs_d_compare(const struct d
 	if (!IS_CASEFOLDED(dentry->d_parent->d_inode)) {
 		if (len != name->len)
 			return -1;
-		return memcmp(str, name, len);
+		return memcmp(str, name->name, len);
 	}
 
 	return f2fs_ci_compare(dentry->d_parent->d_inode, name, &qstr, false);
author maintainer
#135 lore raw

PATCH 135/367 f2fs: fix race conditions in ->d_compare() and ->d_hash()

In reply to Greg Kroah-Hartman

From: Eric Biggers <[email protected]>

commit 80f2388afa6ef985f9c5c228e36705c4d4db4756 upstream.

Since ->d_compare() and ->d_hash() can be called in RCU-walk mode, ->d_parent and ->d_inode can be concurrently modified, and in particular, ->d_inode may be changed to NULL. For f2fs_d_hash() this resulted in a reproducible NULL dereference if a lookup is done in a directory being deleted, e.g. with:

	int main()
	{
		if (fork()) {
			for (;;) {
				mkdir("subdir", 0700);
				rmdir("subdir");
			}
		} else {
			for (;;)
				access("subdir/file", 0);
		}
	}

... or by running the 't_encrypted_d_revalidate' program from xfstests. Both repros work in any directory on a filesystem with the encoding feature, even if the directory doesn't actually have the casefold flag.

I couldn't reproduce a crash in f2fs_d_compare(), but it appears that a similar crash is possible there.

Fix these bugs by reading ->d_parent and ->d_inode using READ_ONCE() and falling back to the case sensitive behavior if the inode is NULL.

Fixes 2c2eb7a300cd ("f2fs: Support case-insensitive file name lookups")
Cc <[email protected]> # v5.4+
---
 fs/f2fs/dir.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
fs/f2fs/dir.c +6 -3
@@ -1069,24 +1069,27 @@ static int f2fs_d_compare(const struct d
 			  const char *str, const struct qstr *name)
 {
 	struct qstr qstr = {.name = str, .len = len };
+	const struct dentry *parent = READ_ONCE(dentry->d_parent);
+	const struct inode *inode = READ_ONCE(parent->d_inode);
 
-	if (!IS_CASEFOLDED(dentry->d_parent->d_inode)) {
+	if (!inode || !IS_CASEFOLDED(inode)) {
 		if (len != name->len)
 			return -1;
 		return memcmp(str, name->name, len);
 	}
 
-	return f2fs_ci_compare(dentry->d_parent->d_inode, name, &qstr, false);
+	return f2fs_ci_compare(inode, name, &qstr, false);
 }
 
 static int f2fs_d_hash(const struct dentry *dentry, struct qstr *str)
 {
 	struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
 	const struct unicode_map *um = sbi->s_encoding;
+	const struct inode *inode = READ_ONCE(dentry->d_inode);
 	unsigned char *norm;
 	int len, ret = 0;
 
-	if (!IS_CASEFOLDED(dentry->d_inode))
+	if (!inode || !IS_CASEFOLDED(inode))
 		return 0;
 
 	norm = f2fs_kmalloc(sbi, PATH_MAX, GFP_ATOMIC);
author maintainer
#136 lore raw

PATCH 136/367 PM: core: Fix handling of devices deleted during system-wide resume

In reply to Greg Kroah-Hartman

From: Rafael J. Wysocki <[email protected]>

commit 0552e05fdfea191a2cf3a0abd33574b5ef9ca818 upstream.

If a device is deleted by one of its system-wide resume callbacks (for example, because it does not appear to be present or accessible any more) along with its children, the resume of the children may continue leading to use-after-free errors and other issues (potentially).

Namely, if the device's children are resumed asynchronously, their resume may have been scheduled already before the device's callback runs and so the device may be deleted while dpm_wait_for_superior() is being executed for them. The memory taken up by the parent device object may be freed then while dpm_wait() is waiting for the parent's resume callback to complete, which leads to a use-after-free. Moreover, the resume of the children is really not expected to continue after they have been unregistered, so it must be terminated right away in that case.

To address this problem, modify dpm_wait_for_superior() to check if the target device is still there in the system-wide PM list of devices and if so, to increment its parent's reference counter, both under dpm_list_mtx which prevents device_del() running for the child from dropping the parent's reference counter prematurely.

If the device is not present in the system-wide PM list of devices any more, the resume of it cannot continue, so check that again after dpm_wait() returns, which means that the parent's callback has been completed, and pass the result of that check to the caller of dpm_wait_for_superior() to allow it to abort the device's resume if it is not there any more.

---
 drivers/base/power/main.c |   42 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 37 insertions(+), 5 deletions(-)
drivers/base/power/main.c +37 -5
@@ -273,10 +273,38 @@ static void dpm_wait_for_suppliers(struc
 	device_links_read_unlock(idx);
 }
 
-static void dpm_wait_for_superior(struct device *dev, bool async)
+static bool dpm_wait_for_superior(struct device *dev, bool async)
 {
-	dpm_wait(dev->parent, async);
+	struct device *parent;
+
+	/*
+	 * If the device is resumed asynchronously and the parent's callback
+	 * deletes both the device and the parent itself, the parent object may
+	 * be freed while this function is running, so avoid that by reference
+	 * counting the parent once more unless the device has been deleted
+	 * already (in which case return right away).
+	 */
+	mutex_lock(&dpm_list_mtx);
+
+	if (!device_pm_initialized(dev)) {
+		mutex_unlock(&dpm_list_mtx);
+		return false;
+	}
+
+	parent = get_device(dev->parent);
+
+	mutex_unlock(&dpm_list_mtx);
+
+	dpm_wait(parent, async);
+	put_device(parent);
+
 	dpm_wait_for_suppliers(dev, async);
+
+	/*
+	 * If the parent's callback has deleted the device, attempting to resume
+	 * it would be invalid, so avoid doing that then.
+	 */
+	return device_pm_initialized(dev);
 }
 
 static void dpm_wait_for_consumers(struct device *dev, bool async)
@@ -621,7 +649,8 @@ static int device_resume_noirq(struct de
 	if (!dev->power.is_noirq_suspended)
 		goto Out;
 
-	dpm_wait_for_superior(dev, async);
+	if (!dpm_wait_for_superior(dev, async))
+		goto Out;
 
 	skip_resume = dev_pm_may_skip_resume(dev);
 
@@ -829,7 +858,8 @@ static int device_resume_early(struct de
 	if (!dev->power.is_late_suspended)
 		goto Out;
 
-	dpm_wait_for_superior(dev, async);
+	if (!dpm_wait_for_superior(dev, async))
+		goto Out;
 
 	callback = dpm_subsys_resume_early_cb(dev, state, &info);
 
@@ -944,7 +974,9 @@ static int device_resume(struct device *
 		goto Complete;
 	}
 
-	dpm_wait_for_superior(dev, async);
+	if (!dpm_wait_for_superior(dev, async))
+		goto Complete;
+
 	dpm_watchdog_set(&wd, dev);
 	device_lock(dev);
 
author maintainer
#137 lore raw

PATCH 137/367 cpufreq: Avoid creating excessively large stack frames

In reply to Greg Kroah-Hartman

From: Rafael J. Wysocki <[email protected]>

commit 1e4f63aecb53e48468661e922fc2fa3b83e55722 upstream.

In the process of modifying a cpufreq policy, the cpufreq core makes a copy of it including all of the internals which is stored on the CPU stack. Because struct cpufreq_policy is relatively large, this may cause the size of the stack frame to exceed the 2 KB limit and so the GCC complains when -Wframe-larger-than= is used.

In fact, it is not necessary to copy the entire policy structure in order to modify it, however.

First, because cpufreq_set_policy() obtains the min and max policy limits from frequency QoS now, it is not necessary to pass the limits to it from the callers. The only things that need to be passed to it from there are the new governor pointer or (if there is a built-in governor in the driver) the "policy" value representing the governor choice. They both can be passed as individual arguments, though, so make cpufreq_set_policy() take them this way and rework its callers accordingly. This avoids making copies of cpufreq policies in the callers of cpufreq_set_policy().

Second, cpufreq_set_policy() still needs to pass the new policy data to the ->verify() callback of the cpufreq driver whose task is to sanitize the min and max policy limits. It still does not need to make a full copy of struct cpufreq_policy for this purpose, but it needs to pass a few items from it to the driver in case they are needed (different drivers have different needs in that respect and all of them have to be covered). For this reason, introduce struct cpufreq_policy_data to hold copies of the members of struct cpufreq_policy used by the existing ->verify() driver callbacks and pass a pointer to a temporary structure of that type to ->verify() (instead of passing a pointer to full struct cpufreq_policy to it).

While at it, notice that intel_pstate and longrun don't really need to verify the "policy" value in struct cpufreq_policy, so drop those check from them to avoid copying "policy" into struct cpufreq_policy_data (which allows it to be slightly smaller).

Also while at it fix up white space in a couple of places and make cpufreq_set_policy() static (as it can be so).

---
 drivers/cpufreq/cppc_cpufreq.c     |    2 
 drivers/cpufreq/cpufreq-nforce2.c  |    2 
 drivers/cpufreq/cpufreq.c          |  147 +++++++++++++++++--------------------
 drivers/cpufreq/freq_table.c       |    4 -
 drivers/cpufreq/gx-suspmod.c       |    2 
 drivers/cpufreq/intel_pstate.c     |   38 ++++-----
 drivers/cpufreq/longrun.c          |    6 -
 drivers/cpufreq/pcc-cpufreq.c      |    2 
 drivers/cpufreq/sh-cpufreq.c       |    2 
 drivers/cpufreq/unicore2-cpufreq.c |    2 
 include/linux/cpufreq.h            |   32 +++++---
 11 files changed, 119 insertions(+), 120 deletions(-)
drivers/cpufreq/cppc_cpufreq.c +1 -1
@@ -217,7 +217,7 @@ static int cppc_cpufreq_set_target(struc
 	return ret;
 }
 
-static int cppc_verify_policy(struct cpufreq_policy *policy)
+static int cppc_verify_policy(struct cpufreq_policy_data *policy)
 {
 	cpufreq_verify_within_cpu_limits(policy);
 	return 0;
drivers/cpufreq/cpufreq-nforce2.c +1 -1
@@ -291,7 +291,7 @@ static int nforce2_target(struct cpufreq
  * nforce2_verify - verifies a new CPUFreq policy
  * @policy: new policy
  */
-static int nforce2_verify(struct cpufreq_policy *policy)
+static int nforce2_verify(struct cpufreq_policy_data *policy)
 {
 	unsigned int fsb_pol_max;
 
drivers/cpufreq/cpufreq.c +70 -77

266 lines not on this page · raw message

drivers/cpufreq/freq_table.c +2 -2
@@ -60,7 +60,7 @@ int cpufreq_frequency_table_cpuinfo(stru
 		return 0;
 }
 
-int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
+int cpufreq_frequency_table_verify(struct cpufreq_policy_data *policy,
 				   struct cpufreq_frequency_table *table)
 {
 	struct cpufreq_frequency_table *pos;
@@ -100,7 +100,7 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_tabl
  * Generic routine to verify policy & frequency table, requires driver to set
  * policy->freq_table prior to it.
  */
-int cpufreq_generic_frequency_table_verify(struct cpufreq_policy *policy)
+int cpufreq_generic_frequency_table_verify(struct cpufreq_policy_data *policy)
 {
 	if (!policy->freq_table)
 		return -ENODEV;
drivers/cpufreq/gx-suspmod.c +1 -1
@@ -328,7 +328,7 @@ static void gx_set_cpuspeed(struct cpufr
  *      for the hardware supported by the driver.
  */
 
-static int cpufreq_gx_verify(struct cpufreq_policy *policy)
+static int cpufreq_gx_verify(struct cpufreq_policy_data *policy)
 {
 	unsigned int tmp_freq = 0;
 	u8 tmp1, tmp2;
drivers/cpufreq/intel_pstate.c +17 -21
@@ -2036,8 +2036,9 @@ static int intel_pstate_get_max_freq(str
 			cpu->pstate.max_freq : cpu->pstate.turbo_freq;
 }
 
-static void intel_pstate_update_perf_limits(struct cpufreq_policy *policy,
-					    struct cpudata *cpu)
+static void intel_pstate_update_perf_limits(struct cpudata *cpu,
+					    unsigned int policy_min,
+					    unsigned int policy_max)
 {
 	int max_freq = intel_pstate_get_max_freq(cpu);
 	int32_t max_policy_perf, min_policy_perf;
@@ -2056,18 +2057,17 @@ static void intel_pstate_update_perf_lim
 		turbo_max = cpu->pstate.turbo_pstate;
 	}
 
-	max_policy_perf = max_state * policy->max / max_freq;
-	if (policy->max == policy->min) {
+	max_policy_perf = max_state * policy_max / max_freq;
+	if (policy_max == policy_min) {
 		min_policy_perf = max_policy_perf;
 	} else {
-		min_policy_perf = max_state * policy->min / max_freq;
+		min_policy_perf = max_state * policy_min / max_freq;
 		min_policy_perf = clamp_t(int32_t, min_policy_perf,
 					  0, max_policy_perf);
 	}
 
 	pr_debug("cpu:%d max_state %d min_policy_perf:%d max_policy_perf:%d\n",
-		 policy->cpu, max_state,
-		 min_policy_perf, max_policy_perf);
+		 cpu->cpu, max_state, min_policy_perf, max_policy_perf);
 
 	/* Normalize user input to [min_perf, max_perf] */
 	if (per_cpu_limits) {
@@ -2081,7 +2081,7 @@ static void intel_pstate_update_perf_lim
 		global_min = DIV_ROUND_UP(turbo_max * global.min_perf_pct, 100);
 		global_min = clamp_t(int32_t, global_min, 0, global_max);
 
-		pr_debug("cpu:%d global_min:%d global_max:%d\n", policy->cpu,
+		pr_debug("cpu:%d global_min:%d global_max:%d\n", cpu->cpu,
 			 global_min, global_max);
 
 		cpu->min_perf_ratio = max(min_policy_perf, global_min);
@@ -2094,7 +2094,7 @@ static void intel_pstate_update_perf_lim
 					  cpu->max_perf_ratio);
 
 	}
-	pr_debug("cpu:%d max_perf_ratio:%d min_perf_ratio:%d\n", policy->cpu,
+	pr_debug("cpu:%d max_perf_ratio:%d min_perf_ratio:%d\n", cpu->cpu,
 		 cpu->max_perf_ratio,
 		 cpu->min_perf_ratio);
 }
@@ -2114,7 +2114,7 @@ static int intel_pstate_set_policy(struc
 
 	mutex_lock(&intel_pstate_limits_lock);
 
-	intel_pstate_update_perf_limits(policy, cpu);
+	intel_pstate_update_perf_limits(cpu, policy->min, policy->max);
 
 	if (cpu->policy == CPUFREQ_POLICY_PERFORMANCE) {
 		/*
@@ -2143,8 +2143,8 @@ static int intel_pstate_set_policy(struc
 	return 0;
 }
 
-static void intel_pstate_adjust_policy_max(struct cpufreq_policy *policy,
-					 struct cpudata *cpu)
+static void intel_pstate_adjust_policy_max(struct cpudata *cpu,
+					   struct cpufreq_policy_data *policy)
 {
 	if (!hwp_active &&
 	    cpu->pstate.max_pstate_physical > cpu->pstate.max_pstate &&
@@ -2155,7 +2155,7 @@ static void intel_pstate_adjust_policy_m
 	}
 }
 
-static int intel_pstate_verify_policy(struct cpufreq_policy *policy)
+static int intel_pstate_verify_policy(struct cpufreq_policy_data *policy)
 {
 	struct cpudata *cpu = all_cpu_data[policy->cpu];
 
@@ -2163,11 +2163,7 @@ static int intel_pstate_verify_policy(st
 	cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
 				     intel_pstate_get_max_freq(cpu));
 
-	if (policy->policy != CPUFREQ_POLICY_POWERSAVE &&
-	    policy->policy != CPUFREQ_POLICY_PERFORMANCE)
-		return -EINVAL;
-
-	intel_pstate_adjust_policy_max(policy, cpu);
+	intel_pstate_adjust_policy_max(cpu, policy);
 
 	return 0;
 }
@@ -2268,7 +2264,7 @@ static struct cpufreq_driver intel_pstat
 	.name		= "intel_pstate",
 };
 
-static int intel_cpufreq_verify_policy(struct cpufreq_policy *policy)
+static int intel_cpufreq_verify_policy(struct cpufreq_policy_data *policy)
 {
 	struct cpudata *cpu = all_cpu_data[policy->cpu];
 
@@ -2276,9 +2272,9 @@ static int intel_cpufreq_verify_policy(s
 	cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
 				     intel_pstate_get_max_freq(cpu));
 
-	intel_pstate_adjust_policy_max(policy, cpu);
+	intel_pstate_adjust_policy_max(cpu, policy);
 
-	intel_pstate_update_perf_limits(policy, cpu);
+	intel_pstate_update_perf_limits(cpu, policy->min, policy->max);
 
 	return 0;
 }
drivers/cpufreq/longrun.c +1 -5
@@ -122,7 +122,7 @@ static int longrun_set_policy(struct cpu
  * Validates a new CPUFreq policy. This function has to be called with
  * cpufreq_driver locked.
  */
-static int longrun_verify_policy(struct cpufreq_policy *policy)
+static int longrun_verify_policy(struct cpufreq_policy_data *policy)
 {
 	if (!policy)
 		return -EINVAL;
@@ -130,10 +130,6 @@ static int longrun_verify_policy(struct
 	policy->cpu = 0;
 	cpufreq_verify_within_cpu_limits(policy);
 
-	if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) &&
-	    (policy->policy != CPUFREQ_POLICY_PERFORMANCE))
-		return -EINVAL;
-
 	return 0;
 }
 
drivers/cpufreq/pcc-cpufreq.c +1 -1
@@ -109,7 +109,7 @@ struct pcc_cpu {
 
 static struct pcc_cpu __percpu *pcc_cpu_info;
 
-static int pcc_cpufreq_verify(struct cpufreq_policy *policy)
+static int pcc_cpufreq_verify(struct cpufreq_policy_data *policy)
 {
 	cpufreq_verify_within_cpu_limits(policy);
 	return 0;
drivers/cpufreq/sh-cpufreq.c +1 -1
@@ -87,7 +87,7 @@ static int sh_cpufreq_target(struct cpuf
 	return work_on_cpu(policy->cpu, __sh_cpufreq_target, &data);
 }
 
-static int sh_cpufreq_verify(struct cpufreq_policy *policy)
+static int sh_cpufreq_verify(struct cpufreq_policy_data *policy)
 {
 	struct clk *cpuclk = &per_cpu(sh_cpuclk, policy->cpu);
 	struct cpufreq_frequency_table *freq_table;
drivers/cpufreq/unicore2-cpufreq.c +1 -1
@@ -22,7 +22,7 @@ static struct cpufreq_driver ucv2_driver
 /* make sure that only the "userspace" governor is run
  * -- anything else wouldn't make sense on this platform, anyway.
  */
-static int ucv2_verify_speed(struct cpufreq_policy *policy)
+static int ucv2_verify_speed(struct cpufreq_policy_data *policy)
 {
 	if (policy->cpu)
 		return -EINVAL;
include/linux/cpufreq.h +23 -9
@@ -148,6 +148,20 @@ struct cpufreq_policy {
 	struct notifier_block nb_max;
 };
 
+/*
+ * Used for passing new cpufreq policy data to the cpufreq driver's ->verify()
+ * callback for sanitization.  That callback is only expected to modify the min
+ * and max values, if necessary, and specifically it must not update the
+ * frequency table.
+ */
+struct cpufreq_policy_data {
+	struct cpufreq_cpuinfo		cpuinfo;
+	struct cpufreq_frequency_table	*freq_table;
+	unsigned int			cpu;
+	unsigned int			min;    /* in kHz */
+	unsigned int			max;    /* in kHz */
+};
+
 struct cpufreq_freqs {
 	struct cpufreq_policy *policy;
 	unsigned int old;
@@ -201,8 +215,6 @@ u64 get_cpu_idle_time(unsigned int cpu,
 struct cpufreq_policy *cpufreq_cpu_acquire(unsigned int cpu);
 void cpufreq_cpu_release(struct cpufreq_policy *policy);
 int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu);
-int cpufreq_set_policy(struct cpufreq_policy *policy,
-		       struct cpufreq_policy *new_policy);
 void refresh_frequency_limits(struct cpufreq_policy *policy);
 void cpufreq_update_policy(unsigned int cpu);
 void cpufreq_update_limits(unsigned int cpu);
@@ -284,7 +296,7 @@ struct cpufreq_driver {
 
 	/* needed by all drivers */
 	int		(*init)(struct cpufreq_policy *policy);
-	int		(*verify)(struct cpufreq_policy *policy);
+	int		(*verify)(struct cpufreq_policy_data *policy);
 
 	/* define one out of two */
 	int		(*setpolicy)(struct cpufreq_policy *policy);
@@ -415,8 +427,9 @@ static inline int cpufreq_thermal_contro
 		(drv->flags & CPUFREQ_IS_COOLING_DEV);
 }
 
-static inline void cpufreq_verify_within_limits(struct cpufreq_policy *policy,
-		unsigned int min, unsigned int max)
+static inline void cpufreq_verify_within_limits(struct cpufreq_policy_data *policy,
+						unsigned int min,
+						unsigned int max)
 {
 	if (policy->min < min)
 		policy->min = min;
@@ -432,10 +445,10 @@ static inline void cpufreq_verify_within
 }
 
 static inline void
-cpufreq_verify_within_cpu_limits(struct cpufreq_policy *policy)
+cpufreq_verify_within_cpu_limits(struct cpufreq_policy_data *policy)
 {
 	cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
-			policy->cpuinfo.max_freq);
+				     policy->cpuinfo.max_freq);
 }
 
 #ifdef CONFIG_CPU_FREQ
@@ -513,6 +526,7 @@ static inline unsigned long cpufreq_scal
  *                          CPUFREQ GOVERNORS                        *
  *********************************************************************/
 
+#define CPUFREQ_POLICY_UNKNOWN		(0)
 /*
  * If (cpufreq_driver->target) exists, the ->governor decides what frequency
  * within the limits is used. If (cpufreq_driver->setpolicy> exists, these
@@ -684,9 +698,9 @@ static inline void dev_pm_opp_free_cpufr
 int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
 				    struct cpufreq_frequency_table *table);
 
-int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
+int cpufreq_frequency_table_verify(struct cpufreq_policy_data *policy,
 				   struct cpufreq_frequency_table *table);
-int cpufreq_generic_frequency_table_verify(struct cpufreq_policy *policy);
+int cpufreq_generic_frequency_table_verify(struct cpufreq_policy_data *policy);
 
 int cpufreq_table_index_unsorted(struct cpufreq_policy *policy,
 				 unsigned int target_freq,