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 | |
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')
-rw-r--r-- | arch/x86/xen/enlighten.c | 9 | ||||
-rw-r--r-- | arch/x86/xen/smp.c | 81 | ||||
-rw-r--r-- | arch/x86/xen/smp.h | 12 |
3 files changed, 98 insertions, 4 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 4f51bebac02c..1ed61c2bf633 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -74,6 +74,7 @@ | |||
74 | 74 | ||
75 | #include "xen-ops.h" | 75 | #include "xen-ops.h" |
76 | #include "mmu.h" | 76 | #include "mmu.h" |
77 | #include "smp.h" | ||
77 | #include "multicalls.h" | 78 | #include "multicalls.h" |
78 | 79 | ||
79 | EXPORT_SYMBOL_GPL(hypercall_page); | 80 | EXPORT_SYMBOL_GPL(hypercall_page); |
@@ -849,6 +850,14 @@ static void set_xen_basic_apic_ops(void) | |||
849 | apic->icr_write = xen_apic_icr_write; | 850 | apic->icr_write = xen_apic_icr_write; |
850 | apic->wait_icr_idle = xen_apic_wait_icr_idle; | 851 | apic->wait_icr_idle = xen_apic_wait_icr_idle; |
851 | apic->safe_wait_icr_idle = xen_safe_apic_wait_icr_idle; | 852 | apic->safe_wait_icr_idle = xen_safe_apic_wait_icr_idle; |
853 | |||
854 | #ifdef CONFIG_SMP | ||
855 | apic->send_IPI_allbutself = xen_send_IPI_allbutself; | ||
856 | apic->send_IPI_mask_allbutself = xen_send_IPI_mask_allbutself; | ||
857 | apic->send_IPI_mask = xen_send_IPI_mask; | ||
858 | apic->send_IPI_all = xen_send_IPI_all; | ||
859 | apic->send_IPI_self = xen_send_IPI_self; | ||
860 | #endif | ||
852 | } | 861 | } |
853 | 862 | ||
854 | #endif | 863 | #endif |
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(); |
diff --git a/arch/x86/xen/smp.h b/arch/x86/xen/smp.h new file mode 100644 index 000000000000..8981a76d081a --- /dev/null +++ b/arch/x86/xen/smp.h | |||
@@ -0,0 +1,12 @@ | |||
1 | #ifndef _XEN_SMP_H | ||
2 | |||
3 | extern void xen_send_IPI_mask(const struct cpumask *mask, | ||
4 | int vector); | ||
5 | extern void xen_send_IPI_mask_allbutself(const struct cpumask *mask, | ||
6 | int vector); | ||
7 | extern void xen_send_IPI_allbutself(int vector); | ||
8 | extern void physflat_send_IPI_allbutself(int vector); | ||
9 | extern void xen_send_IPI_all(int vector); | ||
10 | extern void xen_send_IPI_self(int vector); | ||
11 | |||
12 | #endif | ||