aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/kernel/genapic_flat.c23
-rw-r--r--include/asm-x86_64/ipi.h54
2 files changed, 33 insertions, 44 deletions
diff --git a/arch/x86_64/kernel/genapic_flat.c b/arch/x86_64/kernel/genapic_flat.c
index 9e0a552f0e4a..01d3939e3a9c 100644
--- a/arch/x86_64/kernel/genapic_flat.c
+++ b/arch/x86_64/kernel/genapic_flat.c
@@ -61,31 +61,10 @@ static void flat_init_apic_ldr(void)
61static void flat_send_IPI_mask(cpumask_t cpumask, int vector) 61static void flat_send_IPI_mask(cpumask_t cpumask, int vector)
62{ 62{
63 unsigned long mask = cpus_addr(cpumask)[0]; 63 unsigned long mask = cpus_addr(cpumask)[0];
64 unsigned long cfg;
65 unsigned long flags; 64 unsigned long flags;
66 65
67 local_irq_save(flags); 66 local_irq_save(flags);
68 67 __send_IPI_dest_field(mask, vector, APIC_DEST_LOGICAL);
69 /*
70 * Wait for idle.
71 */
72 apic_wait_icr_idle();
73
74 /*
75 * prepare target chip field
76 */
77 cfg = __prepare_ICR2(mask);
78 apic_write(APIC_ICR2, cfg);
79
80 /*
81 * program the ICR
82 */
83 cfg = __prepare_ICR(0, vector, APIC_DEST_LOGICAL);
84
85 /*
86 * Send the IPI. The write to APIC_ICR fires this off.
87 */
88 apic_write(APIC_ICR, cfg);
89 local_irq_restore(flags); 68 local_irq_restore(flags);
90} 69}
91 70
diff --git a/include/asm-x86_64/ipi.h b/include/asm-x86_64/ipi.h
index ffa6f1517f1a..26961e671948 100644
--- a/include/asm-x86_64/ipi.h
+++ b/include/asm-x86_64/ipi.h
@@ -74,10 +74,39 @@ static inline void __send_IPI_shortcut(unsigned int shortcut, int vector, unsign
74 apic_write(APIC_ICR, cfg); 74 apic_write(APIC_ICR, cfg);
75} 75}
76 76
77/*
78 * This is used to send an IPI with no shorthand notation (the destination is
79 * specified in bits 56 to 63 of the ICR).
80 */
81static inline void __send_IPI_dest_field(unsigned int mask, int vector, unsigned int dest)
82{
83 unsigned long cfg;
84
85 /*
86 * Wait for idle.
87 */
88 apic_wait_icr_idle();
89
90 /*
91 * prepare target chip field
92 */
93 cfg = __prepare_ICR2(mask);
94 apic_write(APIC_ICR2, cfg);
95
96 /*
97 * program the ICR
98 */
99 cfg = __prepare_ICR(0, vector, dest);
100
101 /*
102 * Send the IPI. The write to APIC_ICR fires this off.
103 */
104 apic_write(APIC_ICR, cfg);
105}
77 106
78static inline void send_IPI_mask_sequence(cpumask_t mask, int vector) 107static inline void send_IPI_mask_sequence(cpumask_t mask, int vector)
79{ 108{
80 unsigned long cfg, flags; 109 unsigned long flags;
81 unsigned long query_cpu; 110 unsigned long query_cpu;
82 111
83 /* 112 /*
@@ -86,28 +115,9 @@ static inline void send_IPI_mask_sequence(cpumask_t mask, int vector)
86 * - mbligh 115 * - mbligh
87 */ 116 */
88 local_irq_save(flags); 117 local_irq_save(flags);
89
90 for_each_cpu_mask(query_cpu, mask) { 118 for_each_cpu_mask(query_cpu, mask) {
91 /* 119 __send_IPI_dest_field(x86_cpu_to_apicid[query_cpu],
92 * Wait for idle. 120 vector, APIC_DEST_PHYSICAL);
93 */
94 apic_wait_icr_idle();
95
96 /*
97 * prepare target chip field
98 */
99 cfg = __prepare_ICR2(x86_cpu_to_apicid[query_cpu]);
100 apic_write(APIC_ICR2, cfg);
101
102 /*
103 * program the ICR
104 */
105 cfg = __prepare_ICR(0, vector, APIC_DEST_PHYSICAL);
106
107 /*
108 * Send the IPI. The write to APIC_ICR fires this off.
109 */
110 apic_write(APIC_ICR, cfg);
111 } 121 }
112 local_irq_restore(flags); 122 local_irq_restore(flags);
113} 123}