From 1bfa316ce776d1f90ac96c59b4b69910db19ed6d Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 5 Feb 2016 11:43:11 +0100 Subject: virtio-net: use the backend cross-endian capabilities When running a fully emulated device in cross-endian conditions, including a virtio 1.0 device offered to a big endian guest, we need to fix the vnet headers. This is currently handled by the virtio_net_hdr_swap() function in the core virtio-net code but it should actually be handled by the net backend. With this patch, virtio-net now tries to configure the backend to do the endian fixing when the device starts (i.e. drivers sets the CONFIG_OK bit). If the backend cannot support the requested endiannes, we have to fallback onto virtio_net_hdr_swap(): this is recorded in the needs_vnet_hdr_swap flag, to be used in the TX and RX paths. Note that we reset the backend to the default behaviour (guest native endianness) when the device stops (i.e. device status had CONFIG_OK bit and driver unsets it). This is needed, with the linux tap backend at least, otherwise the guest may lose network connectivity if rebooted into a different endianness. The current vhost-net code also tries to configure net backends. This will be no more needed and will be reverted in a subsequent patch. Reviewed-by: Cornelia Huck Reviewed-by: Laurent Vivier Signed-off-by: Greg Kurz Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Laurent Vivier --- include/hw/virtio/virtio-access.h | 9 --------- include/hw/virtio/virtio-net.h | 1 + 2 files changed, 1 insertion(+), 9 deletions(-) (limited to 'include') diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h index 8aec843..a01fff2 100644 --- a/include/hw/virtio/virtio-access.h +++ b/include/hw/virtio/virtio-access.h @@ -143,15 +143,6 @@ static inline uint64_t virtio_ldq_p(VirtIODevice *vdev, const void *ptr) } } -static inline bool virtio_needs_swap(VirtIODevice *vdev) -{ -#ifdef HOST_WORDS_BIGENDIAN - return virtio_access_is_big_endian(vdev) ? false : true; -#else - return virtio_access_is_big_endian(vdev) ? true : false; -#endif -} - static inline uint16_t virtio_tswap16(VirtIODevice *vdev, uint16_t s) { #ifdef HOST_WORDS_BIGENDIAN diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h index 2ce3b03..0cabdb6 100644 --- a/include/hw/virtio/virtio-net.h +++ b/include/hw/virtio/virtio-net.h @@ -94,6 +94,7 @@ typedef struct VirtIONet { uint64_t curr_guest_offloads; QEMUTimer *announce_timer; int announce_counter; + bool needs_vnet_hdr_swap; } VirtIONet; void virtio_net_set_netclient_name(VirtIONet *n, const char *name, -- cgit v1.1 From a122ab24725c0392d4f53105aff343e703119fbe Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 5 Feb 2016 11:45:40 +0100 Subject: virtio: move cross-endian helper to vhost If target is bi-endian (ppc64, arm), the virtio_legacy_is_cross_endian() indeed returns the runtime state of the virtio device. However, it returns false unconditionally in the general case. This sounds a bit strange given the name of the function. This helper is only useful for vhost actually, where indeed non bi-endian targets don't have to deal with cross-endian issues. This patch moves the helper to vhost.c and gives it a more appropriate name. Reviewed-by: Cornelia Huck Reviewed-by: Laurent Vivier Signed-off-by: Greg Kurz Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Laurent Vivier --- include/hw/virtio/virtio-access.h | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'include') diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h index a01fff2..f1f12af 100644 --- a/include/hw/virtio/virtio-access.h +++ b/include/hw/virtio/virtio-access.h @@ -32,19 +32,6 @@ static inline bool virtio_access_is_big_endian(VirtIODevice *vdev) #endif } -static inline bool virtio_legacy_is_cross_endian(VirtIODevice *vdev) -{ -#ifdef TARGET_IS_BIENDIAN -#ifdef HOST_WORDS_BIGENDIAN - return !virtio_is_big_endian(vdev); -#else - return virtio_is_big_endian(vdev); -#endif -#else - return false; -#endif -} - static inline uint16_t virtio_lduw_phys(VirtIODevice *vdev, hwaddr pa) { if (virtio_access_is_big_endian(vdev)) { -- cgit v1.1 From e5157e313cd9c2d57f28873318d0bb29c77a9b1a Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 5 Feb 2016 11:46:18 +0100 Subject: virtio: optimize virtio_access_is_big_endian() for little-endian targets When adding cross-endian support, we introduced the TARGET_IS_BIENDIAN macro and the virtio_access_is_big_endian() helper to have a branchless fast path in the virtio memory accessors for targets that don't switch endian. This was considered as a strong requirement at the time. Now we have added a runtime check for virtio 1.0, which ruins the benefit of the virtio_access_is_big_endian() helper for always little-endian targets. With this patch, always little-endian targets stop checking for virtio 1.0, since the result is little-endian in all cases. Reviewed-by: Cornelia Huck Reviewed-by: Laurent Vivier Signed-off-by: Greg Kurz Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Laurent Vivier --- include/hw/virtio/virtio-access.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h index f1f12af..8dc84f5 100644 --- a/include/hw/virtio/virtio-access.h +++ b/include/hw/virtio/virtio-access.h @@ -19,13 +19,13 @@ static inline bool virtio_access_is_big_endian(VirtIODevice *vdev) { +#if defined(TARGET_IS_BIENDIAN) + return virtio_is_big_endian(vdev); +#elif defined(TARGET_WORDS_BIGENDIAN) if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) { /* Devices conforming to VIRTIO 1.0 or later are always LE. */ return false; } -#if defined(TARGET_IS_BIENDIAN) - return virtio_is_big_endian(vdev); -#elif defined(TARGET_WORDS_BIGENDIAN) return true; #else return false; -- cgit v1.1 From 9cfaa0079f5053683c6a632070244c35fa319549 Mon Sep 17 00:00:00 2001 From: Cao jin Date: Fri, 15 Jan 2016 10:23:32 +0800 Subject: change type of pci_bridge_initfn() to void Since it can`t fail. Also modify the callers. Signed-off-by: Cao jin Reviewed-by: Markus Armbruster Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Marcel Apfelbaum --- include/hw/pci/pci_bridge.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/hw/pci/pci_bridge.h b/include/hw/pci/pci_bridge.h index 93b621c..ed4aff6 100644 --- a/include/hw/pci/pci_bridge.h +++ b/include/hw/pci/pci_bridge.h @@ -48,7 +48,7 @@ void pci_bridge_disable_base_limit(PCIDevice *dev); void pci_bridge_reset_reg(PCIDevice *dev); void pci_bridge_reset(DeviceState *qdev); -int pci_bridge_initfn(PCIDevice *pci_dev, const char *typename); +void pci_bridge_initfn(PCIDevice *pci_dev, const char *typename); void pci_bridge_exitfn(PCIDevice *pci_dev); -- cgit v1.1 From 5669655aafdb88a8797c74a989dd0c0ebb1349fa Mon Sep 17 00:00:00 2001 From: Victor Kaplansky Date: Thu, 18 Feb 2016 16:12:23 +0200 Subject: vhost-user interrupt management fixes Since guest_mask_notifier can not be used in vhost-user mode due to buffering implied by unix control socket, force use_mask_notifier on virtio devices of vhost-user interfaces, and send correct callfd to the guest at vhost start. Using guest_notifier_mask function in vhost-user case may break interrupt mask paradigm, because mask/unmask is not really done when returning from guest_notifier_mask call, instead message is posted in a unix socket, and processed later. Add an option boolean flag 'use_mask_notifier' to disable the use of guest_notifier_mask in virtio pci. Signed-off-by: Didier Pallard Signed-off-by: Victor Kaplansky Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/virtio/virtio.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 108cdb0..c38a2fe 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -90,6 +90,7 @@ struct VirtIODevice VMChangeStateEntry *vmstate; char *bus_name; uint8_t device_endian; + bool use_guest_notifier_mask; QLIST_HEAD(, VirtQueue) *vector_queues; }; -- cgit v1.1