diff options
author | Avi Kivity <avi@redhat.com> | 2008-11-19 06:58:46 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-03-24 05:03:06 -0400 |
commit | 399ec807ddc38ecccf8c06dbde04531cbdc63e11 (patch) | |
tree | 75a4e3ee9cfffb4ecf7b4608bb592c89f2b62219 /virt/kvm/kvm_main.c | |
parent | 193554750441d91e127dd5066b8aebe0f769101c (diff) |
KVM: Userspace controlled irq routing
Currently KVM has a static routing from GSI numbers to interrupts (namely,
0-15 are mapped 1:1 to both PIC and IOAPIC, and 16:23 are mapped 1:1 to
the IOAPIC). This is insufficient for several reasons:
- HPET requires non 1:1 mapping for the timer interrupt
- MSIs need a new method to assign interrupt numbers and dispatch them
- ACPI APIC mode needs to be able to reassign the PCI LINK interrupts to the
ioapics
This patch implements an interrupt routing table (as a linked list, but this
can be easily changed) and a userspace interface to replace the table. The
routing table is initialized according to the current hardwired mapping.
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r-- | virt/kvm/kvm_main.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 786a3ae373b0..c65484b471c6 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -843,6 +843,7 @@ static struct kvm *kvm_create_vm(void) | |||
843 | if (IS_ERR(kvm)) | 843 | if (IS_ERR(kvm)) |
844 | goto out; | 844 | goto out; |
845 | #ifdef CONFIG_HAVE_KVM_IRQCHIP | 845 | #ifdef CONFIG_HAVE_KVM_IRQCHIP |
846 | INIT_LIST_HEAD(&kvm->irq_routing); | ||
846 | INIT_HLIST_HEAD(&kvm->mask_notifier_list); | 847 | INIT_HLIST_HEAD(&kvm->mask_notifier_list); |
847 | #endif | 848 | #endif |
848 | 849 | ||
@@ -926,6 +927,7 @@ static void kvm_destroy_vm(struct kvm *kvm) | |||
926 | spin_lock(&kvm_lock); | 927 | spin_lock(&kvm_lock); |
927 | list_del(&kvm->vm_list); | 928 | list_del(&kvm->vm_list); |
928 | spin_unlock(&kvm_lock); | 929 | spin_unlock(&kvm_lock); |
930 | kvm_free_irq_routing(kvm); | ||
929 | kvm_io_bus_destroy(&kvm->pio_bus); | 931 | kvm_io_bus_destroy(&kvm->pio_bus); |
930 | kvm_io_bus_destroy(&kvm->mmio_bus); | 932 | kvm_io_bus_destroy(&kvm->mmio_bus); |
931 | #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET | 933 | #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET |
@@ -1946,6 +1948,36 @@ static long kvm_vm_ioctl(struct file *filp, | |||
1946 | break; | 1948 | break; |
1947 | } | 1949 | } |
1948 | #endif | 1950 | #endif |
1951 | #ifdef KVM_CAP_IRQ_ROUTING | ||
1952 | case KVM_SET_GSI_ROUTING: { | ||
1953 | struct kvm_irq_routing routing; | ||
1954 | struct kvm_irq_routing __user *urouting; | ||
1955 | struct kvm_irq_routing_entry *entries; | ||
1956 | |||
1957 | r = -EFAULT; | ||
1958 | if (copy_from_user(&routing, argp, sizeof(routing))) | ||
1959 | goto out; | ||
1960 | r = -EINVAL; | ||
1961 | if (routing.nr >= KVM_MAX_IRQ_ROUTES) | ||
1962 | goto out; | ||
1963 | if (routing.flags) | ||
1964 | goto out; | ||
1965 | r = -ENOMEM; | ||
1966 | entries = vmalloc(routing.nr * sizeof(*entries)); | ||
1967 | if (!entries) | ||
1968 | goto out; | ||
1969 | r = -EFAULT; | ||
1970 | urouting = argp; | ||
1971 | if (copy_from_user(entries, urouting->entries, | ||
1972 | routing.nr * sizeof(*entries))) | ||
1973 | goto out_free_irq_routing; | ||
1974 | r = kvm_set_irq_routing(kvm, entries, routing.nr, | ||
1975 | routing.flags); | ||
1976 | out_free_irq_routing: | ||
1977 | vfree(entries); | ||
1978 | break; | ||
1979 | } | ||
1980 | #endif | ||
1949 | default: | 1981 | default: |
1950 | r = kvm_arch_vm_ioctl(filp, ioctl, arg); | 1982 | r = kvm_arch_vm_ioctl(filp, ioctl, arg); |
1951 | } | 1983 | } |
@@ -2012,6 +2044,10 @@ static long kvm_dev_ioctl_check_extension_generic(long arg) | |||
2012 | case KVM_CAP_USER_MEMORY: | 2044 | case KVM_CAP_USER_MEMORY: |
2013 | case KVM_CAP_DESTROY_MEMORY_REGION_WORKS: | 2045 | case KVM_CAP_DESTROY_MEMORY_REGION_WORKS: |
2014 | return 1; | 2046 | return 1; |
2047 | #ifdef CONFIG_HAVE_KVM_IRQCHIP | ||
2048 | case KVM_CAP_IRQ_ROUTING: | ||
2049 | return 1; | ||
2050 | #endif | ||
2015 | default: | 2051 | default: |
2016 | break; | 2052 | break; |
2017 | } | 2053 | } |