aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/apic/io_apic.c180
-rw-r--r--drivers/iommu/intel_irq_remapping.c7
-rw-r--r--drivers/iommu/irq_remapping.c5
-rw-r--r--drivers/iommu/irq_remapping.h2
-rw-r--r--include/linux/irq.h2
5 files changed, 86 insertions, 110 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 7cbd397884f5..a951ef7decb1 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2224,81 +2224,6 @@ void send_cleanup_vector(struct irq_cfg *cfg)
2224 cfg->move_in_progress = 0; 2224 cfg->move_in_progress = 0;
2225} 2225}
2226 2226
2227static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg)
2228{
2229 int apic, pin;
2230 struct irq_pin_list *entry;
2231 u8 vector = cfg->vector;
2232
2233 for_each_irq_pin(entry, cfg->irq_2_pin) {
2234 unsigned int reg;
2235
2236 apic = entry->apic;
2237 pin = entry->pin;
2238 /*
2239 * With interrupt-remapping, destination information comes
2240 * from interrupt-remapping table entry.
2241 */
2242 if (!irq_remapped(cfg))
2243 io_apic_write(apic, 0x11 + pin*2, dest);
2244 reg = io_apic_read(apic, 0x10 + pin*2);
2245 reg &= ~IO_APIC_REDIR_VECTOR_MASK;
2246 reg |= vector;
2247 io_apic_modify(apic, 0x10 + pin*2, reg);
2248 }
2249}
2250
2251/*
2252 * Either sets data->affinity to a valid value, and returns
2253 * ->cpu_mask_to_apicid of that in dest_id, or returns -1 and
2254 * leaves data->affinity untouched.
2255 */
2256int __ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
2257 unsigned int *dest_id)
2258{
2259 struct irq_cfg *cfg = data->chip_data;
2260 unsigned int irq = data->irq;
2261 int err;
2262
2263 if (!cpumask_intersects(mask, cpu_online_mask))
2264 return -EINVAL;
2265
2266 err = assign_irq_vector(irq, cfg, mask);
2267 if (err)
2268 return err;
2269
2270 err = apic->cpu_mask_to_apicid_and(mask, cfg->domain, dest_id);
2271 if (err) {
2272 if (assign_irq_vector(irq, cfg, data->affinity))
2273 pr_err("Failed to recover vector for irq %d\n", irq);
2274 return err;
2275 }
2276
2277 cpumask_copy(data->affinity, mask);
2278
2279 return 0;
2280}
2281
2282static int
2283ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
2284 bool force)
2285{
2286 unsigned int dest, irq = data->irq;
2287 unsigned long flags;
2288 int ret;
2289
2290 raw_spin_lock_irqsave(&ioapic_lock, flags);
2291 ret = __ioapic_set_affinity(data, mask, &dest);
2292 if (!ret) {
2293 /* Only the high 8 bits are valid. */
2294 dest = SET_APIC_LOGICAL_ID(dest);
2295 __target_IO_APIC_irq(irq, dest, data->chip_data);
2296 ret = IRQ_SET_MASK_OK_NOCOPY;
2297 }
2298 raw_spin_unlock_irqrestore(&ioapic_lock, flags);
2299 return ret;
2300}
2301
2302asmlinkage void smp_irq_move_cleanup_interrupt(void) 2227asmlinkage void smp_irq_move_cleanup_interrupt(void)
2303{ 2228{
2304 unsigned vector, me; 2229 unsigned vector, me;
@@ -2386,6 +2311,87 @@ void irq_force_complete_move(int irq)
2386static inline void irq_complete_move(struct irq_cfg *cfg) { } 2311static inline void irq_complete_move(struct irq_cfg *cfg) { }
2387#endif 2312#endif
2388 2313
2314static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg)
2315{
2316 int apic, pin;
2317 struct irq_pin_list *entry;
2318 u8 vector = cfg->vector;
2319
2320 for_each_irq_pin(entry, cfg->irq_2_pin) {
2321 unsigned int reg;
2322
2323 apic = entry->apic;
2324 pin = entry->pin;
2325 /*
2326 * With interrupt-remapping, destination information comes
2327 * from interrupt-remapping table entry.
2328 */
2329 if (!irq_remapped(cfg))
2330 io_apic_write(apic, 0x11 + pin*2, dest);
2331 reg = io_apic_read(apic, 0x10 + pin*2);
2332 reg &= ~IO_APIC_REDIR_VECTOR_MASK;
2333 reg |= vector;
2334 io_apic_modify(apic, 0x10 + pin*2, reg);
2335 }
2336}
2337
2338/*
2339 * Either sets data->affinity to a valid value, and returns
2340 * ->cpu_mask_to_apicid of that in dest_id, or returns -1 and
2341 * leaves data->affinity untouched.
2342 */
2343int __ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
2344 unsigned int *dest_id)
2345{
2346 struct irq_cfg *cfg = data->chip_data;
2347 unsigned int irq = data->irq;
2348 int err;
2349
2350 if (!config_enabled(CONFIG_SMP))
2351 return -1;
2352
2353 if (!cpumask_intersects(mask, cpu_online_mask))
2354 return -EINVAL;
2355
2356 err = assign_irq_vector(irq, cfg, mask);
2357 if (err)
2358 return err;
2359
2360 err = apic->cpu_mask_to_apicid_and(mask, cfg->domain, dest_id);
2361 if (err) {
2362 if (assign_irq_vector(irq, cfg, data->affinity))
2363 pr_err("Failed to recover vector for irq %d\n", irq);
2364 return err;
2365 }
2366
2367 cpumask_copy(data->affinity, mask);
2368
2369 return 0;
2370}
2371
2372static int
2373ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
2374 bool force)
2375{
2376 unsigned int dest, irq = data->irq;
2377 unsigned long flags;
2378 int ret;
2379
2380 if (!config_enabled(CONFIG_SMP))
2381 return -1;
2382
2383 raw_spin_lock_irqsave(&ioapic_lock, flags);
2384 ret = __ioapic_set_affinity(data, mask, &dest);
2385 if (!ret) {
2386 /* Only the high 8 bits are valid. */
2387 dest = SET_APIC_LOGICAL_ID(dest);
2388 __target_IO_APIC_irq(irq, dest, data->chip_data);
2389 ret = IRQ_SET_MASK_OK_NOCOPY;
2390 }
2391 raw_spin_unlock_irqrestore(&ioapic_lock, flags);
2392 return ret;
2393}
2394
2389static void ack_apic_edge(struct irq_data *data) 2395static void ack_apic_edge(struct irq_data *data)
2390{ 2396{
2391 irq_complete_move(data->chip_data); 2397 irq_complete_move(data->chip_data);
@@ -2565,9 +2571,7 @@ static void irq_remap_modify_chip_defaults(struct irq_chip *chip)
2565 chip->irq_ack = ir_ack_apic_edge; 2571 chip->irq_ack = ir_ack_apic_edge;
2566 chip->irq_eoi = ir_ack_apic_level; 2572 chip->irq_eoi = ir_ack_apic_level;
2567 2573
2568#ifdef CONFIG_SMP
2569 chip->irq_set_affinity = set_remapped_irq_affinity; 2574 chip->irq_set_affinity = set_remapped_irq_affinity;
2570#endif
2571} 2575}
2572#endif /* CONFIG_IRQ_REMAP */ 2576#endif /* CONFIG_IRQ_REMAP */
2573 2577
@@ -2578,9 +2582,7 @@ static struct irq_chip ioapic_chip __read_mostly = {
2578 .irq_unmask = unmask_ioapic_irq, 2582 .irq_unmask = unmask_ioapic_irq,
2579 .irq_ack = ack_apic_edge, 2583 .irq_ack = ack_apic_edge,
2580 .irq_eoi = ack_apic_level, 2584 .irq_eoi = ack_apic_level,
2581#ifdef CONFIG_SMP
2582 .irq_set_affinity = ioapic_set_affinity, 2585 .irq_set_affinity = ioapic_set_affinity,
2583#endif
2584 .irq_retrigger = ioapic_retrigger_irq, 2586 .irq_retrigger = ioapic_retrigger_irq,
2585}; 2587};
2586 2588
@@ -3099,7 +3101,6 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
3099 return err; 3101 return err;
3100} 3102}
3101 3103
3102#ifdef CONFIG_SMP
3103static int 3104static int
3104msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) 3105msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force)
3105{ 3106{
@@ -3121,7 +3122,6 @@ msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force)
3121 3122
3122 return IRQ_SET_MASK_OK_NOCOPY; 3123 return IRQ_SET_MASK_OK_NOCOPY;
3123} 3124}
3124#endif /* CONFIG_SMP */
3125 3125
3126/* 3126/*
3127 * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices, 3127 * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
@@ -3132,9 +3132,7 @@ static struct irq_chip msi_chip = {
3132 .irq_unmask = unmask_msi_irq, 3132 .irq_unmask = unmask_msi_irq,
3133 .irq_mask = mask_msi_irq, 3133 .irq_mask = mask_msi_irq,
3134 .irq_ack = ack_apic_edge, 3134 .irq_ack = ack_apic_edge,
3135#ifdef CONFIG_SMP
3136 .irq_set_affinity = msi_set_affinity, 3135 .irq_set_affinity = msi_set_affinity,
3137#endif
3138 .irq_retrigger = ioapic_retrigger_irq, 3136 .irq_retrigger = ioapic_retrigger_irq,
3139}; 3137};
3140 3138
@@ -3219,7 +3217,6 @@ void native_teardown_msi_irq(unsigned int irq)
3219} 3217}
3220 3218
3221#ifdef CONFIG_DMAR_TABLE 3219#ifdef CONFIG_DMAR_TABLE
3222#ifdef CONFIG_SMP
3223static int 3220static int
3224dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask, 3221dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask,
3225 bool force) 3222 bool force)
@@ -3244,16 +3241,12 @@ dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask,
3244 return IRQ_SET_MASK_OK_NOCOPY; 3241 return IRQ_SET_MASK_OK_NOCOPY;
3245} 3242}
3246 3243
3247#endif /* CONFIG_SMP */
3248
3249static struct irq_chip dmar_msi_type = { 3244static struct irq_chip dmar_msi_type = {
3250 .name = "DMAR_MSI", 3245 .name = "DMAR_MSI",
3251 .irq_unmask = dmar_msi_unmask, 3246 .irq_unmask = dmar_msi_unmask,
3252 .irq_mask = dmar_msi_mask, 3247 .irq_mask = dmar_msi_mask,
3253 .irq_ack = ack_apic_edge, 3248 .irq_ack = ack_apic_edge,
3254#ifdef CONFIG_SMP
3255 .irq_set_affinity = dmar_msi_set_affinity, 3249 .irq_set_affinity = dmar_msi_set_affinity,
3256#endif
3257 .irq_retrigger = ioapic_retrigger_irq, 3250 .irq_retrigger = ioapic_retrigger_irq,
3258}; 3251};
3259 3252
@@ -3274,7 +3267,6 @@ int arch_setup_dmar_msi(unsigned int irq)
3274 3267
3275#ifdef CONFIG_HPET_TIMER 3268#ifdef CONFIG_HPET_TIMER
3276 3269
3277#ifdef CONFIG_SMP
3278static int hpet_msi_set_affinity(struct irq_data *data, 3270static int hpet_msi_set_affinity(struct irq_data *data,
3279 const struct cpumask *mask, bool force) 3271 const struct cpumask *mask, bool force)
3280{ 3272{
@@ -3297,16 +3289,12 @@ static int hpet_msi_set_affinity(struct irq_data *data,
3297 return IRQ_SET_MASK_OK_NOCOPY; 3289 return IRQ_SET_MASK_OK_NOCOPY;
3298} 3290}
3299 3291
3300#endif /* CONFIG_SMP */
3301
3302static struct irq_chip hpet_msi_type = { 3292static struct irq_chip hpet_msi_type = {
3303 .name = "HPET_MSI", 3293 .name = "HPET_MSI",
3304 .irq_unmask = hpet_msi_unmask, 3294 .irq_unmask = hpet_msi_unmask,
3305 .irq_mask = hpet_msi_mask, 3295 .irq_mask = hpet_msi_mask,
3306 .irq_ack = ack_apic_edge, 3296 .irq_ack = ack_apic_edge,
3307#ifdef CONFIG_SMP
3308 .irq_set_affinity = hpet_msi_set_affinity, 3297 .irq_set_affinity = hpet_msi_set_affinity,
3309#endif
3310 .irq_retrigger = ioapic_retrigger_irq, 3298 .irq_retrigger = ioapic_retrigger_irq,
3311}; 3299};
3312 3300
@@ -3341,8 +3329,6 @@ int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
3341 */ 3329 */
3342#ifdef CONFIG_HT_IRQ 3330#ifdef CONFIG_HT_IRQ
3343 3331
3344#ifdef CONFIG_SMP
3345
3346static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector) 3332static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector)
3347{ 3333{
3348 struct ht_irq_msg msg; 3334 struct ht_irq_msg msg;
@@ -3370,16 +3356,12 @@ ht_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force)
3370 return IRQ_SET_MASK_OK_NOCOPY; 3356 return IRQ_SET_MASK_OK_NOCOPY;
3371} 3357}
3372 3358
3373#endif
3374
3375static struct irq_chip ht_irq_chip = { 3359static struct irq_chip ht_irq_chip = {
3376 .name = "PCI-HT", 3360 .name = "PCI-HT",
3377 .irq_mask = mask_ht_irq, 3361 .irq_mask = mask_ht_irq,
3378 .irq_unmask = unmask_ht_irq, 3362 .irq_unmask = unmask_ht_irq,
3379 .irq_ack = ack_apic_edge, 3363 .irq_ack = ack_apic_edge,
3380#ifdef CONFIG_SMP
3381 .irq_set_affinity = ht_set_affinity, 3364 .irq_set_affinity = ht_set_affinity,
3382#endif
3383 .irq_retrigger = ioapic_retrigger_irq, 3365 .irq_retrigger = ioapic_retrigger_irq,
3384}; 3366};
3385 3367
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c
index 853902a1b7db..e0b18f3ae9a8 100644
--- a/drivers/iommu/intel_irq_remapping.c
+++ b/drivers/iommu/intel_irq_remapping.c
@@ -902,7 +902,6 @@ static int intel_setup_ioapic_entry(int irq,
902 return 0; 902 return 0;
903} 903}
904 904
905#ifdef CONFIG_SMP
906/* 905/*
907 * Migrate the IO-APIC irq in the presence of intr-remapping. 906 * Migrate the IO-APIC irq in the presence of intr-remapping.
908 * 907 *
@@ -926,6 +925,9 @@ intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
926 struct irte irte; 925 struct irte irte;
927 int err; 926 int err;
928 927
928 if (!config_enabled(CONFIG_SMP))
929 return -EINVAL;
930
929 if (!cpumask_intersects(mask, cpu_online_mask)) 931 if (!cpumask_intersects(mask, cpu_online_mask))
930 return -EINVAL; 932 return -EINVAL;
931 933
@@ -963,7 +965,6 @@ intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
963 cpumask_copy(data->affinity, mask); 965 cpumask_copy(data->affinity, mask);
964 return 0; 966 return 0;
965} 967}
966#endif
967 968
968static void intel_compose_msi_msg(struct pci_dev *pdev, 969static void intel_compose_msi_msg(struct pci_dev *pdev,
969 unsigned int irq, unsigned int dest, 970 unsigned int irq, unsigned int dest,
@@ -1065,9 +1066,7 @@ struct irq_remap_ops intel_irq_remap_ops = {
1065 .reenable = reenable_irq_remapping, 1066 .reenable = reenable_irq_remapping,
1066 .enable_faulting = enable_drhd_fault_handling, 1067 .enable_faulting = enable_drhd_fault_handling,
1067 .setup_ioapic_entry = intel_setup_ioapic_entry, 1068 .setup_ioapic_entry = intel_setup_ioapic_entry,
1068#ifdef CONFIG_SMP
1069 .set_affinity = intel_ioapic_set_affinity, 1069 .set_affinity = intel_ioapic_set_affinity,
1070#endif
1071 .free_irq = free_irte, 1070 .free_irq = free_irte,
1072 .compose_msi_msg = intel_compose_msi_msg, 1071 .compose_msi_msg = intel_compose_msi_msg,
1073 .msi_alloc_irq = intel_msi_alloc_irq, 1072 .msi_alloc_irq = intel_msi_alloc_irq,
diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 40cda8e98d87..1d29b1c66e72 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -111,16 +111,15 @@ int setup_ioapic_remapped_entry(int irq,
111 vector, attr); 111 vector, attr);
112} 112}
113 113
114#ifdef CONFIG_SMP
115int set_remapped_irq_affinity(struct irq_data *data, const struct cpumask *mask, 114int set_remapped_irq_affinity(struct irq_data *data, const struct cpumask *mask,
116 bool force) 115 bool force)
117{ 116{
118 if (!remap_ops || !remap_ops->set_affinity) 117 if (!config_enabled(CONFIG_SMP) || !remap_ops ||
118 !remap_ops->set_affinity)
119 return 0; 119 return 0;
120 120
121 return remap_ops->set_affinity(data, mask, force); 121 return remap_ops->set_affinity(data, mask, force);
122} 122}
123#endif
124 123
125void free_remapped_irq(int irq) 124void free_remapped_irq(int irq)
126{ 125{
diff --git a/drivers/iommu/irq_remapping.h b/drivers/iommu/irq_remapping.h
index be9d72950c51..b12974cc1dfe 100644
--- a/drivers/iommu/irq_remapping.h
+++ b/drivers/iommu/irq_remapping.h
@@ -59,11 +59,9 @@ struct irq_remap_ops {
59 unsigned int, int, 59 unsigned int, int,
60 struct io_apic_irq_attr *); 60 struct io_apic_irq_attr *);
61 61
62#ifdef CONFIG_SMP
63 /* Set the CPU affinity of a remapped interrupt */ 62 /* Set the CPU affinity of a remapped interrupt */
64 int (*set_affinity)(struct irq_data *data, const struct cpumask *mask, 63 int (*set_affinity)(struct irq_data *data, const struct cpumask *mask,
65 bool force); 64 bool force);
66#endif
67 65
68 /* Free an IRQ */ 66 /* Free an IRQ */
69 int (*free_irq)(int); 67 int (*free_irq)(int);
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 61f5cec031e0..47a937cd84af 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -150,9 +150,7 @@ struct irq_data {
150 void *handler_data; 150 void *handler_data;
151 void *chip_data; 151 void *chip_data;
152 struct msi_desc *msi_desc; 152 struct msi_desc *msi_desc;
153#ifdef CONFIG_SMP
154 cpumask_var_t affinity; 153 cpumask_var_t affinity;
155#endif
156}; 154};
157 155
158/* 156/*