Am 16.09.26 um 22:32 schrieb Eric Farman:
The various indicators pointers allow them to be overwritten,
but leak any existing structs that might be there. The adapter
indicators path checks that it isn't converting from regular
to thin interrupts, but a check in the reverse direction isn't
performed.

Rather than unwinding the existing allocations to allow additional
assignments, just reject these duplicates.

Signed-off-by: Eric Farman <[email protected]>
---
  hw/s390x/virtio-ccw.c | 12 +++++++++++-
  1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index eb6378ea4c..d700db405b 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -565,6 +565,11 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
              ret = -EINVAL;
              break;
          }
+        if (dev->indicators) {
+            /* Do not set without un-setting first */
+            ret = -ENOSYS;
+            break;
+        }
          if (sch->thinint_active) {
              /* Trigger a command reject. */
              ret = -ENOSYS;
@@ -599,6 +604,11 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
              ret = -EINVAL;
              break;
          }
+        if (dev->indicators2) {
+            /* Do not set without un-setting first */
+            ret = -ENOSYS;
+            break;
+        }
          if (!ccw.cda) {
              ret = -EFAULT;
          } else {
@@ -657,7 +667,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
          }
          if (!ccw.cda) {
              ret = -EFAULT;
-        } else if (dev->indicators && !sch->thinint_active) {
+        } else if (dev->indicators || dev->summary_indicator) {
              /* Trigger a command reject. */
              ret = -ENOSYS;
          } else {

I think we have to do the full unwind.
The Linux driver deregisters indicators by issuing SET_IND with address 0,
or SET_IND_ADAPTER with device indicator 0. The virtio drivers reset the
device before del_vqs, so the deregistration lands on a clean state and
QEMU records an indicator at address 0. A later rebind or module reload
does not reset again, so the next SET_IND_ADAPTER and the SET_IND fallback
are both rejected and the probe fails. The old condition on SET_IND_ADAPTER
existed precisely to let the deregistration through while thinint is active.
The fix should release the existing indicator before overwriting, or treat
address 0 as deregistration. Releasing before overwriting also handles the
find_vqs error path in the guest, which deregisters without a reset in between.

Reply via email to