| Age | Commit message (Collapse) | Author |
|
When VIRTIO_F_ACCESS_PLATFORM changes, cached vring pointers and IOTLB
metadata are interpreted in a different address space. Keeping them
across the transition can leave stale ring mappings in use.
Clearing d->iotlb before taking the VQ locks also lets a worker observe
a transient NULL d->iotlb and fall back to d->umem while translating a
descriptor.
Add a common vhost_clear_device_iotlb() helper for vhost-net and
vhost-vsock. Take all VQ mutexes in index order before dropping the
device-wide IOTLB, invalidate each VQ's cached ring access and metadata,
clear pending IOTLB messages, and free the old table after the handoff.
This serializes the transition with workers and prevents mixed address
space mappings.
On the first direct-to-IOTLB transition, invalidate the cached vring
addresses. When an existing device IOTLB is replaced, preserve the
GIOVA ring addresses and reset only the metadata cache. After clearing
ACCESS_PLATFORM, userspace must configure the vring addresses for the
new address mode.
vhost_vq_invalidate_access() clears desc, avail, and used together.
Treat the VQ as invalidated only when all three are NULL, since a single
GIOVA address may legitimately be zero.
Fixes: 6b1e6cc7855b ("vhost: new device IOTLB API")
Fixes: e13a6915a03f ("vhost/vsock: add IOTLB API support")
Suggested-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260828085721.57816-1-physicalmtea@gmail.com>
|
|
vduse_validate_config() only checks the upper bound of vq_align. Invalid
values can therefore reach vring_create_virtqueue_map(). The split-ring
helpers use align - 1 as a bit mask, so the alignment must be a non-zero
power of two. A zero value makes vring_size() drop the descriptor and
available-ring part and vring_init() leave the used ring pointer NULL.
The VIRTIO spec requires the used ring to start at an address
aligned to at least 4 bytes. Reject values below VRING_USED_ALIGN_SIZE as
well as non-power-of-two values before they reach the virtio ring helpers.
Opening a virtio-net device created with vq_align=0 triggered:
BUG: KASAN: null-ptr-deref in virtqueue_kick_prepare_split+0xe3/0x100
Read of size 2 at addr 0000000000000000 by task systemd-network/1062
Call Trace (relevant frames):
dump_stack_lvl
print_report
kasan_report
__asan_load2
virtqueue_kick_prepare_split+0xe3/0x100
virtqueue_kick_prepare+0x40/0x60
try_fill_recv+0x857/0x1250
virtnet_open+0x189/0x460
__dev_open+0x225/0x390
__dev_change_flags+0x368/0x3b0
netif_change_flags+0x56/0xc0
do_setlink.isra.0+0x68c/0x1e30
Validate the value before it reaches the virtio ring helpers.
Fixes: c8a6153b6c59 ("vduse: Introduce VDUSE - vDPA Device in Userspace")
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260830023354.115333-1-physicalmtea@gmail.com>
|
|
vduse_vq_kick() runs in the context of the vdpa .kick_vq callback. With
the virtio_vdpa bus driver that callback is invoked by virtqueue_notify()
from the virtio device driver, which may be an atomic context: virtio-blk
kicks from ->queue_rq(), which blk-mq dispatches under rcu_read_lock()
(the tag set does not use BLK_MQ_F_BLOCKING), and virtio-net kicks from
its xmit path with the tx queue lock held.
Commit b282418bc366 ("vduse: Add suspend") made vduse_vq_kick() take
dev->rwsem for reading in order to check dev->suspended. down_read() may
sleep, so with CONFIG_DEBUG_ATOMIC_SLEEP the first I/O on a VDUSE-backed
virtio-blk device bound to virtio_vdpa now triggers:
BUG: sleeping function called from invalid context at kernel/locking/rwsem.c:1573
in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 27, name: kworker/1:0H
preempt_count: 0, expected: 0
RCU nest depth: 1, expected: 0
3 locks held by kworker/1:0H/27:
#0: ((wq_completion)kblockd){+.+.}-{0:0}, at: process_one_work+0xac7/0xcf0
#1: ((work_completion)(&(&hctx->run_work)->work)){+.+.}-{0:0}, at: process_one_work+0x51f/0xcf0
#2: (rcu_read_lock){....}-{1:3}, at: blk_mq_run_work_fn+0x119/0x220
Workqueue: kblockd blk_mq_run_work_fn
Call Trace:
<TASK>
dump_stack_lvl+0x80/0xa0
__might_resched+0x231/0x370
down_read+0x73/0x330
vduse_vq_kick+0x30/0x120
virtio_vdpa_notify+0x63/0x80
virtqueue_notify+0x45/0x70
virtio_queue_rq+0x19d/0x300
blk_mq_dispatch_rq_list+0x269/0xe20
__blk_mq_sched_dispatch_requests+0x761/0xa60
blk_mq_sched_dispatch_requests+0x6b/0xc0
blk_mq_run_work_fn+0x143/0x220
process_one_work+0x581/0xcf0
worker_thread+0x2fc/0x5a0
kthread+0x1cc/0x210
ret_from_fork+0x3c4/0x540
ret_from_fork_asm+0x1a/0x30
</TASK>
Without CONFIG_DEBUG_ATOMIC_SLEEP, a kick that finds the rwsem
write-locked by vduse_dev_reset() or vduse_vdpa_suspend() blocks inside
an RCU read-side critical section. The vhost_vdpa path kicks from the
vhost worker, i.e. process context, which is why this went unnoticed.
Check dev->suspended under vq->kick_lock instead, which the kick path
already takes, and have vduse_vdpa_suspend() cycle every virtqueue's
kick_lock after setting the flag. A kick that observed suspended == false
has thus finished signalling before suspend returns, which is the
guarantee the rwsem used to provide. The flag is now also read outside
the rwsem, so access it with READ_ONCE()/WRITE_ONCE().
Fixes: b282418bc366 ("vduse: Add suspend")
Signed-off-by: Nikhil <nikhilljatt@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260829225457.1037867-1-nikhilljatt@gmail.com>
|
|
max_io_vqs is currently validated only when a vhost-scsi device is opened.
This allows sysfs to show values larger than the driver will actually use,
e.g. writing 2048 succeeds even though vhost_scsi_open() later clamps it to
VHOST_SCSI_MAX_IO_VQ. This makes the sysfs value differ from the value that
will actually be used.
hv# echo 2048 > /sys/module/vhost_scsi/parameters/max_io_vqs
hv# cat /sys/module/vhost_scsi/parameters/max_io_vqs
2048
[ 315.630495] Invalid max_io_vqs of 2048. Using 1024.
Keep accepting out-of-range values for compatibility, but clamp them in the
module parameter setter and store the effective value. This preserves the
existing behavior that invalid values do not make module loading or sysfs
writes fail. It also makes reads report the value that will actually be
used.
With the parameter value kept in range, remove the duplicate validation
from vhost_scsi_open().
Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260802172534.260047-3-dongli.zhang@oracle.com>
|
|
vhost_scsi_open() allocates one "struct vhost_scsi_virtqueue" for each
virtqueue. With large max_io_vqs values, this array can require a
high-order contiguous allocation and trigger a page allocator warning.
hv# cat /sys/module/vhost_scsi/parameters/max_io_vqs
256
[ 766.075787] ------------[ cut here ]------------
[ 766.077030] WARNING: mm/page_alloc.c:5280 at __alloc_frozen_pages_noprof+0x32c/0x15c0, CPU#23: qemu-system-x86/5964
... ...
[ 766.080351] RIP: 0010:__alloc_frozen_pages_noprof+0x32c/0x15c0
... ...
[ 766.085813] Call Trace:
[ 766.085969] <TASK>
[ 766.086098] ? srso_alias_return_thunk+0x5/0xfbef5
[ 766.086365] ? context_struct_compute_av+0x38a/0x4b0
[ 766.086652] alloc_pages_mpol+0x9f/0x170
[ 766.086883] ___kmalloc_large_node+0xb6/0xd0
[ 766.087124] ? srso_alias_return_thunk+0x5/0xfbef5
[ 766.087389] __kmalloc_large_node_noprof+0x18/0xa0
[ 766.087655] __kmalloc_noprof+0x3a0/0x440
[ 766.087877] ? vhost_scsi_open+0xcb/0x2d0 [vhost_scsi]
[ 766.088162] vhost_scsi_open+0xcb/0x2d0 [vhost_scsi]
[ 766.088449] misc_open+0x123/0x160
[ 766.088679] chrdev_open+0xb1/0x230
[ 766.088885] ? __pfx_chrdev_open+0x10/0x10
[ 766.089157] do_dentry_open+0x11a/0x470
[ 766.089389] vfs_open+0x29/0xf0
[ 766.089596] path_openat+0x7c0/0x1100
[ 766.089821] do_file_open+0xdd/0x190
[ 766.090032] ? srso_alias_return_thunk+0x5/0xfbef5
[ 766.090332] do_sys_openat2+0x7e/0x100
[ 766.090601] __x64_sys_openat+0x51/0xa0
[ 766.090857] do_syscall_64+0xfe/0x590
[ 766.091087] entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 766.091411] RIP: 0033:0x7f9525a11fa6
The array does not require physical contiguity, so allocate it with
kvzalloc_objs() and free it with kvfree().
Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260802172534.260047-2-dongli.zhang@oracle.com>
|
|
vp_interrupt() reads the ISR before dispatching config-change and
vring handling. Reading the ISR also clears it, so once the read
returns non-zero the interrupt was from this device and has already
been consumed.
Currently vp_interrupt() returns the result of vp_vring_interrupt().
For a config-change interrupt with no vring work, that can return
IRQ_NONE even though the ISR was non-zero and the interrupt was
handled.
Call vp_vring_interrupt() for any queue work, but once the ISR is
non-zero return IRQ_HANDLED.
Tested with QEMU virtio-blk-pci forced to INTx using vectors=0 and
pci=nomsi. On an idle device, 200 config-change interrupts were
generated using QMP block_resize.
Before this change, irq_handler_exit reported ret=unhandled and
/proc/irq/11/spurious increased from 0 to 200 unhandled interrupts.
After this change, irq_handler_exit reported ret=handled and the
unhandled count remained at 0.
The issue was found during an LLM-assisted Quality Playbook review.
Fixes: 77cf524654a8 ("virtio_pci: split up vp_interrupt")
Suggested-by: Michael S. Tsirkin <mst@redhat.com>
Assisted-by: LLM
Signed-off-by: Andrew Stellman <astellman@stellman-greene.com>
Message-ID: <20260904141318.30278-1-astellman@stellman-greene.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
vhost allocates a message node whenever address translation misses. If
userspace reads these messages without resolving them, repeated virtqueue
kicks can grow the pending message list until the host runs out of memory.
Virtqueue processing stops at the first translation miss and cannot make
progress until userspace installs a mapping. Keep a pointer to that
outstanding message in the virtqueue and suppress additional misses until
the node is resolved or discarded.
The pointer remains set while the message is queued for reading, copied to
userspace, or waiting on the pending list. Clear it under the IOTLB lock
when the owning node is freed. This bounds outstanding miss messages by the
fixed number of virtqueues without introducing an arbitrary queue limit.
Signed-off-by: Linfeng Sun <linfeng.sun.dev@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260903-fix-kernel-panic-in-vhost_iotlb_miss_pending_list-v1-1-39b8cd427978@gmail.com>
|
|
vringh_iov_pull_iotlb() returns a signed byte count. A failed TX pull is
currently added to the unsigned byte counter and then passed as a size_t
length to receive_filter() and vringh_iov_push_iotlb(). A negative error
can therefore become a large length in the RX path.
Handle non-positive pull results before every length use. Count the TX
error and complete the consumed TX descriptor with zero bytes.
I found this bug myself, though the patch was written with AI assistance.
Fixes: cfe226892913 ("vdpa_sim: filter destination mac address")
Assisted-by: OpenAI-Codex:GPT-5
Signed-off-by: Linfeng Sun <linfeng.sun.dev@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260901094842.25875-1-linfeng.sun.dev@gmail.com>
|
|
vdpasim_blk_check_range() logs an invalid start sector but continues
validating the request. The subsequent unsigned capacity subtraction can
underflow and let an out-of-range buffer offset reach the data path.
The invalid offset is used by three request paths. VIRTIO_BLK_T_OUT
copies guest data to blk->buffer + offset through
vringh_iov_pull_iotlb(), causing an out-of-bounds write in
_copy_from_iter() or memcpy(). VIRTIO_BLK_T_IN copies from
blk->buffer + offset to the guest through vringh_iov_push_iotlb(),
causing an out-of-bounds read in _copy_to_iter().
VIRTIO_BLK_T_WRITE_ZEROES passes blk->buffer + offset to memset(),
causing an out-of-bounds write.
Reject starts at or beyond the capacity before the subtraction. Treat the
capacity boundary as invalid because the IN and OUT paths round byte counts
down to sectors for validation but later copy the original byte counts. A
sub-sector request at the capacity boundary would otherwise still access
past the end of the buffer.
I found this bug myself, though the patch was written with AI assistance.
Fixes: 7d189f617f83 ("vdpa_sim_blk: implement ramdisk behaviour")
Assisted-by: OpenAI-Codex:GPT-5
Signed-off-by: Linfeng Sun <linfeng.sun.dev@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260901094800.25475-1-linfeng.sun.dev@gmail.com>
|
|
When optional queues are skipped, pass the compressed vDPA queue id to
set_vq_affinity() so affinity is applied to the queue that was actually
created.
Signed-off-by: Xiong Weimin <xiongweimin@kylinos.cn>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260804092649.1344478-1-xiongweimin@kylinos.cn>
|
|
Handle dev_set_name() failures before registering the vDPA device so
allocation is unwound through the existing put_device() path.
Signed-off-by: Xiong Weimin <xiongweimin@kylinos.cn>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260804092636.1344431-1-xiongweimin@kylinos.cn>
|
|
Route unsupported provisioned features through the common error path after
vdpa_alloc_device() so the allocated device and adapter pointer are
released consistently.
Fixes: 46fc0917bbab ("vDPA/ifcvf: implement features provisioning")
Cc: stable@vger.kernel.org # v6.3+
Signed-off-by: Xiong Weimin <xiongweimin@kylinos.cn>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <178589471294.1556376.4816776800128323034@kylinos.cn>
|
|
Unwind IRQs already requested by snet_request_irqs() before returning a
VQ IRQ request error so a later DRIVER_OK retry starts from a clean
state. The IRQs are requested and freed while the PCI device remains
bound, so the driver cannot wait for devres cleanup at detach time.
Fixes: 51a8f9d7f587 ("virtio: vdpa: new SolidNET DPU driver.")
Cc: stable@vger.kernel.org # v6.3+
Signed-off-by: Xiong Weimin <xiongweimin@kylinos.cn>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <178589471328.1556376.15570536900532373521@kylinos.cn>
|
|
If requesting MSI-X interrupts fails while DRIVER_OK is being set, leave
the device status unchanged instead of advertising a ready device without
working interrupts.
Signed-off-by: Xiong Weimin <xiongweimin@kylinos.cn>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260804092608.1344269-1-xiongweimin@kylinos.cn>
|
|
vp_modern_map_vq_notify() can fail and return NULL. Check the notify
mapping while adding a pds vDPA device and use the existing teardown path
instead of storing a NULL doorbell pointer in the virtqueue state.
Signed-off-by: Xiong Weimin <xiongweimin@kylinos.cn>
Reviewed-by: Brett Creeley <brett.creeley@amd.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260806005809.1875257-1-xiongweimin@kylinos.cn>
|
|
When the DT node has "wakeup-source", vm_find_vqs() calls
enable_irq_wake() on the shared IRQ, but vm_del_vqs() freed that IRQ
without a matching disable_irq_wake(). That leaves a wake reference
behind and can warn on later free_irq()/request_irq() cycles.
Record whether enable_irq_wake() succeeded, and disable it in
vm_del_vqs() before free_irq().
Fixes: 02213273f72a ("virtio_mmio: add support to set IRQ of a virtio device as wakeup source")
Cc: stable@vger.kernel.org
Signed-off-by: Xiong Weimin <xiongweimin@kylinos.cn>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260805032937.1606737-1-xiongweimin@kylinos.cn>
|
|
vhost_vdpa_config_cb() loads v->config_ctx and signals it without taking
a reference and without holding any lock:
struct eventfd_ctx *config_ctx = v->config_ctx;
if (config_ctx)
eventfd_signal(config_ctx);
VHOST_VDPA_SET_CONFIG_CALL replaces that field and drops what is normally
the last reference to the old context:
swap(ctx, v->config_ctx);
if (ctx)
eventfd_ctx_put(ctx);
eventfd_ctx_put() drops the last kref and frees the context immediately,
with no RCU grace period, so a callback that has already loaded the
pointer goes on to dereference freed memory. The two sides share no
lock: the ioctl runs under vhost_dev.mutex, while the parent invokes the
callback from its own interrupt or workqueue context.
This is not the reopen refcount underflow fixed by commit f6bbf0010ba0
("vhost-vdpa: fix use-after-free of v->config_ctx"), which was about
vhost_vdpa_config_put() leaving a stale pointer behind. Here the pointer
is maintained correctly and it is the read side that is unprotected.
With VDUSE as the parent this is reachable from userspace with access to
/dev/vduse (root by default). VDUSE_DEV_INJECT_CONFIG_IRQ queues
dev->inject, and vduse_dev_irq_inject() runs the callback under VDUSE's
own dev->irq_lock, which vhost does not hold. vduse_dev_reset() does
flush_work(&dev->inject), but VHOST_VDPA_SET_CONFIG_CALL never goes
through reset, so an inject already in flight is not waited for. A
process that injects config interrupts on the VDUSE fd while another
thread swaps the call fd on the vhost-vdpa fd hits it in seconds:
BUG: KASAN: slab-use-after-free in native_queued_spin_lock_slowpath
Read of size 4 at addr ffff888107d21808 by task kworker/u17:1/2993
Workqueue: vduse-irq vduse_dev_irq_inject
Call Trace:
native_queued_spin_lock_slowpath+0x97/0x5b0
_raw_spin_lock_irqsave+0xd4/0xe0
eventfd_signal_mask+0x69/0x120
vhost_vdpa_config_cb+0x34/0x50
vduse_dev_irq_inject+0x46/0x60
process_one_work+0x468/0x950
Allocated by task 2992:
do_eventfd+0x50/0x200
__x64_sys_eventfd2+0x2e/0x40
Freed by task 2992:
eventfd_ctx_put+0xb9/0xc0
vhost_vdpa_unlocked_ioctl+0x116c/0x2190
Add a spinlock covering every access to config_ctx, so the callback
either signals a context that is still alive or observes NULL, and the
put happens only once no callback can reach the old value.
Clearing the parent's callback before the put would not be enough: of the
in-tree set_config_cb() implementations only VDUSE takes a lock, the rest
store the pointer unlocked, so that would not order against an in-flight
invocation.
Fixes: 776f395004d8 ("vhost_vdpa: Support config interrupt in vdpa")
Signed-off-by: Yu Zhang <yuz08559@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260807100025.19750-3-yuz08559@gmail.com>
|
|
vhost_vdpa_set_config_call() swaps the eventfd_ctx_fdget() return value
into v->config_ctx before checking it, so on failure the field briefly
holds an ERR_PTR:
ctx = fd == VHOST_FILE_UNBIND ? NULL : eventfd_ctx_fdget(fd);
swap(ctx, v->config_ctx);
if (!IS_ERR_OR_NULL(ctx))
eventfd_ctx_put(ctx);
if (IS_ERR(v->config_ctx)) {
long ret = PTR_ERR(v->config_ctx);
v->config_ctx = NULL;
return ret;
}
Commit 0bde59c1723a ("vhost-vdpa: set v->config_ctx to NULL if
eventfd_ctx_fdget() fails") added that clearing, and spelled out the
invariant the rest of the file relies on: "we consider 'v->config_ctx'
valid if it is not NULL". The window between the swap and the clearing
still breaks it. vhost_vdpa_config_cb() only tests for NULL, so a config
interrupt delivered inside the window hands the ERR_PTR to
eventfd_signal().
Check the fd before installing it instead. That closes the window and
matches how vhost_vring_ioctl() handles the same failure for the vq call
fd.
It also stops a rejected fd from tearing down a config interrupt that was
working: until now the swap replaced the live context and put it, so
after an EBADF the device silently stopped delivering config interrupts
until userspace installed a new fd.
Fixes: 776f395004d8 ("vhost_vdpa: Support config interrupt in vdpa")
Signed-off-by: Yu Zhang <yuz08559@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260807100025.19750-2-yuz08559@gmail.com>
|
|
vhost_vring_set_num() accepts any non-zero power-of-two queue size that
fits in 16 bits. vhost-vdpa then passes that value to set_vq_num()
without comparing it with get_vq_num_max().
A process with access to /dev/vhost-vdpa-* can therefore configure a
queue larger than the device advertises. With vdpa_sim, the worker can
walk descriptors beyond the mapped descriptor ring. KASAN reports a
16-byte out-of-bounds read, corresponding to one vring_desc, in the
vringh IOTLB path:
BUG: KASAN: out-of-bounds in _copy_from_iter
Read of size 16
copy_from_iotlb
copydesc_iotlb
vringh_getdesc_iotlb
vdpasim_net_work
Cache get_vq_num_max() immediately after reset. Some backends derive
it from writable queue-size state, so querying it after SET_NUM may
return the current size instead of the device capability. Invalidate
the cached value before reset so a failed reset leaves SET_NUM
disabled.
For VHOST_SET_VRING_NUM, copy the complete vring state once and use
the same index and size for validation, vq->num, and set_vq_num().
This ensures that validation and use operate on the same copied values.
Fixes: 4c8cf31885f6 ("vhost: introduce vDPA-based backend")
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260810010300.132959-1-physicalmtea@gmail.com>
|
|
__send_control_msg() publishes &portdev->cpkt as the control-out
virtqueue cookie. remove_vqs() walks every virtqueue and passes leftover
cookies to free_buf(), which treats them as struct port_buffer and
reads sgpages.
If a control message is still on c_ovq when the device is unbound,
free_buf() reads past the ports_device object.
KASAN reported slab-out-of-bounds in free_buf():
free_buf
remove_vqs
virtcons_remove
unbind_store
The object was the ports_device allocated in virtcons_probe().
Drain c_ovq without freeing. The packet lives in portdev and is released
with it.
Fixes: a7a69ec0d8e4 ("virtio_console: free buffers after reset")
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260819021230.292696-1-physicalmtea@gmail.com>
|
|
device_unregister() is device_del() plus put_device(). When the caller
holds no extra reference, that drops the last one and runs the release
callback, which for several transports frees the memory the embedded
struct virtio_device sits in. unregister_virtio_device() then calls
virtio_debug_device_exit(), which reads dev->debugfs_dir out of the freed
object.
Affected transports are the ones whose release callback frees and whose
remove path takes no reference: virtio_mmio, virtio_vdpa, virtio_uml,
mlxbf-tmfifo and virtio_ccw. virtio_pci is unaffected because
virtio_pci_remove() brackets the call with get_device() and put_device().
Remove the debugfs entries before the device can go away. They are only
accessed through the protected debugfs interface, so
debugfs_remove_recursive() waits for in-progress file operations before
returning. Tearing them down while the device is still alive is therefore
safe.
Reproduced on User-Mode Linux with CONFIG_KASAN and CONFIG_VIRTIO_DEBUG
by unbinding a virtio-uml device:
BUG: KASAN: slab-use-after-free in virtio_debug_device_exit+0x36/0x4d
Read of size 8 at addr 00000000616e0b10 by task init/1
__asan_report_load8_noabort
virtio_debug_device_exit+0x36/0x4d
unregister_virtio_device+0x48/0x75
virtio_uml_remove
platform_remove
device_release_driver_internal
unbind_store
Freed by task 1:
kfree
virtio_uml_release_dev
device_release
kobject_put
put_device
device_unregister
With this applied, the report is gone and unbind is clean.
Fixes: 96a8326d69ff ("virtio: add debugfs infrastructure to allow to debug virtio features")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260821213953.76906-1-kmehltretter@gmail.com>
|
|
In a packed ring the AVAIL and USED bits sit in the descriptor itself,
so writing them makes that descriptor available. Those bit combinations
flip meaning on every round of the ring, tracked by a wrap counter, so
invalidating or validating a descriptor means inverting both bits.
Commit 1ce9e6055fa0 ("virtio_ring: introduce packed ring support") has
virtqueue_add_packed() make every descriptor of a chain available as it
maps the chain, and write the head last. The device consumes the ring in
order and stops at a head that is not available yet, so it never reaches
the rest.
When vring_map_one_sg() fails partway, unmap_release unmaps the segments
and restores avail_used_flags, but the descriptors it wrote to in the
ring stay marked with AVAIL and USED bits. The head is now the only
entry that keeps the device from consuming these stale entries.
For example, the ring would look like this now.
Z - pre-previous command
A - previous command
B - aborted command
C - current command
[A1 DONE] [A2 DONE] <C1 EMPTY> [B2] [B3] [Z1 DONE]
When the driver now attempts to issue the C command, the next add starts
at the same head as B. If C spans less descriptors than B, there is no
end marker because AVAIL and USED bits were still in place. And that
means the device will start interpreting these stale entries (B2/B3) as
another command entry, which then blocks the queue.
This effect typically happens in swiotlb configurations under memory
pressure, because vring_map_one_sg() can then fail with larger I/O
requests which then leads to command abortions.
There are broadly 2 ways to avoid leaving those flags behind:
1) Defer those flags too until the chain is complete.
2) Rewrite those flags for the previous wrap counter.
Implement the second option in both packed add paths. The first option
traverses the chain a second time on every successful add. The second
option invalidates all added descriptors when any add fails.
With this patch applied, a packed virtqueue keeps completing requests
after a failed add.
Fixes: 1ce9e6055fa0 ("virtio_ring: introduce packed ring support")
Fixes: f6a15d854986 ("virtio_ring: add in order support")
Assisted-by: Kiro:claude-opus-5 checkpatch sparse
Signed-off-by: Alexander Graf <graf@amazon.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260817223229.28954-1-graf@amazon.com>
|
|
In addition to EN, ICC_CR0_EL1 contains other fields, such as LINK and
LINK_IDLE. The driver only needs to modify EN, and must preserve the
values of all other fields when enabling or disabling the CPU
interface.
Define the missing LINK and LINK_IDLE fields, and use read-modify-write
accesses to update EN without affecting the rest of ICC_CR0_EL1.
Fixes: 7ec80fb3f025 ("irqchip/gic-v5: Add GICv5 PPI support")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Sascha Bischoff <sascha.bischoff@arm.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Link: https://patch.msgid.link/20260907164945.714545-1-sascha.bischoff@arm.com
Closes: https://lore.kernel.org/r/20260807121703.D4B7A1F00A3A@smtp.kernel.org
|
|
The interrupt handler distinguishes the rail that reported the fault, but
the body ignores it. Every SW interrupt walks the regulator array looking
for the name "SW3" and every LDO interrupt looks for "LDO3", so an
over-current on SW1 is reported to the consumers of SW3 while the
consumers of SW1 hear nothing.
The lookup itself is unreliable as well. rdev_get_name() returns the
device tree regulator-name property whenever the board supplies one, and
only falls back to the name in the driver descriptor when it does not.
The binding example for this device sets regulator-name to "sw3" and
"ldo3", which strcmp() does not match against the upper case literals
used here, so a board that follows the documentation gets no over-current
notification at all. A board that names its rails after the schematic
does not match either. No other driver in the tree selects a notification
target this way.
Replace the name lookup with rdev_get_id(), which returns the descriptor
id set by the driver and cannot be overridden from the device tree, and
take both the id and the event from a table indexed by the interrupt.
The die temperature interrupts keep notifying every regulator since they
report a chip wide condition.
Fixes: 7320d41c29bb ("regulator: pf1550: Add support for regulator")
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Link: https://patch.msgid.link/20260904105624.48577-1-donggeunyoo.kernel@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
applesmc_create_key_backlight() allocates applesmc_led_wq before calling
led_classdev_register(). When register fails, the error is returned to
applesmc_init(), which jumps to out_light_sysfs and skips
applesmc_release_key_backlight(), leaking the workqueue.
Destroy the workqueue on the register failure path. The bug was introduced
when the inline init block was refactored into a helper that returns errors
directly, dropping the old out_light_wq unwind label.
Fixes: 0b0b5dff8967 ("hwmon: (applesmc) Simplify feature sysfs handling")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4
Signed-off-by: Cong Nguyen <congnt264@gmail.com>
Link: https://patch.msgid.link/20260828105413.2401385-1-congnt264@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
|
|
Sashiko reports:
The return value in heater_enable_store() causes an unexpected write
failure in user-space.
When the heater is successfully enabled, the function returns 0
instead of count:
drivers/hwmon/sht4x.c:heater_enable_store() {
...
data->heating_complete = jiffies + msecs_to_jiffies(heating_time_bound);
data->data_pending = true;
return 0;
}
Returning 0 signals to VFS that no bytes were processed. Standard
user-space tools will retry the write with the remaining bytes. On the
retry, time_before(jiffies, data->heating_complete) evaluates to true,
and the function immediately fails with -EBUSY.
Return count as expected to fix the problem.
Fixes: 0eed6fc3d2b9e ("hwmon: (sht4x): add heater support")
Cc: Antoni Pokusinski <apokusinski01@gmail.com>
Cc: Alessandro Zini <alessandro.zini@siemens.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Link: https://patch.msgid.link/20260821144916.2889031-2-linux@roeck-us.net
|
|
Sashiko reports:
Heater sysfs callbacks (heater_enable_store, heater_power_store, and
heater_time_store) are exposed to data races without the hwmon lock.
If a user-space process reads hwmon data while another process enables
the heater, heater_enable_store() executes without holding
hwmon_lock(dev). This can interleave I2C commands and mutate shared
state (data->heating_complete and data->data_pending) concurrently
with sht4x_read_values(), leading to corrupted I2C sequences.
Fixes: 53dfa12299c1 ("hwmon: (sht4x) Rely on subsystem locking")
Cc: Alessandro Zini <alessandro.zini@siemens.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Link: https://patch.msgid.link/20260821144916.2889031-1-linux@roeck-us.net
|
|
The file description comment starts with "/**" which is reserved for
kernel-doc comments, triggering a kernel-doc checker warning. Change
it to a plain "/*" comment since it does not document any function or
struct.
Fixes: c67c248ca406a ("hwmon: (yogafan) Add support for Lenovo Yoga/Legion fan monitoring")
Signed-off-by: hanzhijian <hanzhijian1991@gmail.com>
Link: https://patch.msgid.link/20260821115720.2017516-1-hanzhijian1991@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
|
|
INA2XX current limits are converted into shunt voltage limits internally
using the shunt resistor value. Once a current limit's corresponding
voltage limit is written to the hardware, shunt voltage and current
alarms are indistinguishable from each other.
This causes two issues:
1. in0/curr1 alarms may be unintentionally cleared by reading from the
opposite input's alarm.
2. When a limit for either in0 (shunt voltage) or curr1 (current) is
set, both of their alarms are triggered, and both of their limits
read nonzero.
An example of this behavior on an INA231:
# cd /sys/class/hwmon/hwmon0
# head {curr1,in0}_input
==> curr1_input <==
1713
==> in0_input <==
2
# echo 1800 >curr1_lcrit
# head {curr1,in0}_lcrit_alarm
==> curr1_lcrit_alarm <==
1
==> in0_lcrit_alarm <==
0
# head {in0,curr1}_lcrit_alarm
==> in0_lcrit_alarm <==
1
==> curr1_lcrit_alarm <==
0
# head {in0,curr1}_lcrit_alarm
==> in0_lcrit_alarm <==
1
==> curr1_lcrit_alarm <==
1
This is because curr1 uses the same underlying masks
(INA226_SHUNT_*_VOLTAGE_MASK) as in0 on the hardware. As a result,
ina2xx_{curr,in}_read() both read the shunt voltage alarms/limits
without considering whether the voltage or current is currently set.
To fix this, track the active alarm type in ina2xx_data and guard
alarm/limit reads with a check that returns zero if the active alarm is
for a different type. The new field is initialized based on the
MASK_ENABLE register's set function, assuming voltage instead of current
when the shunt voltage mask is set.
After this fix, the alarms only read back 1 if their corresponding limit
is set:
# echo 0 >curr1_lcrit
# head {curr1,in0}_lcrit_alarm
==> curr1_lcrit_alarm <==
0
==> in0_lcrit_alarm <==
0
# echo 9999 >curr1_lcrit
# head {curr1,in0}_lcrit_alarm
==> curr1_lcrit_alarm <==
1
==> in0_lcrit_alarm <==
0
# echo 9999 >in0_lcrit
# head {curr1,in0}_lcrit_alarm
==> curr1_lcrit_alarm <==
0
==> in0_lcrit_alarm <==
1
Fixes: 4d5c2d986757 ("hwmon: (ina2xx) Add support for current limits")
Signed-off-by: Jared Kangas <jkangas@redhat.com>
Link: https://patch.msgid.link/20260820-upstream-ina2xx-in0-curr1-alarms-v2-4-fdce35abc41e@redhat.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
|
|
Instead of passing an explicit mask to alert/limit functions like
ina226_alert_read(), introduce an enum ina2xx_alert_type that can be
converted to a mask internally. This semantically separates current from
shunt voltage in helpers that use function masks, which previously saw
the same mask for the two functions.
Signed-off-by: Jared Kangas <jkangas@redhat.com>
Link: https://patch.msgid.link/20260820-upstream-ina2xx-in0-curr1-alarms-v2-3-fdce35abc41e@redhat.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
|
|
Mirror ina226_alert_limit_read/write and use struct ina2xx_data instead
of struct regmap in ina226_alert_read's parameters.
Signed-off-by: Jared Kangas <jkangas@redhat.com>
Link: https://patch.msgid.link/20260820-upstream-ina2xx-in0-curr1-alarms-v2-2-fdce35abc41e@redhat.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
|
|
The device parameter of hwmon_notify_event() must be a hardware monitoring
device. Since this is easy to get wrong, and since passing a non-hwmon
device may result in a crash, generate a warning traceback and abort if
a wrong device class is passed as parameter.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
|
|
shunt_resistor_store() currently acquires hwmon_lock to set
data->rshunt, but the corresponding access in shunt_resistor_show() is
unprotected. Acquire the lock in shunt_resistor_show() as well to ensure
proper synchronization.
Fixes: 3ad867001c91 ("hwmon: (ina2xx) fix sysfs shunt resistor read access")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260729162836.89BDF1F00A3A@smtp.kernel.org/
Signed-off-by: Jared Kangas <jkangas@redhat.com>
Link: https://patch.msgid.link/20260820-upstream-ina2xx-in0-curr1-alarms-v2-1-fdce35abc41e@redhat.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
|
|
Sashiko reports:
In pec_store(), a guard(mutex)(&hwdev->lock) is taken. If the chip write
operation returns an error other than -EOPNOTSUPP, the code jumps to the
put label, which calls put_device(hdev). If this drops the final reference,
the device is freed. When the function then returns, the guard cleanup
function runs and attempts to unlock the freed mutex.
Use scoped_guard() instead of guard() to avoid the problem.
Fixes: 3ad2a7b9b15d5 ("hwmon: Serialize accesses in hwmon core")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
|
|
fan_alarm_irq_handler() queues fan_data->alarm_work, but nothing
cancels it. fan_alarm_notify() dereferences fan_data and its hwmon
device. On unbind, devres frees the interrupt, which only waits for
the handler itself, and then releases the hwmon device and fan_data,
so a pending fan_alarm_notify() can run after those frees.
Replace INIT_WORK() with devm_work_autocancel(), registered before
devm_request_irq(). The devres cleanup then frees the interrupt
first, so no new work can be queued, and cancels the work while
fan_data and the hwmon device are still alive.
This issue was found by an in-house static analysis tool.
Fixes: d6fe1360f42e ("hwmon: add generic GPIO fan driver")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260819033317.446191-1-fanwu01@zju.edu.cn
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
|
|
When a device is in standby, the driver starts a one-shot conversion and
polls the BUSY flag before reading temperature, alarm, or fault data.
The poll result is currently ignored. Therefore, a timeout or a
status-register read failure can be hidden by a later successful read,
causing stale data to be returned as valid.
Return the polling error before reading the requested attribute.
Fixes: e2fe950f34e5 ("hwmon: add support for MCP998X")
Cc: stable@vger.kernel.org
Signed-off-by: Nikhil Gurudasani <nikhilgurudasani314@gmail.com>
Link: https://patch.msgid.link/20260819180701.34797-1-nikhilgurudasani314@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
|
|
The clk_init_data structure contains several mutually-exclusive members
for different methods to specify the possible parents of a clock,
prompting drivers to initialize only the members they need. However,
not initializing all members may cause subtle issues, which are only
exposed when CONFIG_INIT_STACK_ALL_PATTERN or CONFIG_INIT_STACK_NONE is
enabled.
ltc428_clk_provider_setup() does not fill in any parent clocks, and
assumes that init.num_parents is NULL. However, the latter in
uninitialized, and thus may cause a crash.
Make sure all members are fully initialized, to fix such bugs, and to
avoid future breakage when converting drivers to a different method for
specifying the parents.
Fixes: cbc29538dbf7d740 ("hwmon: Add driver for LTC4282")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/8ec3c5cbd2df675a938f090470f5da5f22008517.1787165329.git.geert+renesas@glider.be
Reviewed-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
|
|
amd_iommu_pdom_id_alloc() returns an int: a domain ID on success, or the
negative errno from ida_alloc_range() when the ID space is exhausted or
memory is short. amd_iommu_alloc_domain_nested() stores that return value
in gdom_info->hdom_id, which is a u32, and only then tests it:
gdom_info->hdom_id = amd_iommu_pdom_id_alloc();
if (gdom_info->hdom_id <= 0) {
The assignment discards the sign, so -ENOSPC becomes 0xffffffe4 and the
test never fires. The nested domain is then set up with a host domain ID
that was never allocated, instead of the allocation failing with -ENOSPC.
Keep the value in an int, test it there, and store it only once it is
known to be valid, which is what the other amd_iommu_pdom_id_alloc()
callers already do.
Fixes: 757d2b1fdf5b ("iommu/amd: Introduce gDomID-to-hDomID Mapping and handle parent domain invalidation")
Signed-off-by: Hemanth Selam <hemanth.selam@gmail.com>
Reviewed-by: Vasant Hegde <vasant.hegde@amd.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
|
|
Commit 283d245468a2 ("iommu/amd: Fix premature break in
init_iommu_one()") unintentionally broke older platforms - such as
the ASRockRack B550D4-4L - where the BIOS advertises incorrect IOMMU
features.
Move the HATDis check ahead of the GASup check, and re-introduce the
break inside the GASup check to restore correct behavior on affected
platforms.
This is a short-term fix to resolve the regression. Longer term, we
should rework how EFRs are tracked and prioritize the MMIO-advertised
EFR over the one reported via IVRS. That requires more extensive
changes and will be addressed separately.
Fixes: 283d245468a2 ("iommu/amd: Fix premature break in init_iommu_one()")
Reported-by: Andreas Juch <andreas@juch.cc>
Closes: https://lore.kernel.org/linux-iommu/07b2d390-f7a0-47e2-bc2c-eb0853acf52e@juch.cc/
Tested-by: Andreas Juch <andreas@juch.cc>
Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
|
|
Commit c5e1a1eb9279 ("iommu/amd: Simplify and Consolidate Virtual APIC
(AVIC) Enablement") moved the GA log allocation from iommu_init_pci()
to enable_iommus_vapic(), which is called on every resume.
iommu_init_ga_log() assigns iommu->ga_log and iommu->ga_log_tail
unconditionally. Each resume therefore replaces the boot-time pointers
and leaks both old allocations. The function also uses GFP_KERNEL from a
syscore resume callback, where interrupts are disabled and the non-boot
CPUs are offline.
Return early if both buffers are already allocated. Clear the pointers
in free_ga_log() so a partial allocation failure cannot leave ga_log
dangling.
Fixes: c5e1a1eb9279 ("iommu/amd: Simplify and Consolidate Virtual APIC (AVIC) Enablement")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Vasant Hegde <vasant.hegde@amd.com>
Reviewed-by: Ankit Soni <Ankit.Soni@amd.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
|
|
When using a 5-level translation table via ZPCI_TABLE_TYPE_RFX
get_rso_from_iova() returns NULL when the region-first entry is invalid.
Yet in get_rto_from_iova() the region-second origin rso is not checked
to be non-NULL before accessing rso[rsx] leading to a NULL pointer
dereference instead of a NULL return when iova_to_phys() is called on
a unmapped IOVA. Fix this by adding the missing NULL check.
Cc: stable@vger.kernel.org
Fixes: 81244074b518 ("iommu/s390: allow larger region tables")
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
|
|
Do not wait for IOFENCE.C completion when the command failed to enter the
queue. The command was not published to hardware, so waiting for its
producer index can only report a misleading execution timeout.
Fixes: 856c0cfe5c5f ("iommu/riscv: Command and fault queue support")
Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
|
|
Serialize command queue publishing so software producer state advances only
after a command is written and the hardware tail is updated. Wait for
hardware consumption outside the queue lock when the command queue is full
so other CPUs are not blocked behind a long poll.
Fixes: 856c0cfe5c5f ("iommu/riscv: Command and fault queue support")
Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
|
|
Add a raw spinlock to the RISC-V IOMMU queue state so command queue
publishing can be serialized by a later change.
Fixes: 856c0cfe5c5f ("iommu/riscv: Command and fault queue support")
Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
|
|
vdec_av1_slice_setup_tile() copies tile_cols + 1 / tile_rows + 1 entries
into mi_col_starts[] / mi_row_starts[] from the bitstream tile_info. Bound
the copy to the array capacity.
Fixes: 0934d3759615 ("media: mediatek: vcodec: separate decoder and encoder")
Assisted-by: Claude:claude-opus-4-8
Cc: stable@vger.kernel.org
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
|
|
rockchip_vpu981_av1_dec_set_tile_info() indexes the tile group entry
array by tile1 * tile_cols + tile0, reading up to tile_cols * tile_rows
entries, lays out one descriptor per tile in the AV1_MAX_TILES tile_info
buffer, and programs the real tile_cols / tile_rows into the hardware.
The tile group entry control is a dynamic array sized to the number of
entries userspace submitted, independent of tile_cols / tile_rows, so a
frame that claims more tiles than entries reads past the array. A frame
that claims more than AV1_MAX_TILES tiles also leaves the hardware
programmed for more tiles than the descriptor buffer holds.
Reject both in prepare_run(): tile_cols * tile_rows must not exceed the
submitted entry count or AV1_MAX_TILES. The entry count is read via
v4l2_ctrl_find() (ctrl->elems). This mirrors the bound the mediatek AV1
decoder already enforces.
Fixes: 727a400686a2 ("media: verisilicon: Add Rockchip AV1 decoder")
Assisted-by: Claude:claude-opus-4-8
Cc: stable@vger.kernel.org
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
|
|
rockchip_vpu981_av1_dec_set_tile_info() divides context_update_tile_id by
tile_info->tile_cols and writes one descriptor per tile into the tile_info
DMA buffer, which holds AV1_MAX_TILES entries; tile_cols and tile_rows
come from the bitstream. Guard the division against a zero tile_cols by
initialising the context-update values to zero and computing them only
when tile_cols is non-zero, and stop the descriptor writes once the
tile_info buffer is full. The tile geometry written to the hardware
registers is left unmodified; the per-dimension and total tile bounds are
enforced by the control validation.
Fixes: 727a400686a2 ("media: verisilicon: Add Rockchip AV1 decoder")
Assisted-by: Claude:claude-opus-4-8
Cc: stable@vger.kernel.org
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
|
|
prepare_tile_info_buffer() writes one entry per tile into the tile_sizes
DMA buffer, sized for a grid equal to the PPS uAPI array capacity. Use the
bounded v4l2_hevc_pps_num_tile_columns() / v4l2_hevc_pps_num_tile_rows()
helpers so the loops stay inside the buffer.
Fixes: cb5dd5a0fa51 ("media: hantro: Introduce G2/HEVC decoder")
Assisted-by: Claude:claude-opus-4-8
Cc: stable@vger.kernel.org
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
|
|
compute_tiles_uniform() and compute_tiles_non_uniform() loop over
num_tile_columns_minus1 + 1 / num_tile_rows_minus1 + 1 entries, and
assemble_hw_pps() writes one COLUMN_WIDTH / ROW_HEIGHT register per tile
and indexes priv_tbl->param_set[] by pic_parameter_set_id, all taken from
the untrusted PPS. Use the bounded v4l2_hevc_pps_num_tile_columns() /
v4l2_hevc_pps_num_tile_rows() helpers for the tile loops, and bail out of
assemble_hw_pps() before indexing priv_tbl->param_set[] with an
out-of-range pic_parameter_set_id, so the writes stay within the hardware
tables.
Fixes: 3595375c2301 ("media: rkvdec: Add HEVC backend")
Fixes: c9a59dc2acc7 ("media: rkvdec: Add HEVC support for the VDPU381 variant")
Assisted-by: Claude:claude-opus-4-8
Cc: stable@vger.kernel.org
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
|
|
The stateless AV1 decoders use tile_info.tile_cols and tile_rows as loop
bounds and as indices into the mi_*_starts[] and *_in_sbs_minus_1[]
arrays, as the divisor for context_update_tile_id, and their product
bounds the per-tile descriptor buffers, but std_validate_compound() does
not bound these u8 fields. Reject a V4L2_CTRL_TYPE_AV1_FRAME whose
tile_cols or tile_rows exceeds V4L2_AV1_MAX_TILE_COLS / _ROWS, or whose
product exceeds V4L2_AV1_MAX_TILE_COUNT. A zero tile count is left to the
consuming driver so the zero-initialised control that existing userspace
submits is still accepted.
Fixes: 9de30f579980 ("media: Add AV1 uAPI")
Assisted-by: Claude:claude-opus-4-8
Cc: stable@vger.kernel.org
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
|