]> git.lizzy.rs Git - plan9front.git/commitdiff
vmx: reset virtio queue state on device reset
authorcinap_lenrek <cinap_lenrek@felloff.net>
Sun, 11 Jul 2021 12:12:51 +0000 (12:12 +0000)
committercinap_lenrek <cinap_lenrek@felloff.net>
Sun, 11 Jul 2021 12:12:51 +0000 (12:12 +0000)
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).

sys/src/cmd/vmx/virtio.c

index 6451eeef571f28c6fad439bef3ff885b2d2f8af5..da0558320e0fbbd37e9a161cf3b54196ef701fcb 100644 (file)
@@ -310,6 +310,17 @@ vioqaddrset(VIOQueue *q, u64int addr)
        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
 viodevstatset(VIODev *v, u32int val)
 {
@@ -325,6 +336,7 @@ viodevstatset(VIODev *v, u32int val)
                        qlock(&v->qu[i]);
                        while(v->qu[i].livebuf > 0)
                                rsleep(&v->qu[i].livebufrend);
+                       vioqreset(&v->qu[i]);
                        qunlock(&v->qu[i]);
                }
        }else{
@@ -396,6 +408,7 @@ mkvioqueue(VIODev *d, int sz, void (*fn)(VIOQueue*))
        q->size = sz;
        q->d = d;
        q->notify = fn;
+       vioqreset(q);
        return q;
 }