Skip to content

Commit

Permalink
fix: machyve#164 virtio-net + UEFI crash
Browse files Browse the repository at this point in the history
When using virtio-net with an UEFI firmware (bootrom),
xhyve crashes on an assertion. See the related bug
machyve#164

The complete details are not clear to me, but it seems
that during boot, the firmware reads on the interface but
doesn't provide big enough read buffers. It seems that
the space for VLAN headers is missing.

This patch drops the related reads, so normal booting can
occur. Network boot probably doesn't work, though.

Signed-off-by: Antoine Martin [email protected]
  • Loading branch information
Antoine Martin authored and dch committed Oct 17, 2020
1 parent 2368a7a commit d1ce163
Showing 1 changed file with 29 additions and 11 deletions.
40 changes: 29 additions & 11 deletions src/pci_virtio_net_vmnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,10 @@ vmn_read(struct vmnet_state *vms, struct iovec *iov, int n) {
v.vm_pkt_size += iov[i].iov_len;
}

assert(v.vm_pkt_size >= vms->max_packet_size);
if (v.vm_pkt_size < vms->max_packet_size) {
fprintf(stderr, "Read buffer too small: %ld bytes. vmnet expected at least %d.\n", v.vm_pkt_size, vms->max_packet_size);
return (-2);
}

v.vm_pkt_iov = iov;
v.vm_pkt_iovcnt = (uint32_t) n;
Expand Down Expand Up @@ -550,17 +553,32 @@ pci_vtnet_tap_rx(struct pci_vtnet_softc *sc)
*/
vrx = iov[0].iov_base;
riov = rx_iov_trim(iov, &n, sc->rx_vhdrlen);

len = (int) vmn_read(sc->vms, riov, n);

if (len < 0 && errno == EWOULDBLOCK) {
/*
* No more packets, but still some avail ring
* entries. Interrupt if needed/appropriate.
*/
vq_retchain(vq);
vq_endchains(vq, 0);
return;

if (len < 0) {
if (len == -2) {
/*
* Buffer passed is too short. The reason is unclear
* to me but it seems that at boot some firmwares pass
* buffers of the standard 1514 Ethernet length whereas the
* size expected by Mac OS is 1518.
*/
iov[0].iov_base = dummybuf;
iov[0].iov_len = sizeof(dummybuf);
(void) vmn_read(sc->vms, iov, 1);
vq_endchains(vq, 1);
return;

} else if (errno == EWOULDBLOCK) {
/*
* No more packets, but still some avail ring
* entries. Interrupt if needed/appropriate.
*/
vq_retchain(vq);
vq_endchains(vq, 0);
return;
}
}

/*
Expand Down

0 comments on commit d1ce163

Please sign in to comment.