diff options
-rw-r--r-- | arch/x86_64/kernel/genapic_flat.c | 23 | ||||
-rw-r--r-- | include/asm-x86_64/ipi.h | 54 |
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) | |||
61 | static void flat_send_IPI_mask(cpumask_t cpumask, int vector) | 61 | static 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 | */ | ||
81 | static 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 | ||
78 | static inline void send_IPI_mask_sequence(cpumask_t mask, int vector) | 107 | static 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 | } |