mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 22:14:03 +02:00
drm/vmwgfx: avoid destroy_workqueue(NULL) on vkms init failure
Two paths through vmw_vkms_init() can leave vmw->crc_workq NULL while
still leaving the rest of the driver in a state that calls
vmw_vkms_cleanup() at module unload:
1. vmw_host_get_guestinfo(GUESTINFO_VBLANK, ...) failing or
returning an oversized buffer -- the common case on hosts
without a VBLANK guestinfo entry -- early-returned before the
workqueue allocation.
2. alloc_ordered_workqueue() returning NULL on memory pressure.
vmw_vkms_cleanup() then calls destroy_workqueue(NULL), which
dereferences wq->name and panics.
Fix the first case by removing the early return: vmw->vkms_enabled
is already false on the rpci-failure path so no work will ever be
queued, and allocating the workqueue unconditionally keeps the
control flow simple. Fix the second case by guarding the cleanup
with a NULL check, since alloc_ordered_workqueue() can still fail
under low memory.
Fixes: 7b0062036c ("drm/vmwgfx: Implement virtual crc generation")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4.7
Signed-off-by: Zack Rusin <zack.rusin@broadcom.com>
Reviewed-by: Ian Forbes <ian.forbes@broadcom.com>
Link: https://patch.msgid.link/20260505222728.519626-9-zack.rusin@broadcom.com
This commit is contained in:
parent
f4f1db96bf
commit
05eaa887e7
|
|
@ -206,14 +206,14 @@ vmw_vkms_init(struct vmw_private *vmw)
|
|||
vmw->vkms_enabled = false;
|
||||
|
||||
ret = vmw_host_get_guestinfo(GUESTINFO_VBLANK, buffer, &buf_len);
|
||||
if (ret || buf_len > max_buf_len)
|
||||
return;
|
||||
buffer[buf_len] = '\0';
|
||||
if (!ret && buf_len <= max_buf_len) {
|
||||
buffer[buf_len] = '\0';
|
||||
|
||||
ret = kstrtobool(buffer, &vmw->vkms_enabled);
|
||||
if (!ret && vmw->vkms_enabled) {
|
||||
ret = drm_vblank_init(&vmw->drm, VMWGFX_NUM_DISPLAY_UNITS);
|
||||
vmw->vkms_enabled = (ret == 0);
|
||||
ret = kstrtobool(buffer, &vmw->vkms_enabled);
|
||||
if (!ret && vmw->vkms_enabled) {
|
||||
ret = drm_vblank_init(&vmw->drm, VMWGFX_NUM_DISPLAY_UNITS);
|
||||
vmw->vkms_enabled = (ret == 0);
|
||||
}
|
||||
}
|
||||
|
||||
vmw->crc_workq = alloc_ordered_workqueue("vmwgfx_crc_generator", 0);
|
||||
|
|
@ -228,7 +228,8 @@ vmw_vkms_init(struct vmw_private *vmw)
|
|||
void
|
||||
vmw_vkms_cleanup(struct vmw_private *vmw)
|
||||
{
|
||||
destroy_workqueue(vmw->crc_workq);
|
||||
if (vmw->crc_workq)
|
||||
destroy_workqueue(vmw->crc_workq);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user