qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] Re: [PATCH v2 3/9] provide in-kernel ioapic


From: Anthony Liguori
Subject: [Qemu-devel] Re: [PATCH v2 3/9] provide in-kernel ioapic
Date: Thu, 08 Oct 2009 08:49:32 -0500
User-agent: Thunderbird 2.0.0.23 (X11/20090825)

Glauber Costa wrote:
This patch provides kvm with an in-kernel ioapic. We are currently not enabling 
it.
The code is heavily based on what's in qemu-kvm.git.

It really ought to be it's own file and own device model. Having the code mixed in with ioapic.c is confusing because it's unclear what code is in use when the in-kernel model is used.

@@ -193,6 +194,79 @@ static void ioapic_mem_writel(void *opaque, 
target_phys_addr_t addr, uint32_t va
     }
 }

+static int kvm_kernel_ioapic_load_from_user(IOAPICState *s)
+{
+    int r = 0;
+#if defined(KVM_CAP_IRQCHIP) && defined(TARGET_I386)

No point in checking the KVM_CAP_IRQCHIP. Just require it during build. Otherwise, !KVM_CAP_IRQCHIP is dead code since I'm sure noone is actually testing kernels that old with modern qemu.

There's no point in restricting to I386 either.

+    struct kvm_irqchip chip;
+    struct kvm_ioapic_state *kioapic;
+    int i;
+
+    if (!(kvm_enabled() && kvm_irqchip_in_kernel()))
+        return 0;
+
+    chip.chip_id = KVM_IRQCHIP_IOAPIC;
+    kioapic = &chip.chip.ioapic;
+
+    kioapic->id = s->id;
+    kioapic->ioregsel = s->ioregsel;
+    kioapic->base_address = IOAPIC_DEFAULT_BASE_ADDRESS;
+    kioapic->irr = s->irr;
+    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+        kioapic->redirtbl[i].bits = s->ioredtbl[i];
+    }
+
+    r = kvm_set_irqchip(&chip);
+#endif
+    return r;
+}
+
+static void kvm_kernel_ioapic_save_to_user(IOAPICState *s)
+{
+#if defined(KVM_CAP_IRQCHIP) && defined(TARGET_I386)
+    struct kvm_irqchip chip;
+    struct kvm_ioapic_state *kioapic;
+    int i;
+
+    if (!(kvm_enabled() && kvm_irqchip_in_kernel()))
+        return;
+    chip.chip_id = KVM_IRQCHIP_IOAPIC;
+    kvm_get_irqchip(&chip);
+    kioapic = &chip.chip.ioapic;
+
+    s->id = kioapic->id;
+    s->ioregsel = kioapic->ioregsel;
+    s->irr = kioapic->irr;
+    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+        s->ioredtbl[i] = kioapic->redirtbl[i].bits;
+    }
+#endif
+}
+
+static void ioapic_pre_save(void *opaque)
+{
+    IOAPICState *s = (void *)opaque;
+
+    kvm_kernel_ioapic_save_to_user(s);
+}
+
+static int ioapic_pre_load(void *opaque)
+{
+    IOAPICState *s = opaque;
+
+    /* in case we are doing version 1, we just set these to sane values */
+    s->irr = 0;
+    return 0;
+}
+
+static int ioapic_post_load(void *opaque, int version_id)
+{
+    IOAPICState *s = opaque;
+
+    return kvm_kernel_ioapic_load_from_user(s);
+}
+
+
 static const VMStateDescription vmstate_ioapic = {
     .name = "ioapic",
     .version_id = 2,
@@ -205,7 +279,10 @@ static const VMStateDescription vmstate_ioapic = {
         VMSTATE_UINT32_V(irr, IOAPICState, 2),
         VMSTATE_UINT64_ARRAY(ioredtbl, IOAPICState, IOAPIC_NUM_PINS),
         VMSTATE_END_OF_LIST()
-    }
+    },
+    .pre_load = ioapic_pre_load,
+    .post_load = ioapic_post_load,
+    .pre_save = ioapic_pre_save,
 };

The in kernel apic should be a separate device model with a separate savevm section. They are different devices and there's no real advantage to pretending like they're the same device.

 static CPUReadMemoryFunc * const ioapic_mem_read[3] = {
diff --git a/kvm-all.c b/kvm-all.c
index 48ae26c..d795285 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -411,6 +411,26 @@ int kvm_check_extension(KVMState *s, unsigned int 
extension)
     return ret;
 }

+#ifdef KVM_CAP_IRQCHIP
+int kvm_set_irqchip(struct kvm_irqchip *chip)
+{
+    if (!kvm_state->irqchip_in_kernel) {
+        return 0;
+    }
+
+    return kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip);
+}

irqchip_in_kernel ought to disappear.

--
Regards,

Anthony Liguori





reply via email to

[Prev in Thread] Current Thread [Next in Thread]