aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorBen Guthro <ben@guthro.net>2012-04-20 12:11:04 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2012-05-07 15:33:15 -0400
commitf447d56d36af18c5104ff29dcb1327c0c0ac3634 (patch)
treee83fe645cd0241714a027b1f42897217eee0f3b0 /arch
parent569ca5b3f94cd0b3295ec5943aa457cf4a4f6a3a (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.c9
-rw-r--r--arch/x86/xen/smp.c81
-rw-r--r--arch/x86/xen/smp.h12
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
79EXPORT_SYMBOL_GPL(hypercall_page); 80EXPORT_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
468static void xen_send_IPI_mask(const struct cpumask *mask, 468static 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
492static void xen_smp_send_call_function_single_ipi(int cpu) 492static 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
498static 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
521void 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
530void 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
538void 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
546void 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
563void 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
498static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id) 571static 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
3extern void xen_send_IPI_mask(const struct cpumask *mask,
4 int vector);
5extern void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
6 int vector);
7extern void xen_send_IPI_allbutself(int vector);
8extern void physflat_send_IPI_allbutself(int vector);
9extern void xen_send_IPI_all(int vector);
10extern void xen_send_IPI_self(int vector);
11
12#endif