1
+ use crossbeam_channel:: unbounded;
1
2
use kvm_bindings:: {
2
3
kvm_enable_cap, kvm_irq_routing, kvm_irq_routing_entry, kvm_irq_routing_entry__bindgen_ty_1,
3
4
kvm_irq_routing_msi, KVM_CAP_SPLIT_IRQCHIP , KVM_IRQ_ROUTING_MSI ,
@@ -96,14 +97,13 @@ pub struct IoApic {
96
97
version : u8 ,
97
98
irq_eoi : [ i32 ; IOAPIC_NUM_PINS ] ,
98
99
irq_routes : Vec < kvm_irq_routing_entry > ,
99
- irq_sender : crossbeam_channel:: Sender < ( WorkerMessage , EventFd ) > ,
100
- event_fd : EventFd ,
100
+ irq_sender : crossbeam_channel:: Sender < WorkerMessage > ,
101
101
}
102
102
103
103
impl IoApic {
104
104
pub fn new (
105
105
vm : & VmFd ,
106
- _irq_sender : crossbeam_channel:: Sender < ( WorkerMessage , EventFd ) > ,
106
+ _irq_sender : crossbeam_channel:: Sender < WorkerMessage > ,
107
107
) -> Result < Self , Error > {
108
108
let mut cap = kvm_enable_cap {
109
109
cap : KVM_CAP_SPLIT_IRQCHIP ,
@@ -121,7 +121,6 @@ impl IoApic {
121
121
irq_eoi : [ 0 ; IOAPIC_NUM_PINS ] ,
122
122
irq_routes : Vec :: with_capacity ( IOAPIC_NUM_PINS ) ,
123
123
irq_sender : _irq_sender,
124
- event_fd : EventFd :: new ( libc:: EFD_SEMAPHORE ) . unwrap ( ) ,
125
124
} ;
126
125
127
126
( 0 ..IOAPIC_NUM_PINS ) . for_each ( |i| ioapic. add_msi_route ( i) ) ;
@@ -175,14 +174,6 @@ impl IoApic {
175
174
}
176
175
}
177
176
178
- fn send_irq_worker_message ( & self , msg : WorkerMessage ) {
179
- self . irq_sender
180
- . send ( ( msg, self . event_fd . try_clone ( ) . unwrap ( ) ) )
181
- . unwrap ( ) ;
182
-
183
- self . event_fd . read ( ) . unwrap ( ) ;
184
- }
185
-
186
177
fn parse_entry ( & self , entry : & RedirectionTableEntry ) -> IoApicEntryInfo {
187
178
let vector = ( entry & IOAPIC_VECTOR_MASK ) as u8 ;
188
179
let dest_idx = ( ( entry >> IOAPIC_LVT_DEST_IDX_SHIFT ) & 0xffff ) as u16 ;
@@ -249,7 +240,16 @@ impl IoApic {
249
240
}
250
241
}
251
242
252
- self . send_irq_worker_message ( WorkerMessage :: GsiRoute ( self . irq_routes . clone ( ) ) ) ;
243
+ let ( response_sender, response_receiver) = unbounded ( ) ;
244
+ self . irq_sender
245
+ . send ( WorkerMessage :: GsiRoute (
246
+ response_sender. clone ( ) ,
247
+ self . irq_routes . clone ( ) ,
248
+ ) )
249
+ . unwrap ( ) ;
250
+ if !response_receiver. recv ( ) . unwrap ( ) {
251
+ error ! ( "unable to set GSI Routes for IO APIC" ) ;
252
+ }
253
253
}
254
254
255
255
fn service ( & mut self ) {
@@ -273,11 +273,49 @@ impl IoApic {
273
273
continue ;
274
274
}
275
275
276
+ let ( response_sender, response_receiver) = unbounded ( ) ;
276
277
if info. trig_mode as u64 == IOAPIC_TRIGGER_EDGE {
277
- self . send_irq_worker_message ( WorkerMessage :: IrqLine ( i as u32 , true ) ) ;
278
- self . send_irq_worker_message ( WorkerMessage :: IrqLine ( i as u32 , false ) ) ;
278
+ self . irq_sender
279
+ . send ( WorkerMessage :: IrqLine (
280
+ response_sender. clone ( ) ,
281
+ i as u32 ,
282
+ true ,
283
+ ) )
284
+ . unwrap ( ) ;
285
+ if !response_receiver. recv ( ) . unwrap ( ) {
286
+ error ! (
287
+ "unable to set IRQ LINE for IRQ {} with active set to {}" ,
288
+ i, true
289
+ ) ;
290
+ }
291
+
292
+ self . irq_sender
293
+ . send ( WorkerMessage :: IrqLine (
294
+ response_sender. clone ( ) ,
295
+ i as u32 ,
296
+ false ,
297
+ ) )
298
+ . unwrap ( ) ;
299
+ if !response_receiver. recv ( ) . unwrap ( ) {
300
+ error ! (
301
+ "unable to set IRQ LINE for IRQ {} with active set to {}" ,
302
+ i, false
303
+ ) ;
304
+ }
279
305
} else {
280
- self . send_irq_worker_message ( WorkerMessage :: IrqLine ( i as u32 , true ) ) ;
306
+ self . irq_sender
307
+ . send ( WorkerMessage :: IrqLine (
308
+ response_sender. clone ( ) ,
309
+ i as u32 ,
310
+ true ,
311
+ ) )
312
+ . unwrap ( ) ;
313
+ if !response_receiver. recv ( ) . unwrap ( ) {
314
+ error ! (
315
+ "unable to set IRQ LINE for IRQ {} with active set to {}" ,
316
+ i, true
317
+ ) ;
318
+ }
281
319
}
282
320
}
283
321
}
0 commit comments