virtio_rpmsg: set DRIVER_OK before using device

virtio spec requires that all drivers set DRIVER_OK
before using devices. While rpmsg isn't yet
included in the virtio 1 spec, previous spec versions
also required this.

virtio rpmsg violates this rule: is calls kick
before setting DRIVER_OK.

The fix isn't trivial since simply calling virtio_device_ready earlier
would mean we might get an interrupt in parallel with adding buffers.

Instead, split kick out to prepare+notify calls.  prepare before
virtio_device_ready - when we know we won't get interrupts. notify right
afterwards.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Ohad Ben-Cohen <ohad@wizery.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Michael S. Tsirkin 2015-03-12 11:54:41 +10:30 committed by Rusty Russell
parent 8051a2a518
commit 71e4b8bf04
1 changed files with 16 additions and 1 deletions

View File

@ -951,6 +951,7 @@ static int rpmsg_probe(struct virtio_device *vdev)
void *bufs_va;
int err = 0, i;
size_t total_buf_space;
bool notify;
vrp = kzalloc(sizeof(*vrp), GFP_KERNEL);
if (!vrp)
@ -1030,8 +1031,22 @@ static int rpmsg_probe(struct virtio_device *vdev)
}
}
/*
* Prepare to kick but don't notify yet - we can't do this before
* device is ready.
*/
notify = virtqueue_kick_prepare(vrp->rvq);
/* From this point on, we can notify and get callbacks. */
virtio_device_ready(vdev);
/* tell the remote processor it can start sending messages */
virtqueue_kick(vrp->rvq);
/*
* this might be concurrent with callbacks, but we are only
* doing notify, not a full kick here, so that's ok.
*/
if (notify)
virtqueue_notify(vrp->rvq);
dev_info(&vdev->dev, "rpmsg host is online\n");