Hi Sasha,
On Thu, Jul 28, 2011 at 12:01 PM, Sasha Levin <[email protected]> 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 <[email protected]>
> ---
> 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 [email protected]
> 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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html