Re: [PATCH v2] vfio/ccw: Flush notoper_work before returning from reset

From: Christian Borntraeger

Date: Mon Nov 09 2026 - 07:47:14 EST


Am 06.11.26 um 20:10 schrieb Yuho Choi:
vfio_ccw_dma_unmap() is the DMA invalidation callback, which must unpin
the pages covering the range before it returns. It calls
vfio_ccw_mdev_reset(), which raises a CLOSE event.

On the normal path fsm_close() calls cp_free() itself, so the pages are
unpinned synchronously. But if the subchannel cannot be disabled or
quiesced, fsm_close() falls through to a NOT_OPER event. Since commit
0c11f61a876e ("s390/vfio_ccw: Move cp cleanup out of not operational"),
fsm_notoper() only queues notoper_work, which is where cp_free() then
runs. That commit flushes the work in vfio_ccw_mdev_close_device() and
vfio_ccw_mdev_release_dev(), but nothing waits for it on the reset
path, so the callback returns with the pages still pinned.

Because notoper_work runs asynchronously, vfio_dma_do_unmap() can exhaust
its 10 retries before cp_free() completes, hitting BUG_ON(++retries > 10)
and taking the host down. A further CLOSE cannot help either, as both
CLOSE and OPEN are fsm_nop in the NOT_OPER state.

Does the the iommufd backend have the same problem?
iopt_unmap_iova_range() keeps calling the unmap callback and gives up with
WARN_ON(tries > 100) and -EDEADLOCK. So that path is also fixed, I guess.

[..]

Fixes: 0c11f61a876e ("s390/vfio_ccw: Move cp cleanup out of not operational")
cc stable ?

Signed-off-by: Yuho Choi <oss.patchbox@xxxxxxxxx>


Eric, Matt,

can you have a look?

[..]