8 #include <linux/kernel.h>
10 #include <linux/types.h>
12 #include "kvm/ioeventfd.h"
16 #define IOEVENTFD_MAX_EVENTS 20
18 static struct epoll_event events
[IOEVENTFD_MAX_EVENTS
];
20 static LIST_HEAD(used_ioevents
);
22 void ioeventfd__init(void)
24 epoll_fd
= epoll_create(IOEVENTFD_MAX_EVENTS
);
26 die("Failed creating epoll fd");
29 void ioeventfd__add_event(struct ioevent
*ioevent
)
31 struct kvm_ioeventfd kvm_ioevent
;
32 struct epoll_event epoll_event
;
33 struct ioevent
*new_ioevent
;
36 new_ioevent
= malloc(sizeof(*new_ioevent
));
37 if (new_ioevent
== NULL
)
38 die("Failed allocating memory for new ioevent");
40 *new_ioevent
= *ioevent
;
41 event
= new_ioevent
->fd
;
43 kvm_ioevent
= (struct kvm_ioeventfd
) {
44 .addr
= ioevent
->io_addr
,
45 .len
= ioevent
->io_len
,
46 .datamatch
= ioevent
->datamatch
,
48 .flags
= KVM_IOEVENTFD_FLAG_PIO
| KVM_IOEVENTFD_FLAG_DATAMATCH
,
51 if (ioctl(ioevent
->fn_kvm
->vm_fd
, KVM_IOEVENTFD
, &kvm_ioevent
) != 0)
52 die("Failed creating new ioeventfd");
54 epoll_event
= (struct epoll_event
) {
56 .data
.ptr
= new_ioevent
,
59 if (epoll_ctl(epoll_fd
, EPOLL_CTL_ADD
, event
, &epoll_event
) != 0)
60 die("Failed assigning new event to the epoll fd");
62 list_add_tail(&new_ioevent
->list
, &used_ioevents
);
65 void ioeventfd__del_event(u64 addr
, u64 datamatch
)
67 struct kvm_ioeventfd kvm_ioevent
;
68 struct ioevent
*ioevent
;
71 list_for_each_entry(ioevent
, &used_ioevents
, list
) {
72 if (ioevent
->io_addr
== addr
) {
78 if (found
== 0 || ioevent
== NULL
)
81 kvm_ioevent
= (struct kvm_ioeventfd
) {
82 .addr
= ioevent
->io_addr
,
83 .len
= ioevent
->io_len
,
84 .datamatch
= ioevent
->datamatch
,
85 .flags
= KVM_IOEVENTFD_FLAG_PIO
86 | KVM_IOEVENTFD_FLAG_DEASSIGN
87 | KVM_IOEVENTFD_FLAG_DATAMATCH
,
90 ioctl(ioevent
->fn_kvm
->vm_fd
, KVM_IOEVENTFD
, &kvm_ioevent
);
92 epoll_ctl(epoll_fd
, EPOLL_CTL_DEL
, ioevent
->fd
, NULL
);
94 list_del(&ioevent
->list
);
100 static void *ioeventfd__thread(void *param
)
105 nfds
= epoll_wait(epoll_fd
, events
, IOEVENTFD_MAX_EVENTS
, -1);
106 for (i
= 0; i
< nfds
; i
++) {
108 struct ioevent
*ioevent
;
110 ioevent
= events
[i
].data
.ptr
;
112 if (read(ioevent
->fd
, &tmp
, sizeof(tmp
)) < 0)
113 die("Failed reading event");
115 ioevent
->fn(ioevent
->fn_kvm
, ioevent
->fn_ptr
);
122 void ioeventfd__start(void)
126 if (pthread_create(&thread
, NULL
, ioeventfd__thread
, NULL
) != 0)
127 die("Failed starting ioeventfd thread");