aboutsummaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorEric Auger2015-09-18 09:29:42 -0500
committerPaolo Bonzini2015-10-01 08:06:44 -0500
commit166c9775f1f8b8f00ad1db0fa5c8fc74059d965d (patch)
tree06d78f0f45d69b861ecc3be064469bcee19c2b21 /virt
parent37d9fe4783ffcaddcc4afe67626691e62c5ab30e (diff)
downloadkernel-omap-166c9775f1f8b8f00ad1db0fa5c8fc74059d965d.tar.gz
kernel-omap-166c9775f1f8b8f00ad1db0fa5c8fc74059d965d.tar.xz
kernel-omap-166c9775f1f8b8f00ad1db0fa5c8fc74059d965d.zip
KVM: create kvm_irqfd.h
Move _irqfd_resampler and _irqfd struct declarations in a new public header: kvm_irqfd.h. They are respectively renamed into kvm_kernel_irqfd_resampler and kvm_kernel_irqfd. Those datatypes will be used by architecture specific code, in the context of IRQ bypass manager integration. Signed-off-by: Eric Auger <eric.auger@linaro.org> Signed-off-by: Feng Wu <feng.wu@intel.com> Reviewed-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/eventfd.c95
1 files changed, 23 insertions, 72 deletions
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index ac89299b8699..413f5a6b61ba 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -23,6 +23,7 @@
23 23
24#include <linux/kvm_host.h> 24#include <linux/kvm_host.h>
25#include <linux/kvm.h> 25#include <linux/kvm.h>
26#include <linux/kvm_irqfd.h>
26#include <linux/workqueue.h> 27#include <linux/workqueue.h>
27#include <linux/syscalls.h> 28#include <linux/syscalls.h>
28#include <linux/wait.h> 29#include <linux/wait.h>
@@ -39,68 +40,14 @@
39#include <kvm/iodev.h> 40#include <kvm/iodev.h>
40 41
41#ifdef CONFIG_HAVE_KVM_IRQFD 42#ifdef CONFIG_HAVE_KVM_IRQFD
42/*
43 * --------------------------------------------------------------------
44 * irqfd: Allows an fd to be used to inject an interrupt to the guest
45 *
46 * Credit goes to Avi Kivity for the original idea.
47 * --------------------------------------------------------------------
48 */
49
50/*
51 * Resampling irqfds are a special variety of irqfds used to emulate
52 * level triggered interrupts. The interrupt is asserted on eventfd
53 * trigger. On acknowledgement through the irq ack notifier, the
54 * interrupt is de-asserted and userspace is notified through the
55 * resamplefd. All resamplers on the same gsi are de-asserted
56 * together, so we don't need to track the state of each individual
57 * user. We can also therefore share the same irq source ID.
58 */
59struct _irqfd_resampler {
60 struct kvm *kvm;
61 /*
62 * List of resampling struct _irqfd objects sharing this gsi.
63 * RCU list modified under kvm->irqfds.resampler_lock
64 */
65 struct list_head list;
66 struct kvm_irq_ack_notifier notifier;
67 /*
68 * Entry in list of kvm->irqfd.resampler_list. Use for sharing
69 * resamplers among irqfds on the same gsi.
70 * Accessed and modified under kvm->irqfds.resampler_lock
71 */
72 struct list_head link;
73};
74
75struct _irqfd {
76 /* Used for MSI fast-path */
77 struct kvm *kvm;
78 wait_queue_t wait;
79 /* Update side is protected by irqfds.lock */
80 struct kvm_kernel_irq_routing_entry irq_entry;
81 seqcount_t irq_entry_sc;
82 /* Used for level IRQ fast-path */
83 int gsi;
84 struct work_struct inject;
85 /* The resampler used by this irqfd (resampler-only) */
86 struct _irqfd_resampler *resampler;
87 /* Eventfd notified on resample (resampler-only) */
88 struct eventfd_ctx *resamplefd;
89 /* Entry in list of irqfds for a resampler (resampler-only) */
90 struct list_head resampler_link;
91 /* Used for setup/shutdown */
92 struct eventfd_ctx *eventfd;
93 struct list_head list;
94 poll_table pt;
95 struct work_struct shutdown;
96};
97 43
98static struct workqueue_struct *irqfd_cleanup_wq; 44static struct workqueue_struct *irqfd_cleanup_wq;
99 45
100static void 46static void
101irqfd_inject(struct work_struct *work) 47irqfd_inject(struct work_struct *work)
102{ 48{
103 struct _irqfd *irqfd = container_of(work, struct _irqfd, inject); 49 struct kvm_kernel_irqfd *irqfd =
50 container_of(work, struct kvm_kernel_irqfd, inject);
104 struct kvm *kvm = irqfd->kvm; 51 struct kvm *kvm = irqfd->kvm;
105 52
106 if (!irqfd->resampler) { 53 if (!irqfd->resampler) {
@@ -121,12 +68,13 @@ irqfd_inject(struct work_struct *work)
121static void 68static void
122irqfd_resampler_ack(struct kvm_irq_ack_notifier *kian) 69irqfd_resampler_ack(struct kvm_irq_ack_notifier *kian)
123{ 70{
124 struct _irqfd_resampler *resampler; 71 struct kvm_kernel_irqfd_resampler *resampler;
125 struct kvm *kvm; 72 struct kvm *kvm;
126 struct _irqfd *irqfd; 73 struct kvm_kernel_irqfd *irqfd;
127 int idx; 74 int idx;
128 75
129 resampler = container_of(kian, struct _irqfd_resampler, notifier); 76 resampler = container_of(kian,
77 struct kvm_kernel_irqfd_resampler, notifier);
130 kvm = resampler->kvm; 78 kvm = resampler->kvm;
131 79
132 kvm_set_irq(kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID, 80 kvm_set_irq(kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID,
@@ -141,9 +89,9 @@ irqfd_resampler_ack(struct kvm_irq_ack_notifier *kian)
141} 89}
142 90
143static void 91static void
144irqfd_resampler_shutdown(struct _irqfd *irqfd) 92irqfd_resampler_shutdown(struct kvm_kernel_irqfd *irqfd)
145{ 93{
146 struct _irqfd_resampler *resampler = irqfd->resampler; 94 struct kvm_kernel_irqfd_resampler *resampler = irqfd->resampler;
147 struct kvm *kvm = resampler->kvm; 95 struct kvm *kvm = resampler->kvm;
148 96
149 mutex_lock(&kvm->irqfds.resampler_lock); 97 mutex_lock(&kvm->irqfds.resampler_lock);
@@ -168,7 +116,8 @@ irqfd_resampler_shutdown(struct _irqfd *irqfd)
168static void 116static void
169irqfd_shutdown(struct work_struct *work) 117irqfd_shutdown(struct work_struct *work)
170{ 118{
171 struct _irqfd *irqfd = container_of(work, struct _irqfd, shutdown); 119 struct kvm_kernel_irqfd *irqfd =
120 container_of(work, struct kvm_kernel_irqfd, shutdown);
172 u64 cnt; 121 u64 cnt;
173 122
174 /* 123 /*
@@ -198,7 +147,7 @@ irqfd_shutdown(struct work_struct *work)
198 147
199/* assumes kvm->irqfds.lock is held */ 148/* assumes kvm->irqfds.lock is held */
200static bool 149static bool
201irqfd_is_active(struct _irqfd *irqfd) 150irqfd_is_active(struct kvm_kernel_irqfd *irqfd)
202{ 151{
203 return list_empty(&irqfd->list) ? false : true; 152 return list_empty(&irqfd->list) ? false : true;
204} 153}
@@ -209,7 +158,7 @@ irqfd_is_active(struct _irqfd *irqfd)
209 * assumes kvm->irqfds.lock is held 158 * assumes kvm->irqfds.lock is held
210 */ 159 */
211static void 160static void
212irqfd_deactivate(struct _irqfd *irqfd) 161irqfd_deactivate(struct kvm_kernel_irqfd *irqfd)
213{ 162{
214 BUG_ON(!irqfd_is_active(irqfd)); 163 BUG_ON(!irqfd_is_active(irqfd));
215 164
@@ -224,7 +173,8 @@ irqfd_deactivate(struct _irqfd *irqfd)
224static int 173static int
225irqfd_wakeup(wait_queue_t *wait, unsigned mode, int sync, void *key) 174irqfd_wakeup(wait_queue_t *wait, unsigned mode, int sync, void *key)
226{ 175{
227 struct _irqfd *irqfd = container_of(wait, struct _irqfd, wait); 176 struct kvm_kernel_irqfd *irqfd =
177 container_of(wait, struct kvm_kernel_irqfd, wait);
228 unsigned long flags = (unsigned long)key; 178 unsigned long flags = (unsigned long)key;
229 struct kvm_kernel_irq_routing_entry irq; 179 struct kvm_kernel_irq_routing_entry irq;
230 struct kvm *kvm = irqfd->kvm; 180 struct kvm *kvm = irqfd->kvm;
@@ -274,12 +224,13 @@ static void
274irqfd_ptable_queue_proc(struct file *file, wait_queue_head_t *wqh, 224irqfd_ptable_queue_proc(struct file *file, wait_queue_head_t *wqh,
275 poll_table *pt) 225 poll_table *pt)
276{ 226{
277 struct _irqfd *irqfd = container_of(pt, struct _irqfd, pt); 227 struct kvm_kernel_irqfd *irqfd =
228 container_of(pt, struct kvm_kernel_irqfd, pt);
278 add_wait_queue(wqh, &irqfd->wait); 229 add_wait_queue(wqh, &irqfd->wait);
279} 230}
280 231
281/* Must be called under irqfds.lock */ 232/* Must be called under irqfds.lock */
282static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd) 233static void irqfd_update(struct kvm *kvm, struct kvm_kernel_irqfd *irqfd)
283{ 234{
284 struct kvm_kernel_irq_routing_entry *e; 235 struct kvm_kernel_irq_routing_entry *e;
285 struct kvm_kernel_irq_routing_entry entries[KVM_NR_IRQCHIPS]; 236 struct kvm_kernel_irq_routing_entry entries[KVM_NR_IRQCHIPS];
@@ -304,7 +255,7 @@ static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd)
304static int 255static int
305kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args) 256kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
306{ 257{
307 struct _irqfd *irqfd, *tmp; 258 struct kvm_kernel_irqfd *irqfd, *tmp;
308 struct fd f; 259 struct fd f;
309 struct eventfd_ctx *eventfd = NULL, *resamplefd = NULL; 260 struct eventfd_ctx *eventfd = NULL, *resamplefd = NULL;
310 int ret; 261 int ret;
@@ -340,7 +291,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
340 irqfd->eventfd = eventfd; 291 irqfd->eventfd = eventfd;
341 292
342 if (args->flags & KVM_IRQFD_FLAG_RESAMPLE) { 293 if (args->flags & KVM_IRQFD_FLAG_RESAMPLE) {
343 struct _irqfd_resampler *resampler; 294 struct kvm_kernel_irqfd_resampler *resampler;
344 295
345 resamplefd = eventfd_ctx_fdget(args->resamplefd); 296 resamplefd = eventfd_ctx_fdget(args->resamplefd);
346 if (IS_ERR(resamplefd)) { 297 if (IS_ERR(resamplefd)) {
@@ -525,7 +476,7 @@ kvm_eventfd_init(struct kvm *kvm)
525static int 476static int
526kvm_irqfd_deassign(struct kvm *kvm, struct kvm_irqfd *args) 477kvm_irqfd_deassign(struct kvm *kvm, struct kvm_irqfd *args)
527{ 478{
528 struct _irqfd *irqfd, *tmp; 479 struct kvm_kernel_irqfd *irqfd, *tmp;
529 struct eventfd_ctx *eventfd; 480 struct eventfd_ctx *eventfd;
530 481
531 eventfd = eventfd_ctx_fdget(args->fd); 482 eventfd = eventfd_ctx_fdget(args->fd);
@@ -581,7 +532,7 @@ kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args)
581void 532void
582kvm_irqfd_release(struct kvm *kvm) 533kvm_irqfd_release(struct kvm *kvm)
583{ 534{
584 struct _irqfd *irqfd, *tmp; 535 struct kvm_kernel_irqfd *irqfd, *tmp;
585 536
586 spin_lock_irq(&kvm->irqfds.lock); 537 spin_lock_irq(&kvm->irqfds.lock);
587 538
@@ -604,7 +555,7 @@ kvm_irqfd_release(struct kvm *kvm)
604 */ 555 */
605void kvm_irq_routing_update(struct kvm *kvm) 556void kvm_irq_routing_update(struct kvm *kvm)
606{ 557{
607 struct _irqfd *irqfd; 558 struct kvm_kernel_irqfd *irqfd;
608 559
609 spin_lock_irq(&kvm->irqfds.lock); 560 spin_lock_irq(&kvm->irqfds.lock);
610 561