Re: [PATCH] PPC: KVM: fix VCPU run for HV KVM
On 01/13/2014 02:44 AM, Alexander Graf wrote: On 10.01.2014, at 08:21, Alexey Kardashevskiy a...@ozlabs.ru wrote: When write to MMIO happens and there is an ioeventfd for that and is handled successfully, ioeventfd_write() returns 0 (success) and kvmppc_handle_store() returns EMULATE_DONE. Then kvmppc_emulate_mmio() converts EMULATE_DONE to RESUME_GUEST_NV and this broke from the loop. This adds handling of RESUME_GUEST_NV in kvmppc_vcpu_run_hv(). Cc: Michael S. Tsirkin m...@redhat.com Suggested-by: Paul Mackerras pau...@samba.org Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- This definitely needs a better commit message. Please, help. ps. it seems like ioeventfd never worked on ppc64. hm. --- arch/powerpc/kvm/book3s_hv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 072287f..24f363f 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -1569,7 +1569,7 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu) vcpu-arch.fault_dar, vcpu-arch.fault_dsisr); srcu_read_unlock(vcpu-kvm-srcu, srcu_idx); } -} while (r == RESUME_GUEST); +} while ((r == RESUME_GUEST_NV) || (r == RESUME_GUEST)); How about while(!(r RESUME_FLAG_HOST)); Rather while(!(r RESUME_FLAG_HOST) (r 0)); and still not obvious that this is really better. Paul agrees with the original patch (and made a better commit message for our internal tree) but I just cannot make him reply in this thread, keep constantly asking him but to no avail :) That should cover all RESUME_GUEST_XXX cases just fine. Apart from that I agree that we should check for ! FLAG_HOST bit rather than the actual RESUME_GUEST value in all case where we check for it (read: please update all places). There are 3 places remotely similar to this and none of them requires a fix like above. -- Alexey -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] PPC: KVM: fix VCPU run for HV KVM
On 04.02.2014, at 09:03, Alexey Kardashevskiy a...@ozlabs.ru wrote: On 01/13/2014 02:44 AM, Alexander Graf wrote: On 10.01.2014, at 08:21, Alexey Kardashevskiy a...@ozlabs.ru wrote: When write to MMIO happens and there is an ioeventfd for that and is handled successfully, ioeventfd_write() returns 0 (success) and kvmppc_handle_store() returns EMULATE_DONE. Then kvmppc_emulate_mmio() converts EMULATE_DONE to RESUME_GUEST_NV and this broke from the loop. This adds handling of RESUME_GUEST_NV in kvmppc_vcpu_run_hv(). Cc: Michael S. Tsirkin m...@redhat.com Suggested-by: Paul Mackerras pau...@samba.org Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- This definitely needs a better commit message. Please, help. ps. it seems like ioeventfd never worked on ppc64. hm. --- arch/powerpc/kvm/book3s_hv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 072287f..24f363f 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -1569,7 +1569,7 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu) vcpu-arch.fault_dar, vcpu-arch.fault_dsisr); srcu_read_unlock(vcpu-kvm-srcu, srcu_idx); } - } while (r == RESUME_GUEST); + } while ((r == RESUME_GUEST_NV) || (r == RESUME_GUEST)); How about while(!(r RESUME_FLAG_HOST)); Rather while(!(r RESUME_FLAG_HOST) (r 0)); and still not obvious that this is really better. Paul agrees with the original patch (and made a better commit message for our internal tree) but I just cannot make him reply in this thread, keep constantly asking him but to no avail :) That should cover all RESUME_GUEST_XXX cases just fine. Apart from that I agree that we should check for ! FLAG_HOST bit rather than the actual RESUME_GUEST value in all case where we check for it (read: please update all places). There are 3 places remotely similar to this and none of them requires a fix like above. Not today. Then someone goes in and realizes that CEDE advanced version 8 should clear r15 at which point you have to set RESUME_GUEST_NV and are in the same mess again. Let's just always treat RESUME_GUEST_NV and RESUME_GUEST as identical when checking for it. If you like, add a small helper like static inline bool is_resume_guest(int r) { return (r == RESUME_GUEST || r == RESUME_GUEST_NV); } in a header and use that one instead. That way we're guaranteed to be consistent. Alex -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 00/17] kvm-unit-tests/arm: initial drop
On Tue, Feb 04, 2014 at 09:19:30AM +0100, Maria Soler wrote: On 29 January 2014 16:35, Andrew Jones drjo...@redhat.com wrote: On Tue, Jan 28, 2014 at 07:16:11PM +0100, María Soler Heredia wrote: Hello Andrew, I have been experimenting a little with your tests and I have some comments and questions. I have already compiled and run versions v1 and v2, which work with kvm disabled, but I cannot run v3 using the same qemu, version 1.6.90 with these two sets of patches: - http://lists.nongnu.org/archive/html/qemu-devel/2013-09/msg02142.html(Adds 'virt' platform) - http://lists.nongnu.org/archive/html/qemu-devel/2013-10/msg01815.html(Introduces virtio-testdev) that you indicated on [PATCH 0/9] kvm-unit-tests/arm: initial drop. Only qemu-system-arm, recent enough to have mach-virt, and the virtio-testdev patch[1], is required. [1] http://lists.nongnu.org/archive/html/qemu-devel/2013-12/msg00690.html Then I thought maybe the problem was that my qemu was too old, so I upgraded to version 1.7.50, the newest available version at git:// git.qemu-project.org/qemu.git and applied patch[1] but it seems to be incompatible with that version of qemu, since it doesn't compile: --- hw/virtio/virtio-testdev.c: In function 'virtio_testdev_class_init': hw/virtio/virtio-testdev.c:136:8: error: 'VirtioDeviceClass' has no member named 'init' --- The latest git://git.qemu.org/qemu.git with the v3 of virtio-testdev that I just sent[*] works for me. virtio-testdev needed to be converted from init to realize. [*] http://lists.nongnu.org/archive/html/qemu-devel/2014-01/msg04041.html I modified hw/virtio/virtio-testdev.c to stop this error from happening, but it won't run the already compiled (with qemu 1.6.90) v1 and v2 or make a runnable version of either v1, v2 or v3 when recompiling them. The error that I get when I run the v3 of the test (with qemu 1.6.90) is as follows: $ ./run_tests.sh -v ./arm-run arm/selftest.flat -smp 1 -m 256 -append 'mem 256' qemu: fatal: Trying to execute code outside RAM or ROM at 0x R00=fff7 R01= R02= R03=2ff20112 R04= R05= R06= R07= R08= R09= R10= R11= R12= R13=40017ff8 R14=080117b0 R15= PSR=a1d3 N-C- A svc32 s00= s01= d00= ... s62= s63= d31= FPSCR: ./arm-run: line 16: 4839 Aborted (core dumped) $command $@ FAIL selftest_mem ./arm-run arm/selftest.flat -smp 1 -append 'vectors' qemu: fatal: Trying to execute code outside RAM or ROM at 0x R00=fff7 R01= R02= R03=2ff20112 R04= R05= R06= R07= R08= R09= R10= R11= R12= R13=40017ff8 R14=080117b0 R15= PSR=a1d3 N-C- A svc32 s00= s01= d00= ... s62= s63= d31= FPSCR: ./arm-run: line 16: 4845 Aborted (core dumped) $command $@ FAIL selftest_vectors ./arm-run arm/selftest.flat -smp 1 -append 'vectors_usr' qemu: fatal: Trying to execute code outside RAM or ROM at 0x R00=fff7 R01= R02= R03=2ff20112 R04= R05= R06= R07= R08= R09= R10= R11= R12= R13=40017ff8 R14=080117b0 R15= PSR=a1d3 N-C- A svc32 s00= s01= d00= ... s62= s63= d31= FPSCR: ./arm-run: line 16: 4851 Aborted (core dumped) $command $@ FAIL selftest_vectors_usr Am I using the wrong qemu? Is there a new dependency that is not mentioned and that may cause this problem? Any other ideas on why this could happen? Are you sure you have the latest mach-virt patches for qemu? v3 of kvm-unit-tests/arm sets the load address to 0x4000, which matches the latest mach-virt. I can run these tests on my x86_64 machine, without kvm enabled, as well as on an armv7 machine with kvm enabled. Are you still running on the FastModel? I never got around to setting one up to see if that works or not. thanks, drew In deed, everything works fine with that qemu. So my old qemu was too old and the other one was simply an incompatible version. I wasn't using FastModels in this case, although all versions work on FastModels as well. The
Re: Fwd: Fwd: AMD, Solaris, KVM. Panic at boot time.
Il 04/02/2014 08:24, Aleksey Larionov ha scritto: No, I can't. My kvm version is a part of proxmoxve hipervizor and this system have own kernel, if I use different kernel then the system breaks down. Then you have to contact proxmox. Paolo -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [libvirt] Looking for project ideas and mentors for Google Summer of Code 2014
On 03.02.2014 08:45, Stefan Hajnoczi wrote: KVM libvirt: you are welcome to join the QEMU umbrella organization like last year. I've updated wiki with a libvirt idea. But I can sense more to come later as I have some time to think about it :) Michal -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: KVM call agenda for 2014-02-04
Juan Quintela quint...@redhat.com wrote: Hi Please, send any topic that you are interested in covering. * Should we change anything to get more people to sign for the call? There hasn't been a call in quite a long time. Ideas? Any further discussion here? No topics for this week, so call is cancelled. Later, Juan. Thanks, Juan. Call details: 09:00 AM to 10:00 AM EDT Every two weeks If you need phone number details, contact me privately -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
kvm (qemu) speed virtio
Good day. Very little speed drives Virtio. Drivers are the latest guest on the system Windows server 2008. Host system centos 6.5. All that can be tried, but failed to increase the speed. And there I have a database running. Screenshots test speed drives http://itmages.ru/image/view/1471772/feec35c3 http://itmages.ru/image/view/1471772/feec35c3 http://itmages.ru/image/view/1471774/2b0baeae http://itmages.ru/image/view/1471774/2b0baeae http://itmages.ru/image/view/1471785/9fffb8f5 http://itmages.ru/image/view/1471785/9fffb8f5 Thanks in advance. Apply nowhere else. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: kvm (qemu) speed virtio
We may have seen this as well. Initial speed tests were actually pretty good, but after running a few IO test it would actually cause the physical disks that were dedicated to the windows vm host side to be stuck at 100% util with no throughput for 30 seconds at a time according to iostat. We were using noop scheduler on the disks. I think it's something with your host, as we stopped seeing it when we moved from stock CentOS 6.5 kernel to vanilla 3.10 kernel. Sorry I don't have more info on the cause, we saw the issue for a few days but were already upgrading due to the need for vxlan, so we didn't bother investigating. On Tue, Feb 4, 2014 at 7:22 AM, XliN saikov...@gmail.com wrote: Good day. Very little speed drives Virtio. Drivers are the latest guest on the system Windows server 2008. Host system centos 6.5. All that can be tried, but failed to increase the speed. And there I have a database running. Screenshots test speed drives http://itmages.ru/image/view/1471772/feec35c3 http://itmages.ru/image/view/1471772/feec35c3 http://itmages.ru/image/view/1471774/2b0baeae http://itmages.ru/image/view/1471774/2b0baeae http://itmages.ru/image/view/1471785/9fffb8f5 http://itmages.ru/image/view/1471785/9fffb8f5 Thanks in advance. Apply nowhere else. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/17] kvm tools: pci: remove BAR 3 hangover from virtio pci msix code
Despite not being used anymore, there are still traces of BAR 3 in both the code and comments for the virtio pci msix implementation. This patch removes the redundant code and fixes up the comments to match what we're actually doing. Cc: Sasha Levin sasha.le...@oracle.com Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/virtio/pci.c | 10 +++--- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c index 91010cabbcde..77c933fd4ab2 100644 --- a/tools/kvm/virtio/pci.c +++ b/tools/kvm/virtio/pci.c @@ -345,7 +345,6 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev, .capabilities = (void *)vpci-pci_hdr.msix - (void *)vpci-pci_hdr, .bar_size[0]= IOPORT_SIZE, .bar_size[1]= PCI_IO_SIZE * 2, - .bar_size[3]= PCI_IO_SIZE, }; vpci-dev_hdr = (struct device_header) { @@ -368,12 +367,9 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev, */ vpci-pci_hdr.msix.ctrl = cpu_to_le16(VIRTIO_PCI_MAX_VQ + VIRTIO_PCI_MAX_CONFIG - 1); - /* -* Both table and PBA could be mapped on the same BAR, but for now -* we're not in short of BARs -*/ - vpci-pci_hdr.msix.table_offset = cpu_to_le32(1); /* Use BAR 1 */ - vpci-pci_hdr.msix.pba_offset = cpu_to_le32(1 | PCI_IO_SIZE); /* Use BAR 3 */ + /* Both table and PBA are mapped to the same BAR (1) */ + vpci-pci_hdr.msix.table_offset = cpu_to_le32(1); + vpci-pci_hdr.msix.pba_offset = cpu_to_le32(1 | PCI_IO_SIZE); vpci-config_vector = 0; r = irq__register_device(subsys_id, pin, line); -- 1.8.2.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 12/17] kvm tools: irq: make irq__alloc_line generic
All architectures are now doing the same thing for irq__alloc_line: 1. Initialise a global counter to some fixed offset 2. Return the current value of the counter and increment it This is better off in core code, with each architecture specifying the initial offset, which is specific to the interrupt controller being used by the guest. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/Makefile | 1 + tools/kvm/arm/gic.c | 12 tools/kvm/arm/include/arm-common/kvm-arch.h | 4 tools/kvm/arm/ioport.c | 5 ++--- tools/kvm/arm/irq.c | 7 --- tools/kvm/irq.c | 9 + tools/kvm/powerpc/include/kvm/kvm-arch.h| 2 ++ tools/kvm/powerpc/irq.c | 17 - tools/kvm/powerpc/xics.c| 28 ++-- tools/kvm/x86/include/kvm/kvm-arch.h| 2 ++ tools/kvm/x86/irq.c | 7 --- 11 files changed, 22 insertions(+), 72 deletions(-) create mode 100644 tools/kvm/irq.c diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile index 27fb2fbeae8d..29f18220c749 100644 --- a/tools/kvm/Makefile +++ b/tools/kvm/Makefile @@ -57,6 +57,7 @@ OBJS += guest_compat.o OBJS += hw/rtc.o OBJS += hw/serial.o OBJS += ioport.o +OBJS += irq.o OBJS += kvm-cpu.o OBJS += kvm.o OBJS += main.o diff --git a/tools/kvm/arm/gic.c b/tools/kvm/arm/gic.c index 8d2ff873c2de..5d8cbe64e628 100644 --- a/tools/kvm/arm/gic.c +++ b/tools/kvm/arm/gic.c @@ -7,18 +7,6 @@ #include linux/byteorder.h #include linux/kvm.h -static int irq_ids; - -int gic__alloc_irqnum(void) -{ - int irq = GIC_SPI_IRQ_BASE + irq_ids++; - - if (irq GIC_MAX_IRQ) - die(GIC IRQ limit %d reached!, GIC_MAX_IRQ); - - return irq; -} - int gic__init_irqchip(struct kvm *kvm) { int err; diff --git a/tools/kvm/arm/include/arm-common/kvm-arch.h b/tools/kvm/arm/include/arm-common/kvm-arch.h index caef590a44ff..348e88d00b1c 100644 --- a/tools/kvm/arm/include/arm-common/kvm-arch.h +++ b/tools/kvm/arm/include/arm-common/kvm-arch.h @@ -5,6 +5,8 @@ #include linux/const.h #include linux/types.h +#include arm-common/gic.h + #define ARM_IOPORT_AREA_AC(0x, UL) #define ARM_MMIO_AREA _AC(0x0001, UL) #define ARM_AXI_AREA _AC(0x4000, UL) @@ -28,6 +30,8 @@ #define KVM_PCI_MMIO_AREA (KVM_PCI_CFG_AREA + ARM_PCI_CFG_SIZE) #define KVM_VIRTIO_MMIO_AREA ARM_MMIO_AREA +#define KVM_IRQ_OFFSET GIC_SPI_IRQ_BASE + #define VIRTIO_DEFAULT_TRANS VIRTIO_MMIO static inline bool arm_addr_in_ioport_region(u64 phys_addr) diff --git a/tools/kvm/arm/ioport.c b/tools/kvm/arm/ioport.c index 74ee10ec16ca..bdd30b6fe812 100644 --- a/tools/kvm/arm/ioport.c +++ b/tools/kvm/arm/ioport.c @@ -1,6 +1,5 @@ #include kvm/ioport.h - -#include arm-common/gic.h +#include kvm/irq.h void ioport__setup_arch(struct kvm *kvm) { @@ -8,5 +7,5 @@ void ioport__setup_arch(struct kvm *kvm) void ioport__map_irq(u8 *irq) { - *irq = gic__alloc_irqnum(); + *irq = irq__alloc_line(); } diff --git a/tools/kvm/arm/irq.c b/tools/kvm/arm/irq.c index a39a2c289d27..d8f44dfbfec4 100644 --- a/tools/kvm/arm/irq.c +++ b/tools/kvm/arm/irq.c @@ -2,13 +2,6 @@ #include kvm/kvm.h #include kvm/util.h -#include arm-common/gic.h - -int irq__alloc_line(void) -{ - return gic__alloc_irqnum(); -} - int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg) { die(__FUNCTION__); diff --git a/tools/kvm/irq.c b/tools/kvm/irq.c new file mode 100644 index ..33ea8d22e285 --- /dev/null +++ b/tools/kvm/irq.c @@ -0,0 +1,9 @@ +#include kvm/irq.h +#include kvm/kvm-arch.h + +static u8 next_line = KVM_IRQ_OFFSET; + +int irq__alloc_line(void) +{ + return next_line++; +} diff --git a/tools/kvm/powerpc/include/kvm/kvm-arch.h b/tools/kvm/powerpc/include/kvm/kvm-arch.h index c147c78b71e7..d2b52bf0f617 100644 --- a/tools/kvm/powerpc/include/kvm/kvm-arch.h +++ b/tools/kvm/powerpc/include/kvm/kvm-arch.h @@ -42,6 +42,8 @@ #define KVM_PCI_MMIO_AREA 0x200 #define KVM_VIRTIO_MMIO_AREA 0x300 +#define KVM_IRQ_OFFSET 16 + #define VIRTIO_DEFAULT_TRANS VIRTIO_PCI struct spapr_phb; diff --git a/tools/kvm/powerpc/irq.c b/tools/kvm/powerpc/irq.c index c187d8f306f2..03f2fe792365 100644 --- a/tools/kvm/powerpc/irq.c +++ b/tools/kvm/powerpc/irq.c @@ -24,23 +24,6 @@ #include kvm/pci.h -#include xics.h -#include spapr_pci.h - -/* - * FIXME: The code in this file assumes an SPAPR guest, using XICS. Make - * generic cope with multiple PPC platform types. - */ - -int irq__alloc_line(void) -{ - /* -* Have I said how nasty I find this? Line should be dontcare... PHB -* should determine which CPU/XICS IRQ to fire. -*/ - return
[PATCH 13/17] kvm tools: irq: move irq line allocation into device registration
For the MMIO and PCI buses, drivers typically allocate an IRQ line for their device before registering the device with the device tree for the relevant bus. This patch moves the IRQ allocation into the bus code, which is then called directly by the device tree when a new device is registered. IOPORT devices, however, tend to use hardcoded IRQs for legacy reasons, so they are still required to deal with their interrupts (which also require remapping for non-x86 architectures). Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/devices.c | 13 + tools/kvm/hw/pci-shmem.c| 4 tools/kvm/hw/vesa.c | 2 -- tools/kvm/include/kvm/pci.h | 2 ++ tools/kvm/include/kvm/virtio-mmio.h | 1 + tools/kvm/pci.c | 15 +++ tools/kvm/virtio/mmio.c | 9 - tools/kvm/virtio/pci.c | 2 -- 8 files changed, 39 insertions(+), 9 deletions(-) diff --git a/tools/kvm/devices.c b/tools/kvm/devices.c index 5b627e9adee2..b560a59944e0 100644 --- a/tools/kvm/devices.c +++ b/tools/kvm/devices.c @@ -1,5 +1,7 @@ #include kvm/devices.h #include kvm/kvm.h +#include kvm/pci.h +#include kvm/virtio-mmio.h #include linux/err.h #include linux/rbtree.h @@ -27,6 +29,17 @@ int device__register(struct device_header *dev) bus = device_trees[dev-bus_type]; dev-dev_num = bus-dev_num++; + switch (dev-bus_type) { + case DEVICE_BUS_PCI: + pci__assign_irq(dev); + break; + case DEVICE_BUS_MMIO: + virtio_mmio_assign_irq(dev); + break; + default: + break; + } + node = bus-root.rb_node; while (*node) { int num = rb_entry(*node, struct device_header, node)-dev_num; diff --git a/tools/kvm/hw/pci-shmem.c b/tools/kvm/hw/pci-shmem.c index 057118332981..34de74770ea9 100644 --- a/tools/kvm/hw/pci-shmem.c +++ b/tools/kvm/hw/pci-shmem.c @@ -358,10 +358,6 @@ int pci_shmem__init(struct kvm *kvm) if (shmem_region == NULL) return 0; - /* Register good old INTx */ - pci_shmem_pci_device.irq_pin = 1; - pci_shmem_pci_device.irq_line = irq__alloc_line(); - /* Register MMIO space for MSI-X */ r = ioport__register(kvm, IOPORT_EMPTY, shmem_pci__io_ops, IOPORT_SIZE, NULL); if (r 0) diff --git a/tools/kvm/hw/vesa.c b/tools/kvm/hw/vesa.c index c7b8e66cc531..a0b15a77998b 100644 --- a/tools/kvm/hw/vesa.c +++ b/tools/kvm/hw/vesa.c @@ -65,8 +65,6 @@ struct framebuffer *vesa__init(struct kvm *kvm) if (r 0) return ERR_PTR(r); - vesa_pci_device.irq_pin = 1; - vesa_pci_device.irq_line= irq__alloc_line(); vesa_base_addr = (u16)r; vesa_pci_device.bar[0] = cpu_to_le32(vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO); device__register(vesa_device); diff --git a/tools/kvm/include/kvm/pci.h b/tools/kvm/include/kvm/pci.h index e1e621d51470..b0c28a10af6a 100644 --- a/tools/kvm/include/kvm/pci.h +++ b/tools/kvm/include/kvm/pci.h @@ -6,6 +6,7 @@ #include linux/pci_regs.h #include endian.h +#include kvm/devices.h #include kvm/kvm.h #include kvm/msi.h @@ -88,6 +89,7 @@ int pci__init(struct kvm *kvm); int pci__exit(struct kvm *kvm); struct pci_device_header *pci__find_dev(u8 dev_num); u32 pci_get_io_space_block(u32 size); +void pci__assign_irq(struct device_header *dev_hdr); void pci__config_wr(struct kvm *kvm, union pci_config_address addr, void *data, int size); void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data, int size); diff --git a/tools/kvm/include/kvm/virtio-mmio.h b/tools/kvm/include/kvm/virtio-mmio.h index 4d6a671c79c5..835f421bcb8d 100644 --- a/tools/kvm/include/kvm/virtio-mmio.h +++ b/tools/kvm/include/kvm/virtio-mmio.h @@ -56,4 +56,5 @@ int virtio_mmio_signal_config(struct kvm *kvm, struct virtio_device *vdev); int virtio_mmio_exit(struct kvm *kvm, struct virtio_device *vdev); int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev, int device_id, int subsys_id, int class); +void virtio_mmio_assign_irq(struct device_header *dev_hdr); #endif diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c index c4442c85b5cf..c2da15252019 100644 --- a/tools/kvm/pci.c +++ b/tools/kvm/pci.c @@ -1,6 +1,7 @@ #include kvm/devices.h #include kvm/pci.h #include kvm/ioport.h +#include kvm/irq.h #include kvm/util.h #include kvm/kvm.h @@ -28,6 +29,20 @@ u32 pci_get_io_space_block(u32 size) return block; } +void pci__assign_irq(struct device_header *dev_hdr) +{ + struct pci_device_header *pci_hdr = dev_hdr-data; + + /* +* PCI supports only INTA#,B#,C#,D# per device. +* +* A#,B#,C#,D# are allowed for multifunctional devices so stick +* with A# for our single function devices. +*/ +
[PATCH 16/17] kvm tools: powerpc: make use of common of_pci.h header definitions
Now that we have some common OF PCI definitions in of_pci.h, make use of them when generating the devicetree for spapr_pci on ppc. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/powerpc/spapr_pci.c | 114 ++ 1 file changed, 48 insertions(+), 66 deletions(-) diff --git a/tools/kvm/powerpc/spapr_pci.c b/tools/kvm/powerpc/spapr_pci.c index ed4b9ab52a7c..768e3f2df648 100644 --- a/tools/kvm/powerpc/spapr_pci.c +++ b/tools/kvm/powerpc/spapr_pci.c @@ -18,6 +18,7 @@ #include kvm/devices.h #include kvm/fdt.h #include kvm/util.h +#include kvm/of_pci.h #include kvm/pci.h #include linux/pci_regs.h @@ -42,26 +43,8 @@ static const uint32_t bars[] = { #define PCI_NUM_REGIONS7 -/* Macros to operate with address in OF binding to PCI */ -#define b_x(x, p, l) (((x) ((1(l))-1)) (p)) -#define b_n(x) b_x((x), 31, 1) /* 0 if relocatable */ -#define b_p(x) b_x((x), 30, 1) /* 1 if prefetchable */ -#define b_t(x) b_x((x), 29, 1) /* 1 if the address is aliased */ -#define b_ss(x)b_x((x), 24, 2) /* the space code */ -#define b_(x) b_x((x), 16, 8) /* bus number */ -#define b_d(x) b_x((x), 11, 5) /* device number */ -#define b_fff(x) b_x((x), 8, 3) /* function number */ -#define b_(x) b_x((x), 0, 8) /* register number */ - -#define SS_M64 3 -#define SS_M32 2 -#define SS_IO 1 -#define SS_CONFIG 0 - - static struct spapr_phb phb; - static void rtas_ibm_read_pci_config(struct kvm_cpu *vcpu, uint32_t token, uint32_t nargs, target_ulong args, @@ -228,11 +211,11 @@ static uint32_t bar_to_ss(unsigned long bar) { if ((bar PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) - return SS_IO; + return OF_PCI_SS_IO; else if (bar PCI_BASE_ADDRESS_MEM_TYPE_64) - return SS_M64; + return OF_PCI_SS_M64; else - return SS_M32; + return OF_PCI_SS_M32; } static unsigned long bar_to_addr(unsigned long bar) @@ -251,33 +234,32 @@ int spapr_populate_pci_devices(struct kvm *kvm, int bus_off, node_off = 0, devid, fn, i, n, devices; struct device_header *dev_hdr; char nodename[256]; - struct { - uint32_t hi; - uint64_t addr; - uint64_t size; - } __attribute__((packed)) reg[PCI_NUM_REGIONS + 1], - assigned_addresses[PCI_NUM_REGIONS]; + struct of_pci_unit_address reg[PCI_NUM_REGIONS + 1], + assigned_addresses[PCI_NUM_REGIONS]; uint32_t bus_range[] = { cpu_to_be32(0), cpu_to_be32(0xff) }; - struct { - uint32_t hi; - uint64_t child; - uint64_t parent; - uint64_t size; - } __attribute__((packed)) ranges[] = { + struct of_pci_ranges_entry ranges[] = { { - cpu_to_be32(b_ss(1)), cpu_to_be64(0), + { + cpu_to_be32(of_pci_b_ss(1)), + cpu_to_be32(0), + cpu_to_be32(0), + }, cpu_to_be64(phb.io_addr), cpu_to_be64(phb.io_size), }, { - cpu_to_be32(b_ss(2)), cpu_to_be64(0), + { + cpu_to_be32(of_pci_b_ss(2)), + cpu_to_be32(0), + cpu_to_be32(0), + }, cpu_to_be64(phb.mem_addr), cpu_to_be64(phb.mem_size), }, }; uint64_t bus_reg[] = { cpu_to_be64(phb.buid), 0 }; uint32_t interrupt_map_mask[] = { - cpu_to_be32(b_d(-1)|b_fff(-1)), 0x0, 0x0, 0x0}; + cpu_to_be32(of_pci_b_d(-1)|of_pci_b_fff(-1)), 0x0, 0x0, 0x0}; uint32_t interrupt_map[SPAPR_PCI_NUM_LSI][7]; /* Start populating the FDT */ @@ -321,7 +303,7 @@ int spapr_populate_pci_devices(struct kvm *kvm, die(Unexpected behaviour in spapr_populate_pci_devices, wrong devid %u\n, devid); } - irqmap[0] = cpu_to_be32(b_d(devid)|b_fff(fn)); + irqmap[0] = cpu_to_be32(of_pci_b_d(devid)|of_pci_b_fff(fn)); irqmap[1] = 0; irqmap[2] = 0; irqmap[3] = 0; @@ -358,15 +340,15 @@ int spapr_populate_pci_devices(struct kvm *kvm, /* Config space region comes first */ reg[0].hi = cpu_to_be32( - b_n(0) | - b_p(0) | - b_t(0) | - b_ss(SS_CONFIG) | -
[PATCH 06/17] kvm tools: pci: ensure BARs are naturally aligned
BARs must be naturally aligned, so enforce this in the PCI IO space allocator. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/pci.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c index e735352eb042..c4442c85b5cf 100644 --- a/tools/kvm/pci.c +++ b/tools/kvm/pci.c @@ -18,11 +18,13 @@ static union pci_config_address pci_config_address; */ static u32 io_space_blocks = KVM_PCI_MMIO_AREA; +/* + * BARs must be naturally aligned, so enforce this in the allocator. + */ u32 pci_get_io_space_block(u32 size) { - u32 block = io_space_blocks; - io_space_blocks += size; - + u32 block = ALIGN(io_space_blocks, size); + io_space_blocks = block + size; return block; } -- 1.8.2.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 05/17] kvm tools: pci: register 24-bit configuration space below MMIO region
Rather than performing all config accesses via ioports, map in a 24-bit memory-mapped configuration space directly below the PCI MMIO region. This will allow architectures to support PCI without having to support legacy ioports in the guest kernel. Instead, kvm tool can forward the config accesses directly to the relevant ioport config callbacks. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/arm/include/arm-common/kvm-arch.h | 7 +-- tools/kvm/include/kvm/pci.h | 1 + tools/kvm/pci.c | 31 + tools/kvm/powerpc/include/kvm/kvm-arch.h| 5 +++-- tools/kvm/x86/include/kvm/kvm-arch.h| 5 +++-- 5 files changed, 39 insertions(+), 10 deletions(-) diff --git a/tools/kvm/arm/include/arm-common/kvm-arch.h b/tools/kvm/arm/include/arm-common/kvm-arch.h index 72b204fd45a4..caef590a44ff 100644 --- a/tools/kvm/arm/include/arm-common/kvm-arch.h +++ b/tools/kvm/arm/include/arm-common/kvm-arch.h @@ -19,10 +19,13 @@ #define ARM_IOPORT_SIZE(ARM_MMIO_AREA - ARM_IOPORT_AREA) #define ARM_VIRTIO_MMIO_SIZE (ARM_AXI_AREA - (ARM_MMIO_AREA + ARM_GIC_SIZE)) -#define ARM_PCI_MMIO_SIZE (ARM_MEMORY_AREA - ARM_AXI_AREA) +#define ARM_PCI_CFG_SIZE (1ULL 24) +#define ARM_PCI_MMIO_SIZE (ARM_MEMORY_AREA - \ + (ARM_AXI_AREA + ARM_PCI_CFG_SIZE)) #define KVM_IOPORT_AREAARM_IOPORT_AREA -#define KVM_PCI_MMIO_AREA ARM_AXI_AREA +#define KVM_PCI_CFG_AREA ARM_AXI_AREA +#define KVM_PCI_MMIO_AREA (KVM_PCI_CFG_AREA + ARM_PCI_CFG_SIZE) #define KVM_VIRTIO_MMIO_AREA ARM_MMIO_AREA #define VIRTIO_DEFAULT_TRANS VIRTIO_MMIO diff --git a/tools/kvm/include/kvm/pci.h b/tools/kvm/include/kvm/pci.h index 3da381175c8d..e1e621d51470 100644 --- a/tools/kvm/include/kvm/pci.h +++ b/tools/kvm/include/kvm/pci.h @@ -18,6 +18,7 @@ #define PCI_CONFIG_DATA0xcfc #define PCI_CONFIG_BUS_FORWARD 0xcfa #define PCI_IO_SIZE0x100 +#define PCI_CFG_SIZE (1ULL 24) union pci_config_address { struct { diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c index 8d3732d35842..e735352eb042 100644 --- a/tools/kvm/pci.c +++ b/tools/kvm/pci.c @@ -162,6 +162,20 @@ void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data, } } +static void pci_config_mmio_access(u64 addr, u8 *data, u32 len, u8 is_write, void *kvm) +{ + union pci_config_address cfg_addr; + + addr-= KVM_PCI_CFG_AREA; + cfg_addr.w = (u32)addr; + cfg_addr.enable_bit = 1; + + if (is_write) + pci__config_wr(kvm, cfg_addr, data, len); + else + pci__config_rd(kvm, cfg_addr, data, len); +} + struct pci_device_header *pci__find_dev(u8 dev_num) { struct device_header *hdr = device__find_dev(DEVICE_BUS_PCI, dev_num); @@ -181,12 +195,21 @@ int pci__init(struct kvm *kvm) return r; r = ioport__register(kvm, PCI_CONFIG_ADDRESS + 0, pci_config_address_ops, 4, NULL); - if (r 0) { - ioport__unregister(kvm, PCI_CONFIG_DATA); - return r; - } + if (r 0) + goto err_unregister_data; + + r = kvm__register_mmio(kvm, KVM_PCI_CFG_AREA, PCI_CFG_SIZE, false, + pci_config_mmio_access, kvm); + if (r 0) + goto err_unregister_addr; return 0; + +err_unregister_addr: + ioport__unregister(kvm, PCI_CONFIG_ADDRESS); +err_unregister_data: + ioport__unregister(kvm, PCI_CONFIG_DATA); + return r; } dev_base_init(pci__init); diff --git a/tools/kvm/powerpc/include/kvm/kvm-arch.h b/tools/kvm/powerpc/include/kvm/kvm-arch.h index 96dea91cbedd..c147c78b71e7 100644 --- a/tools/kvm/powerpc/include/kvm/kvm-arch.h +++ b/tools/kvm/powerpc/include/kvm/kvm-arch.h @@ -38,8 +38,9 @@ * from. Note that this is a PCI bus address. */ #define KVM_IOPORT_AREA0x0 -#define KVM_PCI_MMIO_AREA 0x100 -#define KVM_VIRTIO_MMIO_AREA 0x200 +#define KVM_PCI_CFG_AREA 0x100 +#define KVM_PCI_MMIO_AREA 0x200 +#define KVM_VIRTIO_MMIO_AREA 0x300 #define VIRTIO_DEFAULT_TRANS VIRTIO_PCI diff --git a/tools/kvm/x86/include/kvm/kvm-arch.h b/tools/kvm/x86/include/kvm/kvm-arch.h index 6d59c8e5de0a..8e8389627354 100644 --- a/tools/kvm/x86/include/kvm/kvm-arch.h +++ b/tools/kvm/x86/include/kvm/kvm-arch.h @@ -21,8 +21,9 @@ * from. Note that this is a PCI bus address (though same on x86). */ #define KVM_IOPORT_AREA0x0 -#define KVM_PCI_MMIO_AREA (KVM_MMIO_START + 0x100) -#define KVM_VIRTIO_MMIO_AREA (KVM_MMIO_START + 0x200) +#define KVM_PCI_CFG_AREA (KVM_MMIO_START + 0x100) +#define KVM_PCI_MMIO_AREA (KVM_MMIO_START + 0x200) +#define KVM_VIRTIO_MMIO_AREA (KVM_MMIO_START
[PATCH 05/17] kvm tools: pci: register 24-bit configuration space below MMIO region
Rather than performing all config accesses via ioports, map in a 24-bit memory-mapped configuration space directly below the PCI MMIO region. This will allow architectures to support PCI without having to support legacy ioports in the guest kernel. Instead, kvm tool can forward the config accesses directly to the relevant ioport config callbacks. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/arm/include/arm-common/kvm-arch.h | 7 +-- tools/kvm/include/kvm/pci.h | 1 + tools/kvm/pci.c | 31 + tools/kvm/powerpc/include/kvm/kvm-arch.h| 5 +++-- tools/kvm/x86/include/kvm/kvm-arch.h| 5 +++-- 5 files changed, 39 insertions(+), 10 deletions(-) diff --git a/tools/kvm/arm/include/arm-common/kvm-arch.h b/tools/kvm/arm/include/arm-common/kvm-arch.h index 72b204fd45a4..caef590a44ff 100644 --- a/tools/kvm/arm/include/arm-common/kvm-arch.h +++ b/tools/kvm/arm/include/arm-common/kvm-arch.h @@ -19,10 +19,13 @@ #define ARM_IOPORT_SIZE(ARM_MMIO_AREA - ARM_IOPORT_AREA) #define ARM_VIRTIO_MMIO_SIZE (ARM_AXI_AREA - (ARM_MMIO_AREA + ARM_GIC_SIZE)) -#define ARM_PCI_MMIO_SIZE (ARM_MEMORY_AREA - ARM_AXI_AREA) +#define ARM_PCI_CFG_SIZE (1ULL 24) +#define ARM_PCI_MMIO_SIZE (ARM_MEMORY_AREA - \ + (ARM_AXI_AREA + ARM_PCI_CFG_SIZE)) #define KVM_IOPORT_AREAARM_IOPORT_AREA -#define KVM_PCI_MMIO_AREA ARM_AXI_AREA +#define KVM_PCI_CFG_AREA ARM_AXI_AREA +#define KVM_PCI_MMIO_AREA (KVM_PCI_CFG_AREA + ARM_PCI_CFG_SIZE) #define KVM_VIRTIO_MMIO_AREA ARM_MMIO_AREA #define VIRTIO_DEFAULT_TRANS VIRTIO_MMIO diff --git a/tools/kvm/include/kvm/pci.h b/tools/kvm/include/kvm/pci.h index 3da381175c8d..e1e621d51470 100644 --- a/tools/kvm/include/kvm/pci.h +++ b/tools/kvm/include/kvm/pci.h @@ -18,6 +18,7 @@ #define PCI_CONFIG_DATA0xcfc #define PCI_CONFIG_BUS_FORWARD 0xcfa #define PCI_IO_SIZE0x100 +#define PCI_CFG_SIZE (1ULL 24) union pci_config_address { struct { diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c index 8d3732d35842..e735352eb042 100644 --- a/tools/kvm/pci.c +++ b/tools/kvm/pci.c @@ -162,6 +162,20 @@ void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data, } } +static void pci_config_mmio_access(u64 addr, u8 *data, u32 len, u8 is_write, void *kvm) +{ + union pci_config_address cfg_addr; + + addr-= KVM_PCI_CFG_AREA; + cfg_addr.w = (u32)addr; + cfg_addr.enable_bit = 1; + + if (is_write) + pci__config_wr(kvm, cfg_addr, data, len); + else + pci__config_rd(kvm, cfg_addr, data, len); +} + struct pci_device_header *pci__find_dev(u8 dev_num) { struct device_header *hdr = device__find_dev(DEVICE_BUS_PCI, dev_num); @@ -181,12 +195,21 @@ int pci__init(struct kvm *kvm) return r; r = ioport__register(kvm, PCI_CONFIG_ADDRESS + 0, pci_config_address_ops, 4, NULL); - if (r 0) { - ioport__unregister(kvm, PCI_CONFIG_DATA); - return r; - } + if (r 0) + goto err_unregister_data; + + r = kvm__register_mmio(kvm, KVM_PCI_CFG_AREA, PCI_CFG_SIZE, false, + pci_config_mmio_access, kvm); + if (r 0) + goto err_unregister_addr; return 0; + +err_unregister_addr: + ioport__unregister(kvm, PCI_CONFIG_ADDRESS); +err_unregister_data: + ioport__unregister(kvm, PCI_CONFIG_DATA); + return r; } dev_base_init(pci__init); diff --git a/tools/kvm/powerpc/include/kvm/kvm-arch.h b/tools/kvm/powerpc/include/kvm/kvm-arch.h index 96dea91cbedd..c147c78b71e7 100644 --- a/tools/kvm/powerpc/include/kvm/kvm-arch.h +++ b/tools/kvm/powerpc/include/kvm/kvm-arch.h @@ -38,8 +38,9 @@ * from. Note that this is a PCI bus address. */ #define KVM_IOPORT_AREA0x0 -#define KVM_PCI_MMIO_AREA 0x100 -#define KVM_VIRTIO_MMIO_AREA 0x200 +#define KVM_PCI_CFG_AREA 0x100 +#define KVM_PCI_MMIO_AREA 0x200 +#define KVM_VIRTIO_MMIO_AREA 0x300 #define VIRTIO_DEFAULT_TRANS VIRTIO_PCI diff --git a/tools/kvm/x86/include/kvm/kvm-arch.h b/tools/kvm/x86/include/kvm/kvm-arch.h index 6d59c8e5de0a..8e8389627354 100644 --- a/tools/kvm/x86/include/kvm/kvm-arch.h +++ b/tools/kvm/x86/include/kvm/kvm-arch.h @@ -21,8 +21,9 @@ * from. Note that this is a PCI bus address (though same on x86). */ #define KVM_IOPORT_AREA0x0 -#define KVM_PCI_MMIO_AREA (KVM_MMIO_START + 0x100) -#define KVM_VIRTIO_MMIO_AREA (KVM_MMIO_START + 0x200) +#define KVM_PCI_CFG_AREA (KVM_MMIO_START + 0x100) +#define KVM_PCI_MMIO_AREA (KVM_MMIO_START + 0x200) +#define KVM_VIRTIO_MMIO_AREA (KVM_MMIO_START
[PATCH 04/17] kvm tools: net: allow a mixture of pci and mmio virtio devices
When attempting to initialise a mixture of pci and mmio virtio devices, we cannot share an ops structure, otherwise the transport-specific fields (init/exit and signal handling) will be globally set to the transport of the last registered device. This patch dynamically allocates a new ops structure for each instance of a virtio net device. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/virtio/net.c | 22 +- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/tools/kvm/virtio/net.c b/tools/kvm/virtio/net.c index ae4712c3c550..dbb443124ee1 100644 --- a/tools/kvm/virtio/net.c +++ b/tools/kvm/virtio/net.c @@ -713,13 +713,20 @@ done: static int virtio_net__init_one(struct virtio_net_params *params) { - int i; + int i, err; struct net_dev *ndev; + struct virtio_ops *ops; ndev = calloc(1, sizeof(struct net_dev)); if (ndev == NULL) return -ENOMEM; + ops = malloc(sizeof(*ops)); + if (ops == NULL) { + err = -ENOMEM; + goto err_free_ndev; + } + list_add_tail(ndev-list, ndevs); ndev-kvm = params-kvm; @@ -749,12 +756,13 @@ static int virtio_net__init_one(struct virtio_net_params *params) uip_static_init(ndev-info); } + *ops = net_dev_virtio_ops; if (params-trans strcmp(params-trans, mmio) == 0) - virtio_init(params-kvm, ndev, ndev-vdev, net_dev_virtio_ops, - VIRTIO_MMIO, PCI_DEVICE_ID_VIRTIO_NET, VIRTIO_ID_NET, PCI_CLASS_NET); + virtio_init(params-kvm, ndev, ndev-vdev, ops, VIRTIO_MMIO, + PCI_DEVICE_ID_VIRTIO_NET, VIRTIO_ID_NET, PCI_CLASS_NET); else - virtio_init(params-kvm, ndev, ndev-vdev, net_dev_virtio_ops, - VIRTIO_PCI, PCI_DEVICE_ID_VIRTIO_NET, VIRTIO_ID_NET, PCI_CLASS_NET); + virtio_init(params-kvm, ndev, ndev-vdev, ops, VIRTIO_PCI, + PCI_DEVICE_ID_VIRTIO_NET, VIRTIO_ID_NET, PCI_CLASS_NET); if (params-vhost) virtio_net__vhost_init(params-kvm, ndev); @@ -763,6 +771,10 @@ static int virtio_net__init_one(struct virtio_net_params *params) compat_id = virtio_compat_add_message(virtio-net, CONFIG_VIRTIO_NET); return 0; + +err_free_ndev: + free(ndev); + return err; } int virtio_net__init(struct kvm *kvm) -- 1.8.2.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 10/17] kvm tools: irq: remove remaining parameters to irq__register_device
With the removal of the x86 irq rbtree, the only parameter used by irq__register_device is actually used to return the new line. This patch removes all of the parameters from irq__register_device and returns the allocated line directly. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/arm/irq.c | 5 ++--- tools/kvm/hw/pci-shmem.c| 7 +-- tools/kvm/hw/vesa.c | 7 +-- tools/kvm/include/kvm/irq.h | 2 +- tools/kvm/powerpc/irq.c | 5 ++--- tools/kvm/virtio/mmio.c | 7 ++- tools/kvm/virtio/pci.c | 7 +-- tools/kvm/x86/irq.c | 5 ++--- 8 files changed, 12 insertions(+), 33 deletions(-) diff --git a/tools/kvm/arm/irq.c b/tools/kvm/arm/irq.c index dd53f1216c51..39d4fbc23314 100644 --- a/tools/kvm/arm/irq.c +++ b/tools/kvm/arm/irq.c @@ -4,10 +4,9 @@ #include arm-common/gic.h -int irq__register_device(u32 dev, u8 *line) +int irq__register_device(void) { - *line = gic__alloc_irqnum(); - return 0; + return gic__alloc_irqnum(); } int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg) diff --git a/tools/kvm/hw/pci-shmem.c b/tools/kvm/hw/pci-shmem.c index d0d88f821aba..c0c63223e6d9 100644 --- a/tools/kvm/hw/pci-shmem.c +++ b/tools/kvm/hw/pci-shmem.c @@ -352,7 +352,6 @@ int shmem_parser(const struct option *opt, const char *arg, int unset) int pci_shmem__init(struct kvm *kvm) { - u8 line; char *mem; int r; @@ -360,12 +359,8 @@ int pci_shmem__init(struct kvm *kvm) return 0; /* Register good old INTx */ - r = irq__register_device(PCI_DEVICE_ID_PCI_SHMEM, line); - if (r 0) - return r; - pci_shmem_pci_device.irq_pin = 1; - pci_shmem_pci_device.irq_line = line; + pci_shmem_pci_device.irq_line = irq__register_device(); /* Register MMIO space for MSI-X */ r = ioport__register(kvm, IOPORT_EMPTY, shmem_pci__io_ops, IOPORT_SIZE, NULL); diff --git a/tools/kvm/hw/vesa.c b/tools/kvm/hw/vesa.c index 07c3978c785e..f033ebed0790 100644 --- a/tools/kvm/hw/vesa.c +++ b/tools/kvm/hw/vesa.c @@ -55,23 +55,18 @@ static struct framebuffer vesafb; struct framebuffer *vesa__init(struct kvm *kvm) { u16 vesa_base_addr; - u8 line; char *mem; int r; if (!kvm-cfg.vnc !kvm-cfg.sdl !kvm-cfg.gtk) return NULL; - r = irq__register_device(PCI_DEVICE_ID_VESA, line); - if (r 0) - return ERR_PTR(r); - r = ioport__register(kvm, IOPORT_EMPTY, vesa_io_ops, IOPORT_SIZE, NULL); if (r 0) return ERR_PTR(r); vesa_pci_device.irq_pin = 1; - vesa_pci_device.irq_line= line; + vesa_pci_device.irq_line= irq__register_device(); vesa_base_addr = (u16)r; vesa_pci_device.bar[0] = cpu_to_le32(vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO); device__register(vesa_device); diff --git a/tools/kvm/include/kvm/irq.h b/tools/kvm/include/kvm/irq.h index 7652b8587464..14cf574849b3 100644 --- a/tools/kvm/include/kvm/irq.h +++ b/tools/kvm/include/kvm/irq.h @@ -10,7 +10,7 @@ struct kvm; -int irq__register_device(u32 dev, u8 *line); +int irq__register_device(void); int irq__init(struct kvm *kvm); int irq__exit(struct kvm *kvm); diff --git a/tools/kvm/powerpc/irq.c b/tools/kvm/powerpc/irq.c index d906bb2840bc..3436ae85027f 100644 --- a/tools/kvm/powerpc/irq.c +++ b/tools/kvm/powerpc/irq.c @@ -32,14 +32,13 @@ * generic cope with multiple PPC platform types. */ -int irq__register_device(u32 dev, u8 *line) +int irq__register_device(void) { /* * Have I said how nasty I find this? Line should be dontcare... PHB * should determine which CPU/XICS IRQ to fire. */ - *line = xics_alloc_irqnum(); - return 0; + return xics_alloc_irqnum(); } int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg) diff --git a/tools/kvm/virtio/mmio.c b/tools/kvm/virtio/mmio.c index 90f90ede3c1f..a8212bacd599 100644 --- a/tools/kvm/virtio/mmio.c +++ b/tools/kvm/virtio/mmio.c @@ -260,7 +260,6 @@ int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev, int device_id, int subsys_id, int class) { struct virtio_mmio *vmmio = vdev-virtio; - u8 line; vmmio-addr = virtio_mmio_get_io_space_block(VIRTIO_MMIO_IO_SIZE); vmmio-kvm = kvm; @@ -277,9 +276,7 @@ int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev, .queue_num_max = 256, }; - if (irq__register_device(subsys_id, line) 0) - return -1; - vmmio-irq = line; + vmmio-irq = irq__register_device(); vmmio-dev_hdr = (struct device_header) { .bus_type = DEVICE_BUS_MMIO, .data = generate_virtio_mmio_fdt_node, @@ -293,7 +290,7 @@ int
[PATCH 09/17] kvm tools: irq: replace the x86 irq rbtree with the PCI device tree
The x86 code keeps its own rbtree of PCI devices in order to allocate interrupts. However, this functionality can be moved into the generic PCI device tree and be reused by other architectures. This patch removes the x86 tree and reworks the ACPI mptable generation to use the PCI device tree for enumerating the bus. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/include/kvm/irq.h | 14 -- tools/kvm/x86/irq.c | 109 +--- tools/kvm/x86/mptable.c | 35 ++ 3 files changed, 15 insertions(+), 143 deletions(-) diff --git a/tools/kvm/include/kvm/irq.h b/tools/kvm/include/kvm/irq.h index 20213c064b0b..7652b8587464 100644 --- a/tools/kvm/include/kvm/irq.h +++ b/tools/kvm/include/kvm/irq.h @@ -10,22 +10,8 @@ struct kvm; -struct irq_line { - u8 line; - struct list_headnode; -}; - -struct pci_dev { - struct rb_node node; - u32 id; - u8 pin; - struct list_headlines; -}; - int irq__register_device(u32 dev, u8 *line); -struct rb_node *irq__get_pci_tree(void); - int irq__init(struct kvm *kvm); int irq__exit(struct kvm *kvm); int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg); diff --git a/tools/kvm/x86/irq.c b/tools/kvm/x86/irq.c index 17db2110e96f..ef5ec34aebff 100644 --- a/tools/kvm/x86/irq.c +++ b/tools/kvm/x86/irq.c @@ -17,7 +17,6 @@ #define IRQCHIP_IOAPIC 2 static u8 next_line = 5; -static struct rb_root pci_tree= RB_ROOT; /* First 24 GSIs are routed between IRQCHIPs and IOAPICs */ static u32 gsi = 24; @@ -40,92 +39,10 @@ static int irq__add_routing(u32 gsi, u32 type, u32 irqchip, u32 pin) return 0; } -static struct pci_dev *search(struct rb_root *root, u32 id) -{ - struct rb_node *node = root-rb_node; - - while (node) { - struct pci_dev *data = rb_entry(node, struct pci_dev, node); - int result; - - result = id - data-id; - - if (result 0) - node = node-rb_left; - else if (result 0) - node = node-rb_right; - else - return data; - } - return NULL; -} - -static int insert(struct rb_root *root, struct pci_dev *data) -{ - struct rb_node **new = (root-rb_node), *parent = NULL; - - /* Figure out where to put new node */ - while (*new) { - struct pci_dev *this= container_of(*new, struct pci_dev, node); - int result = data-id - this-id; - - parent = *new; - if (result 0) - new = ((*new)-rb_left); - else if (result 0) - new = ((*new)-rb_right); - else - return -EEXIST; - } - - /* Add new node and rebalance tree. */ - rb_link_node(data-node, parent, new); - rb_insert_color(data-node, root); - - return 0; -} - int irq__register_device(u32 dev, u8 *line) { - struct pci_dev *node; - int r; - - node = search(pci_tree, dev); - - if (!node) { - /* We haven't found a node - First device of it's kind */ - node = malloc(sizeof(*node)); - if (node == NULL) - return -ENOMEM; - - *node = (struct pci_dev) { - .id = dev, - }; - - INIT_LIST_HEAD(node-lines); - - r = insert(pci_tree, node); - if (r) { - free(node); - return r; - } - } - - if (node) { - /* This device already has a pin assigned, give out a new line and device id */ - struct irq_line *new = malloc(sizeof(*new)); - if (new == NULL) - return -ENOMEM; - - new-line = next_line++; - *line = new-line; - - list_add(new-node, node-lines); - - return 0; - } - - return -EFAULT; + *line = next_line++; + return 0; } int irq__init(struct kvm *kvm) @@ -166,24 +83,7 @@ dev_base_init(irq__init); int irq__exit(struct kvm *kvm) { - struct rb_node *ent; - free(irq_routing); - - while ((ent = rb_first(pci_tree))) { - struct pci_dev *dev; - struct irq_line *line; - - dev = rb_entry(ent, struct pci_dev, node); - while (!list_empty(dev-lines)) { - line = list_first_entry(dev-lines, struct irq_line, node); - list_del(line-node); - free(line); - } - rb_erase(dev-node, pci_tree); - free(dev); - } - return 0; }
[PATCH 08/17] kvm tools: irq: remove pin parameter from irq__register_device
In preparation for moving the irq allocation into generic code, remove the pin parameter from irq__register_device and temporarily place the onus on the emulation driver to allocate the pin (which is always 1 and only used on PCI anyway). Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/arm/irq.c | 2 +- tools/kvm/hw/pci-shmem.c| 6 +++--- tools/kvm/hw/vesa.c | 6 +++--- tools/kvm/include/kvm/irq.h | 2 +- tools/kvm/powerpc/irq.c | 3 +-- tools/kvm/virtio/mmio.c | 4 ++-- tools/kvm/virtio/pci.c | 6 +++--- tools/kvm/x86/irq.c | 10 +- 8 files changed, 15 insertions(+), 24 deletions(-) diff --git a/tools/kvm/arm/irq.c b/tools/kvm/arm/irq.c index e173e04f3668..dd53f1216c51 100644 --- a/tools/kvm/arm/irq.c +++ b/tools/kvm/arm/irq.c @@ -4,7 +4,7 @@ #include arm-common/gic.h -int irq__register_device(u32 dev, u8 *pin, u8 *line) +int irq__register_device(u32 dev, u8 *line) { *line = gic__alloc_irqnum(); return 0; diff --git a/tools/kvm/hw/pci-shmem.c b/tools/kvm/hw/pci-shmem.c index 701231a6ce1e..d0d88f821aba 100644 --- a/tools/kvm/hw/pci-shmem.c +++ b/tools/kvm/hw/pci-shmem.c @@ -352,7 +352,7 @@ int shmem_parser(const struct option *opt, const char *arg, int unset) int pci_shmem__init(struct kvm *kvm) { - u8 line, pin; + u8 line; char *mem; int r; @@ -360,11 +360,11 @@ int pci_shmem__init(struct kvm *kvm) return 0; /* Register good old INTx */ - r = irq__register_device(PCI_DEVICE_ID_PCI_SHMEM, pin, line); + r = irq__register_device(PCI_DEVICE_ID_PCI_SHMEM, line); if (r 0) return r; - pci_shmem_pci_device.irq_pin = pin; + pci_shmem_pci_device.irq_pin = 1; pci_shmem_pci_device.irq_line = line; /* Register MMIO space for MSI-X */ diff --git a/tools/kvm/hw/vesa.c b/tools/kvm/hw/vesa.c index 47e3a694d98b..07c3978c785e 100644 --- a/tools/kvm/hw/vesa.c +++ b/tools/kvm/hw/vesa.c @@ -55,14 +55,14 @@ static struct framebuffer vesafb; struct framebuffer *vesa__init(struct kvm *kvm) { u16 vesa_base_addr; - u8 line, pin; + u8 line; char *mem; int r; if (!kvm-cfg.vnc !kvm-cfg.sdl !kvm-cfg.gtk) return NULL; - r = irq__register_device(PCI_DEVICE_ID_VESA, pin, line); + r = irq__register_device(PCI_DEVICE_ID_VESA, line); if (r 0) return ERR_PTR(r); @@ -70,7 +70,7 @@ struct framebuffer *vesa__init(struct kvm *kvm) if (r 0) return ERR_PTR(r); - vesa_pci_device.irq_pin = pin; + vesa_pci_device.irq_pin = 1; vesa_pci_device.irq_line= line; vesa_base_addr = (u16)r; vesa_pci_device.bar[0] = cpu_to_le32(vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO); diff --git a/tools/kvm/include/kvm/irq.h b/tools/kvm/include/kvm/irq.h index 5c1274b98610..20213c064b0b 100644 --- a/tools/kvm/include/kvm/irq.h +++ b/tools/kvm/include/kvm/irq.h @@ -22,7 +22,7 @@ struct pci_dev { struct list_headlines; }; -int irq__register_device(u32 dev, u8 *pin, u8 *line); +int irq__register_device(u32 dev, u8 *line); struct rb_node *irq__get_pci_tree(void); diff --git a/tools/kvm/powerpc/irq.c b/tools/kvm/powerpc/irq.c index ae9da507fb82..d906bb2840bc 100644 --- a/tools/kvm/powerpc/irq.c +++ b/tools/kvm/powerpc/irq.c @@ -32,9 +32,8 @@ * generic cope with multiple PPC platform types. */ -int irq__register_device(u32 dev, u8 *pin, u8 *line) +int irq__register_device(u32 dev, u8 *line) { - *pin = 1; /* * Have I said how nasty I find this? Line should be dontcare... PHB * should determine which CPU/XICS IRQ to fire. diff --git a/tools/kvm/virtio/mmio.c b/tools/kvm/virtio/mmio.c index afae6a70f006..90f90ede3c1f 100644 --- a/tools/kvm/virtio/mmio.c +++ b/tools/kvm/virtio/mmio.c @@ -260,7 +260,7 @@ int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev, int device_id, int subsys_id, int class) { struct virtio_mmio *vmmio = vdev-virtio; - u8 pin, line; + u8 line; vmmio-addr = virtio_mmio_get_io_space_block(VIRTIO_MMIO_IO_SIZE); vmmio-kvm = kvm; @@ -277,7 +277,7 @@ int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev, .queue_num_max = 256, }; - if (irq__register_device(subsys_id, pin, line) 0) + if (irq__register_device(subsys_id, line) 0) return -1; vmmio-irq = line; vmmio-dev_hdr = (struct device_header) { diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c index e1b5be6b036e..77dde3bee741 100644 --- a/tools/kvm/virtio/pci.c +++ b/tools/kvm/virtio/pci.c @@ -335,7 +335,7 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev, int device_id,
[PATCH 03/17] kvm tools: net: don't propagate error codes from tx/rx operations
Currently, if a -tx or -rx callback into the net_dev_operations encounters an error, it returns -1 to the virtio-net code, which in turn treats this as an unsigned (size_t) size describing the data available. The resulting memcpy operation then quickly explodes with a SEGV. This patch detects the error code from the low-level callbacks and exits the thread dealing with the erroneous queue. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/net/uip/core.c | 2 +- tools/kvm/virtio/net.c | 20 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/tools/kvm/net/uip/core.c b/tools/kvm/net/uip/core.c index b3cd8c25d4da..e860f3afec97 100644 --- a/tools/kvm/net/uip/core.c +++ b/tools/kvm/net/uip/core.c @@ -36,7 +36,7 @@ int uip_tx(struct iovec *iov, u16 out, struct uip_info *info) buf = malloc(eth_len); if (!buf) - return -1; + return -ENOMEM; eth = (struct uip_eth *)buf; for (i = 1; i out; i++) { diff --git a/tools/kvm/virtio/net.c b/tools/kvm/virtio/net.c index 2f61718a5029..ae4712c3c550 100644 --- a/tools/kvm/virtio/net.c +++ b/tools/kvm/virtio/net.c @@ -81,7 +81,7 @@ static void *virtio_net_rx_thread(void *p) struct net_dev *ndev = p; u16 out, in; u16 head; - size_t len, copied; + int len, copied; u32 id; mutex_lock(ndev-mutex); @@ -108,11 +108,17 @@ static void *virtio_net_rx_thread(void *p) struct virtio_net_hdr_mrg_rxbuf *hdr; len = ndev-ops-rx(dummy_iov, 1, ndev); + if (len 0) { + pr_warning(%s: rx on vq %u failed (%d), exiting thread\n, + __func__, id, len); + goto out_err; + } + copied = 0; head = virt_queue__get_iov(vq, iov, out, in, kvm); hdr = (void *)iov[0].iov_base; while (copied len) { - size_t iovsize = min(len - copied, iov_size(iov, in)); + size_t iovsize = min_t(size_t, len - copied, iov_size(iov, in)); memcpy_toiovec(iov, buffer + copied, iovsize); copied += iovsize; @@ -131,6 +137,7 @@ static void *virtio_net_rx_thread(void *p) } } +out_err: pthread_exit(NULL); return NULL; @@ -165,6 +172,12 @@ static void *virtio_net_tx_thread(void *p) while (virt_queue__available(vq)) { head = virt_queue__get_iov(vq, iov, out, in, kvm); len = ndev-ops-tx(iov, out, ndev); + if (len 0) { + pr_warning(%s: tx on vq %u failed (%d)\n, + __func__, id, len); + goto out_err; + } + virt_queue__set_used_elem(vq, head, len); } @@ -172,10 +185,9 @@ static void *virtio_net_tx_thread(void *p) ndev-vdev.ops-signal_vq(kvm, ndev-vdev, id); } +out_err: pthread_exit(NULL); - return NULL; - } static virtio_net_ctrl_ack virtio_net_handle_mq(struct kvm* kvm, struct net_dev *ndev, struct virtio_net_ctrl_hdr *ctrl) -- 1.8.2.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 17/17] kvm tools: ARM: allow default virtio transport to be passed on cmdline
This patch changes VIRTIO_DEFAULT_TRANS to take a struct kvm parameter, allowing architectures to choose the default transport dynamically. For ARM, this is driven by an arch-specific cmdline option. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/arm/include/arm-common/kvm-arch.h| 3 ++- tools/kvm/arm/include/arm-common/kvm-config-arch.h | 12 tools/kvm/powerpc/include/kvm/kvm-arch.h | 2 +- tools/kvm/virtio/9p.c | 2 +- tools/kvm/virtio/balloon.c | 2 +- tools/kvm/virtio/blk.c | 2 +- tools/kvm/virtio/console.c | 2 +- tools/kvm/virtio/rng.c | 2 +- tools/kvm/virtio/scsi.c| 2 +- tools/kvm/x86/include/kvm/kvm-arch.h | 2 +- 10 files changed, 18 insertions(+), 13 deletions(-) diff --git a/tools/kvm/arm/include/arm-common/kvm-arch.h b/tools/kvm/arm/include/arm-common/kvm-arch.h index 8adfcd495c03..b6c4bf8de364 100644 --- a/tools/kvm/arm/include/arm-common/kvm-arch.h +++ b/tools/kvm/arm/include/arm-common/kvm-arch.h @@ -32,7 +32,8 @@ #define KVM_IRQ_OFFSET GIC_SPI_IRQ_BASE -#define VIRTIO_DEFAULT_TRANS VIRTIO_MMIO +#define VIRTIO_DEFAULT_TRANS(kvm) \ + ((kvm)-cfg.arch.virtio_trans_pci ? VIRTIO_PCI : VIRTIO_MMIO) static inline bool arm_addr_in_ioport_region(u64 phys_addr) { diff --git a/tools/kvm/arm/include/arm-common/kvm-config-arch.h b/tools/kvm/arm/include/arm-common/kvm-config-arch.h index f3baf392704d..a8ebd94a78f1 100644 --- a/tools/kvm/arm/include/arm-common/kvm-config-arch.h +++ b/tools/kvm/arm/include/arm-common/kvm-config-arch.h @@ -4,9 +4,10 @@ #include kvm/parse-options.h struct kvm_config_arch { - const char *dump_dtb_filename; - unsigned int force_cntfrq; - bool aarch32_guest; + const char *dump_dtb_filename; + unsigned intforce_cntfrq; + boolvirtio_trans_pci; + boolaarch32_guest; }; #define OPT_ARCH_RUN(pfx, cfg) \ @@ -17,6 +18,9 @@ struct kvm_config_arch { OPT_UINTEGER('\0', override-bad-firmware-cntfrq, (cfg)-force_cntfrq,\ Specify Generic Timer frequency in guest DT to \ work around buggy secure firmware *Firmware should be \ -updated to program CNTFRQ correctly*), +updated to program CNTFRQ correctly*), \ + OPT_BOOLEAN('\0', force-pci, (cfg)-virtio_trans_pci, \ + Force virtio devices to use PCI as their default \ + transport), #endif /* ARM_COMMON__KVM_CONFIG_ARCH_H */ diff --git a/tools/kvm/powerpc/include/kvm/kvm-arch.h b/tools/kvm/powerpc/include/kvm/kvm-arch.h index d2b52bf0f617..f8627a2a2dd3 100644 --- a/tools/kvm/powerpc/include/kvm/kvm-arch.h +++ b/tools/kvm/powerpc/include/kvm/kvm-arch.h @@ -44,7 +44,7 @@ #define KVM_IRQ_OFFSET 16 -#define VIRTIO_DEFAULT_TRANS VIRTIO_PCI +#define VIRTIO_DEFAULT_TRANS(kvm) VIRTIO_PCI struct spapr_phb; diff --git a/tools/kvm/virtio/9p.c b/tools/kvm/virtio/9p.c index 127b13afdf0b..25cdd8c2e70b 100644 --- a/tools/kvm/virtio/9p.c +++ b/tools/kvm/virtio/9p.c @@ -1392,7 +1392,7 @@ int virtio_9p__init(struct kvm *kvm) list_for_each_entry(p9dev, devs, list) { virtio_init(kvm, p9dev, p9dev-vdev, p9_dev_virtio_ops, - VIRTIO_DEFAULT_TRANS, PCI_DEVICE_ID_VIRTIO_9P, + VIRTIO_DEFAULT_TRANS(kvm), PCI_DEVICE_ID_VIRTIO_9P, VIRTIO_ID_9P, PCI_CLASS_9P); } diff --git a/tools/kvm/virtio/balloon.c b/tools/kvm/virtio/balloon.c index 486353584904..f7dfb0be2875 100644 --- a/tools/kvm/virtio/balloon.c +++ b/tools/kvm/virtio/balloon.c @@ -262,7 +262,7 @@ int virtio_bln__init(struct kvm *kvm) memset(bdev.config, 0, sizeof(struct virtio_balloon_config)); virtio_init(kvm, bdev, bdev.vdev, bln_dev_virtio_ops, - VIRTIO_DEFAULT_TRANS, PCI_DEVICE_ID_VIRTIO_BLN, + VIRTIO_DEFAULT_TRANS(kvm), PCI_DEVICE_ID_VIRTIO_BLN, VIRTIO_ID_BALLOON, PCI_CLASS_BLN); if (compat_id == -1) diff --git a/tools/kvm/virtio/blk.c b/tools/kvm/virtio/blk.c index ab1871673d46..4bed3a975d1d 100644 --- a/tools/kvm/virtio/blk.c +++ b/tools/kvm/virtio/blk.c @@ -260,7 +260,7 @@ static int virtio_blk__init_one(struct kvm *kvm, struct disk_image *disk) }; virtio_init(kvm, bdev, bdev-vdev, blk_dev_virtio_ops, - VIRTIO_DEFAULT_TRANS, PCI_DEVICE_ID_VIRTIO_BLK, + VIRTIO_DEFAULT_TRANS(kvm), PCI_DEVICE_ID_VIRTIO_BLK, VIRTIO_ID_BLOCK, PCI_CLASS_BLK); list_add_tail(bdev-list, bdevs); diff --git a/tools/kvm/virtio/console.c
[PATCH 06/17] kvm tools: pci: ensure BARs are naturally aligned
BARs must be naturally aligned, so enforce this in the PCI IO space allocator. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/pci.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c index e735352eb042..c4442c85b5cf 100644 --- a/tools/kvm/pci.c +++ b/tools/kvm/pci.c @@ -18,11 +18,13 @@ static union pci_config_address pci_config_address; */ static u32 io_space_blocks = KVM_PCI_MMIO_AREA; +/* + * BARs must be naturally aligned, so enforce this in the allocator. + */ u32 pci_get_io_space_block(u32 size) { - u32 block = io_space_blocks; - io_space_blocks += size; - + u32 block = ALIGN(io_space_blocks, size); + io_space_blocks = block + size; return block; } -- 1.8.2.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 13/17] kvm tools: irq: move irq line allocation into device registration
For the MMIO and PCI buses, drivers typically allocate an IRQ line for their device before registering the device with the device tree for the relevant bus. This patch moves the IRQ allocation into the bus code, which is then called directly by the device tree when a new device is registered. IOPORT devices, however, tend to use hardcoded IRQs for legacy reasons, so they are still required to deal with their interrupts (which also require remapping for non-x86 architectures). Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/devices.c | 13 + tools/kvm/hw/pci-shmem.c| 4 tools/kvm/hw/vesa.c | 2 -- tools/kvm/include/kvm/pci.h | 2 ++ tools/kvm/include/kvm/virtio-mmio.h | 1 + tools/kvm/pci.c | 15 +++ tools/kvm/virtio/mmio.c | 9 - tools/kvm/virtio/pci.c | 2 -- 8 files changed, 39 insertions(+), 9 deletions(-) diff --git a/tools/kvm/devices.c b/tools/kvm/devices.c index 5b627e9adee2..b560a59944e0 100644 --- a/tools/kvm/devices.c +++ b/tools/kvm/devices.c @@ -1,5 +1,7 @@ #include kvm/devices.h #include kvm/kvm.h +#include kvm/pci.h +#include kvm/virtio-mmio.h #include linux/err.h #include linux/rbtree.h @@ -27,6 +29,17 @@ int device__register(struct device_header *dev) bus = device_trees[dev-bus_type]; dev-dev_num = bus-dev_num++; + switch (dev-bus_type) { + case DEVICE_BUS_PCI: + pci__assign_irq(dev); + break; + case DEVICE_BUS_MMIO: + virtio_mmio_assign_irq(dev); + break; + default: + break; + } + node = bus-root.rb_node; while (*node) { int num = rb_entry(*node, struct device_header, node)-dev_num; diff --git a/tools/kvm/hw/pci-shmem.c b/tools/kvm/hw/pci-shmem.c index 057118332981..34de74770ea9 100644 --- a/tools/kvm/hw/pci-shmem.c +++ b/tools/kvm/hw/pci-shmem.c @@ -358,10 +358,6 @@ int pci_shmem__init(struct kvm *kvm) if (shmem_region == NULL) return 0; - /* Register good old INTx */ - pci_shmem_pci_device.irq_pin = 1; - pci_shmem_pci_device.irq_line = irq__alloc_line(); - /* Register MMIO space for MSI-X */ r = ioport__register(kvm, IOPORT_EMPTY, shmem_pci__io_ops, IOPORT_SIZE, NULL); if (r 0) diff --git a/tools/kvm/hw/vesa.c b/tools/kvm/hw/vesa.c index c7b8e66cc531..a0b15a77998b 100644 --- a/tools/kvm/hw/vesa.c +++ b/tools/kvm/hw/vesa.c @@ -65,8 +65,6 @@ struct framebuffer *vesa__init(struct kvm *kvm) if (r 0) return ERR_PTR(r); - vesa_pci_device.irq_pin = 1; - vesa_pci_device.irq_line= irq__alloc_line(); vesa_base_addr = (u16)r; vesa_pci_device.bar[0] = cpu_to_le32(vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO); device__register(vesa_device); diff --git a/tools/kvm/include/kvm/pci.h b/tools/kvm/include/kvm/pci.h index e1e621d51470..b0c28a10af6a 100644 --- a/tools/kvm/include/kvm/pci.h +++ b/tools/kvm/include/kvm/pci.h @@ -6,6 +6,7 @@ #include linux/pci_regs.h #include endian.h +#include kvm/devices.h #include kvm/kvm.h #include kvm/msi.h @@ -88,6 +89,7 @@ int pci__init(struct kvm *kvm); int pci__exit(struct kvm *kvm); struct pci_device_header *pci__find_dev(u8 dev_num); u32 pci_get_io_space_block(u32 size); +void pci__assign_irq(struct device_header *dev_hdr); void pci__config_wr(struct kvm *kvm, union pci_config_address addr, void *data, int size); void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data, int size); diff --git a/tools/kvm/include/kvm/virtio-mmio.h b/tools/kvm/include/kvm/virtio-mmio.h index 4d6a671c79c5..835f421bcb8d 100644 --- a/tools/kvm/include/kvm/virtio-mmio.h +++ b/tools/kvm/include/kvm/virtio-mmio.h @@ -56,4 +56,5 @@ int virtio_mmio_signal_config(struct kvm *kvm, struct virtio_device *vdev); int virtio_mmio_exit(struct kvm *kvm, struct virtio_device *vdev); int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev, int device_id, int subsys_id, int class); +void virtio_mmio_assign_irq(struct device_header *dev_hdr); #endif diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c index c4442c85b5cf..c2da15252019 100644 --- a/tools/kvm/pci.c +++ b/tools/kvm/pci.c @@ -1,6 +1,7 @@ #include kvm/devices.h #include kvm/pci.h #include kvm/ioport.h +#include kvm/irq.h #include kvm/util.h #include kvm/kvm.h @@ -28,6 +29,20 @@ u32 pci_get_io_space_block(u32 size) return block; } +void pci__assign_irq(struct device_header *dev_hdr) +{ + struct pci_device_header *pci_hdr = dev_hdr-data; + + /* +* PCI supports only INTA#,B#,C#,D# per device. +* +* A#,B#,C#,D# are allowed for multifunctional devices so stick +* with A# for our single function devices. +*/ +
[PATCH 16/17] kvm tools: powerpc: make use of common of_pci.h header definitions
Now that we have some common OF PCI definitions in of_pci.h, make use of them when generating the devicetree for spapr_pci on ppc. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/powerpc/spapr_pci.c | 114 ++ 1 file changed, 48 insertions(+), 66 deletions(-) diff --git a/tools/kvm/powerpc/spapr_pci.c b/tools/kvm/powerpc/spapr_pci.c index ed4b9ab52a7c..768e3f2df648 100644 --- a/tools/kvm/powerpc/spapr_pci.c +++ b/tools/kvm/powerpc/spapr_pci.c @@ -18,6 +18,7 @@ #include kvm/devices.h #include kvm/fdt.h #include kvm/util.h +#include kvm/of_pci.h #include kvm/pci.h #include linux/pci_regs.h @@ -42,26 +43,8 @@ static const uint32_t bars[] = { #define PCI_NUM_REGIONS7 -/* Macros to operate with address in OF binding to PCI */ -#define b_x(x, p, l) (((x) ((1(l))-1)) (p)) -#define b_n(x) b_x((x), 31, 1) /* 0 if relocatable */ -#define b_p(x) b_x((x), 30, 1) /* 1 if prefetchable */ -#define b_t(x) b_x((x), 29, 1) /* 1 if the address is aliased */ -#define b_ss(x)b_x((x), 24, 2) /* the space code */ -#define b_(x) b_x((x), 16, 8) /* bus number */ -#define b_d(x) b_x((x), 11, 5) /* device number */ -#define b_fff(x) b_x((x), 8, 3) /* function number */ -#define b_(x) b_x((x), 0, 8) /* register number */ - -#define SS_M64 3 -#define SS_M32 2 -#define SS_IO 1 -#define SS_CONFIG 0 - - static struct spapr_phb phb; - static void rtas_ibm_read_pci_config(struct kvm_cpu *vcpu, uint32_t token, uint32_t nargs, target_ulong args, @@ -228,11 +211,11 @@ static uint32_t bar_to_ss(unsigned long bar) { if ((bar PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) - return SS_IO; + return OF_PCI_SS_IO; else if (bar PCI_BASE_ADDRESS_MEM_TYPE_64) - return SS_M64; + return OF_PCI_SS_M64; else - return SS_M32; + return OF_PCI_SS_M32; } static unsigned long bar_to_addr(unsigned long bar) @@ -251,33 +234,32 @@ int spapr_populate_pci_devices(struct kvm *kvm, int bus_off, node_off = 0, devid, fn, i, n, devices; struct device_header *dev_hdr; char nodename[256]; - struct { - uint32_t hi; - uint64_t addr; - uint64_t size; - } __attribute__((packed)) reg[PCI_NUM_REGIONS + 1], - assigned_addresses[PCI_NUM_REGIONS]; + struct of_pci_unit_address reg[PCI_NUM_REGIONS + 1], + assigned_addresses[PCI_NUM_REGIONS]; uint32_t bus_range[] = { cpu_to_be32(0), cpu_to_be32(0xff) }; - struct { - uint32_t hi; - uint64_t child; - uint64_t parent; - uint64_t size; - } __attribute__((packed)) ranges[] = { + struct of_pci_ranges_entry ranges[] = { { - cpu_to_be32(b_ss(1)), cpu_to_be64(0), + { + cpu_to_be32(of_pci_b_ss(1)), + cpu_to_be32(0), + cpu_to_be32(0), + }, cpu_to_be64(phb.io_addr), cpu_to_be64(phb.io_size), }, { - cpu_to_be32(b_ss(2)), cpu_to_be64(0), + { + cpu_to_be32(of_pci_b_ss(2)), + cpu_to_be32(0), + cpu_to_be32(0), + }, cpu_to_be64(phb.mem_addr), cpu_to_be64(phb.mem_size), }, }; uint64_t bus_reg[] = { cpu_to_be64(phb.buid), 0 }; uint32_t interrupt_map_mask[] = { - cpu_to_be32(b_d(-1)|b_fff(-1)), 0x0, 0x0, 0x0}; + cpu_to_be32(of_pci_b_d(-1)|of_pci_b_fff(-1)), 0x0, 0x0, 0x0}; uint32_t interrupt_map[SPAPR_PCI_NUM_LSI][7]; /* Start populating the FDT */ @@ -321,7 +303,7 @@ int spapr_populate_pci_devices(struct kvm *kvm, die(Unexpected behaviour in spapr_populate_pci_devices, wrong devid %u\n, devid); } - irqmap[0] = cpu_to_be32(b_d(devid)|b_fff(fn)); + irqmap[0] = cpu_to_be32(of_pci_b_d(devid)|of_pci_b_fff(fn)); irqmap[1] = 0; irqmap[2] = 0; irqmap[3] = 0; @@ -358,15 +340,15 @@ int spapr_populate_pci_devices(struct kvm *kvm, /* Config space region comes first */ reg[0].hi = cpu_to_be32( - b_n(0) | - b_p(0) | - b_t(0) | - b_ss(SS_CONFIG) | -
[PATCH 10/17] kvm tools: irq: remove remaining parameters to irq__register_device
With the removal of the x86 irq rbtree, the only parameter used by irq__register_device is actually used to return the new line. This patch removes all of the parameters from irq__register_device and returns the allocated line directly. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/arm/irq.c | 5 ++--- tools/kvm/hw/pci-shmem.c| 7 +-- tools/kvm/hw/vesa.c | 7 +-- tools/kvm/include/kvm/irq.h | 2 +- tools/kvm/powerpc/irq.c | 5 ++--- tools/kvm/virtio/mmio.c | 7 ++- tools/kvm/virtio/pci.c | 7 +-- tools/kvm/x86/irq.c | 5 ++--- 8 files changed, 12 insertions(+), 33 deletions(-) diff --git a/tools/kvm/arm/irq.c b/tools/kvm/arm/irq.c index dd53f1216c51..39d4fbc23314 100644 --- a/tools/kvm/arm/irq.c +++ b/tools/kvm/arm/irq.c @@ -4,10 +4,9 @@ #include arm-common/gic.h -int irq__register_device(u32 dev, u8 *line) +int irq__register_device(void) { - *line = gic__alloc_irqnum(); - return 0; + return gic__alloc_irqnum(); } int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg) diff --git a/tools/kvm/hw/pci-shmem.c b/tools/kvm/hw/pci-shmem.c index d0d88f821aba..c0c63223e6d9 100644 --- a/tools/kvm/hw/pci-shmem.c +++ b/tools/kvm/hw/pci-shmem.c @@ -352,7 +352,6 @@ int shmem_parser(const struct option *opt, const char *arg, int unset) int pci_shmem__init(struct kvm *kvm) { - u8 line; char *mem; int r; @@ -360,12 +359,8 @@ int pci_shmem__init(struct kvm *kvm) return 0; /* Register good old INTx */ - r = irq__register_device(PCI_DEVICE_ID_PCI_SHMEM, line); - if (r 0) - return r; - pci_shmem_pci_device.irq_pin = 1; - pci_shmem_pci_device.irq_line = line; + pci_shmem_pci_device.irq_line = irq__register_device(); /* Register MMIO space for MSI-X */ r = ioport__register(kvm, IOPORT_EMPTY, shmem_pci__io_ops, IOPORT_SIZE, NULL); diff --git a/tools/kvm/hw/vesa.c b/tools/kvm/hw/vesa.c index 07c3978c785e..f033ebed0790 100644 --- a/tools/kvm/hw/vesa.c +++ b/tools/kvm/hw/vesa.c @@ -55,23 +55,18 @@ static struct framebuffer vesafb; struct framebuffer *vesa__init(struct kvm *kvm) { u16 vesa_base_addr; - u8 line; char *mem; int r; if (!kvm-cfg.vnc !kvm-cfg.sdl !kvm-cfg.gtk) return NULL; - r = irq__register_device(PCI_DEVICE_ID_VESA, line); - if (r 0) - return ERR_PTR(r); - r = ioport__register(kvm, IOPORT_EMPTY, vesa_io_ops, IOPORT_SIZE, NULL); if (r 0) return ERR_PTR(r); vesa_pci_device.irq_pin = 1; - vesa_pci_device.irq_line= line; + vesa_pci_device.irq_line= irq__register_device(); vesa_base_addr = (u16)r; vesa_pci_device.bar[0] = cpu_to_le32(vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO); device__register(vesa_device); diff --git a/tools/kvm/include/kvm/irq.h b/tools/kvm/include/kvm/irq.h index 7652b8587464..14cf574849b3 100644 --- a/tools/kvm/include/kvm/irq.h +++ b/tools/kvm/include/kvm/irq.h @@ -10,7 +10,7 @@ struct kvm; -int irq__register_device(u32 dev, u8 *line); +int irq__register_device(void); int irq__init(struct kvm *kvm); int irq__exit(struct kvm *kvm); diff --git a/tools/kvm/powerpc/irq.c b/tools/kvm/powerpc/irq.c index d906bb2840bc..3436ae85027f 100644 --- a/tools/kvm/powerpc/irq.c +++ b/tools/kvm/powerpc/irq.c @@ -32,14 +32,13 @@ * generic cope with multiple PPC platform types. */ -int irq__register_device(u32 dev, u8 *line) +int irq__register_device(void) { /* * Have I said how nasty I find this? Line should be dontcare... PHB * should determine which CPU/XICS IRQ to fire. */ - *line = xics_alloc_irqnum(); - return 0; + return xics_alloc_irqnum(); } int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg) diff --git a/tools/kvm/virtio/mmio.c b/tools/kvm/virtio/mmio.c index 90f90ede3c1f..a8212bacd599 100644 --- a/tools/kvm/virtio/mmio.c +++ b/tools/kvm/virtio/mmio.c @@ -260,7 +260,6 @@ int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev, int device_id, int subsys_id, int class) { struct virtio_mmio *vmmio = vdev-virtio; - u8 line; vmmio-addr = virtio_mmio_get_io_space_block(VIRTIO_MMIO_IO_SIZE); vmmio-kvm = kvm; @@ -277,9 +276,7 @@ int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev, .queue_num_max = 256, }; - if (irq__register_device(subsys_id, line) 0) - return -1; - vmmio-irq = line; + vmmio-irq = irq__register_device(); vmmio-dev_hdr = (struct device_header) { .bus_type = DEVICE_BUS_MMIO, .data = generate_virtio_mmio_fdt_node, @@ -293,7 +290,7 @@ int
[PATCH 15/17] kvm tools: ARM: generate an fdt node for our PCI emulation
This patch factors out some of the openfirmware PCI binding definitions from the powerpc spapr PCI code and uses them to generate appropriate FDT properties for the PCI node on ARM. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/Makefile | 2 +- tools/kvm/arm/fdt.c| 4 ++ tools/kvm/arm/include/arm-common/pci.h | 6 ++ tools/kvm/arm/pci.c| 118 + tools/kvm/include/kvm/of_pci.h | 44 5 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 tools/kvm/arm/include/arm-common/pci.h create mode 100644 tools/kvm/arm/pci.c create mode 100644 tools/kvm/include/kvm/of_pci.h diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile index 29f18220c749..b87265189d1f 100644 --- a/tools/kvm/Makefile +++ b/tools/kvm/Makefile @@ -158,7 +158,7 @@ endif # ARM OBJS_ARM_COMMON:= arm/fdt.o arm/gic.o arm/ioport.o arm/irq.o \ - arm/kvm.o arm/kvm-cpu.o arm/timer.o + arm/kvm.o arm/kvm-cpu.o arm/pci.o arm/timer.o HDRS_ARM_COMMON:= arm/include ifeq ($(ARCH), arm) DEFINES += -DCONFIG_ARM diff --git a/tools/kvm/arm/fdt.c b/tools/kvm/arm/fdt.c index 9a34d9804930..d90fc9e1734f 100644 --- a/tools/kvm/arm/fdt.c +++ b/tools/kvm/arm/fdt.c @@ -5,6 +5,7 @@ #include kvm/virtio-mmio.h #include arm-common/gic.h +#include arm-common/pci.h #include stdbool.h @@ -155,6 +156,9 @@ static int setup_fdt(struct kvm *kvm) dev_hdr = device__next_dev(dev_hdr); } + /* PCI host controller */ + pci__generate_fdt_nodes(fdt, gic_phandle); + /* PSCI firmware */ _FDT(fdt_begin_node(fdt, psci)); _FDT(fdt_property_string(fdt, compatible, arm,psci)); diff --git a/tools/kvm/arm/include/arm-common/pci.h b/tools/kvm/arm/include/arm-common/pci.h new file mode 100644 index ..ee87725ee82f --- /dev/null +++ b/tools/kvm/arm/include/arm-common/pci.h @@ -0,0 +1,6 @@ +#ifndef ARM_COMMON__PCI_H +#define ARM_COMMON__PCI_H + +void pci__generate_fdt_nodes(void *fdt, u32 gic_phandle); + +#endif /* ARM_COMMON__PCI_H */ diff --git a/tools/kvm/arm/pci.c b/tools/kvm/arm/pci.c new file mode 100644 index ..ce1932ecc3ee --- /dev/null +++ b/tools/kvm/arm/pci.c @@ -0,0 +1,118 @@ +#include kvm/devices.h +#include kvm/fdt.h +#include kvm/of_pci.h +#include kvm/pci.h +#include kvm/util.h + +#include arm-common/pci.h + +/* + * An entry in the interrupt-map table looks like: + * pci unit address pci interrupt pin gic phandle gic interrupt + */ + +struct of_gic_irq { + u32 type, num, flags; +} __attribute__((packed)); + +struct of_interrupt_map_entry { + struct of_pci_irq_mask pci_irq_mask; + u32 gic_phandle; + struct of_gic_irq gic_irq; +} __attribute__((packed)); + +void pci__generate_fdt_nodes(void *fdt, u32 gic_phandle) +{ + struct device_header *dev_hdr; + struct of_interrupt_map_entry irq_map[OF_PCI_IRQ_MAP_MAX]; + unsigned nentries = 0; + /* Describe the memory ranges (config and memory) */ + struct of_pci_ranges_entry ranges[] = { + { + .pci_addr = { + .hi = cpu_to_fdt32(of_pci_b_ss(OF_PCI_SS_CONFIG)), + .mid= 0, + .lo = 0, + }, + .cpu_addr = cpu_to_fdt64(KVM_PCI_CFG_AREA), + .length = cpu_to_fdt64(ARM_PCI_CFG_SIZE), + }, + { + .pci_addr = { + .hi = cpu_to_fdt32(of_pci_b_ss(OF_PCI_SS_IO)), + .mid= 0, + .lo = 0, + }, + .cpu_addr = cpu_to_fdt64(KVM_IOPORT_AREA), + .length = cpu_to_fdt64(ARM_IOPORT_SIZE), + }, + { + .pci_addr = { + .hi = cpu_to_fdt32(of_pci_b_ss(OF_PCI_SS_M32)), + .mid= 0, + .lo = 0, + }, + .cpu_addr = cpu_to_fdt64(KVM_PCI_MMIO_AREA), + .length = cpu_to_fdt64(ARM_PCI_MMIO_SIZE), + }, + }; + + /* Boilerplate PCI properties */ + _FDT(fdt_begin_node(fdt, pci)); + _FDT(fdt_property_cell(fdt, #address-cells, 0x3)); + _FDT(fdt_property_cell(fdt, #size-cells, 0x2)); + _FDT(fdt_property_cell(fdt, #interrupt-cells, 0x1)); + _FDT(fdt_property_string(fdt, compatible, linux,pci-virt)); + + _FDT(fdt_property(fdt, ranges, ranges, sizeof(ranges))); + + /* Generate the interrupt map ... */ + dev_hdr =
[PATCH 12/17] kvm tools: irq: make irq__alloc_line generic
All architectures are now doing the same thing for irq__alloc_line: 1. Initialise a global counter to some fixed offset 2. Return the current value of the counter and increment it This is better off in core code, with each architecture specifying the initial offset, which is specific to the interrupt controller being used by the guest. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/Makefile | 1 + tools/kvm/arm/gic.c | 12 tools/kvm/arm/include/arm-common/kvm-arch.h | 4 tools/kvm/arm/ioport.c | 5 ++--- tools/kvm/arm/irq.c | 7 --- tools/kvm/irq.c | 9 + tools/kvm/powerpc/include/kvm/kvm-arch.h| 2 ++ tools/kvm/powerpc/irq.c | 17 - tools/kvm/powerpc/xics.c| 28 ++-- tools/kvm/x86/include/kvm/kvm-arch.h| 2 ++ tools/kvm/x86/irq.c | 7 --- 11 files changed, 22 insertions(+), 72 deletions(-) create mode 100644 tools/kvm/irq.c diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile index 27fb2fbeae8d..29f18220c749 100644 --- a/tools/kvm/Makefile +++ b/tools/kvm/Makefile @@ -57,6 +57,7 @@ OBJS += guest_compat.o OBJS += hw/rtc.o OBJS += hw/serial.o OBJS += ioport.o +OBJS += irq.o OBJS += kvm-cpu.o OBJS += kvm.o OBJS += main.o diff --git a/tools/kvm/arm/gic.c b/tools/kvm/arm/gic.c index 8d2ff873c2de..5d8cbe64e628 100644 --- a/tools/kvm/arm/gic.c +++ b/tools/kvm/arm/gic.c @@ -7,18 +7,6 @@ #include linux/byteorder.h #include linux/kvm.h -static int irq_ids; - -int gic__alloc_irqnum(void) -{ - int irq = GIC_SPI_IRQ_BASE + irq_ids++; - - if (irq GIC_MAX_IRQ) - die(GIC IRQ limit %d reached!, GIC_MAX_IRQ); - - return irq; -} - int gic__init_irqchip(struct kvm *kvm) { int err; diff --git a/tools/kvm/arm/include/arm-common/kvm-arch.h b/tools/kvm/arm/include/arm-common/kvm-arch.h index caef590a44ff..348e88d00b1c 100644 --- a/tools/kvm/arm/include/arm-common/kvm-arch.h +++ b/tools/kvm/arm/include/arm-common/kvm-arch.h @@ -5,6 +5,8 @@ #include linux/const.h #include linux/types.h +#include arm-common/gic.h + #define ARM_IOPORT_AREA_AC(0x, UL) #define ARM_MMIO_AREA _AC(0x0001, UL) #define ARM_AXI_AREA _AC(0x4000, UL) @@ -28,6 +30,8 @@ #define KVM_PCI_MMIO_AREA (KVM_PCI_CFG_AREA + ARM_PCI_CFG_SIZE) #define KVM_VIRTIO_MMIO_AREA ARM_MMIO_AREA +#define KVM_IRQ_OFFSET GIC_SPI_IRQ_BASE + #define VIRTIO_DEFAULT_TRANS VIRTIO_MMIO static inline bool arm_addr_in_ioport_region(u64 phys_addr) diff --git a/tools/kvm/arm/ioport.c b/tools/kvm/arm/ioport.c index 74ee10ec16ca..bdd30b6fe812 100644 --- a/tools/kvm/arm/ioport.c +++ b/tools/kvm/arm/ioport.c @@ -1,6 +1,5 @@ #include kvm/ioport.h - -#include arm-common/gic.h +#include kvm/irq.h void ioport__setup_arch(struct kvm *kvm) { @@ -8,5 +7,5 @@ void ioport__setup_arch(struct kvm *kvm) void ioport__map_irq(u8 *irq) { - *irq = gic__alloc_irqnum(); + *irq = irq__alloc_line(); } diff --git a/tools/kvm/arm/irq.c b/tools/kvm/arm/irq.c index a39a2c289d27..d8f44dfbfec4 100644 --- a/tools/kvm/arm/irq.c +++ b/tools/kvm/arm/irq.c @@ -2,13 +2,6 @@ #include kvm/kvm.h #include kvm/util.h -#include arm-common/gic.h - -int irq__alloc_line(void) -{ - return gic__alloc_irqnum(); -} - int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg) { die(__FUNCTION__); diff --git a/tools/kvm/irq.c b/tools/kvm/irq.c new file mode 100644 index ..33ea8d22e285 --- /dev/null +++ b/tools/kvm/irq.c @@ -0,0 +1,9 @@ +#include kvm/irq.h +#include kvm/kvm-arch.h + +static u8 next_line = KVM_IRQ_OFFSET; + +int irq__alloc_line(void) +{ + return next_line++; +} diff --git a/tools/kvm/powerpc/include/kvm/kvm-arch.h b/tools/kvm/powerpc/include/kvm/kvm-arch.h index c147c78b71e7..d2b52bf0f617 100644 --- a/tools/kvm/powerpc/include/kvm/kvm-arch.h +++ b/tools/kvm/powerpc/include/kvm/kvm-arch.h @@ -42,6 +42,8 @@ #define KVM_PCI_MMIO_AREA 0x200 #define KVM_VIRTIO_MMIO_AREA 0x300 +#define KVM_IRQ_OFFSET 16 + #define VIRTIO_DEFAULT_TRANS VIRTIO_PCI struct spapr_phb; diff --git a/tools/kvm/powerpc/irq.c b/tools/kvm/powerpc/irq.c index c187d8f306f2..03f2fe792365 100644 --- a/tools/kvm/powerpc/irq.c +++ b/tools/kvm/powerpc/irq.c @@ -24,23 +24,6 @@ #include kvm/pci.h -#include xics.h -#include spapr_pci.h - -/* - * FIXME: The code in this file assumes an SPAPR guest, using XICS. Make - * generic cope with multiple PPC platform types. - */ - -int irq__alloc_line(void) -{ - /* -* Have I said how nasty I find this? Line should be dontcare... PHB -* should determine which CPU/XICS IRQ to fire. -*/ - return
[PATCH 09/17] kvm tools: irq: replace the x86 irq rbtree with the PCI device tree
The x86 code keeps its own rbtree of PCI devices in order to allocate interrupts. However, this functionality can be moved into the generic PCI device tree and be reused by other architectures. This patch removes the x86 tree and reworks the ACPI mptable generation to use the PCI device tree for enumerating the bus. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/include/kvm/irq.h | 14 -- tools/kvm/x86/irq.c | 109 +--- tools/kvm/x86/mptable.c | 35 ++ 3 files changed, 15 insertions(+), 143 deletions(-) diff --git a/tools/kvm/include/kvm/irq.h b/tools/kvm/include/kvm/irq.h index 20213c064b0b..7652b8587464 100644 --- a/tools/kvm/include/kvm/irq.h +++ b/tools/kvm/include/kvm/irq.h @@ -10,22 +10,8 @@ struct kvm; -struct irq_line { - u8 line; - struct list_headnode; -}; - -struct pci_dev { - struct rb_node node; - u32 id; - u8 pin; - struct list_headlines; -}; - int irq__register_device(u32 dev, u8 *line); -struct rb_node *irq__get_pci_tree(void); - int irq__init(struct kvm *kvm); int irq__exit(struct kvm *kvm); int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg); diff --git a/tools/kvm/x86/irq.c b/tools/kvm/x86/irq.c index 17db2110e96f..ef5ec34aebff 100644 --- a/tools/kvm/x86/irq.c +++ b/tools/kvm/x86/irq.c @@ -17,7 +17,6 @@ #define IRQCHIP_IOAPIC 2 static u8 next_line = 5; -static struct rb_root pci_tree= RB_ROOT; /* First 24 GSIs are routed between IRQCHIPs and IOAPICs */ static u32 gsi = 24; @@ -40,92 +39,10 @@ static int irq__add_routing(u32 gsi, u32 type, u32 irqchip, u32 pin) return 0; } -static struct pci_dev *search(struct rb_root *root, u32 id) -{ - struct rb_node *node = root-rb_node; - - while (node) { - struct pci_dev *data = rb_entry(node, struct pci_dev, node); - int result; - - result = id - data-id; - - if (result 0) - node = node-rb_left; - else if (result 0) - node = node-rb_right; - else - return data; - } - return NULL; -} - -static int insert(struct rb_root *root, struct pci_dev *data) -{ - struct rb_node **new = (root-rb_node), *parent = NULL; - - /* Figure out where to put new node */ - while (*new) { - struct pci_dev *this= container_of(*new, struct pci_dev, node); - int result = data-id - this-id; - - parent = *new; - if (result 0) - new = ((*new)-rb_left); - else if (result 0) - new = ((*new)-rb_right); - else - return -EEXIST; - } - - /* Add new node and rebalance tree. */ - rb_link_node(data-node, parent, new); - rb_insert_color(data-node, root); - - return 0; -} - int irq__register_device(u32 dev, u8 *line) { - struct pci_dev *node; - int r; - - node = search(pci_tree, dev); - - if (!node) { - /* We haven't found a node - First device of it's kind */ - node = malloc(sizeof(*node)); - if (node == NULL) - return -ENOMEM; - - *node = (struct pci_dev) { - .id = dev, - }; - - INIT_LIST_HEAD(node-lines); - - r = insert(pci_tree, node); - if (r) { - free(node); - return r; - } - } - - if (node) { - /* This device already has a pin assigned, give out a new line and device id */ - struct irq_line *new = malloc(sizeof(*new)); - if (new == NULL) - return -ENOMEM; - - new-line = next_line++; - *line = new-line; - - list_add(new-node, node-lines); - - return 0; - } - - return -EFAULT; + *line = next_line++; + return 0; } int irq__init(struct kvm *kvm) @@ -166,24 +83,7 @@ dev_base_init(irq__init); int irq__exit(struct kvm *kvm) { - struct rb_node *ent; - free(irq_routing); - - while ((ent = rb_first(pci_tree))) { - struct pci_dev *dev; - struct irq_line *line; - - dev = rb_entry(ent, struct pci_dev, node); - while (!list_empty(dev-lines)) { - line = list_first_entry(dev-lines, struct irq_line, node); - list_del(line-node); - free(line); - } - rb_erase(dev-node, pci_tree); - free(dev); - } - return 0; }
[PATCH 07/17] kvm tools: pci: add MMIO interface to virtio-pci devices
This patch adds an MMIO interface for each virtio-pci device, so that they can be accessed without having to use an ioport. For each device, a new memory BAR is added which corresponds to an area of MMIO space with a shim trap handler. This handler simply translates the access into an ioport access via kvm__emulate_io. Since guests can generate accesses via either the ioport or MMIO regions, an ioeventfd is registered for both. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/include/kvm/virtio-pci.h | 4 +- tools/kvm/virtio/pci.c | 111 + 2 files changed, 78 insertions(+), 37 deletions(-) diff --git a/tools/kvm/include/kvm/virtio-pci.h b/tools/kvm/include/kvm/virtio-pci.h index 9b063924e5da..c795ce71fa88 100644 --- a/tools/kvm/include/kvm/virtio-pci.h +++ b/tools/kvm/include/kvm/virtio-pci.h @@ -22,8 +22,10 @@ struct virtio_pci { struct pci_device_header pci_hdr; struct device_headerdev_hdr; void*dev; + struct kvm *kvm; - u16 base_addr; + u16 port_addr; + u32 mmio_addr; u8 status; u8 isr; u32 features; diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c index 77c933fd4ab2..e1b5be6b036e 100644 --- a/tools/kvm/virtio/pci.c +++ b/tools/kvm/virtio/pci.c @@ -24,7 +24,8 @@ static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct virtio_device *vde { struct ioevent ioevent; struct virtio_pci *vpci = vdev-virtio; - int r; + int i, r, flags = IOEVENTFD_FLAG_PIO; + int fds[2]; vpci-ioeventfds[vq] = (struct virtio_pci_ioevent_param) { .vdev = vdev, @@ -32,32 +33,44 @@ static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct virtio_device *vde }; ioevent = (struct ioevent) { - .io_addr= vpci-base_addr + VIRTIO_PCI_QUEUE_NOTIFY, - .io_len = sizeof(u16), .fn = virtio_pci__ioevent_callback, .fn_ptr = vpci-ioeventfds[vq], .datamatch = vq, .fn_kvm = kvm, - .fd = eventfd(0, 0), }; - if (vdev-use_vhost) - /* -* Vhost will poll the eventfd in host kernel side, -* no need to poll in userspace. -*/ - r = ioeventfd__add_event(ioevent, IOEVENTFD_FLAG_PIO); - else - /* Need to poll in userspace. */ - r = ioeventfd__add_event(ioevent, IOEVENTFD_FLAG_PIO | - IOEVENTFD_FLAG_USER_POLL); + /* +* Vhost will poll the eventfd in host kernel side, otherwise we +* need to poll in userspace. +*/ + if (!vdev-use_vhost) + flags |= IOEVENTFD_FLAG_USER_POLL; + + /* ioport */ + ioevent.io_addr = vpci-port_addr + VIRTIO_PCI_QUEUE_NOTIFY; + ioevent.io_len = sizeof(u16); + ioevent.fd = fds[0] = eventfd(0, 0); + r = ioeventfd__add_event(ioevent, flags); if (r) return r; - if (vdev-ops-notify_vq_eventfd) - vdev-ops-notify_vq_eventfd(kvm, vpci-dev, vq, ioevent.fd); + /* mmio */ + ioevent.io_addr = vpci-mmio_addr + VIRTIO_PCI_QUEUE_NOTIFY; + ioevent.io_len = sizeof(u32); + ioevent.fd = fds[1] = eventfd(0, 0); + r = ioeventfd__add_event(ioevent, flags); + if (r) + goto free_ioport_evt; + if (vdev-ops-notify_vq_eventfd) + for (i = 0; i 2; ++i) + vdev-ops-notify_vq_eventfd(kvm, vpci-dev, vq, +fds[i]); return 0; + +free_ioport_evt: + ioeventfd__del_event(vpci-port_addr + VIRTIO_PCI_QUEUE_NOTIFY, vq); + return r; } static inline bool virtio_pci__msix_enabled(struct virtio_pci *vpci) @@ -105,7 +118,7 @@ static bool virtio_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port, vdev = ioport-priv; vpci = vdev-virtio; - offset = port - vpci-base_addr; + offset = port - vpci-port_addr; switch (offset) { case VIRTIO_PCI_HOST_FEATURES: @@ -188,7 +201,7 @@ static bool virtio_pci__io_out(struct ioport *ioport, struct kvm *kvm, u16 port, vdev = ioport-priv; vpci = vdev-virtio; - offset = port - vpci-base_addr; + offset = port - vpci-port_addr; switch (offset) { case VIRTIO_PCI_GUEST_FEATURES: @@ -227,7 +240,8 @@ static struct ioport_operations virtio_pci__io_ops = { .io_out = virtio_pci__io_out, }; -static void virtio_pci__mmio_callback(u64 addr, u8 *data, u32 len, u8 is_write, void *ptr) +static void
[PATCH 08/17] kvm tools: irq: remove pin parameter from irq__register_device
In preparation for moving the irq allocation into generic code, remove the pin parameter from irq__register_device and temporarily place the onus on the emulation driver to allocate the pin (which is always 1 and only used on PCI anyway). Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/arm/irq.c | 2 +- tools/kvm/hw/pci-shmem.c| 6 +++--- tools/kvm/hw/vesa.c | 6 +++--- tools/kvm/include/kvm/irq.h | 2 +- tools/kvm/powerpc/irq.c | 3 +-- tools/kvm/virtio/mmio.c | 4 ++-- tools/kvm/virtio/pci.c | 6 +++--- tools/kvm/x86/irq.c | 10 +- 8 files changed, 15 insertions(+), 24 deletions(-) diff --git a/tools/kvm/arm/irq.c b/tools/kvm/arm/irq.c index e173e04f3668..dd53f1216c51 100644 --- a/tools/kvm/arm/irq.c +++ b/tools/kvm/arm/irq.c @@ -4,7 +4,7 @@ #include arm-common/gic.h -int irq__register_device(u32 dev, u8 *pin, u8 *line) +int irq__register_device(u32 dev, u8 *line) { *line = gic__alloc_irqnum(); return 0; diff --git a/tools/kvm/hw/pci-shmem.c b/tools/kvm/hw/pci-shmem.c index 701231a6ce1e..d0d88f821aba 100644 --- a/tools/kvm/hw/pci-shmem.c +++ b/tools/kvm/hw/pci-shmem.c @@ -352,7 +352,7 @@ int shmem_parser(const struct option *opt, const char *arg, int unset) int pci_shmem__init(struct kvm *kvm) { - u8 line, pin; + u8 line; char *mem; int r; @@ -360,11 +360,11 @@ int pci_shmem__init(struct kvm *kvm) return 0; /* Register good old INTx */ - r = irq__register_device(PCI_DEVICE_ID_PCI_SHMEM, pin, line); + r = irq__register_device(PCI_DEVICE_ID_PCI_SHMEM, line); if (r 0) return r; - pci_shmem_pci_device.irq_pin = pin; + pci_shmem_pci_device.irq_pin = 1; pci_shmem_pci_device.irq_line = line; /* Register MMIO space for MSI-X */ diff --git a/tools/kvm/hw/vesa.c b/tools/kvm/hw/vesa.c index 47e3a694d98b..07c3978c785e 100644 --- a/tools/kvm/hw/vesa.c +++ b/tools/kvm/hw/vesa.c @@ -55,14 +55,14 @@ static struct framebuffer vesafb; struct framebuffer *vesa__init(struct kvm *kvm) { u16 vesa_base_addr; - u8 line, pin; + u8 line; char *mem; int r; if (!kvm-cfg.vnc !kvm-cfg.sdl !kvm-cfg.gtk) return NULL; - r = irq__register_device(PCI_DEVICE_ID_VESA, pin, line); + r = irq__register_device(PCI_DEVICE_ID_VESA, line); if (r 0) return ERR_PTR(r); @@ -70,7 +70,7 @@ struct framebuffer *vesa__init(struct kvm *kvm) if (r 0) return ERR_PTR(r); - vesa_pci_device.irq_pin = pin; + vesa_pci_device.irq_pin = 1; vesa_pci_device.irq_line= line; vesa_base_addr = (u16)r; vesa_pci_device.bar[0] = cpu_to_le32(vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO); diff --git a/tools/kvm/include/kvm/irq.h b/tools/kvm/include/kvm/irq.h index 5c1274b98610..20213c064b0b 100644 --- a/tools/kvm/include/kvm/irq.h +++ b/tools/kvm/include/kvm/irq.h @@ -22,7 +22,7 @@ struct pci_dev { struct list_headlines; }; -int irq__register_device(u32 dev, u8 *pin, u8 *line); +int irq__register_device(u32 dev, u8 *line); struct rb_node *irq__get_pci_tree(void); diff --git a/tools/kvm/powerpc/irq.c b/tools/kvm/powerpc/irq.c index ae9da507fb82..d906bb2840bc 100644 --- a/tools/kvm/powerpc/irq.c +++ b/tools/kvm/powerpc/irq.c @@ -32,9 +32,8 @@ * generic cope with multiple PPC platform types. */ -int irq__register_device(u32 dev, u8 *pin, u8 *line) +int irq__register_device(u32 dev, u8 *line) { - *pin = 1; /* * Have I said how nasty I find this? Line should be dontcare... PHB * should determine which CPU/XICS IRQ to fire. diff --git a/tools/kvm/virtio/mmio.c b/tools/kvm/virtio/mmio.c index afae6a70f006..90f90ede3c1f 100644 --- a/tools/kvm/virtio/mmio.c +++ b/tools/kvm/virtio/mmio.c @@ -260,7 +260,7 @@ int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev, int device_id, int subsys_id, int class) { struct virtio_mmio *vmmio = vdev-virtio; - u8 pin, line; + u8 line; vmmio-addr = virtio_mmio_get_io_space_block(VIRTIO_MMIO_IO_SIZE); vmmio-kvm = kvm; @@ -277,7 +277,7 @@ int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev, .queue_num_max = 256, }; - if (irq__register_device(subsys_id, pin, line) 0) + if (irq__register_device(subsys_id, line) 0) return -1; vmmio-irq = line; vmmio-dev_hdr = (struct device_header) { diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c index e1b5be6b036e..77dde3bee741 100644 --- a/tools/kvm/virtio/pci.c +++ b/tools/kvm/virtio/pci.c @@ -335,7 +335,7 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev, int device_id,
[PATCH 15/17] kvm tools: ARM: generate an fdt node for our PCI emulation
This patch factors out some of the openfirmware PCI binding definitions from the powerpc spapr PCI code and uses them to generate appropriate FDT properties for the PCI node on ARM. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/Makefile | 2 +- tools/kvm/arm/fdt.c| 4 ++ tools/kvm/arm/include/arm-common/pci.h | 6 ++ tools/kvm/arm/pci.c| 118 + tools/kvm/include/kvm/of_pci.h | 44 5 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 tools/kvm/arm/include/arm-common/pci.h create mode 100644 tools/kvm/arm/pci.c create mode 100644 tools/kvm/include/kvm/of_pci.h diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile index 29f18220c749..b87265189d1f 100644 --- a/tools/kvm/Makefile +++ b/tools/kvm/Makefile @@ -158,7 +158,7 @@ endif # ARM OBJS_ARM_COMMON:= arm/fdt.o arm/gic.o arm/ioport.o arm/irq.o \ - arm/kvm.o arm/kvm-cpu.o arm/timer.o + arm/kvm.o arm/kvm-cpu.o arm/pci.o arm/timer.o HDRS_ARM_COMMON:= arm/include ifeq ($(ARCH), arm) DEFINES += -DCONFIG_ARM diff --git a/tools/kvm/arm/fdt.c b/tools/kvm/arm/fdt.c index 9a34d9804930..d90fc9e1734f 100644 --- a/tools/kvm/arm/fdt.c +++ b/tools/kvm/arm/fdt.c @@ -5,6 +5,7 @@ #include kvm/virtio-mmio.h #include arm-common/gic.h +#include arm-common/pci.h #include stdbool.h @@ -155,6 +156,9 @@ static int setup_fdt(struct kvm *kvm) dev_hdr = device__next_dev(dev_hdr); } + /* PCI host controller */ + pci__generate_fdt_nodes(fdt, gic_phandle); + /* PSCI firmware */ _FDT(fdt_begin_node(fdt, psci)); _FDT(fdt_property_string(fdt, compatible, arm,psci)); diff --git a/tools/kvm/arm/include/arm-common/pci.h b/tools/kvm/arm/include/arm-common/pci.h new file mode 100644 index ..ee87725ee82f --- /dev/null +++ b/tools/kvm/arm/include/arm-common/pci.h @@ -0,0 +1,6 @@ +#ifndef ARM_COMMON__PCI_H +#define ARM_COMMON__PCI_H + +void pci__generate_fdt_nodes(void *fdt, u32 gic_phandle); + +#endif /* ARM_COMMON__PCI_H */ diff --git a/tools/kvm/arm/pci.c b/tools/kvm/arm/pci.c new file mode 100644 index ..ce1932ecc3ee --- /dev/null +++ b/tools/kvm/arm/pci.c @@ -0,0 +1,118 @@ +#include kvm/devices.h +#include kvm/fdt.h +#include kvm/of_pci.h +#include kvm/pci.h +#include kvm/util.h + +#include arm-common/pci.h + +/* + * An entry in the interrupt-map table looks like: + * pci unit address pci interrupt pin gic phandle gic interrupt + */ + +struct of_gic_irq { + u32 type, num, flags; +} __attribute__((packed)); + +struct of_interrupt_map_entry { + struct of_pci_irq_mask pci_irq_mask; + u32 gic_phandle; + struct of_gic_irq gic_irq; +} __attribute__((packed)); + +void pci__generate_fdt_nodes(void *fdt, u32 gic_phandle) +{ + struct device_header *dev_hdr; + struct of_interrupt_map_entry irq_map[OF_PCI_IRQ_MAP_MAX]; + unsigned nentries = 0; + /* Describe the memory ranges (config and memory) */ + struct of_pci_ranges_entry ranges[] = { + { + .pci_addr = { + .hi = cpu_to_fdt32(of_pci_b_ss(OF_PCI_SS_CONFIG)), + .mid= 0, + .lo = 0, + }, + .cpu_addr = cpu_to_fdt64(KVM_PCI_CFG_AREA), + .length = cpu_to_fdt64(ARM_PCI_CFG_SIZE), + }, + { + .pci_addr = { + .hi = cpu_to_fdt32(of_pci_b_ss(OF_PCI_SS_IO)), + .mid= 0, + .lo = 0, + }, + .cpu_addr = cpu_to_fdt64(KVM_IOPORT_AREA), + .length = cpu_to_fdt64(ARM_IOPORT_SIZE), + }, + { + .pci_addr = { + .hi = cpu_to_fdt32(of_pci_b_ss(OF_PCI_SS_M32)), + .mid= 0, + .lo = 0, + }, + .cpu_addr = cpu_to_fdt64(KVM_PCI_MMIO_AREA), + .length = cpu_to_fdt64(ARM_PCI_MMIO_SIZE), + }, + }; + + /* Boilerplate PCI properties */ + _FDT(fdt_begin_node(fdt, pci)); + _FDT(fdt_property_cell(fdt, #address-cells, 0x3)); + _FDT(fdt_property_cell(fdt, #size-cells, 0x2)); + _FDT(fdt_property_cell(fdt, #interrupt-cells, 0x1)); + _FDT(fdt_property_string(fdt, compatible, linux,pci-virt)); + + _FDT(fdt_property(fdt, ranges, ranges, sizeof(ranges))); + + /* Generate the interrupt map ... */ + dev_hdr =
[PATCH 14/17] kvm tools: ARM: route guest PCI accesses to the emulation layer
This patch routes guest PCI accesses to kvm__emulate_mmio, rather than exiting lkvm via a die invocation. The guest command-line is also updated to prevent the guest from attempting to program the BARs with new addresses (i.e. probe-only). Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/arm/include/arm-common/kvm-arch.h | 6 +++--- tools/kvm/arm/kvm-cpu.c | 4 ++-- tools/kvm/arm/kvm.c | 5 + 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/tools/kvm/arm/include/arm-common/kvm-arch.h b/tools/kvm/arm/include/arm-common/kvm-arch.h index 348e88d00b1c..8adfcd495c03 100644 --- a/tools/kvm/arm/include/arm-common/kvm-arch.h +++ b/tools/kvm/arm/include/arm-common/kvm-arch.h @@ -46,10 +46,10 @@ static inline bool arm_addr_in_virtio_mmio_region(u64 phys_addr) return phys_addr = KVM_VIRTIO_MMIO_AREA phys_addr limit; } -static inline bool arm_addr_in_pci_mmio_region(u64 phys_addr) +static inline bool arm_addr_in_pci_region(u64 phys_addr) { - u64 limit = KVM_PCI_MMIO_AREA + ARM_PCI_MMIO_SIZE; - return phys_addr = KVM_PCI_MMIO_AREA phys_addr limit; + u64 limit = KVM_PCI_CFG_AREA + ARM_PCI_CFG_SIZE + ARM_PCI_MMIO_SIZE; + return phys_addr = KVM_PCI_CFG_AREA phys_addr limit; } struct kvm_arch { diff --git a/tools/kvm/arm/kvm-cpu.c b/tools/kvm/arm/kvm-cpu.c index d31e7b154ae8..b017994f4014 100644 --- a/tools/kvm/arm/kvm-cpu.c +++ b/tools/kvm/arm/kvm-cpu.c @@ -107,8 +107,8 @@ bool kvm_cpu__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, int direction = is_write ? KVM_EXIT_IO_OUT : KVM_EXIT_IO_IN; u16 port = phys_addr USHRT_MAX; return kvm__emulate_io(kvm, port, data, direction, len, 1); - } else if (arm_addr_in_pci_mmio_region(phys_addr)) { - die(PCI emulation not supported on ARM!); + } else if (arm_addr_in_pci_region(phys_addr)) { + return kvm__emulate_mmio(kvm, phys_addr, data, len, is_write); } return false; diff --git a/tools/kvm/arm/kvm.c b/tools/kvm/arm/kvm.c index 008b7fe75d7d..6db646b4f4fd 100644 --- a/tools/kvm/arm/kvm.c +++ b/tools/kvm/arm/kvm.c @@ -56,6 +56,11 @@ void kvm__arch_read_term(struct kvm *kvm) void kvm__arch_set_cmdline(char *cmdline, bool video) { + /* +* We don't support movable BARs, so force the guest to use what +* we tell it. +*/ + strcpy(cmdline, pci=firmware); } void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size) -- 1.8.2.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/17] kvm tools: net: don't propagate error codes from tx/rx operations
Currently, if a -tx or -rx callback into the net_dev_operations encounters an error, it returns -1 to the virtio-net code, which in turn treats this as an unsigned (size_t) size describing the data available. The resulting memcpy operation then quickly explodes with a SEGV. This patch detects the error code from the low-level callbacks and exits the thread dealing with the erroneous queue. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/net/uip/core.c | 2 +- tools/kvm/virtio/net.c | 20 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/tools/kvm/net/uip/core.c b/tools/kvm/net/uip/core.c index b3cd8c25d4da..e860f3afec97 100644 --- a/tools/kvm/net/uip/core.c +++ b/tools/kvm/net/uip/core.c @@ -36,7 +36,7 @@ int uip_tx(struct iovec *iov, u16 out, struct uip_info *info) buf = malloc(eth_len); if (!buf) - return -1; + return -ENOMEM; eth = (struct uip_eth *)buf; for (i = 1; i out; i++) { diff --git a/tools/kvm/virtio/net.c b/tools/kvm/virtio/net.c index 2f61718a5029..ae4712c3c550 100644 --- a/tools/kvm/virtio/net.c +++ b/tools/kvm/virtio/net.c @@ -81,7 +81,7 @@ static void *virtio_net_rx_thread(void *p) struct net_dev *ndev = p; u16 out, in; u16 head; - size_t len, copied; + int len, copied; u32 id; mutex_lock(ndev-mutex); @@ -108,11 +108,17 @@ static void *virtio_net_rx_thread(void *p) struct virtio_net_hdr_mrg_rxbuf *hdr; len = ndev-ops-rx(dummy_iov, 1, ndev); + if (len 0) { + pr_warning(%s: rx on vq %u failed (%d), exiting thread\n, + __func__, id, len); + goto out_err; + } + copied = 0; head = virt_queue__get_iov(vq, iov, out, in, kvm); hdr = (void *)iov[0].iov_base; while (copied len) { - size_t iovsize = min(len - copied, iov_size(iov, in)); + size_t iovsize = min_t(size_t, len - copied, iov_size(iov, in)); memcpy_toiovec(iov, buffer + copied, iovsize); copied += iovsize; @@ -131,6 +137,7 @@ static void *virtio_net_rx_thread(void *p) } } +out_err: pthread_exit(NULL); return NULL; @@ -165,6 +172,12 @@ static void *virtio_net_tx_thread(void *p) while (virt_queue__available(vq)) { head = virt_queue__get_iov(vq, iov, out, in, kvm); len = ndev-ops-tx(iov, out, ndev); + if (len 0) { + pr_warning(%s: tx on vq %u failed (%d)\n, + __func__, id, len); + goto out_err; + } + virt_queue__set_used_elem(vq, head, len); } @@ -172,10 +185,9 @@ static void *virtio_net_tx_thread(void *p) ndev-vdev.ops-signal_vq(kvm, ndev-vdev, id); } +out_err: pthread_exit(NULL); - return NULL; - } static virtio_net_ctrl_ack virtio_net_handle_mq(struct kvm* kvm, struct net_dev *ndev, struct virtio_net_ctrl_hdr *ctrl) -- 1.8.2.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 07/17] kvm tools: pci: add MMIO interface to virtio-pci devices
This patch adds an MMIO interface for each virtio-pci device, so that they can be accessed without having to use an ioport. For each device, a new memory BAR is added which corresponds to an area of MMIO space with a shim trap handler. This handler simply translates the access into an ioport access via kvm__emulate_io. Since guests can generate accesses via either the ioport or MMIO regions, an ioeventfd is registered for both. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/include/kvm/virtio-pci.h | 4 +- tools/kvm/virtio/pci.c | 111 + 2 files changed, 78 insertions(+), 37 deletions(-) diff --git a/tools/kvm/include/kvm/virtio-pci.h b/tools/kvm/include/kvm/virtio-pci.h index 9b063924e5da..c795ce71fa88 100644 --- a/tools/kvm/include/kvm/virtio-pci.h +++ b/tools/kvm/include/kvm/virtio-pci.h @@ -22,8 +22,10 @@ struct virtio_pci { struct pci_device_header pci_hdr; struct device_headerdev_hdr; void*dev; + struct kvm *kvm; - u16 base_addr; + u16 port_addr; + u32 mmio_addr; u8 status; u8 isr; u32 features; diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c index 77c933fd4ab2..e1b5be6b036e 100644 --- a/tools/kvm/virtio/pci.c +++ b/tools/kvm/virtio/pci.c @@ -24,7 +24,8 @@ static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct virtio_device *vde { struct ioevent ioevent; struct virtio_pci *vpci = vdev-virtio; - int r; + int i, r, flags = IOEVENTFD_FLAG_PIO; + int fds[2]; vpci-ioeventfds[vq] = (struct virtio_pci_ioevent_param) { .vdev = vdev, @@ -32,32 +33,44 @@ static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct virtio_device *vde }; ioevent = (struct ioevent) { - .io_addr= vpci-base_addr + VIRTIO_PCI_QUEUE_NOTIFY, - .io_len = sizeof(u16), .fn = virtio_pci__ioevent_callback, .fn_ptr = vpci-ioeventfds[vq], .datamatch = vq, .fn_kvm = kvm, - .fd = eventfd(0, 0), }; - if (vdev-use_vhost) - /* -* Vhost will poll the eventfd in host kernel side, -* no need to poll in userspace. -*/ - r = ioeventfd__add_event(ioevent, IOEVENTFD_FLAG_PIO); - else - /* Need to poll in userspace. */ - r = ioeventfd__add_event(ioevent, IOEVENTFD_FLAG_PIO | - IOEVENTFD_FLAG_USER_POLL); + /* +* Vhost will poll the eventfd in host kernel side, otherwise we +* need to poll in userspace. +*/ + if (!vdev-use_vhost) + flags |= IOEVENTFD_FLAG_USER_POLL; + + /* ioport */ + ioevent.io_addr = vpci-port_addr + VIRTIO_PCI_QUEUE_NOTIFY; + ioevent.io_len = sizeof(u16); + ioevent.fd = fds[0] = eventfd(0, 0); + r = ioeventfd__add_event(ioevent, flags); if (r) return r; - if (vdev-ops-notify_vq_eventfd) - vdev-ops-notify_vq_eventfd(kvm, vpci-dev, vq, ioevent.fd); + /* mmio */ + ioevent.io_addr = vpci-mmio_addr + VIRTIO_PCI_QUEUE_NOTIFY; + ioevent.io_len = sizeof(u32); + ioevent.fd = fds[1] = eventfd(0, 0); + r = ioeventfd__add_event(ioevent, flags); + if (r) + goto free_ioport_evt; + if (vdev-ops-notify_vq_eventfd) + for (i = 0; i 2; ++i) + vdev-ops-notify_vq_eventfd(kvm, vpci-dev, vq, +fds[i]); return 0; + +free_ioport_evt: + ioeventfd__del_event(vpci-port_addr + VIRTIO_PCI_QUEUE_NOTIFY, vq); + return r; } static inline bool virtio_pci__msix_enabled(struct virtio_pci *vpci) @@ -105,7 +118,7 @@ static bool virtio_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port, vdev = ioport-priv; vpci = vdev-virtio; - offset = port - vpci-base_addr; + offset = port - vpci-port_addr; switch (offset) { case VIRTIO_PCI_HOST_FEATURES: @@ -188,7 +201,7 @@ static bool virtio_pci__io_out(struct ioport *ioport, struct kvm *kvm, u16 port, vdev = ioport-priv; vpci = vdev-virtio; - offset = port - vpci-base_addr; + offset = port - vpci-port_addr; switch (offset) { case VIRTIO_PCI_GUEST_FEATURES: @@ -227,7 +240,8 @@ static struct ioport_operations virtio_pci__io_ops = { .io_out = virtio_pci__io_out, }; -static void virtio_pci__mmio_callback(u64 addr, u8 *data, u32 len, u8 is_write, void *ptr) +static void
[PATCH 14/17] kvm tools: ARM: route guest PCI accesses to the emulation layer
This patch routes guest PCI accesses to kvm__emulate_mmio, rather than exiting lkvm via a die invocation. The guest command-line is also updated to prevent the guest from attempting to program the BARs with new addresses (i.e. probe-only). Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/arm/include/arm-common/kvm-arch.h | 6 +++--- tools/kvm/arm/kvm-cpu.c | 4 ++-- tools/kvm/arm/kvm.c | 5 + 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/tools/kvm/arm/include/arm-common/kvm-arch.h b/tools/kvm/arm/include/arm-common/kvm-arch.h index 348e88d00b1c..8adfcd495c03 100644 --- a/tools/kvm/arm/include/arm-common/kvm-arch.h +++ b/tools/kvm/arm/include/arm-common/kvm-arch.h @@ -46,10 +46,10 @@ static inline bool arm_addr_in_virtio_mmio_region(u64 phys_addr) return phys_addr = KVM_VIRTIO_MMIO_AREA phys_addr limit; } -static inline bool arm_addr_in_pci_mmio_region(u64 phys_addr) +static inline bool arm_addr_in_pci_region(u64 phys_addr) { - u64 limit = KVM_PCI_MMIO_AREA + ARM_PCI_MMIO_SIZE; - return phys_addr = KVM_PCI_MMIO_AREA phys_addr limit; + u64 limit = KVM_PCI_CFG_AREA + ARM_PCI_CFG_SIZE + ARM_PCI_MMIO_SIZE; + return phys_addr = KVM_PCI_CFG_AREA phys_addr limit; } struct kvm_arch { diff --git a/tools/kvm/arm/kvm-cpu.c b/tools/kvm/arm/kvm-cpu.c index d31e7b154ae8..b017994f4014 100644 --- a/tools/kvm/arm/kvm-cpu.c +++ b/tools/kvm/arm/kvm-cpu.c @@ -107,8 +107,8 @@ bool kvm_cpu__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, int direction = is_write ? KVM_EXIT_IO_OUT : KVM_EXIT_IO_IN; u16 port = phys_addr USHRT_MAX; return kvm__emulate_io(kvm, port, data, direction, len, 1); - } else if (arm_addr_in_pci_mmio_region(phys_addr)) { - die(PCI emulation not supported on ARM!); + } else if (arm_addr_in_pci_region(phys_addr)) { + return kvm__emulate_mmio(kvm, phys_addr, data, len, is_write); } return false; diff --git a/tools/kvm/arm/kvm.c b/tools/kvm/arm/kvm.c index 008b7fe75d7d..6db646b4f4fd 100644 --- a/tools/kvm/arm/kvm.c +++ b/tools/kvm/arm/kvm.c @@ -56,6 +56,11 @@ void kvm__arch_read_term(struct kvm *kvm) void kvm__arch_set_cmdline(char *cmdline, bool video) { + /* +* We don't support movable BARs, so force the guest to use what +* we tell it. +*/ + strcpy(cmdline, pci=firmware); } void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size) -- 1.8.2.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 11/17] kvm tools: irq: rename irq__register_device to irq__alloc_line
Since irq__register_device no longer registers a device with anything, rename it to irq__alloc_line, which better describes what is actually going on. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/arm/irq.c | 2 +- tools/kvm/hw/pci-shmem.c| 2 +- tools/kvm/hw/vesa.c | 2 +- tools/kvm/include/kvm/irq.h | 2 +- tools/kvm/powerpc/irq.c | 2 +- tools/kvm/powerpc/xics.c| 4 ++-- tools/kvm/virtio/mmio.c | 2 +- tools/kvm/virtio/pci.c | 2 +- tools/kvm/x86/irq.c | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tools/kvm/arm/irq.c b/tools/kvm/arm/irq.c index 39d4fbc23314..a39a2c289d27 100644 --- a/tools/kvm/arm/irq.c +++ b/tools/kvm/arm/irq.c @@ -4,7 +4,7 @@ #include arm-common/gic.h -int irq__register_device(void) +int irq__alloc_line(void) { return gic__alloc_irqnum(); } diff --git a/tools/kvm/hw/pci-shmem.c b/tools/kvm/hw/pci-shmem.c index c0c63223e6d9..057118332981 100644 --- a/tools/kvm/hw/pci-shmem.c +++ b/tools/kvm/hw/pci-shmem.c @@ -360,7 +360,7 @@ int pci_shmem__init(struct kvm *kvm) /* Register good old INTx */ pci_shmem_pci_device.irq_pin = 1; - pci_shmem_pci_device.irq_line = irq__register_device(); + pci_shmem_pci_device.irq_line = irq__alloc_line(); /* Register MMIO space for MSI-X */ r = ioport__register(kvm, IOPORT_EMPTY, shmem_pci__io_ops, IOPORT_SIZE, NULL); diff --git a/tools/kvm/hw/vesa.c b/tools/kvm/hw/vesa.c index f033ebed0790..c7b8e66cc531 100644 --- a/tools/kvm/hw/vesa.c +++ b/tools/kvm/hw/vesa.c @@ -66,7 +66,7 @@ struct framebuffer *vesa__init(struct kvm *kvm) return ERR_PTR(r); vesa_pci_device.irq_pin = 1; - vesa_pci_device.irq_line= irq__register_device(); + vesa_pci_device.irq_line= irq__alloc_line(); vesa_base_addr = (u16)r; vesa_pci_device.bar[0] = cpu_to_le32(vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO); device__register(vesa_device); diff --git a/tools/kvm/include/kvm/irq.h b/tools/kvm/include/kvm/irq.h index 14cf574849b3..4cec6f0f8447 100644 --- a/tools/kvm/include/kvm/irq.h +++ b/tools/kvm/include/kvm/irq.h @@ -10,7 +10,7 @@ struct kvm; -int irq__register_device(void); +int irq__alloc_line(void); int irq__init(struct kvm *kvm); int irq__exit(struct kvm *kvm); diff --git a/tools/kvm/powerpc/irq.c b/tools/kvm/powerpc/irq.c index 3436ae85027f..c187d8f306f2 100644 --- a/tools/kvm/powerpc/irq.c +++ b/tools/kvm/powerpc/irq.c @@ -32,7 +32,7 @@ * generic cope with multiple PPC platform types. */ -int irq__register_device(void) +int irq__alloc_line(void) { /* * Have I said how nasty I find this? Line should be dontcare... PHB diff --git a/tools/kvm/powerpc/xics.c b/tools/kvm/powerpc/xics.c index c1ef35bbe012..9dc27b8b7752 100644 --- a/tools/kvm/powerpc/xics.c +++ b/tools/kvm/powerpc/xics.c @@ -278,14 +278,14 @@ static int allocated_irqnum = XICS_IRQ_OFFSET; /* * xics_alloc_irqnum(): This is hacky. The problem boils down to the PCI device * code which just calls kvm__irq_line( .. pcidev-pci_hdr.irq_line ..) at will. - * Each PCI device's IRQ line is allocated by irq__register_device() (which + * Each PCI device's IRQ line is allocated by irq__alloc_line() (which * allocates an IRQ AND allocates a.. PCI device num..). * * In future I'd like to at least mimic some kind of 'upstream IRQ controller' * whereby PCI devices let their PHB know when they want to IRQ, and that * percolates up. * - * For now, allocate a REAL xics irq number and (via irq__register_device) push + * For now, allocate a REAL xics irq number and (via irq__alloc_line) push * that into the config space. 8 bits only though! */ int xics_alloc_irqnum(void) diff --git a/tools/kvm/virtio/mmio.c b/tools/kvm/virtio/mmio.c index a8212bacd599..1cb186b452e6 100644 --- a/tools/kvm/virtio/mmio.c +++ b/tools/kvm/virtio/mmio.c @@ -276,7 +276,7 @@ int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev, .queue_num_max = 256, }; - vmmio-irq = irq__register_device(); + vmmio-irq = irq__alloc_line(); vmmio-dev_hdr = (struct device_header) { .bus_type = DEVICE_BUS_MMIO, .data = generate_virtio_mmio_fdt_node, diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c index 8005e17195d9..dbd67580fb03 100644 --- a/tools/kvm/virtio/pci.c +++ b/tools/kvm/virtio/pci.c @@ -409,7 +409,7 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev, vpci-features |= VIRTIO_PCI_F_SIGNAL_MSI; vpci-pci_hdr.irq_pin = 1; - vpci-pci_hdr.irq_line = irq__register_device(); + vpci-pci_hdr.irq_line = irq__alloc_line(); r = device__register(vpci-dev_hdr); if (r 0) goto free_msix_mmio; diff --git a/tools/kvm/x86/irq.c b/tools/kvm/x86/irq.c
[PATCH 00/17] kvm tools: pci: add PCI support for ARM targets
Hello, This patch series adds PCI support for ARM targets to lkvm. Note that there are corresponding kernel patches in order for Linux to use the virtual PCI host controller, so the interface is still subject to change. The main parts of this series are: - Fixes to the MSI-X bar and virtio-net device initialisation - An effective rewrite of the IRQ allocation code, so that core code handles the IRQ allocation for a device, based upon its bus - Introduction of a PCI Memory Space, which is actually a shim around the ioport emulation and simply redirects guest access there - Generation of a device-tree node describing the PCI emulation, using the properties laid out in ePAPR and associated specs Tested on x86_64, AArch32 and AArch64. Build-tested only on PPC64. All feedback welcome! Will Will Deacon (17): kvm tools: pci: register virtio pba structure as mmio region with kvm kvm tools: pci: remove BAR 3 hangover from virtio pci msix code kvm tools: net: don't propagate error codes from tx/rx operations kvm tools: net: allow a mixture of pci and mmio virtio devices kvm tools: pci: register 24-bit configuration space below MMIO region kvm tools: pci: ensure BARs are naturally aligned kvm tools: pci: add MMIO interface to virtio-pci devices kvm tools: irq: remove pin parameter from irq__register_device kvm tools: irq: replace the x86 irq rbtree with the PCI device tree kvm tools: irq: remove remaining parameters to irq__register_device kvm tools: irq: rename irq__register_device to irq__alloc_line kvm tools: irq: make irq__alloc_line generic kvm tools: irq: move irq line allocation into device registration kvm tools: ARM: route guest PCI accesses to the emulation layer kvm tools: ARM: generate an fdt node for our PCI emulation kvm tools: powerpc: make use of common of_pci.h header definitions kvm tools: ARM: allow default virtio transport to be passed on cmdline tools/kvm/Makefile | 3 +- tools/kvm/arm/fdt.c| 4 + tools/kvm/arm/gic.c| 12 -- tools/kvm/arm/include/arm-common/kvm-arch.h| 20 +++- tools/kvm/arm/include/arm-common/kvm-config-arch.h | 12 +- tools/kvm/arm/include/arm-common/pci.h | 6 + tools/kvm/arm/ioport.c | 5 +- tools/kvm/arm/irq.c| 8 -- tools/kvm/arm/kvm-cpu.c| 4 +- tools/kvm/arm/kvm.c| 5 + tools/kvm/arm/pci.c| 118 tools/kvm/devices.c| 13 +++ tools/kvm/hw/pci-shmem.c | 9 -- tools/kvm/hw/vesa.c| 7 -- tools/kvm/include/kvm/irq.h| 16 +-- tools/kvm/include/kvm/of_pci.h | 44 tools/kvm/include/kvm/pci.h| 3 + tools/kvm/include/kvm/virtio-mmio.h| 1 + tools/kvm/include/kvm/virtio-pci.h | 4 +- tools/kvm/irq.c| 9 ++ tools/kvm/net/uip/core.c | 2 +- tools/kvm/pci.c| 54 +++-- tools/kvm/powerpc/include/kvm/kvm-arch.h | 9 +- tools/kvm/powerpc/irq.c| 19 tools/kvm/powerpc/spapr_pci.c | 114 --- tools/kvm/powerpc/xics.c | 28 + tools/kvm/virtio/9p.c | 2 +- tools/kvm/virtio/balloon.c | 2 +- tools/kvm/virtio/blk.c | 2 +- tools/kvm/virtio/console.c | 2 +- tools/kvm/virtio/mmio.c| 14 ++- tools/kvm/virtio/net.c | 42 +-- tools/kvm/virtio/pci.c | 120 tools/kvm/virtio/rng.c | 2 +- tools/kvm/virtio/scsi.c| 2 +- tools/kvm/x86/include/kvm/kvm-arch.h | 9 +- tools/kvm/x86/irq.c| 121 - tools/kvm/x86/mptable.c| 35 +++--- 38 files changed, 480 insertions(+), 402 deletions(-) create mode 100644 tools/kvm/arm/include/arm-common/pci.h create mode 100644 tools/kvm/arm/pci.c create mode 100644 tools/kvm/include/kvm/of_pci.h create mode 100644 tools/kvm/irq.c -- 1.8.2.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/17] kvm tools: pci: register virtio pba structure as mmio region with kvm
Despite allocating and providing code to handle accesses to the pba structure, virtio msix blocks in fact only register the msix table with kvm. This patch fixes the MMIO region so that it includes the pba structure for msix io blocks of virtio pci devices. The corresponding BAR is also updated to advertise the full size of the io block. Cc: Sasha Levin sasha.le...@oracle.com Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/virtio/pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c index bb6e7c45e12a..91010cabbcde 100644 --- a/tools/kvm/virtio/pci.c +++ b/tools/kvm/virtio/pci.c @@ -322,7 +322,7 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev, return r; vpci-base_addr = (u16)r; - r = kvm__register_mmio(kvm, vpci-msix_io_block, PCI_IO_SIZE, false, + r = kvm__register_mmio(kvm, vpci-msix_io_block, PCI_IO_SIZE * 2, false, virtio_pci__mmio_callback, vpci); if (r 0) goto free_ioport; @@ -344,7 +344,7 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev, .status = cpu_to_le16(PCI_STATUS_CAP_LIST), .capabilities = (void *)vpci-pci_hdr.msix - (void *)vpci-pci_hdr, .bar_size[0]= IOPORT_SIZE, - .bar_size[1]= PCI_IO_SIZE, + .bar_size[1]= PCI_IO_SIZE * 2, .bar_size[3]= PCI_IO_SIZE, }; -- 1.8.2.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/17] kvm tools: pci: remove BAR 3 hangover from virtio pci msix code
Despite not being used anymore, there are still traces of BAR 3 in both the code and comments for the virtio pci msix implementation. This patch removes the redundant code and fixes up the comments to match what we're actually doing. Cc: Sasha Levin sasha.le...@oracle.com Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/virtio/pci.c | 10 +++--- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c index 91010cabbcde..77c933fd4ab2 100644 --- a/tools/kvm/virtio/pci.c +++ b/tools/kvm/virtio/pci.c @@ -345,7 +345,6 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev, .capabilities = (void *)vpci-pci_hdr.msix - (void *)vpci-pci_hdr, .bar_size[0]= IOPORT_SIZE, .bar_size[1]= PCI_IO_SIZE * 2, - .bar_size[3]= PCI_IO_SIZE, }; vpci-dev_hdr = (struct device_header) { @@ -368,12 +367,9 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev, */ vpci-pci_hdr.msix.ctrl = cpu_to_le16(VIRTIO_PCI_MAX_VQ + VIRTIO_PCI_MAX_CONFIG - 1); - /* -* Both table and PBA could be mapped on the same BAR, but for now -* we're not in short of BARs -*/ - vpci-pci_hdr.msix.table_offset = cpu_to_le32(1); /* Use BAR 1 */ - vpci-pci_hdr.msix.pba_offset = cpu_to_le32(1 | PCI_IO_SIZE); /* Use BAR 3 */ + /* Both table and PBA are mapped to the same BAR (1) */ + vpci-pci_hdr.msix.table_offset = cpu_to_le32(1); + vpci-pci_hdr.msix.pba_offset = cpu_to_le32(1 | PCI_IO_SIZE); vpci-config_vector = 0; r = irq__register_device(subsys_id, pin, line); -- 1.8.2.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 00/17] kvm tools: pci: add PCI support for ARM targets
Hello, This patch series adds PCI support for ARM targets to lkvm. Note that there are corresponding kernel patches in order for Linux to use the virtual PCI host controller, so the interface is still subject to change. The main parts of this series are: - Fixes to the MSI-X bar and virtio-net device initialisation - An effective rewrite of the IRQ allocation code, so that core code handles the IRQ allocation for a device, based upon its bus - Introduction of a PCI Memory Space, which is actually a shim around the ioport emulation and simply redirects guest access there - Generation of a device-tree node describing the PCI emulation, using the properties laid out in ePAPR and associated specs Tested on x86_64, AArch32 and AArch64. Build-tested only on PPC64. All feedback welcome! Will Will Deacon (17): kvm tools: pci: register virtio pba structure as mmio region with kvm kvm tools: pci: remove BAR 3 hangover from virtio pci msix code kvm tools: net: don't propagate error codes from tx/rx operations kvm tools: net: allow a mixture of pci and mmio virtio devices kvm tools: pci: register 24-bit configuration space below MMIO region kvm tools: pci: ensure BARs are naturally aligned kvm tools: pci: add MMIO interface to virtio-pci devices kvm tools: irq: remove pin parameter from irq__register_device kvm tools: irq: replace the x86 irq rbtree with the PCI device tree kvm tools: irq: remove remaining parameters to irq__register_device kvm tools: irq: rename irq__register_device to irq__alloc_line kvm tools: irq: make irq__alloc_line generic kvm tools: irq: move irq line allocation into device registration kvm tools: ARM: route guest PCI accesses to the emulation layer kvm tools: ARM: generate an fdt node for our PCI emulation kvm tools: powerpc: make use of common of_pci.h header definitions kvm tools: ARM: allow default virtio transport to be passed on cmdline tools/kvm/Makefile | 3 +- tools/kvm/arm/fdt.c| 4 + tools/kvm/arm/gic.c| 12 -- tools/kvm/arm/include/arm-common/kvm-arch.h| 20 +++- tools/kvm/arm/include/arm-common/kvm-config-arch.h | 12 +- tools/kvm/arm/include/arm-common/pci.h | 6 + tools/kvm/arm/ioport.c | 5 +- tools/kvm/arm/irq.c| 8 -- tools/kvm/arm/kvm-cpu.c| 4 +- tools/kvm/arm/kvm.c| 5 + tools/kvm/arm/pci.c| 118 tools/kvm/devices.c| 13 +++ tools/kvm/hw/pci-shmem.c | 9 -- tools/kvm/hw/vesa.c| 7 -- tools/kvm/include/kvm/irq.h| 16 +-- tools/kvm/include/kvm/of_pci.h | 44 tools/kvm/include/kvm/pci.h| 3 + tools/kvm/include/kvm/virtio-mmio.h| 1 + tools/kvm/include/kvm/virtio-pci.h | 4 +- tools/kvm/irq.c| 9 ++ tools/kvm/net/uip/core.c | 2 +- tools/kvm/pci.c| 54 +++-- tools/kvm/powerpc/include/kvm/kvm-arch.h | 9 +- tools/kvm/powerpc/irq.c| 19 tools/kvm/powerpc/spapr_pci.c | 114 --- tools/kvm/powerpc/xics.c | 28 + tools/kvm/virtio/9p.c | 2 +- tools/kvm/virtio/balloon.c | 2 +- tools/kvm/virtio/blk.c | 2 +- tools/kvm/virtio/console.c | 2 +- tools/kvm/virtio/mmio.c| 14 ++- tools/kvm/virtio/net.c | 42 +-- tools/kvm/virtio/pci.c | 120 tools/kvm/virtio/rng.c | 2 +- tools/kvm/virtio/scsi.c| 2 +- tools/kvm/x86/include/kvm/kvm-arch.h | 9 +- tools/kvm/x86/irq.c| 121 - tools/kvm/x86/mptable.c| 35 +++--- 38 files changed, 480 insertions(+), 402 deletions(-) create mode 100644 tools/kvm/arm/include/arm-common/pci.h create mode 100644 tools/kvm/arm/pci.c create mode 100644 tools/kvm/include/kvm/of_pci.h create mode 100644 tools/kvm/irq.c -- 1.8.2.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
QEMU P2P migration speed
Hello, I`ve got strange results during benchmarking migration speed for different kinds of loads on source/target host: when source host is 'empty', migration takes approx. 30 percent longer than the same for host already occupied by one VM with CPU overcommit ratio=1. [src host, three equal vms, each with ability to eat all cores once] [tgt host, one VM, with same appetite and limitations] All VMs was put into cgroups with same cpu ceiling and cpu shares values. Migration time is almost independent of VM RSS(varies by ten percent at maximum), for situation when VM is active on target host, time is about 85 seconds to migrate 8G between hosts, and when it is turned off, migration time *increasing* to 120s. For curious ones, frequency management is completely inactive on both nodes, neither CStates mechanism. Interconnection is relatively fast (20+Gbit/s by IPoIB). Anyone have a suggestions on how to possibly explain/fix this? -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 04/17] kvm tools: net: allow a mixture of pci and mmio virtio devices
When attempting to initialise a mixture of pci and mmio virtio devices, we cannot share an ops structure, otherwise the transport-specific fields (init/exit and signal handling) will be globally set to the transport of the last registered device. This patch dynamically allocates a new ops structure for each instance of a virtio net device. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/virtio/net.c | 22 +- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/tools/kvm/virtio/net.c b/tools/kvm/virtio/net.c index ae4712c3c550..dbb443124ee1 100644 --- a/tools/kvm/virtio/net.c +++ b/tools/kvm/virtio/net.c @@ -713,13 +713,20 @@ done: static int virtio_net__init_one(struct virtio_net_params *params) { - int i; + int i, err; struct net_dev *ndev; + struct virtio_ops *ops; ndev = calloc(1, sizeof(struct net_dev)); if (ndev == NULL) return -ENOMEM; + ops = malloc(sizeof(*ops)); + if (ops == NULL) { + err = -ENOMEM; + goto err_free_ndev; + } + list_add_tail(ndev-list, ndevs); ndev-kvm = params-kvm; @@ -749,12 +756,13 @@ static int virtio_net__init_one(struct virtio_net_params *params) uip_static_init(ndev-info); } + *ops = net_dev_virtio_ops; if (params-trans strcmp(params-trans, mmio) == 0) - virtio_init(params-kvm, ndev, ndev-vdev, net_dev_virtio_ops, - VIRTIO_MMIO, PCI_DEVICE_ID_VIRTIO_NET, VIRTIO_ID_NET, PCI_CLASS_NET); + virtio_init(params-kvm, ndev, ndev-vdev, ops, VIRTIO_MMIO, + PCI_DEVICE_ID_VIRTIO_NET, VIRTIO_ID_NET, PCI_CLASS_NET); else - virtio_init(params-kvm, ndev, ndev-vdev, net_dev_virtio_ops, - VIRTIO_PCI, PCI_DEVICE_ID_VIRTIO_NET, VIRTIO_ID_NET, PCI_CLASS_NET); + virtio_init(params-kvm, ndev, ndev-vdev, ops, VIRTIO_PCI, + PCI_DEVICE_ID_VIRTIO_NET, VIRTIO_ID_NET, PCI_CLASS_NET); if (params-vhost) virtio_net__vhost_init(params-kvm, ndev); @@ -763,6 +771,10 @@ static int virtio_net__init_one(struct virtio_net_params *params) compat_id = virtio_compat_add_message(virtio-net, CONFIG_VIRTIO_NET); return 0; + +err_free_ndev: + free(ndev); + return err; } int virtio_net__init(struct kvm *kvm) -- 1.8.2.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/17] kvm tools: pci: register virtio pba structure as mmio region with kvm
Despite allocating and providing code to handle accesses to the pba structure, virtio msix blocks in fact only register the msix table with kvm. This patch fixes the MMIO region so that it includes the pba structure for msix io blocks of virtio pci devices. The corresponding BAR is also updated to advertise the full size of the io block. Cc: Sasha Levin sasha.le...@oracle.com Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/virtio/pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c index bb6e7c45e12a..91010cabbcde 100644 --- a/tools/kvm/virtio/pci.c +++ b/tools/kvm/virtio/pci.c @@ -322,7 +322,7 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev, return r; vpci-base_addr = (u16)r; - r = kvm__register_mmio(kvm, vpci-msix_io_block, PCI_IO_SIZE, false, + r = kvm__register_mmio(kvm, vpci-msix_io_block, PCI_IO_SIZE * 2, false, virtio_pci__mmio_callback, vpci); if (r 0) goto free_ioport; @@ -344,7 +344,7 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev, .status = cpu_to_le16(PCI_STATUS_CAP_LIST), .capabilities = (void *)vpci-pci_hdr.msix - (void *)vpci-pci_hdr, .bar_size[0]= IOPORT_SIZE, - .bar_size[1]= PCI_IO_SIZE, + .bar_size[1]= PCI_IO_SIZE * 2, .bar_size[3]= PCI_IO_SIZE, }; -- 1.8.2.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 17/17] kvm tools: ARM: allow default virtio transport to be passed on cmdline
This patch changes VIRTIO_DEFAULT_TRANS to take a struct kvm parameter, allowing architectures to choose the default transport dynamically. For ARM, this is driven by an arch-specific cmdline option. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/arm/include/arm-common/kvm-arch.h| 3 ++- tools/kvm/arm/include/arm-common/kvm-config-arch.h | 12 tools/kvm/powerpc/include/kvm/kvm-arch.h | 2 +- tools/kvm/virtio/9p.c | 2 +- tools/kvm/virtio/balloon.c | 2 +- tools/kvm/virtio/blk.c | 2 +- tools/kvm/virtio/console.c | 2 +- tools/kvm/virtio/rng.c | 2 +- tools/kvm/virtio/scsi.c| 2 +- tools/kvm/x86/include/kvm/kvm-arch.h | 2 +- 10 files changed, 18 insertions(+), 13 deletions(-) diff --git a/tools/kvm/arm/include/arm-common/kvm-arch.h b/tools/kvm/arm/include/arm-common/kvm-arch.h index 8adfcd495c03..b6c4bf8de364 100644 --- a/tools/kvm/arm/include/arm-common/kvm-arch.h +++ b/tools/kvm/arm/include/arm-common/kvm-arch.h @@ -32,7 +32,8 @@ #define KVM_IRQ_OFFSET GIC_SPI_IRQ_BASE -#define VIRTIO_DEFAULT_TRANS VIRTIO_MMIO +#define VIRTIO_DEFAULT_TRANS(kvm) \ + ((kvm)-cfg.arch.virtio_trans_pci ? VIRTIO_PCI : VIRTIO_MMIO) static inline bool arm_addr_in_ioport_region(u64 phys_addr) { diff --git a/tools/kvm/arm/include/arm-common/kvm-config-arch.h b/tools/kvm/arm/include/arm-common/kvm-config-arch.h index f3baf392704d..a8ebd94a78f1 100644 --- a/tools/kvm/arm/include/arm-common/kvm-config-arch.h +++ b/tools/kvm/arm/include/arm-common/kvm-config-arch.h @@ -4,9 +4,10 @@ #include kvm/parse-options.h struct kvm_config_arch { - const char *dump_dtb_filename; - unsigned int force_cntfrq; - bool aarch32_guest; + const char *dump_dtb_filename; + unsigned intforce_cntfrq; + boolvirtio_trans_pci; + boolaarch32_guest; }; #define OPT_ARCH_RUN(pfx, cfg) \ @@ -17,6 +18,9 @@ struct kvm_config_arch { OPT_UINTEGER('\0', override-bad-firmware-cntfrq, (cfg)-force_cntfrq,\ Specify Generic Timer frequency in guest DT to \ work around buggy secure firmware *Firmware should be \ -updated to program CNTFRQ correctly*), +updated to program CNTFRQ correctly*), \ + OPT_BOOLEAN('\0', force-pci, (cfg)-virtio_trans_pci, \ + Force virtio devices to use PCI as their default \ + transport), #endif /* ARM_COMMON__KVM_CONFIG_ARCH_H */ diff --git a/tools/kvm/powerpc/include/kvm/kvm-arch.h b/tools/kvm/powerpc/include/kvm/kvm-arch.h index d2b52bf0f617..f8627a2a2dd3 100644 --- a/tools/kvm/powerpc/include/kvm/kvm-arch.h +++ b/tools/kvm/powerpc/include/kvm/kvm-arch.h @@ -44,7 +44,7 @@ #define KVM_IRQ_OFFSET 16 -#define VIRTIO_DEFAULT_TRANS VIRTIO_PCI +#define VIRTIO_DEFAULT_TRANS(kvm) VIRTIO_PCI struct spapr_phb; diff --git a/tools/kvm/virtio/9p.c b/tools/kvm/virtio/9p.c index 127b13afdf0b..25cdd8c2e70b 100644 --- a/tools/kvm/virtio/9p.c +++ b/tools/kvm/virtio/9p.c @@ -1392,7 +1392,7 @@ int virtio_9p__init(struct kvm *kvm) list_for_each_entry(p9dev, devs, list) { virtio_init(kvm, p9dev, p9dev-vdev, p9_dev_virtio_ops, - VIRTIO_DEFAULT_TRANS, PCI_DEVICE_ID_VIRTIO_9P, + VIRTIO_DEFAULT_TRANS(kvm), PCI_DEVICE_ID_VIRTIO_9P, VIRTIO_ID_9P, PCI_CLASS_9P); } diff --git a/tools/kvm/virtio/balloon.c b/tools/kvm/virtio/balloon.c index 486353584904..f7dfb0be2875 100644 --- a/tools/kvm/virtio/balloon.c +++ b/tools/kvm/virtio/balloon.c @@ -262,7 +262,7 @@ int virtio_bln__init(struct kvm *kvm) memset(bdev.config, 0, sizeof(struct virtio_balloon_config)); virtio_init(kvm, bdev, bdev.vdev, bln_dev_virtio_ops, - VIRTIO_DEFAULT_TRANS, PCI_DEVICE_ID_VIRTIO_BLN, + VIRTIO_DEFAULT_TRANS(kvm), PCI_DEVICE_ID_VIRTIO_BLN, VIRTIO_ID_BALLOON, PCI_CLASS_BLN); if (compat_id == -1) diff --git a/tools/kvm/virtio/blk.c b/tools/kvm/virtio/blk.c index ab1871673d46..4bed3a975d1d 100644 --- a/tools/kvm/virtio/blk.c +++ b/tools/kvm/virtio/blk.c @@ -260,7 +260,7 @@ static int virtio_blk__init_one(struct kvm *kvm, struct disk_image *disk) }; virtio_init(kvm, bdev, bdev-vdev, blk_dev_virtio_ops, - VIRTIO_DEFAULT_TRANS, PCI_DEVICE_ID_VIRTIO_BLK, + VIRTIO_DEFAULT_TRANS(kvm), PCI_DEVICE_ID_VIRTIO_BLK, VIRTIO_ID_BLOCK, PCI_CLASS_BLK); list_add_tail(bdev-list, bdevs); diff --git a/tools/kvm/virtio/console.c
[PATCH 11/17] kvm tools: irq: rename irq__register_device to irq__alloc_line
Since irq__register_device no longer registers a device with anything, rename it to irq__alloc_line, which better describes what is actually going on. Signed-off-by: Will Deacon will.dea...@arm.com --- tools/kvm/arm/irq.c | 2 +- tools/kvm/hw/pci-shmem.c| 2 +- tools/kvm/hw/vesa.c | 2 +- tools/kvm/include/kvm/irq.h | 2 +- tools/kvm/powerpc/irq.c | 2 +- tools/kvm/powerpc/xics.c| 4 ++-- tools/kvm/virtio/mmio.c | 2 +- tools/kvm/virtio/pci.c | 2 +- tools/kvm/x86/irq.c | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tools/kvm/arm/irq.c b/tools/kvm/arm/irq.c index 39d4fbc23314..a39a2c289d27 100644 --- a/tools/kvm/arm/irq.c +++ b/tools/kvm/arm/irq.c @@ -4,7 +4,7 @@ #include arm-common/gic.h -int irq__register_device(void) +int irq__alloc_line(void) { return gic__alloc_irqnum(); } diff --git a/tools/kvm/hw/pci-shmem.c b/tools/kvm/hw/pci-shmem.c index c0c63223e6d9..057118332981 100644 --- a/tools/kvm/hw/pci-shmem.c +++ b/tools/kvm/hw/pci-shmem.c @@ -360,7 +360,7 @@ int pci_shmem__init(struct kvm *kvm) /* Register good old INTx */ pci_shmem_pci_device.irq_pin = 1; - pci_shmem_pci_device.irq_line = irq__register_device(); + pci_shmem_pci_device.irq_line = irq__alloc_line(); /* Register MMIO space for MSI-X */ r = ioport__register(kvm, IOPORT_EMPTY, shmem_pci__io_ops, IOPORT_SIZE, NULL); diff --git a/tools/kvm/hw/vesa.c b/tools/kvm/hw/vesa.c index f033ebed0790..c7b8e66cc531 100644 --- a/tools/kvm/hw/vesa.c +++ b/tools/kvm/hw/vesa.c @@ -66,7 +66,7 @@ struct framebuffer *vesa__init(struct kvm *kvm) return ERR_PTR(r); vesa_pci_device.irq_pin = 1; - vesa_pci_device.irq_line= irq__register_device(); + vesa_pci_device.irq_line= irq__alloc_line(); vesa_base_addr = (u16)r; vesa_pci_device.bar[0] = cpu_to_le32(vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO); device__register(vesa_device); diff --git a/tools/kvm/include/kvm/irq.h b/tools/kvm/include/kvm/irq.h index 14cf574849b3..4cec6f0f8447 100644 --- a/tools/kvm/include/kvm/irq.h +++ b/tools/kvm/include/kvm/irq.h @@ -10,7 +10,7 @@ struct kvm; -int irq__register_device(void); +int irq__alloc_line(void); int irq__init(struct kvm *kvm); int irq__exit(struct kvm *kvm); diff --git a/tools/kvm/powerpc/irq.c b/tools/kvm/powerpc/irq.c index 3436ae85027f..c187d8f306f2 100644 --- a/tools/kvm/powerpc/irq.c +++ b/tools/kvm/powerpc/irq.c @@ -32,7 +32,7 @@ * generic cope with multiple PPC platform types. */ -int irq__register_device(void) +int irq__alloc_line(void) { /* * Have I said how nasty I find this? Line should be dontcare... PHB diff --git a/tools/kvm/powerpc/xics.c b/tools/kvm/powerpc/xics.c index c1ef35bbe012..9dc27b8b7752 100644 --- a/tools/kvm/powerpc/xics.c +++ b/tools/kvm/powerpc/xics.c @@ -278,14 +278,14 @@ static int allocated_irqnum = XICS_IRQ_OFFSET; /* * xics_alloc_irqnum(): This is hacky. The problem boils down to the PCI device * code which just calls kvm__irq_line( .. pcidev-pci_hdr.irq_line ..) at will. - * Each PCI device's IRQ line is allocated by irq__register_device() (which + * Each PCI device's IRQ line is allocated by irq__alloc_line() (which * allocates an IRQ AND allocates a.. PCI device num..). * * In future I'd like to at least mimic some kind of 'upstream IRQ controller' * whereby PCI devices let their PHB know when they want to IRQ, and that * percolates up. * - * For now, allocate a REAL xics irq number and (via irq__register_device) push + * For now, allocate a REAL xics irq number and (via irq__alloc_line) push * that into the config space. 8 bits only though! */ int xics_alloc_irqnum(void) diff --git a/tools/kvm/virtio/mmio.c b/tools/kvm/virtio/mmio.c index a8212bacd599..1cb186b452e6 100644 --- a/tools/kvm/virtio/mmio.c +++ b/tools/kvm/virtio/mmio.c @@ -276,7 +276,7 @@ int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev, .queue_num_max = 256, }; - vmmio-irq = irq__register_device(); + vmmio-irq = irq__alloc_line(); vmmio-dev_hdr = (struct device_header) { .bus_type = DEVICE_BUS_MMIO, .data = generate_virtio_mmio_fdt_node, diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c index 8005e17195d9..dbd67580fb03 100644 --- a/tools/kvm/virtio/pci.c +++ b/tools/kvm/virtio/pci.c @@ -409,7 +409,7 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev, vpci-features |= VIRTIO_PCI_F_SIGNAL_MSI; vpci-pci_hdr.irq_pin = 1; - vpci-pci_hdr.irq_line = irq__register_device(); + vpci-pci_hdr.irq_line = irq__alloc_line(); r = device__register(vpci-dev_hdr); if (r 0) goto free_msix_mmio; diff --git a/tools/kvm/x86/irq.c b/tools/kvm/x86/irq.c
file_ram_alloc: unify mem-path,mem-prealloc error handling
-mem-prealloc asks to preallocate memory residing on -mem-path path. Currently QEMU exits in case: - Memory file has been created but allocation via explicit write fails. And it fallbacks to malloc in case: - Querying huge page size fails. - Lack of sync MMU support. - Open fails. - mmap fails. Have the same behaviour for all cases: fail in case -mem-path and -mem-prealloc are specified for regions where the requested size is suitable for hugepages. Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/exec.c b/exec.c index 9ad0a4b..1da1ba7 100644 --- a/exec.c +++ b/exec.c @@ -996,7 +996,7 @@ static void *file_ram_alloc(RAMBlock *block, hpagesize = gethugepagesize(path); if (!hpagesize) { -return NULL; +goto error; } if (memory hpagesize) { @@ -1005,7 +1005,7 @@ static void *file_ram_alloc(RAMBlock *block, if (kvm_enabled() !kvm_has_sync_mmu()) { fprintf(stderr, host lacks kvm mmu notifiers, -mem-path unsupported\n); -return NULL; +goto error; } /* Make name safe to use with mkstemp by replacing '/' with '_'. */ @@ -1023,7 +1023,7 @@ static void *file_ram_alloc(RAMBlock *block, if (fd 0) { perror(unable to create backing store for hugepages); g_free(filename); -return NULL; +goto error; } unlink(filename); g_free(filename); @@ -1043,7 +1043,7 @@ static void *file_ram_alloc(RAMBlock *block, if (area == MAP_FAILED) { perror(file_ram_alloc: can't mmap RAM pages); close(fd); -return (NULL); +goto error; } if (mem_prealloc) { @@ -1087,6 +1087,12 @@ static void *file_ram_alloc(RAMBlock *block, block-fd = fd; return area; + +error: +if (mem_prealloc) { +exit(1); +} +return NULL; } #else static void *file_ram_alloc(RAMBlock *block, -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: file_ram_alloc: unify mem-path,mem-prealloc error handling
On Tue, Feb 04, 2014 at 01:41:53PM -0500, Marcelo Tosatti wrote: -mem-prealloc asks to preallocate memory residing on -mem-path path. Currently QEMU exits in case: - Memory file has been created but allocation via explicit write fails. And it fallbacks to malloc in case: - Querying huge page size fails. - Lack of sync MMU support. - Open fails. - mmap fails. Have the same behaviour for all cases: fail in case -mem-path and -mem-prealloc are specified for regions where the requested size is suitable for hugepages. Signed-off-by: Marcelo Tosatti mtosa...@redhat.com Forgot uq/master on the subject (but its aimed for that tree). -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Measuring KVM Performance using Hardware Performance Counters
On Mon, Feb 3, 2014 at 9:31 PM, Paolo Bonzini pbonz...@redhat.com wrote: Il 03/02/2014 18:06, Xin Tong ha scritto: /.../qemu-system-x86_64 TID 2537 [TID 2537] (877 ticks/71.24%) This is the CPU thread (calls into the KVM modules). This is the thread that calls the int kvm_cpu_exec(CPUArchState *env) and ioctl. /.../vmlinux (395 ticks/45.04%) /kvm (198 ticks/22.58%) /kvm_intel (153 ticks/17.45%) /.../qemu-system-x86_64 (71 ticks/8.10%) /.../libc-2.15.so (47 ticks/5.36%) /.../libpthread-2.15.so (12 ticks/1.37%) /libahci (1 ticks/0.11%) /.../qemu-system-x86_64 TID 2658 [TID 2658] (200 ticks/16.25%) This is probably the VNC thread. /.../vmlinux (190 ticks/95.00%) /.../libpthread-2.15.so (6 ticks/3.00%) /.../libc-2.15.so (2 ticks/1.00%) /.../qemu-system-x86_64 (1 ticks/0.50%) [vdso] (tgid:2534 range:0x7fff10588000-0x7fff10589fff) (1 ticks/0.50%) /.../qemu-system-x86_64 TID 2534 [TID 2534] (154 ticks/12.51%) This is the main thread (lowest TID of all). Is this the thread that executes main_loop_wait and handles IO emulation ? /ksmd [PID 53] (83 ticks/5.36%) /.../top [PID 2617] (43 ticks/2.78%) /.../unity-2d-shell [PID 1807] (41 ticks/2.65%) Now, going to your questions: 2. why is qemu-system-x86_64 only taking 8.10% of the time, i imagine most of the time should be spent in qemu-system-x86_64 as 403.GCC does not do too much IO. This is the same I already answered: the time spent running the guest is in the context of process qemu-system-x86_64, but it is not running code from the qemu executable. In fact, 8.10% spent in qemu-system-x86_64 is a lot. I would expect much less. 3. why are so much time spent in vmlinux ? the symbols for vmlinux is listed below. 4. why are so much time spent in kvm-intel and kvm ? the symbols for both are listed below. Again, I think I already answered this. The time spent in vmx_vcpu_run is the actual time spent in the guest (17.45*60.13% = 10% roughly). I see, so this 10% is the actually useful GCC work done from the prospective of the guest. and the 8.10% is the time spent in the QEMU-system-x86_64 process. Everything else is overhead introduced by either virtualization or profiling. What SPEC scores are you getting from bare-metal, KVM without oprofile and KVM with oprofile? Is the profile substantially different if you use perf instead of oprofile? Can you run scripts/kvm/kvm_stat (from the QEMU tree) while your guest is running (under oprofile) and paste the output from that tool? Data below is from a new 403.gcc run on a haswell linux machine with ref input data set. Profile taken over the entire GCC run. Host linux kernel (compiled myself) version: Linux aristotle 3.13.1+ #3 SMP Mon Feb 3 11:16:00 EST 2014 x86_64 x86_64 x86_64 GNU/Linux Command to run kvm: kvm ~/disks/ubuntu-natty.qcow2 -nographic Commands to oprofile: sudo operf -s --separate-thread --event=CPU_CLK_UNHALTED:500 --vmlinux=/home/xtong/xtong-kernel/vmlinux sudo opreport --image-path /home/xtong/xtong-kernel -l -g -d --xml -o current.opm Profiled KVM Performance (Lower is better): 1005 seconds Non-Profiled KVM Performance (Lower is better): 998 seconds Non-Profiled run on host machine (Lower is better): 686 seconds ( the virtualization overhead is still quite large in spite of the hw extension !). running sudo scripts/kvm/kvm_stat gave kvm statistics kvm_exit 105 16 kvm_entry 105 16 kvm_apic70 10 kvm_emulate_insn35 5 kvm_eoi 35 5 kvm_mmio35 5 kvm_inj_virq35 5 kvm_apic_accept_irq 35 5 Overall: Core0 (53973 ticks/100.00%) /.../qemu-system-x86_64 TID 8861 [TID 8861] (38676 ticks/71.66%) /.../vmlinux (17426 ticks/45.06%) /kvm (7768 ticks/20.08%) /kvm_intel (6882 ticks/17.79%) /.../qemu-system-x86_64 (3535 ticks/9.14%) /.../libc-2.15.so (2384 ticks/6.16%) /.../libpthread-2.15.so (537 ticks/1.39%) /.../librt-2.15.so (82 ticks/0.21%) /.../libglib-2.0.so.0.3200.4 (41 ticks/0.11%) [vdso] (tgid:8858 range:0x7fffe31fe000-0x7fffe31f) (16 ticks/0.04%) /libahci (4 ticks/0.01%) /r8169 (1 ticks/0.00%) /.../qemu-system-x86_64 TID 8858 [TID 8858] (6745 ticks/12.50%) /.../qemu-system-x86_64 TID 8880 [TID 8880] (2945 ticks/5.46%) /.../qemu-system-x86_64 TID 8882 [TID 8882] (2835 ticks/5.25%) /.../qemu-system-x86_64 TID 8860 [TID 8860] (2772 ticks/5.14%) vmlinux (45.06%) CPU_CLK_UNHALTED %
[GIT PULL] tree-wide: clean up no longer required #include linux/init.h
We've had this in linux-next for 2+ weeks (thanks Stephen!) as a linux-stable like queue of patches, and as can be seen here: https://git.kernel.org/pub/scm/linux/kernel/git/paulg/init.git most of the changes in the last week have been trivial adding acks or dropping patches that maintainers decided to take themselves. With -rc1 now containing what was in linux-next, the queue applies to that baseline w/o issue, and I've redone comprehensive multi arch build testing on the -rc1 baseline as a final sanity check. Original RFC discussion and patch posting is here, if needed: https://lkml.org/lkml/2014/1/21/434 Suggested merge text follows: 8- Summary - We removed cpuinit and devinit, which left ~2000 instances of include linux/init.h that were no longer needed. To fully enable this removal/cleanup, we relocate module_init() from init.h into module.h. Multi arch/multi config build testing on linux-next has been used to find and fix any implicit header dependencies prior to deploying the actual init.h -- module.h move, to preserve bisection. Additional details: module_init/module_exit and friends moved to module.h - Aside from enabling this init.h cleanup to extend into modular files, it actually does make sense. For all modules will use some form of our initfunc processing/categorization, but not all initfunc users will be necessarily using modular functionality. So we move these module related macros to module.h and ensure module.h sources init.h module_init in non modular code: This series uncovered that we are enabling people to use module_init in non-modular code. While that works fine, there are at least three reasons why it probably should not be encouraged: 1) it makes a casual reader of the code assume the code is modular even though it is obj-y (builtin) or controlled by a bool Kconfig. 2) it makes it too easy to add dead code in a function that is handed to module_exit() -- [more on that below] 3) it breaks our ability to use priority sorted initcalls properly [more on that below.] 4) on some files, the use of module.h vs. init.h can cost a ~10% increase in the number of lines output from CPP. After this change, a new coder who tries to make use of module_init in non modular code would find themselves also needing to include the module.h header. At which point the odds are greater that they would ask themselves Am I doing this right? I shouldn't need this. Note that existing non-modular code that already includes module.h and uses module_init doesn't get fixed here, since they already build w/o errors triggered by this change; we'll have to hunt them down later. module_init and initcall ordering: -- We have a group of about ten priority sorted initcalls, that are called in init/main.c after most of the hard coded/direct calls have been processed. These serve the purpose of avoiding everyone poking at init/main.c to hook in their init sequence. The bins are: pure_initcall 0 core_initcall 1 postcore_initcall 2 arch_initcall 3 subsys_initcall 4 fs_initcall 5 device_initcall 6 late_initcall 7 These are meant to eventually replace users of the non specific priority __initcall which currently maps onto device_initcall. This is of interest, because in non-modular code, cpp does this: module_init -- __initcall -- device_initcall So all module_init() land in the device_initcall bucket, rather late in the sequence. That makes sense, since if it was a module, the init could be real late (days, weeks after boot). But now imagine you add support for some non-modular bus/arch/infrastructure (say for e.g. PCI) and you use module_init for it. That means anybody else who wants to use your subsystem can't do so if they use an initcall of 0 -- 5 priority. For a real world example of this, see patch #1 in this series: https://lkml.org/lkml/2014/1/14/809 We don't want to force code that is clearly arch or subsys or fs specific to have to use the device_initcall just because something else has been mistakenly put (or left) in that bucket. So a couple of changes do actually change the initcall level where it is inevitably appropriate to do so. Those are called out explicitly in their respective commit logs. module_exit and dead code - Built in code will never have an opportunity to call functions that are registered with module_exit(), so any cases of that uncovered in this series delete that dead code. Note that any built-in code that was already including module.h and using module_exit won't have shown up as breakage on the build coverage of this series, so we'll have to find
Re: kvm (qemu) speed virtio
04.02.2014 20:32, Marcus пишет: We may have seen this as well. Initial speed tests were actually pretty good, but after running a few IO test it would actually cause the physical disks that were dedicated to the windows vm host side to be stuck at 100% util with no throughput for 30 seconds at a time according to iostat. We were using noop scheduler on the disks. I think it's something with your host, as we stopped seeing it when we moved from stock CentOS 6.5 kernel to vanilla 3.10 kernel. Sorry I don't have more info on the cause, we saw the issue for a few days but were already upgrading due to the need for vxlan, so we didn't bother investigating. On Tue, Feb 4, 2014 at 7:22 AM, XliN saikov...@gmail.com wrote: Good day. Very little speed drives Virtio. Drivers are the latest guest on the system Windows server 2008. Host system centos 6.5. All that can be tried, but failed to increase the speed. And there I have a database running. Screenshots test speed drives http://itmages.ru/image/view/1471772/feec35c3 http://itmages.ru/image/view/1471772/feec35c3 http://itmages.ru/image/view/1471774/2b0baeae http://itmages.ru/image/view/1471774/2b0baeae http://itmages.ru/image/view/1471785/9fffb8f5 http://itmages.ru/image/view/1471785/9fffb8f5 Thanks in advance. Apply nowhere else. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Offer a kernel upgrade to 3.10 on centos 6.5? Whether it will survive the host system? =) -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [GIT PULL] tree-wide: clean up no longer required #include linux/init.h
* Paul Gortmaker paul.gortma...@windriver.com wrote: On Feb 4, 2014 3:52 PM, Paul Gortmaker paul.gortma...@windriver.com wrote: We've had this in linux-next for 2+ weeks (thanks Stephen!) as a linux-stable like queue of patches, and as can be seen here: https://git.kernel.org/pub/scm/linux/kernel/git/paulg/init.git Argh, above link is meant for cloning, not viewing. This should be better... https://git.kernel.org/cgit/linux/kernel/git/paulg/init.git/ So, if you meant Linus to pull it, you probably want to cite a real Git URI along the lines of: git://git.kernel.org/pub/scm/linux/kernel/git/paulg/init.git ( Otherwise your pull request might be ignored or worse, you might get an honest reply, due to the https transport being considered evil that no free man outside of corporate firewalls should ever consider and all that. ) Nice cleanups btw. Thanks, Ingo -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [GIT PULL] tree-wide: clean up no longer required #include linux/init.h
Hi Ingo, On Wed, 5 Feb 2014 07:06:33 +0100 Ingo Molnar mi...@kernel.org wrote: So, if you meant Linus to pull it, you probably want to cite a real Git URI along the lines of: git://git.kernel.org/pub/scm/linux/kernel/git/paulg/init.git Paul provided the proper git url further down in the mail along with the usual pull request message (I guess he should have put that bit at the top). -- Cheers, Stephen Rothwells...@canb.auug.org.au pgpCupBnQvITX.pgp Description: PGP signature
Re: [GIT PULL] tree-wide: clean up no longer required #include linux/init.h
* Stephen Rothwell s...@canb.auug.org.au wrote: Hi Ingo, On Wed, 5 Feb 2014 07:06:33 +0100 Ingo Molnar mi...@kernel.org wrote: So, if you meant Linus to pull it, you probably want to cite a real Git URI along the lines of: git://git.kernel.org/pub/scm/linux/kernel/git/paulg/init.git Paul provided the proper git url further down in the mail along with the usual pull request message (I guess he should have put that bit at the top). Yeah, indeed, and it even comes with a signed tag, which is an extra nice touch: git://git.kernel.org/pub/scm/linux/kernel/git/paulg/linux.git tags/init-cleanup (I guess the https was mentioned first to lower expectations.) Thanks, Ingo -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: QEMU P2P migration speed
Il 04/02/2014 18:06, Andrey Korolyov ha scritto: Migration time is almost independent of VM RSS(varies by ten percent at maximum), for situation when VM is active on target host, time is about 85 seconds to migrate 8G between hosts, and when it is turned off, migration time *increasing* to 120s. For curious ones, frequency management is completely inactive on both nodes, neither CStates mechanism. Interconnection is relatively fast (20+Gbit/s by IPoIB). What version of QEMU? Paolo -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] PPC: KVM: fix VCPU run for HV KVM
On 04.02.2014, at 09:03, Alexey Kardashevskiy a...@ozlabs.ru wrote: On 01/13/2014 02:44 AM, Alexander Graf wrote: On 10.01.2014, at 08:21, Alexey Kardashevskiy a...@ozlabs.ru wrote: When write to MMIO happens and there is an ioeventfd for that and is handled successfully, ioeventfd_write() returns 0 (success) and kvmppc_handle_store() returns EMULATE_DONE. Then kvmppc_emulate_mmio() converts EMULATE_DONE to RESUME_GUEST_NV and this broke from the loop. This adds handling of RESUME_GUEST_NV in kvmppc_vcpu_run_hv(). Cc: Michael S. Tsirkin m...@redhat.com Suggested-by: Paul Mackerras pau...@samba.org Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- This definitely needs a better commit message. Please, help. ps. it seems like ioeventfd never worked on ppc64. hm. --- arch/powerpc/kvm/book3s_hv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 072287f..24f363f 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -1569,7 +1569,7 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu) vcpu-arch.fault_dar, vcpu-arch.fault_dsisr); srcu_read_unlock(vcpu-kvm-srcu, srcu_idx); } - } while (r == RESUME_GUEST); + } while ((r == RESUME_GUEST_NV) || (r == RESUME_GUEST)); How about while(!(r RESUME_FLAG_HOST)); Rather while(!(r RESUME_FLAG_HOST) (r 0)); and still not obvious that this is really better. Paul agrees with the original patch (and made a better commit message for our internal tree) but I just cannot make him reply in this thread, keep constantly asking him but to no avail :) That should cover all RESUME_GUEST_XXX cases just fine. Apart from that I agree that we should check for ! FLAG_HOST bit rather than the actual RESUME_GUEST value in all case where we check for it (read: please update all places). There are 3 places remotely similar to this and none of them requires a fix like above. Not today. Then someone goes in and realizes that CEDE advanced version 8 should clear r15 at which point you have to set RESUME_GUEST_NV and are in the same mess again. Let's just always treat RESUME_GUEST_NV and RESUME_GUEST as identical when checking for it. If you like, add a small helper like static inline bool is_resume_guest(int r) { return (r == RESUME_GUEST || r == RESUME_GUEST_NV); } in a header and use that one instead. That way we're guaranteed to be consistent. Alex -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html