Skip to content

Commit 166c977

Browse files
Eric Augerbonzini
authored andcommitted
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 <[email protected]> Signed-off-by: Feng Wu <[email protected]> Reviewed-by: Alex Williamson <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 37d9fe4 commit 166c977

File tree

2 files changed

+92
-72
lines changed

2 files changed

+92
-72
lines changed

include/linux/kvm_irqfd.h

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* This program is free software; you can redistribute it and/or modify
3+
* it under the terms of the GNU General Public License as published by
4+
* the Free Software Foundation; either version 2 of the License.
5+
*
6+
* This program is distributed in the hope that it will be useful,
7+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
8+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9+
* GNU General Public License for more details.
10+
*
11+
* irqfd: Allows an fd to be used to inject an interrupt to the guest
12+
* Credit goes to Avi Kivity for the original idea.
13+
*/
14+
15+
#ifndef __LINUX_KVM_IRQFD_H
16+
#define __LINUX_KVM_IRQFD_H
17+
18+
#include <linux/kvm_host.h>
19+
#include <linux/poll.h>
20+
21+
/*
22+
* Resampling irqfds are a special variety of irqfds used to emulate
23+
* level triggered interrupts. The interrupt is asserted on eventfd
24+
* trigger. On acknowledgment through the irq ack notifier, the
25+
* interrupt is de-asserted and userspace is notified through the
26+
* resamplefd. All resamplers on the same gsi are de-asserted
27+
* together, so we don't need to track the state of each individual
28+
* user. We can also therefore share the same irq source ID.
29+
*/
30+
struct kvm_kernel_irqfd_resampler {
31+
struct kvm *kvm;
32+
/*
33+
* List of resampling struct _irqfd objects sharing this gsi.
34+
* RCU list modified under kvm->irqfds.resampler_lock
35+
*/
36+
struct list_head list;
37+
struct kvm_irq_ack_notifier notifier;
38+
/*
39+
* Entry in list of kvm->irqfd.resampler_list. Use for sharing
40+
* resamplers among irqfds on the same gsi.
41+
* Accessed and modified under kvm->irqfds.resampler_lock
42+
*/
43+
struct list_head link;
44+
};
45+
46+
struct kvm_kernel_irqfd {
47+
/* Used for MSI fast-path */
48+
struct kvm *kvm;
49+
wait_queue_t wait;
50+
/* Update side is protected by irqfds.lock */
51+
struct kvm_kernel_irq_routing_entry irq_entry;
52+
seqcount_t irq_entry_sc;
53+
/* Used for level IRQ fast-path */
54+
int gsi;
55+
struct work_struct inject;
56+
/* The resampler used by this irqfd (resampler-only) */
57+
struct kvm_kernel_irqfd_resampler *resampler;
58+
/* Eventfd notified on resample (resampler-only) */
59+
struct eventfd_ctx *resamplefd;
60+
/* Entry in list of irqfds for a resampler (resampler-only) */
61+
struct list_head resampler_link;
62+
/* Used for setup/shutdown */
63+
struct eventfd_ctx *eventfd;
64+
struct list_head list;
65+
poll_table pt;
66+
struct work_struct shutdown;
67+
};
68+
69+
#endif /* __LINUX_KVM_IRQFD_H */

virt/kvm/eventfd.c

Lines changed: 23 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include <linux/kvm_host.h>
2525
#include <linux/kvm.h>
26+
#include <linux/kvm_irqfd.h>
2627
#include <linux/workqueue.h>
2728
#include <linux/syscalls.h>
2829
#include <linux/wait.h>
@@ -39,68 +40,14 @@
3940
#include <kvm/iodev.h>
4041

4142
#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-
*/
59-
struct _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-
75-
struct _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-
};
9743

9844
static struct workqueue_struct *irqfd_cleanup_wq;
9945

10046
static void
10147
irqfd_inject(struct work_struct *work)
10248
{
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);
10451
struct kvm *kvm = irqfd->kvm;
10552

10653
if (!irqfd->resampler) {
@@ -121,12 +68,13 @@ irqfd_inject(struct work_struct *work)
12168
static void
12269
irqfd_resampler_ack(struct kvm_irq_ack_notifier *kian)
12370
{
124-
struct _irqfd_resampler *resampler;
71+
struct kvm_kernel_irqfd_resampler *resampler;
12572
struct kvm *kvm;
126-
struct _irqfd *irqfd;
73+
struct kvm_kernel_irqfd *irqfd;
12774
int idx;
12875

129-
resampler = container_of(kian, struct _irqfd_resampler, notifier);
76+
resampler = container_of(kian,
77+
struct kvm_kernel_irqfd_resampler, notifier);
13078
kvm = resampler->kvm;
13179

13280
kvm_set_irq(kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID,
@@ -141,9 +89,9 @@ irqfd_resampler_ack(struct kvm_irq_ack_notifier *kian)
14189
}
14290

14391
static void
144-
irqfd_resampler_shutdown(struct _irqfd *irqfd)
92+
irqfd_resampler_shutdown(struct kvm_kernel_irqfd *irqfd)
14593
{
146-
struct _irqfd_resampler *resampler = irqfd->resampler;
94+
struct kvm_kernel_irqfd_resampler *resampler = irqfd->resampler;
14795
struct kvm *kvm = resampler->kvm;
14896

14997
mutex_lock(&kvm->irqfds.resampler_lock);
@@ -168,7 +116,8 @@ irqfd_resampler_shutdown(struct _irqfd *irqfd)
168116
static void
169117
irqfd_shutdown(struct work_struct *work)
170118
{
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);
172121
u64 cnt;
173122

174123
/*
@@ -198,7 +147,7 @@ irqfd_shutdown(struct work_struct *work)
198147

199148
/* assumes kvm->irqfds.lock is held */
200149
static bool
201-
irqfd_is_active(struct _irqfd *irqfd)
150+
irqfd_is_active(struct kvm_kernel_irqfd *irqfd)
202151
{
203152
return list_empty(&irqfd->list) ? false : true;
204153
}
@@ -209,7 +158,7 @@ irqfd_is_active(struct _irqfd *irqfd)
209158
* assumes kvm->irqfds.lock is held
210159
*/
211160
static void
212-
irqfd_deactivate(struct _irqfd *irqfd)
161+
irqfd_deactivate(struct kvm_kernel_irqfd *irqfd)
213162
{
214163
BUG_ON(!irqfd_is_active(irqfd));
215164

@@ -224,7 +173,8 @@ irqfd_deactivate(struct _irqfd *irqfd)
224173
static int
225174
irqfd_wakeup(wait_queue_t *wait, unsigned mode, int sync, void *key)
226175
{
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);
228178
unsigned long flags = (unsigned long)key;
229179
struct kvm_kernel_irq_routing_entry irq;
230180
struct kvm *kvm = irqfd->kvm;
@@ -274,12 +224,13 @@ static void
274224
irqfd_ptable_queue_proc(struct file *file, wait_queue_head_t *wqh,
275225
poll_table *pt)
276226
{
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);
278229
add_wait_queue(wqh, &irqfd->wait);
279230
}
280231

281232
/* Must be called under irqfds.lock */
282-
static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd)
233+
static void irqfd_update(struct kvm *kvm, struct kvm_kernel_irqfd *irqfd)
283234
{
284235
struct kvm_kernel_irq_routing_entry *e;
285236
struct kvm_kernel_irq_routing_entry entries[KVM_NR_IRQCHIPS];
@@ -304,7 +255,7 @@ static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd)
304255
static int
305256
kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
306257
{
307-
struct _irqfd *irqfd, *tmp;
258+
struct kvm_kernel_irqfd *irqfd, *tmp;
308259
struct fd f;
309260
struct eventfd_ctx *eventfd = NULL, *resamplefd = NULL;
310261
int ret;
@@ -340,7 +291,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
340291
irqfd->eventfd = eventfd;
341292

342293
if (args->flags & KVM_IRQFD_FLAG_RESAMPLE) {
343-
struct _irqfd_resampler *resampler;
294+
struct kvm_kernel_irqfd_resampler *resampler;
344295

345296
resamplefd = eventfd_ctx_fdget(args->resamplefd);
346297
if (IS_ERR(resamplefd)) {
@@ -525,7 +476,7 @@ kvm_eventfd_init(struct kvm *kvm)
525476
static int
526477
kvm_irqfd_deassign(struct kvm *kvm, struct kvm_irqfd *args)
527478
{
528-
struct _irqfd *irqfd, *tmp;
479+
struct kvm_kernel_irqfd *irqfd, *tmp;
529480
struct eventfd_ctx *eventfd;
530481

531482
eventfd = eventfd_ctx_fdget(args->fd);
@@ -581,7 +532,7 @@ kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args)
581532
void
582533
kvm_irqfd_release(struct kvm *kvm)
583534
{
584-
struct _irqfd *irqfd, *tmp;
535+
struct kvm_kernel_irqfd *irqfd, *tmp;
585536

586537
spin_lock_irq(&kvm->irqfds.lock);
587538

@@ -604,7 +555,7 @@ kvm_irqfd_release(struct kvm *kvm)
604555
*/
605556
void kvm_irq_routing_update(struct kvm *kvm)
606557
{
607-
struct _irqfd *irqfd;
558+
struct kvm_kernel_irqfd *irqfd;
608559

609560
spin_lock_irq(&kvm->irqfds.lock);
610561

0 commit comments

Comments
 (0)