Skip to content

Commit 3b930dd

Browse files
author
Antoine Martin
committed
fix: Fix upstream xhyve crash (virtio-net + UEFI)
When using virtio-net with an UEFI firmware (-f bootrom), hyperkit crashes on an assertion. See the related bug on xhyve: machyve/xhyve#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 <amartin@unowhy.com>
1 parent 8702deb commit 3b930dd

File tree

1 file changed

+27
-9
lines changed

1 file changed

+27
-9
lines changed

src/lib/pci_virtio_net_vmnet.c

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,10 @@ vmn_read(struct vmnet_state *vms, struct iovec *iov, int n) {
320320
v.vm_pkt_size += iov[i].iov_len;
321321
}
322322

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

325328
v.vm_pkt_iov = iov;
326329
v.vm_pkt_iovcnt = (uint32_t) n;
@@ -539,14 +542,29 @@ pci_vtnet_tap_rx(struct pci_vtnet_softc *sc)
539542

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

542-
if (len < 0 && errno == EWOULDBLOCK) {
543-
/*
544-
* No more packets, but still some avail ring
545-
* entries. Interrupt if needed/appropriate.
546-
*/
547-
vq_retchain(vq);
548-
vq_endchains(vq, 0);
549-
return;
545+
if (len < 0) {
546+
if (len == -2) {
547+
/*
548+
* Buffer passed is too short. The reason is unclear
549+
* to me but it seems that at boot some firmwares pass
550+
* buffers of the standard 1514 Ethernet length whereas the
551+
* size expected by Mac OS is 1518.
552+
*/
553+
iov[0].iov_base = dummybuf;
554+
iov[0].iov_len = sizeof(dummybuf);
555+
(void) vmn_read(sc->vms, iov, 1);
556+
vq_endchains(vq, 1);
557+
return;
558+
559+
} else if (errno == EWOULDBLOCK) {
560+
/*
561+
* No more packets, but still some avail ring
562+
* entries. Interrupt if needed/appropriate.
563+
*/
564+
vq_retchain(vq);
565+
vq_endchains(vq, 0);
566+
return;
567+
}
550568
}
551569

552570
/*

0 commit comments

Comments
 (0)