From eec7f96c2cac88f59fd8c79b78a6e027df4abfb2 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Thu, 16 Aug 2012 09:57:49 +0100 Subject: virtio-blk: hide VIRTIO_BLK_F_CONFIG_WCE from old machine types QEMU has a policy of keeping a stable guest device ABI. When new guest device features are introduced they must not change hardware info seen by existing guests. This is important because operating systems or applications may "fingerprint" the hardware and refuse to run when the hardware changes. To always get the latest guest device ABI, run with x86 machine type "pc". This patch hides the new VIRTIO_BLK_F_CONFIG_WCE virtio feature bit from existing machine types. Only pc-1.2 and later will expose this feature by default. For more info on the VIRTIO_BLK_F_CONFIG_WCE feature bit, see: commit 13e3dce068773c971ff2f19d986378c55897c4a3 Author: Paolo Bonzini Date: Thu Aug 9 16:07:19 2012 +0200 virtio-blk: support VIRTIO_BLK_F_CONFIG_WCE Also rename VIRTIO_BLK_F_WCACHE to VIRTIO_BLK_F_WCE for consistency with the spec. Signed-off-by: Paolo Bonzini Signed-off-by: Kevin Wolf Anthony Liguori reported: This broke qemu-test because it changed the pc-1.0 machine type: Setting guest RANDOM seed to 47167 *** Running tests *** Running test /tests/finger-print.sh... OK --- fingerprints/pc-1.0.x86_64 2011-12-18 13:08:40.000000000 -0600 +++ fingerprint.txt 2012-08-12 13:30:48.000000000 -0500 @@ -55,7 +55,7 @@ /sys/bus/pci/devices/0000:00:06.0/subsystem_device=0x0002 /sys/bus/pci/devices/0000:00:06.0/class=0x010000 /sys/bus/pci/devices/0000:00:06.0/revision=0x00 -/sys/bus/pci/devices/0000:00:06.0/virtio/host-features=0x710006d4 +/sys/bus/pci/devices/0000:00:06.0/virtio/host-features=0x71000ed4 /sys/class/dmi/id/bios_vendor=Bochs /sys/class/dmi/id/bios_date=01/01/2007 /sys/class/dmi/id/bios_version=Bochs Guest fingerprint changed for pc-1.0! Reported-by: Anthony Liguori Signed-off-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- hw/virtio-pci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'hw/virtio-pci.c') diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 5e6e09e..2a3d86f 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -886,6 +886,7 @@ static Property virtio_blk_properties[] = { #ifdef __linux__ DEFINE_PROP_BIT("scsi", VirtIOPCIProxy, blk.scsi, 0, true), #endif + DEFINE_PROP_BIT("config-wce", VirtIOPCIProxy, blk.config_wce, 0, true), DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2), DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features), -- cgit v1.1 From 3cac001e5ae3c0ceb33e0a1978a48cb5e2482ab2 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 29 Aug 2012 19:40:56 +0300 Subject: msix: make [un]use vectors on reset/load optional The facility to use/unuse vectors dynamically is helpful for virtio but little else: everyone just seems to use vectors in their init function. Avoid clearing msix vector use info on reset and load. For virtio, clear it explicitly. This should fix regressions reported with ivshmem - though I didn't test this, I verified that virtio keeps working like it did. Tested-by: Cam Macdonell Signed-off-by: Michael S. Tsirkin Signed-off-by: Anthony Liguori --- hw/virtio-pci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'hw/virtio-pci.c') diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 2a3d86f..b3f0710 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -131,6 +131,7 @@ static int virtio_pci_load_config(void * opaque, QEMUFile *f) if (ret) { return ret; } + msix_unuse_all_vectors(&proxy->pci_dev); msix_load(&proxy->pci_dev, f); if (msix_present(&proxy->pci_dev)) { qemu_get_be16s(f, &proxy->vdev->config_vector); @@ -246,6 +247,7 @@ void virtio_pci_reset(DeviceState *d) VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev); virtio_pci_stop_ioeventfd(proxy); virtio_reset(proxy->vdev); + msix_unuse_all_vectors(&proxy->pci_dev); proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG; } -- cgit v1.1 From b131c74a0e485b084ddaffc8214c8a19af492be7 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Mon, 20 Aug 2012 10:55:56 +0200 Subject: kvm: Clean up irqfd API No need to expose the fd-based interface, everyone will already be fine with the more handy EventNotifier variant. Rename the latter to clarify that we are still talking about irqfds here. Signed-off-by: Jan Kiszka Acked-by: Alex Williamson Signed-off-by: Avi Kivity --- hw/virtio-pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'hw/virtio-pci.c') diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index b3f0710..400f3c2 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -517,7 +517,7 @@ static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy, } irqfd->users++; - ret = kvm_irqchip_add_irq_notifier(kvm_state, n, irqfd->virq); + ret = kvm_irqchip_add_irqfd_notifier(kvm_state, n, irqfd->virq); if (ret < 0) { if (--irqfd->users == 0) { kvm_irqchip_release_virq(kvm_state, irqfd->virq); @@ -538,7 +538,7 @@ static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy, VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; int ret; - ret = kvm_irqchip_remove_irq_notifier(kvm_state, n, irqfd->virq); + ret = kvm_irqchip_remove_irqfd_notifier(kvm_state, n, irqfd->virq); assert(ret == 0); if (--irqfd->users == 0) { -- cgit v1.1 From a8170e5e97ad17ca169c64ba87ae2f53850dab4c Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Tue, 23 Oct 2012 12:30:10 +0200 Subject: Rename target_phys_addr_t to hwaddr target_phys_addr_t is unwieldly, violates the C standard (_t suffixes are reserved) and its purpose doesn't match the name (most target_phys_addr_t addresses are not target specific). Replace it with a finger-friendly, standards conformant hwaddr. Outstanding patchsets can be fixed up with the command git rebase -i --exec 'find -name "*.[ch]" | xargs s/target_phys_addr_t/hwaddr/g' origin Signed-off-by: Avi Kivity Signed-off-by: Anthony Liguori --- hw/virtio-pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'hw/virtio-pci.c') diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 400f3c2..c7f20c3 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -255,7 +255,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) { VirtIOPCIProxy *proxy = opaque; VirtIODevice *vdev = proxy->vdev; - target_phys_addr_t pa; + hwaddr pa; switch (addr) { case VIRTIO_PCI_GUEST_FEATURES: @@ -266,7 +266,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) virtio_set_features(vdev, val); break; case VIRTIO_PCI_QUEUE_PFN: - pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT; + pa = (hwaddr)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT; if (pa == 0) { virtio_pci_stop_ioeventfd(proxy); virtio_reset(proxy->vdev); -- cgit v1.1 From df6db5b32ab776a1d23bd32ae75c0e5284a01234 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Mon, 8 Oct 2012 13:02:30 +0200 Subject: virtio-pci: convert PIO to new memory api read/write Signed-off-by: Alexander Graf --- hw/virtio-pci.c | 126 ++++++++++++++++++++++---------------------------------- 1 file changed, 49 insertions(+), 77 deletions(-) (limited to 'hw/virtio-pci.c') diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index c7f20c3..9603150 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -374,79 +374,39 @@ static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr) return ret; } -static uint32_t virtio_pci_config_readb(void *opaque, uint32_t addr) -{ - VirtIOPCIProxy *proxy = opaque; - uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); - if (addr < config) - return virtio_ioport_read(proxy, addr); - addr -= config; - return virtio_config_readb(proxy->vdev, addr); -} - -static uint32_t virtio_pci_config_readw(void *opaque, uint32_t addr) -{ - VirtIOPCIProxy *proxy = opaque; - uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); - uint16_t val; - if (addr < config) - return virtio_ioport_read(proxy, addr); - addr -= config; - val = virtio_config_readw(proxy->vdev, addr); - if (virtio_is_big_endian()) { - /* - * virtio is odd, ioports are LE but config space is target native - * endian. However, in qemu, all PIO is LE, so we need to re-swap - * on BE targets - */ - val = bswap16(val); - } - return val; -} - -static uint32_t virtio_pci_config_readl(void *opaque, uint32_t addr) -{ - VirtIOPCIProxy *proxy = opaque; - uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); - uint32_t val; - if (addr < config) - return virtio_ioport_read(proxy, addr); - addr -= config; - val = virtio_config_readl(proxy->vdev, addr); - if (virtio_is_big_endian()) { - val = bswap32(val); - } - return val; -} - -static void virtio_pci_config_writeb(void *opaque, uint32_t addr, uint32_t val) +static uint64_t virtio_pci_config_read(void *opaque, hwaddr addr, + unsigned size) { VirtIOPCIProxy *proxy = opaque; uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); + uint64_t val = 0; if (addr < config) { - virtio_ioport_write(proxy, addr, val); - return; + return virtio_ioport_read(proxy, addr); } addr -= config; - virtio_config_writeb(proxy->vdev, addr, val); -} -static void virtio_pci_config_writew(void *opaque, uint32_t addr, uint32_t val) -{ - VirtIOPCIProxy *proxy = opaque; - uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); - if (addr < config) { - virtio_ioport_write(proxy, addr, val); - return; - } - addr -= config; - if (virtio_is_big_endian()) { - val = bswap16(val); + switch (size) { + case 1: + val = virtio_config_readb(proxy->vdev, addr); + break; + case 2: + val = virtio_config_readw(proxy->vdev, addr); + if (virtio_is_big_endian()) { + val = bswap16(val); + } + break; + case 4: + val = virtio_config_readl(proxy->vdev, addr); + if (virtio_is_big_endian()) { + val = bswap32(val); + } + break; } - virtio_config_writew(proxy->vdev, addr, val); + return val; } -static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val) +static void virtio_pci_config_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size) { VirtIOPCIProxy *proxy = opaque; uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); @@ -455,24 +415,36 @@ static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val) return; } addr -= config; - if (virtio_is_big_endian()) { - val = bswap32(val); + /* + * Virtio-PCI is odd. Ioports are LE but config space is target native + * endian. + */ + switch (size) { + case 1: + virtio_config_writeb(proxy->vdev, addr, val); + break; + case 2: + if (virtio_is_big_endian()) { + val = bswap16(val); + } + virtio_config_writew(proxy->vdev, addr, val); + break; + case 4: + if (virtio_is_big_endian()) { + val = bswap32(val); + } + virtio_config_writel(proxy->vdev, addr, val); + break; } - virtio_config_writel(proxy->vdev, addr, val); } -static const MemoryRegionPortio virtio_portio[] = { - { 0, 0x10000, 1, .write = virtio_pci_config_writeb, }, - { 0, 0x10000, 2, .write = virtio_pci_config_writew, }, - { 0, 0x10000, 4, .write = virtio_pci_config_writel, }, - { 0, 0x10000, 1, .read = virtio_pci_config_readb, }, - { 0, 0x10000, 2, .read = virtio_pci_config_readw, }, - { 0, 0x10000, 4, .read = virtio_pci_config_readl, }, - PORTIO_END_OF_LIST() -}; - static const MemoryRegionOps virtio_pci_config_ops = { - .old_portio = virtio_portio, + .read = virtio_pci_config_read, + .write = virtio_pci_config_write, + .impl = { + .min_access_size = 1, + .max_access_size = 4, + }, .endianness = DEVICE_LITTLE_ENDIAN, }; -- cgit v1.1 From 16c915ba42b45df7a64a6908287f03bfa3764bed Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Wed, 20 Jun 2012 12:29:32 +0530 Subject: virtio-rng: hardware random number generator device The Linux kernel already has a virtio-rng driver, this is the device implementation. When the guest asks for entropy from the virtio hwrng, it puts a buffer in the vq. We then put entropy into that buffer, and push it back to the guest. Signed-off-by: Amit Shah Signed-off-by: Anthony Liguori --- aliguori: converted to new RngBackend interface aliguori: remove entropy needed event aliguori: fix migration --- hw/virtio-pci.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'hw/virtio-pci.c') diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 9603150..a3d4777 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -852,6 +852,28 @@ static void virtio_balloon_exit_pci(PCIDevice *pci_dev) virtio_exit_pci(pci_dev); } +static int virtio_rng_init_pci(PCIDevice *pci_dev) +{ + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); + VirtIODevice *vdev; + + vdev = virtio_rng_init(&pci_dev->qdev, &proxy->rng); + if (!vdev) { + return -1; + } + virtio_init_pci(proxy, vdev); + return 0; +} + +static void virtio_rng_exit_pci(PCIDevice *pci_dev) +{ + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); + + virtio_pci_stop_ioeventfd(proxy); + virtio_rng_exit(proxy->vdev); + virtio_exit_pci(pci_dev); +} + static Property virtio_blk_properties[] = { DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0), DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, blk.conf), @@ -982,6 +1004,43 @@ static TypeInfo virtio_balloon_info = { .class_init = virtio_balloon_class_init, }; +static void virtio_rng_initfn(Object *obj) +{ + PCIDevice *pci_dev = PCI_DEVICE(obj); + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); + + object_property_add_link(obj, "rng", TYPE_RNG_BACKEND, + (Object **)&proxy->rng.rng, NULL); +} + +static Property virtio_rng_properties[] = { + DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features), + DEFINE_PROP_END_OF_LIST(), +}; + +static void virtio_rng_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + + k->init = virtio_rng_init_pci; + k->exit = virtio_rng_exit_pci; + k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET; + k->device_id = PCI_DEVICE_ID_VIRTIO_RNG; + k->revision = VIRTIO_PCI_ABI_VERSION; + k->class_id = PCI_CLASS_OTHERS; + dc->reset = virtio_pci_reset; + dc->props = virtio_rng_properties; +} + +static TypeInfo virtio_rng_info = { + .name = "virtio-rng-pci", + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(VirtIOPCIProxy), + .instance_init = virtio_rng_initfn, + .class_init = virtio_rng_class_init, +}; + static int virtio_scsi_init_pci(PCIDevice *pci_dev) { VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); @@ -1046,6 +1105,7 @@ static void virtio_pci_register_types(void) type_register_static(&virtio_serial_info); type_register_static(&virtio_balloon_info); type_register_static(&virtio_scsi_info); + type_register_static(&virtio_rng_info); } type_init(virtio_pci_register_types) -- cgit v1.1 From 904d6f588063fb5ad2b61998acdf1e73fb465067 Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Tue, 30 Oct 2012 17:45:05 -0500 Subject: virtio-rng: add rate limiting support This adds parameters to virtio-rng-pci to allow rate limiting the entropy a guest receives. An example command line: $ qemu -device virtio-rng-pci,max-bytes=1024,period=1000 Would limit entropy collection to 1Kb/s. Signed-off-by: Anthony Liguori --- hw/virtio-pci.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'hw/virtio-pci.c') diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index a3d4777..f90296d 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -1015,6 +1015,13 @@ static void virtio_rng_initfn(Object *obj) static Property virtio_rng_properties[] = { DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features), + /* Set a default rate limit of 2^47 bytes per minute or roughly 2TB/s. If + you have an entropy source capable of generating more entropy than this + and you can pass it through via virtio-rng, then hats off to you. Until + then, this is unlimited for all practical purposes. + */ + DEFINE_PROP_UINT64("max-bytes", VirtIOPCIProxy, rng.max_bytes, INT64_MAX), + DEFINE_PROP_UINT32("period", VirtIOPCIProxy, rng.period_ms, 1 << 16), DEFINE_PROP_END_OF_LIST(), }; -- cgit v1.1 From 500054f161c29ff9db125c0b872809191ad6920b Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Fri, 26 Oct 2012 12:05:49 -0500 Subject: virtio-rng-pci: create a default backend if none exists This allows you to specify: $ qemu -device virtio-rng-pci And things will Just Work with a reasonable default. Signed-off-by: Anthony Liguori --- hw/virtio-pci.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'hw/virtio-pci.c') diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index f90296d..71f4fb5 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -857,6 +857,19 @@ static int virtio_rng_init_pci(PCIDevice *pci_dev) VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); VirtIODevice *vdev; + if (proxy->rng.rng == NULL) { + proxy->rng.default_backend = RNG_RANDOM(object_new(TYPE_RNG_RANDOM)); + + object_property_add_child(OBJECT(pci_dev), + "default-backend", + OBJECT(proxy->rng.default_backend), + NULL); + + object_property_set_link(OBJECT(pci_dev), + OBJECT(proxy->rng.default_backend), + "rng", NULL); + } + vdev = virtio_rng_init(&pci_dev->qdev, &proxy->rng); if (!vdev) { return -1; -- cgit v1.1 From d567e62f98d5789ff4d273b924a0474931c71e8b Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 15 Nov 2012 13:12:14 +1100 Subject: virtio-blk: Remove duplicate property definition For the virtio-blk device (via virtio-pci) the property "config-wce" is defined in two places. First, it's defined from the DEFINE_VIRTIO_BLK_FEATURES macro, second it's defined directly in virtio-pci, just two lines above the call to that macro. The direct definition in virtio-pci.c is broken, since it operates on the 'config_wce' field of VirtIOBlkConf, which is never used anywhere else. Therefore, this patch removes both the extra property definition and the redundant field it works on. Cc: Kevin Wolf Cc: Anthony Liguori Cc: Paul 'Rusty' Russell Signed-off-by: David Gibson Signed-off-by: Stefan Hajnoczi --- hw/virtio-pci.c | 1 - 1 file changed, 1 deletion(-) (limited to 'hw/virtio-pci.c') diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 71f4fb5..7684ac9 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -895,7 +895,6 @@ static Property virtio_blk_properties[] = { #ifdef __linux__ DEFINE_PROP_BIT("scsi", VirtIOPCIProxy, blk.scsi, 0, true), #endif - DEFINE_PROP_BIT("config-wce", VirtIOPCIProxy, blk.config_wce, 0, true), DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2), DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features), -- cgit v1.1 From a2cb15b0ddfa05f81a42d7b65dd0c7c50e420c33 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 12 Dec 2012 14:24:50 +0200 Subject: pci: update all users to look in pci/ update all users so we can remove the makefile hack. Signed-off-by: Michael S. Tsirkin --- hw/virtio-pci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'hw/virtio-pci.c') diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 71f4fb5..e9b722d 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -22,10 +22,10 @@ #include "virtio-net.h" #include "virtio-serial.h" #include "virtio-scsi.h" -#include "pci.h" +#include "pci/pci.h" #include "qemu-error.h" -#include "msi.h" -#include "msix.h" +#include "pci/msi.h" +#include "pci/msix.h" #include "net.h" #include "loader.h" #include "kvm.h" -- cgit v1.1 From 7fa22f2bf7a06d5345283a00a7c6d86b8a345228 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 24 Oct 2012 09:36:33 +0200 Subject: net: do not include net.h everywhere Signed-off-by: Paolo Bonzini --- hw/virtio-pci.c | 1 - 1 file changed, 1 deletion(-) (limited to 'hw/virtio-pci.c') diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index d0d6a5e..a2355dc 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -26,7 +26,6 @@ #include "qemu-error.h" #include "pci/msi.h" #include "pci/msix.h" -#include "net.h" #include "loader.h" #include "kvm.h" #include "blockdev.h" -- cgit v1.1 From 1de7afc984b49af164e2619e6850b9732b173b34 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 17 Dec 2012 18:20:00 +0100 Subject: misc: move include files to include/qemu/ Signed-off-by: Paolo Bonzini --- hw/virtio-pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'hw/virtio-pci.c') diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index a2355dc..f58917f 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -23,14 +23,14 @@ #include "virtio-serial.h" #include "virtio-scsi.h" #include "pci/pci.h" -#include "qemu-error.h" +#include "qemu/error-report.h" #include "pci/msi.h" #include "pci/msix.h" #include "loader.h" #include "kvm.h" #include "blockdev.h" #include "virtio-pci.h" -#include "range.h" +#include "qemu/range.h" /* from Linux's linux/virtio_pci.h */ -- cgit v1.1 From 9c17d615a66ebd655871bf891ec0fe901ad8b332 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 17 Dec 2012 18:20:04 +0100 Subject: softmmu: move include files to include/sysemu/ Signed-off-by: Paolo Bonzini --- hw/virtio-pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'hw/virtio-pci.c') diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index f58917f..d2d2454 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -27,8 +27,8 @@ #include "pci/msi.h" #include "pci/msix.h" #include "loader.h" -#include "kvm.h" -#include "blockdev.h" +#include "sysemu/kvm.h" +#include "sysemu/blockdev.h" #include "virtio-pci.h" #include "qemu/range.h" -- cgit v1.1 From d2a0ccc613ccc48c7240f99e1ce05e0acce6e2a1 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 17 Dec 2012 13:01:07 +0200 Subject: virtio: make bindings typesafe Move bindings from opaque to DeviceState. This gives us better type safety with no performance cost. Add macros to make future QOM work easier. Signed-off-by: Michael S. Tsirkin --- hw/virtio-pci.c | 65 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 26 deletions(-) (limited to 'hw/virtio-pci.c') diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index d2d2454..1f1a285 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -96,35 +96,48 @@ bool virtio_is_big_endian(void); /* virtio device */ +/* DeviceState to VirtIOPCIProxy. For use off data-path. TODO: use QOM. */ +static inline VirtIOPCIProxy *to_virtio_pci_proxy(DeviceState *d) +{ + return container_of(d, VirtIOPCIProxy, pci_dev.qdev); +} -static void virtio_pci_notify(void *opaque, uint16_t vector) +/* DeviceState to VirtIOPCIProxy. Note: used on datapath, + * be careful and test performance if you change this. + */ +static inline VirtIOPCIProxy *to_virtio_pci_proxy_fast(DeviceState *d) { - VirtIOPCIProxy *proxy = opaque; + return container_of(d, VirtIOPCIProxy, pci_dev.qdev); +} + +static void virtio_pci_notify(DeviceState *d, uint16_t vector) +{ + VirtIOPCIProxy *proxy = to_virtio_pci_proxy_fast(d); if (msix_enabled(&proxy->pci_dev)) msix_notify(&proxy->pci_dev, vector); else qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1); } -static void virtio_pci_save_config(void * opaque, QEMUFile *f) +static void virtio_pci_save_config(DeviceState *d, QEMUFile *f) { - VirtIOPCIProxy *proxy = opaque; + VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); pci_device_save(&proxy->pci_dev, f); msix_save(&proxy->pci_dev, f); if (msix_present(&proxy->pci_dev)) qemu_put_be16(f, proxy->vdev->config_vector); } -static void virtio_pci_save_queue(void * opaque, int n, QEMUFile *f) +static void virtio_pci_save_queue(DeviceState *d, int n, QEMUFile *f) { - VirtIOPCIProxy *proxy = opaque; + VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); if (msix_present(&proxy->pci_dev)) qemu_put_be16(f, virtio_queue_vector(proxy->vdev, n)); } -static int virtio_pci_load_config(void * opaque, QEMUFile *f) +static int virtio_pci_load_config(DeviceState *d, QEMUFile *f) { - VirtIOPCIProxy *proxy = opaque; + VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); int ret; ret = pci_device_load(&proxy->pci_dev, f); if (ret) { @@ -143,9 +156,9 @@ static int virtio_pci_load_config(void * opaque, QEMUFile *f) return 0; } -static int virtio_pci_load_queue(void * opaque, int n, QEMUFile *f) +static int virtio_pci_load_queue(DeviceState *d, int n, QEMUFile *f) { - VirtIOPCIProxy *proxy = opaque; + VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); uint16_t vector; if (msix_present(&proxy->pci_dev)) { qemu_get_be16s(f, &vector); @@ -243,7 +256,7 @@ static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy) void virtio_pci_reset(DeviceState *d) { - VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev); + VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); virtio_pci_stop_ioeventfd(proxy); virtio_reset(proxy->vdev); msix_unuse_all_vectors(&proxy->pci_dev); @@ -463,9 +476,9 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address, } } -static unsigned virtio_pci_get_features(void *opaque) +static unsigned virtio_pci_get_features(DeviceState *d) { - VirtIOPCIProxy *proxy = opaque; + VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); return proxy->host_features; } @@ -567,9 +580,9 @@ static void kvm_virtio_pci_vector_release(PCIDevice *dev, unsigned vector) } } -static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign) +static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign) { - VirtIOPCIProxy *proxy = opaque; + VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); VirtQueue *vq = virtio_get_queue(proxy->vdev, n); EventNotifier *notifier = virtio_queue_get_guest_notifier(vq); @@ -587,15 +600,15 @@ static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign) return 0; } -static bool virtio_pci_query_guest_notifiers(void *opaque) +static bool virtio_pci_query_guest_notifiers(DeviceState *d) { - VirtIOPCIProxy *proxy = opaque; + VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); return msix_enabled(&proxy->pci_dev); } -static int virtio_pci_set_guest_notifiers(void *opaque, bool assign) +static int virtio_pci_set_guest_notifiers(DeviceState *d, bool assign) { - VirtIOPCIProxy *proxy = opaque; + VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); VirtIODevice *vdev = proxy->vdev; int r, n; @@ -611,7 +624,7 @@ static int virtio_pci_set_guest_notifiers(void *opaque, bool assign) break; } - r = virtio_pci_set_guest_notifier(opaque, n, assign); + r = virtio_pci_set_guest_notifier(d, n, assign); if (r < 0) { goto assign_error; } @@ -636,14 +649,14 @@ assign_error: /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */ assert(assign); while (--n >= 0) { - virtio_pci_set_guest_notifier(opaque, n, !assign); + virtio_pci_set_guest_notifier(d, n, !assign); } return r; } -static int virtio_pci_set_host_notifier(void *opaque, int n, bool assign) +static int virtio_pci_set_host_notifier(DeviceState *d, int n, bool assign) { - VirtIOPCIProxy *proxy = opaque; + VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); /* Stop using ioeventfd for virtqueue kick if the device starts using host * notifiers. This makes it easy to avoid stepping on each others' toes. @@ -659,9 +672,9 @@ static int virtio_pci_set_host_notifier(void *opaque, int n, bool assign) return virtio_pci_set_host_notifier_internal(proxy, n, assign, false); } -static void virtio_pci_vmstate_change(void *opaque, bool running) +static void virtio_pci_vmstate_change(DeviceState *d, bool running) { - VirtIOPCIProxy *proxy = opaque; + VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); if (running) { /* Try to find out if the guest has bus master disabled, but is @@ -726,7 +739,7 @@ void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev) proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD; } - virtio_bind_device(vdev, &virtio_pci_bindings, proxy); + virtio_bind_device(vdev, &virtio_pci_bindings, DEVICE(proxy)); proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY; proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE; proxy->host_features = vdev->get_features(vdev, proxy->host_features); -- cgit v1.1 From bbef882cc1938fa5a6e1b36a50d79ce5c0cefb81 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 12 Dec 2012 16:10:02 +0200 Subject: msi: add API to get notified about pending bit poll Update all users. Signed-off-by: Michael S. Tsirkin --- hw/virtio-pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'hw/virtio-pci.c') diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 1f1a285..37e8b2d 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -637,7 +637,8 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, bool assign) msix_nr_vectors_allocated(&proxy->pci_dev)); r = msix_set_vector_notifiers(&proxy->pci_dev, kvm_virtio_pci_vector_use, - kvm_virtio_pci_vector_release); + kvm_virtio_pci_vector_release, + NULL); if (r < 0) { goto assign_error; } -- cgit v1.1 From 89d62be9f4fb538db7f919a2be7df2544ffc02c5 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 18 Dec 2012 14:02:46 +0200 Subject: virtio-pci: don't poll masked vectors At the moment, when irqfd is in use but a vector is masked, qemu will poll it and handle vector masks in userspace. Since almost no one ever looks at the pending bits, it is better to defer this until pending bits are actually read. Implement this optimization using the new poll notifier. Signed-off-by: Michael S. Tsirkin --- hw/virtio-pci.c | 52 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 12 deletions(-) (limited to 'hw/virtio-pci.c') diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 37e8b2d..af9a56c 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -508,8 +508,6 @@ static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy, } return ret; } - - virtio_queue_set_guest_notifier_fd_handler(vq, true, true); return 0; } @@ -528,8 +526,6 @@ static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy, if (--irqfd->users == 0) { kvm_irqchip_release_virq(kvm_state, irqfd->virq); } - - virtio_queue_set_guest_notifier_fd_handler(vq, true, false); } static int kvm_virtio_pci_vector_use(PCIDevice *dev, unsigned vector, @@ -580,7 +576,36 @@ static void kvm_virtio_pci_vector_release(PCIDevice *dev, unsigned vector) } } -static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign) +static void kvm_virtio_pci_vector_poll(PCIDevice *dev, + unsigned int vector_start, + unsigned int vector_end) +{ + VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev); + VirtIODevice *vdev = proxy->vdev; + int queue_no; + unsigned int vector; + EventNotifier *notifier; + VirtQueue *vq; + + for (queue_no = 0; queue_no < VIRTIO_PCI_QUEUE_MAX; queue_no++) { + if (!virtio_queue_get_num(vdev, queue_no)) { + break; + } + vector = virtio_queue_vector(vdev, queue_no); + if (vector < vector_start || vector >= vector_end || + !msix_is_masked(dev, vector)) { + continue; + } + vq = virtio_get_queue(vdev, queue_no); + notifier = virtio_queue_get_guest_notifier(vq); + if (event_notifier_test_and_clear(notifier)) { + msix_set_pending(dev, vector); + } + } +} + +static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign, + bool with_irqfd) { VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); VirtQueue *vq = virtio_get_queue(proxy->vdev, n); @@ -591,9 +616,9 @@ static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign) if (r < 0) { return r; } - virtio_queue_set_guest_notifier_fd_handler(vq, true, false); + virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd); } else { - virtio_queue_set_guest_notifier_fd_handler(vq, false, false); + virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd); event_notifier_cleanup(notifier); } @@ -611,9 +636,11 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, bool assign) VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); VirtIODevice *vdev = proxy->vdev; int r, n; + bool with_irqfd = msix_enabled(&proxy->pci_dev) && + kvm_msi_via_irqfd_enabled(); /* Must unset vector notifier while guest notifier is still assigned */ - if (kvm_msi_via_irqfd_enabled() && !assign) { + if (proxy->vector_irqfd && !assign) { msix_unset_vector_notifiers(&proxy->pci_dev); g_free(proxy->vector_irqfd); proxy->vector_irqfd = NULL; @@ -624,21 +651,22 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, bool assign) break; } - r = virtio_pci_set_guest_notifier(d, n, assign); + r = virtio_pci_set_guest_notifier(d, n, assign, + kvm_msi_via_irqfd_enabled()); if (r < 0) { goto assign_error; } } /* Must set vector notifier after guest notifier has been assigned */ - if (kvm_msi_via_irqfd_enabled() && assign) { + if (with_irqfd && assign) { proxy->vector_irqfd = g_malloc0(sizeof(*proxy->vector_irqfd) * msix_nr_vectors_allocated(&proxy->pci_dev)); r = msix_set_vector_notifiers(&proxy->pci_dev, kvm_virtio_pci_vector_use, kvm_virtio_pci_vector_release, - NULL); + kvm_virtio_pci_vector_poll); if (r < 0) { goto assign_error; } @@ -650,7 +678,7 @@ assign_error: /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */ assert(assign); while (--n >= 0) { - virtio_pci_set_guest_notifier(d, n, !assign); + virtio_pci_set_guest_notifier(d, n, !assign, with_irqfd); } return r; } -- cgit v1.1 From 8a873ba78069ef81c4ef073a0bd703172c8b3312 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Mon, 10 Dec 2012 13:14:39 +0100 Subject: virtio-blk: restore VirtIOBlkConf->config_wce flag Two slightly different versions of a patch to conditionally set VIRTIO_BLK_F_CONFIG_WCE through the "config-wce" qdev property have been applied (ea776abca and eec7f96c2). David Gibson noticed that the "config-wce" property is broken as a result and fixed it recently. The fix sets the host_features VIRTIO_BLK_F_CONFIG_WCE bit from a qdev property. Unfortunately, the virtio device then has no chance to test for the presence of the feature bit during virtio_blk_init(). Therefore, reinstate the VirtIOBlkConf->config_wce flag. Drop the duplicate qdev property to set the host_features bit. The VirtIOBlkConf->config_wce flag will be used by virtio-blk-data-plane in a later patch. Signed-off-by: Stefan Hajnoczi --- hw/virtio-pci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'hw/virtio-pci.c') diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index d2d2454..3cab783 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -894,6 +894,7 @@ static Property virtio_blk_properties[] = { #ifdef __linux__ DEFINE_PROP_BIT("scsi", VirtIOPCIProxy, blk.scsi, 0, true), #endif + DEFINE_PROP_BIT("config-wce", VirtIOPCIProxy, blk.config_wce, 0, true), DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2), DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features), -- cgit v1.1 From 392808b49b6aee066d0c1d200e72fc3dc11c9d0f Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Wed, 14 Nov 2012 15:45:38 +0100 Subject: virtio-blk: add x-data-plane=on|off performance feature The virtio-blk-data-plane feature is easy to integrate into hw/virtio-blk.c. The data plane can be started and stopped similar to vhost-net. Users can take advantage of the virtio-blk-data-plane feature using the new -device virtio-blk-pci,x-data-plane=on property. The x-data-plane name was chosen because at this stage the feature is experimental and likely to see changes in the future. If the VM configuration does not support virtio-blk-data-plane an error message is printed. Although we could fall back to regular virtio-blk, I prefer the explicit approach since it prompts the user to fix their configuration if they want the performance benefit of virtio-blk-data-plane. Limitations: * Only format=raw is supported * Live migration is not supported * Block jobs, hot unplug, and other operations fail with -EBUSY * I/O throttling limits are ignored * Only Linux hosts are supported due to Linux AIO usage Signed-off-by: Stefan Hajnoczi --- hw/virtio-pci.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'hw/virtio-pci.c') diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 3cab783..82761cf 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -896,6 +896,9 @@ static Property virtio_blk_properties[] = { #endif DEFINE_PROP_BIT("config-wce", VirtIOPCIProxy, blk.config_wce, 0, true), DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true), +#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE + DEFINE_PROP_BIT("x-data-plane", VirtIOPCIProxy, blk.data_plane, 0, false), +#endif DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2), DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features), DEFINE_PROP_END_OF_LIST(), -- cgit v1.1 From 9807caccd605d09a72495637959568d690e10175 Mon Sep 17 00:00:00 2001 From: Blue Swirl Date: Sat, 14 Apr 2012 20:39:14 +0000 Subject: virtio-pci: replace byte swap hack Remove byte swaps by declaring the config space as native endian. Signed-off-by: Blue Swirl --- hw/virtio-pci.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'hw/virtio-pci.c') diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index c7f0c4d..e714bca 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -92,9 +92,6 @@ */ #define wmb() do { } while (0) -/* HACK for virtio to determine if it's running a big endian guest */ -bool virtio_is_big_endian(void); - /* virtio device */ /* DeviceState to VirtIOPCIProxy. For use off data-path. TODO: use QOM. */ static inline VirtIOPCIProxy *to_virtio_pci_proxy(DeviceState *d) @@ -403,15 +400,9 @@ static uint64_t virtio_pci_config_read(void *opaque, hwaddr addr, break; case 2: val = virtio_config_readw(proxy->vdev, addr); - if (virtio_is_big_endian()) { - val = bswap16(val); - } break; case 4: val = virtio_config_readl(proxy->vdev, addr); - if (virtio_is_big_endian()) { - val = bswap32(val); - } break; } return val; @@ -436,15 +427,9 @@ static void virtio_pci_config_write(void *opaque, hwaddr addr, virtio_config_writeb(proxy->vdev, addr, val); break; case 2: - if (virtio_is_big_endian()) { - val = bswap16(val); - } virtio_config_writew(proxy->vdev, addr, val); break; case 4: - if (virtio_is_big_endian()) { - val = bswap32(val); - } virtio_config_writel(proxy->vdev, addr, val); break; } @@ -457,7 +442,7 @@ static const MemoryRegionOps virtio_pci_config_ops = { .min_access_size = 1, .max_access_size = 4, }, - .endianness = DEVICE_LITTLE_ENDIAN, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void virtio_write_config(PCIDevice *pci_dev, uint32_t address, -- cgit v1.1 From 8e4a424b305e29dc0e454f52df3b35577f342975 Mon Sep 17 00:00:00 2001 From: Blue Swirl Date: Sun, 6 Jan 2013 18:30:17 +0000 Subject: Revert "virtio-pci: replace byte swap hack" This reverts commit 9807caccd605d09a72495637959568d690e10175. Signed-off-by: Blue Swirl --- hw/virtio-pci.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'hw/virtio-pci.c') diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index e714bca..c7f0c4d 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -92,6 +92,9 @@ */ #define wmb() do { } while (0) +/* HACK for virtio to determine if it's running a big endian guest */ +bool virtio_is_big_endian(void); + /* virtio device */ /* DeviceState to VirtIOPCIProxy. For use off data-path. TODO: use QOM. */ static inline VirtIOPCIProxy *to_virtio_pci_proxy(DeviceState *d) @@ -400,9 +403,15 @@ static uint64_t virtio_pci_config_read(void *opaque, hwaddr addr, break; case 2: val = virtio_config_readw(proxy->vdev, addr); + if (virtio_is_big_endian()) { + val = bswap16(val); + } break; case 4: val = virtio_config_readl(proxy->vdev, addr); + if (virtio_is_big_endian()) { + val = bswap32(val); + } break; } return val; @@ -427,9 +436,15 @@ static void virtio_pci_config_write(void *opaque, hwaddr addr, virtio_config_writeb(proxy->vdev, addr, val); break; case 2: + if (virtio_is_big_endian()) { + val = bswap16(val); + } virtio_config_writew(proxy->vdev, addr, val); break; case 4: + if (virtio_is_big_endian()) { + val = bswap32(val); + } virtio_config_writel(proxy->vdev, addr, val); break; } @@ -442,7 +457,7 @@ static const MemoryRegionOps virtio_pci_config_ops = { .min_access_size = 1, .max_access_size = 4, }, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, }; static void virtio_write_config(PCIDevice *pci_dev, uint32_t address, -- cgit v1.1