aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen/events.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/xen/events.c')
-rw-r--r--drivers/xen/events.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index d17aa41a9041..2647ad8e1f19 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -403,11 +403,23 @@ static void unmask_evtchn(int port)
403 403
404 if (unlikely((cpu != cpu_from_evtchn(port)))) 404 if (unlikely((cpu != cpu_from_evtchn(port))))
405 do_hypercall = 1; 405 do_hypercall = 1;
406 else 406 else {
407 /*
408 * Need to clear the mask before checking pending to
409 * avoid a race with an event becoming pending.
410 *
411 * EVTCHNOP_unmask will only trigger an upcall if the
412 * mask bit was set, so if a hypercall is needed
413 * remask the event.
414 */
415 sync_clear_bit(port, BM(&s->evtchn_mask[0]));
407 evtchn_pending = sync_test_bit(port, BM(&s->evtchn_pending[0])); 416 evtchn_pending = sync_test_bit(port, BM(&s->evtchn_pending[0]));
408 417
409 if (unlikely(evtchn_pending && xen_hvm_domain())) 418 if (unlikely(evtchn_pending && xen_hvm_domain())) {
410 do_hypercall = 1; 419 sync_set_bit(port, BM(&s->evtchn_mask[0]));
420 do_hypercall = 1;
421 }
422 }
411 423
412 /* Slow path (hypercall) if this is a non-local port or if this is 424 /* Slow path (hypercall) if this is a non-local port or if this is
413 * an hvm domain and an event is pending (hvm domains don't have 425 * an hvm domain and an event is pending (hvm domains don't have
@@ -418,8 +430,6 @@ static void unmask_evtchn(int port)
418 } else { 430 } else {
419 struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); 431 struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
420 432
421 sync_clear_bit(port, BM(&s->evtchn_mask[0]));
422
423 /* 433 /*
424 * The following is basically the equivalent of 434 * The following is basically the equivalent of
425 * 'hw_resend_irq'. Just like a real IO-APIC we 'lose 435 * 'hw_resend_irq'. Just like a real IO-APIC we 'lose
@@ -1306,7 +1316,7 @@ static void __xen_evtchn_do_upcall(void)
1306{ 1316{
1307 int start_word_idx, start_bit_idx; 1317 int start_word_idx, start_bit_idx;
1308 int word_idx, bit_idx; 1318 int word_idx, bit_idx;
1309 int i; 1319 int i, irq;
1310 int cpu = get_cpu(); 1320 int cpu = get_cpu();
1311 struct shared_info *s = HYPERVISOR_shared_info; 1321 struct shared_info *s = HYPERVISOR_shared_info;
1312 struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); 1322 struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
@@ -1314,6 +1324,8 @@ static void __xen_evtchn_do_upcall(void)
1314 1324
1315 do { 1325 do {
1316 xen_ulong_t pending_words; 1326 xen_ulong_t pending_words;
1327 xen_ulong_t pending_bits;
1328 struct irq_desc *desc;
1317 1329
1318 vcpu_info->evtchn_upcall_pending = 0; 1330 vcpu_info->evtchn_upcall_pending = 0;
1319 1331
@@ -1325,6 +1337,17 @@ static void __xen_evtchn_do_upcall(void)
1325 * selector flag. xchg_xen_ulong must contain an 1337 * selector flag. xchg_xen_ulong must contain an
1326 * appropriate barrier. 1338 * appropriate barrier.
1327 */ 1339 */
1340 if ((irq = per_cpu(virq_to_irq, cpu)[VIRQ_TIMER]) != -1) {
1341 int evtchn = evtchn_from_irq(irq);
1342 word_idx = evtchn / BITS_PER_LONG;
1343 pending_bits = evtchn % BITS_PER_LONG;
1344 if (active_evtchns(cpu, s, word_idx) & (1ULL << pending_bits)) {
1345 desc = irq_to_desc(irq);
1346 if (desc)
1347 generic_handle_irq_desc(irq, desc);
1348 }
1349 }
1350
1328 pending_words = xchg_xen_ulong(&vcpu_info->evtchn_pending_sel, 0); 1351 pending_words = xchg_xen_ulong(&vcpu_info->evtchn_pending_sel, 0);
1329 1352
1330 start_word_idx = __this_cpu_read(current_word_idx); 1353 start_word_idx = __this_cpu_read(current_word_idx);
@@ -1333,7 +1356,6 @@ static void __xen_evtchn_do_upcall(void)
1333 word_idx = start_word_idx; 1356 word_idx = start_word_idx;
1334 1357
1335 for (i = 0; pending_words != 0; i++) { 1358 for (i = 0; pending_words != 0; i++) {
1336 xen_ulong_t pending_bits;
1337 xen_ulong_t words; 1359 xen_ulong_t words;
1338 1360
1339 words = MASK_LSBS(pending_words, word_idx); 1361 words = MASK_LSBS(pending_words, word_idx);
@@ -1362,8 +1384,7 @@ static void __xen_evtchn_do_upcall(void)
1362 1384
1363 do { 1385 do {
1364 xen_ulong_t bits; 1386 xen_ulong_t bits;
1365 int port, irq; 1387 int port;
1366 struct irq_desc *desc;
1367 1388
1368 bits = MASK_LSBS(pending_bits, bit_idx); 1389 bits = MASK_LSBS(pending_bits, bit_idx);
1369 1390