vmx: reset virtio queue state on device reset

when a virtio device gets reset, we have to also reset the device
shadow indices: availableidx and usedidx. for extra safetly,
we also reset the buffer descriptor table addresses.

this is accomplished by adding a vioqreset(VIOQueue*) function
that brings the queue to its initial reset state.

this fixes non functional ethernet after reboot(8).
This commit is contained in:
cinap_lenrek 2021-07-11 12:12:51 +00:00
parent f58d99aa7a
commit ad37339a1c

View file

@ -310,6 +310,17 @@ vioqaddrset(VIOQueue *q, u64int addr)
qunlock(q); qunlock(q);
} }
static void
vioqreset(VIOQueue *q)
{
q->desc = nil;
q->avail = nil;
q->used = nil;
q->addr = 0;
q->availidx = 0;
q->usedidx = 0;
}
static void static void
viodevstatset(VIODev *v, u32int val) viodevstatset(VIODev *v, u32int val)
{ {
@ -325,6 +336,7 @@ viodevstatset(VIODev *v, u32int val)
qlock(&v->qu[i]); qlock(&v->qu[i]);
while(v->qu[i].livebuf > 0) while(v->qu[i].livebuf > 0)
rsleep(&v->qu[i].livebufrend); rsleep(&v->qu[i].livebufrend);
vioqreset(&v->qu[i]);
qunlock(&v->qu[i]); qunlock(&v->qu[i]);
} }
}else{ }else{
@ -396,6 +408,7 @@ mkvioqueue(VIODev *d, int sz, void (*fn)(VIOQueue*))
q->size = sz; q->size = sz;
q->d = d; q->d = d;
q->notify = fn; q->notify = fn;
vioqreset(q);
return q; return q;
} }