diff options
author | Ben Guthro <ben@guthro.net> | 2012-04-20 12:11:04 -0400 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-05-07 15:33:15 -0400 |
commit | f447d56d36af18c5104ff29dcb1327c0c0ac3634 (patch) | |
tree | e83fe645cd0241714a027b1f42897217eee0f3b0 /arch/x86/xen/smp.c | |
parent | 569ca5b3f94cd0b3295ec5943aa457cf4a4f6a3a (diff) |
xen: implement apic ipi interface
Map native ipi vector to xen vector.
Implement apic ipi interface with xen_send_IPI_one.
Tested-by: Steven Noonan <steven@uplinklabs.net>
Signed-off-by: Ben Guthro <ben@guthro.net>
Signed-off-by: Lin Ming <mlin@ss.pku.edu.cn>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'arch/x86/xen/smp.c')
-rw-r--r-- | arch/x86/xen/smp.c | 81 |
1 files changed, 77 insertions, 4 deletions
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 5fac6919b957..2dc6628c1520 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c | |||
@@ -465,8 +465,8 @@ static void xen_smp_send_reschedule(int cpu) | |||
465 | xen_send_IPI_one(cpu, XEN_RESCHEDULE_VECTOR); | 465 | xen_send_IPI_one(cpu, XEN_RESCHEDULE_VECTOR); |
466 | } | 466 | } |
467 | 467 | ||
468 | static void xen_send_IPI_mask(const struct cpumask *mask, | 468 | static void __xen_send_IPI_mask(const struct cpumask *mask, |
469 | enum ipi_vector vector) | 469 | int vector) |
470 | { | 470 | { |
471 | unsigned cpu; | 471 | unsigned cpu; |
472 | 472 | ||
@@ -478,7 +478,7 @@ static void xen_smp_send_call_function_ipi(const struct cpumask *mask) | |||
478 | { | 478 | { |
479 | int cpu; | 479 | int cpu; |
480 | 480 | ||
481 | xen_send_IPI_mask(mask, XEN_CALL_FUNCTION_VECTOR); | 481 | __xen_send_IPI_mask(mask, XEN_CALL_FUNCTION_VECTOR); |
482 | 482 | ||
483 | /* Make sure other vcpus get a chance to run if they need to. */ | 483 | /* Make sure other vcpus get a chance to run if they need to. */ |
484 | for_each_cpu(cpu, mask) { | 484 | for_each_cpu(cpu, mask) { |
@@ -491,10 +491,83 @@ static void xen_smp_send_call_function_ipi(const struct cpumask *mask) | |||
491 | 491 | ||
492 | static void xen_smp_send_call_function_single_ipi(int cpu) | 492 | static void xen_smp_send_call_function_single_ipi(int cpu) |
493 | { | 493 | { |
494 | xen_send_IPI_mask(cpumask_of(cpu), | 494 | __xen_send_IPI_mask(cpumask_of(cpu), |
495 | XEN_CALL_FUNCTION_SINGLE_VECTOR); | 495 | XEN_CALL_FUNCTION_SINGLE_VECTOR); |
496 | } | 496 | } |
497 | 497 | ||
498 | static inline int xen_map_vector(int vector) | ||
499 | { | ||
500 | int xen_vector; | ||
501 | |||
502 | switch (vector) { | ||
503 | case RESCHEDULE_VECTOR: | ||
504 | xen_vector = XEN_RESCHEDULE_VECTOR; | ||
505 | break; | ||
506 | case CALL_FUNCTION_VECTOR: | ||
507 | xen_vector = XEN_CALL_FUNCTION_VECTOR; | ||
508 | break; | ||
509 | case CALL_FUNCTION_SINGLE_VECTOR: | ||
510 | xen_vector = XEN_CALL_FUNCTION_SINGLE_VECTOR; | ||
511 | break; | ||
512 | default: | ||
513 | xen_vector = -1; | ||
514 | printk(KERN_ERR "xen: vector 0x%x is not implemented\n", | ||
515 | vector); | ||
516 | } | ||
517 | |||
518 | return xen_vector; | ||
519 | } | ||
520 | |||
521 | void xen_send_IPI_mask(const struct cpumask *mask, | ||
522 | int vector) | ||
523 | { | ||
524 | int xen_vector = xen_map_vector(vector); | ||
525 | |||
526 | if (xen_vector >= 0) | ||
527 | __xen_send_IPI_mask(mask, xen_vector); | ||
528 | } | ||
529 | |||
530 | void xen_send_IPI_all(int vector) | ||
531 | { | ||
532 | int xen_vector = xen_map_vector(vector); | ||
533 | |||
534 | if (xen_vector >= 0) | ||
535 | __xen_send_IPI_mask(cpu_online_mask, xen_vector); | ||
536 | } | ||
537 | |||
538 | void xen_send_IPI_self(int vector) | ||
539 | { | ||
540 | int xen_vector = xen_map_vector(vector); | ||
541 | |||
542 | if (xen_vector >= 0) | ||
543 | xen_send_IPI_one(smp_processor_id(), xen_vector); | ||
544 | } | ||
545 | |||
546 | void xen_send_IPI_mask_allbutself(const struct cpumask *mask, | ||
547 | int vector) | ||
548 | { | ||
549 | unsigned cpu; | ||
550 | unsigned int this_cpu = smp_processor_id(); | ||
551 | |||
552 | if (!(num_online_cpus() > 1)) | ||
553 | return; | ||
554 | |||
555 | for_each_cpu_and(cpu, mask, cpu_online_mask) { | ||
556 | if (this_cpu == cpu) | ||
557 | continue; | ||
558 | |||
559 | xen_smp_send_call_function_single_ipi(cpu); | ||
560 | } | ||
561 | } | ||
562 | |||
563 | void xen_send_IPI_allbutself(int vector) | ||
564 | { | ||
565 | int xen_vector = xen_map_vector(vector); | ||
566 | |||
567 | if (xen_vector >= 0) | ||
568 | xen_send_IPI_mask_allbutself(cpu_online_mask, xen_vector); | ||
569 | } | ||
570 | |||
498 | static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id) | 571 | static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id) |
499 | { | 572 | { |
500 | irq_enter(); | 573 | irq_enter(); |