diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-05 17:47:31 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-05 17:47:31 -0400 |
| commit | 01227a889ed56ae53aeebb9f93be9d54dd8b2de8 (patch) | |
| tree | d5eba9359a9827e84d4112b84d48c54df5c5acde /virt | |
| parent | 9e6879460c8edb0cd3c24c09b83d06541b5af0dc (diff) | |
| parent | db6ae6158186a17165ef990bda2895ae7594b039 (diff) | |
Merge tag 'kvm-3.10-1' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm updates from Gleb Natapov:
"Highlights of the updates are:
general:
- new emulated device API
- legacy device assignment is now optional
- irqfd interface is more generic and can be shared between arches
x86:
- VMCS shadow support and other nested VMX improvements
- APIC virtualization and Posted Interrupt hardware support
- Optimize mmio spte zapping
ppc:
- BookE: in-kernel MPIC emulation with irqfd support
- Book3S: in-kernel XICS emulation (incomplete)
- Book3S: HV: migration fixes
- BookE: more debug support preparation
- BookE: e6500 support
ARM:
- reworking of Hyp idmaps
s390:
- ioeventfd for virtio-ccw
And many other bug fixes, cleanups and improvements"
* tag 'kvm-3.10-1' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (204 commits)
kvm: Add compat_ioctl for device control API
KVM: x86: Account for failing enable_irq_window for NMI window request
KVM: PPC: Book3S: Add API for in-kernel XICS emulation
kvm/ppc/mpic: fix missing unlock in set_base_addr()
kvm/ppc: Hold srcu lock when calling kvm_io_bus_read/write
kvm/ppc/mpic: remove users
kvm/ppc/mpic: fix mmio region lists when multiple guests used
kvm/ppc/mpic: remove default routes from documentation
kvm: KVM_CAP_IOMMU only available with device assignment
ARM: KVM: iterate over all CPUs for CPU compatibility check
KVM: ARM: Fix spelling in error message
ARM: KVM: define KVM_ARM_MAX_VCPUS unconditionally
KVM: ARM: Fix API documentation for ONE_REG encoding
ARM: KVM: promote vfp_host pointer to generic host cpu context
ARM: KVM: add architecture specific hook for capabilities
ARM: KVM: perform HYP initilization for hotplugged CPUs
ARM: KVM: switch to a dual-step HYP init code
ARM: KVM: rework HYP page table freeing
ARM: KVM: enforce maximum size for identity mapped code
ARM: KVM: move to a KVM provided HYP idmap
...
Diffstat (limited to 'virt')
| -rw-r--r-- | virt/kvm/Kconfig | 3 | ||||
| -rw-r--r-- | virt/kvm/assigned-dev.c | 43 | ||||
| -rw-r--r-- | virt/kvm/eventfd.c | 53 | ||||
| -rw-r--r-- | virt/kvm/ioapic.c | 163 | ||||
| -rw-r--r-- | virt/kvm/ioapic.h | 27 | ||||
| -rw-r--r-- | virt/kvm/irq_comm.c | 215 | ||||
| -rw-r--r-- | virt/kvm/irqchip.c | 237 | ||||
| -rw-r--r-- | virt/kvm/kvm_main.c | 258 |
8 files changed, 659 insertions, 340 deletions
diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig index d01b24b72c61..779262f59e25 100644 --- a/virt/kvm/Kconfig +++ b/virt/kvm/Kconfig | |||
| @@ -6,6 +6,9 @@ config HAVE_KVM | |||
| 6 | config HAVE_KVM_IRQCHIP | 6 | config HAVE_KVM_IRQCHIP |
| 7 | bool | 7 | bool |
| 8 | 8 | ||
| 9 | config HAVE_KVM_IRQ_ROUTING | ||
| 10 | bool | ||
| 11 | |||
| 9 | config HAVE_KVM_EVENTFD | 12 | config HAVE_KVM_EVENTFD |
| 10 | bool | 13 | bool |
| 11 | select EVENTFD | 14 | select EVENTFD |
diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c index 3642239252b0..8db43701016f 100644 --- a/virt/kvm/assigned-dev.c +++ b/virt/kvm/assigned-dev.c | |||
| @@ -80,11 +80,12 @@ kvm_assigned_dev_raise_guest_irq(struct kvm_assigned_dev_kernel *assigned_dev, | |||
| 80 | spin_lock(&assigned_dev->intx_mask_lock); | 80 | spin_lock(&assigned_dev->intx_mask_lock); |
| 81 | if (!(assigned_dev->flags & KVM_DEV_ASSIGN_MASK_INTX)) | 81 | if (!(assigned_dev->flags & KVM_DEV_ASSIGN_MASK_INTX)) |
| 82 | kvm_set_irq(assigned_dev->kvm, | 82 | kvm_set_irq(assigned_dev->kvm, |
| 83 | assigned_dev->irq_source_id, vector, 1); | 83 | assigned_dev->irq_source_id, vector, 1, |
| 84 | false); | ||
| 84 | spin_unlock(&assigned_dev->intx_mask_lock); | 85 | spin_unlock(&assigned_dev->intx_mask_lock); |
| 85 | } else | 86 | } else |
| 86 | kvm_set_irq(assigned_dev->kvm, assigned_dev->irq_source_id, | 87 | kvm_set_irq(assigned_dev->kvm, assigned_dev->irq_source_id, |
| 87 | vector, 1); | 88 | vector, 1, false); |
| 88 | } | 89 | } |
| 89 | 90 | ||
| 90 | static irqreturn_t kvm_assigned_dev_thread_intx(int irq, void *dev_id) | 91 | static irqreturn_t kvm_assigned_dev_thread_intx(int irq, void *dev_id) |
| @@ -165,7 +166,7 @@ static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian) | |||
| 165 | container_of(kian, struct kvm_assigned_dev_kernel, | 166 | container_of(kian, struct kvm_assigned_dev_kernel, |
| 166 | ack_notifier); | 167 | ack_notifier); |
| 167 | 168 | ||
| 168 | kvm_set_irq(dev->kvm, dev->irq_source_id, dev->guest_irq, 0); | 169 | kvm_set_irq(dev->kvm, dev->irq_source_id, dev->guest_irq, 0, false); |
| 169 | 170 | ||
| 170 | spin_lock(&dev->intx_mask_lock); | 171 | spin_lock(&dev->intx_mask_lock); |
| 171 | 172 | ||
| @@ -188,7 +189,7 @@ static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian) | |||
| 188 | 189 | ||
| 189 | if (reassert) | 190 | if (reassert) |
| 190 | kvm_set_irq(dev->kvm, dev->irq_source_id, | 191 | kvm_set_irq(dev->kvm, dev->irq_source_id, |
| 191 | dev->guest_irq, 1); | 192 | dev->guest_irq, 1, false); |
| 192 | } | 193 | } |
| 193 | 194 | ||
| 194 | spin_unlock(&dev->intx_mask_lock); | 195 | spin_unlock(&dev->intx_mask_lock); |
| @@ -202,7 +203,7 @@ static void deassign_guest_irq(struct kvm *kvm, | |||
| 202 | &assigned_dev->ack_notifier); | 203 | &assigned_dev->ack_notifier); |
| 203 | 204 | ||
| 204 | kvm_set_irq(assigned_dev->kvm, assigned_dev->irq_source_id, | 205 | kvm_set_irq(assigned_dev->kvm, assigned_dev->irq_source_id, |
| 205 | assigned_dev->guest_irq, 0); | 206 | assigned_dev->guest_irq, 0, false); |
| 206 | 207 | ||
| 207 | if (assigned_dev->irq_source_id != -1) | 208 | if (assigned_dev->irq_source_id != -1) |
| 208 | kvm_free_irq_source_id(kvm, assigned_dev->irq_source_id); | 209 | kvm_free_irq_source_id(kvm, assigned_dev->irq_source_id); |
| @@ -901,7 +902,7 @@ static int kvm_vm_ioctl_set_pci_irq_mask(struct kvm *kvm, | |||
| 901 | if (match->irq_requested_type & KVM_DEV_IRQ_GUEST_INTX) { | 902 | if (match->irq_requested_type & KVM_DEV_IRQ_GUEST_INTX) { |
| 902 | if (assigned_dev->flags & KVM_DEV_ASSIGN_MASK_INTX) { | 903 | if (assigned_dev->flags & KVM_DEV_ASSIGN_MASK_INTX) { |
| 903 | kvm_set_irq(match->kvm, match->irq_source_id, | 904 | kvm_set_irq(match->kvm, match->irq_source_id, |
| 904 | match->guest_irq, 0); | 905 | match->guest_irq, 0, false); |
| 905 | /* | 906 | /* |
| 906 | * Masking at hardware-level is performed on demand, | 907 | * Masking at hardware-level is performed on demand, |
| 907 | * i.e. when an IRQ actually arrives at the host. | 908 | * i.e. when an IRQ actually arrives at the host. |
| @@ -982,36 +983,6 @@ long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, | |||
| 982 | goto out; | 983 | goto out; |
| 983 | break; | 984 | break; |
| 984 | } | 985 | } |
| 985 | #ifdef KVM_CAP_IRQ_ROUTING | ||
| 986 | case KVM_SET_GSI_ROUTING: { | ||
| 987 | struct kvm_irq_routing routing; | ||
| 988 | struct kvm_irq_routing __user *urouting; | ||
| 989 | struct kvm_irq_routing_entry *entries; | ||
| 990 | |||
| 991 | r = -EFAULT; | ||
| 992 | if (copy_from_user(&routing, argp, sizeof(routing))) | ||
| 993 | goto out; | ||
| 994 | r = -EINVAL; | ||
| 995 | if (routing.nr >= KVM_MAX_IRQ_ROUTES) | ||
| 996 | goto out; | ||
| 997 | if (routing.flags) | ||
| 998 | goto out; | ||
| 999 | r = -ENOMEM; | ||
| 1000 | entries = vmalloc(routing.nr * sizeof(*entries)); | ||
| 1001 | if (!entries) | ||
| 1002 | goto out; | ||
| 1003 | r = -EFAULT; | ||
| 1004 | urouting = argp; | ||
| 1005 | if (copy_from_user(entries, urouting->entries, | ||
| 1006 | routing.nr * sizeof(*entries))) | ||
| 1007 | goto out_free_irq_routing; | ||
| 1008 | r = kvm_set_irq_routing(kvm, entries, routing.nr, | ||
| 1009 | routing.flags); | ||
| 1010 | out_free_irq_routing: | ||
| 1011 | vfree(entries); | ||
| 1012 | break; | ||
| 1013 | } | ||
| 1014 | #endif /* KVM_CAP_IRQ_ROUTING */ | ||
| 1015 | #ifdef __KVM_HAVE_MSIX | 986 | #ifdef __KVM_HAVE_MSIX |
| 1016 | case KVM_ASSIGN_SET_MSIX_NR: { | 987 | case KVM_ASSIGN_SET_MSIX_NR: { |
| 1017 | struct kvm_assigned_msix_nr entry_nr; | 988 | struct kvm_assigned_msix_nr entry_nr; |
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index adb17f266b28..64ee720b75c7 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c | |||
| @@ -35,7 +35,7 @@ | |||
| 35 | 35 | ||
| 36 | #include "iodev.h" | 36 | #include "iodev.h" |
| 37 | 37 | ||
| 38 | #ifdef __KVM_HAVE_IOAPIC | 38 | #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING |
| 39 | /* | 39 | /* |
| 40 | * -------------------------------------------------------------------- | 40 | * -------------------------------------------------------------------- |
| 41 | * irqfd: Allows an fd to be used to inject an interrupt to the guest | 41 | * irqfd: Allows an fd to be used to inject an interrupt to the guest |
| @@ -100,11 +100,13 @@ irqfd_inject(struct work_struct *work) | |||
| 100 | struct kvm *kvm = irqfd->kvm; | 100 | struct kvm *kvm = irqfd->kvm; |
| 101 | 101 | ||
| 102 | if (!irqfd->resampler) { | 102 | if (!irqfd->resampler) { |
| 103 | kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi, 1); | 103 | kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi, 1, |
| 104 | kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi, 0); | 104 | false); |
| 105 | kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi, 0, | ||
| 106 | false); | ||
| 105 | } else | 107 | } else |
| 106 | kvm_set_irq(kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID, | 108 | kvm_set_irq(kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID, |
| 107 | irqfd->gsi, 1); | 109 | irqfd->gsi, 1, false); |
| 108 | } | 110 | } |
| 109 | 111 | ||
| 110 | /* | 112 | /* |
| @@ -121,7 +123,7 @@ irqfd_resampler_ack(struct kvm_irq_ack_notifier *kian) | |||
| 121 | resampler = container_of(kian, struct _irqfd_resampler, notifier); | 123 | resampler = container_of(kian, struct _irqfd_resampler, notifier); |
| 122 | 124 | ||
| 123 | kvm_set_irq(resampler->kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID, | 125 | kvm_set_irq(resampler->kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID, |
| 124 | resampler->notifier.gsi, 0); | 126 | resampler->notifier.gsi, 0, false); |
| 125 | 127 | ||
| 126 | rcu_read_lock(); | 128 | rcu_read_lock(); |
| 127 | 129 | ||
| @@ -146,7 +148,7 @@ irqfd_resampler_shutdown(struct _irqfd *irqfd) | |||
| 146 | list_del(&resampler->link); | 148 | list_del(&resampler->link); |
| 147 | kvm_unregister_irq_ack_notifier(kvm, &resampler->notifier); | 149 | kvm_unregister_irq_ack_notifier(kvm, &resampler->notifier); |
| 148 | kvm_set_irq(kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID, | 150 | kvm_set_irq(kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID, |
| 149 | resampler->notifier.gsi, 0); | 151 | resampler->notifier.gsi, 0, false); |
| 150 | kfree(resampler); | 152 | kfree(resampler); |
| 151 | } | 153 | } |
| 152 | 154 | ||
