Skip to content

Commit d8354a1

Browse files
halil-pasicVasily Gorbik
authored andcommitted
s390/virtio_ccw: Fix config change notifications
Commit e3e9bda ("s390/virtio_ccw: use DMA handle from DMA API") broke configuration change notifications for virtio-ccw by putting the DMA address of *indicatorp directly into ccw->cda disregarding the fact that if !!(vcdev->is_thinint) then the function virtio_ccw_register_adapter_ind() will overwrite that ccw->cda value with the address of the virtio_thinint_area so it can actually set up the adapter interrupts via CCW_CMD_SET_IND_ADAPTER. Thus we end up pointing to the wrong object for both CCW_CMD_SET_IND if setting up the adapter interrupts fails, and for CCW_CMD_SET_CONF_IND regardless whether it succeeds or fails. To fix this, let us save away the dma address of *indicatorp in a local variable, and copy it to ccw->cda after the "vcdev->is_thinint" branch. Fixes: e3e9bda ("s390/virtio_ccw: use DMA handle from DMA API") Reported-by: Boqiao Fu <[email protected]> Reported-by: Sebastian Mitterle <[email protected]> Closes: https://issues.redhat.com/browse/RHEL-39983 Tested-by: Thomas Huth <[email protected]> Reviewed-by: Eric Farman <[email protected]> Signed-off-by: Halil Pasic <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vasily Gorbik <[email protected]>
1 parent 4181b51 commit d8354a1

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

drivers/s390/virtio/virtio_ccw.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,7 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs,
698698
dma64_t *indicatorp = NULL;
699699
int ret, i, queue_idx = 0;
700700
struct ccw1 *ccw;
701+
dma32_t indicatorp_dma = 0;
701702

702703
ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw), NULL);
703704
if (!ccw)
@@ -725,7 +726,7 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs,
725726
*/
726727
indicatorp = ccw_device_dma_zalloc(vcdev->cdev,
727728
sizeof(*indicatorp),
728-
&ccw->cda);
729+
&indicatorp_dma);
729730
if (!indicatorp)
730731
goto out;
731732
*indicatorp = indicators_dma(vcdev);
@@ -735,6 +736,7 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs,
735736
/* no error, just fall back to legacy interrupts */
736737
vcdev->is_thinint = false;
737738
}
739+
ccw->cda = indicatorp_dma;
738740
if (!vcdev->is_thinint) {
739741
/* Register queue indicators with host. */
740742
*indicators(vcdev) = 0;

0 commit comments

Comments
 (0)