Hi Sasha, On Thu, Jul 28, 2011 at 12:01 PM, Sasha Levin <levinsasha928@xxxxxxxxx> wrote: > Map GSIs manually when starting the guest. > This will allow us mapping new GSIs for MSIX in the future. > > Signed-off-by: Sasha Levin <levinsasha928@xxxxxxxxx> > --- > tools/kvm/builtin-run.c | 3 ++ > tools/kvm/include/kvm/irq.h | 3 ++ > tools/kvm/irq.c | 75 +++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 81 insertions(+), 0 deletions(-) > > diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c > index 941129c..f9c3e7e 100644 > --- a/tools/kvm/builtin-run.c > +++ b/tools/kvm/builtin-run.c > @@ -35,6 +35,7 @@ > #include <kvm/vnc.h> > #include <kvm/sdl.h> > #include <kvm/framebuffer.h> > +#include <kvm/irq.h> > > /* header files for gitish interface */ > #include <kvm/builtin-run.h> > @@ -573,6 +574,8 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix) > > kvm = kvm__init(kvm_dev, ram_size, guest_name); > > + irq__init(); > + > kvm->single_step = single_step; > > ioeventfd__init(); > diff --git a/tools/kvm/include/kvm/irq.h b/tools/kvm/include/kvm/irq.h > index 7a75a0c..2f00b18 100644 > --- a/tools/kvm/include/kvm/irq.h > +++ b/tools/kvm/include/kvm/irq.h > @@ -21,4 +21,7 @@ int irq__register_device(u32 dev, u8 *num, u8 *pin, u8 *line); > > struct rb_node *irq__get_pci_tree(void); > > +void irq__init(void); > +u32 irq__add_msix_route(u32 low, u32 high, u32 data); > + > #endif > diff --git a/tools/kvm/irq.c b/tools/kvm/irq.c > index 15f4702..fc5d800 100644 > --- a/tools/kvm/irq.c > +++ b/tools/kvm/irq.c > @@ -1,16 +1,47 @@ > #include "kvm/irq.h" > +#include "kvm/kvm.h" > +#include "kvm/util.h" > > #include <linux/types.h> > #include <linux/rbtree.h> > #include <linux/list.h> > +#include <linux/kvm.h> > +#include <sys/ioctl.h> > > #include <stddef.h> > #include <stdlib.h> > > +#define IRQ_MAX_GSI 64 > +#define IRQCHIP_MASTER 0 > +#define IRQCHIP_SLAVE 1 > +#define IRQCHIP_IOAPIC 2 > + > static u8 next_line = 3; > static u8 next_dev = 1; > static struct rb_root pci_tree = RB_ROOT; > > +/* First 24 GSIs are routed between IRQCHIPs and IOAPICs */ > +static u32 gsi = 24; > + > +extern struct kvm *kvm; I'd prefer you actually pass this as an argument to irq__init() and irq__add_msix_route(). > + > +struct kvm_irq_routing *irq_routing; > + > +static int irq__add_routing(u32 gsi, u32 type, u32 irqchip, u32 pin) > +{ > + if (gsi >= IRQ_MAX_GSI) > + return -ENOSPC; EINVAL is more appropriate, I think. > + > + irq_routing->entries[irq_routing->nr++] = (struct kvm_irq_routing_entry) { > + .gsi = gsi, > + .type = type, > + .u.irqchip.irqchip = irqchip, > + .u.irqchip.pin = pin, Please indent the assignments. > + }; > + > + return 0; > +} > + > static struct pci_dev *search(struct rb_root *root, u32 id) > { > struct rb_node *node = root->rb_node; > @@ -106,6 +137,50 @@ int irq__register_device(u32 dev, u8 *num, u8 *pin, u8 *line) > return -1; > } > > +void irq__init(void) > +{ > + int i, r; > + > + irq_routing = malloc(sizeof(struct kvm_irq_routing) + > + IRQ_MAX_GSI * sizeof(struct kvm_irq_routing_entry)); We usually die() on out-of-memory. Maybe it doesn't make sense here. Dunno. > + > + /* Hook first 8 GSIs to master IRQCHIP */ > + for (i = 0; i < 8; i++) > + irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_MASTER, i); > + > + /* Hook next 8 GSIs to slave IRQCHIP */ > + for (i = 8; i < 16; i++) > + irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_SLAVE, 8-i); > + > + /* Last but not least, IOAPIC */ > + for (i = 0; i < 24; i++) { > + if (i == 0) > + irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_IOAPIC, 2); > + else > + irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_IOAPIC, i); > + } > + > + r = ioctl(kvm->vm_fd, KVM_SET_GSI_ROUTING, irq_routing); > + if (r) > + die("Failed setting GSI routes"); > +} > + > +u32 irq__add_msix_route(u32 low, u32 high, u32 data) > +{ > + irq_routing->entries[irq_routing->nr++] = (struct kvm_irq_routing_entry) { > + .gsi = gsi, > + .type = KVM_IRQ_ROUTING_MSI, > + .u.msi.address_lo = low, > + .u.msi.address_hi = high, > + .u.msi.data = data, Please indent the assignments. > + }; > + > + if (ioctl(kvm->vm_fd, KVM_SET_GSI_ROUTING, irq_routing)) > + return -1; How will that work when we have 'u32' as the return value type? > + > + return gsi++; > +} > + > struct rb_node *irq__get_pci_tree(void) > { > return rb_first(&pci_tree); > -- > 1.7.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 > -- 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