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

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

 



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

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux