diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2015-03-11 21:24:41 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2015-03-13 01:25:42 -0400 |
commit | 71e4b8bf0482fc7d70e9d4c10b13c207a285d58a (patch) | |
tree | 435db3fcf8c9e28fdc331b64fb0f4effb80b3138 /drivers/rpmsg | |
parent | 8051a2a518fcf3827a143470083ad6008697ff17 (diff) |
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>
Diffstat (limited to 'drivers/rpmsg')
-rw-r--r-- | drivers/rpmsg/virtio_rpmsg_bus.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index 92f6af6da699..73354ee27877 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c | |||
@@ -951,6 +951,7 @@ static int rpmsg_probe(struct virtio_device *vdev) | |||
951 | void *bufs_va; | 951 | void *bufs_va; |
952 | int err = 0, i; | 952 | int err = 0, i; |
953 | size_t total_buf_space; | 953 | size_t total_buf_space; |
954 | bool notify; | ||
954 | 955 | ||
955 | vrp = kzalloc(sizeof(*vrp), GFP_KERNEL); | 956 | vrp = kzalloc(sizeof(*vrp), GFP_KERNEL); |
956 | if (!vrp) | 957 | if (!vrp) |
@@ -1030,8 +1031,22 @@ static int rpmsg_probe(struct virtio_device *vdev) | |||
1030 | } | 1031 | } |
1031 | } | 1032 | } |
1032 | 1033 | ||
1034 | /* | ||
1035 | * Prepare to kick but don't notify yet - we can't do this before | ||
1036 | * device is ready. | ||
1037 | */ | ||
1038 | notify = virtqueue_kick_prepare(vrp->rvq); | ||
1039 | |||
1040 | /* From this point on, we can notify and get callbacks. */ | ||
1041 | virtio_device_ready(vdev); | ||
1042 | |||
1033 | /* tell the remote processor it can start sending messages */ | 1043 | /* tell the remote processor it can start sending messages */ |
1034 | virtqueue_kick(vrp->rvq); | 1044 | /* |
1045 | * this might be concurrent with callbacks, but we are only | ||
1046 | * doing notify, not a full kick here, so that's ok. | ||
1047 | */ | ||
1048 | if (notify) | ||
1049 | virtqueue_notify(vrp->rvq); | ||
1035 | 1050 | ||
1036 | dev_info(&vdev->dev, "rpmsg host is online\n"); | 1051 | dev_info(&vdev->dev, "rpmsg host is online\n"); |
1037 | 1052 | ||