From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1N11gi-0000AB-4d for qemu-devel@nongnu.org; Thu, 22 Oct 2009 13:43:00 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1N11gS-0008N8-0B for qemu-devel@nongnu.org; Thu, 22 Oct 2009 13:42:47 -0400 Received: from [199.232.76.173] (port=53793 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N11gQ-0008AH-CP for qemu-devel@nongnu.org; Thu, 22 Oct 2009 13:42:42 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53082) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1N11bN-0002wu-DU for qemu-devel@nongnu.org; Thu, 22 Oct 2009 13:37:29 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n9MHbRac012064 for ; Thu, 22 Oct 2009 13:37:27 -0400 Date: Thu, 22 Oct 2009 15:07:30 -0200 From: Marcelo Tosatti Subject: Re: [Qemu-devel] [RFC] in-kernel irqchip : split devices Message-ID: <20091022170730.GC4450@amt.cnet> References: <20091014143042.GD8092@mothafucka.localdomain> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20091014143042.GD8092@mothafucka.localdomain> List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Glauber Costa Cc: qemu-devel@nongnu.org, Avi Kivity On Wed, Oct 14, 2009 at 11:30:43AM -0300, Glauber Costa wrote: > Hello people, > > As I promised, I am sending a very brief PoC wrt split devices and in-kernel irqchip. > In this mail, I am including only the ioapic version for apreciation. I also have i8259, > and apic will take me a little bit more. This is just to try to bind the discussion to real > code. > > Note that we end up with a very slim representation of the device, and the code is much less > confusing, IMHO. Looks good to me. > Index: qemu/Makefile.target > =================================================================== > --- qemu.orig/Makefile.target > +++ qemu/Makefile.target > @@ -197,6 +197,8 @@ obj-i386-y += usb-uhci.o vmmouse.o vmpor > obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o > obj-i386-y += ne2000-isa.o > > +obj-i386-$(CONFIG_KVM) += ioapic-kvm.o > + > # shared objects > obj-ppc-y = ppc.o ide/core.o ide/qdev.o ide/isa.o ide/pci.o ide/macio.o > obj-ppc-y += vga.o vga-pci.o $(sound-obj-y) dma.o openpic.o > Index: qemu/hw/ioapic-kvm.c > =================================================================== > --- /dev/null > +++ qemu/hw/ioapic-kvm.c > @@ -0,0 +1,81 @@ > +#include "hw.h" > +#include "pc.h" > +#include "qemu-timer.h" > +#include "host-utils.h" > +#include "kvm.h" > + > +#define IOAPIC_NUM_PINS 0x18 > +#define IOAPIC_DEFAULT_BASE_ADDRESS 0xfec00000 > + > +static void ioapic_reset(void *opaque) > +{ > + struct kvm_ioapic_state *s = opaque; > + struct kvm_irqchip *chip; > + int i; > + > + chip = container_of(s, struct kvm_irqchip, chip.ioapic); > + > + chip->chip_id = KVM_IRQCHIP_IOAPIC; > + > + memset(s, 0, sizeof(*s)); > + s->base_address = IOAPIC_DEFAULT_BASE_ADDRESS; > + for(i = 0; i < IOAPIC_NUM_PINS; i++) > + s->redirtbl[i].bits = 1 << 16; /* mask LVT */ > + > + kvm_set_irqchip(chip); > +} > + > +static void ioapic_pre_save(void *opaque) > +{ > + struct kvm_ioapic_state *s = opaque; > + struct kvm_irqchip *chip; > + > + chip = container_of(s, struct kvm_irqchip, chip.ioapic); > + > + kvm_get_irqchip(chip); > +} > + > +static int ioapic_post_load(void *opaque, int version_id) > +{ > + struct kvm_ioapic_state *s = opaque; > + struct kvm_irqchip *chip; > + > + chip = container_of(s, struct kvm_irqchip, chip.ioapic); > + > + return kvm_set_irqchip(chip); > +} > + > +static const VMStateDescription vmstate_kvm_ioapic = { > + .name = "ioapic-kvm", > + .version_id = 1, > + .minimum_version_id = 1, > + .post_load = ioapic_post_load, > + .pre_save = ioapic_pre_save, > + .fields = (VMStateField []) { > + VMSTATE_U64(base_address, struct kvm_ioapic_state), > + VMSTATE_UINT32(id, struct kvm_ioapic_state), > + VMSTATE_UINT32(ioregsel, struct kvm_ioapic_state), > + VMSTATE_UINT32(irr, struct kvm_ioapic_state), > + VMSTATE_ARRAY_UNSAFE(redirtbl, struct kvm_ioapic_state, IOAPIC_NUM_PINS, 0, vmstate_info_u64, __u64), > + VMSTATE_END_OF_LIST() > + } > +}; > + > + > +static void kvm_ioapic_set_irq(void *opaque, int vector, int level) > +{ > +} > + > +qemu_irq *kvm_ioapic_init(void) > +{ > + struct kvm_irqchip *s; > + > + s = qemu_mallocz(sizeof(*s)); > + > + ioapic_reset(&s->chip.ioapic); > + > + vmstate_register(0, &vmstate_kvm_ioapic, &s->chip.ioapic); > + qemu_register_reset(ioapic_reset, &s->chip.ioapic); > + > + return qemu_allocate_irqs(kvm_ioapic_set_irq, &s->chip.ioapic, IOAPIC_NUM_PINS); > +} > Index: qemu/hw/pc.h > =================================================================== > --- qemu.orig/hw/pc.h > +++ qemu/hw/pc.h > @@ -48,6 +48,8 @@ void ioapic_set_irq(void *opaque, int ve > void apic_reset_irq_delivered(void); > int apic_get_irq_delivered(void); > > +qemu_irq *kvm_ioapic_init(void); > + > /* i8254.c */ > > #define PIT_FREQ 1193182 > Index: qemu/kvm-all.c > =================================================================== > --- qemu.orig/kvm-all.c > +++ qemu/kvm-all.c > @@ -411,6 +411,26 @@ int kvm_check_extension(KVMState *s, uns > 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); > +} > + > +int kvm_get_irqchip(struct kvm_irqchip *chip) > +{ > + if (!kvm_state->irqchip_in_kernel) { > + return 0; > + } > + > + return kvm_vm_ioctl(kvm_state, KVM_GET_IRQCHIP, chip); > +} > +#endif > + > int kvm_init(int smp_cpus) > { > static const char upgrade_note[] = > Index: qemu/kvm.h > =================================================================== > --- qemu.orig/kvm.h > +++ qemu/kvm.h > @@ -16,6 +16,7 @@ > > #include "config.h" > #include "qemu-queue.h" > +#include > > #ifdef CONFIG_KVM > extern int kvm_allowed; > @@ -63,6 +64,9 @@ int kvm_update_guest_debug(CPUState *env > int kvm_pit_in_kernel(void); > int kvm_irqchip_in_kernel(void); > > +int kvm_set_irqchip(struct kvm_irqchip *chip); > +int kvm_get_irqchip(struct kvm_irqchip *chip); > + > /* internal API */ > > struct KVMState;