Also, provide a kvm_ioapic that does not depend highly on common code. Signed-off-by: Glauber Costa <glommer@xxxxxxxxxx> --- hw/ioapic.c | 162 +++++++++++++++++++++++++++++++++++++--------------------- hw/pc.c | 7 ++- hw/pc.h | 1 + 3 files changed, 110 insertions(+), 60 deletions(-) diff --git a/hw/ioapic.c b/hw/ioapic.c index 6c178c7..3eb5d5f 100644 --- a/hw/ioapic.c +++ b/hw/ioapic.c @@ -198,58 +198,11 @@ static void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t va } } -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; - - chip.chip_id = KVM_IRQCHIP_IOAPIC; - kvm_get_irqchip(kvm_context, &chip); - kioapic = &chip.chip.ioapic; - - s->id = kioapic->id; - s->ioregsel = kioapic->ioregsel; - s->base_address = kioapic->base_address; - s->irr = kioapic->irr; - for (i = 0; i < IOAPIC_NUM_PINS; i++) { - s->ioredtbl[i] = kioapic->redirtbl[i].bits; - } -#endif -} - -static void kvm_kernel_ioapic_load_from_user(IOAPICState *s) -{ -#if defined(KVM_CAP_IRQCHIP) && defined(TARGET_I386) - struct kvm_irqchip chip; - struct kvm_ioapic_state *kioapic; - int i; - - chip.chip_id = KVM_IRQCHIP_IOAPIC; - kioapic = &chip.chip.ioapic; - - kioapic->id = s->id; - kioapic->ioregsel = s->ioregsel; - kioapic->base_address = s->base_address; - kioapic->irr = s->irr; - for (i = 0; i < IOAPIC_NUM_PINS; i++) { - kioapic->redirtbl[i].bits = s->ioredtbl[i]; - } - - kvm_set_irqchip(kvm_context, &chip); -#endif -} - -static void ioapic_save(QEMUFile *f, void *opaque) +static void ioapic_save_common(QEMUFile *f, void *opaque) { IOAPICState *s = opaque; int i; - if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) { - kvm_kernel_ioapic_save_to_user(s); - } - qemu_put_8s(f, &s->id); qemu_put_8s(f, &s->ioregsel); qemu_put_be64s(f, &s->base_address); @@ -259,7 +212,12 @@ static void ioapic_save(QEMUFile *f, void *opaque) } } -static int ioapic_load(QEMUFile *f, void *opaque, int version_id) +static void ioapic_save(QEMUFile *f, void *opaque) +{ + ioapic_save_common(f, opaque); +} + +static int ioapic_load_common(QEMUFile *f, void *opaque, int version_id) { IOAPICState *s = opaque; int i; @@ -283,14 +241,15 @@ static int ioapic_load(QEMUFile *f, void *opaque, int version_id) qemu_get_be64s(f, &s->ioredtbl[i]); } - if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) { - kvm_kernel_ioapic_load_from_user(s); - } - return 0; } -static void ioapic_reset(void *opaque) +static int ioapic_load(QEMUFile *f, void *opaque, int version_id) +{ + return ioapic_load_common(f, opaque, version_id); +} + +static void ioapic_reset_common(void *opaque) { IOAPICState *s = opaque; int i; @@ -299,11 +258,11 @@ static void ioapic_reset(void *opaque) s->base_address = IOAPIC_DEFAULT_BASE_ADDRESS; for(i = 0; i < IOAPIC_NUM_PINS; i++) s->ioredtbl[i] = 1 << 16; /* mask LVT */ -#ifdef KVM_CAP_IRQCHIP - if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) { - kvm_kernel_ioapic_load_from_user(s); - } -#endif +} + +static void ioapic_reset(void *opaque) +{ + ioapic_reset_common(opaque); } static CPUReadMemoryFunc *ioapic_mem_read[3] = { @@ -335,3 +294,88 @@ IOAPICState *ioapic_init(void) return s; } + +#ifdef KVM_CAP_IRQCHIP +static void kvm_kernel_ioapic_save_to_user(IOAPICState *s) +{ +#if defined(TARGET_I386) + struct kvm_irqchip chip; + struct kvm_ioapic_state *kioapic; + int i; + + chip.chip_id = KVM_IRQCHIP_IOAPIC; + kvm_get_irqchip(kvm_context, &chip); + kioapic = &chip.chip.ioapic; + + s->id = kioapic->id; + s->ioregsel = kioapic->ioregsel; + s->base_address = kioapic->base_address; + s->irr = kioapic->irr; + for (i = 0; i < IOAPIC_NUM_PINS; i++) { + s->ioredtbl[i] = kioapic->redirtbl[i].bits; + } +#endif +} + +static void kvm_kernel_ioapic_load_from_user(IOAPICState *s) +{ +#if defined(TARGET_I386) + struct kvm_irqchip chip; + struct kvm_ioapic_state *kioapic; + int i; + + chip.chip_id = KVM_IRQCHIP_IOAPIC; + kioapic = &chip.chip.ioapic; + + kioapic->id = s->id; + kioapic->ioregsel = s->ioregsel; + kioapic->base_address = s->base_address; + kioapic->irr = s->irr; + for (i = 0; i < IOAPIC_NUM_PINS; i++) { + kioapic->redirtbl[i].bits = s->ioredtbl[i]; + } + + kvm_set_irqchip(kvm_context, &chip); +#endif +} + +static void kvm_ioapic_save(QEMUFile *f, void *opaque) +{ + IOAPICState *s = opaque; + kvm_kernel_ioapic_save_to_user(s); + + ioapic_save_common(f, opaque); +} + +static int kvm_ioapic_load(QEMUFile *f, void *opaque, int version_id) +{ + IOAPICState *s = opaque; + int r = ioapic_load_common(f, opaque, version_id); + + if (r == 0) + kvm_kernel_ioapic_load_from_user(s); + return r; +} + + +static void kvm_ioapic_reset(void *opaque) +{ + IOAPICState *s = opaque; + + ioapic_reset_common(opaque); + + kvm_kernel_ioapic_load_from_user(s); +} + +IOAPICState *kvm_ioapic_init(void) +{ + IOAPICState *s; + + s = qemu_mallocz(sizeof(IOAPICState)); + kvm_ioapic_reset(s); + + register_savevm("ioapic", 0, 2, kvm_ioapic_save, kvm_ioapic_load, s); + qemu_register_reset(kvm_ioapic_reset, 0, s); + return s; +} +#endif diff --git a/hw/pc.c b/hw/pc.c index a99ab07..861dc34 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -1042,7 +1042,12 @@ static void pc_init1(ram_addr_t ram_size, register_ioport_write(0x92, 1, 1, ioport92_write, NULL); if (pci_enabled) { - ioapic = ioapic_init(); +#ifdef KVM_CAP_IRQCHIP + if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) + ioapic = kvm_ioapic_init(); + else +#endif + ioapic = ioapic_init(); } #ifdef USE_KVM_PIT if (kvm_enabled() && qemu_kvm_pit_in_kernel()) diff --git a/hw/pc.h b/hw/pc.h index ab847b9..d7f4a46 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -53,6 +53,7 @@ int apic_accept_pic_intr(CPUState *env); void apic_deliver_pic_intr(CPUState *env, int level); int apic_get_interrupt(CPUState *env); IOAPICState *ioapic_init(void); +IOAPICState *kvm_ioapic_init(void); void ioapic_set_irq(void *opaque, int vector, int level); void apic_reset_irq_delivered(void); int apic_get_irq_delivered(void); -- 1.5.6.6 -- 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