7.2.9-rc1 review
Subsystems (6)
Greg Kroah-Hartman
maintainercover 7.2.9-rc1 review
This is the start of the stable review cycle for the 7.2.9 release. There are 457 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 Fri, 02 Oct 2026 15:23:04 +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/v7.x/stable-review/patch-7.2.9-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-7.2.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 7.2.9-rc1
Shengzhuo Wei <[email protected]>
i2c: qcom-geni: release DMA channels on probe error
Karol Wachowski <[email protected]>
accel/ivpu: Drop IRQF_ONESHOT to allow IPC IRQ threading on PREEMPT_RT
Sean Christopherson <[email protected]>
KVM: x86: Add static calls for nested virtualization ops
Sean Christopherson <[email protected]>
KVM: x86: Reject nested CAP enablement if nested virtualization is disabled
Paolo Bonzini <[email protected]>
KVM: move TSS constants from kvm_host.h to tss.h
Sean Christopherson <[email protected]>
KVM: x86/mmu: Move kvm_mmu_do_page_fault() from mmu_internal.h => mmu.c
Sean Christopherson <[email protected]>
KVM: x86/mmu: Move kvm_arch_async_page_ready() below kvm_tdp_page_fault()
Sean Christopherson <[email protected]>
KVM: x86: Move IRQ-related helper declarations from kvm_host.h => irq.h
Marc Zyngier <[email protected]>
KVM: arm64: nv: Delay freeing of shadow S2 structures until VM destruction
Marc Zyngier <[email protected]>
KVM: arm64: nv: Fix life cycle of the nested_mmus array
Ilya Maximets <[email protected]>
net/sched: act_ct: avoid modifying shared unconfirmed ct entry
Ilya Maximets <[email protected]>
net/sched: act_ct: fix helper UAF due to extensions realloc
Alex Hung <[email protected]>
drm/amd/display: Relax DML frame limit with UBSAN
Christian Brauner <[email protected]>
super: make iterate_supers_type() deletion-safe
Christian Brauner <[email protected]>
super: take lock after last reference count
Christian Brauner <[email protected]>
super: convert s_count to refcount_t s_passive
Viken Dadhaniya <[email protected]>
i2c: qcom-geni: Fix hardcoded clock index in SE_GENI_CLK_SEL
Praveen Talari <[email protected]>
i2c: qcom-geni: Store of_device_id data in driver private struct
Praveen Talari <[email protected]>
i2c: qcom-geni: Move resource initialization to separate function
Praveen Talari <[email protected]>
i2c: qcom-geni: Isolate serial engine setup
Jakub Pawlak <[email protected]>
accel/ivpu: Use separate flag for job timeout
Karol Wachowski <[email protected]>
accel/ivpu: Use threaded IRQ for IPC callback processing
Arnd Bergmann <[email protected]>
landlock: Work around gcc-16 -Wuninitialized warning
Tangudu Tilak Tirumalesh <[email protected]>
drm/xe: Add wa_14025941587 to xe2, xe3 and xe3p platforms
Darrick J. Wong <[email protected]>
xfs: fix cursor and pointer handling when recovering iunlink buckets
Darrick J. Wong <[email protected]>
xfs: fix blockgc group quota scanning when usrquota isn't enforced
Darrick J. Wong <[email protected]>
xfs: drop dquot flush lock when we can't find a buffer to flush
Darrick J. Wong <[email protected]>
xfs: don't merge different file IO error types
Darrick J. Wong <[email protected]>
xfs: don't let memory failures leak blocks and kill repairs
Darrick J. Wong <[email protected]>
xfs: don't let hidden_space go negative in xfs_metafile_resv_init
Darrick J. Wong <[email protected]>
xfs: call xfs_dquot_set_prealloc_limits if we installed default rtb limits
Darrick J. Wong <[email protected]>
xfs: fix wild memcpy access when formatting ondisk rtrefcount btree roots
Darrick J. Wong <[email protected]>
xfs: fix rtgroup repair estimations
Darrick J. Wong <[email protected]>
xfs: check di_forkoff correctly in scrub
Darrick J. Wong <[email protected]>
xfs: use the correct reservations for rtrmap/refcount recovery
Darrick J. Wong <[email protected]>
xfs: only flag zero padding for dir3 data blocks, not dir3 block blocks
Darrick J. Wong <[email protected]>
xfs: don't call xfs_exchange_range_finish for a dry run
Darrick J. Wong <[email protected]>
xfs: check padding field in xfs_ioc_commit_range
Darrick J. Wong <[email protected]>
xfs: use correct jiffies comparison function in xchk_maybe_relax
Darrick J. Wong <[email protected]>
xfs: release orphanage dir inode if chown fails
Darrick J. Wong <[email protected]>
xfs: fix attr fork block count checks in xrep_inode_blockcounts
Darrick J. Wong <[email protected]>
xfs: don't assert when XFS_SCRUB_TYPE_HEALTHY scans return corruption
Adarsh Das <[email protected]>
smb: client: delete compound mids on send failure before unlock
Zihan Xi <[email protected]>
smb: client: close completed creates on compound wait errors
Zihan Xi <[email protected]>
smb: client: validate POSIX create context length
Namjae Jeon <[email protected]>
smb: client: use finish_no_open() for non-regular inodes
Zihan Xi <[email protected]>
smb: client: preserve create-context parsing errors
Zihan Xi <[email protected]>
smb: client: clean up failed cached directory opens
Zihan Xi <[email protected]>
smb: client: close handle after create-context parsing failure
Zihan Xi <[email protected]>
smb: client: fix create context out-of-bounds reads
Hui Peng <[email protected]>
Bluetooth: RFCOMM: fix NULL dereference of dlc->session in RFCOMM_CONNINFO
Aldo Ariel Panzardo <[email protected]>
Bluetooth: mgmt: fix race in read_unconf_index_list()
Aldo Ariel Panzardo <[email protected]>
Bluetooth: L2CAP: validate frame length before control and FCS access
Aldo Ariel Panzardo <[email protected]>
Bluetooth: ISO: release unused CIS holds after channel attach
Aldo Ariel Panzardo <[email protected]>
Bluetooth: ISO: balance the parent hold in hci_bind_bis()
Aldo Ariel Panzardo <[email protected]>
Bluetooth: hci_sock: reject out-of-range OCF values
Aldo Ariel Panzardo <[email protected]>
Bluetooth: hci_sock: validate event length before filtering
Aldo Ariel Panzardo <[email protected]>
Bluetooth: hci_conn: fix CIS hold ownership on reuse
Davi Chaves Azevedo <[email protected]>
sched/cache: Refresh LLC capacity across CPU hotplug, to fix capacity underestimation bug
Tim Chen <[email protected]>
sched/cache: Decouple sched_cache_group from mm to fix UAF
Tejun Heo <[email protected]>
sched_ext: Derive SCX_RQ_IN_WAKEUP from the core enqueue flags
Tan Chi <[email protected]>
RISC-V: KVM: Fix HSM hart status error propagation
Xie Bo <[email protected]>
RISC-V: KVM: Propagate interrupted G-stage faults
Xie Bo <[email protected]>
RISC-V: KVM: Release unused page after MMU invalidation
Myeonghun Pak <[email protected]>
RISC-V: KVM: Synchronize hrtimer callback during teardown
Xie Bo <[email protected]>
RISC-V: KVM: Serialize IMSIC attributes with vCPU migration
Fuad Tabba <[email protected]>
KVM: arm64: Transfer the hyp stack pages out of the host stage-2
Lorenzo Stoakes (ARM) <[email protected]>
KVM: arm64: nv: Fix null ptr deref on nested wp/unmap, teardown race
Lorenzo Stoakes (ARM) <[email protected]>
KVM: arm64: Fix spurious warning for benign stage 2 teardown race
Karl Mehltretter <[email protected]>
KVM: arm64: Fix AArch32 DBGBXVR<n> handling
Fuad Tabba <[email protected]>
KVM: arm64: Don't WARN on an unknown VM ioctl in protected mode
Sean Christopherson <[email protected]>
KVM: SEV: Do cache maintenance on the source VM during intra-host migration
Sean Christopherson <[email protected]>
KVM: SEV: Free have_run_cpus during VM destruction even if VM is no longer SEV
Zeng Chi <[email protected]>
KVM: Don't treat reserved xarray entries as having memory attributes
David Ballesteros <[email protected]>
KVM: Ensure memory attributes xarray nodes are accounted to the caller's memcg
Anthony Krowiak <[email protected]>
s390/vfio-ap: fix KVM GISC and page leak when queue removed from host config
Niklas Schnelle <[email protected]>
s390/pci: Don't report recovery success on skipped recovery
Niklas Schnelle <[email protected]>
s390/pci: Report SCLP status on error events when no pdev is associated
Niklas Schnelle <[email protected]>
s390/pci: Fix missing device lock in zpci_report_status()
Niklas Schnelle <[email protected]>
s390/pci: Fix leak of struct pci_dev reference in zpci_report_status()
Peter Oberparleiter <[email protected]>
s390/cmf: Fix virtual vs physical address confusion
Vineeth Vijayan <[email protected]>
s390/cio: Fix NULL pointer dereference in ccw_device_get_util_str()
Ilya Titov <[email protected]>
pinctrl: sunxi: keep a shadow copy of the data register output latches
Myeonghun Pak <[email protected]>
pinctrl: single: free the IRQ on domain creation failure
Shawn Guo <[email protected]>
pinctrl: qcom: nord: Split QUP1 SE2/SE3 into lane-pair functions
Conor Dooley <[email protected]>
pinctrl: mpfs-mssio: use correct regmap function to set bank voltage
Conor Dooley <[email protected]>
pinctrl: mpfs-mssio: fix width of unused bank voltage setting
Dapeng Mi <[email protected]>
perf/x86/intel: Constrain Panther Cove UOPS_DISPATCHED events to PMCs 0-3
Dapeng Mi <[email protected]>
perf/x86/intel: Remove incorrect Panther Cove PEBS data-source constraints
Dapeng Mi <[email protected]>
perf/x86/intel: Remove incorrect LionCove PEBS data-source constraints
Dapeng Mi <[email protected]>
perf/x86/intel: Fix Panther Cove PEBS data-source snoop states
Dapeng Mi <[email protected]>
perf/x86/intel: Fix DKT PEBS load/store direction for latency events, to fix sample classification
Dapeng Mi <[email protected]>
perf/x86/intel: Fix GRT PEBS load/store direction for latency events, to fix sample classification
Dapeng Mi <[email protected]>
perf/x86/intel: Fix CMT PEBS load/store direction for latency events, to fix sample classification
Puranjay Mohan <[email protected]>
perf/core: Run sched_task() for PMUs with only CPU-wide events
Puranjay Mohan <[email protected]>
perf/core: Fix NULL pmu_ctx passed to pmu->sched_task()
Zhenghui Hao <[email protected]>
parisc: parse early parameters in setup_arch()
Helge Deller <[email protected]>
parisc: Increase kernel stack size to 32kb
Geert Uytterhoeven <[email protected]>
scsi: ufs: pltfrm: Add quirk for R-Car S4 lacking lanes-per-direction
Stanley Jhu <[email protected]>
scsi: ufs: core: Keep internal commands dispatchable during error handling
Yehyeong Lee <[email protected]>
scsi: libiscsi_tcp: Check the data direction of a Data-In PDU
Myeonghun Pak <[email protected]>
nfc: trf7970a: power down on startup RX gain failure
Doruk Tan Ozturk <[email protected]>
nfc: port100: reject frames whose declared length exceeds the received data
Aamir Ahmed <[email protected]>
nfc: llcp: drop truncated I/RR/RNR PDUs in nfc_llcp_recv_hdlc()
Luxiao Xu <[email protected]>
nfc: fix use-after-free in nfc_get_local_general_bytes
Aohan Mei <[email protected]>
netfilter: nf_tables: skip expired catchall elements on insert and delete
Luxiao Xu <[email protected]>
netfilter: ip6t_rt: fix zero-address non-strict match out-of-bounds read
Weiming Shi <[email protected]>
netfilter: ip6t_rpfilter: reject routes without inet6_dev
Wentao Liang <[email protected]>
net: usb: lan78xx: Fix URB reference leak in lan78xx_submit_deferred_urbs()
Ming Wang <[email protected]>
net: usb: cdc_mbim: add MeiG Smart SRM821 to ZLP whitelist
Zhang Yunfei <[email protected]>
net: txgbe: fix FDIR filter restore for VF rules
Abhishek Ojha <[email protected]>
net: phy: micrel: Advance register data pointer in write loop
Alexander Sverdlin <[email protected]>
net: phy: intel-xway: workaround 100BASE-TX Link-Up issue
Guangshuo Li <[email protected]>
net: ena: fix MMIO read buffer leak on probe failure
Guangshuo Li <[email protected]>
net: ena: fix PHC cleanup on probe failure
Fourie Zhang <[email protected]>
net: bridge: mdb: restart port group walk after deletion
Gajdos Tamás <[email protected]>
net: atl1e: fix soft lockup on out-of-range hw_next_to_clean read
Gajdos Tamás <[email protected]>
net: atl1c: fix soft lockup on out-of-range tpd_cons read
Ilya Maximets <[email protected]>
net: openvswitch: conntrack: fix helper UAF due to extensions realloc
Ilya Maximets <[email protected]>
net: openvswitch: conntrack: remove 'add_helper' dead code
Ilya Maximets <[email protected]>
net: openvswitch: conntrack: avoid modifying shared unconfirmed ct entry
Théo Lebrun <[email protected]>
net: macb: fix dma_alloc_coherent() leak on macb_alloc() error paths
Yuqi Xu <[email protected]>
net: ipconfig: bound DHCP option construction
Wentao Liang <[email protected]>
net: hisilicon: hns_dsaf_mac: fix mdio device leak in hns_mac_register_phy()
Gajdos Tamás <[email protected]>
net: atl1: fix soft lockup on out-of-range cmb_tpd_next_to_clean read
Zijie Huang <[email protected]>
net: arp: terminate device name before lookup
Myeonghun Pak <[email protected]>
net: airoha: npu: cancel wdt_work after releasing the WDT IRQ
Weiming Shi <[email protected]>
net/sched: reject IDR error pointers when deleting actions
Andrea Parri <[email protected]>
net/mlx5e: fix swapped IPv6 IPsec policy masks
Ralf Lici <[email protected]>
net/mlx5e: advertise MACsec offload only when supported
Wentao Liang <[email protected]>
net/mlx5: Fix rev_entry reference leak in mlx5_tc_ct_shared_counter_get()
Wei Jie LAW <[email protected]>
HID: wacom: fix OOB read in wacom_wac_pen_serial_enforce()
Junjie Cao <[email protected]>
HID: quirks: add ALWAYS_POLL quirk for SDINNOVATION gaming keyboard
Tristan Madani <[email protected]>
HID: hid-oxp: use cancel_delayed_work_sync() in remove
Chen Changcheng <[email protected]>
HID: alps: fix use-after-free on input2 registration failure
Chen Changcheng <[email protected]>
HID: alps: unregister DualPoint Stick input device on remove
Willem de Bruijn <[email protected]>
packet: use ubuf_info completion for TX_RING packets
Angel J <[email protected]>
PCI: of_property: Omit bus properties without a subordinate bus
Liz Fong-Jones <[email protected]>
PCI: Fix BAR resize for devices on a root bus
SJ Park <[email protected]>
mm/damon/core: reset invalid quota->charge_target_from
Liew Rui Yan <[email protected]>
mm/damon/core: allow esz to be set to zero
Liew Rui Yan <[email protected]>
mm/damon/core: fix unconditionally skip last region
Nathan Gao <[email protected]>
mm/damon/ops-common: use a page-aligned address in damon_ptep_mkold()
SJ Park <[email protected]>
mm/damon/vaddr: avoid hw-driven pte updates during damon_hugetlb_mkold()
Jaewook You <[email protected]>
mm/hugetlb: preserve mremap address delta when skipping page tables
Longlong Xia <[email protected]>
mm/hugetlb: do not dissolve gigantic pages without runtime support
Jinjiang Tu <[email protected]>
mm/rmap: fix missing barrier between anon_vma init and vma->anon_vma publish
Karl Mehltretter <[email protected]>
gpio: tps65219: Fix TPS65214 GPIO direction programming
Karl Mehltretter <[email protected]>
gpio: tps65219: Use the variant-specific direction callback
Karl Mehltretter <[email protected]>
gpio: tps65219: Fix GPIO input value reads
Peiyang He <[email protected]>
drm/virtio: fix NULL pointer dereference on fence allocation failure
Peiyang He <[email protected]>
drm/virtio: fix memory leak of fence event on execbuffer failure
Matthew Brost <[email protected]>
drm/xe: Keep walking on SVM eviction failure
Szymon Acedański <[email protected]>
drm/xe: Limit sg segment size to PAGE_SIZE on Xen PV
Tangudu Tilak Tirumalesh <[email protected]>
drm/xe: harden adjust_idledly() against divide-by-zero and overflow
Matthew Auld <[email protected]>
drm/xe/vm: nuke PTs only after unlinking contested VMAs
Peiyang He <[email protected]>
drm/nouveau: don't bump pin count on failed re-pin in nouveau_bo_pin_locked()
Jonghyuk Kim(MalHyuk) <[email protected]>
drm/nouveau: RCU-free the scheduler-containing nouveau_sched
Wentao Liang <[email protected]>
drm/nouveau: Fix runtime PM leak in nouveau_connector_detect()
Wentao Liang <[email protected]>
drm/nouveau: Fix gem reference leak in validate_init()
Peiyang He <[email protected]>
drm/nouveau: fix double-free in nvif_vmm_dtor
Wentao Liang <[email protected]>
drm/nouveau: Fix bridge reference leak in nv1a_ram_new()
Guangshuo Li <[email protected]>
drm/nouveau: fix autosuspend cleanup during teardown
Peiyang He <[email protected]>
drm/nouveau/uvmm: fix UAF in nouveau_uvmm_sm when BO is in TTM_PL_SYSTEM
Junrui Luo <[email protected]>
drm/nouveau/dmem: pin VRAM for the whole registered range
Prike Liang <[email protected]>
drm/amdgpu: move userq fence wait out of signalling section
Wentao Liang <[email protected]>
drm/amdgpu: Fix vmid_wait fence leak in amdgpu_ring_init()
Wentao Liang <[email protected]>
drm/amdgpu: Fix runtime PM leak in amdgpu_debugfs_test_ib_show()
Wentao Liang <[email protected]>
drm/amdgpu: Fix last_update fence leak in amdgpu_vm_init()
Wentao Liang <[email protected]>
drm/amdgpu: Fix acpi device leak in amdgpu_acpi_enumerate_xcc()
Sunil Khatri <[email protected]>
drm/amdgpu/vcn5.0.1: fix video_timeout unit mismatch in jpeg reset wait
Sunil Khatri <[email protected]>
drm/amdgpu/vcn4.0.3: fix video_timeout unit mismatch in jpeg reset wait
Sunil Khatri <[email protected]>
drm/amdgpu/userq: fix double jiffies conversion in hang detect timeout
Ivan Lipski <[email protected]>
drm/amd/display: Bump frame warning limit for clang builds of dml
Wentao Liang <[email protected]>
drm/amd/display: Fix dc stream excess put in dm_update_crtc_state()
Asad Kamal <[email protected]>
drm/amdkfd: fix use-after-free and multi-container gap in kfd_dev_mapping
Imre Deak <[email protected]>
drm/i915/dp_mst: Fix configuring TUs for a disconnected stream
Imre Deak <[email protected]>
drm/i915/dp_mst: Fix configuring FEC for a disconnected stream
Ankit Nautiyal <[email protected]>
drm/i915/quirks: Limit eDP rate to HBR2 on HP Pavilion Plus 14-ew1
Christian König <[email protected]>
drm/i915: fix incorrect RCU teardown order
Brajesh Gupta <[email protected]>
drm/imagination: Fix page count for page table for map() interface
Brajesh Gupta <[email protected]>
drm/imagination: Propagate map failures correctly from pvr_mmu_map_sgl()
shechenglong <[email protected]>
drm/client: fix restore of partially initialized client
Dongliang Qin <[email protected]>
rds: ib: Clear the sg list when mapping an MR fails
Hui Peng <[email protected]>
mctp: route: iterate socket tag list in mctp_lookup_prealloc_tag()
Zixuan Chai <[email protected]>
llc: reserve device headroom for allocated frames
Ridham Khurana <[email protected]>
gpio: zynq: fix runtime PM leak on request error path
Bartosz Golaszewski <[email protected]>
gpio: cdev: fix kernel stack leak to user-space in error path
Wentao Liang <[email protected]>
gpio: arizona: Fix runtime PM leak in arizona_gpio_direction_out()
Andrea Parri <[email protected]>
kprobes: Fix permanent hang when flushing the kprobe optimizer
Hui Peng <[email protected]>
ipv6: sr: enforce exact attribute length for SEG6_ATTR_DST
Norbert Szetei <[email protected]>
ipv6: do not let ipv6_find_hdr() return an offset past the packet end
Fan Wu <[email protected]>
ipe: protect the dm-verity root hash with RCU
Fan Wu <[email protected]>
ipe: fix use-after-free when auditing a newly loaded policy
Wentao Liang <[email protected]>
fsl/fman: Fix clk reference leak in read_dts_node()
Josef Bacik <[email protected]>
writeback: report a Tasks-RCU quiescent state per cgwb drain pass
Pavankumar Kondeti <[email protected]>
workqueue: Fix NULL current_pwq deref in flush dependency check
Patrick Lu (Anthropic) <[email protected]>
writeback: bound cleanup_offline_cgwb() rescans by rotating scanned inodes
Hao Ge <[email protected]>
netfs: Fix missing alloc tagging of direct mempool allocations
Christian Brauner <[email protected]>
fs/ntfs3: use d_instantiate_new() in ntfs_create_inode() and murder syzbot's "WARNING in do_new_mount" saga
David Carlier <[email protected]>
fprobe: Terminate the fgraph_data list when the reservation is not filled
Hui Peng <[email protected]>
fou: reject omitted FOU_ATTR_IPPROTO on FOU_ENCAP_DIRECT
Guopeng Zhang <[email protected]>
cgroup/pids: Restore pids.events notifications in local mode
Hui Peng <[email protected]>
cgroup/cpuset: Return PERR_NOCPUS in remote_partition_enable() on subpartitions_cpus conflict
Holger Dengler <[email protected]>
crypto: s390/hmac - Generate intermediate CV for API partial block handling
Andrea Parri <[email protected]>
bpf: fs/xattr: don't assume the inode is locked in path_unlink/path_rmdir
Myeonghun Pak <[email protected]>
bna: prevent IOC timer rearm during teardown
Matthias Goergens <[email protected]>
ata: libata-scsi: bound the ATA passthru sense descriptor writes
David Carlier <[email protected]>
arm64: errata: match the target implementation CPU's own MIDR
Fuad Tabba <[email protected]>
arm64/boot: Disable trapping of PMZR_EL0 writes to EL2
Dairui Zhang <[email protected]>
af_packet: fix integer overflow in prb_calc_retire_blk_tmo()
Aohan Mei <[email protected]>
sctp: discard the rest of the packet on a stale-cookie error
Willem de Bruijn <[email protected]>
tcp: prevent collapsing skbs across boundary in rtx queue
Eric Dumazet <[email protected]>
tipc: reject invalid and unexpected GRP_ACK_MSG to prevent bc_ackers underflow
Willem de Bruijn <[email protected]>
virtio_net: copy zerocopy frags in start_xmit without NAPI
Aldo Ariel Panzardo <[email protected]>
vsock: ignore empty child namespace mode writes
Melody Wang <[email protected]>
x86/sev: Make vTPM SVSM calls preemption-safe
Mario Limonciello <[email protected]>
x86/PCI: Disable enhanced atomics on AMD NBIO 7.7 and 7.11
Masami Hiramatsu (Google) <[email protected]>
x86/mce: Fix hardware debug register corruption on task migration
Xiang Mei <[email protected]>
vlan: require the MAC header to be present in __vlan_insert_inner_tag()
Matthew Brost <[email protected]>
drm/pagemap: dma-unmap pages before handling migration errors
Mark Amirkan <[email protected]>
mptcp: return sk_wait_data() errors from recvmsg()
Zhan Xusheng <[email protected]>
sched/core: Account PSI IRQ time to the execution context, not the scheduling context
Puranjay Mohan <[email protected]>
perf/core: Fill branch entries with a single assignment
Namhyung Kim <[email protected]>
perf/core: Fix a refcount leak in attach_perf_ctx_data()
Dapeng Mi <[email protected]>
perf/x86/intel: Delete dead NVL PEBS data-source initcall
Sean Christopherson <[email protected]>
perf/x86/intel: Make @data a mandatory param for intel_guest_get_msrs()
Sean Christopherson <[email protected]>
perf/x86/intel: Don't pointlessly context switch DS_AREA (and PEBS config) if PEBS is unused
Sean Christopherson <[email protected]>
perf/x86/intel: Don't write PEBS_ENABLED on host<=>guest xfers if CPU has PEBS isolation, to fix stuck PEBS_ENABLED
Sean Christopherson <[email protected]>
perf/x86/intel: Ensure KVM guest PEBS path doesn't set unwanted PERF_GLOBAL_CTRL bits
Hui Peng <[email protected]>
autofs: fix sbi->pipe file reference leak in autofs_kill_sb()
Amir Goldstein <[email protected]>
ovl: fix UAF in ovl_do_mkdir() debug print
Eric Dumazet <[email protected]>
vlan: ensure sufficient headroom in vlan_dev_hard_header()
Eric Dumazet <[email protected]>
net/sched: sch_teql: fix shadowed err in __teql_resolve()
Eric Dumazet <[email protected]>
bridge: check llc_mac_hdr_init() return value in br_send_bpdu()
Eric Dumazet <[email protected]>
llc: fix skb UAF and leaks on llc_mac_hdr_init() failure
Eric Dumazet <[email protected]>
gve: DQO: reject TSO packets with an out of range MSS
Eddie Phillips <[email protected]>
gve: fix TX drop when GSO MSS is too small for hw
Eric Dumazet <[email protected]>
gve: DQO: fix header length used by gve_can_send_tso() for UDP GSO
Eric Dumazet <[email protected]>
net: flush skb_defer_nodes in dev_cpu_dead()
Coia Prant <[email protected]>
net: ethernet: stmmac: dwmac-rk: fix bulk clock leak when the PHY clock fails
Ginger Li <[email protected]>
tipc: Fix a data race on mon->peer_cnt in mon_timeout()
Sidraya Jayagond <[email protected]>
net/smc: fix UAF on lgr list traversal in smcr_port_err()
Allison Henderson <[email protected]>
net/rds: size a connection's path set by the transport it ends up with
Sang-Hoon Choi <[email protected]>
nfp: hold IPsec RX state under the XArray lock
Jiawen Wu <[email protected]>
net: libwx: fix races in Tx timestamp handling
Jiawen Wu <[email protected]>
net: wangxun: implement soft quiesce for PCIe error recovery
Aleksei Sviridkin <[email protected]>
net: phylink: record the PHY only once bringup cannot fail
Yilin Zhang <[email protected]>
tcp: fix use-after-free of retransmit_skb_hint in tcp_send_synack()
Aleksei Sviridkin <[email protected]>
net: dsa: mt7530: leave the MDIO IRQ mappings to regmap-irq
Aleksei Sviridkin <[email protected]>
net: dsa: mt7530: fix NULL dereference on unbind of MT7531 and MT7621
Donggeun Yoo <[email protected]>
bpf: Zero-fill other CPUs when BPF_F_CPU creates a per-cpu hash element
Christian Lamparter <[email protected]>
net: emac: move setting of netops to fix crash
Fang Xieyan <[email protected]>
net/sched: act_ife: validate metadata length before decoding
Haseeb Malik <[email protected]>
macsec: initialize SecY before registering the netdevice
David Dai <[email protected]>
bonding: crypto offload enabled, non-offload slave failover, rekey failed
Pengpeng Hou <[email protected]>
drm/imagination: clamp freelist reconstruction requests
Norbert Szetei <[email protected]>
net: xps: reject an out of range traffic class
Sanghyun Park <[email protected]>
vxlan: use one headroom snapshot for neighbour replies
Xuanqiang Luo <[email protected]>
ip_gre: Reject enabling collect metadata through changelink
Florian Fainelli <[email protected]>
net: bcmgenet: mask DMA_TIMEOUT_MASK when reading DMA_RING0_TIMEOUT
Florian Fainelli <[email protected]>
net: bcmgenet: validate Ethernet address in bcmgenet_set_mac_addr
Florian Fainelli <[email protected]>
net: bcmgenet: do not skip WoL power up on GENET V1
Florian Fainelli <[email protected]>
net: bcmgenet: initialize u64 stats seq counter for all queues
Florian Fainelli <[email protected]>
net: bcmgenet: fix 64-bit RTNL stats reading in ethtool on 32-bit systems
Yuya Kusakabe <[email protected]>
net: ipv6: keep room for the mac header in dst_dev_overhead()
Lorenzo Bianconi <[email protected]>
net: stmmac: clear stale buf->page after recycling on skb build failure
Ivan Delalande <[email protected]>
tg3: use random MAC address when tg3_get_device_address fails
Johan Almbladh <[email protected]>
bpf: Fix BSWAP 32 and 16 on MIPS64
Johan Almbladh <[email protected]>
bpf: Fix immediate JMP JEQ/JNE on MIPS32
Jonas Jelonek <[email protected]>
net: mdio: realtek-rtl9300: fix RTL931x C22 extended page selection
Nicolo Giuliani <[email protected]>
net: dsa: mv88e6xxx: 88E6191X and 88E6193X have no PTP
Ido Schimmel <[email protected]>
vrf: Stop corrupting skb->csum when capturing CHECKSUM_COMPLETE packets
Shihuang Liu <[email protected]>
net: skbuff: fix pull-bound underflow in skb_checksum_setup_ipv6()
Jakub Kicinski <[email protected]>
veth: manage XDP program pointers during channel resize
Nicolai Buchwitz <[email protected]>
net: bcmgenet: stop Tx NAPI before disabling the queues
Victor Nogueira <[email protected]>
net/sched: act_gate: budget the per-entry list in get_fill_size
Deepanshu Kartikey <[email protected]>
nfc: pn533: fix OOB read in pn533_acr122_is_rx_frame_valid()
Ömer Mete Kaya <[email protected]>
nfc: llcp: fix slab-out-of-bounds reads when logging service names
Ömer Mete Kaya <[email protected]>
nfc: llcp: fix WKS SAP hijacking via prefix match in nfc_llcp_wks_sap()
Ömer Mete Kaya <[email protected]>
nfc: llcp: fix -ENOMEM on connect with zero-length service name
Pengpeng Hou <[email protected]>
nfc: st21nfca: validate ISO15693 inventory length
Cong Nguyen <[email protected]>
nfc: llcp: fix sdreq TLV list leak on parse/alloc/send failure
Chris Gellermann <[email protected]>
nfc: virtual_ncidev: Add missing ioctl compat handler
Chris Gellermann <[email protected]>
selftests/nci: Fix out-of-bounds store on thread join
Chaithanya Lagisetty <[email protected]>
selftests: nci: Fix uninitialized family ID on missing attribute
Lee Jones <[email protected]>
nfc: llcp: Fix race condition in accept_queue lifecycle
Lei Zhu <[email protected]>
selftests: nci: Correct pthread_create return value check
Aldo Ariel Panzardo <[email protected]>
nfc: llcp: Fix list corruption / refcount desync in nfc_llcp_recv_dm()
Pengpeng Hou <[email protected]>
nfc: st21nfca: validate received frame size
Pengpeng Hou <[email protected]>
nfc: nfcmrvl: validate helper command length before pull
Weiming Shi <[email protected]>
bpf: Reject dev-bound-only programs on other devices
Bernard Ladenthin <[email protected]>
net/sched: fix potential stack infoleak in em_text_dump()
Björn Töpel <[email protected]>
eth: fbnic: Avoid rounding zero ring sizes
Maxime Chevallier <[email protected]>
net: stmmac: selftests: Account for alignment shift on dwmac1000 for Jumbo test
Maxime Chevallier <[email protected]>
net: stmmac: size the RX buffers from the frame length, not the MTU
Maxime Chevallier <[email protected]>
net: stmmac: dwmac4: Use the correct bufzise when the len is exactly 8K
Maxime Chevallier <[email protected]>
net: stmmac: selftests: Capture all packets for vlan checks
Maxime Chevallier <[email protected]>
net: stmmac: selftests: Check the dev->features for S-TAG offload testing
Maxime Chevallier <[email protected]>
net: stmmac: selftests: Validate EEE based on the actual LPI timer value
Maxime Chevallier <[email protected]>
net: stmmac: selftests: Support running selftests on DSA conduits
Xin Long <[email protected]>
sctp: hold asoc or transport before mod_timer() in timer handlers
Bernardo Soares <[email protected]>
net/mlx5: Bridge, don't fail unlink of untracked/unsupported peer ports
Bernardo Soares <[email protected]>
net/mlx5: Bridge, don't fail switchdev events of sibling eswitch ports
Takashi Sakamoto <[email protected]>
firewire: cdev: fix back-transition for iso_resource_auto client resource
Zhao Gongyi <[email protected]>
bpf, sockmap: Reject max_entries > INT_MAX in sock_map_alloc
Emil Tsalapatis <[email protected]>
bpf: Reject pkt arguments in mutating subprogs
Emil Tsalapatis <[email protected]>
bpf: Fix bpf_sock context code generation
Emil Tsalapatis <[email protected]>
bpf: Fix bounds check for skb-backed dynptrs
Manaf Meethalavalappu Pallikunhi <[email protected]>
thermal: gov_step_wise: Fix stale mitigation vote with non-zero lower bounds
Florian Schmaus <[email protected]>
PM: hibernate: Freeze kernel threads after image preallocation
Coia Prant <[email protected]>
net: pcs: xpcs: fix clock reference leak on xpcs_init_clks failure
Jakub Kicinski <[email protected]>
genetlink: report the real command id for dump-only ops in policy dumps
bui duc phuc <[email protected]>
net: ethernet: ti: netcp: fix pm_runtime usage counter leak on error
Muhammad Bilal <[email protected]>
net: spacemit: clear TX descriptor on fragment mapping failure
Mikhail Zaslonko <[email protected]>
s390/debug: Fix NULL pointer dereference in debug_info_copy()
Mikhail Zaslonko <[email protected]>
s390/debug: Do not register views for failed static debug areas
Nemesa Garg <[email protected]>
drm/i915/psr: Clear stale sel fetch enable bits on sel fetch disable
Myeonghun Pak <[email protected]>
tg3: clean up PHYLIB resources on probe failure
Shardul Bankar <[email protected]>
udp: remove a disconnected socket from the 4-tuple hash table
Shardul Bankar <[email protected]>
udp: relocate a connected socket in the 4-tuple hash table on re-connect
Kuniyuki Iwashima <[email protected]>
ipv6: Fix dst leak for uncached routes.
Pengpeng Hou <[email protected]>
net: usb: sr9700: include receive overhead in the length check
Ivan Vecera <[email protected]>
dpll: use exact lookup for reference sync pin id
Nicolai Buchwitz <[email protected]>
net: don't require the hwtstamp NDOs when a PHY provides timestamping
Kuniyuki Iwashima <[email protected]>
ipv6: Prevent rt6_insert_exception() for dying fib6_info.
Ratheesh Kannoth <[email protected]>
octeontx2-af: Fix memory scaling limitation in SR-IOV mode
Xu Yunxiang <[email protected]>
bpf: Reject non-negative offsets in stack_slot_obj_get_spi()
Hui Peng <[email protected]>
Bluetooth: RFCOMM: Reject short EA=0 frames in rfcomm_recv_frame()
Ravindra <[email protected]>
Bluetooth: btintel_pcie: validate device-supplied DMA indices
Hui Peng <[email protected]>
Bluetooth: bnep: fix out-of-bounds reads on short RX/TX frames and control fallthrough
Sk Anirban <[email protected]>
drm/xe/gt_throttle: Report power brake as a throttle reason on CRI
Ralf Lici <[email protected]>
ovpn: reject invalid peer VPN addresses
Ralf Lici <[email protected]>
ovpn: reject multipeer peers without VPN addresses
Ralf Lici <[email protected]>
ovpn: reject duplicate peer VPN addresses
Ralf Lici <[email protected]>
ovpn: always unhash old VPN addresses before rehashing
Ralf Lici <[email protected]>
ovpn: replace bind when clearing stale local source
Ralf Lici <[email protected]>
ovpn: replace bind when learning local endpoint
Ralf Lici <[email protected]>
ovpn: validate peer state before caching UDP dst
Ralf Lici <[email protected]>
ovpn: track UDP socket route key for peer dst cache
Ralf Lici <[email protected]>
ovpn: skip UDP source validation for unspecified addresses
Ralf Lici <[email protected]>
ovpn: preserve IPv6 scope id for netlink peer endpoints
Li Youhong <[email protected]>
drm/bridge: samsung-dsim: fix TE GPIO lifetime for host attach
Prathamesh Shete <[email protected]>
pinctrl: tegra238: Fix register bank for AON pin groups
Benjamin Leggett <[email protected]>
drm/virtio: sync shmem backing on guest-bound transfers
Dmitry Osipenko <[email protected]>
Revert "drm/virtio: Allow importing prime buffers when 3D is enabled"
Junrui Luo <[email protected]>
drm/virtio: release the GEM object on virtio_gpu_vram_create() errors
Junrui Luo <[email protected]>
drm/virtio: fix object leaks in virtio_gpu_resource_create_blob_ioctl()
Junrui Luo <[email protected]>
drm/virtio: fix object leak in virtio_gpu_resource_create_ioctl()
Junrui Luo <[email protected]>
drm/virtio: fix object leak when drm_gem_handle_create() fails
Jamal Hadi Salim <[email protected]>
net/sched: sch_hfsc: bound the classify inner-filter walk with a drift budget
Yuqi Xu <[email protected]>
bpf: Check params size before reading reserved fields
Aamir Ahmed <[email protected]>
net: usb: catc: bound the RX packet length in catc_rx_done()
Kumar Kartikeya Dwivedi <[email protected]>
bpf: Bound ownership depth through local kptrs and graph roots
Quentin Armitage <[email protected]>
net: allow IFLA_INET_CONF messages when NLA_F_NESTED unset
Yiqi Sun <[email protected]>
sctp: avoid livelock while updating retransmit path
Alexander Duyck <[email protected]>
eth: fbnic: Handle FW mailbox completions flagged with an error
Alexander Duyck <[email protected]>
eth: fbnic: Set AW_FLUSH_MODE alongside AW_FLUSH when flushing the mailbox
Alexander Duyck <[email protected]>
eth: fbnic: reset num_napi when the napi vectors are freed
Alexander Duyck <[email protected]>
eth: fbnic: use the Rx queue napi pointer to find the napi vector
Björn Töpel <[email protected]>
eth: fbnic: Handle maximum standalone channels
Alexander Duyck <[email protected]>
net: ethtool: keep rtnl_lock for the ioctl self test
Kuniyuki Iwashima <[email protected]>
ip6_gre: Call ip6erspan_tunnel_unlink_md() in ip6erspan_changelink().
Lorenzo Bianconi <[email protected]>
net: ethernet: mtk_eth_soc: unregister net_devices in case of probe failure
Jérémy Jean <[email protected]>
net: gue: reject invalid REMCSUM offsets
Nguyen Ngoc Thang <[email protected]>
net/sched: act_ct: don't WARN on benign flow_offload_alloc() failure
Giuseppe Ranieri <[email protected]>
drm/nouveau/disp: don't reject HDMI config on cards without SCDC
Francesco Magazzu <[email protected]>
drm/nouveau/clk: don't clobber reclock status when restoring volt/fan
Dan Carpenter <[email protected]>
drm/nouveau/clk: fix list cursor use after loop in nvkm_clk_ustate_update
hpp.iscas <[email protected]>
pinctrl: qcom: ipq5210: Publish the OF module alias
Joseph Qi <[email protected]>
ocfs2: make ocfs2_calc_xattr_init() return void
Zeng Heng <[email protected]>
arm64: io: Reject non-user protection in ioremap_prot()
Naman Gulati <[email protected]>
netfilter: ctnetlink: fix suspicious RCU usage in expect_iter_name
Julian Anastasov <[email protected]>
ipvs: revalidate ihl before icmp_send
Karl Mehltretter <[email protected]>
netfilter: nft_synproxy: use the family-aware checksum helper
Florian Westphal <[email protected]>
netfilter: nfnetlink_queue: hold nfnl mutex in event notifier
Jérémy Jean <[email protected]>
netfilter: flowtable: publish HW_DEAD after worker is done
Frank Wunderlich <[email protected]>
gpiolib: use of_node_name if line-name is missing
Linkui Xiao <[email protected]>
ipv4: fib: fix data-race and stale genid check around nh->nh_saddr
Kumar Kartikeya Dwivedi <[email protected]>
libbpf: Reject truncated ldimm64 CO-RE relocations
Kumar Kartikeya Dwivedi <[email protected]>
bpf: Restrict CO-RE poisoning to relocatable instructions
Kumar Kartikeya Dwivedi <[email protected]>
bpf: Preserve packet pointer class displacement in regsafe()
Kumar Kartikeya Dwivedi <[email protected]>
bpf: Make post-verification instruction rewrites killable
Shay Drory <[email protected]>
net/mlx5: LAG, reload IB reps of LAG master before the rest
Shay Drory <[email protected]>
net/mlx5: SD, unload reps on shared FDB create error path
Shay Drory <[email protected]>
net/mlx5: devcom, Base component size on linked devices
Heyang Tan <[email protected]>
octeontx2-af: use seq_file for rsrc_alloc debugfs
Kyle Hendry <[email protected]>
net: pcs: rzn1-miic: Fix config array initialization
Jamal Hadi Salim <[email protected]>
net/sched: cls_u32: fix manual hash table handle IDR aliasing
Björn Töpel <[email protected]>
eth: fbnic: Fix payload page pool error cleanup
Weiming Shi <[email protected]>
bpf: Skip unsettled links in link iterator
Zhiling Zou <[email protected]>
xsk: Use a 32-bit compare in xsk_map_gen_lookup
Julian Sun <[email protected]>
fs: avoid repeated scans in evict_inodes()
David Howells <[email protected]>
netfs, afs: Fix symlink reading
David Howells <[email protected]>
netfs: Fix netfs_read_gaps() to use separate sink folios
Vineeth Vijayan <[email protected]>
s390/cio: Guard PMCW field accesses with dnv check
Vineeth Vijayan <[email protected]>
s390/cio: Check pmcw.dnv before pmcw.ena in I/O entry points
Vineeth Vijayan <[email protected]>
s390/cio: Fix cio_update_schib() to not cache invalid schib
Karl Mehltretter <[email protected]>
s390/pci/docs: Fix sriov_numvfs attribute name
Bart Van Assche <[email protected]>
scsi: megaraid_sas: Protect megasas_get_ctrl_info() in megasas_resume()
Eva Kurchatova <[email protected]>
selftests: cgroup: give the O_TMPFILE open in get_temp_fd() a mode
Lee Jones <[email protected]>
Bluetooth: mgmt: Dequeue pending mesh_send_sync entries on cancel
Zijun Hu <[email protected]>
Bluetooth: btnxpuart: Fix skb leak in nxp_process_fw_dump()
Christiano Amora <[email protected]>
Bluetooth: SMP: reject Security Request over BR/EDR
Andre Przywara <[email protected]>
pinctrl: sunxi: A523: fix voltage withstand encoding
ZHOU Jiaxiang <[email protected]>
scsi: sd_zbc: Reject disks with too many zones
ZHOU Jiaxiang <[email protected]>
scsi: block: Fix zones_cond out-of-bounds write on zone report
Ran Hongyun <[email protected]>
squashfs: Add dictionary size range check to prevent shift-out-of-bounds
Mark Brown <[email protected]>
KVM: arm64: Fix FGT mapping for HFGITR_EL2.nGCSEPP
Sebastian Ott <[email protected]>
KVM: selftests: fix steal_time for arm64 with host page size > 4K
Fuad Tabba <[email protected]>
KVM: arm64: Match hyp text by physical address in fix_host_ownership()
Karl Mehltretter <[email protected]>
KVM: arm64: Return -EINVAL for an empty SMCCC filter range at base 0
Fuad Tabba <[email protected]>
KVM: arm64: Derive GUEST_HAS_SVE from the SVE feature bit at EL2
Fuad Tabba <[email protected]>
KVM: arm64: Do not clear VM-wide SVE feature on vCPU init failure
Fuad Tabba <[email protected]>
KVM: arm64: Validate the SVE vector length in pkvm_vcpu_init_sve()
Fuad Tabba <[email protected]>
KVM: arm64: vgic-its: Skip unreachable devices instead of failing the save
Fuad Tabba <[email protected]>
KVM: arm64: vgic-its: Free the caches when GITS_BASER changes
SeungJu Cheon <[email protected]>
RISC-V: KVM: Fix perf-backed counter accounting across stop and read
SeungJu Cheon <[email protected]>
RISC-V: KVM: Report snapshot write failure to the guest
SeungJu Cheon <[email protected]>
RISC-V: KVM: Preserve firmware counter value across stop/start
Zongmin Zhou <[email protected]>
KVM: riscv: Fix NACL hfence entry update order
Yicong Yang <[email protected]>
RISC-V: KVM: Fix the conversion between vsip and hvip
Benjamin Tissoires <[email protected]>
HID: bpf: fix __hid_bpf_hw_check_params report length
Slawomir Stepien <[email protected]>
HID: amd_sfh: Validate PCI BAR size before mapping
Sarah Emery <[email protected]>
pinctrl: generic: serialise pinctrl_generic_dt_node_to_map()
Sean Anderson <[email protected]>
pinctrl: meson: Fix typo in s4 group name
Donggeun Yoo <[email protected]>
bpf, arm64: set up the frame pointer for the exception callback
Masoud Aghasi <[email protected]>
bpf: Fix u32 overflow issue in map batch operations
Geliang Tang <[email protected]>
bpf, sockmap: Fix self-redirect copied_seq double-counting
Pu Lehui <[email protected]>
bpf: Fix UAF due to concurrent consumption of ttrace lists in alloc_bulk
Jiayuan Chen <[email protected]>
bpf: Fix out-of-bounds read of rtt_min in sock_ops
Jose Fernandez (Anthropic) <[email protected]>
bpf: Avoid soft lockup in __htab_map_lookup_and_delete_batch()
Siddharth Chintamaneni <[email protected]>
bpf: Allow terminal gotox instructions
Jim Mattson <[email protected]>
KVM: x86/pmu: Move Intel PMU global MSRs to intel_is_valid_msr()
Oscar Priego Verdugo <[email protected]>
HID: elecom: fix bus type for M-XGL20DLBK
René Onier <[email protected]>
HID: winwing: fix use-after-free in force feedback teardown
Lovekesh Solanki <[email protected]>
HID: multitouch: Add report ID mismatch quirk for ASUS ROG Z13 Folio
Jiayuan Chen <[email protected]>
tcp: Skip cond_resched() in inet_csk_listen_stop() under BPF context
Jiayuan Chen <[email protected]>
bpf: Fix out-of-bounds read of sk_protocol in bpf_sock_destroy()
Jiayuan Chen <[email protected]>
bpf: Fix divide-by-zero in btf_struct_walk()
Sven Schnelle <[email protected]>
selftests/ftrace: Fix unique symbol check in kprobe_non_uniq_symbol.tc
Weiming Shi <[email protected]>
bpf: Disallow bpf_skb_pull_data() for LWT_SEG6LOCAL
Daniel Borkmann <[email protected]>
bpf: Fix bpf_skb_change_tail wrt csum partial skbs
Steffen Eiden <[email protected]>
s390/uv: Prevent potential out-of-bounds read
Steffen Eiden <[email protected]>
s390/uv: Fix loop condition in uv_find_secrets
Claudio Imbrenda <[email protected]>
KVM: s390: Fix race in _destroy_pages_crste()
Claudio Imbrenda <[email protected]>
KVM: s390: Fix potential races in dat skey functions
Claudio Imbrenda <[email protected]>
KVM: s390: Properly handle NULL pointer in dat_cond_set_storage_key()
Claudio Imbrenda <[email protected]>
KVM: s390: Add missing srcu in kvm_s390_set_irq_state()
Claudio Imbrenda <[email protected]>
KVM: s390: Fix IRQ injection with SIGP Stop and Store Status
Claudio Imbrenda <[email protected]>
KVM: s390: Fix _gaccess_shadow_fault()
Claudio Imbrenda <[email protected]>
KVM: s390: Fix dirty marking in adapter_indicators_set*()
Mostafa Saleh <[email protected]>
remoteproc: qcom_q6v5_adsp: Fix iommu_unmap() usage
Dominik Kaszewski <[email protected]>
drm/amd/display: Remove sink usage from DPMS
Sean Rhodes <[email protected]>
ALSA: hda/realtek: Add StarFighter HDA SSID
Sean Rhodes <[email protected]>
ALSA: hda/realtek: Limit Star Labs internal mic boost
Leo Li <[email protected]>
drm/amd/display: Atomize IRQ register read/modify/write ops
-------------
Diffstat:
Documentation/arch/arm64/booting.rst | 1 + Documentation/arch/s390/pci.rst | 2 +- .../bindings/pinctrl/qcom,nord-tlmm.yaml | 7 +- Makefile | 4 +- arch/arm64/include/asm/el2_setup.h | 9 +- arch/arm64/include/asm/io.h | 3 +- arch/arm64/include/asm/kvm_host.h | 2 +- arch/arm64/include/asm/kvm_nested.h | 3 +- arch/arm64/include/asm/kvm_pkvm.h | 3 +- arch/arm64/kernel/cpu_errata.c | 15 +- arch/arm64/kvm/arm.c | 8 +- arch/arm64/kvm/emulate-nested.c | 2 +- arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 1 + arch/arm64/kvm/hyp/nvhe/mem_protect.c | 8 + arch/arm64/kvm/hyp/nvhe/pkvm.c | 25 +- arch/arm64/kvm/hyp/nvhe/setup.c | 12 +- arch/arm64/kvm/hypercalls.c | 3 +- arch/arm64/kvm/mmu.c | 15 +- arch/arm64/kvm/nested.c | 115 ++++---- arch/arm64/kvm/sys_regs.c | 1 + arch/arm64/kvm/vgic/vgic-its.c | 43 +-- arch/arm64/net/bpf_jit_comp.c | 2 + arch/mips/net/bpf_jit_comp32.c | 2 +- arch/mips/net/bpf_jit_comp64.c | 3 +- arch/parisc/include/asm/thread_info.h | 2 +- arch/parisc/kernel/setup.c | 12 + arch/riscv/include/asm/csr.h | 20 +- arch/riscv/kvm/aia_imsic.c | 11 +- arch/riscv/kvm/mmu.c | 10 +- arch/riscv/kvm/nacl.c | 20 +- arch/riscv/kvm/vcpu.c | 3 +- arch/riscv/kvm/vcpu_exit.c | 2 +- arch/riscv/kvm/vcpu_onereg.c | 8 +- arch/riscv/kvm/vcpu_pmu.c | 33 +-- arch/riscv/kvm/vcpu_sbi_hsm.c | 4 +- arch/riscv/kvm/vcpu_timer.c | 5 +- arch/s390/crypto/hmac_s390.c | 5 +- arch/s390/include/asm/debug.h | 8 +- arch/s390/kernel/debug.c | 15 +- arch/s390/kernel/uv.c | 8 +- arch/s390/kvm/dat.c | 41 ++- arch/s390/kvm/gaccess.c | 13 + arch/s390/kvm/gmap.c | 6 +- arch/s390/kvm/interrupt.c | 149 ++++++----- arch/s390/pci/pci_event.c | 7 +- arch/s390/pci/pci_report.c | 32 ++- arch/s390/pci/pci_report.h | 4 +- arch/x86/coco/sev/svsm.c | 10 +- arch/x86/events/amd/brs.c | 9 +- arch/x86/events/amd/lbr.c | 16 +- arch/x86/events/intel/core.c | 80 ++++-- arch/x86/events/intel/ds.c | 68 ++--- arch/x86/events/intel/lbr.c | 63 +++-- arch/x86/events/perf_event.h | 4 - arch/x86/include/asm/kvm-x86-nested-ops.h | 36 +++ arch/x86/include/asm/kvm_host.h | 22 +- arch/x86/kernel/cpu/mce/core.c | 27 +- arch/x86/kvm/hyperv.c | 6 +- arch/x86/kvm/irq.h | 6 + arch/x86/kvm/mmu.h | 5 +- arch/x86/kvm/mmu/mmu.c | 129 ++++++--- arch/x86/kvm/mmu/mmu_internal.h | 66 ----- arch/x86/kvm/mmu/paging_tmpl.h | 2 +- arch/x86/kvm/pmu.c | 8 - arch/x86/kvm/svm/nested.c | 1 + arch/x86/kvm/svm/sev.c | 18 +- arch/x86/kvm/svm/svm.c | 1 + arch/x86/kvm/tss.h | 7 + arch/x86/kvm/vmx/nested.c | 1 + arch/x86/kvm/vmx/pmu_intel.c | 3 + arch/x86/kvm/vmx/vmx.c | 2 + arch/x86/kvm/x86.c | 62 +++-- arch/x86/kvm/x86.h | 2 +- arch/x86/pci/fixup.c | 99 +++++++ block/blk-zoned.c | 15 +- drivers/accel/ivpu/ivpu_drv.c | 31 ++- drivers/accel/ivpu/ivpu_drv.h | 7 +- drivers/accel/ivpu/ivpu_hw.c | 4 + drivers/accel/ivpu/ivpu_ipc.c | 8 +- drivers/accel/ivpu/ivpu_ipc.h | 2 +- drivers/accel/ivpu/ivpu_job.c | 66 ++++- drivers/accel/ivpu/ivpu_job.h | 7 +- drivers/accel/ivpu/ivpu_mmu.c | 1 - drivers/accel/ivpu/ivpu_pm.c | 1 + drivers/ata/libata-scsi.c | 10 +- drivers/base/cacheinfo.c | 11 +- drivers/bluetooth/btintel_pcie.c | 16 ++ drivers/bluetooth/btnxpuart.c | 8 +- drivers/dpll/dpll_netlink.c | 3 +- drivers/firewire/core-cdev.c | 6 +- drivers/gpio/gpio-arizona.c | 8 +- drivers/gpio/gpio-tps65219.c | 12 +- drivers/gpio/gpio-zynq.c | 10 +- drivers/gpio/gpiolib-cdev.c | 32 ++- drivers/gpio/gpiolib.c | 7 + drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 4 +- drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 4 +- drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c | 3 + drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 16 +- drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 1 + drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c | 3 +- drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c | 3 +- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 71 ++++- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 3 +- .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 3 +- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 62 +++-- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.h | 28 ++ drivers/gpu/drm/amd/display/dc/dml/Makefile | 8 +- drivers/gpu/drm/amd/display/dc/dml2_0/Makefile | 2 +- drivers/gpu/drm/amd/display/dc/link/link_dpms.c | 180 ++++++------- drivers/gpu/drm/bridge/samsung-dsim.c | 2 +- drivers/gpu/drm/clients/drm_fbdev_client.c | 8 + drivers/gpu/drm/drm_pagemap.c | 12 +- drivers/gpu/drm/i915/display/intel_cursor.c | 7 +- drivers/gpu/drm/i915/display/intel_display_types.h | 2 + drivers/gpu/drm/i915/display/intel_dp_mst.c | 24 +- drivers/gpu/drm/i915/display/intel_dp_mst.h | 2 + drivers/gpu/drm/i915/display/intel_link_bw.c | 3 +- drivers/gpu/drm/i915/display/intel_psr.c | 15 ++ drivers/gpu/drm/i915/display/intel_quirks.c | 3 + drivers/gpu/drm/i915/display/skl_universal_plane.c | 9 +- drivers/gpu/drm/i915/gem/i915_gem_object.c | 2 +- drivers/gpu/drm/imagination/pvr_free_list.c | 15 +- drivers/gpu/drm/imagination/pvr_mmu.c | 19 +- drivers/gpu/drm/imagination/pvr_mmu.h | 2 +- drivers/gpu/drm/imagination/pvr_vm.c | 4 +- drivers/gpu/drm/nouveau/nouveau_bo.c | 3 +- drivers/gpu/drm/nouveau/nouveau_connector.c | 5 +- drivers/gpu/drm/nouveau/nouveau_dmem.c | 4 +- drivers/gpu/drm/nouveau/nouveau_drm.c | 5 +- drivers/gpu/drm/nouveau/nouveau_gem.c | 2 + drivers/gpu/drm/nouveau/nouveau_sched.c | 2 +- drivers/gpu/drm/nouveau/nouveau_sched.h | 1 + drivers/gpu/drm/nouveau/nouveau_uvmm.c | 13 +- drivers/gpu/drm/nouveau/nvif/vmm.c | 1 + drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c | 3 +- drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c | 23 +- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c | 2 + drivers/gpu/drm/virtio/virtgpu_drv.h | 5 + drivers/gpu/drm/virtio/virtgpu_gem.c | 2 +- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 49 +++- drivers/gpu/drm/virtio/virtgpu_prime.c | 2 +- drivers/gpu/drm/virtio/virtgpu_submit.c | 11 +- drivers/gpu/drm/virtio/virtgpu_vq.c | 46 ++++ drivers/gpu/drm/virtio/virtgpu_vram.c | 17 +- drivers/gpu/drm/xe/regs/xe_gt_regs.h | 1 + drivers/gpu/drm/xe/xe_bo.c | 7 + drivers/gpu/drm/xe/xe_bo.h | 19 ++ drivers/gpu/drm/xe/xe_gt_throttle.c | 5 +- drivers/gpu/drm/xe/xe_guc_ads.c | 2 +- drivers/gpu/drm/xe/xe_hw_engine.c | 96 ++++++- drivers/gpu/drm/xe/xe_vm.c | 21 +- drivers/gpu/drm/xe/xe_wa_oob.rules | 2 + drivers/hid/amd-sfh-hid/amd_sfh_common.h | 4 + drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 10 + drivers/hid/bpf/hid_bpf_dispatch.c | 12 +- drivers/hid/hid-alps.c | 25 +- drivers/hid/hid-ids.h | 3 + drivers/hid/hid-multitouch.c | 29 +- drivers/hid/hid-oxp.c | 6 +- drivers/hid/hid-quirks.c | 3 +- drivers/hid/hid-winwing.c | 10 +- drivers/hid/wacom_sys.c | 5 +- drivers/i2c/busses/i2c-qcom-geni.c | 293 +++++++++++---------- drivers/net/bonding/bond_main.c | 2 +- drivers/net/dsa/mt7530-mdio.c | 18 +- drivers/net/dsa/mt7530.c | 3 - drivers/net/dsa/mv88e6xxx/chip.c | 68 ++++- drivers/net/ethernet/airoha/airoha_npu.c | 18 +- drivers/net/ethernet/amazon/ena/ena_netdev.c | 2 + drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 3 + drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 3 + drivers/net/ethernet/atheros/atlx/atl1.c | 3 + drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 3 +- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 34 ++- drivers/net/ethernet/broadcom/tg3.c | 15 +- drivers/net/ethernet/brocade/bna/bnad.c | 24 +- drivers/net/ethernet/cadence/macb_main.c | 14 +- drivers/net/ethernet/freescale/fman/fman.c | 1 + drivers/net/ethernet/google/gve/gve_desc_dqo.h | 5 + drivers/net/ethernet/google/gve/gve_tx_dqo.c | 40 ++- drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c | 3 + drivers/net/ethernet/ibm/emac/core.c | 16 +- drivers/net/ethernet/marvell/octeontx2/af/common.h | 45 +++- .../ethernet/marvell/octeontx2/af/rvu_debugfs.c | 104 +++----- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 6 +- .../ethernet/mellanox/mlx5/core/en/rep/bridge.c | 45 +++- drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c | 3 + .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 4 +- .../ethernet/mellanox/mlx5/core/en_accel/macsec.c | 2 + drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 1 - .../net/ethernet/mellanox/mlx5/core/esw/bridge.c | 15 +- .../net/ethernet/mellanox/mlx5/core/esw/bridge.h | 2 + drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c | 44 +++- .../ethernet/mellanox/mlx5/core/lag/shared_fdb.c | 1 + .../net/ethernet/mellanox/mlx5/core/lib/devcom.c | 5 +- drivers/net/ethernet/meta/fbnic/fbnic_csr.h | 5 + drivers/net/ethernet/meta/fbnic/fbnic_debugfs.c | 4 +- drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c | 16 +- drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 47 +++- drivers/net/ethernet/meta/fbnic/fbnic_fw.h | 1 + drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 18 +- drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 30 ++- drivers/net/ethernet/netronome/nfp/crypto/ipsec.c | 3 +- drivers/net/ethernet/spacemit/k1_emac.c | 3 + drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 5 +- drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 4 +- drivers/net/ethernet/stmicro/stmmac/hwif.h | 2 +- drivers/net/ethernet/stmicro/stmmac/ring_mode.c | 4 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 21 +- .../net/ethernet/stmicro/stmmac/stmmac_selftests.c | 153 ++++++++--- drivers/net/ethernet/ti/netcp_core.c | 2 +- drivers/net/ethernet/wangxun/libwx/wx_hw.c | 1 + drivers/net/ethernet/wangxun/libwx/wx_lib.c | 65 ++++- drivers/net/ethernet/wangxun/libwx/wx_lib.h | 1 + drivers/net/ethernet/wangxun/libwx/wx_ptp.c | 161 ++++++++--- drivers/net/ethernet/wangxun/libwx/wx_ptp.h | 1 + drivers/net/ethernet/wangxun/libwx/wx_type.h | 2 + drivers/net/ethernet/wangxun/txgbe/txgbe_fdir.c | 13 +- drivers/net/ethernet/wangxun/txgbe/txgbe_main.c | 16 ++ drivers/net/macsec.c | 84 +++--- drivers/net/mdio/mdio-realtek-rtl9300.c | 6 + drivers/net/ovpn/netlink.c | 108 +++++++- drivers/net/ovpn/peer.c | 121 +++++++-- drivers/net/ovpn/peer.h | 25 +- drivers/net/ovpn/udp.c | 193 +++++++++++--- drivers/net/pcs/pcs-rzn1-miic.c | 3 +- drivers/net/pcs/pcs-xpcs.c | 4 +- drivers/net/phy/intel-xway.c | 29 +- drivers/net/phy/micrel.c | 1 + drivers/net/phy/phylink.c | 20 +- drivers/net/usb/catc.c | 15 +- drivers/net/usb/cdc_mbim.c | 5 + drivers/net/usb/lan78xx.c | 2 + drivers/net/usb/sr9700.c | 3 +- drivers/net/veth.c | 2 + drivers/net/virtio_net.c | 9 + drivers/net/vrf.c | 2 - drivers/net/vxlan/vxlan_core.c | 6 +- drivers/nfc/microread/microread.c | 6 +- drivers/nfc/nfcmrvl/fw_dnld.c | 11 +- drivers/nfc/pn533/pn533.c | 14 +- drivers/nfc/pn533/pn533.h | 4 +- drivers/nfc/pn533/usb.c | 4 +- drivers/nfc/pn544/pn544.c | 7 +- drivers/nfc/port100.c | 7 + drivers/nfc/st21nfca/core.c | 12 +- drivers/nfc/st21nfca/i2c.c | 29 +- drivers/nfc/trf7970a.c | 4 +- drivers/nfc/virtual_ncidev.c | 3 +- drivers/pci/of_property.c | 11 +- drivers/pci/setup-bus.c | 23 +- drivers/perf/arm_brbe.c | 2 +- drivers/pinctrl/meson/pinctrl-meson-s4.c | 2 +- drivers/pinctrl/microchip/pinctrl-mpfs-mssio.c | 6 +- drivers/pinctrl/pinctrl-generic.c | 4 + drivers/pinctrl/pinctrl-single.c | 3 +- drivers/pinctrl/qcom/pinctrl-ipq5210.c | 1 + drivers/pinctrl/qcom/pinctrl-nord.c | 34 ++- drivers/pinctrl/sunxi/pinctrl-sun55i-a523-r.c | 2 +- drivers/pinctrl/sunxi/pinctrl-sun55i-a523.c | 2 +- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 82 ++++-- drivers/pinctrl/sunxi/pinctrl-sunxi.h | 9 + drivers/pinctrl/tegra/pinctrl-tegra238.c | 204 +++++++------- drivers/remoteproc/qcom_q6v5_adsp.c | 8 +- drivers/s390/cio/chp.c | 3 + drivers/s390/cio/cio.c | 11 +- drivers/s390/cio/cio.h | 5 +- drivers/s390/cio/cmf.c | 2 +- drivers/s390/cio/device.c | 9 +- drivers/s390/cio/device_fsm.c | 3 + drivers/s390/cio/device_ops.c | 23 ++ drivers/s390/cio/vfio_ccw_fsm.c | 2 +- drivers/s390/crypto/vfio_ap_ops.c | 18 +- drivers/scsi/libiscsi_tcp.c | 3 + drivers/scsi/megaraid/megaraid_sas_base.c | 4 +- drivers/scsi/sd_zbc.c | 8 +- drivers/thermal/gov_step_wise.c | 10 +- drivers/ufs/core/ufshcd.c | 6 + drivers/ufs/host/ufshcd-pltfrm.c | 6 +- fs/autofs/inode.c | 4 + fs/bpf_fs_kfuncs.c | 4 - fs/fs-writeback.c | 25 +- fs/inode.c | 11 +- fs/kernfs/mount.c | 4 +- fs/netfs/buffered_read.c | 34 +-- fs/netfs/objects.c | 4 +- fs/netfs/read_collect.c | 5 + fs/netfs/rolling_buffer.c | 2 +- fs/ntfs3/inode.c | 7 +- fs/ocfs2/namei.c | 9 +- fs/ocfs2/xattr.c | 13 +- fs/ocfs2/xattr.h | 8 +- fs/overlayfs/overlayfs.h | 4 +- fs/smb/client/cached_dir.c | 32 ++- fs/smb/client/dir.c | 52 +++- fs/smb/client/smb2inode.c | 6 +- fs/smb/client/smb2misc.c | 9 +- fs/smb/client/smb2ops.c | 28 +- fs/smb/client/smb2pdu.c | 54 +++- fs/smb/client/transport.c | 71 ++++- fs/squashfs/xz_wrapper.c | 6 +- fs/super.c | 114 ++++---- fs/xfs/libxfs/xfs_metafile.c | 8 +- fs/xfs/libxfs/xfs_rtrefcount_btree.c | 4 +- fs/xfs/scrub/dir.c | 2 +- fs/xfs/scrub/health.c | 6 +- fs/xfs/scrub/inode.c | 2 +- fs/xfs/scrub/inode_repair.c | 2 +- fs/xfs/scrub/newbt.c | 8 +- fs/xfs/scrub/orphanage.c | 6 +- fs/xfs/scrub/repair.c | 21 +- fs/xfs/scrub/scrub.h | 2 +- fs/xfs/scrub/trace.h | 12 +- fs/xfs/xfs_dquot.c | 8 +- fs/xfs/xfs_exchrange.c | 13 +- fs/xfs/xfs_healthmon.c | 4 +- fs/xfs/xfs_icache.c | 2 +- fs/xfs/xfs_log_recover.c | 13 +- fs/xfs/xfs_qm.c | 10 +- fs/xfs/xfs_refcount_item.c | 8 +- fs/xfs/xfs_rmap_item.c | 8 +- include/linux/ethtool.h | 2 + include/linux/fs/super_types.h | 2 +- include/linux/if_vlan.h | 3 + include/linux/mempool.h | 7 + include/linux/mm_types.h | 15 +- include/linux/perf_event.h | 17 -- include/linux/sched.h | 6 +- include/linux/sched/topology.h | 4 +- include/linux/skbuff.h | 24 +- include/net/dst.h | 3 +- include/net/gue.h | 19 +- include/net/ip6_route.h | 4 +- include/net/netfilter/nf_conntrack.h | 5 + include/net/nfc/hci.h | 2 +- include/net/nfc/nfc.h | 3 +- include/net/tcp.h | 4 +- kernel/bpf/btf.c | 140 ++++++---- kernel/bpf/core.c | 21 +- kernel/bpf/crypto.c | 5 +- kernel/bpf/fixups.c | 24 +- kernel/bpf/hashtab.c | 43 ++- kernel/bpf/memalloc.c | 50 ++-- kernel/bpf/offload.c | 2 + kernel/bpf/states.c | 3 + kernel/bpf/syscall.c | 15 +- kernel/bpf/verifier.c | 17 +- kernel/cgroup/cpuset.c | 3 +- kernel/cgroup/pids.c | 5 + kernel/events/core.c | 17 +- kernel/exit.c | 11 +- kernel/kprobes.c | 22 +- kernel/power/hibernate.c | 26 +- kernel/sched/core.c | 2 +- kernel/sched/ext/ext.c | 7 +- kernel/sched/fair.c | 173 ++++++++---- kernel/sched/topology.c | 22 +- kernel/trace/fprobe.c | 15 ++ kernel/workqueue.c | 2 +- mm/backing-dev.c | 5 +- mm/damon/core.c | 39 ++- mm/damon/ops-common.c | 7 +- mm/damon/vaddr.c | 21 +- mm/hugetlb.c | 20 +- mm/rmap.c | 6 +- mm/vma.c | 8 + net/8021q/vlan_dev.c | 5 + net/bluetooth/bnep/core.c | 17 +- net/bluetooth/bnep/netdev.c | 8 +- net/bluetooth/hci_conn.c | 14 +- net/bluetooth/hci_sock.c | 20 +- net/bluetooth/iso.c | 7 + net/bluetooth/l2cap_core.c | 10 +- net/bluetooth/mgmt.c | 27 +- net/bluetooth/rfcomm/core.c | 3 +- net/bluetooth/rfcomm/sock.c | 6 +- net/bluetooth/smp.c | 17 ++ net/bridge/br_mdb.c | 2 + net/bridge/br_stp_bpdu.c | 5 +- net/core/dev.c | 49 +++- net/core/dev.h | 2 + net/core/dev_ioctl.c | 25 +- net/core/filter.c | 46 ++-- net/core/skbuff.c | 21 +- net/core/skmsg.c | 4 + net/core/sock_map.c | 1 + net/ethtool/common.h | 2 + net/ipv4/arp.c | 1 + net/ipv4/devinet.c | 7 +- net/ipv4/fib_semantics.c | 13 +- net/ipv4/fou_core.c | 4 + net/ipv4/inet_connection_sock.c | 3 +- net/ipv4/ip_gre.c | 12 + net/ipv4/ipconfig.c | 45 ++-- net/ipv4/tcp_output.c | 3 + net/ipv4/udp.c | 44 +++- net/ipv6/exthdrs_core.c | 3 + net/ipv6/ip6_fib.c | 2 +- net/ipv6/ip6_gre.c | 2 +- net/ipv6/netfilter/ip6t_rpfilter.c | 2 +- net/ipv6/netfilter/ip6t_rt.c | 11 +- net/ipv6/route.c | 12 +- net/ipv6/seg6.c | 4 +- net/llc/llc_c_ac.c | 2 +- net/llc/llc_s_ac.c | 4 + net/llc/llc_sap.c | 8 +- net/mctp/route.c | 2 +- net/mptcp/protocol.c | 2 +- net/netfilter/ipvs/ip_vs_core.c | 6 + net/netfilter/nf_conntrack_netlink.c | 3 +- net/netfilter/nf_flow_table_offload.c | 7 +- net/netfilter/nf_tables_api.c | 10 +- net/netfilter/nfnetlink_queue.c | 8 +- net/netfilter/nft_synproxy.c | 3 +- net/netlink/genetlink.c | 8 +- net/nfc/core.c | 15 +- net/nfc/digital_dep.c | 8 +- net/nfc/llcp.h | 1 + net/nfc/llcp_commands.c | 2 +- net/nfc/llcp_core.c | 173 ++++++++---- net/nfc/llcp_sock.c | 67 +++-- net/nfc/nci/core.c | 10 +- net/nfc/netlink.c | 7 +- net/nfc/nfc.h | 3 +- net/openvswitch/conntrack.c | 37 ++- net/packet/af_packet.c | 104 +++++--- net/rds/connection.c | 6 + net/rds/ib_frmr.c | 11 +- net/sched/act_api.c | 2 +- net/sched/act_ct.c | 41 ++- net/sched/act_gate.c | 30 ++- net/sched/act_ife.c | 17 +- net/sched/act_meta_mark.c | 6 +- net/sched/act_meta_skbprio.c | 6 +- net/sched/act_meta_skbtcindex.c | 6 +- net/sched/cls_u32.c | 12 +- net/sched/em_text.c | 2 +- net/sched/sch_hfsc.c | 22 ++ net/sched/sch_teql.c | 7 +- net/sctp/associola.c | 15 +- net/sctp/input.c | 7 +- net/sctp/sm_sideeffect.c | 37 +-- net/sctp/sm_statefuns.c | 2 + net/smc/smc_core.c | 2 + net/smc/smc_ib.c | 10 +- net/tipc/group.c | 4 +- net/tipc/monitor.c | 3 +- net/vmw_vsock/af_vsock.c | 3 + net/xdp/xskmap.c | 2 +- security/ipe/eval.c | 12 +- security/ipe/eval.h | 2 +- security/ipe/fs.c | 8 +- security/ipe/hooks.c | 22 +- security/ipe/policy_fs.c | 3 + security/landlock/access.h | 8 + sound/hda/codecs/realtek/alc269.c | 9 + tools/arch/riscv/include/asm/csr.h | 20 +- tools/lib/bpf/libbpf.c | 7 + tools/lib/bpf/relo_core.c | 58 ++-- .../testing/selftests/bpf/prog_tests/linked_list.c | 4 +- tools/testing/selftests/cgroup/test_cpuset_prs.sh | 2 + tools/testing/selftests/cgroup/test_memcontrol.c | 2 +- .../ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc | 2 +- tools/testing/selftests/kvm/steal_time.c | 30 ++- tools/testing/selftests/nci/nci_dev.c | 45 ++-- virt/kvm/kvm_main.c | 30 ++- 471 files changed, 5769 insertions(+), 2585 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/457 drm/amd/display: Atomize IRQ register read/modify/write ops
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leo Li <[email protected]>
[ Upstream commit 63e19ef3ddab806c472748c825f4dc88dcd994e8 ]
[Why]
The OTG_GLOBAL_SYNC_STATUS register controls various HW IRQ sources for the output timing generator (OTG). VUPDATE_NO_LOCK is one of them.
To enable the IRQ, driver sets the VUPDATE_NO_LOCK_EN bit in the GLOBAL_SYNC_STATUS register.
To ack the IRQ after it fires, the driver sets the VUPDATE_NO_LOCK_CLEAR bit in the same GLOBAL_SYNC_STATUS register.
The bit sets are done through read/modify/write operations, which are not atomic. Thus, the following race is possible:
Thread A: IRQ handler:
*HW IRQ fires*
# IRQ disable
val = read(GLOBAL_SYNC_STATUS)
unset(val, VUPDATE_NO_LOCK_EN)
write(val, GLOBAL_SYNC_STATUS)
# ACK reads VUPDATE_NO_LOCK_EN unset val1 = read(GLOBAL_SYNC_STATUS) set(val1, VUPDATE_NO_LOCK_CLEAR)
# IRQ enable
val = read(GLOBAL_SYNC_STATUS)
set(val, VUPDATE_NO_LOCK_EN)
write(val, GLOBAL_SYNC_STATUS)
# BAD! clears VUPDATE_NO_LOCK_EN write(val1, GLOBAL_SYNC_STATUS)
Regarding the tagged Fixes: change, it appears the change made this race more likely to occur. Since VUPDATE_NO_LOCK is now the sole IRQ source for vblank handling, a single race on high refresh panels can lead to a time out.
[How]
The GLOBAL_SYNC_STATUS register is only one example, other IRQ control registers also share the same scheme. On top of GLOBAL_SYNC_STATUS, let's clean up those as well.
To keep things simple, Let's atomize the IRQ rmw ops via a single driver-wide spinlock. Due to the small scope of this lock, it is unlikely to cause noticeable overhead on top of all the existing locking within the IRQ set/handle paths.
Since DM is responsible for locking, wrap dc_interrupt_set/ack with the spinlock in the new amdgpu_dm_irq_set/ack functions. Migrate/drop all references in DM to dc_interrupt_set/ack to use amdgpu_dm_irq_set/ack instead.
Modified for unit tests not present in 7.2.y
--- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 ++++ .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 3 +- .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 3 +- .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 62 +++++++++++-------- .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.h | 28 +++++++++ 6 files changed, 82 insertions(+), 30 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +2 -2
@@ -3344,7 +3344,7 @@ static void dm_gpureset_toggle_interrupts(struct amdgpu_device *adev,if (acrtc && state->stream_status[i].plane_count !=0 &&amdgpu_ip_version (adev,DCE_HWIP ,0 ) ==0 ) { irq_source =IRQ_TYPE_PFLIP + acrtc->otg_inst; - rc =dc_interrupt_set (adev->dm.dc, irq_source, enable) ?0 : -EBUSY ; + rc =amdgpu_dm_irq_set (adev, irq_source, enable) ?0 : -EBUSY ;if (rc)drm_warn (adev_to_drm (adev),"Failed to %s pflip interrupts\n" , enable ?"enable" :"disable" );
@@ -3368,7 +3368,7 @@ static void dm_gpureset_toggle_interrupts(struct amdgpu_device *adev,/* During gpu-reset we disable and then enable vblank irq, so * don't use amdgpu_irq_get/put() to avoid refcount change. */ -if (!dc_interrupt_set (adev->dm.dc, irq_source, enable)) +if (!amdgpu_dm_irq_set (adev, irq_source, enable))drm_warn (adev_to_drm (adev),"Failed to %sable vblank interrupt\n" , enable ?"en" :"dis" ); }else if (acrtc && state->stream_status[i].plane_count !=0 ) {
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +12 -0
@@ -550,6 +550,18 @@ struct amdgpu_display_manager {struct common_irq_params vupdate_params[DC_IRQ_SOURCE_VUPDATE6 -DC_IRQ_SOURCE_VUPDATE1 +1 ]; +/** +* @irq_reg_lock: +* +* Serializes the read-modify-writes of the HW interrupt control +* registers. Several interrupt sources share one register - e.g. the +* enable and clear bits of both VSTARTUP (vblank) and VUPDATE_NO_LOCK +* live in OTG_GLOBAL_SYNC_STATUS. Therefore, enabling one source must +* not race with acking another. Held only across amdgpu_dm_irq_set() +* and amdgpu_dm_irq_ack(). +*/ +spinlock_t irq_reg_lock; +/** * @dmub_trace_params: *
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +2 -1
@@ -31,6 +31,7 @@#include "amdgpu_dm_psr.h" #include "amdgpu_dm_replay.h" #include "amdgpu_dm_crtc.h" +#include "amdgpu_dm_irq.h" #include "amdgpu_dm_plane.h" #include "amdgpu_dm_trace.h" #include "amdgpu_dm_debugfs.h"
@@ -87,7 +88,7 @@ int amdgpu_dm_crtc_set_vupdate_irq(struct drm_crtc *crtc, bool enable) irq_source =IRQ_TYPE_VUPDATE + acrtc->otg_inst; - rc =dc_interrupt_set (adev->dm.dc, irq_source, enable) ?0 : -EBUSY ; + rc =amdgpu_dm_irq_set (adev, irq_source, enable) ?0 : -EBUSY ;DRM_DEBUG_VBL ("crtc %d - vupdate irq %sabling: r=%d\n" , acrtc->crtc_id, enable ?"en" :"dis" , rc);
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +2 -1
@@ -1378,12 +1378,13 @@ void dm_helpers_free_gpu_mem(bool dm_helpers_dmub_outbox_interrupt_control (struct dc_context *ctx,bool enable) { +struct amdgpu_device *adev = ctx->driver_context;enum dc_irq_source irq_source;bool ret; irq_source =DC_IRQ_SOURCE_DMCUB_OUTBOX ; - ret =dc_interrupt_set (ctx->dc, irq_source, enable); + ret =amdgpu_dm_irq_set (adev, irq_source, enable);DRM_DEBUG_DRIVER ("Dmub trace irq %sabling: r=%d\n" , enable ?"en" :"dis" , ret);
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +36 -26
166 lines not on this page · raw message
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.h +28 -0
@@ -81,6 +81,34 @@ void amdgpu_dm_irq_unregister_interrupt(struct amdgpu_device *adev,enum dc_irq_source irq_source, void *ih_index); +/** +* amdgpu_dm_irq_set - enable or disable a DC interrupt source. +* +* @adev: AMD DRM device +* @src: DC interrupt source to toggle +* @enable: true to enable the source, false to disable it +* +* DM-wide replacement for dc_interrupt_set(). As locking is DM's +* responsibility, this is a thin wrapper serializes the underlying +* read-modify-write against the other interrupt sources sharing HW control +* registers with @src, so DM must never call dc_interrupt_set() directly. +* +* Returns: true if the source was toggled. +*/ +bool amdgpu_dm_irq_set (struct amdgpu_device *adev,enum dc_irq_source src, +bool enable); + +/** +* amdgpu_dm_irq_ack - acknowledge a DC interrupt source. +* +* @adev: AMD DRM device +* @src: DC interrupt source to acknowledge +* +* DM-wide replacement for dc_interrupt_ack(), serialized the same way as +* amdgpu_dm_irq_set(). +*/ +void amdgpu_dm_irq_ack (struct amdgpu_device *adev,enum dc_irq_source src); +void amdgpu_dm_set_irq_funcs (struct amdgpu_device *adev);void amdgpu_dm_outbox_init (struct amdgpu_device *adev);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 2/457 ALSA: hda/realtek: Limit Star Labs internal mic boost
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Rhodes <[email protected]>
[ Upstream commit 186d4adbb40138e7cb7cffc87a81e95630ced123 ]
The 30 dB internal mic boost is too high for laptops, especially with fans. Limit Star Labs internal mic boost to 10 dB.
--- sound/hda/codecs/realtek/alc269.c | 6 ++++++ 1 file changed, 6 insertions(+)
sound/hda/codecs/realtek/alc269.c +6 -0
@@ -4209,6 +4209,7 @@ enum {ALC245_FIXUP_CLEVO_NOISY_MIC ,ALC269_FIXUP_VAIO_VJFH52_MIC_NO_PRESENCE ,ALC233_FIXUP_MEDION_MTL_SPK , +ALC269_FIXUP_STARLABS_LIMIT_INT_MIC_BOOST ,ALC233_FIXUP_STARLABS_STARFIGHTER ,ALC294_FIXUP_BASS_SPEAKER_15 , ALC283_FIXUP_DELL_HP_RESUME,
@@ -6755,6 +6756,10 @@ static const struct hda_fixup alc269_fixups[] = { { } }, }, + [ALC269_FIXUP_STARLABS_LIMIT_INT_MIC_BOOST] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc269_fixup_limit_int_mic_boost, + }, [ALC233_FIXUP_STARLABS_STARFIGHTER] = { .type = HDA_FIXUP_FUNC, .v.func = alc233_fixup_starlabs_starfighter,
@@ -8168,6 +8173,7 @@ static const struct hda_quirk alc269_fixup_vendor_tbl[] = {SND_PCI_QUIRK_VENDOR (0x104d ,"Sony VAIO" ,ALC269_FIXUP_SONY_VAIO ),SND_PCI_QUIRK_VENDOR (0x17aa ,"Lenovo XPAD" ,ALC269_FIXUP_LENOVO_XPAD_ACPI ),SND_PCI_QUIRK_VENDOR (0x19e5 ,"Huawei Matebook" ,ALC255_FIXUP_MIC_MUTE_LED ), + SND_PCI_QUIRK_VENDOR(0x2145, "Star Labs", ALC269_FIXUP_STARLABS_LIMIT_INT_MIC_BOOST), {} };
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 3/457 ALSA: hda/realtek: Add StarFighter HDA SSID
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Rhodes <[email protected]>
[ Upstream commit cd401c70df472d3eddd0b6b055726a03c212181a ]
Support the new StarFighter HDA SSID while keeping the existing SSID chained to the same quirk until the new match reaches backports.
--- sound/hda/codecs/realtek/alc269.c | 3 +++ 1 file changed, 3 insertions(+)
sound/hda/codecs/realtek/alc269.c +3 -0
@@ -6763,6 +6763,8 @@ static const struct hda_fixup alc269_fixups[] = { [ALC233_FIXUP_STARLABS_STARFIGHTER] = { .type = HDA_FIXUP_FUNC, .v.func = alc233_fixup_starlabs_starfighter, + .chained = true, + .chain_id = ALC269_FIXUP_STARLABS_LIMIT_INT_MIC_BOOST, }, [ALC294_FIXUP_BASS_SPEAKER_15] = { .type = HDA_FIXUP_FUNC,
@@ -8090,6 +8092,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {SND_PCI_QUIRK (0x1f66 ,0x0105 ,"Ayaneo Portable Game Player" ,ALC287_FIXUP_CS35L41_I2C_2 ),SND_PCI_QUIRK (0x2014 ,0x800a ,"Positivo ARN50" ,ALC269_FIXUP_LIMIT_INT_MIC_BOOST ),SND_PCI_QUIRK (0x2039 ,0x0001 ,"Inspur S14-G1" ,ALC295_FIXUP_CHROME_BOOK ), +SND_PCI_QUIRK (0x2145 ,0x0001 ,"Star Labs StarFighter" ,ALC233_FIXUP_STARLABS_STARFIGHTER ),SND_PCI_QUIRK (0x2782 ,0x0214 ,"VAIO VJFE-CL" ,ALC269_FIXUP_LIMIT_INT_MIC_BOOST ),SND_PCI_QUIRK (0x2782 ,0x0228 ,"Infinix ZERO BOOK 13" ,ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13 ), SND_PCI_QUIRK(0x2782, 0x0232, "CHUWI CoreBook XPro", ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO),
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 4/457 drm/amd/display: Remove sink usage from DPMS
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dominik Kaszewski <[email protected]>
[ Upstream commit 8fa813b7fd1eccbed13e126166cf764f1f11a7d3 ]
[Why]stream->sink is optional and can be null, so should always be checked before dereference. Additionally, most of its usage in DPMS sequences is for stream->sink->link, which can be replaced with stream->link, as the two should always be the same.
[How]
* Replace stream->sink->link in DPMS on/off
* Add assert to USB4 BW allocation where sink is required
* Avoid inconsistencies in resource access, e.g. don't repeat stream->link after it was already saved to a local variable
* Pull out effective VPG calculation to helper getter
* Formatting fixes
--- .../gpu/drm/amd/display/dc/link/link_dpms.c | 178 +++++++++--------- 1 file changed, 90 insertions(+), 88 deletions(-)
drivers/gpu/drm/amd/display/dc/link/link_dpms.c +90 -88
@@ -2296,6 +2296,8 @@ static enum dc_status enable_link(static bool allocate_usb4_bandwidth_for_stream (struct dc_stream_state *stream,int stream_bw) { +ASSERT (stream->sink); +struct dc_link *link = stream->sink->link;int req_bw = stream_bw;
@@ -2342,6 +2344,8 @@ static bool allocate_usb4_bandwidth_for_stream(struct dc_stream_state *stream, istatic bool allocate_usb4_bandwidth (struct dc_stream_state *stream) { +ASSERT (stream->sink); +bool ret; int bw = dc_bandwidth_in_kbps_from_timing(&stream->timing,
@@ -2361,38 +2365,43 @@ static bool deallocate_usb4_bandwidth(struct dc_stream_state *stream)return ret; } +static struct vpg *get_vpg (struct pipe_ctx *pipe_ctx) +{ +if (dc_is_hdmi_frl_signal (pipe_ctx->stream->signal)) +return pipe_ctx->stream_res.hpo_frl_stream_enc->vpg; +else if (dp_is_128b_132b_signal (pipe_ctx)) +return pipe_ctx->stream_res.hpo_dp_stream_enc->vpg; +else +return pipe_ctx->stream_res.stream_enc->vpg; +} +void link_set_dpms_off (struct pipe_ctx *pipe_ctx) { -struct dc *dc = pipe_ctx->stream->ctx->dc; +DC_LOGGER_INIT (pipe_ctx->stream->ctx->logger);struct dc_stream_state *stream = pipe_ctx->stream; -struct dc_link *link = stream->sink->link; -struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg; +struct dc *dc = stream->ctx->dc; +struct dc_link *link = stream->link; +struct vpg *vpg =get_vpg (pipe_ctx);enum dp_panel_mode panel_mode_dp =dp_get_panel_mode (link); -DC_LOGGER_INIT (pipe_ctx->stream->ctx->logger); -ASSERT (is_master_pipe_for_link (link, pipe_ctx)); -if (dp_is_128b_132b_signal (pipe_ctx)) - vpg = pipe_ctx->stream_res.hpo_dp_stream_enc->vpg; -if (dc_is_hdmi_frl_signal (pipe_ctx->stream->signal)) - vpg = pipe_ctx->stream_res.hpo_frl_stream_enc->vpg; -if (dc_is_virtual_signal (pipe_ctx->stream->signal)) +if (dc_is_virtual_signal (stream->signal))return ; -if (pipe_ctx->stream->sink) { -if (pipe_ctx->stream->sink->sink_signal !=SIGNAL_TYPE_VIRTUAL && - pipe_ctx->stream->sink->sink_signal !=SIGNAL_TYPE_NONE ) { +if (stream->sink) { +if (stream->sink->sink_signal !=SIGNAL_TYPE_VIRTUAL && + stream->sink->sink_signal !=SIGNAL_TYPE_NONE ) {DC_LOG_DC ("%s pipe_ctx dispname=%s signal=%x link=%d sink_count=%d\n" , __func__, - pipe_ctx->stream->sink->edid_caps.display_name, - pipe_ctx->stream->signal, link->link_index, link->sink_count); + stream->sink->edid_caps.display_name, + stream->signal, link->link_index, link->sink_count); } }link_wait_for_unlocked (link); -if (!pipe_ctx->stream->sink->edid_caps.panel_patch.skip_avmute) { -if (dc_is_hdmi_signal (pipe_ctx->stream->signal)) +if (stream->sink && !stream->sink->edid_caps.panel_patch.skip_avmute) { +if (dc_is_hdmi_signal (stream->signal))set_avmute (pipe_ctx, true); }
@@ -2402,15 +2411,15 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx) dc->hwss.blank_stream (pipe_ctx);if (pipe_ctx->link_config.dp_tunnel_settings.should_use_dp_bw_allocation) -deallocate_usb4_bandwidth (pipe_ctx->stream); +deallocate_usb4_bandwidth (stream); -if (pipe_ctx->stream->signal ==SIGNAL_TYPE_DISPLAY_PORT_MST ) +if (stream->signal ==SIGNAL_TYPE_DISPLAY_PORT_MST )deallocate_mst_payload (pipe_ctx); -else if (dc_is_dp_sst_signal (pipe_ctx->stream->signal) && +else if (dc_is_dp_sst_signal (stream->signal) &&dp_is_128b_132b_signal (pipe_ctx))update_sst_payload (pipe_ctx, false); -if (dc_is_hdmi_signal (pipe_ctx->stream->signal)) { +if (dc_is_hdmi_signal (stream->signal)) {struct ext_hdmi_settings settings = {0 };enum engine_id eng_id = pipe_ctx->stream_res.stream_enc->id;
@@ -2433,7 +2442,7 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx) } } -if (pipe_ctx->stream->signal ==SIGNAL_TYPE_DISPLAY_PORT && +if (stream->signal ==SIGNAL_TYPE_DISPLAY_PORT && !dp_is_128b_132b_signal (pipe_ctx)) {/* In DP1.x SST mode, our encoder will go to TPS1
@@ -2443,18 +2452,18 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx)* state machine. * In DP2 or MST mode, our encoder will stay video active */ -disable_link (pipe_ctx->stream->link, &pipe_ctx->link_res, pipe_ctx->stream->signal); +disable_link (link, &pipe_ctx->link_res, stream->signal); dc->hwss.disable_stream (pipe_ctx); }else { dc->hwss.disable_stream (pipe_ctx); -disable_link (pipe_ctx->stream->link, &pipe_ctx->link_res, pipe_ctx->stream->signal); +disable_link (link, &pipe_ctx->link_res, stream->signal); }edp_set_panel_assr (link, pipe_ctx, &panel_mode_dp, false); -if (pipe_ctx->stream->timing.flags.DSC) { -if (dc_is_dp_signal (pipe_ctx->stream->signal)) +if (stream->timing.flags.DSC) { +if (dc_is_dp_signal (stream->signal))link_set_dsc_enable (pipe_ctx, false); -else if (dc_is_hdmi_frl_signal (pipe_ctx->stream->signal)) +else if (dc_is_hdmi_frl_signal (stream->signal))link_set_dsc_on_stream (pipe_ctx, false); }if (dp_is_128b_132b_signal (pipe_ctx)) {
@@ -2468,7 +2477,7 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx)/* for psp not exist case */ if (link->connector_signal ==SIGNAL_TYPE_EDP && dc->debug.psp_disabled_wa) {/* reset internal save state to default since eDP is off */ -enum dp_panel_mode panel_mode =dp_get_panel_mode (pipe_ctx->stream->link); +enum dp_panel_mode panel_mode =dp_get_panel_mode (link);/* since current psp not loaded, we need to reset it to default */ link->panel_mode = panel_mode; }
@@ -2478,62 +2487,57 @@ void link_set_dpms_on(struct dc_state *state, struct pipe_ctx *pipe_ctx) { - struct dc *dc = pipe_ctx->stream->ctx->dc; + DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);struct dc_stream_state *stream = pipe_ctx->stream; -struct dc_link *link = stream->sink->link; +struct dc *dc = stream->ctx->dc; +struct dc_link *link = stream->link;enum dc_status status;struct link_encoder *link_enc = pipe_ctx->link_res.dio_link_enc;enum otg_out_mux_dest otg_out_dest =OUT_MUX_DIO ; -struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg; +struct vpg *vpg =get_vpg (pipe_ctx);const struct link_hwss *link_hwss =get_link_hwss (link, &pipe_ctx->link_res);bool apply_edp_fast_boot_optimization = - pipe_ctx->stream->apply_edp_fast_boot_optimization; - -DC_LOGGER_INIT (pipe_ctx->stream->ctx->logger); + stream->apply_edp_fast_boot_optimization;ASSERT (is_master_pipe_for_link (link, pipe_ctx)); -if (dp_is_128b_132b_signal (pipe_ctx)) - vpg = pipe_ctx->stream_res.hpo_dp_stream_enc->vpg; -if (dc_is_hdmi_frl_signal (pipe_ctx->stream->signal)) - vpg = pipe_ctx->stream_res.hpo_frl_stream_enc->vpg; -if (dc_is_virtual_signal (pipe_ctx->stream->signal)) +if (dc_is_virtual_signal (stream->signal))return ; -if (pipe_ctx->stream->sink) { -if (pipe_ctx->stream->sink->sink_signal !=SIGNAL_TYPE_VIRTUAL && - pipe_ctx->stream->sink->sink_signal !=SIGNAL_TYPE_NONE ) { +if (stream->sink) { +if (stream->sink->sink_signal !=SIGNAL_TYPE_VIRTUAL && + stream->sink->sink_signal !=SIGNAL_TYPE_NONE ) {DC_LOG_DC ("%s pipe_ctx dispname=%s signal=%x link=%d sink_count=%d\n" , __func__, - pipe_ctx->stream->sink->edid_caps.display_name, - pipe_ctx->stream->signal, + stream->sink->edid_caps.display_name, + stream->signal, link->link_index, link->sink_count); } } -link_wait_for_unlocked (stream->link); +link_wait_for_unlocked (link);if (!dc->config.unify_link_enc_assignment) link_enc =link_enc_cfg_get_link_enc (link);ASSERT (link_enc); -if (!dc_is_virtual_signal (pipe_ctx->stream->signal) - && !dc_is_hdmi_frl_signal (pipe_ctx->stream->signal) +if (!dc_is_virtual_signal (stream->signal) + && !dc_is_hdmi_frl_signal (stream->signal) && !dp_is_128b_132b_signal (pipe_ctx)) {if (link_enc) link_enc->funcs->setup ( link_enc, - pipe_ctx->stream->signal); + stream->signal); } - pipe_ctx->stream->link->link_state_valid = true; + link->link_state_valid = true; -if (dc_is_hdmi_frl_signal (pipe_ctx->stream->signal)) -hdmi_frl_decide_link_settings (stream, &stream->link->frl_link_settings, &pipe_ctx->dsc_padding_params); +if (dc_is_hdmi_frl_signal (stream->signal)) +hdmi_frl_decide_link_settings (stream, &link->frl_link_settings, &pipe_ctx->dsc_padding_params);if (pipe_ctx->stream_res.tg->funcs->set_out_mux) {if (dp_is_128b_132b_signal (pipe_ctx)) otg_out_dest =OUT_MUX_HPO_DP ; -else if (dc_is_hdmi_frl_signal (pipe_ctx->stream->signal)) +else if (dc_is_hdmi_frl_signal (stream->signal)) otg_out_dest =OUT_MUX_HPO_FRL ;else otg_out_dest =OUT_MUX_DIO ;
@@ -2542,7 +2546,7 @@ void link_set_dpms_on( link_hwss->setup_stream_attribute (pipe_ctx); - pipe_ctx->stream->apply_edp_fast_boot_optimization = false; + stream->apply_edp_fast_boot_optimization = false;// Enable VPG before building infoframe if (vpg && vpg->funcs->vpg_poweron)
@@ -2551,15 +2555,15 @@ void link_set_dpms_on(resource_build_info_frame (pipe_ctx); dc->hwss.update_info_frame (pipe_ctx); -if (dc_is_dp_signal (pipe_ctx->stream->signal)) +if (dc_is_dp_signal (stream->signal))dp_trace_source_sequence (link,DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME );/* Do not touch link on seamless boot optimization. */ -if (pipe_ctx->stream->apply_seamless_boot_optimization) { - pipe_ctx->stream->dpms_off = false; +if (stream->apply_seamless_boot_optimization) { + stream->dpms_off = false;/* Still enable stream features & audio on seamless boot for DP external displays */ -if (pipe_ctx->stream->signal ==SIGNAL_TYPE_DISPLAY_PORT ) { +if (stream->signal ==SIGNAL_TYPE_DISPLAY_PORT ) {enable_stream_features (pipe_ctx); dc->hwss.enable_audio_stream (pipe_ctx); }
@@ -2569,11 +2573,11 @@ void link_set_dpms_on( }/* eDP lit up by bios already, no need to enable again. */ -if (pipe_ctx->stream->signal ==SIGNAL_TYPE_EDP && +if (stream->signal ==SIGNAL_TYPE_EDP && apply_edp_fast_boot_optimization && - !pipe_ctx->stream->timing.flags.DSC && + !stream->timing.flags.DSC && !pipe_ctx->next_odm_pipe) { - pipe_ctx->stream->dpms_off = false; + stream->dpms_off = false;update_psp_stream_config (pipe_ctx, false);if (link->is_dds) {
@@ -2586,7 +2590,7 @@ void link_set_dpms_on(return ; } -if (pipe_ctx->stream->dpms_off) +if (stream->dpms_off)return ;/* For Dp tunneling link, a pending HPD means that we have a race condition between processing
@@ -2604,9 +2608,9 @@ void link_set_dpms_on(* will be automatically set at a later time when the video is enabled * (DP_VID_STREAM_EN = 1). */ -if (pipe_ctx->stream->timing.flags.DSC) { -if (dc_is_dp_signal (pipe_ctx->stream->signal) || -dc_is_virtual_signal (pipe_ctx->stream->signal)) +if (stream->timing.flags.DSC) { +if (dc_is_dp_signal (stream->signal) || +dc_is_virtual_signal (stream->signal))link_set_dsc_enable (pipe_ctx, true); }
@@ -2617,7 +2621,7 @@ void link_set_dpms_on(if (status !=DC_OK ) {DC_LOG_WARNING ("enabling link %u failed: %d\n" , - pipe_ctx->stream->link->link_index, + link->link_index, status);/* Abort stream enable *unless* the failure was due to
@@ -2627,19 +2631,18 @@ void link_set_dpms_on(*/ if ((status !=DC_FAIL_DP_LINK_TRAINING && status !=DC_FAIL_HDMI_FRL_LINK_TRAINING ) || - pipe_ctx->stream->signal ==SIGNAL_TYPE_DISPLAY_PORT_MST ) { -if (false == stream->link->link_status.link_active) -disable_link (stream->link, &pipe_ctx->link_res, - pipe_ctx->stream->signal); + stream->signal ==SIGNAL_TYPE_DISPLAY_PORT_MST ) { +if (false == link->link_status.link_active) +disable_link (link, &pipe_ctx->link_res, + stream->signal);BREAK_TO_DEBUGGER ();return ; } } -if (pipe_ctx->stream->timing.flags.DSC && -dc_is_hdmi_frl_signal (pipe_ctx->stream->signal)) -//TODO: bring HDMI FRL in line with DP -link_set_dsc_on_stream (pipe_ctx, true); +if (stream->timing.flags.DSC &&dc_is_hdmi_frl_signal (stream->signal)) +//TODO: bring HDMI FRL in line with DP +link_set_dsc_on_stream (pipe_ctx, true);/* turn off otg test pattern if enable */ if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
@@ -2651,37 +2654,37 @@ void link_set_dpms_on(* as a workaround for the incorrect value being applied * from transmitter control. */ -if (!(dc_is_virtual_signal (pipe_ctx->stream->signal) || -dc_is_hdmi_frl_signal (pipe_ctx->stream->signal) || +if (!(dc_is_virtual_signal (stream->signal) || +dc_is_hdmi_frl_signal (stream->signal) ||dp_is_128b_132b_signal (pipe_ctx))) {if (link_enc) link_enc->funcs->setup ( link_enc, - pipe_ctx->stream->signal); + stream->signal); } dc->hwss.enable_stream (pipe_ctx);/* Set DPS PPS SDP (AKA "info frames") */ -if (pipe_ctx->stream->timing.flags.DSC) { -if (dc_is_dp_signal (pipe_ctx->stream->signal) || -dc_is_virtual_signal (pipe_ctx->stream->signal)) { +if (stream->timing.flags.DSC) { +if (dc_is_dp_signal (stream->signal) || +dc_is_virtual_signal (stream->signal)) {dp_set_dsc_on_rx (pipe_ctx, true);link_set_dsc_pps_packet (pipe_ctx, true, true); } } -if (dc_is_dp_signal (pipe_ctx->stream->signal)) +if (dc_is_dp_signal (stream->signal))dp_set_hblank_reduction_on_rx (pipe_ctx);if (pipe_ctx->link_config.dp_tunnel_settings.should_use_dp_bw_allocation) -allocate_usb4_bandwidth (pipe_ctx->stream); +allocate_usb4_bandwidth (stream); -if (pipe_ctx->stream->signal ==SIGNAL_TYPE_DISPLAY_PORT_MST ) +if (stream->signal ==SIGNAL_TYPE_DISPLAY_PORT_MST )allocate_mst_payload (pipe_ctx); -else if (dc_is_dp_sst_signal (pipe_ctx->stream->signal) && +else if (dc_is_dp_sst_signal (stream->signal) &&dp_is_128b_132b_signal (pipe_ctx))update_sst_payload (pipe_ctx, true);
@@ -2690,23 +2693,22 @@ void link_set_dpms_on(* training and stream unblank resolves the corruption issue. * This is workaround. */ -if (pipe_ctx->stream->signal ==SIGNAL_TYPE_EDP && +if (stream->signal ==SIGNAL_TYPE_EDP && link->is_display_mux_present)msleep (20 ); dc->hwss.unblank_stream (pipe_ctx, - &pipe_ctx->stream->link->cur_link_settings); + &link->cur_link_settings);if (stream->sink_patches.delay_ignore_msa >0 )msleep (stream->sink_patches.delay_ignore_msa); -if (dc_is_dp_signal (pipe_ctx->stream->signal)) +if (dc_is_dp_signal (stream->signal))enable_stream_features (pipe_ctx);update_psp_stream_config (pipe_ctx, false); dc->hwss.enable_audio_stream (pipe_ctx); -if (dc_is_hdmi_signal (pipe_ctx->stream->signal)) { +if (dc_is_hdmi_signal (stream->signal))set_avmute (pipe_ctx, false); - } }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 5/457 remoteproc: qcom_q6v5_adsp: Fix iommu_unmap() usage
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mostafa Saleh <[email protected]>
[ Upstream commit 0d8e2195bce6f08c1c53c5ef4d7347fe46418101 ]
During adsp_map_carveout, the IOVA is computed by combining the physical address and the SID:
iova = adsp->mem_phys | (sid << 32);
However, adsp_unmap_carveout() uses the physical address and not the IOVA in iommu_unmap(), causing the unmap to fail or leak mappings because the address doesn't match the original IOVA.
Cache the constructed IOVA within the qcom_adsp device struct during mapping and use it during unmapping.
--- drivers/remoteproc/qcom_q6v5_adsp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/remoteproc/qcom_q6v5_adsp.c +4 -4
@@ -104,6 +104,7 @@ struct qcom_adsp {struct completion stop_done;phys_addr_t mem_phys; +unsigned long iova;phys_addr_t mem_reloc;void *mem_region;size_t mem_size;
@@ -333,7 +334,7 @@ static void adsp_unmap_carveout(struct rproc *rproc)struct qcom_adsp *adsp = rproc->priv;if (adsp->has_iommu) -iommu_unmap (rproc->domain, adsp->mem_phys, adsp->mem_size); +iommu_unmap (rproc->domain, adsp->iova, adsp->mem_size); }static int adsp_map_carveout (struct rproc *rproc)
@@ -341,7 +342,6 @@ static int adsp_map_carveout(struct rproc *rproc)struct qcom_adsp *adsp = rproc->priv;struct of_phandle_args args;long long sid; -unsigned long iova;int ret;if (!adsp->has_iommu)
@@ -358,9 +358,9 @@ static int adsp_map_carveout(struct rproc *rproc)of_node_put (args.np);/* Add SID configuration for ADSP Firmware to SMMU */ - iova = adsp->mem_phys | (sid <<32 ); + adsp->iova = adsp->mem_phys | (sid <<32 ); - ret =iommu_map (rproc->domain, iova, adsp->mem_phys, + ret =iommu_map (rproc->domain, adsp->iova, adsp->mem_phys, adsp->mem_size,IOMMU_READ |IOMMU_WRITE ,GFP_KERNEL );if (ret) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 6/457 KVM: s390: Fix dirty marking in adapter_indicators_set*()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudio Imbrenda <[email protected]>
[ Upstream commit d215f014b3526a9898d87bfb4b866287f0864cc9 ]
When the indicator and/or summary bits are set in the guest, the accessed page was only marked dirty in KVM if the access was performed using the slow path; accesses through the new kvm_arch_set_irq_inatomic fast inject path would not mark the page as dirty.
Fix by adding/moving the missing calls to mark_page_dirty(). Note that for the inatomic path set_page_dirty{,_lock}() is not needed as the page stays pinned; the unpin path correctly marks it as dirty.
Opportunistically reorder the local variables to be in reverse Christmas tree order and refactor to use guard().
Message-ID: <[email protected]>
--- arch/s390/kvm/interrupt.c | 75 ++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 37 deletions(-)
arch/s390/kvm/interrupt.c +38 -37
@@ -2976,61 +2976,58 @@ static int adapter_indicators_set(struct kvm *kvm,struct s390_io_adapter *adapter, struct kvm_s390_adapter_int *adapter_int) { - unsigned long bit; -int summary_set, idx; struct s390_map_info *ind_info, *summary_info; -void *map;struct page *ind_page, *summary_page; -unsigned long flags; +unsigned long bit; +int summary_set; +void *map; ind_page =NULL ; -spin_lock_irqsave (&adapter->maps_lock, flags); - ind_info =get_map_info (adapter, adapter_int->ind_addr); + scoped_guard(spinlock_irqsave, &adapter->maps_lock) { + ind_info =get_map_info (adapter, adapter_int->ind_addr); +if (ind_info) { + map =page_address (ind_info->page); + bit =get_ind_bit (ind_info->addr, adapter_int->ind_offset, adapter->swap); +set_bit (bit, map); + } + }if (!ind_info) { -spin_unlock_irqrestore (&adapter->maps_lock, flags); ind_page =pin_map_page (kvm, adapter_int->ind_addr,0 );if (!ind_page)return -1 ; - idx =srcu_read_lock (&kvm->srcu); map =page_address (ind_page); bit =get_ind_bit (adapter_int->ind_addr, adapter_int->ind_offset, adapter->swap);set_bit (bit, map); -mark_page_dirty (kvm, adapter_int->ind_gaddr >>PAGE_SHIFT );set_page_dirty_lock (ind_page); -srcu_read_unlock (&kvm->srcu, idx);unpin_user_page (ind_page); - }else { - map =page_address (ind_info->page); - bit =get_ind_bit (ind_info->addr, adapter_int->ind_offset, adapter->swap); -set_bit (bit, map); -spin_unlock_irqrestore (&adapter->maps_lock, flags); } + scoped_guard(srcu, &kvm->srcu) +mark_page_dirty (kvm,gpa_to_gfn (adapter_int->ind_gaddr)); -spin_lock_irqsave (&adapter->maps_lock, flags); - summary_info =get_map_info (adapter, adapter_int->summary_addr); + scoped_guard(spinlock_irqsave, &adapter->maps_lock) { + summary_info =get_map_info (adapter, adapter_int->summary_addr); +if (summary_info) { + map =page_address (summary_info->page); + bit =get_ind_bit (summary_info->addr, adapter_int->summary_offset, + adapter->swap); + summary_set =test_and_set_bit (bit, map); + } + }if (!summary_info) { -spin_unlock_irqrestore (&adapter->maps_lock, flags); summary_page =pin_map_page (kvm, adapter_int->summary_addr,0 );if (WARN_ON_ONCE (!summary_page))return -1 ; - idx =srcu_read_lock (&kvm->srcu); map =page_address (summary_page); bit =get_ind_bit (adapter_int->summary_addr, adapter_int->summary_offset, adapter->swap); summary_set =test_and_set_bit (bit, map); -mark_page_dirty (kvm, adapter_int->summary_gaddr >>PAGE_SHIFT );set_page_dirty_lock (summary_page); -srcu_read_unlock (&kvm->srcu, idx);unpin_user_page (summary_page); - }else { - map =page_address (summary_info->page); - bit =get_ind_bit (summary_info->addr, adapter_int->summary_offset, - adapter->swap); - summary_set =test_and_set_bit (bit, map); -spin_unlock_irqrestore (&adapter->maps_lock, flags); } + scoped_guard(srcu, &kvm->srcu) +mark_page_dirty (kvm,gpa_to_gfn (adapter_int->summary_gaddr));return summary_set ?0 :1 ; }
@@ -3040,26 +3037,29 @@ static int adapter_indicators_set_fast(struct kvm *kvm, struct kvm_s390_adapter_int *adapter_int, int setbit) { +struct s390_map_info *ind_info, *summary_info;unsigned long bit;int summary_set; -struct s390_map_info *ind_info, *summary_info;void *map; -spin_lock (&adapter->maps_lock); +guard (srcu)(&kvm->srcu); +guard (spinlock)(&adapter->maps_lock); + ind_info =get_map_info (adapter, adapter_int->ind_addr); -if (!ind_info) { -spin_unlock (&adapter->maps_lock); +if (!ind_info)return -EWOULDBLOCK ; - } + map =page_address (ind_info->page); bit =get_ind_bit (ind_info->addr, adapter_int->ind_offset, adapter->swap); -if (setbit) +if (setbit) {set_bit (bit, map); +mark_page_dirty (kvm,gpa_to_gfn (adapter_int->ind_gaddr)); + } + summary_info =get_map_info (adapter, adapter_int->summary_addr); -if (!summary_info) { -spin_unlock (&adapter->maps_lock); +if (!summary_info)return -EWOULDBLOCK ; - } + map =page_address (summary_info->page); bit =get_ind_bit (summary_info->addr, adapter_int->summary_offset, adapter->swap);
@@ -3069,7 +3069,8 @@ static int adapter_indicators_set_fast(struct kvm *kvm, summary_set =test_and_set_bit (bit, map); else summary_set =test_and_clear_bit (bit, map); -spin_unlock (&adapter->maps_lock); +mark_page_dirty (kvm,gpa_to_gfn (adapter_int->summary_gaddr)); +return summary_set ?0 :1 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 7/457 KVM: s390: Fix _gaccess_shadow_fault()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudio Imbrenda <[email protected]>
[ Upstream commit faff4c8ff3dbec6d71b89dd281a0d17c4478fa44 ]
In some circumstances, it is possible that the page of nested guest memory that is being shadowed is not present at all in the parent guest gmap. dat_entry_walk() will not find any leaf entry and return with -ENOENT, which will erroneously be propagated all the way to userspace.
Fix by manually calling gmap_link() on the memory of the nested guest that is being shadowed if the mapping was not already present.
Message-ID: <[email protected]>
--- arch/s390/kvm/gaccess.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
arch/s390/kvm/gaccess.c +13 -0
@@ -1593,12 +1593,25 @@ static inline int ___gaccess_shadow_fault(struct kvm_vcpu *vcpu, struct gmap *sg parent =READ_ONCE (sg->parent);if (!parent)return -EAGAIN ; +retry: scoped_guard(spinlock, &parent->children_lock) {if (READ_ONCE (sg->parent) != parent)return -EAGAIN ; sg->invalidated = false; rc =_gaccess_do_shadow (vcpu->arch.mc, sg, saddr, walk); } +if (rc == -ENOENT ) { +struct kvm_memory_slot *slot; +struct guest_fault *entries; + + entries =get_entries (walk); + slot =kvm_vcpu_gfn_to_memslot (vcpu, entries[LEVEL_MEM ].gfn); +if (!slot) +return PGM_ADDRESSING ; + rc =gmap_link (vcpu->arch.mc, parent, entries +LEVEL_MEM , slot); +if (!rc) + goto retry; + }if (!rc)kvm_s390_release_faultin_array (vcpu->kvm, walk->raw_entries, false);return rc;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 8/457 KVM: s390: Fix IRQ injection with SIGP Stop and Store Status
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudio Imbrenda <[email protected]>
[ Upstream commit d343407b728a80b74be3c24b59f15e60289ea527 ]
When __inject_sigp_stop() is called for a Stop and Store Status operation, if the vCPU is running, the interrupt is marked as pending and the status is stored by the thread performing the KVM_RUN IOCTL.
If the vCPU is already stopped, the status is stored immediately.
Storing the status means writing into userspace, which might fault, and __inject_sigp_stop() is called from do_inject_vcpu() which in turn is always called holding a spinlock, which is obviously an issue.
Fix this by returning -EWOULDBLOCK from __inject_sigp_stop(), and adding a bool flag to indicate whether a store status is needed. The callers of do_inject_vcpu() are modified to pass the pointer to the bool flag; whenever a Store Status operation is needed, the callers can now perform it outside the spinlock.
Opportunistically refactor kvm_s390_set_irq_state() to use scoped_guard() and __free().
Message-ID: <[email protected]>
Stable-dep-of: f3a557067d57 ("KVM: s390: Add missing srcu in kvm_s390_set_irq_state()")
--- arch/s390/kvm/interrupt.c | 70 +++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 32 deletions(-)
arch/s390/kvm/interrupt.c +38 -32
@@ -1550,23 +1550,21 @@ static int __inject_set_prefix(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) }#define KVM_S390_STOP_SUPP_FLAGS (KVM_S390_STOP_FLAG_STORE_STATUS) -static int __inject_sigp_stop (struct kvm_vcpu *vcpu,struct kvm_s390_irq *irq) +static int __inject_sigp_stop (struct kvm_vcpu *vcpu,struct kvm_s390_irq *irq,bool *storestatus) {struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;struct kvm_s390_stop_info *stop = &li->irq.stop; -int rc =0 ; vcpu->stat.inject_stop_signal++;trace_kvm_s390_inject_vcpu (vcpu->vcpu_id,KVM_S390_SIGP_STOP ,0 ,0 );if (irq->u.stop.flags & ~KVM_S390_STOP_SUPP_FLAGS )return -EINVAL ; -if (is_vcpu_stopped (vcpu)) { -if (irq->u.stop.flags &KVM_S390_STOP_FLAG_STORE_STATUS ) - rc =kvm_s390_store_status_unloaded (vcpu, -KVM_S390_STORE_STATUS_NOADDR ); -return rc; +if (!(irq->u.stop.flags &KVM_S390_STOP_FLAG_STORE_STATUS )) +return 0 ; + *storestatus = true; +return -EWOULDBLOCK ; }if (test_and_set_bit (IRQ_PEND_SIGP_STOP , &li->pending_irqs))
@@ -2102,7 +2100,7 @@ void kvm_s390_clear_stop_irq(struct kvm_vcpu *vcpu)spin_unlock (&li->lock); } -static int do_inject_vcpu (struct kvm_vcpu *vcpu,struct kvm_s390_irq *irq) +static int do_inject_vcpu (struct kvm_vcpu *vcpu,struct kvm_s390_irq *irq,bool *storestatus) {int rc;
@@ -2114,7 +2112,7 @@ static int do_inject_vcpu(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) rc =__inject_set_prefix (vcpu, irq);break ;case KVM_S390_SIGP_STOP : - rc =__inject_sigp_stop (vcpu, irq); + rc =__inject_sigp_stop (vcpu, irq, storestatus);break ;case KVM_S390_RESTART : rc =__inject_sigp_restart (vcpu);
@@ -2150,11 +2148,16 @@ static int do_inject_vcpu(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)int kvm_s390_inject_vcpu (struct kvm_vcpu *vcpu,struct kvm_s390_irq *irq) {struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; +bool storestatus = false;int rc;spin_lock (&li->lock); - rc =do_inject_vcpu (vcpu, irq); + rc =do_inject_vcpu (vcpu, irq, &storestatus);spin_unlock (&li->lock); + +if (rc == -EWOULDBLOCK && storestatus) + rc =kvm_s390_store_status_unloaded (vcpu,KVM_S390_STORE_STATUS_NOADDR ); +if (!rc)kvm_s390_vcpu_wakeup (vcpu);return rc;
@@ -3190,7 +3193,8 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, struct kvm *kvm,int kvm_s390_set_irq_state (struct kvm_vcpu *vcpu,void __user *irqstate,int len) {struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; -struct kvm_s390_irq *buf; + struct kvm_s390_irq *buf __free(kvfree) = NULL; +bool tmp, storestatus = false;int r =0 ;int n;
@@ -3198,31 +3202,33 @@ int kvm_s390_set_irq_state(struct kvm_vcpu *vcpu, void __user *irqstate, int lenif (!buf)return -ENOMEM ; -if (copy_from_user ((void *) buf, irqstate, len)) { - r = -EFAULT ; - goto out_free; - } +if (copy_from_user ((void *)buf, irqstate, len)) +return -EFAULT ; -/* -* Don't allow setting the interrupt state -* when there are already interrupts pending -*/ -spin_lock (&li->lock); -if (li->pending_irqs) { - r = -EBUSY ; - goto out_unlock; - } + scoped_guard(spinlock, &li->lock) { +/* +* Don't allow setting the interrupt state +* when there are already interrupts pending +*/ +if (li->pending_irqs) +return -EBUSY ; -for (n =0 ; n < len /sizeof (*buf); n++) { - r =do_inject_vcpu (vcpu, &buf[n]); -if (r) -break ; +for (n =0 ; n < len /sizeof (*buf); n++) { + tmp = false; + r =do_inject_vcpu (vcpu, &buf[n], &tmp); +if (r == -EWOULDBLOCK && tmp) { + storestatus = true; + r =0 ; + } +if (r) +break ; + } } -out_unlock: -spin_unlock (&li->lock); -out_free: -vfree (buf); +if (storestatus) { + n =kvm_s390_store_status_unloaded (vcpu,KVM_S390_STORE_STATUS_NOADDR ); +return r ? r : n; + }return r; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 9/457 KVM: s390: Add missing srcu in kvm_s390_set_irq_state()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudio Imbrenda <[email protected]>
[ Upstream commit f3a557067d57ce6ae98d485c8009b223e16f5f36 ]
Like kvm_s390_inject_vcpu(), kvm_s390_set_irq_state() also needs the kvm->srcu or the slots lock when performing the Store status operation.
Fix by taking kvm->srcu in kvm_s390_set_irq_state().
Message-ID: <[email protected]>
--- arch/s390/kvm/interrupt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/s390/kvm/interrupt.c +2 -2
@@ -3224,9 +3224,9 @@ int kvm_s390_set_irq_state(struct kvm_vcpu *vcpu, void __user *irqstate, int lenbreak ; } } -if (storestatus) { - n =kvm_s390_store_status_unloaded (vcpu,KVM_S390_STORE_STATUS_NOADDR ); +scoped_guard (srcu, &vcpu->kvm->srcu) + n = kvm_s390_store_status_unloaded(vcpu, KVM_S390_STORE_STATUS_NOADDR);return r ? r : n; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 10/457 KVM: s390: Properly handle NULL pointer in dat_cond_set_storage_key()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudio Imbrenda <[email protected]>
[ Upstream commit 88e22ffd1e46b95e40a6afabe486deb1d31a3ae1 ]
Some callers pass NULL as oldkey. Calling page_cond_set_storage_key() will cause that NULL pointer to get dereferenced.
Fix by checking for NULL and assigning the pointer to a dummy local variable to avoid crashes.
Message-ID: <[email protected]>
Stable-dep-of: 27554b9505dd ("KVM: s390: Fix potential races in dat skey functions")
--- arch/s390/kvm/dat.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
arch/s390/kvm/dat.c +4 -1
@@ -722,9 +722,12 @@ int dat_cond_set_storage_key(struct kvm_s390_mmu_cache *mmc, union asce asce, gfif (rc)return rc; -if (!ptep) +if (!ptep) { +if (!oldkey) + oldkey = &prev;return page_cond_set_storage_key (large_crste_to_phys (*crstep, gfn), skey, oldkey, nq, mr, mc); + } old =pgste_get_lock (ptep); pgste = old;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 11/457 KVM: s390: Fix potential races in dat skey functions
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudio Imbrenda <[email protected]>
[ Upstream commit 27554b9505ddfc0aeab466aeb60929dfa17284c7 ]
When dat_cond_set_storage_key() finds a large page, it will conditionally set the storage key in absolute memory using large_crste_to_phys() to get the absolute address.
There is a race window between dat_entry_walk() and large_crste_to_phys(): the large page could have been split concurrently, and large_crste_to_phys() might be called with a crste that does not designate a large page, leading to crashes.
Similar issues were also present in dat_set_storage_key().
dat_get_storage_key() and dat_reset_reference_bit() did instead check for a potential concurrent splitting of the large page, but then handled it incorrectly.
Fix by performing a READ_ONCE on the crste pointer, checking and using the result, instead of dereferencing the pointer again. In case a race is detacted, try dat_entry_walk() again.
Message-ID: <[email protected]>
--- arch/s390/kvm/dat.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-)
arch/s390/kvm/dat.c +28 -8
@@ -620,17 +620,20 @@ int dat_get_storage_key(union asce asce, gfn_t gfn, union skey *skey)union pte *ptep;int rc; +again: skey->skey =0 ; rc =dat_entry_walk (NULL , gfn, asce,DAT_WALK_ANY ,TABLE_TYPE_PAGE_TABLE , &crstep, &ptep);if (rc)return rc;if (!ptep) { -union crste crste; +union crste crste =READ_ONCE (*crstep); - crste =READ_ONCE (*crstep); -if (!crste.h.fc || !crste.s.fc1.pr) +if (!crste_leaf (crste) && !crste.h.i) + goto again; +if (!crste.s.fc1.pr)return 0 ; + skey->skey =page_get_storage_key (large_crste_to_phys (crste, gfn));return 0 ; }
@@ -661,13 +664,20 @@ int dat_set_storage_key(struct kvm_s390_mmu_cache *mc, union asce asce, gfn_t gfunion pte *ptep;int rc; +again: rc =dat_entry_walk (mc, gfn, asce,DAT_WALK_LEAF_ALLOC ,TABLE_TYPE_PAGE_TABLE , &crstep, &ptep);if (rc)return rc;if (!ptep) { -page_set_storage_key (large_crste_to_phys (*crstep, gfn), skey.skey, !nq); +union crste crste =READ_ONCE (*crstep); + +/* A large page has been split concurrently, try again */ +if (!crste_leaf (crste)) + goto again; + +page_set_storage_key (large_crste_to_phys (crste, gfn), skey.skey, !nq);return 0 ; }
@@ -717,15 +727,22 @@ int dat_cond_set_storage_key(struct kvm_s390_mmu_cache *mmc, union asce asce, gfunion pte *ptep;int rc; +again: rc =dat_entry_walk (mmc, gfn, asce,DAT_WALK_LEAF_ALLOC ,TABLE_TYPE_PAGE_TABLE , &crstep, &ptep);if (rc)return rc;if (!ptep) { +union crste crste =READ_ONCE (*crstep); + +/* A large page has been split concurrently, try again */ +if (!crste_leaf (crste)) + goto again;if (!oldkey) oldkey = &prev; -return page_cond_set_storage_key (large_crste_to_phys (*crstep, gfn), skey, oldkey, + +return page_cond_set_storage_key (large_crste_to_phys (crste, gfn), skey, oldkey, nq, mr, mc); }
@@ -766,7 +783,7 @@ int dat_reset_reference_bit(union asce asce, gfn_t gfn, union skey *skey)int rc; skey->skey =0 ; - +again: rc =dat_entry_walk (NULL , gfn, asce,DAT_WALK_ANY ,TABLE_TYPE_PAGE_TABLE , &crstep, &ptep);if (rc)return rc;
@@ -774,9 +791,12 @@ int dat_reset_reference_bit(union asce asce, gfn_t gfn, union skey *skey)if (!ptep) {union crste crste =READ_ONCE (*crstep); -if (!crste.h.fc || !crste.s.fc1.pr) +/* A large page has been split concurrently, try again */ +if (!crste_leaf (crste) && !crste.h.i) + goto again; +if (!crste.s.fc1.pr)return 0 ; - skey->skey =page_reset_referenced (large_crste_to_phys (*crstep, gfn)) <<1 ; + skey->skey =page_reset_referenced (large_crste_to_phys (crste, gfn)) <<1 ;return 0 ; } old =pgste_get_lock (ptep);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 12/457 KVM: s390: Fix race in _destroy_pages_crste()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudio Imbrenda <[email protected]>
[ Upstream commit 4ca00a9154f998116fba9a32cce5bd938d228065 ]
Use READ_ONCE() in _destroy_pages_crste() to read the crste, avoid dereferencing the pointer multiple times.
Message-ID: <[email protected]>
--- arch/s390/kvm/gmap.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
arch/s390/kvm/gmap.c +4 -2
@@ -991,11 +991,13 @@ static long _destroy_pages_pte(union pte *ptep, gfn_t gfn, gfn_t next, struct dastatic long _destroy_pages_crste (union crste *crstep,gfn_t gfn,gfn_t next,struct dat_walk *walk) {phys_addr_t origin, cur, end; +union crste crste; -if (!crstep->h.fc || !crstep->s.fc1.pr) + crste =READ_ONCE (*crstep); +if (!crste.h.fc || !crste.s.fc1.pr)return 0 ; - origin =crste_origin_large (*crstep); + origin =crste_origin_large (crste); cur = ((max (gfn, walk->start) - gfn) <<PAGE_SHIFT ) + origin; end = ((min (next, walk->end) - gfn) <<PAGE_SHIFT ) + origin;for ( ; cur < end; cur +=PAGE_SIZE )
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 13/457 s390/uv: Fix loop condition in uv_find_secrets
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steffen Eiden <[email protected]>
[ Upstream commit d12ce6bce5ec5175c3581e01c71e7a5abb286d9b ]
Systems with more than 85 UV secrets got -ENOENT for any secret past the first page.
Fix this by setting the start index at the beginning of the loop in uv_find_secret() and not at the end. First test if there are more secrets left by comparing start_idx with list->next_secret_idx, and then set the start index to the next secret index.
Message-ID: <[email protected]>
--- arch/s390/kernel/uv.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
arch/s390/kernel/uv.c +4 -2
@@ -781,11 +781,14 @@ int uv_find_secret(const u8 secret_id[UV_SECRET_ID_LEN],struct uv_secret_list *list, struct uv_secret_list_item_hdr *secret) { - u16 start_idx = 0; + u16 start_idx;u16 list_rc;int ret; + list->next_secret_idx =0 ; + do { + start_idx = list->next_secret_idx; uv_list_secrets(list, start_idx, &list_rc, NULL); if (list_rc != UVC_RC_EXECUTED && list_rc != UVC_RC_MORE_DATA) { if (list_rc == UVC_RC_INV_CMD)
@@ -796,7 +799,6 @@ int uv_find_secret(const u8 secret_id[UV_SECRET_ID_LEN], ret =find_secret_in_page (secret_id, list, secret);if (ret ==0 )return ret; - start_idx = list->next_secret_idx; }while (list_rc ==UVC_RC_MORE_DATA && start_idx < list->next_secret_idx);return -ENOENT ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 14/457 s390/uv: Prevent potential out-of-bounds read
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steffen Eiden <[email protected]>
[ Upstream commit f47190b08b71e8482072978373ee88cb2dfbdaf4 ]
When the system has more than 85 secrets, the uv_secret_list struct array only holds up to 85 items per page, resulting in an out of bounds read in find_secret_in_page if the targeted secret is in the next page or not stored at all.
Fix this by looping over the number of stored secrets which is the per sub-list count of stored secrets and not the overall count.
Message-ID: <[email protected]>
--- arch/s390/kernel/uv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/s390/kernel/uv.c +1 -1
@@ -760,7 +760,7 @@ static int find_secret_in_page(const u8 secret_id[UV_SECRET_ID_LEN], {u16 i; -for (i =0 ; i < list->total_num_secrets; i++) { +for (i =0 ; i < list->num_secr_stored; i++) {if (memcmp (secret_id, list->secrets[i].id,UV_SECRET_ID_LEN ) ==0 ) { *secret = list->secrets[i].hdr;return 0 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 15/457 bpf: Fix bpf_skb_change_tail wrt csum partial skbs
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Borkmann <[email protected]>
[ Upstream commit 3b55f350c68a0aceff108f47f9d31f47ebffaf7b ]
Cilium generates ICMP "frag needed" replies from BPF when a LB DSR packet exceeds the egress MTU. The reply is built by first trimming the packet down to target size via bpf_skb_change_tail(), and then pushing the ICMP error headers in front of it.
The trim is rejected for skbs which carry a checksum offload, e.g. TCP packets aggregated by GRO on ingress where tcp_gro_complete() leaves the skb as CHECKSUM_PARTIAL. __bpf_skb_min_len() raises the minimum length to the end of the L4 checksum field, so a trim to 42 bytes bails out with -EINVAL given a min_len of 52 in this case, and due to that the ICMP generator fails. This is not the case if GRO is turned off.
Fix this bpf_skb_change_tail() restriction and drop the checksum offload when the new length no longer covers the checksum field. The BPF program rewrites the skb into an ICMP error and computes the checksum itself anyway.
--- net/core/filter.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
net/core/filter.c +5 -6
@@ -3871,12 +3871,6 @@ static u32 __bpf_skb_min_len(const struct sk_buff *skb)if (offset >0 ) min_len = offset; } -if (skb->ip_summed ==CHECKSUM_PARTIAL ) { - offset =skb_checksum_start_offset (skb) + - skb->csum_offset +sizeof (__sum16); -if (offset >0 ) - min_len = offset; - }return min_len; }
@@ -3893,6 +3887,11 @@ static int bpf_skb_grow_rcsum(struct sk_buff *skb, unsigned int new_len)static int bpf_skb_trim_rcsum (struct sk_buff *skb,unsigned int new_len) { +if (skb->ip_summed ==CHECKSUM_PARTIAL && + new_len <skb_checksum_start_offset (skb) + skb->csum_offset + +sizeof (__sum16)) + skb->ip_summed =CHECKSUM_NONE ; +return __skb_trim_rcsum (skb, new_len); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 16/457 bpf: Disallow bpf_skb_pull_data() for LWT_SEG6LOCAL
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <[email protected]>
[ Upstream commit e4a62833adff6ef0fe7c0b90393204fe3c26b5c5 ]
An LWT_SEG6LOCAL program can invalidate its cached SRH with bpf_lwt_seg6_adjust_srh() and then call bpf_skb_pull_data(). The latter may reallocate skb->head, leaving the per-CPU SRH pointer dangling. Post-program SRH validation then writes through that pointer.
Disallow bpf_skb_pull_data() for LWT_SEG6LOCAL programs so the verifier rejects this unsafe helper combination. Other LWT program types continue to expose the helper through lwt_out_func_proto().
--- net/core/filter.c | 2 ++ 1 file changed, 2 insertions(+)
net/core/filter.c +2 -0
@@ -8881,6 +8881,8 @@ static const struct bpf_func_proto * lwt_seg6local_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) { switch (func_id) { + case BPF_FUNC_skb_pull_data: + return NULL;#if IS_ENABLED (CONFIG_IPV6_SEG6_BPF )case BPF_FUNC_lwt_seg6_store_bytes:return &bpf_lwt_seg6_store_bytes_proto;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 17/457 selftests/ftrace: Fix unique symbol check in kprobe_non_uniq_symbol.tc
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Schnelle <[email protected]>
[ Upstream commit d22c3e0088e85be8131f7a9283f759cdbb20726d ]
The current regex also matches symbols in modules, which makes the test fail on s390 where name_show is present only once in the kernel, but also multiple times in modules:
000001b1401cdc20 t name_show000001b0c05e6c40 t name_show [mdev]000001b0c0495f30 t name_show [i2c_core]
Fix this by changing the regular expression to only match the function name.
--- .../selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc +1 -1
@@ -6,7 +6,7 @@ SYMBOL='name_show' # We skip this test on kernel where SYMBOL is unique or does not exist. -if [ "$(grep -c -E "[[:alnum:]]+ t ${SYMBOL}" /proc/kallsyms)" -le '1' ]; then +if [ "$(grep -c -E "[[:alnum:]]+ t ${SYMBOL}$" /proc/kallsyms)" -le '1' ]; then exit_unsupported fi
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 18/457 bpf: Fix divide-by-zero in btf_struct_walk()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <[email protected]>
[ Upstream commit b0b3dc66529676228cb938cbcad66920f735c223 ]
When an access goes past the struct and the last member is a flexible array, btf_struct_walk() folds the offset back into a single element with (off - moff) % t->size, but never checks that the element type has a size.
BTF takes an empty struct, so this in program BTF
/* event could be empty */
struct event {
#ifdef HAVE_TIMESTAMP
__u64 ts;
#endif
};
struct batch {
int nr;
struct event events[];
};divides by zero at prog load time. Getting there needs a PTR_TO_BTF_ID that is not MEM_ALLOC, e.g. a plain read of a local kptr stashed in a map from a sleepable program.
Oops: divide error: 0000 [#1] SMP KASAN PTI RIP: 0010:btf_struct_walk+0x53f/0x1570 Call Trace: <TASK> btf_struct_access+0x42a/0xcd0 check_ptr_to_btf_access+0x4dc/0x1160 check_mem_access+0x3a45/0x8740 check_load_mem+0x36a/0xd10 do_check_common+0x3ef0/0xb210 bpf_check+0x6d3b/0x8580 bpf_prog_load+0xf7c/0x2720 __sys_bpf+0xa83/0x3690 __x64_sys_bpf+0xc7/0x150 x64_sys_call+0x1f3f/0x27e0 do_syscall_64+0xe5/0x610 entry_SYSCALL_64_after_hwframe+0x76/0x7e </TASK>
Reject a zero-sized element type. The fixed array path in the same function already bails out on the same thing:
btf_struct_walk() ... /* skip empty array */ if (moff == mtrue_end) continue; msize /= total_nelems;
--- kernel/bpf/btf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/bpf/btf.c +1 -1
@@ -7191,7 +7191,7 @@ static int btf_struct_walk(struct bpf_verifier_log *log, const struct btf *btf,if (btf_type_is_int (t))return WALK_SCALAR ; -if (!btf_type_is_struct (t)) +if (!btf_type_is_struct (t) || !t->size) goto error; off = (off - moff) % t->size;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 19/457 bpf: Fix out-of-bounds read of sk_protocol in bpf_sock_destroy()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <[email protected]>
[ Upstream commit 01b245ba016d44861690594e10f67e026ce8552f ]
sk_protocol lives in struct sock, not in struct sock_common. A timewait or request sock handed to bpf_sock_destroy() by the tcp iterator is neither, so reading sk->sk_protocol runs past the object:
==================================================================
BUG: KASAN: slab-out-of-bounds in bpf_sock_destroy+0xc7/0xe0 Read of size 2 at addr ffff8881047d11b4 by task test_progs/428 Tainted: [W]=WARN Call Trace: <TASK> dump_stack_lvl+0x91/0xf0 print_report+0xd1/0x630 kasan_report+0xf3/0x130 __asan_report_load2_noabort+0x14/0x30 bpf_sock_destroy+0xc7/0xe0 bpf_prog_c3dd61f9d9cd9f37_iter_tcp6_timewait+0x9f/0xb7 bpf_iter_run_prog+0x538/0xde0 bpf_iter_tcp_seq_show+0x26b/0x4b0 bpf_seq_read+0x424/0x1210 vfs_read+0x197/0xe40 ksys_read+0x119/0x240 __x64_sys_read+0x72/0xc0 x64_sys_call+0x647/0x27e0 do_syscall_64+0xe5/0x610 entry_SYSCALL_64_after_hwframe+0x76/0x7e
Only check sk_protocol on full socks. tcp_abort() already knows how to deal with TIME_WAIT and NEW_SYN_RECV socks. Also fix the comment, it never matched the code.
--- net/core/filter.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
net/core/filter.c +9 -4
@@ -12659,8 +12659,9 @@ __bpf_kfunc_start_defs();* @sock: Pointer to socket to be destroyed * * Return: -* On error, may return EPROTONOSUPPORT, EINVAL. -* EPROTONOSUPPORT if protocol specific destroy handler is not supported. +* On error, may return EOPNOTSUPP, or whatever the protocol specific +* destroy handler returns. +* EOPNOTSUPP if protocol specific destroy handler is not supported. * 0 otherwise */ __bpf_kfunc int bpf_sock_destroy(struct sock_common *sock)
@@ -12672,8 +12673,12 @@ __bpf_kfunc int bpf_sock_destroy(struct sock_common *sock)* Supporting protocols will need to acquire sock lock in the BPF context * prior to invoking this kfunc. */ -if (!sk->sk_prot->diag_destroy || (sk->sk_protocol !=IPPROTO_TCP && - sk->sk_protocol !=IPPROTO_UDP )) +if (!sk->sk_prot->diag_destroy) +return -EOPNOTSUPP ; + +if (sk_fullsock (sk) && + sk->sk_protocol !=IPPROTO_TCP && + sk->sk_protocol !=IPPROTO_UDP )return -EOPNOTSUPP ;return sk->sk_prot->diag_destroy (sk,ECONNABORTED );
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 20/457 tcp: Skip cond_resched() in inet_csk_listen_stop() under BPF context
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <[email protected]>
[ Upstream commit eaab8cab451b9502ce224cd202550375b894a467 ]
bpf_sock_destroy() runs from the tcp iterator, under rcu_read_lock(). If the sock is a listener that still has children in its accept queue, tcp_abort() ends up in inet_csk_listen_stop() and the cond_resched() there trips the debug check:
BUG: sleeping function called from invalid context at net/ipv4/inet_connection_sock.c:1523
in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 628, name: test_progspreempt_count: 0, expected: 0
RCU nest depth: 1, expected: 0
locks held by test_progs/628: 3, last CPU#3:
#0: ffff8881158cee18 (&p->lock){+.+.}-{4:4}, at: bpf_seq_read+0x56/0x1210 #1: ffff8881106bb858 (sk_lock-AF_INET6){+.+.}-{0:0}, at: bpf_iter_tcp_seq_show+0x32b/0x4b0 #2: ffffffffb435af20 (rcu_read_lock){....}-{1:3}, at: bpf_iter_run_prog+0x46b/0xde0
CPU: 3 UID: 0 PID: 628 Comm: test_progs Tainted: G W 7.2.0+ #65 PREEMPT Tainted: [W]=WARN Call Trace: <TASK> dump_stack_lvl+0xc1/0xf0 dump_stack+0x10/0x20 __might_resched+0x3d2/0x610 inet_csk_listen_stop+0x7b/0xbf0 tcp_abort+0x23b/0x3b0 bpf_sock_destroy+0xfc/0x140 bpf_prog_448133d24601754f_iter_tcp6_server+0x81/0x8a bpf_iter_run_prog+0x538/0xde0 bpf_iter_tcp_seq_show+0x26b/0x4b0 bpf_seq_read+0x424/0x1210 vfs_read+0x197/0xe40 ksys_read+0x119/0x240 __x64_sys_read+0x72/0xc0 x64_sys_call+0x647/0x27e0 do_syscall_64+0xe5/0x610 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7fad39b28aca RSP: 002b:00007ffc381c61c0 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 RAX: ffffffffffffffda RBX: 00007ffc381c6a88 RCX: 00007fad39b28aca RDX: 0000000000000032 RSI: 00007ffc381c6250 RDI: 0000000000000014 RBP: 00007ffc381c61e0 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000003 R13: 0000000000000000 R14: 000055f077c1bbb0 R15: 00007fad3a0f3000 </TASK>
The commit that added the kfunc already guards lock_sock() in tcp_abort() and udp_abort() with has_current_bpf_ctx(), but missed the listener path. Do the same for the cond_resched(). The loop runs inside the iterator's rcu_read_lock(), it must not reschedule or report a quiescent state there.
--- net/ipv4/inet_connection_sock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/ipv4/inet_connection_sock.c +2 -1
@@ -1520,7 +1520,8 @@ void inet_csk_listen_stop(struct sock *sk)local_bh_enable ();sock_put (child); -cond_resched (); +if (!has_current_bpf_ctx ()) +cond_resched (); }if (queue->fastopenq.rskq_rst_head) {/* Free all the reqs queued in rskq_rst_head. */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 21/457 HID: multitouch: Add report ID mismatch quirk for ASUS ROG Z13 Folio
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lovekesh Solanki <[email protected]>
[ Upstream commit aaaea79efba5a27cb9e0a5a628046d829d3f2cbb ]
Commit e716edafedad ("HID: multitouch: Check to ensure report responses match the request") introduced validating GET_FEATURE responses return the requested report ID.
ASUS ROG Z13 Flow (2025) GZ302EA touchpad (USB 0b05:1a30) returns a different report ID for Win8 feature request. Before this check, the response was still processed and allowed device to switch into its full Touchpad Precision mode.
After the validation, the response is discarded before hid_report_raw_event() processes it and device remains in fallback mode and no longer exposes ABS_MT_SLOT, ABS_MT_TOOL_TYPE or the multi-finger BTN_TOOL_* capabilities for palm rejection.
Add a device quirk to allow the known firmware behavior for this device while preserving report ID validation for all other devices.
The device previously matched the generic MT_CLS_WIN_8 entry, so base the new class on MT_CLS_WIN_8 to keep it on the same quirk set as before the regression. MT_QUIRK_CONFIDENCE must be set
explicitly: it is normally enabled by the class name check in mt_touch_input_mapping(), which only matches the MT_CLS_WIN_8* names, and it is what makes ABS_MT_TOOL_TYPE available for touchpads.
--- drivers/hid/hid-multitouch.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-)
drivers/hid/hid-multitouch.c +27 -2
@@ -79,6 +79,7 @@ MODULE_LICENSE("GPL");#define MT_QUIRK_APPLE_TOUCHBAR BIT(23)#define MT_QUIRK_YOGABOOK9I BIT(24)#define MT_QUIRK_KEEP_LATENCY_ON_CLOSE BIT(25) +#define MT_QUIRK_IGNORE_FEATURE_ID_MISMATCH BIT(26)#define MT_INPUTMODE_TOUCHSCREEN 0x02#define MT_INPUTMODE_TOUCHPAD 0x03
@@ -235,6 +236,7 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app);#define MT_CLS_APPLE_TOUCHBAR 0x0114#define MT_CLS_YOGABOOK9I 0x0115#define MT_CLS_EGALAX_P80H84 0x0116 +#define MT_CLS_ASUS_ROG_Z13_FOLIO 0x0117#define MT_CLS_SIS 0x0457#define MT_DEFAULT_MAXCONTACT 10
@@ -405,6 +407,16 @@ static const struct mt_class mt_classes[] = { .quirks = MT_QUIRK_ALWAYS_VALID |MT_QUIRK_CONTACT_CNT_ACCURATE | MT_QUIRK_ASUS_CUSTOM_UP }, + { .name = MT_CLS_ASUS_ROG_Z13_FOLIO, + .quirks =MT_QUIRK_ALWAYS_VALID | +MT_QUIRK_IGNORE_DUPLICATES | +MT_QUIRK_HOVERING | +MT_QUIRK_CONTACT_CNT_ACCURATE | +MT_QUIRK_STICKY_FINGERS | +MT_QUIRK_WIN8_PTP_BUTTONS | +MT_QUIRK_CONFIDENCE | + MT_QUIRK_IGNORE_FEATURE_ID_MISMATCH, + .export_all_inputs = true }, { .name = MT_CLS_VTL, .quirks =MT_QUIRK_ALWAYS_VALID | MT_QUIRK_CONTACT_CNT_ACCURATE |
@@ -507,6 +519,7 @@ static const struct attribute_group mt_attribute_group = {static void mt_get_feature (struct hid_device *hdev,struct hid_report *report) { +struct mt_device *td =hid_get_drvdata (hdev);int ret;u32 size =hid_report_len (report);u8 *buf;
@@ -528,8 +541,14 @@ static void mt_get_feature(struct hid_device *hdev, struct hid_report *report)dev_warn (&hdev->dev,"failed to fetch feature %d\n" , report->id); }else { -/* The report ID in the request and the response should match */ -if (report->id != buf[0 ]) { +/* +* The report ID in the request and the response should match. +* Some firmware (e.g. the ASUS ROG Z13 Folio +* touchpad) returns a mismatched ID on this specific fetch; +* tolerate it only for devices explicitly flagged as such. +*/ +if (report->id != buf[0 ] && + !(td->mtclass.quirks &MT_QUIRK_IGNORE_FEATURE_ID_MISMATCH )) {hid_err (hdev,"Returned feature report did not match the request\n" ); goto free; }
@@ -2726,6 +2745,12 @@ static const struct hid_device_id mt_devices[] = { HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288) }, +/* Asus ROG Flow Z13 (2025) GZ302EA keyboard-cover touchpad */ + { .driver_data = MT_CLS_ASUS_ROG_Z13_FOLIO, +HID_DEVICE (BUS_USB ,HID_GROUP_MULTITOUCH_WIN_8 , +USB_VENDOR_ID_ASUSTEK , + USB_DEVICE_ID_ASUSTEK_ROG_Z13_FOLIO) }, +/* Generic MT device */ { HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH, HID_ANY_ID, HID_ANY_ID) },
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 22/457 HID: winwing: fix use-after-free in force feedback teardown
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: René Onier <[email protected]>
[ Upstream commit a1a5ad37e50ceb192c07ac7e2d7143638cd4d110 ]
winwing_init_ff() passes the driver's private data, allocated with devm_kzalloc() in winwing_probe(), as the effect context to input_ff_create_memless(). The memoryless force-feedback core takes ownership of that pointer and frees it with kfree() from input_ff_destroy() (ml_ff_destroy()) when the input device is destroyed.
Freeing a devm-managed allocation with kfree() is an invalid free, and the same object is then released again by devres when the HID device is torn down, a double free. As the allocation also embeds the LED class devices, their timers and work item live on freed memory and the slab gets corrupted. This triggers on unbind, rmmod, hot-unplug and on system suspend, where the firmware cache walks the now-corrupt devres list. KASAN reports:
BUG: KASAN: invalid-free in input_ff_destroy
Allocated by task N:
winwing_probePass NULL as the memless context instead and fetch the driver data from the input device in winwing_play_effect(): the HID core already stores the hid_device as the input device's drvdata. The force-feedback core then owns nothing that it must not free.
--- drivers/hid/hid-winwing.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/hid/hid-winwing.c +8 -2
@@ -315,7 +315,8 @@ static void winwing_haptic_rumble_cb(struct work_struct *work)static int winwing_play_effect (struct input_dev *dev,void *context,struct ff_effect *effect) { -struct winwing_drv_data *data = (struct winwing_drv_data *) context; +struct hid_device *hdev =input_get_drvdata (dev); +struct winwing_drv_data *data =hid_get_drvdata (hdev);if (effect->type !=FF_RUMBLE )return 0 ;
@@ -342,7 +343,12 @@ static int winwing_init_ff(struct hid_device *hdev, struct hid_input *hidinput)input_set_capability (hidinput->input,EV_FF ,FF_RUMBLE ); -return input_ff_create_memless (hidinput->input, data, +/* +* input_ff_create_memless() takes ownership of the context pointer +* and frees it on teardown; do not hand it the devm-managed drvdata. +* winwing_play_effect() fetches it from the input device instead. +*/ +return input_ff_create_memless (hidinput->input,NULL , winwing_play_effect); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 23/457 HID: elecom: fix bus type for M-XGL20DLBK
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oscar Priego Verdugo <[email protected]>
[ Upstream commit 8e2a4b458ad25e13422bb059758c30a6562aa9cf ]
The M-XGL20DLBK is matched as a USB device by hid-elecom, but its entry in hid_have_special_driver[] uses HID_BLUETOOTH_DEVICE.
This prevents the special-driver quirk entry from matching the USB device handled by hid-elecom. Use HID_USB_DEVICE there as well.
--- drivers/hid/hid-quirks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hid/hid-quirks.c +1 -1
@@ -422,7 +422,7 @@ static const struct hid_device_id hid_have_special_driver[] = {#endif #if IS_ENABLED(CONFIG_HID_ELECOM) { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XGL20DLBK) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XGL20DLBK) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1MRBK_01AC) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_018F) },
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 24/457 KVM: x86/pmu: Move Intel PMU global MSRs to intel_is_valid_msr()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jim Mattson <[email protected]>
[ Upstream commit 79a71cc2568f4b5d42284da2aa26f3b4f47ce01b ]
Commit c85cdc1cc1ea ("KVM: x86/pmu: Move handling PERF_GLOBAL_CTRL and friends to common x86") moved the existence check for the following Intel PMU MSRs to kvm_pmu_is_valid_msr():
- MSR_CORE_PERF_GLOBAL_STATUS
- MSR_CORE_PERF_GLOBAL_CTRL
- MSR_CORE_PERF_GLOBAL_OVF_CTRL
That commit deemed these MSRs valid whenever pmu->version > 1. It intended to share the check with AMD PerfMonV2 because both vendor implementations require version 2 or greater for global PMU controls. However, as noted in the commit message, AMD uses different MSR indices for its global PMU registers.
Commit 4a2771895ca6 ("KVM: x86/svm/pmu: Add AMD PerfMonV2 support") subsequently added AMD PerfMonV2 support and set pmu->version = 2. Because kvm_pmu_is_valid_msr() validated the Intel MSRs whenever pmu->version > 1, KVM incorrectly permitted AMD guests with PerfMonV2 to access these Intel MSRs without a #GP.
Move the validation of these Intel MSRs to intel_is_valid_msr() and remove the common switch statement from kvm_pmu_is_valid_msr(). AMD already validates its own global PMU MSRs in amd_is_valid_msr().
--- arch/x86/kvm/pmu.c | 8 -------- arch/x86/kvm/vmx/pmu_intel.c | 3 +++ 2 files changed, 3 insertions(+), 8 deletions(-)
arch/x86/kvm/pmu.c +0 -8
@@ -812,14 +812,6 @@ void kvm_pmu_deliver_pmi(struct kvm_vcpu *vcpu)bool kvm_pmu_is_valid_msr (struct kvm_vcpu *vcpu,u32 msr) { -switch (msr) { -case MSR_CORE_PERF_GLOBAL_STATUS : -case MSR_CORE_PERF_GLOBAL_CTRL : -case MSR_CORE_PERF_GLOBAL_OVF_CTRL : -return kvm_pmu_has_perf_global_ctrl (vcpu_to_pmu (vcpu)); -default : -break ; - }return kvm_pmu_call (msr_idx_to_pmc)(vcpu, msr) ||kvm_pmu_call (is_valid_msr)(vcpu, msr); }
arch/x86/kvm/vmx/pmu_intel.c +3 -0
@@ -187,6 +187,9 @@ static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr)int ret;switch (msr) { +case MSR_CORE_PERF_GLOBAL_STATUS : +case MSR_CORE_PERF_GLOBAL_CTRL : +case MSR_CORE_PERF_GLOBAL_OVF_CTRL :case MSR_CORE_PERF_FIXED_CTR_CTRL :return kvm_pmu_has_perf_global_ctrl (pmu);case MSR_IA32_PEBS_ENABLE :
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 25/457 bpf: Allow terminal gotox instructions
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Siddharth Chintamaneni <[email protected]>
[ Upstream commit 0d7823cd4cda35f2060a685fa276ff7709915abc ]
check_subprogs() treats gotox as a direct jump and validates its reserved zero offset. When gotox is the final instruction, this produces a synthetic successor one instruction past the end of the subprogram and rejects an otherwise valid program.
Skip direct-offset validation for gotox and accept it as a non-fallthrough terminal instruction. Its actual targets remain validated from the instruction-array jump table during CFG construction.
--- kernel/bpf/verifier.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
kernel/bpf/verifier.c +4 -1
@@ -2876,6 +2876,8 @@ static int check_subprogs(struct bpf_verifier_env *env) subprog[cur_subprog].exit_idx = i; goto next; } +if (insn_is_gotox (&insn[i])) + goto next; off = i +bpf_jmp_offset (&insn[i]) +1 ;if (off < subprog_start || off >= subprog_end) {verbose (env,"jump out of range from insn %d to %d\n" , i, off);
@@ -2889,7 +2891,8 @@ static int check_subprogs(struct bpf_verifier_env *env)*/ if (code != (BPF_JMP |BPF_EXIT ) && code != (BPF_JMP32 |BPF_JA ) && - code != (BPF_JMP |BPF_JA )) { + code != (BPF_JMP |BPF_JA ) && + !insn_is_gotox (&insn[i])) {verbose (env,"last insn is not an exit or jmp\n" );return -EINVAL ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 26/457 bpf: Avoid soft lockup in __htab_map_lookup_and_delete_batch()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jose Fernandez (Anthropic) <[email protected]>
[ Upstream commit 85136bf22404474a815fc0ed26ec0d1cbc1bc3f9 ]
__htab_map_lookup_and_delete_batch() has no rescheduling point. The batch count bounds how many entries are copied out, not how many buckets are visited, so one BPF_MAP_LOOKUP_BATCH call can walk the map end to end. The empty-bucket fast path is worse: it stays inside a single rcu_read_lock() / bpf_disable_instrumentation() section for any run of consecutive empty buckets.
That holds up on small maps, but it falls apart at scale. On a 144-CPU arm64 host running a CONFIG_PREEMPT_NONE kernel, periodic BPF_MAP_LOOKUP_BATCH calls against an LRU hash map with 16,777,216 buckets held a CPU inside the batch op for 77+ seconds and triggered the soft lockup watchdog.
Commit 75134f16e7dd ("bpf: Add schedule points in batch ops") fixed this same problem in the generic batch ops, but not in this htab-native path, which every htab-based hash map variant uses for its lookup[_and_delete] batch ops.
Complete that fix here. Leave the critical section after 64 consecutive empty buckets, call cond_resched_tasks_rcu_qs(), and resume at the saved bucket cursor. No locks are held at that point, and resuming from the cursor is already the function's behavior for non-empty buckets. Add the same call to the per-bucket loop after copy_to_user(), where every lock has been dropped. cond_resched_rcu() is not enough here: sleeping with bpf_prog_active elevated makes tracing programs on that CPU silently skip their invocations.
Plain cond_resched() is not enough either. It is a no-op under PREEMPT and PREEMPT_LAZY, the only models arm64 and x86 have offered since commit 7dadeaa6e851 ("sched: Further restrict the preemption modes"). It is also never a Tasks RCU quiescent state, in any model: the reschedule counts as a preemption. The walking task stays a holdout and stalls every synchronize_rcu_tasks() caller, ftrace and BPF trampoline teardown included, until the syscall returns [1]. cond_resched_tasks_rcu_qs() is the usual tool for that [2]. It reports the quiescent state at each yield and still reschedules as cond_resched() does on PREEMPT_NONE and PREEMPT_VOLUNTARY kernels.
--- kernel/bpf/hashtab.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-)
kernel/bpf/hashtab.c +21 -3
@@ -1773,6 +1773,12 @@ static int htab_lru_percpu_map_lookup_and_delete_elem(struct bpf_map *map, flags); } +/* +* Max consecutive empty buckets to walk in one RCU + +* instrumentation-disabled section before rescheduling. +*/ +#define HTAB_BATCH_EMPTY_RESCHED 64 + static int __htab_map_lookup_and_delete_batch(struct bpf_map *map, const union bpf_attr *attr,
@@ -1794,6 +1800,7 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map,unsigned long flags =0 ;bool locked = false;struct htab_elem *l; +u32 empty_cnt =0 ;struct bucket *b;int ret =0 ;
@@ -1972,12 +1979,21 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map, } next_batch: -/* If we are not copying data, we can go to next bucket and avoid -* unlocking the rcu. +/* +* If we are not copying data, we can go to next bucket and avoid +* unlocking the rcu. Bound the walk though: after +* HTAB_BATCH_EMPTY_RESCHED consecutive empty buckets, fully exit +* the critical section (no locks are held here) and reschedule. */ if (!bucket_cnt && (batch +1 < htab->n_buckets)) { batch++; - goto again_nocopy; +if (++empty_cnt <HTAB_BATCH_EMPTY_RESCHED ) + goto again_nocopy; + empty_cnt =0 ; +rcu_read_unlock (); +bpf_enable_instrumentation (); +cond_resched_tasks_rcu_qs (); + goto again; }rcu_read_unlock ();
@@ -1991,11 +2007,13 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map, } total += bucket_cnt; + empty_cnt =0 ; batch++;if (batch >= htab->n_buckets) { ret = -ENOENT ; goto after_loop; } +cond_resched_tasks_rcu_qs (); goto again; after_loop:
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 27/457 bpf: Fix out-of-bounds read of rtt_min in sock_ops
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <[email protected]>
[ Upstream commit 75f8cf22463d82bb1fb0239a3d485fc8f4c8ef03 ]
A sockops prog reading skops->rtt_min never checks the sk type: on the tcp_conn_request() path sock_ops->sk is a request_sock (non-full), and the ctx rewrite casts it to a tcp_sock (full) and reads rtt_min past the end of the request_sock, returning dirty adjacent memory.
SEC("sockops")
int prog(struct bpf_sock_ops *skops)
{
switch (skops->op) {
case BPF_SOCK_OPS_RWND_INIT:
leak = skops->rtt_min; /* reads the request_sock OOB */
...
}
}For instance one such read returned rtt_min=0xffff8881, the high half of a leaked kernel pointer.
Guarding that cast is exactly what SOCK_OPS_GET_FIELD() does -- it checks is_locked_tcp_sock and returns 0 when sock_ops->sk is not a locked full socket. Every other tcp_sock field in sock_ops goes through it; rtt_min is the only one open-coded, so it skips the check.
Read rtt_min through SOCK_OPS_GET_FIELD() too. rtt_min is a bit special:
it is a struct minmax and we only want the current min, so pass rtt_min.s[0].v. That is equivalent to the old hand-computed offset
offsetof(struct tcp_sock, rtt_min) + sizeof_field(struct minmax_sample, t)
(s[0] sits at rtt_min + 0 and .v at + sizeof(.t), i.e. what minmax_get() returns), so the loaded field is unchanged and only the full-sock guard is added. The two BUILD_BUG_ON()s that protected the hand-computed offset are no longer needed.
Before patch:
0: r1 = *(u64 *)(r1 +0) ; r1 = skops->sk 1: r1 = *(u32 *)(r1 +2324) ; ((tcp_sock *)sk)->rtt_min.s[0].v
After patch:
0: *(u64 *)(r1 +56) = r9 1: r9 = *(u8 *)(r1 +50) ; is_locked_tcp_sock 2: if r9 == 0 goto pc+4 ; not a locked full sock -> 0 3: r9 = *(u64 *)(r1 +56) 4: r1 = *(u64 *)(r1 +0) ; r1 = skops->sk 5: r1 = *(u32 *)(r1 +2324) ; rtt_min.s[0].v 6: goto pc+2 7: r9 = *(u64 *)(r1 +56) 8: r1 = 0
--- net/core/filter.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-)
net/core/filter.c +1 -12
@@ -10943,18 +10943,7 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,break ;case offsetof(struct bpf_sock_ops , rtt_min): - BUILD_BUG_ON(sizeof_field(struct tcp_sock, rtt_min) != - sizeof(struct minmax)); -BUILD_BUG_ON (sizeof (struct minmax ) < -sizeof (struct minmax_sample )); - - *insn++ =BPF_LDX_MEM (BPF_FIELD_SIZEOF ( - struct bpf_sock_ops_kern, sk), - si->dst_reg, si->src_reg, - offsetof(struct bpf_sock_ops_kern , sk)); - *insn++ =BPF_LDX_MEM (BPF_W , si->dst_reg, si->dst_reg, - offsetof(struct tcp_sock , rtt_min) + - sizeof_field(struct minmax_sample, t)); + SOCK_OPS_GET_FIELD(rtt_min, rtt_min.s[0].v, struct tcp_sock);break ;case offsetof(struct bpf_sock_ops , bpf_sock_ops_cb_flags):
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 28/457 bpf: Fix UAF due to concurrent consumption of ttrace lists in alloc_bulk
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pu Lehui <[email protected]>
[ Upstream commit 1c21452d02eec2f008e2c5535820f85adbd7587a ]
Syzkaller repeatedly triggered UAF splats related to nodes in waiting_for_gp_ttrace within the bpf memalloc:
BUG: KASAN: slab-use-after-free in llist_del_first+0x85/0x110 lib/llist.c:61 Read of size 8 at addr ffff8881572cd080 by task syz.4.470/5112 ... llist_del_first+0x85/0x110 lib/llist.c:61 alloc_bulk+0x193/0x460 kernel/bpf/memalloc.c:229 bpf_mem_refill+0x386/0x560 kernel/bpf/memalloc.c:436 Freed by task 14: ... __free_rcu kernel/bpf/memalloc.c:281 [inline] __free_rcu_tasks_trace+0x48/0xd0 kernel/bpf/memalloc.c:291 rcu_tasks_invoke_cbs+0x1ec/0x3e0 kernel/rcu/tasks.h:571 rcu_tasks_one_gp+0x13d/0x220 kernel/rcu/tasks.h:621 rcu_tasks_kthread+0xf3/0x120 kernel/rcu/tasks.h:651
The reason is that the UAF occurs after the RCU Tasks Trace GP expires:
when the __free_rcu() callback runs, there is no synchronization protecting llist_del_all() against concurrent alloc_bulk() operating on waiting_for_gp_ttrace, leading to the race condition below:
CPU0 CPU1
__free_rcu (RCU Tasks Trace callback)alloc_bulk
llist_del_first(&c->waiting_for_gp_ttrace)
entry = smp_load_acquire(&head->first);
do {
if (entry == NULL)
return NULL;
free_all(llist_del_all(&c->waiting_for_gp_ttrace))
llist_for_each_safe(pos, t, llnode)
free_one(pos);
next = READ_ONCE(entry->next); <-- trigger UAF
} while (!try_cmpxchg(&head->first, &entry, next));In addition, there is also a theoretical race condition on the free_by_rcu_ttrace list. This race requires two preconditions: an in-flight Tasks Trace GP keeping c->call_rcu_ttrace_in_progress == 1, and concurrent cross-CPU frees repopulating c->free_by_rcu_ttrace with new nodes. Under these conditions, the following scenario triggers UAF:
// CPU0
// irq work is still busy (on PREEMPT_RT)alloc_bulk()
llist_del_first(&c->free_by_rcu_ttrace)
entry = smp_load_acquire(&head->first);
do {
if (entry == NULL)
return NULL;
// CPU1
bpf_mem_alloc_destroy()
WRITE_ONCE(c->draining, true)
// wait for CPU0
irq_work_sync()
// CPU2
do_call_rcu_ttrace(tgt(CPU0))
if (c->draining) {
llist_del_all(&c->free_by_rcu_ttrace)
free_all()
}// CPU0 continue
next = READ_ONCE(entry->next); <-- trigger UAF
while (!try_cmpxchg(&head->first, &entry, next));Fix this by introducing a raw spinlock to synchronize the concurrent consumption on waiting_for_gp_ttrace and free_by_rcu_ttrace.
--- kernel/bpf/memalloc.c | 50 ++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 22 deletions(-)
kernel/bpf/memalloc.c +28 -22
@@ -119,6 +119,7 @@ struct bpf_mem_cache {struct llist_head waiting_for_gp_ttrace;struct rcu_head rcu_ttrace;atomic_t call_rcu_ttrace_in_progress; +raw_spinlock_t lock; };struct bpf_mem_caches {
@@ -214,25 +215,24 @@ static void alloc_bulk(struct bpf_mem_cache *c, int cnt, int node, bool atomic) gfp = __GFP_NOWARN | __GFP_ACCOUNT; gfp |= atomic ?GFP_NOWAIT :GFP_KERNEL ; -for (i =0 ; i < cnt; i++) { -/* -* For every 'c' llist_del_first(&c->free_by_rcu_ttrace); is -* done only by one CPU == current CPU. Other CPUs might -* llist_add() and llist_del_all() in parallel. -*/ - obj =llist_del_first (&c->free_by_rcu_ttrace); -if (!obj) -break ; -add_obj_to_free_list (c, obj); - } -if (i >= cnt) -return ; +/* +* c->lock serializes concurrent llist_del_first() against +* llist_del_all() in __free_rcu() and do_call_rcu_ttrace(). +*/ + scoped_guard(raw_spinlock_irqsave, &c->lock) { +for (i =0 ; i < cnt; i++) { + obj =llist_del_first (&c->free_by_rcu_ttrace); +if (!obj) +break ; +add_obj_to_free_list (c, obj); + } -for (; i < cnt; i++) { - obj =llist_del_first (&c->waiting_for_gp_ttrace); -if (!obj) -break ; -add_obj_to_free_list (c, obj); +for (; i < cnt; i++) { + obj =llist_del_first (&c->waiting_for_gp_ttrace); +if (!obj) +break ; +add_obj_to_free_list (c, obj); + } }if (i >= cnt)return ;
@@ -279,8 +279,12 @@ static int free_all(struct bpf_mem_cache *c, struct llist_node *llnode, bool perstatic void __free_rcu (struct rcu_head *head) { struct bpf_mem_cache *c = container_of(head, struct bpf_mem_cache, rcu_ttrace); +struct llist_node *llnode; + +scoped_guard (raw_spinlock_irqsave, &c->lock) + llnode = llist_del_all(&c->waiting_for_gp_ttrace); -free_all (c,llist_del_all (&c->waiting_for_gp_ttrace), !!c->percpu_size); +free_all (c, llnode, !!c->percpu_size);atomic_set (&c->call_rcu_ttrace_in_progress,0 ); }
@@ -300,7 +304,8 @@ static void do_call_rcu_ttrace(struct bpf_mem_cache *c)if (atomic_xchg (&c->call_rcu_ttrace_in_progress,1 )) {if (unlikely (READ_ONCE (c->draining))) { - llnode =llist_del_all (&c->free_by_rcu_ttrace); +scoped_guard (raw_spinlock_irqsave, &c->lock) + llnode = llist_del_all(&c->free_by_rcu_ttrace);free_all (c, llnode, !!c->percpu_size); }return ;
@@ -535,6 +540,7 @@ int bpf_mem_alloc_init(struct bpf_mem_alloc *ma, int size, bool percpu) c->objcg = objcg; c->percpu_size = percpu_size; c->tgt = c; +raw_spin_lock_init (&c->lock);init_refill_work (c);prefill_mem_cache (c, cpu); }
@@ -557,7 +563,7 @@ int bpf_mem_alloc_init(struct bpf_mem_alloc *ma, int size, bool percpu) c->objcg = objcg; c->percpu_size = percpu_size; c->tgt = c; - +raw_spin_lock_init (&c->lock);init_refill_work (c);prefill_mem_cache (c, cpu); }
@@ -609,7 +615,7 @@ int bpf_mem_alloc_percpu_unit_init(struct bpf_mem_alloc *ma, int size) c->objcg = objcg; c->percpu_size = percpu_size; c->tgt = c; - +raw_spin_lock_init (&c->lock);init_refill_work (c);prefill_mem_cache (c, cpu); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 29/457 bpf, sockmap: Fix self-redirect copied_seq double-counting
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geliang Tang <[email protected]>
[ Upstream commit 490a83d6386eec1d29f470c8d7331677fb46c3b7 ]
When a BPF stream_verdict program redirects an skb back to the same socket (self-redirect with BPF_F_INGRESS), sk_psock_verdict_apply() calls tcp_eat_skb() which advances tcp_sk->copied_seq. However, the skb is then delivered to the socket's psock ingress queue and later read by tcp_bpf_recvmsg_parser(), which also advances copied_seq via the copied_from_self accounting path. This double-counting causes copied_seq to advance by 2x the actual data length, triggering:
TCP recvmsg seq # bug 2: copied BF2E806, seq BF2E7FD, \ rcvnxt BF2E806, fl 0 WARNING: net/ipv4/tcp.c:2745 at tcp_recvmsg_locked+0x72b/0x2640 Call Trace: tcp_recvmsg+0x10a/0x500 sock_recvmsg+0x168/0x1d0 __sys_recvfrom+0x19a/0x2a0 __x64_sys_recvfrom+0xe4/0x1f0 do_syscall_64+0xf7/0x530 entry_SYSCALL_64_after_hwframe+0x77/0x7f
cleanup rbuf bug: copied BF2E806 seq BF2E806 rcvnxt BF2E806
WARNING: net/ipv4/tcp.c:1609 at tcp_cleanup_rbuf+0xf2/0x1c0 Call Trace: tcp_recvmsg_locked+0x8d1/0x2640 tcp_recvmsg+0x10a/0x500 sock_recvmsg+0x168/0x1d0 __sys_recvfrom+0x19a/0x2a0 __x64_sys_recvfrom+0xe4/0x1f0 do_syscall_64+0xf7/0x530 entry_SYSCALL_64_after_hwframe+0x77/0x7f
Fix this by converting self-redirect verdict to __SK_PASS at the beginning of sk_psock_verdict_apply(). This bypasses the __SK_REDIRECT case entirely (which calls sk_psock_eat_skb), letting the __SK_PASS path queue the skb to the psock ingress queue. The data is then read via tcp_bpf_recvmsg_parser(), which advances copied_seq exactly once through copied_from_self. Cross-socket redirects continue through __SK_REDIRECT with sk_psock_eat_skb() unchanged.
--- net/core/skmsg.c | 4 ++++ 1 file changed, 4 insertions(+)
net/core/skmsg.c +4 -0
@@ -1000,6 +1000,10 @@ static int sk_psock_verdict_apply(struct sk_psock *psock, struct sk_buff *skb,int err =0 ;u32 len, off; +if (verdict == __SK_REDIRECT &&skb_bpf_ingress (skb) && +skb_bpf_redirect_fetch (skb) == psock->sk) + verdict = __SK_PASS; +switch (verdict) {case __SK_PASS: err = -EIO ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 30/457 bpf: Fix u32 overflow issue in map batch operations
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masoud Aghasi <[email protected]>
[ Upstream commit 953824e508b27d12837e32ef37ef6248e1f6fc7a ]
Several map batch operation implementations such as generic_map_lookup_batch() use calculations in the form of "values + cp * map->value_size" to compute the desired userspace memory address for reading or writing. This can overflow the u32 type (the result of "cp * map->value_size") when the map size exceeds 4GB.
generic_map_lookup_batch() may corrupt values for some keys in userspace memory, and in some cases it mismatches values for some keys while still reporting success.
Other batch operations may fail to delete or update some keys, or the syscall may return unexpected errors.
Add size_t casts to prevent the affected offset and size calculations from overflowing.
--- kernel/bpf/hashtab.c | 8 ++++---- kernel/bpf/syscall.c | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-)
kernel/bpf/hashtab.c +4 -4
@@ -1998,10 +1998,10 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map,rcu_read_unlock ();bpf_enable_instrumentation (); -if (bucket_cnt && (copy_to_user (ukeys + total * key_size, keys, - key_size * bucket_cnt) || -copy_to_user (uvalues + total * value_size, values, - value_size * bucket_cnt))) { +if (bucket_cnt && (copy_to_user (ukeys + (size_t )total * key_size, keys, + (size_t )key_size * bucket_cnt) || +copy_to_user (uvalues + (size_t )total * value_size, values, + (size_t )value_size * bucket_cnt))) { ret = -EFAULT ; goto after_loop; }
kernel/bpf/syscall.c +5 -5
@@ -2033,7 +2033,7 @@ int generic_map_delete_batch(struct bpf_map *map,for (cp =0 ; cp < max_count; cp++) { err = -EFAULT ; -if (copy_from_user (key, keys + cp * map->key_size, +if (copy_from_user (key, keys + (size_t )cp * map->key_size, map->key_size))break ;
@@ -2095,9 +2095,9 @@ int generic_map_update_batch(struct bpf_map *map, struct file *map_file,for (cp =0 ; cp < max_count; cp++) { err = -EFAULT ; -if (copy_from_user (key, keys + cp * map->key_size, +if (copy_from_user (key, keys + (size_t )cp * map->key_size, map->key_size) || -copy_from_user (value, values + cp * value_size, value_size)) +copy_from_user (value, values + (size_t )cp * value_size, value_size))break ; err = bpf_map_update_value(map, map_file, key, value,
@@ -2176,12 +2176,12 @@ int generic_map_lookup_batch(struct bpf_map *map,if (err) goto free_buf; -if (copy_to_user (keys + cp * map->key_size, key, +if (copy_to_user (keys + (size_t )cp * map->key_size, key, map->key_size)) { err = -EFAULT ; goto free_buf; } -if (copy_to_user (values + cp * value_size, value, value_size)) { +if (copy_to_user (values + (size_t )cp * value_size, value, value_size)) { err = -EFAULT ; goto free_buf; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 31/457 bpf, arm64: set up the frame pointer for the exception callback
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donggeun Yoo <[email protected]>
[ Upstream commit ef1fb82f12186dd26153b14d9fbcf4ec98db81b3 ]
A program acting as exception boundary saves all callee-saved registers, so build_prologue() takes the exception_cb path and never calls push_callee_regs(). That is the only place find_used_callee_regs() runs, and with it the only place ctx->fp_used is set, so the callback prologue does not emit the
mov x25, sp
that points BPF_REG_FP at the frame the callback runs on. x25 keeps whatever it held when bpf_throw() was called. If the throw came from a subprogram that uses its own BPF stack, that is the subprogram's frame pointer, and since the subprogram never returns it never restores x25 either.
Stack accesses through BPF_REG_FP are rewritten to be stack pointer relative, so those still land in the callback's own frame. Materializing the register does not: a callback that passes the address of a local variable to a helper hands over an address in the dead subprogram's frame. That address is below the callback's stack pointer by then, and the helper's own call chain covers it, so the helper can write over its own return address. 0x1234 below is the value the helper was asked to store:
pc : 0x1234 lr : 0x1234 Call trace: 0x1234 (P) bpf_test_run+0x188/0x3e0 bpf_prog_test_run_skb+0x47c/0x998 __sys_bpf+0xbdc/0xdd8 Kernel panic - not syncing: Oops: Fatal exception in interrupt
Set ctx->fp_used on the exception callback path so that the existing code further down sets x25 from the stack pointer. The epilogue restores it from the main program's save area along with the other callee-saved registers, as it already does. x86 sets the frame pointer for the callback from the argument it is passed, and powerpc computes it from the stack pointer.
--- arch/arm64/net/bpf_jit_comp.c | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/net/bpf_jit_comp.c +2 -0
@@ -600,6 +600,8 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)* 12 registers are on the stack */ emit (A64_SUB_I (1 ,A64_SP ,A64_FP ,96 ), ctx); +/* The callback may use its own BPF stack, set up fp for it. */ + ctx->fp_used = true; }/* Stack must be multiples of 16B */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 32/457 pinctrl: meson: Fix typo in s4 group name
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Anderson <[email protected]>
[ Upstream commit 692f32609a30f75ca3401e25b504bfd06bd5662a ]
One of the i2c pin groups has some junk at the end. The name should be i2c2_scl_h1, and indeed that's the name used by i2c2_pins3 in meson-s4.dtsi.
--- drivers/pinctrl/meson/pinctrl-meson-s4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pinctrl/meson/pinctrl-meson-s4.c +1 -1
@@ -854,7 +854,7 @@ static const char * const i2c1_groups[] = {static const char *const i2c2_groups[] = {"i2c2_sda_d" ,"i2c2_scl_d" ,"i2c2_sda_h8" ,"i2c2_scl_h9" , -"i2c2_sda_h0" ,"i2c2_scl_h1l," +"i2c2_sda_h0" ,"i2c2_scl_h1" , };static const char *const i2c3_groups[] = {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 33/457 pinctrl: generic: serialise pinctrl_generic_dt_node_to_map()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sarah Emery <[email protected]>
[ Upstream commit 51ae99659469edba2e83931efa26b77d36ca02c2 ]
pinctrl_generic_add_group() documents that the caller must take care of locking, and pinmux_generic_add_function() needs it too, but pinctrl_generic_dt_node_to_map() calls them without holding pctldev->mutex, and the core caller in create_pinctrl() does not take it either.
The driver core calls pinctrl_bind_pins() before probing a device, so two devices that reference the same pin controller can run pinctrl_generic_dt_node_to_map() on one pctldev at the same time.
Both add functions take the new selector from pctldev->num_groups or pctldev->num_functions, and radix_tree_insert() at that index. Two racing callers can read the same selector before either has inserted, so the second insert collides and fails:
k1-pinctrl d401e000.pinctrl:
error -EEXIST: error adding function pcie2-0-cfg k1-pinctrl d401e000.pinctrl:
does not have pin group pcie0-0-cfg.pcie0-0-pins
leaving one consumer without its pin configuration.
This was hit on a SpacemiT K3 board, where PCIe devices probe in parallel against the single shared pin controller.
Take pctldev->mutex across the whole function, so that the groups and the function referring are in a single critical section.
--- drivers/pinctrl/pinctrl-generic.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/pinctrl/pinctrl-generic.c +4 -0
@@ -3,8 +3,10 @@#define pr_fmt (fmt) "generic pinconfig core: " fmt#include <linux/array_size.h> +#include <linux/cleanup.h> #include <linux/device.h> #include <linux/module.h> +#include <linux/mutex.h> #include <linux/of.h> #include <linux/slab.h>
@@ -196,6 +198,8 @@ static int pinctrl_generic_dt_node_to_map(struct pinctrl_dev *pctldev,int ngroups =0 ;int ret; +guard (mutex)(&pctldev->mutex); + *maps =NULL ; *num_maps =0 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 34/457 HID: amd_sfh: Validate PCI BAR size before mapping
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Slawomir Stepien <[email protected]>
[ Upstream commit 65bcc5f89704efe5b9d69d4ea2c1002d90c31382 ]
The amd_sfh driver maps PCI BAR 2 using pcim_iomap_regions() and subsequently accesses MMIO registers at offsets up to 0x10958 (e.g., AMD_P2C_MSG3 at 0x1068C). However, the driver never validates that the BAR size is large enough to cover these accesses. If the driver is bound to a device with a smaller BAR 2, this leads to an out-of-bounds memory access and a page fault during the probe function.
For example, a page fault can occur when reading from privdata->mmio + AMD_P2C_MSG3 in mp2_select_ops():
BUG: unable to handle page fault for address: ffffc9000390368c PGD 100000067 P4D 100000067 PUD 1012c1067 PMD 105b64067 PTE 0 Oops: Oops: 0000 [#1] SMP KASAN NOPTI RIP: 0010:readl arch/x86/include/asm/io.h:59 [inline] RIP: 0010:mp2_select_ops drivers/hid/amd-sfh-hid/amd_sfh_pcie.c:282 [inline] RIP: 0010:amd_mp2_pci_probe+0x337/0x5f0 drivers/hid/amd-sfh-hid/amd_sfh_pcie.c:487 Call Trace: <TASK> local_pci_probe drivers/pci/pci-driver.c:332 [inline] pci_call_probe drivers/pci/pci-driver.c:394 [inline] __pci_device_probe drivers/pci/pci-driver.c:455 [inline] pci_device_probe+0x431/0xc90 drivers/pci/pci-driver.c:489
Fix this by verifying that the length of BAR 2 is at least 128KB before attempting to map it. Since the maximum accessed offset is 0x10958, and PCI BAR sizes are powers of 2, any legitimate hardware will have a BAR size of at least 128KB.
--- drivers/hid/amd-sfh-hid/amd_sfh_common.h | 4 ++++ drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 10 ++++++++++ 2 files changed, 14 insertions(+)
drivers/hid/amd-sfh-hid/amd_sfh_common.h +4 -0
@@ -12,11 +12,15 @@#include <linux/mutex.h> #include <linux/pci.h> +#include <linux/sizes.h> #include "amd_sfh_hid.h" #define PCI_DEVICE_ID_AMD_MP2 0x15E4#define PCI_DEVICE_ID_AMD_MP2_1_1 0x164A +/* The BAR 2 size must cover the highest register offset (0x10958) */ +#define AMD_SFH_MIN_BAR_SIZE SZ_128K +#define AMD_C2P_MSG (regno) (0x10500 + ((regno) * 4))#define AMD_P2C_MSG (regno) (0x10680 + ((regno) * 4))
drivers/hid/amd-sfh-hid/amd_sfh_pcie.c +10 -0
@@ -451,6 +451,16 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *iif (rc)return rc; +if (!(pci_resource_flags (pdev,2 ) &IORESOURCE_MEM )) { +dev_err (&pdev->dev,"BAR 2 is not IORESOURCE_MEM\n" ); +return -ENODEV ; + } + +if (pci_resource_len (pdev,2 ) <AMD_SFH_MIN_BAR_SIZE ) { +dev_err (&pdev->dev,"BAR 2 is too small\n" ); +return -EINVAL ; + } + rc =pcim_iomap_regions (pdev,BIT (2 ),DRIVER_NAME );if (rc)return rc;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 35/457 HID: bpf: fix __hid_bpf_hw_check_params report length
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Tissoires <[email protected]>
[ Upstream commit c4afa4862b878d56e0cc1021298794ac1b45bc49 ]
Turns out that USB, I2C and other transport drivers (except uhid which just passes the data) still need to have the report ID in the first byte.
Because they expect the first byte to be the report ID or 0, when the report ID is 0, they strip that first byte before forwarding to the device. This means that the transport layer forwards a buffer of size N-1 to the device, which gets rejected.
--- drivers/hid/bpf/hid_bpf_dispatch.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/hid/bpf/hid_bpf_dispatch.c +8 -4
@@ -359,7 +359,7 @@ hid_bpf_release_context(struct hid_bpf_ctx *ctx)static int __hid_bpf_hw_check_params (struct hid_bpf_ctx *ctx,__u8 *buf,size_t *buf__sz, -enum hid_report_type rtype) +enum hid_report_type rtype,bool hw_request) {struct hid_report_enum *report_enum;struct hid_report *report;
@@ -388,6 +388,10 @@ __hid_bpf_hw_check_params(struct hid_bpf_ctx *ctx, __u8 *buf, size_t *buf__sz, report_len =hid_report_len (report); +/* unnumbered reports need to have a report ID reserved in the first byte */ +if (hw_request && report_enum->numbered ==0 ) + report_len +=1 ; +if (*buf__sz > report_len) *buf__sz = report_len;
@@ -420,7 +424,7 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz,return -EDEADLOCK ;/* check arguments */ - ret =__hid_bpf_hw_check_params (ctx, buf, &size, rtype); + ret =__hid_bpf_hw_check_params (ctx, buf, &size, rtype, true);if (ret)return ret;
@@ -480,7 +484,7 @@ hid_bpf_hw_output_report(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz)return -EDEADLOCK ;/* check arguments */ - ret =__hid_bpf_hw_check_params (ctx, buf, &size,HID_OUTPUT_REPORT ); + ret =__hid_bpf_hw_check_params (ctx, buf, &size,HID_OUTPUT_REPORT , true);if (ret)return ret;
@@ -506,7 +510,7 @@ __hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *breturn -EDEADLOCK ;/* check arguments */ - ret =__hid_bpf_hw_check_params (ctx, buf, &size, type); + ret =__hid_bpf_hw_check_params (ctx, buf, &size, type, false);if (ret)return ret;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 36/457 RISC-V: KVM: Fix the conversion between vsip and hvip
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yicong Yang <[email protected]>
[ Upstream commit 52c6b7d20d3e791a9e75aa2be2a467990154c7cd ]
Per AIA spec 1.0 Section 6.3.2, the interrupt numbers 13-63 shares same bit position between related VS shadow CSRs and hypervisor CSRs. So there's a shift only for SSI, STI and SEI interrupt.
Currently the KVM always does a shift for all the interrupts (include LCOFI with number 13) when doing the conversion between vsip and hvip. Fix this by only doing shift the SSI, STI and SEI. Add wrappers for doing the conversion between vsip and hvip.
--- arch/riscv/include/asm/csr.h | 20 ++++++++++++++++---- arch/riscv/kvm/vcpu.c | 3 +-- arch/riscv/kvm/vcpu_onereg.c | 8 +++----- tools/arch/riscv/include/asm/csr.h | 20 ++++++++++++++++---- 4 files changed, 36 insertions(+), 15 deletions(-)
arch/riscv/include/asm/csr.h +16 -4
@@ -183,12 +183,24 @@#define HGATP_MODE_SHIFT HGATP32_MODE_SHIFT#endif -/* VSIP & HVIP relation */ +/* +* VSIP & HVIP relation +* +* The bit positions are same between VSIP and HVIP for interrupt +* numbers 13-63, where there's a shift for the SSI, STI and SEI. +*/ #define VSIP_TO_HVIP_SHIFT (IRQ_VS_SOFT - IRQ_S_SOFT) -#define VSIP_VALID_MASK ((_AC(1, UL) << IRQ_S_SOFT) | \ +#define VSIP_BIAS_MASK ((_AC(1, UL) << IRQ_S_SOFT) | \ (_AC(1, UL) << IRQ_S_TIMER) | \ - (_AC(1, UL) << IRQ_S_EXT) | \ - (_AC(1, UL) << IRQ_PMU_OVF)) + (_AC(1, UL) << IRQ_S_EXT)) +#define VSIP_NO_BIAS_MASK (_AC(1, UL) << IRQ_PMU_OVF) +#define VSIP_VALID_MASK (VSIP_BIAS_MASK | VSIP_NO_BIAS_MASK) +#define vsip_to_hvip (_vsip) ((((_vsip) & VSIP_BIAS_MASK) << \ + VSIP_TO_HVIP_SHIFT) | \ + ((_vsip) & VSIP_NO_BIAS_MASK)) +#define hvip_to_vsip (_hvip) ((((_hvip) >> VSIP_TO_HVIP_SHIFT) & \ + VSIP_BIAS_MASK) | \ + ((_hvip) & VSIP_NO_BIAS_MASK))/* AIA CSR bits */ #define TOPI_IID_SHIFT 16
arch/riscv/kvm/vcpu.c +1 -2
@@ -475,8 +475,7 @@ bool kvm_riscv_vcpu_has_interrupts(struct kvm_vcpu *vcpu, u64 mask)bool ret;raw_spin_lock_irqsave (&vcpu->arch.irqs_pending_lock, flags); - ie = ((vcpu->arch.guest_csr.vsie &VSIP_VALID_MASK ) - <<VSIP_TO_HVIP_SHIFT ) & (unsigned long )mask; + ie =vsip_to_hvip (vcpu->arch.guest_csr.vsie) & (unsigned long )mask; ie |= vcpu->arch.guest_csr.vsie & ~IRQ_LOCAL_MASK & (unsigned long )mask; ret = vcpu->arch.irqs_pending[0 ] & ie;
arch/riscv/kvm/vcpu_onereg.c +3 -5
@@ -272,7 +272,7 @@ static int kvm_riscv_vcpu_general_get_csr(struct kvm_vcpu *vcpu,if (reg_num ==KVM_REG_RISCV_CSR_REG (sip)) {kvm_riscv_vcpu_flush_interrupts (vcpu); - *out_val = (csr->hvip >>VSIP_TO_HVIP_SHIFT ) &VSIP_VALID_MASK ; + *out_val =hvip_to_vsip (csr->hvip); *out_val |= csr->hvip & ~IRQ_LOCAL_MASK ; }else *out_val = ((unsigned long *)csr)[reg_num];
@@ -293,10 +293,8 @@ static int kvm_riscv_vcpu_general_set_csr(struct kvm_vcpu *vcpu, reg_num =array_index_nospec (reg_num, regs_max); -if (reg_num ==KVM_REG_RISCV_CSR_REG (sip)) { - reg_val &=VSIP_VALID_MASK ; - reg_val <<=VSIP_TO_HVIP_SHIFT ; - } +if (reg_num ==KVM_REG_RISCV_CSR_REG (sip)) + reg_val =vsip_to_hvip (reg_val); ((unsigned long *)csr)[reg_num] = reg_val;
tools/arch/riscv/include/asm/csr.h +16 -4
@@ -163,12 +163,24 @@#define HGATP_MODE_SHIFT HGATP32_MODE_SHIFT#endif -/* VSIP & HVIP relation */ +/* +* VSIP & HVIP relation +* +* The bit positions are same between VSIP and HVIP for interrupt +* numbers 13-63, where there's a shift for the SSI, STI and SEI. +*/ #define VSIP_TO_HVIP_SHIFT (IRQ_VS_SOFT - IRQ_S_SOFT) -#define VSIP_VALID_MASK ((_AC(1, UL) << IRQ_S_SOFT) | \ +#define VSIP_BIAS_MASK ((_AC(1, UL) << IRQ_S_SOFT) | \ (_AC(1, UL) << IRQ_S_TIMER) | \ - (_AC(1, UL) << IRQ_S_EXT) | \ - (_AC(1, UL) << IRQ_PMU_OVF)) + (_AC(1, UL) << IRQ_S_EXT)) +#define VSIP_NO_BIAS_MASK (_AC(1, UL) << IRQ_PMU_OVF) +#define VSIP_VALID_MASK (VSIP_BIAS_MASK | VSIP_NO_BIAS_MASK) +#define vsip_to_hvip (_vsip) ((((_vsip) & VSIP_BIAS_MASK) << \ + VSIP_TO_HVIP_SHIFT) | \ + ((_vsip) & VSIP_NO_BIAS_MASK)) +#define hvip_to_vsip (_hvip) ((((_hvip) >> VSIP_TO_HVIP_SHIFT) & \ + VSIP_BIAS_MASK) | \ + ((_hvip) & VSIP_NO_BIAS_MASK))/* AIA CSR bits */ #define TOPI_IID_SHIFT 16
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 37/457 KVM: riscv: Fix NACL hfence entry update order
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zongmin Zhou <[email protected]>
[ Upstream commit b3d346838ec65fac7fd83f5dbcedd13cadfffddb ]
The SBI v3.0 specification (section 15.1.2) requires a nested HFENCE entry to be populated as follows:
1) find an unused entry with Config.Pending == 0
2) update the Page_Number and Page_Count words
3) update the Config word with Config.Pending set
__kvm_riscv_nacl_hfence() writes the Config word first, so the SBI implementation (or NACL hardware) can observe a pending entry with pnum/pcount values left over from the previous use of that entry, resulting in incorrect TLB flush ranges.
Write pnum and pcount first and the Config word last. Since the consumer is an external agent on coherent shared memory, use WRITE_ONCE() to stop the compiler from reordering the stores and smp_wmb() to make the parameter words globally visible before the Pending bit is set.
--- arch/riscv/kvm/nacl.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
arch/riscv/kvm/nacl.c +16 -4
@@ -42,12 +42,24 @@ void __kvm_riscv_nacl_hfence(void *shmem, } } - entp = shmem +SBI_NACL_SHMEM_HFENCE_ENTRY_CONFIG (i); - *entp =cpu_to_lelong (control); +/* +* Per SBI v3.0 section 15.1.2, the Page_Number and Page_Count +* words must be updated before the Config word with its Pending +* bit set. WRITE_ONCE() stops the compiler from reordering the +* stores and smp_wmb() makes the parameter words globally +* visible to the SBI implementation (or NACL hardware) before +* the Pending bit is set. +*/ entp = shmem +SBI_NACL_SHMEM_HFENCE_ENTRY_PNUM (i); - *entp =cpu_to_lelong (page_num); +WRITE_ONCE (*entp,cpu_to_lelong (page_num)); entp = shmem +SBI_NACL_SHMEM_HFENCE_ENTRY_PCOUNT (i); - *entp =cpu_to_lelong (page_count); +WRITE_ONCE (*entp,cpu_to_lelong (page_count)); + +/* Ensure the parameter words are visible before the Pending bit */ +smp_wmb (); + + entp = shmem +SBI_NACL_SHMEM_HFENCE_ENTRY_CONFIG (i); +WRITE_ONCE (*entp,cpu_to_lelong (control)); }int kvm_riscv_nacl_enable (void )
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 38/457 RISC-V: KVM: Preserve firmware counter value across stop/start
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeungJu Cheon <[email protected]>
[ Upstream commit 8b3fd1a8b305321171602bfa7c41212441cf69e4 ]
Firmware events accumulate in kvpmu->fw_event[].value while running, but counter stop only clears fw_event[].started without saving the value back to pmc->counter_val. A subsequent counter start without SBI_PMU_START_FLAG_SET_INIT_VALUE reloads the stale counter_val into fw_event[].value, losing all events counted so far.
Save fw_event[].value into counter_val when actually stopping a running counter, and remove the now redundant synchronization from the snapshot path.
--- arch/riscv/kvm/vcpu_pmu.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
arch/riscv/kvm/vcpu_pmu.c +6 -6
@@ -675,10 +675,12 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base, goto out; } -if (!kvpmu->fw_event[fevent_code].started) +if (!kvpmu->fw_event[fevent_code].started) { sbiret =SBI_ERR_ALREADY_STOPPED ; - - kvpmu->fw_event[fevent_code].started = false; + }else { + kvpmu->fw_event[fevent_code].started = false; + pmc->counter_val = kvpmu->fw_event[fevent_code].value; + } }else if (pmc->perf_event) {if (pmc->started) {/* Stop counting the counter */
@@ -696,9 +698,7 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base, }if (snap_flag_set && !sbiret) { -if (pmc->cinfo.type ==SBI_PMU_CTR_TYPE_FW ) - pmc->counter_val = kvpmu->fw_event[fevent_code].value; -else if (pmc->perf_event) +if (pmc->perf_event) pmc->counter_val +=perf_event_read_value (pmc->perf_event, &enabled, &running);/*
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 39/457 RISC-V: KVM: Report snapshot write failure to the guest
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeungJu Cheon <[email protected]>
[ Upstream commit 057dd2639ceae79adced5d8fe52c32d562edcb3a ]
If kvm_vcpu_write_guest() fails while updating the PMU snapshot area on counter stop, the guest may receive SBI_SUCCESS without the snapshot being updated, leaving stale data in shared memory.
Return SBI_ERR_FAILURE when the snapshot write fails.
--- arch/riscv/kvm/vcpu_pmu.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
arch/riscv/kvm/vcpu_pmu.c +4 -3
@@ -727,9 +727,10 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base, } } -if (shmem_needs_update) -kvm_vcpu_write_guest (vcpu, kvpmu->snapshot_addr, kvpmu->sdata, -sizeof (struct riscv_pmu_snapshot_data )); +if (shmem_needs_update && +kvm_vcpu_write_guest (vcpu, kvpmu->snapshot_addr, kvpmu->sdata, +sizeof (struct riscv_pmu_snapshot_data ))) + sbiret =SBI_ERR_FAILURE ; out: retdata->err_val = sbiret;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 40/457 RISC-V: KVM: Fix perf-backed counter accounting across stop and read
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeungJu Cheon <[email protected]>
[ Upstream commit c7e2cc38c56142cdab25e6f73602a8222bf9479b ]
pmu_ctr_read() adds the event count returned by perf_event_read_value() to counter_val, which can accumulate the same count repeatedly across reads. kvm_riscv_vcpu_pmu_ctr_stop() also leaves counter_val stale by not folding the current event count into it.
Make reads of perf-backed counters side-effect free, and use perf_event_pause() when stopping a counter to fold the current event count into counter_val while resetting it. This preserves the counter value across stop/start and lets the snapshot path use counter_val directly.
--- arch/riscv/kvm/vcpu_pmu.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
arch/riscv/kvm/vcpu_pmu.c +8 -8
@@ -270,12 +270,13 @@ static int pmu_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx,return -EINVAL ; pmc->counter_val = kvpmu->fw_event[fevent_code].value; + *out_val = pmc->counter_val; }else if (pmc->perf_event) { - pmc->counter_val +=perf_event_read_value (pmc->perf_event, &enabled, &running); + *out_val = pmc->counter_val + +perf_event_read_value (pmc->perf_event, &enabled, &running); }else {return -EINVAL ; } - *out_val = pmc->counter_val;return 0 ; }
@@ -645,7 +646,6 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base, {struct kvm_pmu *kvpmu =vcpu_to_pmu (vcpu);int i, pmc_index, sbiret =0 ; -u64 enabled, running;struct kvm_pmc *pmc;int fevent_code;bool snap_flag_set = flags &SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT ;
@@ -683,8 +683,11 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base, } }else if (pmc->perf_event) {if (pmc->started) { -/* Stop counting the counter */ -perf_event_disable (pmc->perf_event); +/* +* Stop the counter and fold the live count into counter_val. +* Reset the event value to avoid redundant accumulation. +*/ + pmc->counter_val +=perf_event_pause (pmc->perf_event, true); pmc->started = false; }else { sbiret =SBI_ERR_ALREADY_STOPPED ;
@@ -698,9 +701,6 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base, }if (snap_flag_set && !sbiret) { -if (pmc->perf_event) - pmc->counter_val +=perf_event_read_value (pmc->perf_event, - &enabled, &running);/* * The counter and overflow indices in the snapshot region are w.r.to * cbase. Modify the set bit in the counter mask instead of the pmc_index
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 41/457 KVM: arm64: vgic-its: Free the caches when GITS_BASER changes
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fuad Tabba <[email protected]>
[ Upstream commit 8cd92f77ae4f5371a7d581f8324c24919670b304 ]
A guest that disables the ITS and re-points or shrinks GITS_BASER<n> with VALID still set keeps the devices and collections it mapped against the old table, as KVM frees them only when VALID is cleared. The contents of the table are IMPLEMENTATION DEFINED, so a write that gives GITS_BASER<n> a different address or size may lose whatever the old value described. Free the list whenever the stored value changes, and drop the translation cache with it.
The cache is not empty just because the ITS is disabled: its->enabled is written under the cmd_lock, while vgic_its_resolve_lpi() tests it under the its_lock, so an injection can still cache an entry after the ITS was disabled. Hence the invalidation inside the its_lock section.
Test for a change rather than a write: its_restore_enable() rewrites GITS_BASER<n> from its probe-time cache on resume, and KVM reports GITS_TYPER.HCC as 0, so nothing re-maps the boot CPU's collection afterwards.
--- arch/arm64/kvm/vgic/vgic-its.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
arch/arm64/kvm/vgic/vgic-its.c +8 -3
@@ -1658,7 +1658,7 @@ static void vgic_mmio_write_its_baser(struct kvm *kvm, unsigned long val) {const struct vgic_its_abi *abi =vgic_its_get_abi (its); -u64 entry_size, table_type; +u64 old, entry_size, table_type;u64 reg, *regptr, clearbits =0 ;/* When GITS_CTLR.Enable is 1, we ignore write accesses. */
@@ -1681,7 +1681,9 @@ static void vgic_mmio_write_its_baser(struct kvm *kvm,return ; } - reg =update_64bit_reg (*regptr, addr &7 , len, val); + old = *regptr; + + reg =update_64bit_reg (old, addr &7 , len, val); reg &= ~GITS_BASER_RO_MASK ; reg &= ~clearbits;
@@ -1691,7 +1693,8 @@ static void vgic_mmio_write_its_baser(struct kvm *kvm, *regptr = reg; -if (!(reg &GITS_BASER_VALID )) { +/* The ITS driver rewrites an unchanged GITS_BASER<n> on resume. */ +if (reg != old) {/* Take the its_lock to prevent a race with a save/restore */ mutex_lock (&its->its_lock);switch (table_type) {
@@ -1702,6 +1705,8 @@ static void vgic_mmio_write_its_baser(struct kvm *kvm,vgic_its_free_collection_list (kvm, its);break ; } +/* A concurrent injection may have cached a translation. */ +vgic_its_invalidate_cache (its);mutex_unlock (&its->its_lock); } }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 42/457 KVM: arm64: vgic-its: Skip unreachable devices instead of failing the save
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fuad Tabba <[email protected]>
[ Upstream commit cc5d96036e01ac330d24b2f0c336d60f82ab4930 ]
vgic_its_save_device_tables() aborts with -EINVAL when a device's entry falls outside the device table, which a guest can arrange on its own: an indirect table lets it clear an L1 entry's valid bit without touching GITS_BASER. That fails a save userspace should be able to issue reliably.
Skip the device instead, and point the saved DTE chain past it, as commit ad1e686e2378d ("KVM: arm64: vgic-its: Point saved ITEs at the next valid entry") does for ITEs. compute_next_devid_offset() takes the next device off the list whether or not it was saved, so the predecessor would otherwise point at an entry the save never wrote. Restore follows that offset while it stays inside the table being scanned: within an L2 block, or anywhere in a flat table. Both need userspace to remove a memslot under the table, since dropping an L1 entry takes the whole block with it and scan_its_table() stops at the block boundary.
--- arch/arm64/kvm/vgic/vgic-its.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-)
arch/arm64/kvm/vgic/vgic-its.c +19 -13
@@ -2024,18 +2024,22 @@ static int vgic_its_attr_regs_access(struct kvm_device *dev,return ret; } -static u32 compute_next_devid_offset (struct list_head *h, +static u32 compute_next_devid_offset (struct vgic_its *its,u64 baser,struct its_device *dev) { -struct its_device *next; -u32 next_offset; +struct its_device *next = dev; -if (list_is_last (&dev->dev_list, h)) -return 0 ; - next =list_next_entry (dev, dev_list); - next_offset = next->device_id - dev->device_id; +/* +* Point at the next device vgic_its_save_device_tables() saves. It +* sorts device_list first, so the subtraction cannot underflow. +*/ +list_for_each_entry_continue (next, &its->device_list, dev_list) { +if (vgic_its_check_id (its, baser, next->device_id,NULL )) +return min_t (u32, next->device_id - dev->device_id, +VITS_DTE_MAX_DEVID_OFFSET ); + } -return min_t (u32, next_offset,VITS_DTE_MAX_DEVID_OFFSET ); +return 0 ; }static u32 compute_next_eventid_offset (struct list_head *h,struct its_ite *ite)
@@ -2275,17 +2279,18 @@ static int vgic_its_restore_itt(struct vgic_its *its, struct its_device *dev)* vgic_its_save_dte - Save a device table entry at a given GPA * * @its: ITS handle +* @baser: GITS_BASER<dev> the caller is saving against * @dev: ITS device * @ptr: GPA */ -static int vgic_its_save_dte (struct vgic_its *its,struct its_device *dev, -gpa_t ptr) +static int vgic_its_save_dte (struct vgic_its *its,u64 baser, +struct its_device *dev,gpa_t ptr) {u64 val, itt_addr_field;u32 next_offset; itt_addr_field = dev->itt_addr >>8 ; - next_offset =compute_next_devid_offset (&its->device_list, dev); + next_offset =compute_next_devid_offset (its, baser, dev); val = (1ULL << KVM_ITS_DTE_VALID_SHIFT | ((u64)next_offset << KVM_ITS_DTE_NEXT_SHIFT) | (itt_addr_field << KVM_ITS_DTE_ITTADDR_SHIFT) |
@@ -2384,15 +2389,16 @@ static int vgic_its_save_device_tables(struct vgic_its *its)int ret;gpa_t eaddr; +/* Don't fail a save that userspace must be able to issue. */ if (!vgic_its_check_id (its, baser, dev->device_id, &eaddr)) -return -EINVAL ; +continue ; ret =vgic_its_save_itt (its, dev);if (ret)return ret; - ret =vgic_its_save_dte (its, dev, eaddr); + ret =vgic_its_save_dte (its, baser, dev, eaddr);if (ret)return ret; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 43/457 KVM: arm64: Validate the SVE vector length in pkvm_vcpu_init_sve()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fuad Tabba <[email protected]>
[ Upstream commit 2a2eb10795a1e495aebc7f829ccecb72c05b4fd9 ]
pkvm_vcpu_init_sve() clamps only the upper bound of the host-provided sve_max_vl, so an invalid vector length reaches sve_state_size_from_vl() and the WARN_ON() there, which is fatal at EL2. The existing !sve_state_size test rejects such a length, but only after the macro has run.
Check sve_vl_valid() before deriving the state size. A valid length cannot yield a zero size, so the !sve_state_size test goes with it.
--- arch/arm64/kvm/hyp/nvhe/pkvm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
arch/arm64/kvm/hyp/nvhe/pkvm.c +3 -2
@@ -460,14 +460,15 @@ static int pkvm_vcpu_init_sve(struct pkvm_hyp_vcpu *hyp_vcpu, struct kvm_vcpu *h/* Limit guest vector length to the maximum supported by the host. */ sve_max_vl =min (READ_ONCE (host_vcpu->arch.sve_max_vl), kvm_host_sve_max_vl); - sve_state_size =sve_state_size_from_vl (sve_max_vl); sve_state =kern_hyp_va (READ_ONCE (host_vcpu->arch.sve_state)); -if (!sve_state || !sve_state_size) { +if (!sve_vl_valid (sve_max_vl) || !sve_state) { ret = -EINVAL ; goto err; } + sve_state_size =sve_state_size_from_vl (sve_max_vl); + ret =hyp_pin_shared_mem (sve_state, sve_state + sve_state_size);if (ret) goto err;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 44/457 KVM: arm64: Do not clear VM-wide SVE feature on vCPU init failure
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fuad Tabba <[email protected]>
[ Upstream commit a1b3c788ad31837e348075e93dbba3f447492776 ]
pkvm_vcpu_init_sve() clears KVM_ARM_VCPU_SVE in kvm->arch.vcpu_features when it fails, but vcpu_has_sve() tests KVM_ARCH_FLAG_GUEST_HAS_SVE, which is left set. Later vCPUs on that VM then skip the SVE setup and register with a NULL sve_state, which the guest's first FP access hands to sve_load_state().
Return the error without touching vcpu_features.
--- arch/arm64/kvm/hyp/nvhe/pkvm.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
arch/arm64/kvm/hyp/nvhe/pkvm.c +4 -9
@@ -451,7 +451,7 @@ static int pkvm_vcpu_init_sve(struct pkvm_hyp_vcpu *hyp_vcpu, struct kvm_vcpu *hunsigned int sve_max_vl;size_t sve_state_size;void *sve_state; -int ret =0 ; +int ret;if (!vcpu_has_feature (vcpu,KVM_ARM_VCPU_SVE )) {vcpu_clear_flag (vcpu,VCPU_SVE_FINALIZED );
@@ -462,24 +462,19 @@ static int pkvm_vcpu_init_sve(struct pkvm_hyp_vcpu *hyp_vcpu, struct kvm_vcpu *h sve_max_vl =min (READ_ONCE (host_vcpu->arch.sve_max_vl), kvm_host_sve_max_vl); sve_state =kern_hyp_va (READ_ONCE (host_vcpu->arch.sve_state)); -if (!sve_vl_valid (sve_max_vl) || !sve_state) { - ret = -EINVAL ; - goto err; - } +if (!sve_vl_valid (sve_max_vl) || !sve_state) +return -EINVAL ; sve_state_size =sve_state_size_from_vl (sve_max_vl); ret =hyp_pin_shared_mem (sve_state, sve_state + sve_state_size);if (ret) - goto err; +return ret; vcpu->arch.sve_state = sve_state; vcpu->arch.sve_max_vl = sve_max_vl;return 0 ; -err: -clear_bit (KVM_ARM_VCPU_SVE , vcpu->kvm->arch.vcpu_features); -return ret; }static int vm_copy_id_regs (struct pkvm_hyp_vcpu *hyp_vcpu)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 45/457 KVM: arm64: Derive GUEST_HAS_SVE from the SVE feature bit at EL2
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fuad Tabba <[email protected]>
[ Upstream commit 4f16c5fc8dc4c5596e3777ab9f449a54e3f85fd5 ]
pkvm_init_features_from_host() takes KVM_ARCH_FLAG_GUEST_HAS_SVE and KVM_ARM_VCPU_SVE from the host separately, but pkvm_vcpu_init_sve() tests the bit while vcpu_has_sve() reads the flag. A host that sets the flag without the bit gets a vCPU with a NULL sve_state that the world switch loads the guest's SVE state from.
Derive the flag from the bit, and drop the protected path's copy of the host's flag, which is dead code since protected VMs are not allowed SVE.
--- arch/arm64/kvm/hyp/nvhe/pkvm.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
arch/arm64/kvm/hyp/nvhe/pkvm.c +5 -4
@@ -360,7 +360,7 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const strucif (test_bit (KVM_ARCH_FLAG_WRITABLE_IMP_ID_REGS , &host_arch_flags)) hyp_vm->kvm.arch.midr_el1 = host_kvm->arch.midr_el1; -return ; + goto out; }if (kvm_pkvm_ext_allowed (kvm,KVM_CAP_ARM_MTE ))
@@ -379,13 +379,14 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const strucif (kvm_pkvm_ext_allowed (kvm,KVM_CAP_ARM_PTRAUTH_GENERIC ))set_bit (KVM_ARM_VCPU_PTRAUTH_GENERIC , allowed_features); -if (kvm_pkvm_ext_allowed (kvm,KVM_CAP_ARM_SVE )) { +if (kvm_pkvm_ext_allowed (kvm,KVM_CAP_ARM_SVE ))set_bit (KVM_ARM_VCPU_SVE , allowed_features); - kvm->arch.flags |= host_arch_flags &BIT (KVM_ARCH_FLAG_GUEST_HAS_SVE ); - }bitmap_and (kvm->arch.vcpu_features, host_kvm->arch.vcpu_features, allowed_features,KVM_VCPU_MAX_FEATURES ); +out: +__assign_bit (KVM_ARCH_FLAG_GUEST_HAS_SVE , &kvm->arch.flags, +kvm_vcpu_has_feature (kvm,KVM_ARM_VCPU_SVE )); }static void unpin_host_vcpu (struct kvm_vcpu *host_vcpu)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 46/457 KVM: arm64: Return -EINVAL for an empty SMCCC filter range at base 0
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <[email protected]>
[ Upstream commit 64dc6f1db7e620f2e9337bb181f305fb0561da79 ]
kvm_smccc_set_filter() only rejects a range if its inclusive end, base + nr_functions - 1, is below base. That catches an empty range (nr_functions == 0) at every nonzero base, but at base 0 the end wraps to U32_MAX and KVM tries to insert [0, U32_MAX], which overlaps the reserved Arm Architecture Calls ranges. KVM_ARM_VM_SMCCC_FILTER then returns -EEXIST instead of the -EINVAL that the smccc_filter selftest expects for an empty range.
Reject a zero function count explicitly.
Tested with a userspace reproducer on an arm64 VHE host under QEMU TCG:
EEXIST before, EINVAL after.
--- arch/arm64/kvm/hypercalls.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm64/kvm/hypercalls.c +2 -1
@@ -185,7 +185,8 @@ static int kvm_smccc_set_filter(struct kvm *kvm, struct kvm_smccc_filter __user start = filter.base; end = start + filter.nr_functions -1 ; -if (end < start || filter.action >=NR_SMCCC_FILTER_ACTIONS ) +if (!filter.nr_functions || end < start || + filter.action >=NR_SMCCC_FILTER_ACTIONS )return -EINVAL ;mutex_lock (&kvm->arch.config_lock);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 47/457 KVM: arm64: Match hyp text by physical address in fix_host_ownership()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fuad Tabba <[email protected]>
[ Upstream commit 5a8b505ede133fb30ca3b3a19d0db00c08237615 ]
On a non-hVHE host, fix_host_ownership_walker()'s test for PAGE_HYP_EXEC never matches: KVM_PGTABLE_PROT_UX is cleared at map time and only PX is reported on read-back. Hyp text is therefore donated rather than left read-only in the host stage-2, and the instruction dump in nvhe_hyp_panic_handler() reads a page the host has no access to.
Match the text by physical address instead, in a helper a later patch reuses. A test on the permissions would leave any other executable mapping host-readable too.
--- arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 1 + arch/arm64/kvm/hyp/nvhe/mem_protect.c | 8 ++++++++ arch/arm64/kvm/hyp/nvhe/setup.c | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-)
arch/arm64/kvm/hyp/include/nvhe/mem_protect.h +1 -0
@@ -52,6 +52,7 @@ int __pkvm_host_test_clear_young_guest(u64 gfn, u64 nr_pages, bool mkold, structint __pkvm_host_mkyoung_guest (u64 gfn,struct pkvm_hyp_vcpu *vcpu);bool addr_is_memory (phys_addr_t phys); +bool addr_is_hyp_text (phys_addr_t phys);int host_stage2_idmap_locked (phys_addr_t addr,u64 size,enum kvm_pgtable_prot prot);int host_stage2_set_owner_locked (phys_addr_t addr,u64 size,u8 owner_id);int kvm_host_prepare_stage2 (void *pgt_pool_base);
arch/arm64/kvm/hyp/nvhe/mem_protect.c +8 -0
@@ -443,6 +443,14 @@ bool addr_is_memory(phys_addr_t phys)return !!find_mem_range (phys, &range); } +bool addr_is_hyp_text (phys_addr_t phys) +{ +phys_addr_t start =ALIGN_DOWN (__hyp_pa (__hyp_text_start),PAGE_SIZE ); +phys_addr_t end =PAGE_ALIGN (__hyp_pa (__hyp_text_end)); + +return phys >= start && phys < end; +} +static bool is_in_mem_range (u64 addr,struct kvm_mem_range *range) {return range->start <= addr && addr < range->end;
arch/arm64/kvm/hyp/nvhe/setup.c +1 -1
@@ -217,7 +217,7 @@ static int fix_host_ownership_walker(const struct kvm_pgtable_visit_ctx *ctx,case PKVM_PAGE_OWNED :set_hyp_state (page,PKVM_PAGE_OWNED );/* hyp text is RO in the host stage-2 to be inspected on panic. */ -if (prot ==PAGE_HYP_EXEC ) { +if (addr_is_hyp_text (phys)) {set_host_state (page,PKVM_NOPAGE );return host_stage2_idmap_locked (phys,PAGE_SIZE ,KVM_PGTABLE_PROT_R ); }else {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 48/457 KVM: selftests: fix steal_time for arm64 with host page size > 4K
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Ott <[email protected]>
[ Upstream commit 96e6757cb0674acb86ee8b558ee6bffe0eec0bb0 ]
Fix the following failure when running with 16K host page size:
==== Test Assertion Failure ====
lib/kvm_util.c:991: vm_adjust_num_guest_pages(vm->mode, npages) == npages pid=873 tid=873 errno=0 - Success
1 0x0000000000405a27: vm_mem_add at kvm_util.c:991
2 0x000000000040241f: check_steal_time_uapi at steal_time.c:223 (discriminator 7)
3 (inlined by) main at steal_time.c:539 (discriminator 7)
4 0x00007fff8b57af3b: ?? ??:0
5 0x00007fff8b57b007: ?? ??:0
6 0x0000000000402b6f: _start at ??:?Number of guest pages is not compatible with the host. Try npages=4
--- tools/testing/selftests/kvm/steal_time.c | 30 ++++++++++++++++-------- 1 file changed, 20 insertions(+), 10 deletions(-)
tools/testing/selftests/kvm/steal_time.c +20 -10
@@ -27,6 +27,9 @@static void *st_gva[NR_VCPUS ];static u64 guest_stolen_time[NR_VCPUS ]; +static struct kvm_vm *vm_create_steal_time (u32 nr_vcpus,void *guest_code, +struct kvm_vcpu *vcpus[]); +#if defined(__x86_64__)/* steal_time must have 64-byte alignment */
@@ -211,17 +214,14 @@ static void check_steal_time_uapi(void)u64 st_ipa;int ret; - vm =vm_create_with_one_vcpu (&vcpu,NULL ); -struct kvm_device_attr dev = { .group =KVM_ARM_VCPU_PVTIME_CTRL , .attr =KVM_ARM_VCPU_PVTIME_IPA , .addr = (u64)&st_ipa, }; + vm =vm_create_steal_time (1 ,NULL , &vcpu);vcpu_ioctl (vcpu,KVM_HAS_DEVICE_ATTR , &dev); -vm_userspace_mem_region_add (vm,VM_MEM_SRC_ANONYMOUS ,ST_GPA_BASE ,1 ,1 ,0 ); -virt_map (vm,ST_GPA_BASE ,ST_GPA_BASE ,1 ); st_ipa = (ulong )ST_GPA_BASE |1 ; ret =__vcpu_ioctl (vcpu,KVM_SET_DEVICE_ATTR , &dev);
@@ -504,6 +504,21 @@ static void run_vcpu(struct kvm_vcpu *vcpu) } } +static struct kvm_vm *vm_create_steal_time (u32 nr_vcpus,void *guest_code, +struct kvm_vcpu *vcpus[]) +{ +unsigned int gpages; +struct kvm_vm *vm; + +/* Create a VM and an identity mapped memslot for the steal time structure */ + vm =vm_create_with_vcpus (nr_vcpus, guest_code, vcpus); + gpages =vm_calc_num_guest_pages (VM_MODE_DEFAULT ,STEAL_TIME_SIZE * nr_vcpus); +vm_userspace_mem_region_add (vm,VM_MEM_SRC_ANONYMOUS ,ST_GPA_BASE ,1 , gpages,0 ); +virt_map (vm,ST_GPA_BASE ,ST_GPA_BASE , gpages); + +return vm; +} +int main (int ac,char **av) {struct kvm_vcpu *vcpus[NR_VCPUS ];
@@ -511,7 +526,6 @@ int main(int ac, char **av)pthread_attr_t attr;pthread_t thread;cpu_set_t cpuset; -unsigned int gpages;long stolen_time;long run_delay;bool verbose;
@@ -526,11 +540,7 @@ int main(int ac, char **av)pthread_attr_setaffinity_np (&attr,sizeof (cpu_set_t), &cpuset);pthread_setaffinity_np (pthread_self (),sizeof (cpu_set_t), &cpuset); -/* Create a VM and an identity mapped memslot for the steal time structure */ - vm =vm_create_with_vcpus (NR_VCPUS , guest_code, vcpus); - gpages =vm_calc_num_guest_pages (VM_MODE_DEFAULT ,STEAL_TIME_SIZE *NR_VCPUS ); -vm_userspace_mem_region_add (vm,VM_MEM_SRC_ANONYMOUS ,ST_GPA_BASE ,1 , gpages,0 ); -virt_map (vm,ST_GPA_BASE ,ST_GPA_BASE , gpages); + vm =vm_create_steal_time (NR_VCPUS , guest_code, vcpus);ksft_print_header ();TEST_REQUIRE (is_steal_time_supported (vcpus[0 ]));
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 49/457 KVM: arm64: Fix FGT mapping for HFGITR_EL2.nGCSEPP
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Brown <[email protected]>
[ Upstream commit 089e4f3c4862ba3f29dff2361caa8084879194fd ]
The encoding to trap mapping currently maps a FGT on OP_GCSPOPX to HFGITR_EL2.nGCSEPP but as per DDI0601 2026-06 this FGT controls trapping of GCSPUSHX and GCSPOPCX, and not the separate GCSPOPX instruction. Update the mapping to reflect the architecture.
--- arch/arm64/kvm/emulate-nested.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/kvm/emulate-nested.c +1 -1
@@ -1432,7 +1432,7 @@ static const struct encoding_to_trap_config encoding_to_fgt[] __initconst = {SR_FGT (OP_AT_S1E1A ,HFGITR ,ATS1E1A ,1 ),SR_FGT (OP_COSP_RCTX ,HFGITR ,COSPRCTX ,1 ),SR_FGT (OP_GCSPUSHX ,HFGITR , nGCSEPP,0 ), -SR_FGT (OP_GCSPOPX ,HFGITR , nGCSEPP,0 ), +SR_FGT (OP_GCSPOPCX ,HFGITR , nGCSEPP,0 ),SR_FGT (OP_GCSPUSHM ,HFGITR , nGCSPUSHM_EL1,0 ),SR_FGT (OP_BRB_IALL ,HFGITR , nBRBIALL,0 ), SR_FGT(OP_BRB_INJ, HFGITR, nBRBINJ, 0),
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 50/457 squashfs: Add dictionary size range check to prevent shift-out-of-bounds
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ran Hongyun <[email protected]>
[ Upstream commit 1f7745fb3580152ca902ef181b605f33cabfb1d0 ]
When an abnormal SquashFS image (COMP_OPTS flag is 1 but dictionary size is 0) is mounted, and performs shift operations using dictionarysize, the shift exponent is -1, causing a shift-out-of-bounds.
Detail as below:squashfs_comp_opts(msblk, buffer, length)
squashfs_xz_comp_opts()
if (comp_opts)
n = ffs(opts->dict_size) - 1;<----opts->dict_size=0, n=-1
if (opts->dict_size != (1 << n) && opts->dict_size !=
(1 << n) + (1 << (n + 1))) <----shift-out-of-boundsFix it by adding a dictionary size range check before the shift operation.
--- fs/squashfs/xz_wrapper.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/squashfs/xz_wrapper.c +3 -3
@@ -57,10 +57,10 @@ static void *squashfs_xz_comp_opts(struct squashfs_sb_info *msblk, opts->dict_size =le32_to_cpu (comp_opts->dictionary_size); -/* the dictionary size should be 2^n or 2^n+2^(n+1) */ +/* the dictionary size should be positive and 2^n or 2^n+2^(n+1) */ n =ffs (opts->dict_size) -1 ; -if (opts->dict_size != (1 << n) && opts->dict_size != (1 << n) + - (1 << (n +1 ))) { +if (opts->dict_size <=0 || (opts->dict_size != (1 << n) && + opts->dict_size != (1 << n) + (1 << (n +1 )))) { err = -EIO ; goto out; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 51/457 scsi: block: Fix zones_cond out-of-bounds write on zone report
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: ZHOU Jiaxiang <[email protected]>
[ Upstream commit 7c431d61b69a3fd0784c20aa4cd0b8fb501b5653 ]
blk_revalidate_disk_zones() sizes the zones_cond array from the disk capacity and zone size, but the index used by blk_revalidate_zone_cond() comes from the device-driven report_zones() walk and is never checked against the array size. A device reporting more zones than fit the array makes blk_zone_set_cond() write out of bounds.
One way to reach this is a zone count exceeding 32 bits: both blk_revalidate_zone_args.nr_zones and struct zoned_disk_info.nr_zones are unsigned int, so a disk advertising more than UINT_MAX zones (e.g. 2^32 + 1024 zones of one 512-byte logical block) gets its zone count truncated to a small value, undersizing the array while the report walk keeps counting upward.
Check the index against the array size before storing the zone condition, and refuse to revalidate when the zone count does not fit 32 bits.
--- block/blk-zoned.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
block/blk-zoned.c +13 -2
@@ -2048,12 +2048,17 @@ static int disk_revalidate_zone_resources(struct gendisk *disk, struct blk_revalidate_zone_args *args) {struct queue_limits *lim = &disk->queue->limits; +unsigned long long nr_zones;unsigned int pool_size;int ret =0 ; args->disk = disk; - args->nr_zones = -DIV_ROUND_UP_ULL (get_capacity (disk), lim->chunk_sectors); + nr_zones =DIV_ROUND_UP_ULL (get_capacity (disk), lim->chunk_sectors); +if (nr_zones >UINT_MAX ) { +pr_warn ("%s: Too many zones (%llu)\n" , disk->disk_name, nr_zones); +return -EINVAL ; + } + args->nr_zones = nr_zones;/* Cached zone conditions: 1 byte per zone */ args->zones_cond =kzalloc (args->nr_zones,GFP_NOIO );
@@ -2161,6 +2166,12 @@ static int blk_revalidate_zone_cond(struct blk_zone *zone, unsigned int idx, {enum blk_zone_cond cond = zone->cond; +if (idx >= args->nr_zones) { +pr_warn ("%s: Zone report index %u exceeds zone count %u\n" , + args->disk->disk_name, idx, args->nr_zones); +return -EINVAL ; + } +/* Check that the zone condition is consistent with the zone type. */ switch (cond) {case BLK_ZONE_COND_NOT_WP :
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 52/457 scsi: sd_zbc: Reject disks with too many zones
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: ZHOU Jiaxiang <[email protected]>
[ Upstream commit b6ec0f79745967c751c85df373062c8d15e45fc4 ]
sd_zbc_read_zones() computes the number of zones with 64-bit arithmetic and stores the result in the unsigned int nr_zones field of struct zoned_disk_info, silently truncating counts that exceed 32 bits. The truncated count is later used to size per-zone resources, while the device may still report more zones than fit.
Moreover, sd_zbc_report_zones() counts the reported zones with a signed int zone_idx, which overflows past INT_MAX. Reject devices reporting more than INT_MAX zones at scan time; such a device is not realistic for any medium that exists today, and accepting it produces inconsistent zone bookkeeping.
--- drivers/scsi/sd_zbc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/scsi/sd_zbc.c +7 -1
@@ -589,7 +589,7 @@ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp)int sd_zbc_read_zones (struct scsi_disk *sdkp,struct queue_limits *lim,u8 buf[SD_BUF_SIZE ]) { -unsigned int nr_zones; +u64 nr_zones;u32 zone_blocks =0 ;int ret;
@@ -621,6 +621,12 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, struct queue_limits *lim, goto err; nr_zones =round_up (sdkp->capacity, zone_blocks) >>ilog2 (zone_blocks); +if (nr_zones >INT_MAX ) { +sd_printk (KERN_ERR , sdkp,"Too many zones (%llu)\n" , + nr_zones); + ret = -EINVAL ; + goto err; + } sdkp->early_zone_info.nr_zones = nr_zones; sdkp->early_zone_info.zone_blocks = zone_blocks;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 53/457 pinctrl: sunxi: A523: fix voltage withstand encoding
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andre Przywara <[email protected]>
[ Upstream commit ef56085dfd1df3a53ecce8a4ff440cf6d67f430d ]
The Allwinner A523 uses the same GPIO voltage "withstand" programming (setting the input level voltage thresholds) as the previous SoCs, but for some odd reason inverts the encoding of 1.8V vs. 3.3V.
Add a new bias voltage type to note this difference, and select it for the A523. At the same time also use the newer "CTL" version, which in addition allows to turn off the withstand programming for I/O voltages other than exact 1.8V or 3.3V (for instance for 2.5V sometimes used for Ethernet PHYs). The A523 has that enable register, but didn't use it so far.
This fixes eMMC and reportedly Ethernet operation on some A523 boards.
--- drivers/pinctrl/sunxi/pinctrl-sun55i-a523-r.c | 2 +- drivers/pinctrl/sunxi/pinctrl-sun55i-a523.c | 2 +- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 6 ++++++ drivers/pinctrl/sunxi/pinctrl-sunxi.h | 2 ++ 4 files changed, 10 insertions(+), 2 deletions(-)
drivers/pinctrl/sunxi/pinctrl-sun55i-a523-r.c +1 -1
@@ -26,7 +26,7 @@ static const u8 a523_r_irq_bank_muxes[SUNXI_PINCTRL_MAX_BANKS] =static struct sunxi_pinctrl_desc a523_r_pinctrl_data = { .irq_banks =ARRAY_SIZE (a523_r_irq_bank_map), .irq_bank_map = a523_r_irq_bank_map, - .io_bias_cfg_variant =BIAS_VOLTAGE_PIO_POW_MODE_SEL , + .io_bias_cfg_variant =BIAS_VOLTAGE_PIO_POW_MODE_CTL_INV , .pin_base =PL_BASE , };
drivers/pinctrl/sunxi/pinctrl-sun55i-a523.c +1 -1
@@ -26,7 +26,7 @@ static const u8 a523_irq_bank_muxes[SUNXI_PINCTRL_MAX_BANKS] =static struct sunxi_pinctrl_desc a523_pinctrl_data = { .irq_banks =ARRAY_SIZE (a523_irq_bank_map), .irq_bank_map = a523_irq_bank_map, - .io_bias_cfg_variant =BIAS_VOLTAGE_PIO_POW_MODE_SEL , + .io_bias_cfg_variant =BIAS_VOLTAGE_PIO_POW_MODE_CTL_INV , };static int a523_pinctrl_probe (struct platform_device *pdev)
drivers/pinctrl/sunxi/pinctrl-sunxi.c +6 -0
@@ -728,6 +728,7 @@ static int sunxi_pinctrl_set_io_bias_cfg(struct sunxi_pinctrl *pctl, {unsigned short bank;unsigned long flags; +bool inverted = false;u32 val, reg;int uV;
@@ -766,6 +767,9 @@ static int sunxi_pinctrl_set_io_bias_cfg(struct sunxi_pinctrl *pctl, reg &= ~IO_BIAS_MASK ;writel (reg | val, pctl->membase +sunxi_grp_config_reg (pin));return 0 ; +case BIAS_VOLTAGE_PIO_POW_MODE_CTL_INV : + inverted = true; + fallthrough;case BIAS_VOLTAGE_PIO_POW_MODE_CTL : val = uV >1800000 && uV <=2500000 ?BIT (bank) :0 ;
@@ -780,6 +784,8 @@ static int sunxi_pinctrl_set_io_bias_cfg(struct sunxi_pinctrl *pctl, fallthrough;case BIAS_VOLTAGE_PIO_POW_MODE_SEL : val = uV <=1800000 ?1 :0 ; +if (inverted) + val = !val;raw_spin_lock_irqsave (&pctl->lock, flags); reg =readl (pctl->membase + pctl->pow_mod_sel_offset);
drivers/pinctrl/sunxi/pinctrl-sunxi.h +2 -0
@@ -116,8 +116,10 @@ enum sunxi_desc_bias_voltage {* Bias voltage is set through PIO_POW_MOD_SEL_REG * and PIO_POW_MOD_CTL_REG register, as seen on * A100 and D1 SoC, for example. +* Some SoCs invert the encoding for 1.8V vs. 3.3V. */ BIAS_VOLTAGE_PIO_POW_MODE_CTL , + BIAS_VOLTAGE_PIO_POW_MODE_CTL_INV, }; struct sunxi_desc_function {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 54/457 Bluetooth: SMP: reject Security Request over BR/EDR
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christiano Amora <[email protected]>
[ Upstream commit f033482d76a9f18080c7a40c5f9c678bd7adc8f3 ]
Bose QC Ultra Headphones (dual-mode, same public address on both transports) occasionally send an SMP Security Request on the BR/EDR SMP fixed channel right after the ACL link is encrypted. The kernel handles it as if it were an LE link: smp_cmd_security_req() has no transport check, smp_ltk_encrypt() looks up an LTK with the ACL connection's dst_type, and hci_find_ltk() matches the peer's LE LTK because the LE public address type is stored as ADDR_LE_DEV_PUBLIC (0), the same value as BDADDR_BREDR. HCI_OP_LE_START_ENC is then issued on the ACL handle, the controller rejects it with Invalid HCI Command Parameters, and hci_cs_le_start_enc() disconnects the link with HCI_ERROR_AUTH_FAILURE. The headphones drop within a second of connecting, before any profile is up; a manual reconnect works.
btmon (MediaTek MT7922, kernel 7.0.12):
Quoted 1 line
HCI Event: Encryption Change (
0x08) plen 4
Status: Success (0x00)
Handle: 50 Address: BC:87:FA:47:73:5E (Bose Corporation)
Encryption: Enabled with AES-CCM (0x02)Quoted 1 line
ACL Data RX: Handle 50 flags
0x02dlen 6
BR/EDR SMP: Security Request (0x0b) len 1
Authentication requirement: No bonding, No MITM, SC (0x08)
< HCI Command: LE Start Encryption (0x08|0x0019) plen 28
Handle: 50 Address: BC:87:FA:47:73:5E (Bose Corporation)Quoted 1 line
HCI Event: Command Status (
0x0f) plen 4
LE Start Encryption (0x08|0x0019) ncmd 1
Status: Invalid HCI Command Parameters (0x12)
< HCI Command: Disconnect (0x01|0x0006) plen 3
Handle: 50 Address: BC:87:FA:47:73:5E (Bose Corporation)
Reason: Authentication Failure (0x05)SMP over BR/EDR is limited to cross-transport key derivation; the Security Request procedure (Core Specification Vol 3, Part H, Section 2.4.6, PDU in Section 3.6.7) has no BR/EDR counterpart. Reply with Pairing Failed / Command Not Supported on a non-LE link, before the PDU is parsed, and keep the connection. The reply is sent directly rather than through smp_failure(): rejecting a command on the wrong transport is not an authentication failure, and MGMT_EV_AUTH_FAILED would make bluetoothd disconnect the device.
Tested on the affected host (kernel 7.0.12, MediaTek MT7922, Bose QC Ultra) with the patched module built out of tree: 7 days and 49 reconnects without a drop, against 2 drops in the 3 days before the patch. Every disconnect in that week had a userspace or remote reason.
--- net/bluetooth/smp.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
net/bluetooth/smp.c +17 -0
@@ -2268,6 +2268,23 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)bt_dev_dbg (hdev,"conn %p" , conn); +/* SMP over BR/EDR only covers cross-transport key derivation; the +* Security Request procedure has no BR/EDR counterpart. Reject it +* here, otherwise smp_ltk_encrypt() finds the peer's LE LTK +* (ADDR_LE_DEV_PUBLIC and BDADDR_BREDR are both 0) and issues +* HCI_OP_LE_START_ENC on the ACL handle, which the controller +* rejects and hci_cs_le_start_enc() turns into a disconnect. Reply +* without smp_failure(): this is not an authentication failure, and +* MGMT_EV_AUTH_FAILED would make bluetoothd drop the device. +*/ +if (hcon->type !=LE_LINK ) { +u8 reason =SMP_CMD_NOTSUPP ; + +smp_send_cmd (conn,SMP_CMD_PAIRING_FAIL ,sizeof (reason), + &reason); +return 0 ; + } +if (skb->len <sizeof (*rp))return SMP_INVALID_PARAMS ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 55/457 Bluetooth: btnxpuart: Fix skb leak in nxp_process_fw_dump()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zijun Hu <[email protected]>
[ Upstream commit f2bbb36426581045a8bf7793da5419b9375e4348 ]
When CONFIG_DEV_COREDUMP=n, hci_devcd_append() returns -EOPNOTSUPP without freeing its skb argument. This leaks the cloned skb and also prevents nxp_set_ind_reset() from being called to perform recovery.
Fix by guarding the hci_devcd_append(hdev, skb_clone(skb, GFP_ATOMIC)) call with IS_ENABLED(CONFIG_DEV_COREDUMP).
--- drivers/bluetooth/btnxpuart.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/bluetooth/btnxpuart.c +5 -3
@@ -1397,9 +1397,11 @@ static int nxp_process_fw_dump(struct hci_dev *hdev, struct sk_buff *skb) msecs_to_jiffies(20000)); } - err =hci_devcd_append (hdev,skb_clone (skb,GFP_ATOMIC )); -if (err <0 ) - goto free_skb; +if (IS_ENABLED (CONFIG_DEV_COREDUMP )) { + err =hci_devcd_append (hdev,skb_clone (skb,GFP_ATOMIC )); +if (err <0 ) + goto free_skb; + }if (buf_len ==0 ) {bt_dev_warn (hdev,"==== FW dump complete ===" );
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 56/457 Bluetooth: mgmt: Dequeue pending mesh_send_sync entries on cancel
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lee Jones <[email protected]>
[ Upstream commit 71af682ba4692c2ed9ace4c3d4ca462ae368c029 ]
In send_cancel(), pending mesh_tx objects are removed from the hdev->mesh_pending list and freed via mesh_send_complete(). However, if a mesh transmission was already queued onto hdev->cmd_sync_work_list via mesh_next(), the queued entry retains a raw pointer to mesh_tx.
When hci_cmd_sync_work later processes the entry, it attempts to execute mesh_send_sync and its destroy callback mesh_send_start_complete using the already freed mesh_tx pointer, leading to a use-after-free.
Fix this by invoking hci_cmd_sync_dequeue() for mesh_send_sync on the target mesh_tx before completing it. If the entry is found and dequeued, its destroy callback will complete and free the object; otherwise, mesh_send_complete() is called directly.
Additionally, ensure the transmission queue advances after cancellation or errors. In mesh_send_start_complete(), call mesh_next() on error unless err is -ECANCELED, because hci_cmd_sync_dequeue() holds hdev->cmd_sync_work_lock and calling mesh_next() synchronously would deadlock. Instead, advance the queue in send_cancel() once the lock is released and if no transmission is in progress.
--- net/bluetooth/mgmt.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
net/bluetooth/mgmt.c +15 -4
@@ -2310,6 +2310,8 @@ static void mesh_send_start_complete(struct hci_dev *hdev, void *data, int err)hci_dev_clear_flag (hdev,HCI_MESH_SENDING );/* Send Complete Error Code for handle */ mesh_send_complete (hdev, mesh_tx, false); +if (err != -ECANCELED ) +mesh_next (hdev,NULL ,0 );return ; }
@@ -2419,19 +2421,28 @@ static int send_cancel(struct hci_dev *hdev, void *data)do { mesh_tx =mgmt_mesh_next (hdev, cmd->sk); -if (mesh_tx) -mesh_send_complete (hdev, mesh_tx, false); +if (mesh_tx) { +if (!hci_cmd_sync_dequeue (hdev, mesh_send_sync, + mesh_tx,NULL )) +mesh_send_complete (hdev, mesh_tx, false); + } }while (mesh_tx); }else { mesh_tx =mgmt_mesh_find (hdev, cancel->handle); -if (mesh_tx && mesh_tx->sk == cmd->sk) -mesh_send_complete (hdev, mesh_tx, false); +if (mesh_tx && mesh_tx->sk == cmd->sk) { +if (!hci_cmd_sync_dequeue (hdev, mesh_send_sync, + mesh_tx,NULL )) +mesh_send_complete (hdev, mesh_tx, false); + } }mgmt_cmd_complete (cmd->sk, hdev->id,MGMT_OP_MESH_SEND_CANCEL ,0 ,NULL ,0 ); +if (!hci_dev_test_flag (hdev,HCI_MESH_SENDING )) +mesh_next (hdev,NULL ,0 ); +return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 57/457 selftests: cgroup: give the O_TMPFILE open in get_temp_fd() a mode
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eva Kurchatova <[email protected]>
[ Upstream commit c774ec8f0a5d02a06d34c27f5a7de7e333b91265 ]
O_TMPFILE, like O_CREAT, needs the third argument. Without it glibc refuses the call at compile time as soon as fortification is on:
In function 'open',
inlined from 'get_temp_fd' at test_memcontrol.c:33:9:
/usr/include/bits/fcntl2.h:52:11: error: call to '__open_missing_mode'
declared with attribute error: open with O_CREAT or O_TMPFILE in second argument needs 3 arguments
The fortify checks take effect only once the compiler optimises, and cgroup/Makefile builds with "-Wall -pthread" alone, so this goes unnoticed in a plain build. Building the tests with the flags distributions commonly use, -O2 -D_FORTIFY_SOURCE=3, loses test_memcontrol entirely.
--- tools/testing/selftests/cgroup/test_memcontrol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/cgroup/test_memcontrol.c +1 -1
@@ -30,7 +30,7 @@ static int page_size;int get_temp_fd (void ) { -return open ("." ,O_TMPFILE |O_RDWR |O_EXCL ); +return open ("." ,O_TMPFILE |O_RDWR |O_EXCL ,0600 ); }int alloc_pagecache (int fd,size_t size)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 58/457 scsi: megaraid_sas: Protect megasas_get_ctrl_info() in megasas_resume()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
[ Upstream commit 42d1221d321e55afc7bba9109a77aaf5a817c8a3 ]
Protect the megasas_get_ctrl_info() call in megasas_resume() with instance->reset_mutex using scoped_guard().
megasas_get_ctrl_info() may release and reacquire instance->reset_mutex. Hence, calling this function without holding instance->reset_mutex is not safe.
--- drivers/scsi/megaraid/megaraid_sas_base.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/scsi/megaraid/megaraid_sas_base.c +3 -1
@@ -7886,7 +7886,9 @@ megasas_resume(struct device *dev) goto fail_init_mfi; } -if (megasas_get_ctrl_info (instance) !=DCMD_SUCCESS ) +scoped_guard (mutex, &instance->reset_mutex) + rval = megasas_get_ctrl_info(instance); +if (rval !=DCMD_SUCCESS ) goto fail_init_mfi; tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 59/457 s390/pci/docs: Fix sriov_numvfs attribute name
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <[email protected]>
[ Upstream commit 4525a911049543c23885a540a788d13be318a486 ]
The attribute is sriov_numvfs (drivers/pci/iov.c); the document names it sriov_numvf, which does not exist.
Use sriov_numvfs.
--- Documentation/arch/s390/pci.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Documentation/arch/s390/pci.rst +1 -1
@@ -67,7 +67,7 @@ Entries specific to zPCI functions and entries that hold zPCI information. A physical function that currently supports a virtual function cannot be powered off until all virtual functions are removed with: - echo 0 > /sys/bus/pci/devices/DDDD:BB:dd.f/sriov_numvf + echo 0 > /sys/bus/pci/devices/DDDD:BB:dd.f/sriov_numvfs * /sys/bus/pci/devices/DDDD:BB:dd.f/:
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 60/457 s390/cio: Fix cio_update_schib() to not cache invalid schib
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vineeth Vijayan <[email protected]>
[ Upstream commit 29d9e5835d89223aa913dcf7b942cc1c148bdd25 ]
When pmcw.dnv is 0, the contents of all SCHIB fields are unpredictable. Zero sch->schib in that case to prevent subsequent code from making decisions based on unpredictable data.
--- drivers/s390/cio/cio.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/s390/cio/cio.c +7 -4
@@ -453,7 +453,8 @@ EXPORT_SYMBOL_GPL(cio_commit_config);/** * cio_update_schib - Perform stsch and update schib if subchannel is valid. * @sch: subchannel on which to perform stsch -* Return zero on success, -ENODEV otherwise. +* Return zero on success, -ENODEV if the subchannel is not operational, +* -EACCES if the subchannel has no valid device. */ int cio_update_schib (struct subchannel *sch) {
@@ -462,10 +463,12 @@ int cio_update_schib(struct subchannel *sch)if (stsch (sch->schid, &schib))return -ENODEV ; -memcpy (&sch->schib, &schib,sizeof (schib)); - -if (!css_sch_is_valid (&schib)) +if (!css_sch_is_valid (&schib)) { +memset (&sch->schib,0 ,sizeof (sch->schib));return -EACCES ; + } + +memcpy (&sch->schib, &schib,sizeof (schib));return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 61/457 s390/cio: Check pmcw.dnv before pmcw.ena in I/O entry points
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vineeth Vijayan <[email protected]>
[ Upstream commit f6f2985eabdb2bfdc82ce90a1ea3ec53ba795f34 ]
The device number valid (dnv) bit in the PMCW must be checked before acting on any other PMCW fields for IO-type subchannels. A subchannel with dnv=0 has no valid device number associated, making it meaningless to evaluate the enabled (ena) state or issue any I/O instruction against it.
--- drivers/s390/cio/device_ops.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/s390/cio/device_ops.c +12 -0
@@ -142,6 +142,8 @@ int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)if (!cdev || !cdev->dev.parent)return -ENODEV ; sch =to_subchannel (cdev->dev.parent); +if (!sch->schib.pmcw.dnv) +return -ENODEV ;if (!sch->schib.pmcw.ena)return -EINVAL ;if (cdev->private->state ==DEV_STATE_NOT_OPER )
@@ -198,6 +200,8 @@ int ccw_device_start_timeout_key(struct ccw_device *cdev, struct ccw1 *cpa,if (!cdev || !cdev->dev.parent)return -ENODEV ; sch =to_subchannel (cdev->dev.parent); +if (!sch->schib.pmcw.dnv) +return -ENODEV ;if (!sch->schib.pmcw.ena)return -EINVAL ;if (cdev->private->state ==DEV_STATE_NOT_OPER )
@@ -379,6 +383,8 @@ int ccw_device_halt(struct ccw_device *cdev, unsigned long intparm)if (!cdev || !cdev->dev.parent)return -ENODEV ; sch =to_subchannel (cdev->dev.parent); +if (!sch->schib.pmcw.dnv) +return -ENODEV ;if (!sch->schib.pmcw.ena)return -EINVAL ;if (cdev->private->state ==DEV_STATE_NOT_OPER )
@@ -413,6 +419,8 @@ int ccw_device_resume(struct ccw_device *cdev)if (!cdev || !cdev->dev.parent)return -ENODEV ; sch =to_subchannel (cdev->dev.parent); +if (!sch->schib.pmcw.dnv) +return -ENODEV ;if (!sch->schib.pmcw.ena)return -EINVAL ;if (cdev->private->state ==DEV_STATE_NOT_OPER )
@@ -548,6 +556,8 @@ int ccw_device_tm_start_timeout_key(struct ccw_device *cdev, struct tcw *tcw,int rc; sch =to_subchannel (cdev->dev.parent); +if (!sch->schib.pmcw.dnv) +return -ENODEV ;if (!sch->schib.pmcw.ena)return -EINVAL ;if (cdev->private->state ==DEV_STATE_VERIFY ) {
@@ -694,6 +704,8 @@ int ccw_device_tm_intrg(struct ccw_device *cdev) {struct subchannel *sch =to_subchannel (cdev->dev.parent); +if (!sch->schib.pmcw.dnv) +return -ENODEV ;if (!sch->schib.pmcw.ena)return -EINVAL ;if (cdev->private->state !=DEV_STATE_ONLINE )
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 62/457 s390/cio: Guard PMCW field accesses with dnv check
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vineeth Vijayan <[email protected]>
[ Upstream commit 9590f4d83880dfb5a81906e48e72779248fbe8f0 ]
When PMCW.DNV is 0, no I/O device is associated with the subchannel. However, several code paths access PMCW fields directly from the cached sch->schib without first invoking the update helper. Add explicit DNV validation before accessing PMCW fields from the cached SCHIB to avoid using invalid data.
--- drivers/s390/cio/chp.c | 3 +++ drivers/s390/cio/device.c | 9 +++++---- drivers/s390/cio/device_fsm.c | 3 +++ drivers/s390/cio/device_ops.c | 9 +++++++++ drivers/s390/cio/vfio_ccw_fsm.c | 2 +- 5 files changed, 21 insertions(+), 5 deletions(-)
drivers/s390/cio/chp.c +3 -0
@@ -78,6 +78,9 @@ u8 chp_get_sch_opm(struct subchannel *sch)int opm;int i; +if (!sch->schib.pmcw.dnv) +return 0 ; + opm =0 ;chp_id_init (&chpid);for (i =0 ; i <8 ; i++) {
drivers/s390/cio/device.c +5 -4
@@ -922,7 +922,7 @@ static int ccw_device_move_to_sch(struct ccw_device *cdev,if (!sch_is_pseudo_sch (old_sch)) {spin_lock_irq (&old_sch->lock); - old_enabled = old_sch->schib.pmcw.ena; + old_enabled = old_sch->schib.pmcw.dnv && old_sch->schib.pmcw.ena; rc =0 ;if (old_enabled) rc =cio_disable_subchannel (old_sch);
@@ -941,7 +941,7 @@ static int ccw_device_move_to_sch(struct ccw_device *cdev,CIO_MSG_EVENT (0 ,"device_move(0.%x.%04x,0.%x.%04x)=%d\n" , cdev->private->dev_id.ssid, cdev->private->dev_id.devno, sch->schid.ssid, - sch->schib.pmcw.dev, rc); + sch->schid.sch_no, rc);if (old_enabled) {/* Try to re-enable the old subchannel. */ spin_lock_irq (&old_sch->lock);
@@ -1207,7 +1207,7 @@ static void io_subchannel_quiesce(struct subchannel *sch) cdev =sch_get_cdev (sch);if (cio_is_console (sch->schid)) goto out_unlock; -if (!sch->schib.pmcw.ena) +if (!sch->schib.pmcw.dnv || !sch->schib.pmcw.ena) goto out_unlock; ret =cio_disable_subchannel (sch);if (ret != -EBUSY )
@@ -1254,7 +1254,8 @@ static int recovery_check(struct device *dev, void *data)switch (cdev->private->state) {case DEV_STATE_ONLINE : sch =to_subchannel (cdev->dev.parent); -if ((sch->schib.pmcw.pam & sch->opm) == sch->vpm) +if (sch->schib.pmcw.dnv && + (sch->schib.pmcw.pam & sch->opm) == sch->vpm)break ; fallthrough;case DEV_STATE_DISCONNECTED :
drivers/s390/cio/device_fsm.c +3 -0
@@ -170,6 +170,9 @@ __recover_lost_chpids(struct subchannel *sch, int old_lpm)int mask, i;struct chp_id chpid; +if (!sch->schib.pmcw.dnv) +return ; +chp_id_init (&chpid);for (i =0 ; i<8 ; i++) { mask =0x80 >> i;
drivers/s390/cio/device_ops.c +9 -0
@@ -490,6 +490,8 @@ struct channel_path_desc_fmt0 *ccw_device_get_chp_desc(struct ccw_device *cdev,struct chp_id chpid; sch =to_subchannel (cdev->dev.parent); +if (!sch->schib.pmcw.dnv) +return NULL ;chp_id_init (&chpid); chpid.id = sch->schib.pmcw.chpid[chp_idx];return chp_get_chp_desc (chpid);
@@ -510,6 +512,8 @@ u8 *ccw_device_get_util_str(struct ccw_device *cdev, int chp_idx)struct chp_id chpid;u8 *util_str; +if (!sch->schib.pmcw.dnv) +return NULL ;chp_id_init (&chpid); chpid.id = sch->schib.pmcw.chpid[chp_idx]; chp =chpid_to_chp (chpid);
@@ -662,6 +666,9 @@ int ccw_device_get_mdc(struct ccw_device *cdev, u8 mask)struct chp_id chpid;int mdc =0 , i; +if (!sch->schib.pmcw.dnv) +return 0 ; +/* Adjust requested path mask to excluded varied off paths. */ if (mask) mask &= sch->lpm;
@@ -798,6 +805,8 @@ int ccw_device_get_chpid(struct ccw_device *cdev, int chp_idx, u8 *chpid)if ((chp_idx <0 ) || (chp_idx >7 ))return -EINVAL ; +if (!sch->schib.pmcw.dnv) +return -ENODEV ; mask =0x80 >> chp_idx;if (!(sch->schib.pmcw.pim & mask))return -ENODEV ;
drivers/s390/cio/vfio_ccw_fsm.c +1 -1
@@ -399,7 +399,7 @@ static void fsm_close(struct vfio_ccw_private *private,spin_lock_irq (&sch->lock); -if (!sch->schib.pmcw.ena) +if (!sch->schib.pmcw.dnv || !sch->schib.pmcw.ena) goto err_unlock; ret =cio_disable_subchannel (sch);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 63/457 netfs: Fix netfs_read_gaps() to use separate sink folios
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
[ Upstream commit fc3ae66514ca5e87251f79044236e3e8babd24a3 ]
Fix netfs_read_gaps() to use separate folios rather than re-using a single sink folio to discard the unwanted data so that cifs checksum checking sees all the data that was fetched.
--- fs/netfs/buffered_read.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-)
fs/netfs/buffered_read.c +19 -15
@@ -482,15 +482,14 @@ static int netfs_read_gaps(struct file *file, struct folio *folio)struct netfs_group *group =netfs_folio_group (folio);struct netfs_folio *finfo =netfs_folio_info (folio);struct netfs_inode *ctx =netfs_inode (mapping->host); -struct folio *sink =NULL ; -struct bio_vec *bvec; +struct bio_vec *bvec =NULL ;unsigned int from = finfo->dirty_offset;unsigned int to = from + finfo->dirty_len; -unsigned int off =0 , i =0 ; +unsigned int off =0 ;size_t flen =folio_size (folio);size_t nr_bvec = flen /PAGE_SIZE +2 ;size_t part; -int ret; +int ret, i =0 , sink_from =-1 , sink_to =-1 ;_enter ("%lx" , folio->index);
@@ -515,24 +514,23 @@ static int netfs_read_gaps(struct file *file, struct folio *folio)if (!bvec) goto discard; - sink =folio_alloc (GFP_KERNEL ,0 ); -if (!sink) { -kfree (bvec); - goto discard; - } -trace_netfs_folio (folio, netfs_folio_trace_read_gaps); - rreq->direct_bv = bvec; - rreq->direct_bv_count = nr_bvec;if (from >0 ) {bvec_set_folio (&bvec[i++], folio, from,0 ); off = from; } + sink_from = i;while (off < to) { +struct folio *sink =folio_alloc (GFP_KERNEL ,0 ); + +if (!sink) + goto discard; part =min_t (size_t, to - off,PAGE_SIZE ); -bvec_set_folio (&bvec[i++], sink, part,0 ); +bvec_set_folio (&bvec[i], sink, part,0 ); off += part; + sink_to = i; + i++; }if (to < flen)bvec_set_folio (&bvec[i++], folio, flen - to, to);
@@ -553,8 +551,10 @@ static int netfs_read_gaps(struct file *file, struct folio *folio)folio_mark_uptodate (folio); } -if (sink) -folio_put (sink); +if (sink_to >=0 ) +for (; sink_from <= sink_to; sink_from++) +folio_put (bvec_folio (&bvec[sink_from])); +kfree (bvec);folio_unlock (folio);netfs_put_request (rreq, netfs_rreq_trace_put_return);return ret <0 ? ret :0 ;
@@ -563,6 +563,10 @@ static int netfs_read_gaps(struct file *file, struct folio *folio)netfs_put_failed_request (rreq); alloc_error:folio_unlock (folio); +if (sink_to >=0 ) +for (; sink_from <= sink_to; sink_from++) +folio_put (bvec_folio (&bvec[sink_from])); +kfree (bvec);return ret; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 64/457 netfs, afs: Fix symlink reading
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
[ Upstream commit c51e89c5b5db3e1927738fad7cd18b66dde68aed ]
Fix the reading of symlinks from the cache in afs by making netfslib trim the amount read down to i_size. The problem is that afs sets the size of the iterator to the size of the buffer (PAGE_SIZE) so that the cache can round the read size up to the cache's DIO size.
Note that this also impacts the reading of AFS mountpoints as they're just stored as symlinks with an odd file mode.
--- fs/netfs/read_collect.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/netfs/read_collect.c +5 -0
@@ -435,6 +435,11 @@ static void netfs_rreq_assess_single(struct netfs_io_request *rreq)netfs_single_mark_inode_dirty (rreq->inode); } +/* To do DIO, the cache has to round the size up, so we need to undo +* the rounding. +*/ + rreq->transferred =min (rreq->transferred, rreq->i_size); +if (rreq->iocb) { rreq->iocb->ki_pos += rreq->transferred;if (rreq->iocb->ki_complete) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 65/457 fs: avoid repeated scans in evict_inodes()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Julian Sun <[email protected]>
[ Upstream commit 7459c021874246c196f397686e100702f059b9e7 ]
We observed hung tasks when users attempted to unmount a filesystem after its disk had been removed while still in use. During device removal, fs_bdev_mark_dead() calls evict_inodes() while holding s_umount.
Each time evict_inodes() drops s_inode_list_lock to reschedule, it restarts the walk from the head of s_inodes. With many referenced inodes at the head of the list, these restarts repeatedly scan the same inodes without reclaiming them. This can keep s_umount held for a long time, blocking concurrent umount attempts and triggering hung-task reports.
Keep the current inode, already marked I_FREEING, out of the disposal batch until s_inode_list_lock is reacquired. Resume the walk from this inode and dispose of it in a later batch or at the end of the walk.
The zero-refcount and state checks under i_lock allow this walker to claim the inode by setting I_FREEING and removing it from the LRU. Other reclaimers skip the inode, leaving this walker responsible for eviction. Only evict() removes it from s_inodes, so keeping it out of the disposal batch ensures that it remains on the list while the lock is dropped. After reacquiring the lock, reading its current next pointer accounts for concurrent removal of following inodes.
The existing inode lifetime rules prohibit acquiring a reference to an inode marked I_FREEING or I_WILL_FREE. __iget() requires its caller to hold i_lock and establish that taking a reference is valid. Inode lookup and igrab() check these flags under i_lock when acquiring a reference from zero. ihold() requires an existing reference, which would keep i_count nonzero and prevent this walker from claiming the inode. These rules already allow iput_final() and the inode shrinker to release i_lock after setting I_FREEING and before eviction completes.
A temporary __iget() reference would also keep the inode on the list, but its release must preserve last-reference handling. Another user can acquire a reference, update lazy timestamps and drop its reference while the pin is held. If the pin becomes the last reference, dropping it with atomic_dec_and_test() and evicting directly bypasses iput()'s lazytime handling and can lose those timestamp updates.
Releasing the pin with iput() preserves that handling, but does not guarantee eviction. fs_bdev_mark_dead() runs with SB_ACTIVE set, so iput() may retain the inode in cache, whereas evict_inodes() must evict eligible zero-reference inodes. The inode may also have been freed when iput() returns, so the walker cannot then use it to force eviction. Using I_FREEING preserves the existing eviction behavior without introducing an additional last-reference transition.
The xfstests auto group passed on ext4 and XFS with known unrelated failures excluded. No new issues were observed, and the previously reproducible hung task no longer occurs with this patch.
--- fs/inode.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
fs/inode.c +5 -6
@@ -883,7 +883,6 @@ void evict_inodes(struct super_block *sb)struct inode *inode;LIST_HEAD (dispose); -again:spin_lock (&sb->s_inode_list_lock);list_for_each_entry (inode, &sb->s_inodes, i_sb_list) {if (icount_read_once (inode))
@@ -902,19 +901,19 @@ void evict_inodes(struct super_block *sb)inode_state_set (inode,I_FREEING );inode_lru_list_del (inode);spin_unlock (&inode->i_lock); -list_add (&inode->i_lru, &dispose);/* -* We can have a ton of inodes to evict at unmount time given -* enough memory, check to see if we need to go to sleep for a -* bit so we don't livelock. +* Keep this inode out of dispose so it stays on s_inodes while +* the list lock is dropped. I_FREEING prevents new references +* and leaves eviction to us, so we can resume the walk from it. */ if (need_resched ()) {spin_unlock (&sb->s_inode_list_lock);cond_resched ();dispose_list (&dispose); - goto again; +spin_lock (&sb->s_inode_list_lock); } +list_add (&inode->i_lru, &dispose); }spin_unlock (&sb->s_inode_list_lock);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 66/457 xsk: Use a 32-bit compare in xsk_map_gen_lookup
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhiling Zou <[email protected]>
[ Upstream commit 70504de0bb627848667207bec7ccfd647deb8814 ]
xsk_map_gen_lookup() loads a u32 key and compares it with max_entries using BPF_JMP_IMM. BPF immediates are sign-extended to 64 bits, so a max_entries value of 0x80000000 or higher becomes a threshold larger than every zero-extended 32-bit key. An out-of-range index then skips the bounds check and the generated lookup reads past xsk_map[].
Compare with BPF_JMP32_IMM so the check stays in 32-bit unsigned range.
--- net/xdp/xskmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/xdp/xskmap.c +1 -1
@@ -124,7 +124,7 @@ static int xsk_map_gen_lookup(struct bpf_map *map, struct bpf_insn *insn_buf)struct bpf_insn *insn = insn_buf; *insn++ =BPF_LDX_MEM (BPF_W , ret, index,0 ); - *insn++ =BPF_JMP_IMM (BPF_JGE , ret, map->max_entries,5 ); + *insn++ =BPF_JMP32_IMM (BPF_JGE , ret, map->max_entries,5 ); *insn++ =BPF_ALU64_IMM (BPF_LSH , ret,ilog2 (sizeof (struct xsk_sock *))); *insn++ =BPF_ALU64_IMM (BPF_ADD , mp, offsetof(struct xsk_map , xsk_map)); *insn++ =BPF_ALU64_REG (BPF_ADD , ret, mp);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 67/457 bpf: Skip unsettled links in link iterator
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <[email protected]>
[ Upstream commit 50e80e2bb5e2be8515205b9c496b9640ddefa434 ]
bpf_link_prime() inserts a link into link_idr before anon_inode_getfile() succeeds and before bpf_link_settle() publishes the ID in link->id. bpf_link_by_id() treats such an ID-zero link as unsettled, but the link iterator takes a reference without this check.
If anon_inode_getfile() then fails, the creator removes the ID and frees its still-private link directly. The iterator is left with a dangling reference and its next bpf_link_put() accesses freed memory.
Treat ID-zero entries as transient in bpf_link_get_curr_or_next(), just as bpf_link_by_id() does.
BUG: KASAN: slab-use-after-free in bpf_link_put Write of size 8 by task exp/384 Call Trace: bpf_link_put kernel/bpf/syscall.c:3372 bpf_link_seq_next kernel/bpf/link_iter.c:33 bpf_seq_read kernel/bpf/bpf_iter.c:158 vfs_read fs/read_write.c:572 ksys_read fs/read_write.c:716 do_syscall_64 arch/x86/entry/syscall_64.c:84 entry_SYSCALL_64_after_hwframe arch/x86/entry/entry_64.S:121 Kernel panic - not syncing: KASAN: panic_on_warn set ...
--- kernel/bpf/syscall.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
kernel/bpf/syscall.c +4 -1
@@ -6106,7 +6106,10 @@ struct bpf_link *bpf_link_get_curr_or_next(u32 *id) again: link =idr_get_next (&link_idr, id);if (link) { - link =bpf_link_inc_not_zero (link); +if (link->id) + link =bpf_link_inc_not_zero (link); +else + link =ERR_PTR (-EAGAIN );if (IS_ERR (link)) { (*id)++; goto again;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 68/457 eth: fbnic: Fix payload page pool error cleanup
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Björn Töpel <[email protected]>
[ Upstream commit 8e0b235bd918d06f54ba8fddd2c3ddc36ca59c15 ]
The payload page pool pointer contains an error pointer when its allocation fails. The cleanup path passes that error pointer to page_pool_destroy() instead of destroying the header page pool. This can dereference the error pointer and leave the header page pool allocated.
Destroy the header page pool instead.
--- drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/meta/fbnic/fbnic_txrx.c +1 -1
@@ -1622,7 +1622,7 @@ fbnic_alloc_qt_page_pools(struct fbnic_net *fbn, struct fbnic_q_triad *qt,return 0 ; err_destroy_sub0: -page_pool_destroy (pp); +page_pool_destroy (qt->sub0.page_pool);return PTR_ERR (pp); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 69/457 net/sched: cls_u32: fix manual hash table handle IDR aliasing
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <[email protected]>
[ Upstream commit 0a5f5d9e94dead312d32c366b917c64e552b72f7 ]
A u32 hash table created with an explicit handle ('tc filter add ... handle 801: u32 divisor N') keys its IDR entry on the raw handle, while the destroy paths free it under handle2id(handle). The two key domains disagree for handles in the 0x800..0xFFF htid range:handle2id() folds them back into the auto-allocated id space (1..0x7FF).
A manual table therefore leaves its raw-keyed IDR entry unreachable on delete (a permanent leak), and its delete can drop the idr entry of an unrelated live auto table. A later auto allocation can then hand out a handle that aliases the live manual table; u32_lookup_ht() first-match routes lookups and TCA_U32_LINK for that htid to the wrong table.
Key the divisor-path alloc on handle2id(handle) so allocation and removal share one key domain. A manual handle that maps onto an id already in use is rejected with -ENOSPC, and auto allocation skips ids held by live manual tables.
Conditions to recreate:
ip link add test0 type dummy
tc qdisc add dev test0 clsact
tc filter add dev test0 ingress protocol ip pref 1 \
handle 801: u32 divisor 16 tc filter add dev test0 ingress protocol ip pref 2 u32 divisor 16 tc -d filter show dev test0 ingress | grep 'fh 801:' # unpatched: two live tables with handle 0x80100000 (the pref 2 root # hnode is auto-allocated id 1); patched: the auto hnode takes id 2.
Also tested with a poc with a live u32 table on the block, add/delete a manual table 'handle 901: u32 divisor 1' twice; unpatched, the re-add fails with -ENOSPC because the raw key leaked on the first delete.
--- net/sched/cls_u32.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
net/sched/cls_u32.c +10 -2
@@ -1003,8 +1003,16 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,return -ENOMEM ; } }else { - err =idr_alloc_u32 (&tp_c->handle_idr, ht, &handle, - handle,GFP_KERNEL ); +/* The IDR is keyed on the mapped id, and that is +* what the destroy paths remove. Ask for it here, +* so a manual handle colliding with the +* auto-allocated id space is rejected (-ENOSPC) +* instead of aliasing a future auto id. +*/ +u32 id =handle2id (handle); + + err =idr_alloc_u32 (&tp_c->handle_idr, ht, &id, id, +GFP_KERNEL );if (err) {kfree (ht);return err;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 70/457 net: pcs: rzn1-miic: Fix config array initialization
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kyle Hendry <[email protected]>
[ Upstream commit daf677c2c6449011ee695d55b48b5b2977a36f88 ]
Fix memset parameters to initialize the entire DT value array
--- drivers/net/pcs/pcs-rzn1-miic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/pcs/pcs-rzn1-miic.c +2 -1
@@ -683,7 +683,8 @@ static int miic_parse_dt(struct miic *miic, u32 *mode_cfg)if (!dt_val)return -ENOMEM ; -memset (dt_val,MIIC_MODCTRL_CONF_NONE ,sizeof (*dt_val)); +memset (dt_val,MIIC_MODCTRL_CONF_NONE , +sizeof (*dt_val) * miic->of_data->conf_conv_count);if (of_property_read_u32 (np,"renesas,miic-switch-portin" , &conf) ==0 ) dt_val[0 ] = conf;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 71/457 octeontx2-af: use seq_file for rsrc_alloc debugfs
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heyang Tan <[email protected]>
[ Upstream commit 39c6580765dad6477fb2637f6f616e0d276aae65 ]
The rsrc_alloc debugfs reader writes rows directly to userspace without respecting the caller's read count. It also uses the current row length as the userspace stride, which can corrupt output when rows have different widths.
Use seq_file to handle userspace buffer sizes, offsets, and partial reads, and write output columns directly to the seq_file buffer.
--- .../marvell/octeontx2/af/rvu_debugfs.c | 104 ++++++------------ 1 file changed, 33 insertions(+), 71 deletions(-)
drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c +33 -71
@@ -714,110 +714,72 @@ static int get_max_column_width(struct rvu *rvu) }/* Dumps current provisioning status of all RVU block LFs */ -static ssize_t rvu_dbg_rsrc_attach_status (struct file *filp, -char __user *buffer, -size_t count,loff_t *ppos) +static int rvu_dbg_rsrc_attach_status (struct seq_file *filp,void *unused) { -int index, off =0 , flag =0 , len =0 , i =0 ; -struct rvu *rvu = filp->private_data; -int bytes_not_copied =0 ; +struct rvu *rvu = filp->private; +int index, pf, vf, pcifunc;struct rvu_block block; -int pf, vf, pcifunc; -int buf_size =2048 ;int lf_str_size;char *lfs; -char *buf; - -/* don't allow partial reads */ -if (*ppos !=0 ) -return 0 ; - - buf =kzalloc (buf_size,GFP_KERNEL ); -if (!buf) -return -ENOMEM ; -/* Get the maximum width of a column */ lf_str_size =get_max_column_width (rvu); +if (lf_str_size <0 ) +return lf_str_size; lfs =kzalloc (lf_str_size,GFP_KERNEL ); -if (!lfs) { -kfree (buf); +if (!lfs)return -ENOMEM ; - } - off +=scnprintf (&buf[off], buf_size -1 - off,"%-*s" , lf_str_size, -"pcifunc" ); -for (index =0 ; index <BLK_COUNT ; index++) -if (strlen (rvu->hw->block[index].name)) { - off +=scnprintf (&buf[off], buf_size -1 - off, -"%-*s" , lf_str_size, - rvu->hw->block[index].name); - } - off +=scnprintf (&buf[off], buf_size -1 - off,"\n" ); - bytes_not_copied =copy_to_user (buffer + (i * off), buf, off); -if (bytes_not_copied) - goto out; +seq_printf (filp,"%-*s" , lf_str_size,"pcifunc" ); +for (index =0 ; index <BLK_COUNT ; index++) +if (strlen (rvu->hw->block[index].name)) +seq_printf (filp,"%-*s" , lf_str_size, + rvu->hw->block[index].name); - i++; - *ppos += off; +seq_putc (filp,'\n' );for (pf =0 ; pf < rvu->hw->total_pfs; pf++) {for (vf =0 ; vf <= rvu->hw->total_vfs; vf++) { - off =0 ; - flag =0 ; pcifunc =rvu_make_pcifunc (rvu->pdev, pf, vf);if (!pcifunc)continue ; -if (vf) { +for (index =0 ; index <BLK_COUNT ; index++) { + block = rvu->hw->block[index]; +if (!strlen (block.name)) +continue ; + lfs[0 ] ='\0' ; +get_lf_str_list (&block, pcifunc, lfs); +if (strlen (lfs)) +break ; + } +if (index ==BLK_COUNT ) +continue ; + +if (vf)sprintf (lfs,"PF%d:VF%d" , pf, vf -1 ); - off =scnprintf (&buf[off], - buf_size -1 - off, -"%-*s" , lf_str_size, lfs); - }else { +else sprintf (lfs,"PF%d" , pf); - off =scnprintf (&buf[off], - buf_size -1 - off, -"%-*s" , lf_str_size, lfs); - } +seq_printf (filp,"%-*s" , lf_str_size, lfs);for (index =0 ; index <BLK_COUNT ; index++) { block = rvu->hw->block[index];if (!strlen (block.name))continue ; - len =0 ; - lfs[len] ='\0' ; -get_lf_str_list (&block, pcifunc, lfs); -if (strlen (lfs)) - flag =1 ; - off +=scnprintf (&buf[off], buf_size -1 - off, -"%-*s" , lf_str_size, lfs); - } -if (flag) { - off +=scnprintf (&buf[off], - buf_size -1 - off,"\n" ); - bytes_not_copied =copy_to_user (buffer + - (i * off), - buf, off); -if (bytes_not_copied) - goto out; - - i++; - *ppos += off; + lfs[0 ] ='\0' ; +get_lf_str_list (&block, pcifunc, lfs); +seq_printf (filp,"%-*s" , lf_str_size, lfs); } +seq_putc (filp,'\n' ); } } -out:kfree (lfs); -kfree (buf); -if (bytes_not_copied) -return -EFAULT ; -return *ppos; +return 0 ; } -RVU_DEBUG_FOPS (rsrc_status, rsrc_attach_status,NULL ); +RVU_DEBUG_SEQ_FOPS (rsrc_status, rsrc_attach_status,NULL );static int rvu_dbg_rvu_pf_cgx_map_display (struct seq_file *filp,void *unused) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 72/457 net/mlx5: devcom, Base component size on linked devices
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shay Drory <[email protected]>
[ Upstream commit d09e8f64653c93da5793c16be19330968f2a32e6 ]
mlx5_devcom_comp_get_size() returns the component's kref count. That kref is bumped in mlx5_devcom_register_component() under comp_list_lock, before the comp_dev is linked onto comp_dev_list_head under comp->sem. The event broadcast (mlx5_devcom_locked_send_event()) walks that list.
Hence, a caller can read the expected size, but send_event won't be sent to all peers. In the SD group registration path, this lets a member broadcast its role-election event over an incomplete list, electing a primary that never completes the group, is never marked ready, and leaves the group with a stale primary.
Track the number of linked comp_devs in a dedicated counter, maintained under comp->sem together with the list add/remove, and return it from mlx5_devcom_comp_get_size().
--- drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c +4 -1
@@ -37,6 +37,7 @@ struct mlx5_devcom_comp {struct mlx5_devcom_key key;mlx5_devcom_event_handler_t handler;struct kref ref; +int nr_devs;bool ready;struct rw_semaphore sem;struct lock_class_key lock_key;
@@ -170,6 +171,7 @@ devcom_alloc_comp_dev(struct mlx5_devcom_dev *devc,down_write (&comp->sem);list_add_tail (&devcom->list, &comp->comp_dev_list_head); +WRITE_ONCE (comp->nr_devs, comp->nr_devs +1 );up_write (&comp->sem);return devcom;
@@ -182,6 +184,7 @@ devcom_free_comp_dev(struct mlx5_devcom_comp_dev *devcom)down_write (&comp->sem);list_del (&devcom->list); +WRITE_ONCE (comp->nr_devs, comp->nr_devs -1 );up_write (&comp->sem);kref_put (&devcom->devc->ref, mlx5_devcom_dev_release);
@@ -284,7 +287,7 @@ int mlx5_devcom_comp_get_size(struct mlx5_devcom_comp_dev *devcom) {struct mlx5_devcom_comp *comp = devcom->comp; -return kref_read (&comp->ref); +return READ_ONCE (comp->nr_devs); } int mlx5_devcom_locked_send_event(struct mlx5_devcom_comp_dev *devcom,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 73/457 net/mlx5: SD, unload reps on shared FDB create error path
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shay Drory <[email protected]>
[ Upstream commit e1e29ada2b938b13ba689a06a8bd8604564da2b3 ]
mlx5_lag_shared_fdb_create() sets sd_fdb_active on every group member before reloading the representors, so mlx5_lag_is_active() is already true and the guard in mlx5_esw_offloads_rep_load() does not skip the VF/SF reps. If the reload then fails, the error path clears sd_fdb_active and destroys the shared FDB, leaving the reps loaded while SD LAG is inactive - the state cited commit was written to prevent.
Unload the reps in the error path as well.
--- drivers/net/ethernet/mellanox/mlx5/core/lag/shared_fdb.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/mellanox/mlx5/core/lag/shared_fdb.c +1 -0
@@ -270,6 +270,7 @@ int mlx5_lag_shared_fdb_create(struct mlx5_lag *ldev, pf->sd_fdb_active = false; }mlx5_lag_destroy_single_fdb_filter (ldev, group_id); +mlx5_lag_unload_reps_from_locked (ldev, filter); } err_add_devices:mlx5_lag_add_devices_filter (ldev, filter);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 74/457 net/mlx5: LAG, reload IB reps of LAG master before the rest
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shay Drory <[email protected]>
[ Upstream commit bae23d1ae62092c7f0ec6d5f7e1be5d164822638 ]
In a shared-FDB LAG the master device creates the bond IB device; the other LAG members do not create their own, they populate a port inside the master's IB device. mlx5_lag_reload_ib_reps_unlocked() reloaded the members' IB reps in iteration order, with no guarantee the master is reloaded first. When a non-master member is reloaded before the master, it tries to populate its port in an IB device that has not been recreated yet.
Hence, reload the master's IB reps first, then every other member.
--- .../net/ethernet/mellanox/mlx5/core/lag/lag.c | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c +32 -12
@@ -1266,25 +1266,45 @@ void mlx5_lag_remove_devices(struct mlx5_lag *ldev)mlx5_lag_remove_devices_filter (ldev,MLX5_LAG_FILTER_PORTS ); } +static int mlx5_lag_reload_ib_reps_idx (struct mlx5_lag *ldev,int idx, +u32 flags) +{ +struct lag_func *pf =mlx5_lag_pf (ldev, idx); +struct mlx5_eswitch *esw; +int ret; + +if (pf->dev->priv.flags & flags) +return 0 ; + + esw = pf->dev->priv.eswitch; +mlx5_esw_reps_block (esw); + ret =mlx5_eswitch_reload_ib_reps (esw); +mlx5_esw_reps_unblock (esw); + +return ret; +} +static int mlx5_lag_reload_ib_reps_unlocked (struct mlx5_lag *ldev,u32 flags,u32 filter,bool cont_on_fail) { -struct lag_func *pf; +int master_idx =mlx5_lag_get_dev_index_by_seq_filter (ldev,MLX5_LAG_P1 , + filter);int ret;int i; +if (master_idx <0 ) +return -EINVAL ; + + ret =mlx5_lag_reload_ib_reps_idx (ldev, master_idx, flags); +if (ret && !cont_on_fail) +return ret; +mlx5_lag_for_each (i,0 , ldev, filter) { - pf =mlx5_lag_pf (ldev, i); -if (!(pf->dev->priv.flags & flags)) { -struct mlx5_eswitch *esw; - - esw = pf->dev->priv.eswitch; -mlx5_esw_reps_block (esw); - ret =mlx5_eswitch_reload_ib_reps (esw); -mlx5_esw_reps_unblock (esw); -if (ret && !cont_on_fail) -return ret; - } +if (i == master_idx) +continue ; + ret =mlx5_lag_reload_ib_reps_idx (ldev, i, flags); +if (ret && !cont_on_fail) +return ret; }return 0 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 75/457 bpf: Make post-verification instruction rewrites killable
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <[email protected]>
[ Upstream commit 261b61d3735b042ae25634f795c4540be0fc140c ]
After do_check() returns, the verifier runs several instruction rewrite passes. Some of them patch or remove one instruction at a time. Each operation moves the remaining instruction and auxiliary-data arrays and adjusts all branch offsets, making the overall work quadratic in the program length.
A privileged loader can submit 131072 unconditional jumps by zero followed by a valid return. Verification finishes quickly, but bpf_opt_remove_nops() then spends a long time removing each jump separately. Since this post-verification work neither checks for signals nor reschedules, a pending SIGKILL cannot terminate the task until the rewrite finishes.
Make bpf_patch_insn_data() and verifier_remove_insns() common cancellation and rescheduling points. These helpers run from BPF_PROG_LOAD process context, and bpf_patch_insn_data() can already sleep while reallocating auxiliary data.
Report interrupted constant blinding as -EINTR and propagate it through both JIT paths, including kernels that permit interpreter fallback. Other blinding failures retain the existing fallback behavior.
This does not reduce the quadratic cost of the rewrite passes, but it makes the work preemptible and allows a killed loader to be torn down promptly.
--- kernel/bpf/core.c | 21 +++++++++++++++++---- kernel/bpf/fixups.c | 24 ++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 6 deletions(-)
kernel/bpf/core.c +17 -4
@@ -19,6 +19,7 @@#include <uapi/linux/btf.h> #include <linux/filter.h> +#include <linux/sched/signal.h> #include <linux/skbuff.h> #include <linux/static_call.h> #include <linux/vmalloc.h>
@@ -1612,6 +1613,8 @@ struct bpf_prog *bpf_jit_blind_constants(struct bpf_verifier_env *env, struct bp* fix it up here on error. */ bpf_jit_prog_release_other (prog, clone); +if (env &&fatal_signal_pending (current)) +return ERR_PTR (-EINTR );return IS_ERR (tmp) ? tmp :ERR_PTR (-ENOMEM ); }
@@ -2641,11 +2644,14 @@ static struct bpf_prog *bpf_prog_jit_compile(struct bpf_verifier_env *env, struc orig_prog = prog; prog =bpf_jit_blind_constants (env, prog);/* -* If blinding was requested and we failed during blinding, we must fall -* back to the interpreter. +* Fall back to the interpreter after blinding failures, except when +* the loader was killed. */ -if (IS_ERR (prog)) +if (IS_ERR (prog)) { +if (PTR_ERR (prog) == -EINTR ) +return prog; goto out_restore; + } prog =bpf_int_jit_compile (env, prog);if (prog->jited) {
@@ -2668,6 +2674,8 @@ static struct bpf_prog *bpf_prog_jit_compile(struct bpf_verifier_env *env, strucstruct bpf_prog *__bpf_prog_select_runtime (struct bpf_verifier_env *env,struct bpf_prog *fp,int *err) { +struct bpf_prog *jit_prog; +/* In case of BPF to BPF calls, verifier did all the prep * work with regards to JITing, etc. */
@@ -2690,7 +2698,12 @@ struct bpf_prog *__bpf_prog_select_runtime(struct bpf_verifier_env *env, structif (*err)return fp; - fp =bpf_prog_jit_compile (env, fp); + jit_prog =bpf_prog_jit_compile (env, fp); +if (IS_ERR (jit_prog)) { + *err =PTR_ERR (jit_prog); +return fp; + } + fp = jit_prog;bpf_prog_jit_attempt_done (fp);if (!fp->jited && jit_needed) { *err = -ENOTSUPP ;
kernel/bpf/fixups.c +22 -2
@@ -8,6 +8,7 @@#include <linux/bsearch.h> #include <linux/sort.h> #include <linux/perf_event.h> +#include <linux/sched/signal.h> #include <net/xdp.h> #include "disasm.h"
@@ -240,12 +241,28 @@ static void adjust_poke_descs(struct bpf_prog *prog, u32 off, u32 len) } } +/* +* Some post-verification instruction rewriting passes require an +* O(prog->len) operation per instruction. Keep their shared primitives +* killable and preemptible. +*/ +static bool bpf_rewrite_must_abort (void ) +{ +if (fatal_signal_pending (current)) +return true; +cond_resched (); +return false; +} +struct bpf_prog *bpf_patch_insn_data (struct bpf_verifier_env *env,u32 off,const struct bpf_insn *patch,u32 len) {struct bpf_prog *new_prog;struct bpf_insn_aux_data *new_data =NULL ; +if (bpf_rewrite_must_abort ()) +return NULL ; +if (len >1 ) { new_data = vrealloc(env->insn_aux_data, array_size(env->prog->len + len - 1,
@@ -457,6 +474,9 @@ static int verifier_remove_insns(struct bpf_verifier_env *env, u32 off, u32 cnt)unsigned int orig_prog_len = env->prog->len;int err; +if (bpf_rewrite_must_abort ()) +return -EINTR ; +if (bpf_prog_is_offloaded (env->prog->aux))bpf_prog_offload_remove_insns (env, off, cnt);
@@ -1316,7 +1336,7 @@ int bpf_jit_subprogs(struct bpf_verifier_env *env) } prog =bpf_jit_blind_constants (env, prog);if (IS_ERR (prog)) { - err = -ENOMEM ; + err =PTR_ERR (prog); prog = orig_prog; goto out_restore; }
@@ -1395,7 +1415,7 @@ int bpf_fixup_call_args(struct bpf_verifier_env *env) err =bpf_jit_subprogs (env);if (err ==0 )return 0 ; -if (err == -EFAULT ) +if (err == -EFAULT || err == -EINTR )return err; }#ifndef CONFIG_BPF_JIT_ALWAYS_ON
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 76/457 bpf: Preserve packet pointer class displacement in regsafe()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <[email protected]>
[ Upstream commit fd16449a9b3b31a8f18944c2f0e29e4e218ca2cf ]
regsafe() maps packet pointer IDs between states and checks that each current register range is a subset of the corresponding explored register range. It does not, however, preserve the displacement between registers that share a packet pointer ID.
This is unsound because packet range is shared by ID. A bounds check on one class member updates every member, and a later access can consume the range through another member. Commit 022ac0750883 ("bpf: use reg->var_off instead of reg->off for pointers") folded the fixed pointer offset into r64 and removed the old off equality check, so two individually narrower registers can prune even when their displacement has changed. The explored path can then license an out-of-bounds packet access on the pruned path.
Require matching range bases for packet pointers with an ID. Together with the existing ID mapping, this preserves the displacement between members of each packet-pointer class without adding per-ID state. Packet pointers without an ID remain unaffected.
--- kernel/bpf/states.c | 3 +++ 1 file changed, 3 insertions(+)
kernel/bpf/states.c +3 -0
@@ -635,6 +635,9 @@ static bool regsafe(struct bpf_verifier_env *env, struct bpf_reg_state *rold,/* id relations must be preserved */ if (!check_ids (rold->id, rcur->id, idmap))return false; +/* Preserve displacements between pointers sharing an ID. */ +if (rold->id && rold->r64.base != rcur->r64.base) +return false;/* new val must satisfy old val knowledge */ return range_within (rold, rcur) &&tnum_in (rold->var_off, rcur->var_off);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 77/457 bpf: Restrict CO-RE poisoning to relocatable instructions
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <[email protected]>
[ Upstream commit 394ae398337c5f87e567f6cd63b937fc2b2f6ddc ]
CO-RE relocation records can name any instruction offset. When a relocation cannot be resolved, bpf_core_patch_insn() currently poisons its target before checking whether that instruction is a valid relocation target. Malformed metadata can therefore replace jumps, calls, exits, register-source arithmetic, or non-immediate loads instead of failing at the relocation step.
Handle poisoning only after the instruction has passed the same class and operand-form checks used for a resolved relocation. Route invalid forms through the existing diagnostic and return a hard error. Keep poisoning supported instructions, including both halves of a plain ldimm64, so an unresolved relocation in dead code remains valid.
Extend bpf_core_poison_insn() to poison both halves of ldimm64, and return its status directly from each validated instruction case. This avoids routing the success path through a common label and leaves the helper free to report errors.
The shared relocation code applies this restriction to both libbpf and in-kernel CO-RE.
--- tools/lib/bpf/relo_core.c | 58 +++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 27 deletions(-)
tools/lib/bpf/relo_core.c +31 -27
@@ -980,23 +980,30 @@ static int bpf_core_calc_relo(const char *prog_name, }/* -* Turn instruction for which CO_RE relocation failed into invalid one with +* Turn instruction for which CO-RE relocation failed into invalid one with * distinct signature. */ -static void bpf_core_poison_insn (const char *prog_name,int relo_idx, -int insn_idx,struct bpf_insn *insn) +static int bpf_core_poison_insn (const char *prog_name,int relo_idx, +struct bpf_insn *insn,int insn_idx) { -pr_debug ("prog '%s': relo #%d: substituting insn #%d w/ invalid insn\n" , - prog_name, relo_idx, insn_idx); - insn->code =BPF_JMP |BPF_CALL ; - insn->dst_reg =0 ; - insn->src_reg =0 ; - insn->off =0 ; -/* if this instruction is reachable (not a dead code), -* verifier will complain with the following message: -* invalid func unknown#195896080 -*/ - insn->imm =195896080 ;/* => 0xbad2310 => "bad relo" */ +int insn_cnt =is_ldimm64_insn (insn) ?2 :1 ; +int i; + +for (i =0 ; i < insn_cnt; i++) { +pr_debug ("prog '%s': relo #%d: substituting insn #%d w/ invalid insn\n" , + prog_name, relo_idx, insn_idx + i); + insn[i].code =BPF_JMP |BPF_CALL ; + insn[i].dst_reg =0 ; + insn[i].src_reg =0 ; + insn[i].off =0 ; +/* +* If this instruction is reachable (not dead code), the verifier +* will complain with "invalid func unknown#195896080". +*/ + insn[i].imm =195896080 ;/* => 0xbad2310 => "bad relo" */ + } + +return 0 ; }static int insn_bpf_size_to_bytes (struct bpf_insn *insn)
@@ -1047,17 +1054,6 @@ int bpf_core_patch_insn(const char *prog_name, struct bpf_insn *insn, class =BPF_CLASS (insn->code); -if (res->poison) { -poison: -/* poison second part of ldimm64 to avoid confusing error from -* verifier about "unknown opcode 00" -*/ -if (is_ldimm64_insn (insn)) -bpf_core_poison_insn (prog_name, relo_idx, insn_idx +1 , insn +1 ); -bpf_core_poison_insn (prog_name, relo_idx, insn_idx, insn); -return 0 ; - } - orig_val = res->orig_val; new_val = res->new_val;
@@ -1065,7 +1061,9 @@ int bpf_core_patch_insn(const char *prog_name, struct bpf_insn *insn,case BPF_ALU :case BPF_ALU64 :if (BPF_SRC (insn->code) !=BPF_K ) -return -EINVAL ; + goto bad_insn; +if (res->poison) +return bpf_core_poison_insn (prog_name, relo_idx, insn, insn_idx);if (res->validate && insn->imm != orig_val) { pr_warn("prog '%s': relo #%d: unexpected insn #%d (ALU/ALU64) value: got %u, exp %llu -> %llu\n", prog_name, relo_idx,
@@ -1082,6 +1080,8 @@ int bpf_core_patch_insn(const char *prog_name, struct bpf_insn *insn,case BPF_LDX :case BPF_ST :case BPF_STX : +if (res->poison) +return bpf_core_poison_insn (prog_name, relo_idx, insn, insn_idx);if (res->validate && insn->off != orig_val) { pr_warn("prog '%s': relo #%d: unexpected insn #%d (LDX/ST/STX) value: got %u, exp %llu -> %llu\n", prog_name, relo_idx, insn_idx, insn->off, (unsigned long long)orig_val,
@@ -1097,7 +1097,7 @@ int bpf_core_patch_insn(const char *prog_name, struct bpf_insn *insn,pr_warn ("prog '%s': relo #%d: insn #%d (LDX/ST/STX) accesses field incorrectly. " "Make sure you are accessing pointers, unsigned integers, or fields of matching type and size.\n" , prog_name, relo_idx, insn_idx); - goto poison; +return bpf_core_poison_insn (prog_name, relo_idx, insn, insn_idx); } orig_val = insn->off;
@@ -1140,6 +1140,9 @@ int bpf_core_patch_insn(const char *prog_name, struct bpf_insn *insn,return -EINVAL ; } +if (res->poison) +return bpf_core_poison_insn (prog_name, relo_idx, insn, insn_idx); + imm = (__u32 )insn[0 ].imm | ((__u64 )insn[1 ].imm <<32 );if (res->validate && imm != orig_val) { pr_warn("prog '%s': relo #%d: unexpected insn #%d (LDIMM64) value: got %llu, exp %llu -> %llu\n",
@@ -1157,6 +1160,7 @@ int bpf_core_patch_insn(const char *prog_name, struct bpf_insn *insn,break ; }default : +bad_insn:pr_warn ("prog '%s': relo #%d: trying to relocate unrecognized insn #%d, code:0x%x, src:0x%x, dst:0x%x, off:0x%x, imm:0x%x\n" , prog_name, relo_idx, insn_idx, insn->code, insn->src_reg, insn->dst_reg, insn->off, insn->imm);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 78/457 libbpf: Reject truncated ldimm64 CO-RE relocations
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <[email protected]>
[ Upstream commit b4e875d397da451fb4e9c573ff4b86db53caba05 ]
CO-RE relocation of an ldimm64 instruction operates on two instruction slots. A malformed BPF ELF can end a function after the first slot and attach a CO-RE relocation to it. libbpf allocates the instruction array according to the function symbol size, so the shared relocation code would then access beyond the allocation.
Reject a terminal ldimm64 in libbpf's relocation loop, where the program length is available, before resolving or applying the relocation. Both resolved and unresolved relocations validate the absent second slot, and unresolved relocation poisoning would additionally write past the array.
The in-kernel caller is protected by the verifier's early instruction-stream check before it applies CO-RE relocations.
--- tools/lib/bpf/libbpf.c | 7 +++++++ 1 file changed, 7 insertions(+)
tools/lib/bpf/libbpf.c +7 -0
@@ -6162,6 +6162,13 @@ bpf_object__relocate_core(struct bpf_object *obj, const char *targ_btf_path)return -EINVAL ; insn = &prog->insns[insn_idx]; +if (is_ldimm64_insn (insn) && (size_t )insn_idx +1 >= prog->insns_cnt) { +pr_warn ("prog '%s': relo #%d: insn #%d (LDIMM64) is truncated\n" , + prog->name, i, insn_idx); + err = -EINVAL ; + goto out; + } + err =record_relo_core (prog, rec, insn_idx);if (err) { pr_warn("prog '%s': relo #%d: failed to record relocation: %s\n",
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 79/457 ipv4: fib: fix data-race and stale genid check around nh->nh_saddr
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linkui Xiao <[email protected]>
[ Upstream commit 46bc52d13594848023e681860df8700c8db14354 ]
fib_select_multipath() compares nexthop_nh->nh_saddr against the flow source address with no lock held, while fib_info_update_nhc_saddr() stores a new value from another CPU as soon as the preferred source address of the egress device changes.
Commit 195374d89368 ("ipv4: fib: annotate races around nh->nh_saddr_genid and nh->nh_saddr") added WRITE_ONCE() on the store side and READ_ONCE() in fib_result_prefsrc() after syzbot reported
BUG: KCSAN: data-race in fib_select_path / fib_select_path
but it only covered that reader. fib_select_multipath(), reached from fib_select_path(), is a second lockless reader of nh->nh_saddr and was left bare.
Moreover, nh_saddr is only meaningful when nh_saddr_genid matches dev_addr_genid, as established by commit 436c3b66ec98 ("ipv4: Invalidate nexthop cache nh_saddr more correctly."). fib_select_multipath() skips that validation, so it can score a nexthop using a stale source address and skew the ECMP selection.
Annotate both reads with READ_ONCE() and refresh the cached source address via fib_info_update_nhc_saddr() when the genid does not match, mirroring fib_result_prefsrc().
--- net/ipv4/fib_semantics.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
net/ipv4/fib_semantics.c +12 -1
@@ -2176,6 +2176,15 @@ static bool fib_good_nh(const struct fib_nh *nh)return !!(state &NUD_VALID ); } +static __be32 fib_nh_saddr (struct net *net,const struct fib_info *fi, +struct fib_nh *nh,int genid) +{ +if (READ_ONCE (nh->nh_saddr_genid) == genid) +return READ_ONCE (nh->nh_saddr); + +return fib_info_update_nhc_saddr (net, &nh->nh_common, fi->fib_scope); +} +void fib_select_multipath (struct fib_result *res,int hash,const struct flowi4 *fl4) {
@@ -2184,6 +2193,7 @@ void fib_select_multipath(struct fib_result *res, int hash,bool use_neigh;int score =-1 ;__be32 saddr; +int genid;if (unlikely (res->fi->nh)) {nexthop_path_fib_result (res, hash);
@@ -2192,6 +2202,7 @@ void fib_select_multipath(struct fib_result *res, int hash, use_neigh =READ_ONCE (net->ipv4.sysctl_fib_multipath_use_neigh); saddr = fl4 ? fl4->saddr :0 ; + genid = saddr ?atomic_read (&net->ipv4.dev_addr_genid) :0 ;change_nexthops (fi) {int nh_upper_bound, nh_score =0 ;
@@ -2204,7 +2215,7 @@ void fib_select_multipath(struct fib_result *res, int hash, (use_neigh && !fib_good_nh(nexthop_nh)))continue ; -if (saddr && nexthop_nh->nh_saddr == saddr) +if (saddr &&fib_nh_saddr (net, fi, nexthop_nh, genid) == saddr) nh_score +=2 ;if (hash <= nh_upper_bound) nh_score++;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 80/457 gpiolib: use of_node_name if line-name is missing
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Wunderlich <[email protected]>
[ Upstream commit d54a489c8c4b627775445d54a6cbd32f209bda8f ]
Until v7.0, GPIO hogs inherited the DT node name when no line-name property was specified. This was implemented as a fallback in of_parse_own_gpio().
Commit d1d564ec4992 ("gpio: move hogs into GPIO core") moved hog parsing into the GPIO core and removed this fallback.
Consequently, GPIO hogs without a line-name property are now displayed with a ? in /sys/kernel/debug/gpio. Restore the old fallback.
--- drivers/gpio/gpiolib.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/gpio/gpiolib.c +7 -0
@@ -1029,6 +1029,13 @@ int gpiochip_add_hog(struct gpio_chip *gc, struct fwnode_handle *fwnode) ret =of_gpiochip_get_lflags (gc, &gpiospec, &lflags);if (ret)return ret; + +/* +* If no line-name property is present, fall back to the OF +* node name as in the previous implementation. +*/ +if (!name) + name =to_of_node (fwnode)->name; }else {/* * GPIO_ACTIVE_LOW is currently the only lookup flag
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 81/457 netfilter: flowtable: publish HW_DEAD after worker is done
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jérémy Jean <[email protected]>
[ Upstream commit d644b23afe1ef509c9961a6d84a093c2587edf02 ]
flow_offload_work_del() sets NF_FLOW_HW_DEAD before the work handler clears NF_FLOW_HW_PENDING. Once a flow is both HW_DYING and HW_DEAD, a concurrent garbage collection pass can remove it and schedule it for RCU freeing.
The offload worker holds neither an RCU read lock nor a reference to the flow. If it is preempted after publishing HW_DEAD, the RCU callback can free the flow before the worker resumes and clears HW_PENDING, resulting in a use-after-free.
Move HW_DEAD publication to the common worker epilogue after the pending bit is cleared, making it the final flow access by destroy work. Order all preceding flow accesses before publishing the bit that allows garbage collection to free the object.
--- net/netfilter/nf_flow_table_offload.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
net/netfilter/nf_flow_table_offload.c +6 -1
@@ -995,7 +995,6 @@ static void flow_offload_work_del(struct flow_offload_work *offload)flow_offload_tuple_del (offload,FLOW_OFFLOAD_DIR_ORIGINAL );if (test_bit (NF_FLOW_HW_BIDIRECTIONAL , &offload->flow->flags))flow_offload_tuple_del (offload,FLOW_OFFLOAD_DIR_REPLY ); -set_bit (NF_FLOW_HW_DEAD , &offload->flow->flags); } static void flow_offload_tuple_stats(struct flow_offload_work *offload,
@@ -1059,6 +1058,12 @@ static void flow_offload_work_handler(struct work_struct *work) }clear_bit (NF_FLOW_HW_PENDING , &offload->flow->flags); +if (offload->cmd ==FLOW_CLS_DESTROY ) { +/* Publish after the worker's last flow access. */ +smp_mb__before_atomic (); +set_bit (NF_FLOW_HW_DEAD , &offload->flow->flags); + } +kfree (offload); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 82/457 netfilter: nfnetlink_queue: hold nfnl mutex in event notifier
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
[ Upstream commit 9461613afc59acef44a0071b0dd5075f6e993ffe ]
We must serialize the release notifier and the config netlink function. A concurrent thread can issue close() which can call the release function while unrelated socket processes UNBIND request for same portid:
Oops: general protection fault, [..] RIP: 0010:__instance_destroy+0x60/0x210 [nfnetlink_queue] Call Trace: nfqnl_recv_config+0x9b0/0xdc0 [nfnetlink_queue] nfnetlink_rcv_msg+0x7c2/0xeb0 ? __pfx_nfnetlink_rcv_msg+0x10/0x10
After this, parallel UNBIND and URELEASE events are impossible.
This change isn't nice, but its the shortest fix given instances are not refcounted and the nfnetlink config callback drops the rcu read lock early due to need for sleeping allocations.
--- net/netfilter/nfnetlink_queue.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
net/netfilter/nfnetlink_queue.c +5 -3
@@ -1527,6 +1527,7 @@ nfqnl_rcv_nl_event(struct notifier_block *this,if (event ==NETLINK_URELEASE && n->protocol ==NETLINK_NETFILTER ) {int i; +nfnl_lock (NFNL_SUBSYS_QUEUE );/* destroy all instances for this portid */ spin_lock (&q->instances_lock);for (i =0 ; i <INSTANCE_BUCKETS ; i++) {
@@ -1540,6 +1541,7 @@ nfqnl_rcv_nl_event(struct notifier_block *this, } }spin_unlock (&q->instances_lock); +nfnl_unlock (NFNL_SUBSYS_QUEUE ); }return NOTIFY_DONE ; }
@@ -1859,9 +1861,9 @@ static int nfqnl_recv_config(struct sk_buff *skb, const struct nfnl_info *info,/* Lookup queue under RCU. After peer_portid check (or for new queue * in BIND case), the queue is owned by the socket sending this message. -* A socket cannot simultaneously send a message and close, so while -* processing this CONFIG message, nfqnl_rcv_nl_event() (triggered by -* socket close) cannot destroy this queue. Safe to use without RCU. +* nfqnl_rcv_nl_event() will block on the nfnl subsys mutex that is +* held by the caller, so the queue cannot be destroyed in parallel, +* even after we drop the RCU read lock. */ rcu_read_lock (); queue =instance_lookup (q, queue_num);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 83/457 netfilter: nft_synproxy: use the family-aware checksum helper
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <[email protected]>
[ Upstream commit a311a898172743558b82f6035ef2aa8c310a4223 ]
nft_synproxy_do_eval() verifies the TCP checksum before it switches on skb->protocol. It uses nf_ip_checksum(), which constructs an IPv4 pseudo header and relies on the IPv4 header checksum when folding the whole skb. Neither operation is valid for an IPv6 packet.
A correctly checksummed IPv6 segment can therefore fail verification when it reaches the hook as CHECKSUM_NONE or, at NF_INET_LOCAL_IN, CHECKSUM_COMPLETE. nft_synproxy_do_eval() returns NF_DROP before nft_synproxy_eval_v6() can send a SYN-ACK.
nft_synproxy_validate() deliberately admits NFPROTO_IPV6 and NFPROTO_INET, and the xtables counterpart ip6t_SYNPROXY.c already calls nf_ip6_checksum().
Use nf_checksum() with nft_pf() so the checksum helper dispatches to the packet family's implementation.
--- net/netfilter/nft_synproxy.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/netfilter/nft_synproxy.c +2 -1
@@ -118,7 +118,8 @@ static void nft_synproxy_do_eval(const struct nft_synproxy *priv,return ; } -if (nf_ip_checksum (skb,nft_hook (pkt), thoff,IPPROTO_TCP )) { +if (nf_checksum (skb,nft_hook (pkt), thoff,IPPROTO_TCP , +nft_pf (pkt))) { regs->verdict.code =NF_DROP ;return ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 84/457 ipvs: revalidate ihl before icmp_send
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Julian Anastasov <[email protected]>
[ Upstream commit e290145564886d6a3038810c621f738c1fe9fa51 ]
While the outer IP header is already pulled into the skb head, we must be careful and revalidate the embedded headers after reading them from the skb frags to prevent possible out-of-bounds access.
One such place reported by Sashiko is ip_vs_in_icmp() where local process can change the ihl field and after pskb_may_pull() we can see larger value. Even if icmp_send() has checks to prevent out-of-bounds access, play safe and add check to drop the packet if the ihl field is changed. As the outer headers are pulled, make sure the transport header is updated too, it was used before commit 7fcc2fe39fed ("net:
icmp: avoid invalid transport header access in icmp_send tracepoint")
--- net/netfilter/ipvs/ip_vs_core.c | 6 ++++++ 1 file changed, 6 insertions(+)
net/netfilter/ipvs/ip_vs_core.c +6 -0
@@ -1961,6 +1961,12 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related,/* Ensure the IP header is present in headroom */ if (!pskb_may_pull (skb, hlen_orig)) goto ignore_tunnel; +skb_set_transport_header (skb, hlen_orig); +/* Before now we may used ihl from skb frag, revalidate it after +* copying it into skb head to prevent out-of-bounds access +*/ +if (ip_hdr (skb)->ihl *4 != hlen_orig) + goto ignore_tunnel;IP_VS_DBG (12 ,"Sending ICMP for %pI4->%pI4: t=%u, c=%u, i=%u\n" , &ip_hdr (skb)->saddr, &ip_hdr (skb)->daddr, type, code,ntohl (info));
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 85/457 netfilter: ctnetlink: fix suspicious RCU usage in expect_iter_name
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naman Gulati <[email protected]>
[ Upstream commit 207d591c353201f3bd3e0c89bb7d44a849c8fd59 ]
expect_iter_name() is invoked by nf_ct_expect_iterate_net() under spin_lock_bh(&nf_conntrack_expect_lock). It does not hold rcu_read_lock().
When accessing exp->helper with rcu_dereference() in syzbot's report, lockdep warns:
=============================
WARNING: suspicious RCU usage
syzkaller #0 Not tainted
-----------------------------
net/netfilter/nf_conntrack_netlink.c:3393 suspicious rcu_dereference_check() usage!
locks held by syz-executor381/5628: 2, last CPU#1:
#0: ffffffff9aee42a0 (nfnl_subsys_ctnetlink_exp){+.+.}-{4:4},
at: nfnetlink_rcv_msg+0xa69/0x12b0
#1: ffffffff8ea74d58 (nf_conntrack_expect_lock){+...}-{3:3},
at: nf_ct_expect_iterate_net+0x38/0x180Call Trace: <TASK> dump_stack_lvl+0xe8/0x150 lockdep_rcu_suspicious+0x140/0x1d0 expect_iter_name+0xfb/0x100 nf_ct_expect_iterate_net+0xf2/0x180 ctnetlink_del_expect+0x45d/0x640 nfnetlink_rcv_msg+0xcc2/0x12b0 netlink_rcv_skb+0x226/0x4a0 nfnetlink_rcv+0x2b9/0x28c0 netlink_unicast+0x7bd/0x940 netlink_sendmsg+0x813/0xb40 ____sys_sendmsg+0x54e/0x850 ___sys_sendmsg+0x2a5/0x360 __sys_sendmsg+0x2a5/0x360 do_syscall_64+0x166/0x520 entry_SYSCALL_64_after_hwframe+0x77/0x7f
Use rcu_dereference_protected() with lockdep_is_held() on nf_conntrack_expect_lock instead, similar to expect_iter_me() in nf_conntrack_helper.c.
--- net/netfilter/nf_conntrack_netlink.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/netfilter/nf_conntrack_netlink.c +2 -1
@@ -3392,7 +3392,8 @@ static bool expect_iter_name(struct nf_conntrack_expect *exp, void *data)struct nf_conntrack_helper *helper;const char *name = data; - helper =rcu_dereference (exp->helper); + helper =rcu_dereference_protected (exp->helper, +lockdep_is_held (&nf_conntrack_expect_lock));if (!helper)return false;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 86/457 arm64: io: Reject non-user protection in ioremap_prot()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zeng Heng <[email protected]>
[ Upstream commit bb756b11ad63832ebee58caf9e8f9381eaecff9f ]
Mapping a stack-top page via /dev/mem with PROT_NONE and then reading that process's /proc/<pid>/cmdline triggers a spurious WARN in ioremap_prot() through generic_access_phys():
WARNING: ./arch/arm64/include/asm/io.h:275 at generic_access_phys
Call trace:
generic_access_phys+0x1c8/0x228 (P)
__access_remote_vm+0x2b4/0x398
access_remote_vm+0x14/0x30
get_mm_cmdline+0xf8/0x2a0
proc_pid_cmdline_read+0x68/0x120generic_access_phys() passes the protection derived from the user PTE to ioremap_prot(). On arm64, a PROT_NONE mapping is represented by a present-invalid PTE, so pte_present() still returns true and the protection reaches ioremap_prot().
A PROT_NONE mapping does not have PTE_USER, causing the existing WARN_ON_ONCE() in ioremap_prot() to fire even though this is a valid user mapping. Execute-only mappings have the same issue and must not be readable through this path either.
ioremap_prot() should therefore reject protection values without PTE_USER without warning. This makes the access fail cleanly for PROT_NONE and execute-only mappings while retaining the existing user-protection contract.
--- arch/arm64/include/asm/io.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm64/include/asm/io.h +2 -1
@@ -272,7 +272,8 @@ static inline void __iomem *ioremap_prot(phys_addr_t phys, size_t size,pgprot_t prot;ptval_t user_prot_val =pgprot_val (user_prot); -if (WARN_ON_ONCE (!(user_prot_val &PTE_USER ))) +/* Reject PROT_NONE and exec-only */ +if (!(user_prot_val &PTE_USER ))return NULL ; prot = __pgprot_modify(PAGE_KERNEL, PTE_ATTRINDX_MASK,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 87/457 ocfs2: make ocfs2_calc_xattr_init() return void
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joseph Qi <[email protected]>
[ Upstream commit 525c0edc032b3297d0c1056cf1fa20cf1f9e6184 ]
ocfs2_calc_xattr_init() used to read the default ACL off the parent inode itself, so it could return an error from ocfs2_xattr_get_nolock(). Commit bd7c05fb4a47 ("ocfs2: fix circular locking dependency in ocfs2_init_acl()") moved that lookup before the transaction starts and deleted the error path, but left the now vestigial 'int ret = 0' declaration and both 'return ret' statements behind, along with an unreachable error branch in ocfs2_mknod().
Drop the leftover variable and convert the return type to void, so the callee states that it always succeeds and the caller no longer carries a check that can never trigger.
No functional change.
--- fs/ocfs2/namei.c | 9 ++------- fs/ocfs2/xattr.c | 13 +++++-------- fs/ocfs2/xattr.h | 8 ++++---- 3 files changed, 11 insertions(+), 19 deletions(-)
fs/ocfs2/namei.c +2 -7
@@ -336,13 +336,8 @@ static int ocfs2_mknod(struct mnt_idmap *idmap, goto leave;/* calculate meta data/clusters for setting security and acl xattr */ - status =ocfs2_calc_xattr_init (dir, mode, &si, &want_clusters, - &xattr_credits, &want_meta, - &acl_state); -if (status <0 ) { -mlog_errno (status); - goto leave; - } +ocfs2_calc_xattr_init (dir, mode, &si, &want_clusters, &xattr_credits, + &want_meta, &acl_state);/* Reserve a cluster if creating an extent based directory. */ if (S_ISDIR (mode) && !ocfs2_supports_inline_data (osb)) {
fs/ocfs2/xattr.c +5 -8
@@ -635,12 +635,11 @@ int ocfs2_calc_security_init(struct inode *dir,return ret; } -int ocfs2_calc_xattr_init (struct inode *dir,umode_t mode, -struct ocfs2_security_xattr_info *si, -int *want_clusters,int *xattr_credits, -int *want_meta,struct ocfs2_acl_state *acl_state) +void ocfs2_calc_xattr_init (struct inode *dir,umode_t mode, +struct ocfs2_security_xattr_info *si, +int *want_clusters,int *xattr_credits, +int *want_meta,struct ocfs2_acl_state *acl_state) { -int ret =0 ;struct ocfs2_super *osb =OCFS2_SB (dir->i_sb);int s_size =0 , a_size =0 , acl_len =0 , new_clusters;
@@ -662,7 +661,7 @@ int ocfs2_calc_xattr_init(struct inode *dir, umode_t mode, }if (!(s_size + a_size)) -return ret; +return ;/* * The max space of security xattr taken inline is
@@ -728,8 +727,6 @@ int ocfs2_calc_xattr_init(struct inode *dir, umode_t mode, } } } - -return ret; } static int ocfs2_xattr_extend_allocation(struct inode *inode,
fs/ocfs2/xattr.h +4 -4
@@ -59,10 +59,10 @@ int ocfs2_calc_security_init(struct inode *, int *, int *, struct ocfs2_alloc_context **);struct ocfs2_acl_state ; -int ocfs2_calc_xattr_init (struct inode *dir,umode_t mode, -struct ocfs2_security_xattr_info *si, -int *want_clusters,int *xattr_credits, -int *want_meta,struct ocfs2_acl_state *acl_state); +void ocfs2_calc_xattr_init (struct inode *dir,umode_t mode, +struct ocfs2_security_xattr_info *si, +int *want_clusters,int *xattr_credits, +int *want_meta,struct ocfs2_acl_state *acl_state);/* * xattrs can live inside an inode, as part of an external xattr block,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 88/457 pinctrl: qcom: ipq5210: Publish the OF module alias
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: hpp.iscas <[email protected]>
[ Upstream commit 447dcff90557748a5ac384aaf5d70b2c7e3b961d ]
The IPQ5210 TLMM platform driver can be a module and matches through ipq5210_tlmm_of_match. This table is not published for OF modalias matching.
Publish the existing table, preserving arch_initcall ordering and the shared MSM pinctrl probe.
--- drivers/pinctrl/qcom/pinctrl-ipq5210.c | 1 + 1 file changed, 1 insertion(+)
drivers/pinctrl/qcom/pinctrl-ipq5210.c +1 -0
@@ -867,6 +867,7 @@ static const struct of_device_id ipq5210_tlmm_of_match[] = { { .compatible = "qcom,ipq5210-tlmm", }, { }, }; +MODULE_DEVICE_TABLE (of, ipq5210_tlmm_of_match);static int ipq5210_tlmm_probe (struct platform_device *pdev) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 89/457 drm/nouveau/clk: fix list cursor use after loop in nvkm_clk_ustate_update
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit aff09d9e37e02dc60bde79035ac15b136d602259 ]
If list_for_each_entry() exits without hitting a break then "pstate" is not a valid pstate pointer. Introduce a "found" variable instead.
The check is reachable from userspace: nvkm_clk_ustate_update() takes the pstate id straight from the 'pstate' debugfs file, so requesting an id that is not in clk->states - or any id at all when the perf tables are broken and the list is empty - makes the pstate->pstate != req test dereference the list head cast to a struct nvkm_pstate, which is an out-of-bounds read.
--- drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c +5 -2
@@ -473,6 +473,7 @@ static int nvkm_clk_ustate_update(struct nvkm_clk *clk, int req) {struct nvkm_pstate *pstate; +bool found = false;int i =0 ;if (!clk->allow_reclock)
@@ -480,12 +481,14 @@ nvkm_clk_ustate_update(struct nvkm_clk *clk, int req)if (req !=-1 && req !=-2 ) {list_for_each_entry (pstate, &clk->states, head) { -if (pstate->pstate == req) +if (pstate->pstate == req) { + found = true;break ; + } i++; } -if (pstate->pstate != req) +if (!found)return -EINVAL ; req = i; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 90/457 drm/nouveau/clk: dont clobber reclock status when restoring volt/fan
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Francesco Magazzu <[email protected]>
[ Upstream commit e5cccdafc855cd5f96f4b51d38114a0360b075d7 ]
nvkm_cstate_prog() reuses 'ret' for the voltage and fan-speed restore calls it makes after reprogramming the clocks. Those calls almost always succeed, so the status of the reclock itself is overwritten and the function reports success even when clk->func->calc() or clk->func->prog() failed. The converse is also true: a successful reclock is reported as an error if the final restore call fails, even though that failure is only logged and otherwise ignored.
The only consumer of the return value is the error message in nvkm_pstate_work(), so in practice a failing reclock is simply never reported. Nothing else changes, but a function that returns success on failure is a trap for the next caller.
Keep the calc/prog status in 'ret' and use a separate local for the restore calls.
--- drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c +9 -7
@@ -199,16 +199,18 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei) }if (volt) { - ret =nvkm_volt_set_id (volt, cstate->voltage, - pstate->base.voltage, clk->temp,-1 ); -if (ret && ret != -ENODEV ) -nvkm_error (subdev,"failed to lower voltage: %d\n" , ret); +int err =nvkm_volt_set_id (volt, cstate->voltage, + pstate->base.voltage, clk->temp,-1 ); + +if (err && err != -ENODEV ) +nvkm_error (subdev,"failed to lower voltage: %d\n" , err); }if (therm) { - ret =nvkm_therm_cstate (therm, pstate->fanspeed,-1 ); -if (ret && ret != -ENODEV ) -nvkm_error (subdev,"failed to lower fan speed: %d\n" , ret); +int err =nvkm_therm_cstate (therm, pstate->fanspeed,-1 ); + +if (err && err != -ENODEV ) +nvkm_error (subdev,"failed to lower fan speed: %d\n" , err); }return ret;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 91/457 drm/nouveau/disp: dont reject HDMI config on cards without SCDC
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Giuseppe Ranieri <[email protected]>
[ Upstream commit 1717fcc5be575d4768279148ae9465a8b13d4339 ]
nv50_hdmi_enable() passes the sink's SCDC capability from its EDID straight through to nvif_outp_hdmi(). On pre-Maxwell-2 cards there is no hdmi->scdc callback, so nvkm_uoutp_mthd_hdmi() rejects the whole configuration with -EINVAL, and nv50_hdmi_enable() returns before hdmi->ctrl() runs and before the AVI and VSI infoframes are sent.
The result on such a card driving an SCDC-capable HDMI 2.0 sink is that HDMI audio silently stops working. Video is unaffected, and nothing is logged, which makes the failure hard to attribute.
SCDC is optional, and the hdmi->scdc() call further down is already guarded against a missing callback. Requesting it on a card that cannot do it need not invalidate the rest of the HDMI configuration, so drop that term from the condition and let the existing guard skip SCDC alone.
--- drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c +1 -2
@@ -253,8 +253,7 @@ nvkm_uoutp_mthd_hdmi(struct nvkm_outp *outp, void *argv, u32 argc)if (!ior->func->hdmi || args->v0.max_ac_packet >0x1f || - args->v0.rekey >0x7f || - (args->v0.scdc && !ior->func->hdmi->scdc)) + args->v0.rekey >0x7f )return -EINVAL ;if (!args->v0.enable) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 92/457 net/sched: act_ct: dont WARN on benign flow_offload_alloc() failure
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nguyen Ngoc Thang <[email protected]>
[ Upstream commit 47abe7a5c4eb53269aca3506446f851572a059a3 ]
flow_offload_alloc() returns NULL when the conntrack entry is dying (e.g. raced with a conntrack flush) or when the GFP_ATOMIC allocation fails; both are expected under load and neither is a kernel bug. This path runs from softirq on every committed packet, so with panic_on_warn=1 an unprivileged user can panic the box just by racing a conntrack flush against a tc ... action ct commit classifier.
Reproduced with a custom repro under QEMU: a small, fixed set of UDP flows through tc filter ... action ct commit on lo, raced against threads flooding bare ctnetlink CT_DELETE (flush) requests. Hits
WARNING: net/sched/act_ct.c:437 (tcf_ct_flow_table_add(), inlined
into tcf_ct_act() in this build) within ~15s on the unpatched kernel; same setup is clean on the patched kernel. The fix itself is
behavior-preserving: both branches already did goto err_alloc before and after, only the WARN is removed.
--- net/sched/act_ct.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
net/sched/act_ct.c +2 -3
@@ -432,11 +432,10 @@ static void tcf_ct_flow_table_add(struct tcf_ct_flow_table *ct_ft,if (test_and_set_bit (IPS_OFFLOAD_BIT , &ct->status))return ; +/* NULL if ct is dying (raced flush) or the atomic alloc failed. */ entry =flow_offload_alloc (ct); -if (!entry) { -WARN_ON_ONCE (1 ); +if (!entry) goto err_alloc; - }if (tcp) { ct->proto.tcp.seen[0 ].flags |=IP_CT_TCP_FLAG_BE_LIBERAL ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 93/457 net: gue: reject invalid REMCSUM offsets
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jérémy Jean <[email protected]>
[ Upstream commit 2566866fc30965d915d0b52b5c3323b362619f0e ]
The REMCSUM option carries an absolute checksum start and checksum field offset. gue_remcsum() passes them to skb_remcsum_process(), whose partial path stores offset - start in the u16 skb->csum_offset variable. If offset is less than start, this underflows.
A forwarded packet can retain CHECKSUM_PARTIAL and reach a NETIF_F_HW_CSUM driver which trusts the metadata, leading skb_copy_and_csum_dev() to write two bytes about 64 KiB beyond the destination buffer.
Reject reversed tuples in validate_gue_flags(), after the existing length validation, so all GUE parsers enforce the ordering in one place.
--- include/net/gue.h | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
include/net/gue.h +15 -4
@@ -84,8 +84,9 @@ static inline size_t guehdr_priv_flags_len(__be32 flags) }/* Validate standard and private flags. Returns non-zero (meaning invalid) -* if there is an unknown standard or private flags, or the options length for -* the flags exceeds the options length specific in hlen of the GUE header. +* if there is an unknown standard or private flags, if the options length for +* the flags exceeds the options length specified in hlen of the GUE header, or +* if a private option contains invalid data. */ static inline int validate_gue_flags (struct guehdr *guehdr,size_t optlen) {
@@ -103,8 +104,8 @@ static inline int validate_gue_flags(struct guehdr *guehdr, size_t optlen)/* Private flags are last four bytes accounted in * guehdr_flags_len */ -__be32 pflags = *(__be32 *)((void *)&guehdr[1 ] + - len -GUE_LEN_PRIV ); +void *data = (void *)&guehdr[1 ] + len; +__be32 pflags = *(__be32 *)(data -GUE_LEN_PRIV );if (pflags & ~GUE_PFLAGS_ALL )return 1 ;
@@ -112,6 +113,16 @@ static inline int validate_gue_flags(struct guehdr *guehdr, size_t optlen) len +=guehdr_priv_flags_len (pflags);if (len > optlen)return 1 ; + +if (pflags &GUE_PFLAG_REMCSUM ) { +__be16 *pd = data; + +/* The field offset pd[1] must not be less +* than the start pd[0]. +*/ +if (ntohs (pd[1 ]) <ntohs (pd[0 ])) +return 1 ; + } }return 0 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 94/457 net: ethernet: mtk_eth_soc: unregister net_devices in case of probe failure
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <[email protected]>
[ Upstream commit 310d1ac61a4d5a2ca8356a3a48d263acf54503ce ]
If register_netdev() fails for one of the MTK_MAX_DEVS devices in mtk_probe(), the error path jumps to err_deinit_ppe, skipping mtk_unreg_dev(). The previously registered net_devices are then freed by mtk_free_dev() while still in NETREG_REGISTERED state, hitting the BUG_ON(dev->reg_state != NETREG_UNREGISTERED).
Route the register_netdev() failure to err_unreg_netdev so the net_devices registered so far are properly unregistered before being freed.
--- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +5 -1
@@ -4508,6 +4508,10 @@ static int mtk_unreg_dev(struct mtk_eth *eth) mac =netdev_priv (eth->netdev[i]);if (MTK_HAS_CAPS (eth->soc->caps,MTK_QDMA ))unregister_netdevice_notifier (&mac->device_notifier); + +if (eth->netdev[i]->reg_state !=NETREG_REGISTERED ) +continue ; +unregister_netdev (eth->netdev[i]); }
@@ -5339,7 +5343,7 @@ static int mtk_probe(struct platform_device *pdev) err =register_netdev (eth->netdev[i]);if (err) {dev_err (eth->dev,"error bringing up device\n" ); - goto err_deinit_ppe; + goto err_unreg_netdev; }else netif_info(eth, probe, eth->netdev[i], "mediatek frame engine at 0x%08lx, irq %d\n",
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 95/457 ip6_gre: Call ip6erspan_tunnel_unlink_md() in ip6erspan_changelink().
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit dd47bcf279f1083f09bf5266890b26263361022b ]
The cited commit accidentally added ip6gre_tunnel_unlink_md() in ip6erspan_changelink().
Let's correct it to ip6erspan_tunnel_unlink_md().
--- net/ipv6/ip6_gre.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv6/ip6_gre.c +1 -1
@@ -2280,7 +2280,7 @@ static int ip6erspan_changelink(struct net_device *dev, struct nlattr *tb[],return PTR_ERR (t);ip6erspan_set_version (data, &p); -ip6gre_tunnel_unlink_md (ign, t); +ip6erspan_tunnel_unlink_md (ign, t);ip6gre_tunnel_unlink (ign, t);ip6erspan_tnl_change (t, &p, !tb[IFLA_MTU ]);ip6erspan_tunnel_link_md (ign, t);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 96/457 net: ethtool: keep rtnl_lock for the ioctl self test
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Duyck <[email protected]>
[ Upstream commit 1b82958f3f035df5ccaab5430a2302f08a5d5351 ]
An offline self test that brings the interface down and back up with netif_close() / netif_open() requires rtnl_lock for both. Since the ethtool IOCTL path became rtnl-optional for ops-locked drivers, the ETHTOOL_TEST ioctl runs holding only the netdev instance lock, so on an ops-locked driver the self test now tears the device down without rtnl_lock.
With lockdep this reproduces deterministically on every offline self test on such a driver; note the sole lock held is the instance lock, not rtnl:
WARNING: suspicious RCU usage
net/core/netpoll.c:207 suspicious rcu_dereference_protected() usage! 1 lock held by ethtool/107:
#0: (&dev->lock){+.+.}, at: dev_ethtool
Call Trace: netpoll_poll_disable __dev_close_many netif_close_many netif_close fbnic_self_test dev_ethtool_locked dev_ethtool dev_ioctl sock_ioctl __x64_sys_ioctl
Without lockdep the same condition trips ASSERT_RTNL() in __dev_close_many() / __dev_open(); that check only samples the global rtnl state, so it can be masked by a concurrent rtnl holder, but the device is still being reconfigured without the lock it requires.
The ethtool self_test is a legacy ioctl-only command, so an ETHTOOL_TEST case is only needed on the ioctl path. Add an opt-in bit for drivers whose self test needs rtnl_lock and set it on the ops-locked drivers whose offline self test tears the interface down and up:
- fbnic (ops-locked via queue_mgmt_ops): fbnic_self_test() offline path uses netif_close() / netif_open().
- bnxt (ops-locked via queue_mgmt_ops): bnxt_self_test() offline path goes through bnxt_close_nic() / bnxt_half_open_nic() / bnxt_half_close_nic() / bnxt_open_nic(), which close and reopen the device.
--- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 3 ++- drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c | 3 ++- include/linux/ethtool.h | 2 ++ net/ethtool/common.h | 2 ++ 4 files changed, 8 insertions(+), 2 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +2 -1
@@ -5733,7 +5733,8 @@ const struct ethtool_ops bnxt_ethtool_ops = { .op_needs_rtnl = ETHTOOL_OP_NEEDS_RTNL_SCHANNELS |ETHTOOL_OP_NEEDS_RTNL_SRINGPARAM |ETHTOOL_OP_NEEDS_RTNL_SCOALESCE | - ETHTOOL_OP_NEEDS_RTNL_RSS, +ETHTOOL_OP_NEEDS_RTNL_RSS | + ETHTOOL_OP_NEEDS_RTNL_TEST, .supported_coalesce_params =ETHTOOL_COALESCE_USECS |ETHTOOL_COALESCE_MAX_FRAMES | ETHTOOL_COALESCE_USECS_IRQ |
drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c +2 -1
@@ -2025,7 +2025,8 @@ static const struct ethtool_ops fbnic_ethtool_ops = {ETHTOOL_OP_NEEDS_RTNL_SPAUSEPARAM |ETHTOOL_OP_NEEDS_RTNL_SCHANNELS |ETHTOOL_OP_NEEDS_RTNL_SRINGPARAM | - ETHTOOL_OP_NEEDS_RTNL_GLINK, +ETHTOOL_OP_NEEDS_RTNL_GLINK | + ETHTOOL_OP_NEEDS_RTNL_TEST, .get_drvinfo = fbnic_get_drvinfo, .get_regs_len = fbnic_get_regs_len, .get_regs = fbnic_get_regs,
include/linux/ethtool.h +2 -0
@@ -944,6 +944,7 @@ struct kernel_ethtool_ts_info {#define ETHTOOL_OP_NEEDS_RTNL_SPAUSEPARAM BIT(6)#define ETHTOOL_OP_NEEDS_RTNL_RSS BIT(7)#define ETHTOOL_OP_NEEDS_RTNL_GLINK BIT(8) +#define ETHTOOL_OP_NEEDS_RTNL_TEST BIT(9)/** * struct ethtool_ops - optional netdev operations
@@ -981,6 +982,7 @@ struct kernel_ethtool_ts_info {* - netdev_update_features() * - netif_set_real_num_tx_queues() * - ethtool_op_get_link() (syncs link watch under rtnl_lock) +* - netif_open() / netif_close() (used by @self_test) * * @get_drvinfo: Report driver/device information. Modern drivers no * longer have to implement this callback. Most fields are
net/ethtool/common.h +2 -0
@@ -163,6 +163,8 @@ ethtool_ioctl_needs_rtnl(const struct net_device *dev, u32 ethcmd)return ops->op_needs_rtnl ÐTOOL_OP_NEEDS_RTNL_RSS ;case ETHTOOL_GLINK :return ops->op_needs_rtnl ÐTOOL_OP_NEEDS_RTNL_GLINK ; +case ETHTOOL_TEST : +return ops->op_needs_rtnl ÐTOOL_OP_NEEDS_RTNL_TEST ; }return false; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 97/457 eth: fbnic: Handle maximum standalone channels
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Björn Töpel <[email protected]>
[ Upstream commit 1f4c73064a50f53d596c6f1d06d2d700f43c4b32 ]
Standalone channels use one NAPI vector for each Tx and Rx queue. fbnic's allocation path excludes FBNIC_MAX_TXQS from that layout. A 64-Tx/64-Rx configuration therefore records 128 vectors but allocates only 64, leaving NULL entries that resource setup dereferences.
Include the maximum vector count in standalone allocation.
--- drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/meta/fbnic/fbnic_txrx.c +1 -1
@@ -1791,7 +1791,7 @@ int fbnic_alloc_napi_vectors(struct fbnic_net *fbn)int err;/* Allocate 1 Tx queue per napi vector */ -if (num_napi <FBNIC_MAX_TXQS && num_napi == num_tx + num_rx) { +if (num_napi <=FBNIC_MAX_TXQS && num_napi == num_tx + num_rx) {while (num_tx) { err = fbnic_alloc_napi_vector(fbd, fbn, num_napi, v_idx,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 98/457 eth: fbnic: use the Rx queue napi pointer to find the napi vector
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Duyck <[email protected]>
[ Upstream commit b5d9e9d4d0c13bc8b60d8d97e7a07fb25fea639e ]
The queue management ndos pick the napi vector for an Rx queue with:
nv = fbn->napi[idx % fbn->num_napi];
The issue is this is only correct in the cases where there are no standalone Tx vectors. In those cases we were allocating the Tx vectors first and then the Rx so the queues would be pointing to Tx NAPI vectors instead of the Rx ones.
The mapping the ndos want is already recorded. fbnic_set_netif_napi() publishes it with netif_queue_set_napi(), which stores the napi pointer in netdev_rx_queue.napi, and fbnic_reset_netif_napi() clears it again. Both run under the netdev instance lock that the queue management ndos also hold, so the pointer can be read directly.
Use it and drop the divide. The pointer is NULL exactly while the datapath is down, so fbnic_queue_mem_alloc() can reject that case rather than reaching into freed state: netdev_rx_queue_restart() calls it before it tests netif_running(), and fbnic_pm_suspend() leaves netif_running() true across a PCIe recovery that never completes, so a queue restart can arrive after fbnic_stop() has freed the rings and the vectors. fbnic_stop() clears the association in fbnic_reset_netif_queues() before fbnic_free_napi_vectors(), so the NULL is always published first. fbnic_queue_start() and fbnic_queue_stop() need no check of their own, as netdev_rx_queue_reconfig() only reaches them once fbnic_queue_mem_alloc() has succeeded under the same instance lock.
--- drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 26 +++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-)
drivers/net/ethernet/meta/fbnic/fbnic_txrx.c +23 -3
@@ -7,6 +7,7 @@#include <linux/iopoll.h> #include <linux/pci.h> #include <net/netdev_queues.h> +#include <net/netdev_rx_queue.h> #include <net/page_pool/helpers.h> #include <net/tcp.h> #include <net/xdp.h>
@@ -2853,6 +2854,17 @@ void fbnic_napi_depletion_check(struct net_device *netdev)fbnic_wrfl (fbd); } +/* Returns the napi vector servicing an Rx queue, or NULL if the datapath +* is torn down. The association is published by fbnic_set_netif_napi() +* and cleared by fbnic_reset_netif_napi(), both under the instance lock. +*/ +static struct fbnic_napi_vector *fbnic_rxq_nv (struct net_device *dev,int idx) +{ +struct napi_struct *napi =__netif_get_rx_queue (dev, idx)->napi; + + return napi ? container_of(napi, struct fbnic_napi_vector, napi) : NULL; +} +static int fbnic_queue_mem_alloc (struct net_device *dev,struct netdev_queue_config *qcfg,void *qmem,int idx)
@@ -2865,8 +2877,16 @@ static int fbnic_queue_mem_alloc(struct net_device *dev,if (!netif_running (dev))return fbnic_alloc_qt_page_pools (fbn, qt, idx); +/* A failed PCIe recovery or resume can leave the datapath torn down +* while netif_running() is still true. This ndo runs before +* netdev_rx_queue_restart() checks netif_running(), so bail out +* rather than touching rings and vectors that are already freed. +*/ + nv =fbnic_rxq_nv (dev, idx); +if (!nv) +return -ENETDOWN ; + real = container_of(fbn->rx[idx], struct fbnic_q_triad, cmpl); - nv = fbn->napi[idx % fbn->num_napi];fbnic_ring_init (&qt->sub0, real->sub0.doorbell, real->sub0.q_idx, real->sub0.flags);
@@ -2917,7 +2937,7 @@ static int fbnic_queue_start(struct net_device *dev,struct fbnic_q_triad *real; real = container_of(fbn->rx[idx], struct fbnic_q_triad, cmpl); - nv = fbn->napi[idx % fbn->num_napi]; + nv =fbnic_rxq_nv (dev, idx);fbnic_aggregate_ring_bdq_counters (fbn, &real->sub0);fbnic_aggregate_ring_bdq_counters (fbn, &real->sub1);
@@ -2939,7 +2959,7 @@ static int fbnic_queue_stop(struct net_device *dev, void *qmem, int idx)int err; real = container_of(fbn->rx[idx], struct fbnic_q_triad, cmpl); - nv = fbn->napi[idx % fbn->num_napi]; + nv =fbnic_rxq_nv (dev, idx);fbnic_dbg_nv_exit (nv);napi_disable_locked (&nv->napi);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 99/457 eth: fbnic: reset num_napi when the napi vectors are freed
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Duyck <[email protected]>
[ Upstream commit 4bcc4a92c603fe7f062cea22e20da2e0ad6b12c3 ]
fbn->num_napi is the count of live napi vectors, each of which owns an IRQ. The PM path had freed them without clearing the count. fbnic_pm_suspend() tears the datapath down via ndo_stop() and frees the IRQs, but leaves netif_running() true so resume knows to re-open. Resume rebuilds the datapath in __fbnic_pm_resume() and fbnic_reset_queues() sets num_napi and __fbnic_open() re-allocates the vectors.
When the datapath is torn down but never rebuilt, num_napi is left pointing at freed vectors under 2 different scenarios:
- a PCIe error recovery that fails (fbnic_err_slot_reset() -> __fbnic_pm_resume() returns an error -> PCI_ERS_RESULT_DISCONNECT), so .resume never runs; or
- an __fbnic_open() that fails partway on resume and unwinds, freeing the vectors after fbnic_reset_queues() has already set num_napi.
The netdev is then running with num_napi > 0 but napi[] freed, and the eventual remove/unbind close re-enters fbnic_down() -> fbnic_dbg_down() and dereferences the freed vectors:
BUG: kernel NULL pointer dereference, address: 0000000000000210 RIP: fbnic_dbg_down+0x28
Clear num_napi when the vectors are freed: in the suspend teardown (a good resume re-establishes it before __fbnic_open()) and on the resume open failure. A redundant ndo_stop() then walks an empty napi[]. The normal ndo_stop() down/up cycle is untouched and keeps num_napi for the next ndo_open().
--- drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
drivers/net/ethernet/meta/fbnic/fbnic_pci.c +14 -4
@@ -434,6 +434,7 @@ static int fbnic_pm_suspend(struct device *dev) {struct fbnic_dev *fbd =dev_get_drvdata (dev);struct net_device *netdev = fbd->netdev; +struct fbnic_net *fbn;if (fbnic_init_failure (fbd)) goto null_uc_addr;
@@ -441,11 +442,16 @@ static int fbnic_pm_suspend(struct device *dev)rtnl_lock ();netdev_lock (netdev); + fbn =netdev_priv (netdev); +netif_device_detach (netdev);if (netif_running (netdev)) netdev->netdev_ops->ndo_stop (netdev); +/* The IRQs are about to be freed, so drop the napi vector count */ + fbn->num_napi =0 ; +netdev_unlock (netdev);rtnl_unlock ();
@@ -508,16 +514,20 @@ static int __fbnic_pm_resume(struct device *dev)if (fbnic_init_failure (fbd))return 0 ; +rtnl_lock (); +netdev_lock (netdev); + fbn =netdev_priv (netdev);/* Reset the queues if needed */ fbnic_reset_queues (fbn, fbn->num_tx_queues, fbn->num_rx_queues); -rtnl_lock (); -netdev_lock (netdev); - -if (netif_running (netdev)) +if (netif_running (netdev)) { err =__fbnic_open (fbn); +/* On failure the vectors are freed, so drop the count */ +if (err) + fbn->num_napi =0 ; + }netdev_unlock (netdev);rtnl_unlock ();
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 100/457 eth: fbnic: Set AW_FLUSH_MODE alongside AW_FLUSH when flushing the mailbox
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Duyck <[email protected]>
[ Upstream commit 8947f13e436a4ff5eed9f8f019b2865a07af4bb2 ]
When tearing down the FW mailbox Rx ring, fbnic_mbx_reset_desc_ring() writes AW_CFG with FLUSH set and everything else, BME included, cleared. Clearing BME halts the device's writes to the host but leaves the staged requests parked in the PUL write pipeline rather than draining them, so on the write path FLUSH alone never terminates the outstanding requests and the flush the firmware waits on never completes.
Add the FLUSH_MODE definition and set both bits so the staged writes drain out of the pipeline on their own. BME stays cleared, so nothing lands on the host; it is restored later in fbnic_mbx_init_desc_ring() when the ring is rebuilt, once the outstanding writes are gone.
The read path is unaffected. AR_CFG has no equivalent mode bit and AR_FLUSH terminates the outstanding reads by itself, so it is left as is.
Both writes remain plain stores rather than read-modify-writes. That is
deliberate: the matching write in fbnic_mbx_init_desc_ring() restores BME and the TLP attributes, and clears both flush bits as a side effect.
--- drivers/net/ethernet/meta/fbnic/fbnic_csr.h | 1 + drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-)
drivers/net/ethernet/meta/fbnic/fbnic_csr.h +1 -0
@@ -974,6 +974,7 @@ enum {/* PUL User Registers */ #define FBNIC_CSR_START_PUL_USER 0x31000/* CSR section delimiter */ #define FBNIC_PUL_OB_TLP_HDR_AW_CFG 0x3103d/* 0xc40f4 */ +#define FBNIC_PUL_OB_TLP_HDR_AW_CFG_FLUSH_MODE CSR_BIT(20)#define FBNIC_PUL_OB_TLP_HDR_AW_CFG_FLUSH CSR_BIT(19)#define FBNIC_PUL_OB_TLP_HDR_AW_CFG_BME CSR_BIT(18)#define FBNIC_PUL_OB_TLP_HDR_AW_CFG_RDE_ATTR CSR_GENMASK(17, 15)
drivers/net/ethernet/meta/fbnic/fbnic_fw.c +8 -1
@@ -60,8 +60,15 @@ static void fbnic_mbx_reset_desc_ring(struct fbnic_dev *fbd, int mbx_idx)*/ switch (mbx_idx) {case FBNIC_IPC_MBX_RX_IDX : +/* Clearing BME blocks the device from writing to the host +* but leaves the requests parked in the write pipeline. The +* write path only clears outstanding requests when both FLUSH +* and FLUSH_MODE are set; FLUSH_MODE lets them drain without +* landing on the host. +*/ wr32 (fbd,FBNIC_PUL_OB_TLP_HDR_AW_CFG , -FBNIC_PUL_OB_TLP_HDR_AW_CFG_FLUSH ); +FBNIC_PUL_OB_TLP_HDR_AW_CFG_FLUSH | +FBNIC_PUL_OB_TLP_HDR_AW_CFG_FLUSH_MODE );break ;case FBNIC_IPC_MBX_TX_IDX : wr32(fbd, FBNIC_PUL_OB_TLP_HDR_AR_CFG,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 101/457 eth: fbnic: Handle FW mailbox completions flagged with an error
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Duyck <[email protected]>
[ Upstream commit 1b97a269a5bdde20d4e69511f27649c9cb82b7c7 ]
The firmware can complete a mailbox descriptor while also setting FW_ERR to indicate it could not process the request, for example on a mailbox DMA error. The completion carries no valid data.
The driver did not check FW_ERR. On the Rx mailbox it would sync and parse the stale page as a normal message, and on the Tx mailbox it silently freed the request. If the initial capabilities exchange in fbnic_mbx_poll_tx_ready() hit FW_ERR -- on the Tx request or on the Rx response descriptor -- no response was parsed and the poll spun until it timed out even though the ring was healthy.
Check FW_ERR on both mailboxes. Count it per-mailbox in fbnic_fw_mbx.resp_error, which is also shown in debugfs, warn (rate limited, since the bit is firmware controlled), and drop the Rx page instead of parsing it.
In fbnic_mbx_poll_tx_ready() re-issue the capabilities request when either the Tx or the Rx resp_error counter advances, so a FW_ERR on the request or on its response triggers a retry rather than a timeout. A valid capabilities response is honored before the retry check, so a response parsed in the same poll as an unrelated FW_ERR is not discarded. The counters are mailbox-wide rather than keyed to the capabilities request; that is sufficient here because the exchange runs during bring-up before any other mailbox traffic, and any spurious retry is bounded by the existing 10s timeout.
--- drivers/net/ethernet/meta/fbnic/fbnic_csr.h | 4 ++ .../net/ethernet/meta/fbnic/fbnic_debugfs.c | 4 +- drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 38 ++++++++++++++++++- drivers/net/ethernet/meta/fbnic/fbnic_fw.h | 1 + 4 files changed, 44 insertions(+), 3 deletions(-)
drivers/net/ethernet/meta/fbnic/fbnic_csr.h +4 -0
@@ -1216,6 +1216,10 @@ enum {#define FBNIC_IPC_MBX_DESC_LEN_MASK DESC_GENMASK(63, 48)#define FBNIC_IPC_MBX_DESC_EOM DESC_BIT(46)#define FBNIC_IPC_MBX_DESC_ADDR_MASK DESC_GENMASK(45, 3) +/* Set with FW_CMPL when the FW completed a descriptor without successfully +* processing it (e.g. a mailbox DMA error); the completion has no valid data. +*/ +#define FBNIC_IPC_MBX_DESC_FW_ERR DESC_BIT(2)#define FBNIC_IPC_MBX_DESC_FW_CMPL DESC_BIT(1)#define FBNIC_IPC_MBX_DESC_HOST_CMPL DESC_BIT(0)
drivers/net/ethernet/meta/fbnic/fbnic_debugfs.c +2 -2
@@ -539,8 +539,8 @@ static void fbnic_dbg_fw_mbx_display(struct seq_file *s,/* Generate header */ seq_puts (s, mbx_idx ==FBNIC_IPC_MBX_RX_IDX ?"Rx\n" :"Tx\n" ); -seq_printf (s,"Rdy: %d Head: %d Tail: %d\n" , - mbx->ready, mbx->head, mbx->tail); +seq_printf (s,"Rdy: %d Head: %d Tail: %d resp_error: %llu\n" , + mbx->ready, mbx->head, mbx->tail, mbx->resp_error);snprintf (hdr,sizeof (hdr),"%3s %-4s %s %-12s %s %-3s %-16s\n" ,"Idx" ,"Len" ,"E" ,"Addr" ,"F" ,"H" ,"Raw" );
drivers/net/ethernet/meta/fbnic/fbnic_fw.c +37 -1
@@ -292,6 +292,12 @@ static void fbnic_mbx_process_tx_msgs(struct fbnic_dev *fbd)if (!(desc &FBNIC_IPC_MBX_DESC_FW_CMPL ))break ; +if (desc &FBNIC_IPC_MBX_DESC_FW_ERR ) { + tx_mbx->resp_error++; +dev_warn_ratelimited (fbd->dev, +"FW completed a Tx mailbox request with an error\n" ); + } +fbnic_mbx_unmap_and_free_msg (fbd,FBNIC_IPC_MBX_TX_IDX , head); head++;
@@ -1673,6 +1679,13 @@ static void fbnic_mbx_process_rx_msgs(struct fbnic_dev *fbd)if (!(desc &FBNIC_IPC_MBX_DESC_FW_CMPL ))break ; +if (desc &FBNIC_IPC_MBX_DESC_FW_ERR ) { + rx_mbx->resp_error++; +dev_warn_ratelimited (fbd->dev, +"FW reported an error on an Rx mailbox message; dropping\n" ); + goto next_page; + } +dma_sync_single_for_cpu (fbd->dev, rx_mbx->buf_info[head].addr,FBNIC_RX_PAGE_SIZE ,DMA_FROM_DEVICE );
@@ -1740,7 +1753,9 @@ void fbnic_mbx_poll(struct fbnic_dev *fbd)int fbnic_mbx_poll_tx_ready (struct fbnic_dev *fbd) {struct fbnic_fw_mbx *tx_mbx = &fbd->mbx[FBNIC_IPC_MBX_TX_IDX ]; +struct fbnic_fw_mbx *rx_mbx = &fbd->mbx[FBNIC_IPC_MBX_RX_IDX ];unsigned long timeout = jiffies +10 *HZ +1 ; +u64 tx_resp_error, rx_resp_error;int err, i; do {
@@ -1771,6 +1786,9 @@ int fbnic_mbx_poll_tx_ready(struct fbnic_dev *fbd)* mgmt.version once we get the actual version from the firmware * in the capabilities request message. */ +send_cap_req: + tx_resp_error = tx_mbx->resp_error; + rx_resp_error = rx_mbx->resp_error; err =fbnic_fw_xmit_simple_msg (fbd,FBNIC_TLV_MSG_ID_HOST_CAP_REQ );if (err) goto clean_mbx;
@@ -1788,9 +1806,27 @@ int fbnic_mbx_poll_tx_ready(struct fbnic_dev *fbd)msleep (20 );fbnic_mbx_poll (fbd); +/* A valid capabilities response ends the poll. Check it +* before the FW_ERR retry below so a response parsed in the +* same poll as an unrelated FW_ERR is not discarded. +*/ +if (fbd->fw_cap.running.mgmt.version >=MIN_FW_VER_CODE ) +break ; +/* set err, but wait till mgmt.version check to report it */ -if (!time_is_after_jiffies (timeout)) +if (!time_is_after_jiffies (timeout)) { err = -ETIMEDOUT ; +continue ; + } + +/* The FW can flag our capabilities request (Tx) or its +* response (Rx) with FW_ERR, in which case it produced no +* usable response. The ring is not wedged, so re-issue the +* request instead of spinning until the timeout. +*/ +if (tx_mbx->resp_error != tx_resp_error || + rx_mbx->resp_error != rx_resp_error) + goto send_cap_req; }return 0 ;
drivers/net/ethernet/meta/fbnic/fbnic_fw.h +1 -0
@@ -13,6 +13,7 @@ struct fbnic_tlv_msg;struct fbnic_fw_mbx {u8 ready, head, tail; +u64 resp_error;struct {struct fbnic_tlv_msg *msg;dma_addr_t addr;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 102/457 sctp: avoid livelock while updating retransmit path
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yiqi Sun <[email protected]>
[ Upstream commit d2c31b837406395e576afeb25958c98e9938f3f6 ]
sctp_assoc_update_retran_path() can loop forever when every remaining transport, including retran_path, is SCTP_UNCONFIRMED: the state check runs before the wraparound test, so the loop cannot observe that it has completed a full pass.
Fix this by considering a transport only when it is not UNCONFIRMED, then checking whether the walk has returned to retran_path. This makes the full-pass termination independent of the transport state while preserving the existing fallback selection semantics.
Also restore the NULL guard around the retran_path assignment. In the all-UNCONFIRMED case there is no eligible replacement transport, and installing NULL would leave later retransmit-path users and the debug print with a NULL path.
--- net/sctp/associola.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
net/sctp/associola.c +8 -7
@@ -1285,18 +1285,19 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc)/* Manually skip the head element. */ if (&trans->transports == &asoc->peer.transport_addr_list)continue ; -if (trans->state ==SCTP_UNCONFIRMED ) -continue ; - trans_next =sctp_trans_elect_best (trans, trans_next); -/* Active is good enough for immediate return. */ -if (trans_next->state ==SCTP_ACTIVE ) -break ; +if (trans->state !=SCTP_UNCONFIRMED ) { + trans_next =sctp_trans_elect_best (trans, trans_next); +/* Active is good enough for immediate return. */ +if (trans_next->state ==SCTP_ACTIVE ) +break ; + }/* We've reached the end, time to update path. */ if (trans == asoc->peer.retran_path)break ; } - asoc->peer.retran_path = trans_next; +if (trans_next) + asoc->peer.retran_path = trans_next;pr_debug ("%s: association:%p updated new path to addr:%pISpc\n" , __func__, asoc, &asoc->peer.retran_path->ipaddr.sa);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 103/457 net: allow IFLA_INET_CONF messages when NLA_F_NESTED unset
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Quentin Armitage <[email protected]>
[ Upstream commit 6c096bb08de97cdca051fecddad22cac6a1fd275 ]
Commit fa8fca88714c ("ipv4: validate IPV4_DEVCONF attributes properly") added validation of IFLA_INET_CONF attributes, and in the process changed the call of nla_for_each_nested() to nla_parse_nested(). A side effect of this change is that the IFLA_INET_CONF option is now tested for NLA_F_NESTED being set, and fails if it is not. Prior to the commit there was no check of NLA_F_NESTED.
Change nla_parse_nested() to nla_parse(). This restores the previous functionality of not checking NLA_F_NESTED, thereby allowing code that (incorrectly) doesn't set NLA_F_NESTED to continue to work.
This issue was identified because keepalived started logging errors when it was configuring macvlans that it created.
--- net/ipv4/devinet.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
net/ipv4/devinet.c +4 -3
@@ -2117,9 +2117,10 @@ static int inet_validate_link_af(const struct net_device *dev,return err;if (tb[IFLA_INET_CONF ]) { - err =nla_parse_nested (nested_tb,IPV4_DEVCONF_MAX , - tb[IFLA_INET_CONF ], inet_devconf_policy, - extack); + err =nla_parse (nested_tb,IPV4_DEVCONF_MAX , +nla_data (tb[IFLA_INET_CONF ]), +nla_len (tb[IFLA_INET_CONF ]), + inet_devconf_policy, extack);if (err <0 )return err;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 104/457 bpf: Bound ownership depth through local kptrs and graph roots
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <[email protected]>
[ Upstream commit bfc888f04588f591851e95c974954cfca58e6c19 ]
Program-allocated objects can own other local objects through referenced kptrs. bpf_obj_free_fields() follows those pointers through __bpf_obj_drop_impl() synchronously, before the object storage is freed through RCU. A self-referential local kptr type therefore permits arbitrarily deep object chains, and dropping the head can exhaust the kernel stack. Long acyclic type chains have the same problem.
btf_check_and_fixup_fields() still assumes referenced kptrs only point to kernel types and checks ownership through list and rbtree roots only. Its existing rule is sufficient for graph-only cycles: the target of each graph edge must contain a node, so every type in a cycle has both a root and a node. The rule rejects such a type owning another root, breaking every cycle. It also limits graph-only chains to three types, or two if the first type contains a node, and conservatively rejects longer acyclic chains. The missing local-kptr edges, rather than a missed graph-only cycle, are the bug introduced by support for bpf_kptr_xchg() into local kptrs.
Replace that restriction with one bounded ownership walk covering graph roots and local referenced kptrs. Run it after all BTF records have been fixed up, reject cycles and paths deeper than eight record-bearing types, and cache each type's suffix depth while checking it against the remaining budget. This also permits the longer acyclic graph-only layouts rejected by the old rule; update their existing BTF tests accordingly.
Keep the bound independent of MAX_CALL_FRAMES because recursive destruction can run below a BPF call chain. A plain local pointee without special-field metadata adds only a final non-recursing drop. Non-owning kptrs and kernel-BTF kptrs do not recurse through local records and remain outside the walk. Include local percpu-kptr edges too, although allocation of percpu objects with special fields is currently forbidden, so that relaxing that restriction cannot bypass the ownership bound.
btf_check_and_fixup_fields() continues to initialize graph_root.value_rec, including for separately allocated map records. The ownership relationships belong to immutable program BTF and only need validation at BTF load time.
--- kernel/bpf/btf.c | 134 +++++++++++------- .../selftests/bpf/prog_tests/linked_list.c | 4 +- 2 files changed, 88 insertions(+), 50 deletions(-)
kernel/bpf/btf.c +86 -48
@@ -4269,13 +4269,10 @@ int btf_check_and_fixup_fields(const struct btf *btf, struct btf_record *rec) {int i; -/* There are three types that signify ownership of some other type: -* kptr_ref, bpf_list_head, bpf_rb_root. -* kptr_ref only supports storing kernel types, which can't store -* references to program allocated local types. -* -* Hence we only need to ensure that bpf_{list_head,rb_root} ownership -* does not form cycles. +/* +* Check fields which require the complete BTF and initialize runtime +* metadata. Ownership relationships are validated after every record has +* been fixed up. */ if (IS_ERR_OR_NULL (rec) || !(rec->field_mask & (BPF_GRAPH_ROOT |BPF_UPTR )))return 0 ;
@@ -4306,51 +4303,88 @@ int btf_check_and_fixup_fields(const struct btf *btf, struct btf_record *rec)if (!meta)return -EFAULT ; rec->fields[i].graph_root.value_rec = meta->record; + } +return 0 ; +} -/* We need to set value_rec for all root types, but no need -* to check ownership cycle for a type unless it's also a -* node type. -*/ -if (!(rec->field_mask &BPF_GRAPH_NODE )) +static int btf_owned_type_idx (const struct btf *btf,struct btf_struct_metas *tab, +const struct btf_field *field) +{ +struct btf_struct_meta *meta; +u32 btf_id; + +if (field->type &BPF_GRAPH_ROOT ) { + btf_id = field->graph_root.value_btf_id; + }else if (field->type ==BPF_KPTR_REF || field->type ==BPF_KPTR_PERCPU ) { +if (btf_is_kernel (field->kptr.btf)) +return -ENOENT ; + btf_id = field->kptr.btf_id; + }else { +return -ENOENT ; + } + + meta =btf_find_struct_meta (btf, btf_id); +if (!meta) +return field->type &BPF_GRAPH_ROOT ? -EFAULT : -ENOENT ; +return meta - tab->types; +} + +/* +* Each ownership edge adds kernel frames through bpf_obj_free_fields() and +* __bpf_obj_drop_impl(). Keep the bound deliberately small because object +* destruction can itself run below a BPF call chain. A final pointee without +* special fields is not present in the struct metadata table and adds only a +* non-recursing drop. +*/ +#define BTF_MAX_OWNERSHIP_DEPTH 8 + +static int btf_ownership_depth (const struct btf *btf, +struct btf_struct_metas *tab,u8 *depth, +int idx,int depth_left) +{ +const struct btf_record *rec = tab->types[idx].record; +int i, ret, max_depth =0 ; + +if (!depth_left) +return -ELOOP ; +if (depth[idx]) + goto done; + +for (i =0 ; i < rec->cnt; i++) { + ret =btf_owned_type_idx (btf, tab, &rec->fields[i]); +if (ret == -ENOENT )continue ; +if (ret <0 ) +return ret; + ret =btf_ownership_depth (btf, tab, depth, ret, depth_left -1 ); +if (ret <0 ) +return ret; + max_depth =max (max_depth, ret); + } + depth[idx] = max_depth +1 ; +done: +return depth[idx] > depth_left ? -ELOOP : depth[idx]; +} -/* We need to ensure ownership acyclicity among all types. The -* proper way to do it would be to topologically sort all BTF -* IDs based on the ownership edges, since there can be multiple -* bpf_{list_head,rb_node} in a type. Instead, we use the -* following resaoning: -* -* - A type can only be owned by another type in user BTF if it -* has a bpf_{list,rb}_node. Let's call these node types. -* - A type can only _own_ another type in user BTF if it has a -* bpf_{list_head,rb_root}. Let's call these root types. -* -* We ensure that if a type is both a root and node, its -* element types cannot be root types. -* -* To ensure acyclicity: -* -* When A is an root type but not a node, its ownership -* chain can be: -* A -> B -> C -* Where: -* - A is an root, e.g. has bpf_rb_root. -* - B is both a root and node, e.g. has bpf_rb_node and -* bpf_list_head. -* - C is only an root, e.g. has bpf_list_node -* -* When A is both a root and node, some other type already -* owns it in the BTF domain, hence it can not own -* another root type through any of the ownership edges. -* A -> B -* Where: -* - A is both an root and node. -* - B is only an node. -*/ -if (meta->record->field_mask &BPF_GRAPH_ROOT ) -return -ELOOP ; +static int btf_check_ownership_depth (const struct btf *btf, +struct btf_struct_metas *tab) +{ +u8 *depth; +int i, ret =0 ; + + depth =kvcalloc (tab->cnt,sizeof (*depth),GFP_KERNEL | __GFP_NOWARN); +if (!depth) +return -ENOMEM ; + +for (i =0 ; i < tab->cnt; i++) { + ret =btf_ownership_depth (btf, tab, depth, i, +BTF_MAX_OWNERSHIP_DEPTH ); +if (ret <0 ) +break ; + ret =0 ; } -return 0 ; +kvfree (depth); +return ret; } static void __btf_struct_show(const struct btf *btf, const struct btf_type *t,
@@ -6045,6 +6079,10 @@ static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr,if (err <0 ) goto errout_meta; } + + err =btf_check_ownership_depth (btf, struct_meta_tab); +if (err <0 ) + goto errout_meta; } err =bpf_log_attr_finalize (attr_log, &env->log);
tools/testing/selftests/bpf/prog_tests/linked_list.c +2 -2
@@ -713,7 +713,7 @@ static void test_btf(void)break ; err =btf__load_into_kernel (btf); -ASSERT_EQ (err, -ELOOP ,"check btf" ); +ASSERT_EQ (err,0 ,"check btf" );btf__free (btf);break ; }
@@ -772,7 +772,7 @@ static void test_btf(void)break ; err =btf__load_into_kernel (btf); -ASSERT_EQ (err, -ELOOP ,"check btf" ); +ASSERT_EQ (err,0 ,"check btf" );btf__free (btf);break ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 105/457 net: usb: catc: bound the RX packet length in catc_rx_done()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aamir Ahmed <[email protected]>
[ Upstream commit 9d565b6b72fe3f41fd43636e143072848105189f ]
catc_rx_done() walks a multi-packet URB, reading a two-byte length from each packet header. Its bound, pkt_len > urb->actual_length, ignores the header offset and compares against the whole transfer rather than the bytes left from pkt_start, so a crafted packet header makes skb_copy_to_linear_data() read past the buffer.
A length below ETH_HLEN is also accepted, including zero, and eth_type_trans() then reads a MAC header from the uninitialised tailroom of a shorter skb. The is_f5u011 branch takes its length straight from the transfer, so a zero-length URB reaches the same path.
Track the bytes remaining from the current packet, and reject a header that does not fit, a length past what is left, and a length below an Ethernet header.
A transfer shorter than an Ethernet header, including a zero-length one, previously became a runt skb passed to netif_rx() and counted as received; it is now counted in rx_length_errors and ends the walk.
--- drivers/net/usb/catc.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
drivers/net/usb/catc.c +12 -3
@@ -233,17 +233,26 @@ static void catc_rx_done(struct urb *urb) } do { - if(!catc->is_f5u011) { - pkt_len = le16_to_cpup((__le16*)pkt_start); - if (pkt_len > urb->actual_length) { + int remaining = urb->actual_length - + (pkt_start - (u8 *)urb->transfer_buffer); + + if (!catc->is_f5u011) { + if (remaining < pkt_offset) { catc->netdev->stats.rx_length_errors++; catc->netdev->stats.rx_errors++; break; } + pkt_len = le16_to_cpup((__le16 *)pkt_start); } else { pkt_len = urb->actual_length; } + if (pkt_len < ETH_HLEN || pkt_len + pkt_offset > remaining) { + catc->netdev->stats.rx_length_errors++; + catc->netdev->stats.rx_errors++; + break; + } + if (!(skb = dev_alloc_skb(pkt_len))) return;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 106/457 bpf: Check params size before reading reserved fields
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuqi Xu <[email protected]>
[ Upstream commit a11212910cf09b2fe8db9afa41ef60c4f81879c5 ]
bpf_crypto_ctx_create() is a kfunc whose second argument is declared with the __sz annotation, so the verifier only guarantees that params__sz bytes of params are valid. The function nevertheless reads params->reserved[0] and params->reserved[1] (offsets 14 and 15) before comparing params__sz against the size of struct bpf_crypto_params, so a BPF program can pass a shorter buffer and have the kernel read past the region that was validated for it.
Move the size check in front of the reserved field reads.
--- kernel/bpf/crypto.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
kernel/bpf/crypto.c +3 -2
@@ -149,8 +149,9 @@ bpf_crypto_ctx_create(const struct bpf_crypto_params *params, u32 params__sz,const struct bpf_crypto_type *type;struct bpf_crypto_ctx *ctx; -if (!params || params->reserved[0 ] || params->reserved[1 ] || - params__sz !=sizeof (struct bpf_crypto_params )) { +if (!params || + params__sz !=sizeof (struct bpf_crypto_params ) || + params->reserved[0 ] || params->reserved[1 ]) { *err = -EINVAL ;return NULL ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 107/457 net/sched: sch_hfsc: bound the classify inner-filter walk with a drift budget
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <[email protected]>
[ Upstream commit 8a60ade2277e1f0e0d0578d565354e52292fa46d ]
hfsc_classify() applies the "filter may only point downwards" level check only when the filter result carries no bound class. A filter created with a flowid gets res.class set once at bind time, so the check never runs for it during classification. hfsc_adjust_levels() can later raise a class's level without revalidating existing bindings, leaving two binds that were each legal at bind time pointing at each other; the classify walk then bounces between two interior classes forever with the qdisc lock held and BH disabled — a soft lockup from a single packet. The stuck walk trips the watchdog:
watchdog: BUG: soft lockup - CPU#3 stuck for 13s! [ping:444] RIP: 0010:u32_classify+0x542/0x17f0 ... tcf_classify+0x66/0xa0 hfsc_enqueue+0x166/0xdf0
Bound the traversal with a budget of non-descending hops, the only way a configured walk can move without descending the class tree once levels drift after bind time. The budget is cumulative over the whole walk and is deliberately not reset on a descending hop: a chain that alternates a descent with a lateral hop would return the budget every lap and never trip. Descending hops never decrement it, so legitimately deep trees are unaffected and a terminating lateral chain still classifies normally. Drop the packet with a rate-limited warning once the budget is exhausted, mirroring the merged HTB fix.
This is a follow-up to commit 729c4896ab82 ("net/sched: sch_htb: limit htb_classify inner-class filter hops"), which bounded the same classify loop on the HTB side but left the HFSC walk unbounded.
Conditions to recreate the bug:
- CONFIG_NET_SCHED, CONFIG_NET_SCH_HFSC, CONFIG_NET_CLS_U32, CONFIG_LOCKUP_DETECTOR.
- Build a cycle with two legal-at-bind-time flowid binds and a level
drift: class X 1:1 (child of root) with leaf child 1:10; class Y 1:2 (sibling of X) with children 1:20 and 1:200; root u32 filter flowid 1:1; filter on X flowid 1:2 (legal when Y is a leaf); after Y's level rises to 2, filter on Y flowid 1:1 (legal then). Send one packet (ping on the device). Unfixed kernel: classify spins with the qdisc lock held; with softlockup_panic=1 it panics.
- Reachable from unprivileged user via unshare -Urn (CAP_NET_ADMIN).
--- net/sched/sch_hfsc.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
net/sched/sch_hfsc.c +22 -0
@@ -386,6 +386,15 @@ cftree_update(struct hfsc_class *cl)#define SM_MASK ((1ULL << SM_SHIFT) - 1)#define ISM_MASK ((1ULL << ISM_SHIFT) - 1) +/* +* Cap on the non-descending hops a classify walk may take before its +* filter chain is treated as misconfigured. A flowid binding that was +* legal at bind time can become lateral once hfsc_adjust_levels() +* raises a class level; a few such hops are legitimate, an unbounded +* run means the chain cycles. +*/ +#define HFSC_CLASSIFY_MAX_DRIFT 8 +static inline u64 seg_x2y (u64 x,u64 sm) {
@@ -1133,6 +1142,7 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)struct hfsc_class *head, *cl;struct tcf_result res;struct tcf_proto *tcf; +unsigned int drift;int result; if (TC_H_MAJ(skb->priority ^ sch->handle) == 0 &&
@@ -1142,6 +1152,7 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr) *qerr =NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; head = &q->root; + drift =HFSC_CLASSIFY_MAX_DRIFT ; tcf =rcu_dereference_bh (q->root.filter_list);while (tcf && (result =tcf_classify_qdisc (skb, tcf, &res, false)) >=0 ) {#ifdef CONFIG_NET_CLS_ACT
@@ -1167,6 +1178,17 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)if (cl->level ==0 )return cl;/* hit leaf class */ +/* +* flowid binds skip the level check above (res.class is set +* at bind time and levels drift after), so a walk can follow +* lateral hops without descending; a bounded number of them +* is legal, more means the chain cycles. +*/ +if (cl->level >= head->level && drift-- ==0 ) { +pr_warn_ratelimited ("hfsc: classify hop budget exhausted, dropping packet\n" ); +return NULL ; + } +/* apply inner filter chain */ tcf =rcu_dereference_bh (cl->filter_list); head = cl;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 108/457 drm/virtio: fix object leak when drm_gem_handle_create() fails
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junrui Luo <[email protected]>
[ Upstream commit 36570ef2244cc4d7563b1f0157bc0f032498638c ]
virtio_gpu_gem_create() owns the reference taken by virtio_gpu_object_create(). On the drm_gem_handle_create() error path it calls drm_gem_object_release() instead of dropping that reference.
drm_gem_object_release() is the inverse of drm_gem_object_init() and does not touch the reference count or call obj->funcs->free(), so it is only correct as the last step of a destructor, as in virtio_gpu_cleanup_object(). Using it here leaves the bo at refcount 1 with no remaining reference, so virtio_gpu_free_object() never runs and the shmem pages, sg table and virtio_gpu_object are leaked. Since virtio_gpu_object_create() has already set bo->created, VIRTIO_GPU_CMD_RESOURCE_UNREF is not queued either, leaking the host-side resource and the resource id.
drm_gem_handle_create_tail() drops the handle reference on all of its internal error paths, so the caller only has to drop its own. Use drm_gem_object_put(), matching the success path below.
--- drivers/gpu/drm/virtio/virtgpu_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/virtio/virtgpu_gem.c +1 -1
@@ -45,7 +45,7 @@ static int virtio_gpu_gem_create(struct drm_file *file, ret =drm_gem_handle_create (file, &obj->base.base, &handle);if (ret) { -drm_gem_object_release (&obj->base.base); +drm_gem_object_put (&obj->base.base);return ret; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 109/457 drm/virtio: fix object leak in virtio_gpu_resource_create_ioctl()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junrui Luo <[email protected]>
[ Upstream commit 477bc3068fc3777b9d8ffd79e265b0dfdf2d3a6b ]
virtio_gpu_resource_create_ioctl() calls drm_gem_object_release() on the drm_gem_handle_create() error path instead of dropping the reference it owns, so obj->funcs->free() never runs and the virtio_gpu_object, its pages and sg table, the resource id and the host-side resource are leaked.
Use drm_gem_object_put() instead.
--- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/virtio/virtgpu_ioctl.c +1 -1
@@ -185,7 +185,7 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, ret =drm_gem_handle_create (file, obj, &handle);if (ret) { -drm_gem_object_release (obj); +drm_gem_object_put (obj);return ret; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 110/457 drm/virtio: fix object leaks in virtio_gpu_resource_create_blob_ioctl()
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junrui Luo <[email protected]>
[ Upstream commit 24b6d5c7641412c9ebef0d4c8b888d49a0e6b880 ]
virtio_gpu_resource_create_blob_ioctl() calls drm_gem_object_release() on both the virtio_gpu_resource_assign_uuid() and drm_gem_handle_create() error paths instead of dropping the reference it owns, so obj->funcs->free() never runs and the virtio_gpu_object, the resource id and the host-side resource are leaked.
Use drm_gem_object_put() instead.
--- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/virtio/virtgpu_ioctl.c +2 -2
@@ -557,14 +557,14 @@ static int virtio_gpu_resource_create_blob_ioctl(struct drm_device *dev,if (params.blob_flags &VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE ) { ret =virtio_gpu_resource_assign_uuid (vgdev, bo);if (ret) { -drm_gem_object_release (obj); +drm_gem_object_put (obj);return ret; } } ret =drm_gem_handle_create (file, obj, &handle);if (ret) { -drm_gem_object_release (obj); +drm_gem_object_put (obj);return ret; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 111/457 drm/virtio: release the GEM object on virtio_gpu_vram_create() errors
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junrui Luo <[email protected]>
[ Upstream commit 036d28db1818af2f9d80db771f5405da84d7732d ]
virtio_gpu_vram_create() frees the object with a bare kfree(vram) on both error paths after drm_gem_private_object_init() has run, and on the second one after drm_gem_create_mmap_offset() has linked obj->vma_node into the device's VMA offset manager. The freed object stays in that interval tree, so a later lookup or insertion walks freed memory, and the dma_resv and gpuva lock are never destroyed.
Call drm_gem_object_release() before kfree() on both paths.
--- drivers/gpu/drm/virtio/virtgpu_vram.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
drivers/gpu/drm/virtio/virtgpu_vram.c +9 -8
@@ -212,16 +212,12 @@ int virtio_gpu_vram_create(struct virtio_gpu_device *vgdev,/* Create fake offset */ ret =drm_gem_create_mmap_offset (obj); -if (ret) { -kfree (vram); -return ret; - } +if (ret) + goto err_release_obj; ret =virtio_gpu_resource_id_get (vgdev, &vram->base.hw_res_handle); -if (ret) { -kfree (vram); -return ret; - } +if (ret) + goto err_release_obj;virtio_gpu_cmd_resource_create_blob (vgdev, &vram->base, params,NULL ,0 );
@@ -237,6 +233,11 @@ int virtio_gpu_vram_create(struct virtio_gpu_device *vgdev, *bo_ptr = &vram->base;return 0 ; + +err_release_obj: +drm_gem_object_release (obj); +kfree (vram); +return ret; }void virtio_gpu_vram_map_deferred (struct virtio_gpu_object_vram *vram)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 112/457 Revert "drm/virtio: Allow importing prime buffers when 3D is enabled"
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Osipenko <[email protected]>
[ Upstream commit 1e3b08de63274d0b009e99ef51cd6a9c0c6bf08c ]
Guest userspace may import udmabuf to vrend. Vrend doesn't support guest blobs, and thus, further 3d operations with the imported blob are failing. Typical scenario of the problem shown with mouse cursor RGBA image imported into virtio-gpu, which previously was rejected by virtio-gpu driver. Revert enabling guest blobs importing into vrend to fix the regression.
--- drivers/gpu/drm/virtio/virtgpu_prime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/virtio/virtgpu_prime.c +1 -1
@@ -310,7 +310,7 @@ struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev, } } -if (!vgdev->has_resource_blob) +if (!vgdev->has_resource_blob || vgdev->has_virgl_3d)return drm_gem_prime_import (dev, buf); bo =kzalloc_obj (*bo);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 113/457 drm/virtio: sync shmem backing on guest-bound transfers
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Leggett <[email protected]>
[ Upstream commit 598c1c3e895590f845e04455d5580ea28ffde666 ]
virtio_gpu_cmd_transfer_to_host_{2d,3d}() sync the shmem backing for the device before the transfer, but nothing syncs for the CPU when a transfer runs the other way. That breaks two ways. Where the DMA layer bounces, the device writes into the bounce buffer while the guest keeps reading the original pages. Where DMA is not coherent, the device writes memory while the CPU keeps stale cache lines, because nothing reaches arch_sync_dma_for_cpu(). Either way DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST hands back stale data.
Sashiko originally found this in
https://lore.kernel.org/dri-devel/[email protected]
but the suggestion there to fix this with dma_sync_sgtable_for_cpu() isn't a sufficient fix, for two reasons.
- The transfer is asynchronous. virtio_gpu_cmd_transfer_from_host_3d() only queues the command, so a sync there would run before the device had written anything. It belongs on completion, and ahead of any fence signalling. A waiter woken by the fence would otherwise race the sync and read the backing pages regardless. It needs its own pass over the reclaim list rather than a step inside the existing one, because virtio_gpu_fence_event_process() also signals every earlier fence in the same context, so any entry in that loop may signal an earlier entry's fence.
- The transfer is also partial, carrying an offset, a level and a box. Where the mapping bounces, a sync for the CPU copies the whole mapping back, so unless the mapping is primed first the regions the device did not write come back holding whatever the bounce buffer contained, discarding data the guest owned.
So the fix: Prime the mapping before queueing, tag the vbuffer, and sync for the CPU on completion before the fence is signalled.
A second transfer must not snapshot the mapping while an earlier one is still in flight, or the snapshot would predate whatever the CPU wrote once the earlier fence signalled and the later sync would discard it.
To mitigate this, wait for outstanding fences under the reservation before priming.
Neither sync copies anything unless the mapping genuinely bounces:swiotlb_sync_single_for_cpu() and its Xen counterpart look the address up in the bounce pool and return early when it is absent. On a platform with non-coherent DMA they still perform the necessary cache maintenance.
The range cannot be narrowed to the box, since for a non-blob resource virtio_gpu_transfer_from_host_ioctl() rejects a caller-supplied stride and layer_stride, leaving the layout to the host and the guest with no way to work out which bytes the device writes. A host3d guest blob does carry both, so its extent could be bounded, but the sync is left whole there too rather than special-cased: priming makes the untouched regions round-trip unchanged either way.
Behaviour changes worth noting:
- TRANSFER_FROM_HOST can now block, where before it returned as soon as the command was queued. Repeated readbacks of one resource serialise, and a readback can wait behind an earlier queued command that touched it, since virtio_gpu_array_add_fence() tags uploads, execbufs and plane flushes alike with DMA_RESV_USAGE_WRITE. -ERESTARTSYS was already possible here via dma_resv_lock_interruptible().
- A CPU write racing an in-flight transfer to the same resource is now lost, where before it survived and the transfer was lost instead. Priming captures the pages as of queueing, so a write landing before completion is overwritten by the sync.
- TRANSFER_TO_HOST can also block now, but only while a guest-bound transfer on the same resource is outstanding, which happens only for callers that issue both without waiting.
- Where a batch of completions contains a guest-bound transfer, the sync pass delays fence signalling for the whole batch. Only bounced pages are copied and the swiotlb pool bounds it. A batch with no such transfer is unaffected.
Tested under QEMU on x86 with swiotlb=force and virtio-vga-gl iommu_platform=on, which forces both preconditions required to hit the original bug.
--- drivers/gpu/drm/virtio/virtgpu_drv.h | 5 +++ drivers/gpu/drm/virtio/virtgpu_ioctl.c | 43 ++++++++++++++++++++++++ drivers/gpu/drm/virtio/virtgpu_vq.c | 46 ++++++++++++++++++++++++++ 3 files changed, 94 insertions(+)
drivers/gpu/drm/virtio/virtgpu_drv.h +5 -0
@@ -114,6 +114,8 @@ struct virtio_gpu_object {bool dumb;bool created;bool attached; +/* a guest-bound transfer is queued and its mapping not yet synced */ +bool from_host_pending;bool host3d_blob, guest_blob;uint32_t blob_mem, blob_flags;
@@ -192,6 +194,9 @@ struct virtio_gpu_vbuffer {struct list_head list;uint32_t seqno; + +/* guest-bound transfer whose shmem backing needs a CPU sync */ +bool sync_for_cpu; };struct virtio_gpu_output {
drivers/gpu/drm/virtio/virtgpu_ioctl.c +43 -0
55 lines not on this page · raw message
drivers/gpu/drm/virtio/virtgpu_vq.c +46 -0
64 lines not on this page · raw message
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 114/457 pinctrl: tegra238: Fix register bank for AON pin groups
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Prathamesh Shete <[email protected]>
[ Upstream commit ae2c5bf969573708cd5b6bb6393631255d83c3fe ]
The AON pin controller has a single register region and therefore, the bank defined in the tegra238_functions[] and tegra238_aon_groups[] for the AON pin groups must be 0. However, commit 25cac7292d49 ("pinctrl: tegra: Add Tegra238 pinmux driver") incorrectly specified the bank for these pins as 1 and not 0. This means that in the tegra_pinctrl_probe() function we use an invalid index when accessing the pmx->regs[] array which causes an incorrect address to be used for accessing the pinmux registers.
Fix this by correcting the bank for the AON pin groups.
--- drivers/pinctrl/tegra/pinctrl-tegra238.c | 204 +++++++++++------------ 1 file changed, 102 insertions(+), 102 deletions(-)
drivers/pinctrl/tegra/pinctrl-tegra238.c +102 -102
@@ -1744,57 +1744,57 @@ static const char * const tegra238_functions[] = {#define drive_sdmmc1_dat0_pu2 DRV_PINGROUP_ENTRY_Y(0x8034, 28, 2, 30, 2, -1, -1, -1, -1, 0)#define drive_ufs0_rst_n_pv1 DRV_PINGROUP_ENTRY_Y(0x11004, 12, 5, 24, 5, -1, -1, -1, -1, 0)#define drive_ufs0_ref_clk_pv0 DRV_PINGROUP_ENTRY_Y(0x1100c, 12, 5, 24, 5, -1, -1, -1, -1, 0) -#define drive_batt_oc_paa4 DRV_PINGROUP_ENTRY_Y(0x1024, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_bootv_ctl_n_paa0 DRV_PINGROUP_ENTRY_Y(0x102c, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_vcomp_alert_paa2 DRV_PINGROUP_ENTRY_Y(0x105c, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_hdmi_cec_pbb0 DRV_PINGROUP_ENTRY_Y(0x1064, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_touch_clk_pdd3 DRV_PINGROUP_ENTRY_Y(0x106c, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_uart3_rx_pcc6 DRV_PINGROUP_ENTRY_Y(0x1074, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_uart3_tx_pcc5 DRV_PINGROUP_ENTRY_Y(0x107c, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_gen8_i2c_sda_pdd2 DRV_PINGROUP_ENTRY_Y(0x1084, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_gen8_i2c_scl_pdd1 DRV_PINGROUP_ENTRY_Y(0x108c, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_spi2_mosi_pcc2 DRV_PINGROUP_ENTRY_Y(0x1094, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_gen2_i2c_scl_pcc7 DRV_PINGROUP_ENTRY_Y(0x109c, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_spi2_cs0_pcc3 DRV_PINGROUP_ENTRY_Y(0x10a4, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_gen2_i2c_sda_pdd0 DRV_PINGROUP_ENTRY_Y(0x10ac, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_spi2_sck_pcc0 DRV_PINGROUP_ENTRY_Y(0x10b4, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_spi2_miso_pcc1 DRV_PINGROUP_ENTRY_Y(0x10bc, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio49_pee2 DRV_PINGROUP_ENTRY_Y(0x10c4, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio50_pee4 DRV_PINGROUP_ENTRY_Y(0x10cc, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio82_pee3 DRV_PINGROUP_ENTRY_Y(0x10d4, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio71_pff2 DRV_PINGROUP_ENTRY_Y(0x10dc, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio76_pff7 DRV_PINGROUP_ENTRY_Y(0x10e4, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio74_pff5 DRV_PINGROUP_ENTRY_Y(0x10ec, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio00_paa1 DRV_PINGROUP_ENTRY_Y(0x10f4, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio19_pdd6 DRV_PINGROUP_ENTRY_Y(0x10fc, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio86_phh3 DRV_PINGROUP_ENTRY_Y(0x1104, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio72_pff3 DRV_PINGROUP_ENTRY_Y(0x110c, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio77_pgg0 DRV_PINGROUP_ENTRY_Y(0x1114, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio80_pff6 DRV_PINGROUP_ENTRY_Y(0x111c, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio84_pgg1 DRV_PINGROUP_ENTRY_Y(0x1124, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio83_pee5 DRV_PINGROUP_ENTRY_Y(0x112c, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio73_pff4 DRV_PINGROUP_ENTRY_Y(0x1134, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio70_pff1 DRV_PINGROUP_ENTRY_Y(0x113c, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio04_paa5 DRV_PINGROUP_ENTRY_Y(0x1144, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio85_pgg6 DRV_PINGROUP_ENTRY_Y(0x114c, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio69_pff0 DRV_PINGROUP_ENTRY_Y(0x1154, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio25_paa6 DRV_PINGROUP_ENTRY_Y(0x115c, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_soc_gpio26_paa7 DRV_PINGROUP_ENTRY_Y(0x1164, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_uart5_tx_pgg7 DRV_PINGROUP_ENTRY_Y(0x116c, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_uart5_rx_phh0 DRV_PINGROUP_ENTRY_Y(0x1174, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_uart2_tx_pgg2 DRV_PINGROUP_ENTRY_Y(0x117c, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_uart2_rx_pgg3 DRV_PINGROUP_ENTRY_Y(0x1184, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_uart2_cts_pgg5 DRV_PINGROUP_ENTRY_Y(0x118c, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_uart2_rts_pgg4 DRV_PINGROUP_ENTRY_Y(0x1194, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_uart5_cts_phh2 DRV_PINGROUP_ENTRY_Y(0x119c, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_uart5_rts_phh1 DRV_PINGROUP_ENTRY_Y(0x11a4, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_pwm7_pee1 DRV_PINGROUP_ENTRY_Y(0x11ac, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_pwm2_pdd7 DRV_PINGROUP_ENTRY_Y(0x11b4, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_pwm3_pee0 DRV_PINGROUP_ENTRY_Y(0x11bc, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_pwm1_paa3 DRV_PINGROUP_ENTRY_Y(0x11c4, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_spi2_cs1_pcc4 DRV_PINGROUP_ENTRY_Y(0x11cc, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_dmic1_clk_pdd4 DRV_PINGROUP_ENTRY_Y(0x11d4, 12, 5, 20, 5, -1, -1, -1, -1, 1) -#define drive_dmic1_dat_pdd5 DRV_PINGROUP_ENTRY_Y(0x11dc, 12, 5, 20, 5, -1, -1, -1, -1, 1) +#define drive_batt_oc_paa4 DRV_PINGROUP_ENTRY_Y(0x1024, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_bootv_ctl_n_paa0 DRV_PINGROUP_ENTRY_Y(0x102c, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_vcomp_alert_paa2 DRV_PINGROUP_ENTRY_Y(0x105c, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_hdmi_cec_pbb0 DRV_PINGROUP_ENTRY_Y(0x1064, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_touch_clk_pdd3 DRV_PINGROUP_ENTRY_Y(0x106c, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_uart3_rx_pcc6 DRV_PINGROUP_ENTRY_Y(0x1074, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_uart3_tx_pcc5 DRV_PINGROUP_ENTRY_Y(0x107c, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_gen8_i2c_sda_pdd2 DRV_PINGROUP_ENTRY_Y(0x1084, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_gen8_i2c_scl_pdd1 DRV_PINGROUP_ENTRY_Y(0x108c, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_spi2_mosi_pcc2 DRV_PINGROUP_ENTRY_Y(0x1094, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_gen2_i2c_scl_pcc7 DRV_PINGROUP_ENTRY_Y(0x109c, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_spi2_cs0_pcc3 DRV_PINGROUP_ENTRY_Y(0x10a4, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_gen2_i2c_sda_pdd0 DRV_PINGROUP_ENTRY_Y(0x10ac, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_spi2_sck_pcc0 DRV_PINGROUP_ENTRY_Y(0x10b4, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_spi2_miso_pcc1 DRV_PINGROUP_ENTRY_Y(0x10bc, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio49_pee2 DRV_PINGROUP_ENTRY_Y(0x10c4, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio50_pee4 DRV_PINGROUP_ENTRY_Y(0x10cc, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio82_pee3 DRV_PINGROUP_ENTRY_Y(0x10d4, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio71_pff2 DRV_PINGROUP_ENTRY_Y(0x10dc, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio76_pff7 DRV_PINGROUP_ENTRY_Y(0x10e4, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio74_pff5 DRV_PINGROUP_ENTRY_Y(0x10ec, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio00_paa1 DRV_PINGROUP_ENTRY_Y(0x10f4, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio19_pdd6 DRV_PINGROUP_ENTRY_Y(0x10fc, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio86_phh3 DRV_PINGROUP_ENTRY_Y(0x1104, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio72_pff3 DRV_PINGROUP_ENTRY_Y(0x110c, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio77_pgg0 DRV_PINGROUP_ENTRY_Y(0x1114, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio80_pff6 DRV_PINGROUP_ENTRY_Y(0x111c, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio84_pgg1 DRV_PINGROUP_ENTRY_Y(0x1124, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio83_pee5 DRV_PINGROUP_ENTRY_Y(0x112c, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio73_pff4 DRV_PINGROUP_ENTRY_Y(0x1134, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio70_pff1 DRV_PINGROUP_ENTRY_Y(0x113c, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio04_paa5 DRV_PINGROUP_ENTRY_Y(0x1144, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio85_pgg6 DRV_PINGROUP_ENTRY_Y(0x114c, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio69_pff0 DRV_PINGROUP_ENTRY_Y(0x1154, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio25_paa6 DRV_PINGROUP_ENTRY_Y(0x115c, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_soc_gpio26_paa7 DRV_PINGROUP_ENTRY_Y(0x1164, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_uart5_tx_pgg7 DRV_PINGROUP_ENTRY_Y(0x116c, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_uart5_rx_phh0 DRV_PINGROUP_ENTRY_Y(0x1174, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_uart2_tx_pgg2 DRV_PINGROUP_ENTRY_Y(0x117c, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_uart2_rx_pgg3 DRV_PINGROUP_ENTRY_Y(0x1184, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_uart2_cts_pgg5 DRV_PINGROUP_ENTRY_Y(0x118c, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_uart2_rts_pgg4 DRV_PINGROUP_ENTRY_Y(0x1194, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_uart5_cts_phh2 DRV_PINGROUP_ENTRY_Y(0x119c, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_uart5_rts_phh1 DRV_PINGROUP_ENTRY_Y(0x11a4, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_pwm7_pee1 DRV_PINGROUP_ENTRY_Y(0x11ac, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_pwm2_pdd7 DRV_PINGROUP_ENTRY_Y(0x11b4, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_pwm3_pee0 DRV_PINGROUP_ENTRY_Y(0x11bc, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_pwm1_paa3 DRV_PINGROUP_ENTRY_Y(0x11c4, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_spi2_cs1_pcc4 DRV_PINGROUP_ENTRY_Y(0x11cc, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_dmic1_clk_pdd4 DRV_PINGROUP_ENTRY_Y(0x11d4, 12, 5, 20, 5, -1, -1, -1, -1, 0) +#define drive_dmic1_dat_pdd5 DRV_PINGROUP_ENTRY_Y(0x11dc, 12, 5, 20, 5, -1, -1, -1, -1, 0)#define drive_sdmmc1_comp DRV_PINGROUP_ENTRY_N
@@ -1961,57 +1961,57 @@ static const struct tegra_pingroup tegra238_groups[] = { };static const struct tegra_pingroup tegra238_aon_groups[] = { -PINGROUP (bootv_ctl_n_paa0,RSVD0 ,RSVD1 ,RSVD2 ,RSVD3 ,0x1028 ,1 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio00_paa1,RSVD0 ,RSVD1 ,RSVD2 ,RSVD3 ,0x10f0 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (vcomp_alert_paa2,SOC_THERM_OC1 ,RSVD1 ,RSVD2 ,RSVD3 ,0x1058 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (pwm1_paa3,GP_PWM1 ,RSVD1 ,RSVD2 ,RSVD3 ,0x11c0 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (batt_oc_paa4,SOC_THERM_OC2 ,RSVD1 ,RSVD2 ,RSVD3 ,0x1020 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio04_paa5,RSVD0 ,RSVD1 ,RSVD2 ,RSVD3 ,0x1140 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio25_paa6,RSVD0 ,RSVD1 ,RSVD2 ,RSVD3 ,0x1158 ,1 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio26_paa7,RSVD0 ,SOC_THERM_OC3 ,RSVD2 ,RSVD3 ,0x1160 ,1 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (hdmi_cec_pbb0,HDMI_CEC ,RSVD1 ,RSVD2 ,RSVD3 ,0x1060 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (spi2_sck_pcc0,SPI2_SCK ,RSVD1 ,RSVD2 ,RSVD3 ,0x10b0 ,1 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (spi2_miso_pcc1,SPI2_DIN ,RSVD1 ,RSVD2 ,RSVD3 ,0x10b8 ,1 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (spi2_mosi_pcc2,SPI2_DOUT ,RSVD1 ,RSVD2 ,RSVD3 ,0x1090 ,1 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (spi2_cs0_pcc3,SPI2_CS0 ,RSVD1 ,RSVD2 ,RSVD3 ,0x10a0 ,1 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (spi2_cs1_pcc4,SPI2_CS1 ,RSVD1 ,RSVD2 ,RSVD3 ,0x11c8 ,1 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (uart3_tx_pcc5,UARTC_TXD ,RSVD1 ,RSVD2 ,RSVD3 ,0x1078 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (uart3_rx_pcc6,UARTC_RXD ,RSVD1 ,RSVD2 ,RSVD3 ,0x1070 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (gen2_i2c_scl_pcc7,I2C2_CLK ,RSVD1 ,RSVD2 ,RSVD3 ,0x1098 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (gen2_i2c_sda_pdd0,I2C2_DAT ,RSVD1 ,RSVD2 ,RSVD3 ,0x10a8 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (gen8_i2c_scl_pdd1,I2C8_CLK ,RSVD1 ,RSVD2 ,RSVD3 ,0x1088 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (gen8_i2c_sda_pdd2,I2C8_DAT ,RSVD1 ,RSVD2 ,RSVD3 ,0x1080 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (touch_clk_pdd3,GP_PWM4 ,TOUCH_CLK ,RSVD2 ,RSVD3 ,0x1068 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (dmic1_clk_pdd4,DMIC1_CLK ,RSVD1 ,DMIC5_CLK ,RSVD3 ,0x11d0 ,1 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (dmic1_dat_pdd5,DMIC1_DAT ,RSVD1 ,DMIC5_DAT ,RSVD3 ,0x11d8 ,1 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio19_pdd6,RSVD0 ,WDT_RESET_OUTB ,RSVD2 ,RSVD3 ,0x10f8 ,1 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio49_pee2,RSVD0 ,RSVD1 ,RSVD2 ,RSVD3 ,0x10c0 ,1 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio50_pee4,RSVD0 ,RSVD1 ,RSVD2 ,RSVD3 ,0x10c8 ,1 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio82_pee3,RSVD0 ,RSVD1 ,RSVD2 ,RSVD3 ,0x10d0 ,1 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio71_pff2,PPC_MODE_1 ,RSVD1 ,RSVD2 ,RSVD3 ,0x10d8 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio76_pff7,RSVD0 ,RSVD1 ,TSC_EDGE_OUT0 ,TSC_EDGE_OUT0A ,0x10e0 ,1 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio74_pff5,PPC_READY ,PPC_I2C_DAT ,RSVD2 ,RSVD3 ,0x10e8 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio86_phh3,RSVD0 ,SPI5_CS1 ,TSC_EDGE_OUT3 ,TSC_EDGE_OUT0D ,0x1100 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio72_pff3,PPC_MODE_2 ,RSVD1 ,RSVD2 ,RSVD3 ,0x1108 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio77_pgg0,RSVD0 ,RSVD1 ,TSC_EDGE_OUT1 ,TSC_EDGE_OUT0B ,0x1110 ,1 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio80_pff6,RSVD0 ,PPC_RST_N ,RSVD2 ,RSVD3 ,0x1118 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio84_pgg1,RSVD0 ,RSVD1 ,TSC_EDGE_OUT2 ,TSC_EDGE_OUT0C ,0x1120 ,1 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio83_pee5,RSVD0 ,RSVD1 ,RSVD2 ,RSVD3 ,0x1128 ,1 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio73_pff4,PPC_CC ,PPC_I2C_CLK ,RSVD2 ,RSVD3 ,0x1130 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio70_pff1,PPC_MODE_0 ,RSVD1 ,RSVD2 ,RSVD3 ,0x1138 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio85_pgg6,RSVD0 ,SPI4_CS1 ,RSVD2 ,RSVD3 ,0x1148 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (soc_gpio69_pff0,PPC_INT_N ,RSVD1 ,RSVD2 ,RSVD3 ,0x1150 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (uart5_tx_pgg7,UARTE_TXD ,SPI5_SCK ,RSVD2 ,RSVD3 ,0x1168 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (uart5_rx_phh0,UARTE_RXD ,SPI5_MISO ,RSVD2 ,RSVD3 ,0x1170 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (uart2_tx_pgg2,UARTB_TXD ,SPI4_SCK ,RSVD2 ,RSVD3 ,0x1178 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (uart2_rx_pgg3,UARTB_RXD ,SPI4_MISO ,RSVD2 ,RSVD3 ,0x1180 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (uart2_cts_pgg5,UARTB_CTS ,SPI4_CS0 ,RSVD2 ,RSVD3 ,0x1188 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (uart2_rts_pgg4,UARTB_RTS ,SPI4_MOSI ,RSVD2 ,RSVD3 ,0x1190 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (uart5_cts_phh2,UARTE_CTS ,SPI5_CS0 ,RSVD2 ,RSVD3 ,0x1198 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (uart5_rts_phh1,UARTE_RTS ,SPI5_MOSI ,RSVD2 ,RSVD3 ,0x11a0 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (pwm2_pdd7,GP_PWM2 ,LED_BLINK ,RSVD2 ,RSVD3 ,0x11b0 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (pwm3_pee0,GP_PWM3 ,RSVD1 ,RSVD2 ,RSVD3 ,0x11b8 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), -PINGROUP (pwm7_pee1,GP_PWM7 ,RSVD1 ,RSVD2 ,RSVD3 ,0x11a8 ,1 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (bootv_ctl_n_paa0,RSVD0 ,RSVD1 ,RSVD2 ,RSVD3 ,0x1028 ,0 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio00_paa1,RSVD0 ,RSVD1 ,RSVD2 ,RSVD3 ,0x10f0 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (vcomp_alert_paa2,SOC_THERM_OC1 ,RSVD1 ,RSVD2 ,RSVD3 ,0x1058 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (pwm1_paa3,GP_PWM1 ,RSVD1 ,RSVD2 ,RSVD3 ,0x11c0 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (batt_oc_paa4,SOC_THERM_OC2 ,RSVD1 ,RSVD2 ,RSVD3 ,0x1020 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio04_paa5,RSVD0 ,RSVD1 ,RSVD2 ,RSVD3 ,0x1140 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio25_paa6,RSVD0 ,RSVD1 ,RSVD2 ,RSVD3 ,0x1158 ,0 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio26_paa7,RSVD0 ,SOC_THERM_OC3 ,RSVD2 ,RSVD3 ,0x1160 ,0 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (hdmi_cec_pbb0,HDMI_CEC ,RSVD1 ,RSVD2 ,RSVD3 ,0x1060 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (spi2_sck_pcc0,SPI2_SCK ,RSVD1 ,RSVD2 ,RSVD3 ,0x10b0 ,0 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (spi2_miso_pcc1,SPI2_DIN ,RSVD1 ,RSVD2 ,RSVD3 ,0x10b8 ,0 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (spi2_mosi_pcc2,SPI2_DOUT ,RSVD1 ,RSVD2 ,RSVD3 ,0x1090 ,0 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (spi2_cs0_pcc3,SPI2_CS0 ,RSVD1 ,RSVD2 ,RSVD3 ,0x10a0 ,0 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (spi2_cs1_pcc4,SPI2_CS1 ,RSVD1 ,RSVD2 ,RSVD3 ,0x11c8 ,0 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (uart3_tx_pcc5,UARTC_TXD ,RSVD1 ,RSVD2 ,RSVD3 ,0x1078 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (uart3_rx_pcc6,UARTC_RXD ,RSVD1 ,RSVD2 ,RSVD3 ,0x1070 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (gen2_i2c_scl_pcc7,I2C2_CLK ,RSVD1 ,RSVD2 ,RSVD3 ,0x1098 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (gen2_i2c_sda_pdd0,I2C2_DAT ,RSVD1 ,RSVD2 ,RSVD3 ,0x10a8 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (gen8_i2c_scl_pdd1,I2C8_CLK ,RSVD1 ,RSVD2 ,RSVD3 ,0x1088 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (gen8_i2c_sda_pdd2,I2C8_DAT ,RSVD1 ,RSVD2 ,RSVD3 ,0x1080 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (touch_clk_pdd3,GP_PWM4 ,TOUCH_CLK ,RSVD2 ,RSVD3 ,0x1068 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (dmic1_clk_pdd4,DMIC1_CLK ,RSVD1 ,DMIC5_CLK ,RSVD3 ,0x11d0 ,0 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (dmic1_dat_pdd5,DMIC1_DAT ,RSVD1 ,DMIC5_DAT ,RSVD3 ,0x11d8 ,0 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio19_pdd6,RSVD0 ,WDT_RESET_OUTB ,RSVD2 ,RSVD3 ,0x10f8 ,0 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio49_pee2,RSVD0 ,RSVD1 ,RSVD2 ,RSVD3 ,0x10c0 ,0 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio50_pee4,RSVD0 ,RSVD1 ,RSVD2 ,RSVD3 ,0x10c8 ,0 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio82_pee3,RSVD0 ,RSVD1 ,RSVD2 ,RSVD3 ,0x10d0 ,0 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio71_pff2,PPC_MODE_1 ,RSVD1 ,RSVD2 ,RSVD3 ,0x10d8 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio76_pff7,RSVD0 ,RSVD1 ,TSC_EDGE_OUT0 ,TSC_EDGE_OUT0A ,0x10e0 ,0 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio74_pff5,PPC_READY ,PPC_I2C_DAT ,RSVD2 ,RSVD3 ,0x10e8 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio86_phh3,RSVD0 ,SPI5_CS1 ,TSC_EDGE_OUT3 ,TSC_EDGE_OUT0D ,0x1100 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio72_pff3,PPC_MODE_2 ,RSVD1 ,RSVD2 ,RSVD3 ,0x1108 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio77_pgg0,RSVD0 ,RSVD1 ,TSC_EDGE_OUT1 ,TSC_EDGE_OUT0B ,0x1110 ,0 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio80_pff6,RSVD0 ,PPC_RST_N ,RSVD2 ,RSVD3 ,0x1118 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio84_pgg1,RSVD0 ,RSVD1 ,TSC_EDGE_OUT2 ,TSC_EDGE_OUT0C ,0x1120 ,0 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio83_pee5,RSVD0 ,RSVD1 ,RSVD2 ,RSVD3 ,0x1128 ,0 ,Y ,-1 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio73_pff4,PPC_CC ,PPC_I2C_CLK ,RSVD2 ,RSVD3 ,0x1130 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio70_pff1,PPC_MODE_0 ,RSVD1 ,RSVD2 ,RSVD3 ,0x1138 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio85_pgg6,RSVD0 ,SPI4_CS1 ,RSVD2 ,RSVD3 ,0x1148 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (soc_gpio69_pff0,PPC_INT_N ,RSVD1 ,RSVD2 ,RSVD3 ,0x1150 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (uart5_tx_pgg7,UARTE_TXD ,SPI5_SCK ,RSVD2 ,RSVD3 ,0x1168 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (uart5_rx_phh0,UARTE_RXD ,SPI5_MISO ,RSVD2 ,RSVD3 ,0x1170 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (uart2_tx_pgg2,UARTB_TXD ,SPI4_SCK ,RSVD2 ,RSVD3 ,0x1178 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (uart2_rx_pgg3,UARTB_RXD ,SPI4_MISO ,RSVD2 ,RSVD3 ,0x1180 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (uart2_cts_pgg5,UARTB_CTS ,SPI4_CS0 ,RSVD2 ,RSVD3 ,0x1188 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (uart2_rts_pgg4,UARTB_RTS ,SPI4_MOSI ,RSVD2 ,RSVD3 ,0x1190 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (uart5_cts_phh2,UARTE_CTS ,SPI5_CS0 ,RSVD2 ,RSVD3 ,0x1198 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (uart5_rts_phh1,UARTE_RTS ,SPI5_MOSI ,RSVD2 ,RSVD3 ,0x11a0 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (pwm2_pdd7,GP_PWM2 ,LED_BLINK ,RSVD2 ,RSVD3 ,0x11b0 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (pwm3_pee0,GP_PWM3 ,RSVD1 ,RSVD2 ,RSVD3 ,0x11b8 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), +PINGROUP (pwm7_pee1,GP_PWM7 ,RSVD1 ,RSVD2 ,RSVD3 ,0x11a8 ,0 ,Y ,5 ,7 ,6 ,8 ,-1 ,10 ,12 ), };static const struct tegra_pinctrl_soc_data tegra238_pinctrl_aon = {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 115/457 drm/bridge: samsung-dsim: fix TE GPIO lifetime for host attach
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Youhong <[email protected]>
[ Upstream commit ada667890773e033d2f40dc94176e3beb930b516 ]
When the Exynos DSI driver was generalized into samsung-dsim, the TE GPIO acquisition was switched from gpiod_get_optional() to devm_gpiod_get_optional() while keeping the matching gpiod_put() calls. That combination is wrong for a managed descriptor.
However, dropping the puts and keeping the managed get is also wrong:samsung_dsim_register_te_irq() runs from the DSI host attach callback, and host detach/reattach can happen without destroying the device that owns the managed action. A second attach would then request the GPIO again without having released it.
Switch back to a non-managed gpiod_get_optional() and keep the explicit gpiod_put() on the request_irq() error path and in samsung_dsim_unregister_te_irq().
--- drivers/gpu/drm/bridge/samsung-dsim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/bridge/samsung-dsim.c +1 -1
@@ -1862,7 +1862,7 @@ static int samsung_dsim_register_te_irq(struct samsung_dsim *dsi, struct deviceint te_gpio_irq;int ret; - dsi->te_gpio =devm_gpiod_get_optional (dev,"te" ,GPIOD_IN ); + dsi->te_gpio =gpiod_get_optional (dev,"te" ,GPIOD_IN );if (!dsi->te_gpio)return 0 ;else if (IS_ERR (dsi->te_gpio))
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 116/457 ovpn: preserve IPv6 scope id for netlink peer endpoints
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ralf Lici <[email protected]>
[ Upstream commit 7a6d08ee0f0e30023d18779bb314db8fd9a3b6d4 ]
ovpn accepts OVPN_A_PEER_REMOTE_IPV6_SCOPE_ID and reports bind->remote.in6.sin6_scope_id in peer dumps, but the netlink endpoint parser never copied the attribute into the sockaddr_in6 used to create or update the peer bind.
As a result, an IPv6 link-local remote endpoint configured through netlink loses its interface scope, unlike on the peer float path where ipv6_iface_scope_id populates the field. The UDPv6 output path then builds a flow with flowi6_oif set to zero and route lookup can fail or select the wrong interface.
Copy the scope id when parsing non-v4-mapped IPv6 remote endpoints. The existing precheck already rejects the scope-id attribute for IPv4 and v4-mapped IPv6 remotes.
--- drivers/net/ovpn/netlink.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/net/ovpn/netlink.c +6 -0
@@ -100,6 +100,8 @@ static bool ovpn_nl_attr_sockaddr_remote(struct nlattr **attrs,struct sockaddr_in6 *sin6;struct sockaddr_in *sin;struct in6_addr *in6; +struct nlattr *scope; +u32 scope_id =0 ;__be16 port =0 ;__be32 *in;
@@ -114,6 +116,9 @@ static bool ovpn_nl_attr_sockaddr_remote(struct nlattr **attrs, }else if (attrs[OVPN_A_PEER_REMOTE_IPV6 ]) { ss->ss_family =AF_INET6 ; in6 =nla_data (attrs[OVPN_A_PEER_REMOTE_IPV6 ]); + scope = attrs[OVPN_A_PEER_REMOTE_IPV6_SCOPE_ID ]; +if (scope) + scope_id =nla_get_u32 (scope); }else {return false; }
@@ -126,6 +131,7 @@ static bool ovpn_nl_attr_sockaddr_remote(struct nlattr **attrs,if (!ipv6_addr_v4mapped (in6)) { sin6 = (struct sockaddr_in6 *)ss; sin6->sin6_port = port; + sin6->sin6_scope_id = scope_id;memcpy (&sin6->sin6_addr, in6,sizeof (*in6));break ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 117/457 ovpn: skip UDP source validation for unspecified addresses
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ralf Lici <[email protected]>
[ Upstream commit 77393b4d72dfeb764b2af2b848acc659f6fcfd0a ]
ovpn validates the cached local UDP source address before reusing or refreshing a peer dst cache. This is only meaningful when a concrete source address is selected.
For IPv6, calling ipv6_chk_addr with :: checks whether the unspecified address itself is configured on the host. A peer may legitimately have bind->local.ipv6 set to :: when no local endpoint was configured or after a stale learned address was cleared. In that case the source should be left unspecified and selected by ip6_dst_lookup_flow().
For IPv4, inet_confirm_addr(..., local = 0, ...) asks for local address autoselection rather than validating a chosen source. Skip the precheck there as well and let ip_route_output_flow select or reject the source.
Only validate non-zero/non-any source addresses.
--- drivers/net/ovpn/udp.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/net/ovpn/udp.c +4 -3
@@ -161,8 +161,8 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind,if (rt) goto transmit; -if (unlikely (!inet_confirm_addr (sock_net (sk),NULL ,0 , fl.saddr, -RT_SCOPE_HOST ))) { +if (fl.saddr &&unlikely (!inet_confirm_addr (sock_net (sk),NULL ,0 , + fl.saddr,RT_SCOPE_HOST ))) {/* we may end up here when the cached address is not usable * anymore. In this case we reset address/cache and perform a * new look up
@@ -238,7 +238,8 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind,if (dst) goto transmit; -if (unlikely (!ipv6_chk_addr (sock_net (sk), &fl.saddr,NULL ,0 ))) { +if (!ipv6_addr_any (&fl.saddr) && +unlikely (!ipv6_chk_addr (sock_net (sk), &fl.saddr,NULL ,0 ))) {/* we may end up here when the cached address is not usable * anymore. In this case we reset address/cache and perform a * new look up
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 118/457 ovpn: track UDP socket route key for peer dst cache
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ralf Lici <[email protected]>
[ Upstream commit 7c66b7a4ae80a9309e6dc1d24b7b6b897e6348eb ]
ovpn stores the route used to transmit UDP packets in a per-peer dst cache. A cached dst is only valid for the route lookup inputs used when it was resolved.
Some of those inputs are mutable while userspace still owns the UDP socket. In particular, changes to the socket mark or UDP source port do not invalidate ovpn's peer dst cache, so ovpn can keep using a route selected with an old socket route key.
Replace the cached mark with a route key containing the socket-owned lookup inputs currently used by ovpn, and reset the peer dst cache when the key changes. Before storing a newly looked-up dst, recheck the route key under the peer lock so a dst resolved for stale socket state is not published.
--- drivers/net/ovpn/peer.c | 1 + drivers/net/ovpn/peer.h | 19 ++++++++- drivers/net/ovpn/udp.c | 90 +++++++++++++++++++++++++++++++++++------ 3 files changed, 95 insertions(+), 15 deletions(-)
drivers/net/ovpn/peer.c +1 -0
@@ -113,6 +113,7 @@ struct ovpn_peer *ovpn_peer_new(struct ovpn_priv *ovpn, u32 id)RCU_INIT_POINTER (peer->bind,NULL );ovpn_crypto_state_init (&peer->crypto);spin_lock_init (&peer->lock); +seqcount_spinlock_init (&peer->route_key_seq, &peer->lock);kref_init (&peer->refcount);ovpn_peer_stats_init (&peer->vpn_stats);ovpn_peer_stats_init (&peer->link_stats);
drivers/net/ovpn/peer.h +17 -2
@@ -10,6 +10,7 @@#ifndef _NET_OVPN_OVPNPEER_H_#define _NET_OVPN_OVPNPEER_H_ +#include <linux/seqlock.h> #include <net/dst_cache.h> #include <net/strparser.h>
@@ -17,6 +18,16 @@#include "socket.h" #include "stats.h" +/** +* struct ovpn_route_key - route key used for the peer dst cache +* @mark: fwmark used for route lookup +* @sport: UDP source port used for route lookup +*/ +struct ovpn_route_key { +u32 mark; +__be16 sport; +}; +/** * struct ovpn_peer - the main remote peer object * @ovpn: main openvpn instance this peer belongs to
@@ -45,6 +56,8 @@* @tcp.sk_cb.ops: pointer to the original prot_ops object (TCP only) * @crypto: the crypto configuration (ciphers, keys, etc..) * @dst_cache: cache for dst_entry used to send to peer +* @route_key: route key matching the current dst cache contents +* @route_key_seq: seqcount protecting lockless route_key reads * @bind: remote peer binding * @keepalive_interval: seconds after which a new keepalive should be sent * @keepalive_xmit_exp: future timestamp when next keepalive should be sent
@@ -55,7 +68,7 @@* @vpn_stats: per-peer in-VPN TX/RX stats * @link_stats: per-peer link/transport TX/RX stats * @delete_reason: why peer was deleted (i.e. timeout, transport error, ..) -* @lock: protects binding to peer (bind) and keepalive* fields +* @lock: protects binding to peer (bind), route_key and keepalive* fields * @refcount: reference counter * @rcu: used to free peer in an RCU safe way * @release_entry: entry for the socket release list
@@ -99,6 +112,8 @@ struct ovpn_peer { } tcp;struct ovpn_crypto_state crypto;struct dst_cache dst_cache; +struct ovpn_route_key route_key; +seqcount_spinlock_t route_key_seq;struct ovpn_bind __rcu *bind;unsigned long keepalive_interval;unsigned long keepalive_xmit_exp;
@@ -109,7 +124,7 @@ struct ovpn_peer {struct ovpn_peer_stats vpn_stats;struct ovpn_peer_stats link_stats;enum ovpn_del_peer_reason delete_reason; -spinlock_t lock;/* protects bind and keepalive* */ +spinlock_t lock;/* protects bind, route_key and keepalive* */ struct kref refcount;struct rcu_head rcu;struct llist_node release_entry;
drivers/net/ovpn/udp.c +77 -13
179 lines not on this page · raw message
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 119/457 ovpn: validate peer state before caching UDP dst
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ralf Lici <[email protected]>
[ Upstream commit fa603710bdb9aea33c0d9cc2c05ed24d84f58753 ]
UDP route lookup runs without peer->lock while the bind is protected by RCU. The route key is snapshotted separately. Either can change while the lookup is in progress.
The TX path currently checks only the route key before publishing the looked-up dst. If the bind changes but the route key does not, a dst resolved from the old endpoint can be installed in the cache after the bind replacement.
Compare both the bind pointer and the route key under peer->lock before updating the cache. The RCU read-side critical section keeps the old bind alive throughout the lookup, so pointer identity is sufficient to detect a replacement.
--- drivers/net/ovpn/udp.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-)
drivers/net/ovpn/udp.c +31 -2
@@ -173,6 +173,35 @@ static void ovpn_dst_cache_check_key(struct ovpn_peer *peer,spin_unlock_bh (&peer->lock); } +/** +* ovpn_dst_cache_current - check whether a route lookup matches peer state +* @peer: the peer owning the bind and dst cache +* @bind: the RCU bind used for the route lookup +* @key: the route key used for the route lookup +* +* Check that @bind is still the current peer bind and that @key still matches +* the peer route key. The caller must hold @peer->lock. The TX path keeps +* @bind inside an RCU read-side critical section, so pointer identity is enough +* to detect whether the bind was replaced while the route lookup was running. +* +* Return: true if the lookup result still matches the current peer state and +* may update the dst cache. +*/ +static bool ovpn_dst_cache_current (const struct ovpn_peer *peer, +const struct ovpn_bind *bind, +const struct ovpn_route_key *key) +{ +const struct ovpn_bind *curr_bind; + +lockdep_assert_held (&peer->lock); + + curr_bind =rcu_dereference_protected (peer->bind, +lockdep_is_held (&peer->lock)); + +return curr_bind == bind && +ovpn_route_key_equal (key, &peer->route_key); +} +/** * ovpn_udp4_output - send IPv4 packet over udp socket * @peer: the destination peer
@@ -240,7 +269,7 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind,/* avoid storing a stale cache */ spin_lock_bh (&peer->lock); -if (likely (ovpn_route_key_equal (key, &peer->route_key))) +if (likely (ovpn_dst_cache_current (peer, bind, key)))dst_cache_set_ip4 (cache, &rt->dst, fl.saddr);spin_unlock_bh (&peer->lock);
@@ -313,7 +342,7 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind,/* avoid storing a stale cache */ spin_lock_bh (&peer->lock); -if (likely (ovpn_route_key_equal (key, &peer->route_key))) +if (likely (ovpn_dst_cache_current (peer, bind, key)))dst_cache_set_ip6 (cache, dst, &fl.saddr);spin_unlock_bh (&peer->lock);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 120/457 ovpn: replace bind when learning local endpoint
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ralf Lici <[email protected]>
[ Upstream commit aea934a221ec6a867221e5b765f65f1857befd53 ]
struct ovpn_bind is published through peer->bind with RCU, but local endpoint learning updates bind->local in place under peer->lock. UDP TX reads the field without that lock. In particular, a concurrent IPv6 update can therefore result in a torn address read.
Use ovpn_peer_reset_sockaddr to publish a replacement bind when learning a new local endpoint, just as a remote endpoint change does. Preserve the current remote address and reset the dst cache only after the new bind has been published successfully.
Track remote endpoint changes separately so that float notification and transport-address rehashing remain limited to actual peer floats.
--- drivers/net/ovpn/peer.c | 43 ++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 20 deletions(-)
drivers/net/ovpn/peer.c +23 -20
@@ -200,13 +200,12 @@ static void __ovpn_peer_hash_transp_addr(struct ovpn_peer *peer,*/ void ovpn_peer_endpoints_update (struct ovpn_peer *peer,struct sk_buff *skb) { +const void *local_ip =NULL ;struct sockaddr_storage ss;struct sockaddr_in6 *sa6; -bool reset_cache = false;struct sockaddr_in *sa;struct ovpn_bind *bind; -const void *local_ip; -size_t salen =0 ; +bool floated = false;spin_lock_bh (&peer->lock); bind = rcu_dereference_protected(peer->bind,
@@ -233,8 +232,7 @@ void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb) .sin_addr.s_addr = ip_hdr(skb)->saddr, .sin_port = udp_hdr(skb)->source, }; - salen =sizeof (*sa); - reset_cache = true; + floated = true;break ; }
@@ -246,10 +244,12 @@ void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb)netdev_name (peer->ovpn->dev), peer->id, &bind->local.ipv4.s_addr, &ip_hdr(skb)->daddr); - bind->local.ipv4.s_addr =ip_hdr (skb)->daddr; - reset_cache = true; + local_ip = &ip_hdr (skb)->daddr; +memcpy (&ss, &bind->remote,sizeof (struct sockaddr_in )); +break ; } -break ; +/* nothing changed */ + goto unlock;case htons (ETH_P_IPV6 ):/* float check */ if (unlikely (!ovpn_bind_skb_src_match (bind, skb))) {
@@ -271,8 +271,7 @@ void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb)ipv6_iface_scope_id (&ipv6_hdr (skb)->saddr, skb->skb_iif), }; - salen =sizeof (*sa6); - reset_cache = true; + floated = true;break ; }
@@ -285,26 +284,30 @@ void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb)netdev_name (peer->ovpn->dev), peer->id, &bind->local.ipv6, &ipv6_hdr(skb)->daddr); - bind->local.ipv6 =ipv6_hdr (skb)->daddr; - reset_cache = true; + local_ip = &ipv6_hdr (skb)->daddr; +memcpy (&ss, &bind->remote,sizeof (struct sockaddr_in6 )); +break ; } -break ; +/* nothing changed */ + goto unlock;default : goto unlock; } -if (unlikely (reset_cache)) -dst_cache_reset (&peer->dst_cache); - -/* if the peer did not float, we can bail out now */ -if (likely (!salen)) - goto unlock; -if (unlikely (ovpn_peer_reset_sockaddr (peer, (struct sockaddr_storage *)&ss, local_ip) <0 )) goto unlock; +/* reset the cache only after a successful bind update to avoid useless +* cache misses on concurrent TX +*/ +dst_cache_reset (&peer->dst_cache); + +/* if only the local address changed, bail out now */ +if (!floated) + goto unlock; +net_dbg_ratelimited ("%s: peer %d floated to %pIScp" ,netdev_name (peer->ovpn->dev), peer->id, &ss);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 121/457 ovpn: replace bind when clearing stale local source
In reply to Greg Kroah-Hartman7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ralf Lici <[email protected]>
[ Upstream commit 7d8104988f423572df1f3347ce578037b1043f34 ]
The UDP output fallback clears bind->local in place when the remembered source address is no longer usable. The bind is RCU-published and read locklessly by concurrent TX, so an IPv6 reader can observe a torn address.
Retry the route lookup with source address autoselection without modifying the bind. After a successful lookup, revalidate the bind and route key under peer->lock, reset the dst cache, and best-effort publish a replacement bind with a wildcard local address.
Do not cache the resolved dst when clearing the local source. Replacing the source invalidates all per-CPU cache entries, while dst_cache_set_ip4 and dst_cache_set_ip6 update only the current CPU slot. The current packet can still use the resolved route; if bind allocation fails, a later cache miss retries the repair.
--- drivers/net/ovpn/udp.c | 81 +++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 25 deletions(-)
drivers/net/ovpn/udp.c +56 -25
@@ -185,7 +185,7 @@ static void ovpn_dst_cache_check_key(struct ovpn_peer *peer,* to detect whether the bind was replaced while the route lookup was running. * * Return: true if the lookup result still matches the current peer state and -* may update the dst cache. +* may update the dst cache or replace the bind. */ static bool ovpn_dst_cache_current(const struct ovpn_peer *peer, const struct ovpn_bind *bind,
@@ -218,6 +218,9 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind,struct sk_buff *skb, const struct ovpn_route_key *key) { + struct sockaddr_storage remote; +struct in_addr local = {}; +bool reset_local = false;struct rtable *rt; struct flowi4 fl = { .saddr = bind->local.ipv4.s_addr,
@@ -236,24 +239,17 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind,if (fl.saddr &&unlikely (!inet_confirm_addr (sock_net (sk),NULL ,0 , fl.saddr,RT_SCOPE_HOST ))) { -/* we may end up here when the cached address is not usable -* anymore. In this case we reset address/cache and perform a -* new look up +/* The learned local address is not usable anymore. +* Retry with source address autoselection. */ fl.saddr =0 ; -spin_lock_bh (&peer->lock); - bind->local.ipv4.s_addr =0 ; -spin_unlock_bh (&peer->lock); -dst_cache_reset (cache); + reset_local = true; } rt =ip_route_output_flow (sock_net (sk), &fl, sk);if (IS_ERR (rt) &&PTR_ERR (rt) == -EINVAL ) { fl.saddr =0 ; -spin_lock_bh (&peer->lock); - bind->local.ipv4.s_addr =0 ; -spin_unlock_bh (&peer->lock); -dst_cache_reset (cache); + reset_local = true; rt =ip_route_output_flow (sock_net (sk), &fl, sk); }
@@ -267,10 +263,28 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind, goto err; } -/* avoid storing a stale cache */ +/* avoid storing a stale cache or local address */ spin_lock_bh (&peer->lock); -if (likely (ovpn_dst_cache_current (peer, bind, key))) -dst_cache_set_ip4 (cache, &rt->dst, fl.saddr); +if (likely (ovpn_dst_cache_current (peer, bind, key))) { +if (!reset_local) { +dst_cache_set_ip4 (cache, &rt->dst, fl.saddr); +spin_unlock_bh (&peer->lock); + goto transmit; + } + +/* invalidate per-CPU dst entries that may still carry +* the stale source +*/ +dst_cache_reset (cache); + +/* preserve the current remote */ +memcpy (&remote, &bind->remote,sizeof (struct sockaddr_in )); +/* The current packet already has a valid wildcard-source route. +* If replacing the bind fails, leave the stale local in place; +* a later cache miss will retry the repair. +*/ +ovpn_peer_reset_sockaddr (peer, &remote, &local); + }spin_unlock_bh (&peer->lock); transmit:
@@ -300,6 +314,9 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind,struct sk_buff *skb, const struct ovpn_route_key *key) { + struct in6_addr local = in6addr_any; +struct sockaddr_storage remote; +bool reset_local = false;struct dst_entry *dst;int ret;
@@ -320,15 +337,11 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind,if (!ipv6_addr_any (&fl.saddr) &&unlikely (!ipv6_chk_addr (sock_net (sk), &fl.saddr,NULL ,0 ))) { -/* we may end up here when the cached address is not usable -* anymore. In this case we reset address/cache and perform a -* new look up +/* The learned local address is not usable anymore. +* Retry with source address autoselection. */ fl.saddr = in6addr_any; -spin_lock_bh (&peer->lock); - bind->local.ipv6 = in6addr_any; -spin_unlock_bh (&peer->lock); -dst_cache_reset (cache); + reset_local = true; } dst =ip6_dst_lookup_flow (sock_net (sk), sk, &fl,NULL );
@@ -340,10 +353,28 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, goto err; } -/* avoid storing a stale cache */ +/* avoid storing a stale cache or local address */ spin_lock_bh (&peer->lock); -if (likely (ovpn_dst_cache_current (peer, bind, key))) -dst_cache_set_ip6 (cache, dst, &fl.saddr); +if (likely (ovpn_dst_cache_current (peer, bind, key))) { +if (!reset_local) { +dst_cache_set_ip6 (cache, dst, &fl.saddr); +spin_unlock_bh (&peer->lock); + goto transmit; + } + +/* invalidate per-CPU dst entries that may still carry +* the stale source +*/ +dst_cache_reset (cache); + +/* preserve the current remote */ +memcpy (&remote, &bind->remote,sizeof (struct sockaddr_in6 )); +/* The current packet already has a valid wildcard-source route. +* If replacing the bind fails, leave the stale local in place; +* a later cache miss will retry the repair. +*/ +ovpn_peer_reset_sockaddr (peer, &remote, &local); + }spin_unlock_bh (&peer->lock); transmit:
Signature · 1 line
2.53.0