diff options
| -rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 54 |
1 files changed, 12 insertions, 42 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 8eb863e27ea6..f88af6b037c2 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
| @@ -2267,6 +2267,9 @@ ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, | |||
| 2267 | * updated vector information), by using a virtual vector (io-apic pin number). | 2267 | * updated vector information), by using a virtual vector (io-apic pin number). |
| 2268 | * Real vector that is used for interrupting cpu will be coming from | 2268 | * Real vector that is used for interrupting cpu will be coming from |
| 2269 | * the interrupt-remapping table entry. | 2269 | * the interrupt-remapping table entry. |
| 2270 | * | ||
| 2271 | * As the migration is a simple atomic update of IRTE, the same mechanism | ||
| 2272 | * is used to migrate MSI irq's in the presence of interrupt-remapping. | ||
| 2270 | */ | 2273 | */ |
| 2271 | static int | 2274 | static int |
| 2272 | ir_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, | 2275 | ir_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, |
| @@ -2291,10 +2294,16 @@ ir_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, | |||
| 2291 | irte.dest_id = IRTE_DEST(dest); | 2294 | irte.dest_id = IRTE_DEST(dest); |
| 2292 | 2295 | ||
| 2293 | /* | 2296 | /* |
| 2294 | * Modified the IRTE and flushes the Interrupt entry cache. | 2297 | * Atomically updates the IRTE with the new destination, vector |
| 2298 | * and flushes the interrupt entry cache. | ||
| 2295 | */ | 2299 | */ |
| 2296 | modify_irte(irq, &irte); | 2300 | modify_irte(irq, &irte); |
| 2297 | 2301 | ||
| 2302 | /* | ||
| 2303 | * After this point, all the interrupts will start arriving | ||
| 2304 | * at the new destination. So, time to cleanup the previous | ||
| 2305 | * vector allocation. | ||
| 2306 | */ | ||
| 2298 | if (cfg->move_in_progress) | 2307 | if (cfg->move_in_progress) |
| 2299 | send_cleanup_vector(cfg); | 2308 | send_cleanup_vector(cfg); |
| 2300 | 2309 | ||
| @@ -3144,45 +3153,6 @@ msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) | |||
| 3144 | 3153 | ||
| 3145 | return 0; | 3154 | return 0; |
| 3146 | } | 3155 | } |
| 3147 | #ifdef CONFIG_INTR_REMAP | ||
| 3148 | /* | ||
| 3149 | * Migrate the MSI irq to another cpumask. This migration is | ||
| 3150 | * done in the process context using interrupt-remapping hardware. | ||
| 3151 | */ | ||
| 3152 | static int | ||
| 3153 | ir_msi_set_affinity(struct irq_data *data, const struct cpumask *mask, | ||
| 3154 | bool force) | ||
| 3155 | { | ||
| 3156 | struct irq_cfg *cfg = data->chip_data; | ||
| 3157 | unsigned int dest, irq = data->irq; | ||
| 3158 | struct irte irte; | ||
| 3159 | |||
| 3160 | if (get_irte(irq, &irte)) | ||
| 3161 | return -1; | ||
| 3162 | |||
| 3163 | if (__ioapic_set_affinity(data, mask, &dest)) | ||
| 3164 | return -1; | ||
| 3165 | |||
| 3166 | irte.vector = cfg->vector; | ||
| 3167 | irte.dest_id = IRTE_DEST(dest); | ||
| 3168 | |||
| 3169 | /* | ||
| 3170 | * atomically update the IRTE with the new destination and vector. | ||
| 3171 | */ | ||
| 3172 | modify_irte(irq, &irte); | ||
| 3173 | |||
| 3174 | /* | ||
| 3175 | * After this point, all the interrupts will start arriving | ||
| 3176 | * at the new destination. So, time to cleanup the previous | ||
| 3177 | * vector allocation. | ||
| 3178 | */ | ||
| 3179 | if (cfg->move_in_progress) | ||
| 3180 | send_cleanup_vector(cfg); | ||
| 3181 | |||
| 3182 | return 0; | ||
| 3183 | } | ||
| 3184 | |||
| 3185 | #endif | ||
| 3186 | #endif /* CONFIG_SMP */ | 3156 | #endif /* CONFIG_SMP */ |
| 3187 | 3157 | ||
| 3188 | /* | 3158 | /* |
| @@ -3207,7 +3177,7 @@ static struct irq_chip msi_ir_chip = { | |||
| 3207 | #ifdef CONFIG_INTR_REMAP | 3177 | #ifdef CONFIG_INTR_REMAP |
| 3208 | .irq_ack = ir_ack_apic_edge, | 3178 | .irq_ack = ir_ack_apic_edge, |
| 3209 | #ifdef CONFIG_SMP | 3179 | #ifdef CONFIG_SMP |
| 3210 | .irq_set_affinity = ir_msi_set_affinity, | 3180 | .irq_set_affinity = ir_ioapic_set_affinity, |
| 3211 | #endif | 3181 | #endif |
| 3212 | #endif | 3182 | #endif |
| 3213 | .irq_retrigger = ioapic_retrigger_irq, | 3183 | .irq_retrigger = ioapic_retrigger_irq, |
| @@ -3416,7 +3386,7 @@ static struct irq_chip ir_hpet_msi_type = { | |||
| 3416 | #ifdef CONFIG_INTR_REMAP | 3386 | #ifdef CONFIG_INTR_REMAP |
| 3417 | .irq_ack = ir_ack_apic_edge, | 3387 | .irq_ack = ir_ack_apic_edge, |
| 3418 | #ifdef CONFIG_SMP | 3388 | #ifdef CONFIG_SMP |
| 3419 | .irq_set_affinity = ir_msi_set_affinity, | 3389 | .irq_set_affinity = ir_ioapic_set_affinity, |
| 3420 | #endif | 3390 | #endif |
| 3421 | #endif | 3391 | #endif |
| 3422 | .irq_retrigger = ioapic_retrigger_irq, | 3392 | .irq_retrigger = ioapic_retrigger_irq, |
