summary refs log tree commit diff stats
path: root/hw/pc.c
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@siemens.com>2011-10-16 13:23:26 +0200
committerJan Kiszka <jan.kiszka@siemens.com>2012-01-19 12:14:42 +0100
commit680c1c6fd73c0cb3971938944936f18bbb7bad1b (patch)
tree82f323ff3cd5432f07a58139384688e453f3db7c /hw/pc.c
parent9b5b76d44930dc9266bb6d30862704cb3c86d2ca (diff)
downloadfocaccia-qemu-680c1c6fd73c0cb3971938944936f18bbb7bad1b.tar.gz
focaccia-qemu-680c1c6fd73c0cb3971938944936f18bbb7bad1b.zip
kvm: x86: Add user space part for in-kernel APIC
This introduces the alternative APIC device which makes use of KVM's
in-kernel device model. External NMI injection via LINT1 is emulated by
checking the current state of the in-kernel APIC, only injecting a NMI
into the VCPU if LINT1 is unmasked and configured to DM_NMI.

MSI is not yet supported, so we disable this when the in-kernel model is
in use.

CC: Lai Jiangshan <laijs@cn.fujitsu.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Diffstat (limited to 'hw/pc.c')
-rw-r--r--hw/pc.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/hw/pc.c b/hw/pc.c
index 38d787a74a..6a8a8719ce 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -879,25 +879,30 @@ DeviceState *cpu_get_current_apic(void)
 static DeviceState *apic_init(void *env, uint8_t apic_id)
 {
     DeviceState *dev;
-    SysBusDevice *d;
     static int apic_mapped;
 
-    dev = qdev_create(NULL, "apic");
+    if (kvm_enabled() && kvm_irqchip_in_kernel()) {
+        dev = qdev_create(NULL, "kvm-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);
-    d = sysbus_from_qdev(dev);
 
     /* XXX: mapping more APICs at the same memory location */
     if (apic_mapped == 0) {
         /* NOTE: the APIC is directly connected to the CPU - it is not
            on the global memory bus. */
         /* XXX: what if the base changes? */
-        sysbus_mmio_map(d, 0, MSI_ADDR_BASE);
+        sysbus_mmio_map(sysbus_from_qdev(dev), 0, MSI_ADDR_BASE);
         apic_mapped = 1;
     }
 
-    msi_supported = true;
+    /* KVM does not support MSI yet. */
+    if (!kvm_enabled() || !kvm_irqchip_in_kernel()) {
+        msi_supported = true;
+    }
 
     return dev;
 }