@@ -55,7 +55,7 @@ static const char *vfio_pci_irq_names[] = {
55
55
Device::Device (const std::string &name, int groupFileDescriptor,
56
56
const kernel::devices::PciDevice *pci_device)
57
57
: name(name), fd(-1 ), attachedToGroup(false ), groupFd(groupFileDescriptor),
58
- info(), irqs (), regions(), mappings(), pci_device(pci_device),
58
+ info(), info_irq_vectors (), regions(), mappings(), pci_device(pci_device),
59
59
log(Log::get(" kernel:vfio:device" )) {
60
60
if (groupFileDescriptor < 0 )
61
61
throw RuntimeError (" Invalid group file descriptor" );
@@ -81,7 +81,7 @@ Device::Device(const std::string &name, int groupFileDescriptor,
81
81
info.num_regions = pci_device != 0 ? VFIO_PCI_CONFIG_REGION_INDEX + 1 : 1 ;
82
82
83
83
// Reserve slots already so that we can use the []-operator for access
84
- irqs .resize (info.num_irqs );
84
+ info_irq_vectors .resize (info.num_irqs );
85
85
regions.resize (info.num_regions );
86
86
mappings.resize (info.num_regions );
87
87
@@ -120,7 +120,7 @@ Device::Device(const std::string &name, int groupFileDescriptor,
120
120
log ->debug (" irq {} info: flags: 0x{:x}, count: {}" , irq.index , irq.flags ,
121
121
irq.count );
122
122
123
- irqs [i] = irq;
123
+ info_irq_vectors [i] = irq;
124
124
}
125
125
}
126
126
@@ -212,7 +212,7 @@ void Device::dump() {
212
212
}
213
213
214
214
for (size_t i = 0 ; i < info.num_irqs ; i++) {
215
- struct vfio_irq_info *irq = &irqs [i];
215
+ struct vfio_irq_info *irq = &info_irq_vectors [i];
216
216
217
217
if (irq->count > 0 ) {
218
218
log ->info (" IRQ {} {}: count={}, flags={}" , irq->index ,
@@ -247,12 +247,57 @@ bool Device::pciEnable() {
247
247
return true ;
248
248
}
249
249
250
+ std::vector<Device::IrqVectorInfo> Device::initEventFds () {
251
+ std::vector<Device::IrqVectorInfo> vectors;
252
+ for (auto info_irq_vector : info_irq_vectors) {
253
+ Device::IrqVectorInfo irq = {0 };
254
+ const size_t irqCount = info_irq_vector.count ;
255
+ const size_t irqSetSize =
256
+ sizeof (struct vfio_irq_set ) + sizeof (int ) * irqCount;
257
+
258
+ auto *irqSetBuf = new char [irqSetSize];
259
+ if (!irqSetBuf)
260
+ throw MemoryAllocationError ();
261
+ auto *irqSet = reinterpret_cast <struct vfio_irq_set *>(irqSetBuf);
262
+
263
+ irqSet->argsz = irqSetSize;
264
+ // DATA_EVENTFD binds the interrupt to the provided eventfd.
265
+ // SET_ACTION_TRIGGER enables kernel->userspace signalling.
266
+ irqSet->flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER;
267
+ irqSet->index = info_irq_vector.index ;
268
+ irqSet->start = 0 ;
269
+ irqSet->count = irqCount;
270
+ irq.automask = info_irq_vector.flags & VFIO_IRQ_INFO_AUTOMASKED;
271
+ irq.numFds = irqCount;
272
+ // Now set the new eventfds
273
+ for (size_t i = 0 ; i < irqCount; i++) {
274
+ irq.eventFds [i] = eventfd (0 , 0 );
275
+ if (fd < 0 ) {
276
+ delete[] irqSetBuf;
277
+ throw std::runtime_error (" Event FD could not be created." );
278
+ }
279
+ eventfdList.push_back (fd);
280
+ }
281
+
282
+ memcpy (irqSet->data , irq.eventFds , sizeof (int ) * irqCount);
283
+
284
+ if (ioctl (fd, VFIO_DEVICE_SET_IRQS, irqSet) != 0 ) {
285
+ delete[] irqSetBuf;
286
+ throw std::runtime_error (" failed to set irqs" );
287
+ }
288
+ delete[] irqSetBuf;
289
+ vectors.push_back (irq);
290
+ }
291
+
292
+ return vectors;
293
+ }
294
+
250
295
int Device::pciMsiInit (int efds[]) {
251
296
// Check if this is really a vfio-pci device
252
297
if (not isVfioPciDevice ())
253
298
return -1 ;
254
299
255
- const size_t irqCount = irqs [VFIO_PCI_MSI_IRQ_INDEX].count ;
300
+ const size_t irqCount = info_irq_vectors [VFIO_PCI_MSI_IRQ_INDEX].count ;
256
301
const size_t irqSetSize =
257
302
sizeof (struct vfio_irq_set ) + sizeof (int ) * irqCount;
258
303
@@ -299,7 +344,7 @@ int Device::pciMsiDeinit(int efds[]) {
299
344
if (not isVfioPciDevice ())
300
345
return -1 ;
301
346
302
- const size_t irqCount = irqs [VFIO_PCI_MSI_IRQ_INDEX].count ;
347
+ const size_t irqCount = info_irq_vectors [VFIO_PCI_MSI_IRQ_INDEX].count ;
303
348
const size_t irqSetSize =
304
349
sizeof (struct vfio_irq_set ) + sizeof (int ) * irqCount;
305
350
0 commit comments