On Wed, 23 Nov 2016, Rafael Zalamena wrote:

> > Maybe something like this is enough already (untested):
> 
> I tried your diff without Mike's if_vio diff and it doesn't panic anymore,
> however it doesn't work.
> 
> vioX can send packets to host, host receives them and reply, but vioX
> doesn't see any packets back. I don't even need to touch the interface
> up/down status to see this happening. Also when the interface comes
> up after being shutdown it sends a bunch of packets to host.

Sorry, device_status is a bitmask, not a plain value.

Try the patch below. The first hunk is to fix the 'sends a bunch of 
packets'. If it causes any problems, leave it out.

diff --git usr.sbin/vmd/virtio.c usr.sbin/vmd/virtio.c
index 93def73..6436e6a 100644
--- usr.sbin/vmd/virtio.c
+++ usr.sbin/vmd/virtio.c
@@ -703,6 +703,13 @@ virtio_net_io(int dir, uint16_t reg, uint32_t *data, 
uint8_t *intr,
                        break;
                case VIRTIO_CONFIG_DEVICE_STATUS:
                        dev->cfg.device_status = *data;
+                       if (*data == 0) {
+                               dev->vq[0].last_avail = 0;
+                               dev->vq[0].notified_avail = 0;
+                               dev->vq[1].last_avail = 0;
+                               dev->vq[1].notified_avail = 0;
+                               /* XXX do proper reset */
+                       }
                        break;
                default:
                        break;
@@ -796,6 +803,9 @@ vionet_enq_rx(struct vionet_dev *dev, char *pkt, ssize_t 
sz, int *spc)
 
        ret = 0;
 
+       if (!(dev->cfg.device_status & VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK))
+               return ret;
+
        vr_sz = vring_size(VIONET_QUEUE_SIZE);
        q_gpa = dev->vq[0].qa;
        q_gpa = q_gpa * VIRTIO_PAGE_SIZE;

Reply via email to