From 9468e9c41a89b1c9f3a905b8959e1dd3f055c732 Mon Sep 17 00:00:00 2001 From: Wei Liu Date: Thu, 12 Apr 2012 10:02:47 +0000 Subject: [PATCH] Xen: Add xen-apic support and hook it up. Signed-off-by: Wei Liu Signed-off-by: Stefano Stabellini Acked-by: Paolo Bonzini --- Makefile.target | 2 +- hw/pc.c | 8 +++++ hw/xen_apic.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 hw/xen_apic.c diff --git a/Makefile.target b/Makefile.target index e88b896e38..f9ce361d1f 100644 --- a/Makefile.target +++ b/Makefile.target @@ -237,7 +237,7 @@ QEMU_CFLAGS += $(VNC_PNG_CFLAGS) obj-$(CONFIG_XEN) += xen-all.o xen_machine_pv.o xen_domainbuild.o xen-mapcache.o obj-$(CONFIG_NO_XEN) += xen-stub.o -obj-i386-$(CONFIG_XEN) += xen_platform.o +obj-i386-$(CONFIG_XEN) += xen_platform.o xen_apic.o # Inter-VM PCI shared memory CONFIG_IVSHMEM = diff --git a/hw/pc.c b/hw/pc.c index 67f0479f40..1f5aacb2d2 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -42,6 +42,7 @@ #include "sysbus.h" #include "sysemu.h" #include "kvm.h" +#include "xen.h" #include "blockdev.h" #include "ui/qemu-spice.h" #include "memory.h" @@ -891,9 +892,12 @@ static DeviceState *apic_init(void *env, uint8_t apic_id) if (kvm_irqchip_in_kernel()) { dev = qdev_create(NULL, "kvm-apic"); + } else if (xen_enabled()) { + dev = qdev_create(NULL, "xen-apic"); } else { dev = qdev_create(NULL, "apic"); } + qdev_prop_set_uint8(dev, "id", apic_id); qdev_prop_set_ptr(dev, "cpu_env", env); qdev_init_nofail(dev); @@ -912,6 +916,10 @@ static DeviceState *apic_init(void *env, uint8_t apic_id) msi_supported = true; } + if (xen_enabled()) { + msi_supported = true; + } + return dev; } diff --git a/hw/xen_apic.c b/hw/xen_apic.c new file mode 100644 index 0000000000..1725ff67dd --- /dev/null +++ b/hw/xen_apic.c @@ -0,0 +1,90 @@ +/* + * Xen basic APIC support + * + * Copyright (c) 2012 Citrix + * + * Authors: + * Wei Liu + * + * This work is licensed under the terms of the GNU GPL version 2 or + * later. See the COPYING file in the top-level directory. + */ +#include "hw/apic_internal.h" +#include "hw/msi.h" +#include "xen.h" + +static uint64_t xen_apic_mem_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + return ~(uint64_t)0; +} + +static void xen_apic_mem_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) +{ + if (size != sizeof(uint32_t)) { + fprintf(stderr, "Xen: APIC write data size = %d, invalid\n", size); + return; + } + + xen_hvm_inject_msi(addr, data); +} + +static const MemoryRegionOps xen_apic_io_ops = { + .read = xen_apic_mem_read, + .write = xen_apic_mem_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + +static void xen_apic_init(APICCommonState *s) +{ + memory_region_init_io(&s->io_memory, &xen_apic_io_ops, s, "xen-apic-msi", + MSI_SPACE_SIZE); +} + +static void xen_apic_set_base(APICCommonState *s, uint64_t val) +{ +} + +static void xen_apic_set_tpr(APICCommonState *s, uint8_t val) +{ +} + +static uint8_t xen_apic_get_tpr(APICCommonState *s) +{ + return 0; +} + +static void xen_apic_vapic_base_update(APICCommonState *s) +{ +} + +static void xen_apic_external_nmi(APICCommonState *s) +{ +} + +static void xen_apic_class_init(ObjectClass *klass, void *data) +{ + APICCommonClass *k = APIC_COMMON_CLASS(klass); + + k->init = xen_apic_init; + k->set_base = xen_apic_set_base; + k->set_tpr = xen_apic_set_tpr; + k->get_tpr = xen_apic_get_tpr; + k->vapic_base_update = xen_apic_vapic_base_update; + k->external_nmi = xen_apic_external_nmi; +} + +static TypeInfo xen_apic_info = { + .name = "xen-apic", + .parent = TYPE_APIC_COMMON, + .instance_size = sizeof(APICCommonState), + .class_init = xen_apic_class_init, +}; + +static void xen_apic_register_types(void) +{ + type_register_static(&xen_apic_info); +} + +type_init(xen_apic_register_types)