On 06/13/2014 01:52 PM, Alexander Graf wrote: > > On 13.06.14 13:24, Greg Kurz wrote: >> From: Rusty Russell <ru...@rustcorp.com.au> >> >> Signed-off-by: Rusty Russell <ru...@rustcorp.com.au> >> Reviewed-by: Anthony Liguori <aligu...@us.ibm.com> >> [ pass VirtIODevice * to memory accessors, >> TCP checksums fix by Cédric Le Goater, >> Greg Kurz <gk...@linux.vnet.ibm.com> ] >> Cc: Cédric Le Goater <c...@fr.ibm.com> >> Signed-off-by: Greg Kurz <gk...@linux.vnet.ibm.com> >> --- >> hw/net/virtio-net.c | 34 +++++++++++++++++++++++++++------- >> 1 file changed, 27 insertions(+), 7 deletions(-) >> >> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c >> index 58e7b73..fb17919 100644 >> --- a/hw/net/virtio-net.c >> +++ b/hw/net/virtio-net.c >> @@ -23,6 +23,7 @@ >> #include "hw/virtio/virtio-bus.h" >> #include "qapi/qmp/qjson.h" >> #include "monitor/monitor.h" >> +#include "hw/virtio/virtio-access.h" >> #define VIRTIO_NET_VM_VERSION 11 >> @@ -72,8 +73,8 @@ static void virtio_net_get_config(VirtIODevice *vdev, >> uint8_t *config) >> VirtIONet *n = VIRTIO_NET(vdev); >> struct virtio_net_config netcfg; >> - stw_p(&netcfg.status, n->status); >> - stw_p(&netcfg.max_virtqueue_pairs, n->max_queues); >> + virtio_stw_p(vdev, &netcfg.status, n->status); >> + virtio_stw_p(vdev, &netcfg.max_virtqueue_pairs, n->max_queues); >> memcpy(netcfg.mac, n->mac, ETH_ALEN); >> memcpy(config, &netcfg, n->config_size); >> } >> @@ -611,6 +612,7 @@ static int virtio_net_handle_offloads(VirtIONet *n, >> uint8_t cmd, >> static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd, >> struct iovec *iov, unsigned int iov_cnt) >> { >> + VirtIODevice *vdev = VIRTIO_DEVICE(n); >> struct virtio_net_ctrl_mac mac_data; >> size_t s; >> NetClientState *nc = qemu_get_queue(n->nic); >> @@ -639,7 +641,7 @@ static int virtio_net_handle_mac(VirtIONet *n, uint8_t >> cmd, >> s = iov_to_buf(iov, iov_cnt, 0, &mac_data.entries, >> sizeof(mac_data.entries)); >> - mac_data.entries = ldl_p(&mac_data.entries); >> + mac_data.entries = virtio_ldl_p(vdev, &mac_data.entries); >> if (s != sizeof(mac_data.entries)) { >> goto error; >> } >> @@ -666,7 +668,7 @@ static int virtio_net_handle_mac(VirtIONet *n, uint8_t >> cmd, >> s = iov_to_buf(iov, iov_cnt, 0, &mac_data.entries, >> sizeof(mac_data.entries)); >> - mac_data.entries = ldl_p(&mac_data.entries); >> + mac_data.entries = virtio_ldl_p(vdev, &mac_data.entries); >> if (s != sizeof(mac_data.entries)) { >> goto error; >> } >> @@ -706,12 +708,13 @@ error: >> static int virtio_net_handle_vlan_table(VirtIONet *n, uint8_t cmd, >> struct iovec *iov, unsigned int >> iov_cnt) >> { >> + VirtIODevice *vdev = VIRTIO_DEVICE(n); >> uint16_t vid; >> size_t s; >> NetClientState *nc = qemu_get_queue(n->nic); >> s = iov_to_buf(iov, iov_cnt, 0, &vid, sizeof(vid)); >> - vid = lduw_p(&vid); >> + vid = virtio_lduw_p(vdev, &vid); >> if (s != sizeof(vid)) { >> return VIRTIO_NET_ERR; >> } >> @@ -748,7 +751,7 @@ static int virtio_net_handle_mq(VirtIONet *n, uint8_t >> cmd, >> return VIRTIO_NET_ERR; >> } >> - queues = lduw_p(&mq.virtqueue_pairs); >> + queues = virtio_lduw_p(vdev, &mq.virtqueue_pairs); >> if (queues < VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN || >> queues > VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX || >> @@ -863,6 +866,14 @@ static int virtio_net_has_buffers(VirtIONetQueue *q, >> int bufsize) >> return 1; >> } >> +static void virtio_net_hdr_swap(VirtIODevice *vdev, struct virtio_net_hdr >> *hdr) >> +{ >> + virtio_tswap16s(vdev, &hdr->hdr_len); >> + virtio_tswap16s(vdev, &hdr->gso_size); >> + virtio_tswap16s(vdev, &hdr->csum_start); >> + virtio_tswap16s(vdev, &hdr->csum_offset); >> +} >> + >> /* dhclient uses AF_PACKET but doesn't pass auxdata to the kernel so >> * it never finds out that the packets don't have valid checksums. This >> * causes dhclient to get upset. Fedora's carried a patch for ages to >> @@ -898,6 +909,7 @@ static void receive_header(VirtIONet *n, const struct >> iovec *iov, int iov_cnt, >> void *wbuf = (void *)buf; >> work_around_broken_dhclient(wbuf, wbuf + n->host_hdr_len, >> size - n->host_hdr_len); >> + virtio_net_hdr_swap(VIRTIO_DEVICE(n), wbuf); >> iov_from_buf(iov, iov_cnt, 0, buf, sizeof(struct virtio_net_hdr)); >> } else { >> struct virtio_net_hdr hdr = { >> @@ -1047,7 +1059,7 @@ static ssize_t virtio_net_receive(NetClientState *nc, >> const uint8_t *buf, size_t >> } >> if (mhdr_cnt) { >> - stw_p(&mhdr.num_buffers, i); >> + virtio_stw_p(vdev, &mhdr.num_buffers, i); >> iov_from_buf(mhdr_sg, mhdr_cnt, >> 0, >> &mhdr.num_buffers, sizeof mhdr.num_buffers); >> @@ -1106,6 +1118,14 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) >> exit(1); >> } >> + if (n->has_vnet_hdr) { >> + if (out_sg[0].iov_len < n->guest_hdr_len) { >> + error_report("virtio-net header incorrect"); >> + exit(1); >> + } >> + virtio_net_hdr_swap(vdev, (void *) out_sg[0].iov_base); > > Where does this come from? If you're doing twap() wouldn't that have been > broken before too?
That's a (possible) fix for virtio-net when vhost=off. It should probably be in another patch. C.