Xen HVM e1000 Issues + Patch

Xen HVM has some very nice features for emulating certain hardware interfaces for HVM guests.

This post describes an issue with the e1000 model driver on Debian’s packaged xen-qemu-dm-4.0.

Enabling the e1000 driver is straightforward and accomplished by adding the model the VM config for the vif as follows:

vif = [ 'type=ioemu, bridge=xen-br0, model=e1000', ]

(For completeness sake, the models available are: i82551, i82557b, i82559er, ne2k_pci, ne2k_isa, pcnet, rtl8139, e1000, smc91c111, lance and mcf_fec.)

When using the e1000 driver you will notice that the dom0 cannot ping the domU guest, nor can other guests ping the domU. However, pinging the domU from another machine on your network will work.

The reason for this is that the e1000 driver does not pad frames to be at least the minimum ethernet frame size. When the offending frame is forwarded through a physical adapter it will add the needed padding. This explains the odd behavior and can cause quite some frustration especially if your domU guest absolutely needs to use the e1000.

The solution is to patch and rebuild the pre-packaged xen-qemu-dm-4.0. The patch required for this is here:

--- a/hw/e1000.c        2010-07-02 11:36:34.000000000 -0500
+++ b/hw/e1000.c        2012-02-20 01:39:24.559113732 -0600
@@ -51,6 +51,7 @@
 
 #define IOPORT_SIZE       0x40
 #define PNPMMIO_SIZE      0x20000
+#define MIN_BUF_SIZE     60
 
 /*
  * HW models:
@@ -602,11 +603,20 @@
     unsigned int n, rdt;
     uint32_t rdh_start;
     uint16_t vlan_special = 0;
-    uint8_t vlan_status = 0, vlan_offset = 0;
+    uint8_t vlan_status = 0, vlan_offset = 0, min_buf[MIN_BUF_SIZE];
 
     if (!(s->mac_reg[RCTL] & E1000_RCTL_EN))
         return;
 
+    /* Pad to minimum Ethernet frame length */
+    if (size < sizeof(min_buf)) {
+        memcpy(min_buf, buf, size);
+        memset(&min_buf[size], 0, sizeof(min_buf) - size);
+        buf = min_buf;
+        size = sizeof(min_buf);
+    }
+
+
     if (size > s->rxbuf_size) {
         DBGOUT(RX, "packet too large for buffers (%d > %d)\n", size,
                s->rxbuf_size);

Originally seen on: http://permalink.gmane.org/gmane.comp.emulators.qemu/80804

Posted in debian, xen