diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2017-09-13 17:29:48 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2017-09-25 14:52:01 -0400 |
commit | 5ba204a1817ba95a7b24dbe8ef2c7ddd4cea886e (patch) | |
tree | 7c380c7c5be6bc722097d02e7cfe769536cb6cb8 | |
parent | d491bdff888e8a287f6017c70a8dd10f46984851 (diff) |
iommu/amd: Reevaluate vector configuration on activate()
With the upcoming reservation/management scheme, early activation will
assign a special vector. The final activation at request_irq() assigns a
real vector, which needs to be updated in the tables.
Split out the reconfiguration code in set_affinity and use it for
reactivation.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Juergen Gross <jgross@suse.com>
Tested-by: Yu Chen <yu.c.chen@intel.com>
Acked-by: Juergen Gross <jgross@suse.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Alok Kataria <akataria@vmware.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: iommu@lists.linux-foundation.org
Cc: Borislav Petkov <bp@alien8.de>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Rui Zhang <rui.zhang@intel.com>
Cc: "K. Y. Srinivasan" <kys@microsoft.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Len Brown <lenb@kernel.org>
Link: https://lkml.kernel.org/r/20170913213155.944883733@linutronix.de
-rw-r--r-- | drivers/iommu/amd_iommu.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index ea03f4138f5f..a78fa34f113a 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
@@ -4170,16 +4170,25 @@ static void irq_remapping_free(struct irq_domain *domain, unsigned int virq, | |||
4170 | irq_domain_free_irqs_common(domain, virq, nr_irqs); | 4170 | irq_domain_free_irqs_common(domain, virq, nr_irqs); |
4171 | } | 4171 | } |
4172 | 4172 | ||
4173 | static void amd_ir_update_irte(struct irq_data *irqd, struct amd_iommu *iommu, | ||
4174 | struct amd_ir_data *ir_data, | ||
4175 | struct irq_2_irte *irte_info, | ||
4176 | struct irq_cfg *cfg); | ||
4177 | |||
4173 | static int irq_remapping_activate(struct irq_domain *domain, | 4178 | static int irq_remapping_activate(struct irq_domain *domain, |
4174 | struct irq_data *irq_data, bool early) | 4179 | struct irq_data *irq_data, bool early) |
4175 | { | 4180 | { |
4176 | struct amd_ir_data *data = irq_data->chip_data; | 4181 | struct amd_ir_data *data = irq_data->chip_data; |
4177 | struct irq_2_irte *irte_info = &data->irq_2_irte; | 4182 | struct irq_2_irte *irte_info = &data->irq_2_irte; |
4178 | struct amd_iommu *iommu = amd_iommu_rlookup_table[irte_info->devid]; | 4183 | struct amd_iommu *iommu = amd_iommu_rlookup_table[irte_info->devid]; |
4184 | struct irq_cfg *cfg = irqd_cfg(irq_data); | ||
4179 | 4185 | ||
4180 | if (iommu) | 4186 | if (!iommu) |
4181 | iommu->irte_ops->activate(data->entry, irte_info->devid, | 4187 | return 0; |
4182 | irte_info->index); | 4188 | |
4189 | iommu->irte_ops->activate(data->entry, irte_info->devid, | ||
4190 | irte_info->index); | ||
4191 | amd_ir_update_irte(irq_data, iommu, data, irte_info, cfg); | ||
4183 | return 0; | 4192 | return 0; |
4184 | } | 4193 | } |
4185 | 4194 | ||
@@ -4267,6 +4276,22 @@ static int amd_ir_set_vcpu_affinity(struct irq_data *data, void *vcpu_info) | |||
4267 | return modify_irte_ga(irte_info->devid, irte_info->index, irte, ir_data); | 4276 | return modify_irte_ga(irte_info->devid, irte_info->index, irte, ir_data); |
4268 | } | 4277 | } |
4269 | 4278 | ||
4279 | |||
4280 | static void amd_ir_update_irte(struct irq_data *irqd, struct amd_iommu *iommu, | ||
4281 | struct amd_ir_data *ir_data, | ||
4282 | struct irq_2_irte *irte_info, | ||
4283 | struct irq_cfg *cfg) | ||
4284 | { | ||
4285 | |||
4286 | /* | ||
4287 | * Atomically updates the IRTE with the new destination, vector | ||
4288 | * and flushes the interrupt entry cache. | ||
4289 | */ | ||
4290 | iommu->irte_ops->set_affinity(ir_data->entry, irte_info->devid, | ||
4291 | irte_info->index, cfg->vector, | ||
4292 | cfg->dest_apicid); | ||
4293 | } | ||
4294 | |||
4270 | static int amd_ir_set_affinity(struct irq_data *data, | 4295 | static int amd_ir_set_affinity(struct irq_data *data, |
4271 | const struct cpumask *mask, bool force) | 4296 | const struct cpumask *mask, bool force) |
4272 | { | 4297 | { |
@@ -4284,13 +4309,7 @@ static int amd_ir_set_affinity(struct irq_data *data, | |||
4284 | if (ret < 0 || ret == IRQ_SET_MASK_OK_DONE) | 4309 | if (ret < 0 || ret == IRQ_SET_MASK_OK_DONE) |
4285 | return ret; | 4310 | return ret; |
4286 | 4311 | ||
4287 | /* | 4312 | amd_ir_update_irte(data, iommu, ir_data, irte_info, cfg); |
4288 | * Atomically updates the IRTE with the new destination, vector | ||
4289 | * and flushes the interrupt entry cache. | ||
4290 | */ | ||
4291 | iommu->irte_ops->set_affinity(ir_data->entry, irte_info->devid, | ||
4292 | irte_info->index, cfg->vector, cfg->dest_apicid); | ||
4293 | |||
4294 | /* | 4313 | /* |
4295 | * After this point, all the interrupts will start arriving | 4314 | * After this point, all the interrupts will start arriving |
4296 | * at the new destination. So, time to cleanup the previous | 4315 | * at the new destination. So, time to cleanup the previous |