summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCornelia Huck <cornelia.huck@de.ibm.com>2013-08-29 17:52:43 +0200
committerChristian Borntraeger <borntraeger@de.ibm.com>2013-09-20 12:46:53 +0200
commit441ea695f9e9d64399f69904c2dd12e59963f1a4 (patch)
tree80e9164bfc52201e7b521c5b33efa0cb6337fb8e
parentabd137a1bc72614e1e6ca1cd9502426e4b4f7e6a (diff)
downloadqemu-441ea695f9e9d64399f69904c2dd12e59963f1a4.tar.gz
qemu-441ea695f9e9d64399f69904c2dd12e59963f1a4.tar.bz2
qemu-441ea695f9e9d64399f69904c2dd12e59963f1a4.zip
s390/ipl: Fix waiting for virtio processing
The guest side must not manipulate the index for the used buffers. Instead, remember the state of the used buffer locally and wait until it has moved. Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Acked-by: Alexander Graf <agraf@suse.de> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
-rw-r--r--pc-bios/s390-ccw/virtio.c7
-rw-r--r--pc-bios/s390-ccw/virtio.h1
2 files changed, 5 insertions, 3 deletions
diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
index 49f2d291fc..4d6e48fcbe 100644
--- a/pc-bios/s390-ccw/virtio.c
+++ b/pc-bios/s390-ccw/virtio.c
@@ -123,6 +123,7 @@ static void vring_init(struct vring *vr, unsigned int num, void *p,
/* We're running with interrupts off anyways, so don't bother */
vr->used->flags = VRING_USED_F_NO_NOTIFY;
vr->used->idx = 0;
+ vr->used_idx = 0;
debug_print_addr("init vr", vr);
}
@@ -150,8 +151,6 @@ static void vring_send_buf(struct vring *vr, void *p, int len, int flags)
if (!(flags & VRING_DESC_F_NEXT)) {
vr->avail->idx++;
}
-
- vr->used->idx = vr->next_idx;
}
static u64 get_clock(void)
@@ -180,7 +179,8 @@ static int vring_wait_reply(struct vring *vr, int timeout)
struct subchannel_id schid = vr->schid;
int r = 0;
- while (vr->used->idx == vr->next_idx) {
+ /* Wait until the used index has moved. */
+ while (vr->used->idx == vr->used_idx) {
vring_notify(schid);
if (timeout && (get_second() >= target_second)) {
r = 1;
@@ -189,6 +189,7 @@ static int vring_wait_reply(struct vring *vr, int timeout)
yield();
}
+ vr->used_idx = vr->used->idx;
vr->next_idx = 0;
vr->desc[0].len = 0;
vr->desc[0].flags = 0;
diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h
index 86fdd579b4..772a63f152 100644
--- a/pc-bios/s390-ccw/virtio.h
+++ b/pc-bios/s390-ccw/virtio.h
@@ -115,6 +115,7 @@ struct vring_used {
struct vring {
unsigned int num;
int next_idx;
+ int used_idx;
struct vring_desc *desc;
struct vring_avail *avail;
struct vring_used *used;