diff options
-rw-r--r-- | Documentation/virtual/kvm/api.txt | 17 | ||||
-rw-r--r-- | arch/x86/kvm/mmu.c | 3 | ||||
-rw-r--r-- | include/linux/kvm_host.h | 4 | ||||
-rw-r--r-- | virt/kvm/eventfd.c | 23 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 3 |
5 files changed, 37 insertions, 13 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 930126698a0f..2c9948379469 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt | |||
@@ -1930,6 +1930,23 @@ The "pte_enc" field provides a value that can OR'ed into the hash | |||
1930 | PTE's RPN field (ie, it needs to be shifted left by 12 to OR it | 1930 | PTE's RPN field (ie, it needs to be shifted left by 12 to OR it |
1931 | into the hash PTE second double word). | 1931 | into the hash PTE second double word). |
1932 | 1932 | ||
1933 | 4.75 KVM_IRQFD | ||
1934 | |||
1935 | Capability: KVM_CAP_IRQFD | ||
1936 | Architectures: x86 | ||
1937 | Type: vm ioctl | ||
1938 | Parameters: struct kvm_irqfd (in) | ||
1939 | Returns: 0 on success, -1 on error | ||
1940 | |||
1941 | Allows setting an eventfd to directly trigger a guest interrupt. | ||
1942 | kvm_irqfd.fd specifies the file descriptor to use as the eventfd and | ||
1943 | kvm_irqfd.gsi specifies the irqchip pin toggled by this event. When | ||
1944 | an event is tiggered on the eventfd, an interrupt is injected into | ||
1945 | the guest using the specified gsi pin. The irqfd is removed using | ||
1946 | the KVM_IRQFD_FLAG_DEASSIGN flag, specifying both kvm_irqfd.fd | ||
1947 | and kvm_irqfd.gsi. | ||
1948 | |||
1949 | |||
1933 | 5. The kvm_run structure | 1950 | 5. The kvm_run structure |
1934 | ------------------------ | 1951 | ------------------------ |
1935 | 1952 | ||
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index be3cea4407ff..57e168e27b5b 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -3934,6 +3934,9 @@ static void kvm_mmu_remove_some_alloc_mmu_pages(struct kvm *kvm, | |||
3934 | { | 3934 | { |
3935 | struct kvm_mmu_page *page; | 3935 | struct kvm_mmu_page *page; |
3936 | 3936 | ||
3937 | if (list_empty(&kvm->arch.active_mmu_pages)) | ||
3938 | return; | ||
3939 | |||
3937 | page = container_of(kvm->arch.active_mmu_pages.prev, | 3940 | page = container_of(kvm->arch.active_mmu_pages.prev, |
3938 | struct kvm_mmu_page, link); | 3941 | struct kvm_mmu_page, link); |
3939 | kvm_mmu_prepare_zap_page(kvm, page, invalid_list); | 3942 | kvm_mmu_prepare_zap_page(kvm, page, invalid_list); |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index c4464356b35b..96c158a37d3e 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
@@ -815,7 +815,7 @@ static inline void kvm_free_irq_routing(struct kvm *kvm) {} | |||
815 | #ifdef CONFIG_HAVE_KVM_EVENTFD | 815 | #ifdef CONFIG_HAVE_KVM_EVENTFD |
816 | 816 | ||
817 | void kvm_eventfd_init(struct kvm *kvm); | 817 | void kvm_eventfd_init(struct kvm *kvm); |
818 | int kvm_irqfd(struct kvm *kvm, int fd, int gsi, int flags); | 818 | int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args); |
819 | void kvm_irqfd_release(struct kvm *kvm); | 819 | void kvm_irqfd_release(struct kvm *kvm); |
820 | void kvm_irq_routing_update(struct kvm *, struct kvm_irq_routing_table *); | 820 | void kvm_irq_routing_update(struct kvm *, struct kvm_irq_routing_table *); |
821 | int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args); | 821 | int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args); |
@@ -824,7 +824,7 @@ int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args); | |||
824 | 824 | ||
825 | static inline void kvm_eventfd_init(struct kvm *kvm) {} | 825 | static inline void kvm_eventfd_init(struct kvm *kvm) {} |
826 | 826 | ||
827 | static inline int kvm_irqfd(struct kvm *kvm, int fd, int gsi, int flags) | 827 | static inline int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args) |
828 | { | 828 | { |
829 | return -EINVAL; | 829 | return -EINVAL; |
830 | } | 830 | } |
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index f59c1e8de7a2..7d7e2aaffece 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c | |||
@@ -198,7 +198,7 @@ static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd, | |||
198 | } | 198 | } |
199 | 199 | ||
200 | static int | 200 | static int |
201 | kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi) | 201 | kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args) |
202 | { | 202 | { |
203 | struct kvm_irq_routing_table *irq_rt; | 203 | struct kvm_irq_routing_table *irq_rt; |
204 | struct _irqfd *irqfd, *tmp; | 204 | struct _irqfd *irqfd, *tmp; |
@@ -212,12 +212,12 @@ kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi) | |||
212 | return -ENOMEM; | 212 | return -ENOMEM; |
213 | 213 | ||
214 | irqfd->kvm = kvm; | 214 | irqfd->kvm = kvm; |
215 | irqfd->gsi = gsi; | 215 | irqfd->gsi = args->gsi; |
216 | INIT_LIST_HEAD(&irqfd->list); | 216 | INIT_LIST_HEAD(&irqfd->list); |
217 | INIT_WORK(&irqfd->inject, irqfd_inject); | 217 | INIT_WORK(&irqfd->inject, irqfd_inject); |
218 | INIT_WORK(&irqfd->shutdown, irqfd_shutdown); | 218 | INIT_WORK(&irqfd->shutdown, irqfd_shutdown); |
219 | 219 | ||
220 | file = eventfd_fget(fd); | 220 | file = eventfd_fget(args->fd); |
221 | if (IS_ERR(file)) { | 221 | if (IS_ERR(file)) { |
222 | ret = PTR_ERR(file); | 222 | ret = PTR_ERR(file); |
223 | goto fail; | 223 | goto fail; |
@@ -298,19 +298,19 @@ kvm_eventfd_init(struct kvm *kvm) | |||
298 | * shutdown any irqfd's that match fd+gsi | 298 | * shutdown any irqfd's that match fd+gsi |
299 | */ | 299 | */ |
300 | static int | 300 | static int |
301 | kvm_irqfd_deassign(struct kvm *kvm, int fd, int gsi) | 301 | kvm_irqfd_deassign(struct kvm *kvm, struct kvm_irqfd *args) |
302 | { | 302 | { |
303 | struct _irqfd *irqfd, *tmp; | 303 | struct _irqfd *irqfd, *tmp; |
304 | struct eventfd_ctx *eventfd; | 304 | struct eventfd_ctx *eventfd; |
305 | 305 | ||
306 | eventfd = eventfd_ctx_fdget(fd); | 306 | eventfd = eventfd_ctx_fdget(args->fd); |
307 | if (IS_ERR(eventfd)) | 307 | if (IS_ERR(eventfd)) |
308 | return PTR_ERR(eventfd); | 308 | return PTR_ERR(eventfd); |
309 | 309 | ||
310 | spin_lock_irq(&kvm->irqfds.lock); | 310 | spin_lock_irq(&kvm->irqfds.lock); |
311 | 311 | ||
312 | list_for_each_entry_safe(irqfd, tmp, &kvm->irqfds.items, list) { | 312 | list_for_each_entry_safe(irqfd, tmp, &kvm->irqfds.items, list) { |
313 | if (irqfd->eventfd == eventfd && irqfd->gsi == gsi) { | 313 | if (irqfd->eventfd == eventfd && irqfd->gsi == args->gsi) { |
314 | /* | 314 | /* |
315 | * This rcu_assign_pointer is needed for when | 315 | * This rcu_assign_pointer is needed for when |
316 | * another thread calls kvm_irq_routing_update before | 316 | * another thread calls kvm_irq_routing_update before |
@@ -338,12 +338,15 @@ kvm_irqfd_deassign(struct kvm *kvm, int fd, int gsi) | |||
338 | } | 338 | } |
339 | 339 | ||
340 | int | 340 | int |
341 | kvm_irqfd(struct kvm *kvm, int fd, int gsi, int flags) | 341 | kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args) |
342 | { | 342 | { |
343 | if (flags & KVM_IRQFD_FLAG_DEASSIGN) | 343 | if (args->flags & ~KVM_IRQFD_FLAG_DEASSIGN) |
344 | return kvm_irqfd_deassign(kvm, fd, gsi); | 344 | return -EINVAL; |
345 | |||
346 | if (args->flags & KVM_IRQFD_FLAG_DEASSIGN) | ||
347 | return kvm_irqfd_deassign(kvm, args); | ||
345 | 348 | ||
346 | return kvm_irqfd_assign(kvm, fd, gsi); | 349 | return kvm_irqfd_assign(kvm, args); |
347 | } | 350 | } |
348 | 351 | ||
349 | /* | 352 | /* |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 7e140683ff14..44ee7124b16d 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -2047,7 +2047,7 @@ static long kvm_vm_ioctl(struct file *filp, | |||
2047 | r = -EFAULT; | 2047 | r = -EFAULT; |
2048 | if (copy_from_user(&data, argp, sizeof data)) | 2048 | if (copy_from_user(&data, argp, sizeof data)) |
2049 | goto out; | 2049 | goto out; |
2050 | r = kvm_irqfd(kvm, data.fd, data.gsi, data.flags); | 2050 | r = kvm_irqfd(kvm, &data); |
2051 | break; | 2051 | break; |
2052 | } | 2052 | } |
2053 | case KVM_IOEVENTFD: { | 2053 | case KVM_IOEVENTFD: { |
@@ -2845,6 +2845,7 @@ void kvm_exit(void) | |||
2845 | kvm_arch_hardware_unsetup(); | 2845 | kvm_arch_hardware_unsetup(); |
2846 | kvm_arch_exit(); | 2846 | kvm_arch_exit(); |
2847 | free_cpumask_var(cpus_hardware_enabled); | 2847 | free_cpumask_var(cpus_hardware_enabled); |
2848 | __free_page(fault_page); | ||
2848 | __free_page(hwpoison_page); | 2849 | __free_page(hwpoison_page); |
2849 | __free_page(bad_page); | 2850 | __free_page(bad_page); |
2850 | } | 2851 | } |