aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorWeidong Han <weidong.han@intel.com>2009-05-22 12:41:14 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2009-06-23 17:09:15 -0400
commitc4658b4e777bebf69884f4884a9bfb2f84dd71d9 (patch)
treec38cf0924b01e42a936b56d9f5c3d254822d3471 /drivers/pci
parent2c2e2c389d03bb16b8cdf9db3ac615385fac100f (diff)
Intel-IOMMU, intr-remap: set the whole 128bits of irte when modify/free it
Interrupt remapping table entry is 128bits. Currently, it only sets low 64bits of irte in modify_irte and free_irte. This ignores high 64bits setting of irte, that means source-id setting will be ignored. This patch sets the whole 128bits of irte when modify/free it. Following source-id checking patch depends on this. Signed-off-by: Weidong Han <weidong.han@intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/intr_remapping.c40
1 files changed, 26 insertions, 14 deletions
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index 1e83c8c5f985..44025a0c2bb6 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -314,7 +314,8 @@ int modify_irte(int irq, struct irte *irte_modified)
314 index = irq_iommu->irte_index + irq_iommu->sub_handle; 314 index = irq_iommu->irte_index + irq_iommu->sub_handle;
315 irte = &iommu->ir_table->base[index]; 315 irte = &iommu->ir_table->base[index];
316 316
317 set_64bit((unsigned long *)irte, irte_modified->low); 317 set_64bit((unsigned long *)&irte->low, irte_modified->low);
318 set_64bit((unsigned long *)&irte->high, irte_modified->high);
318 __iommu_flush_cache(iommu, irte, sizeof(*irte)); 319 __iommu_flush_cache(iommu, irte, sizeof(*irte));
319 320
320 rc = qi_flush_iec(iommu, index, 0); 321 rc = qi_flush_iec(iommu, index, 0);
@@ -369,12 +370,32 @@ struct intel_iommu *map_dev_to_ir(struct pci_dev *dev)
369 return drhd->iommu; 370 return drhd->iommu;
370} 371}
371 372
373static int clear_entries(struct irq_2_iommu *irq_iommu)
374{
375 struct irte *start, *entry, *end;
376 struct intel_iommu *iommu;
377 int index;
378
379 if (irq_iommu->sub_handle)
380 return 0;
381
382 iommu = irq_iommu->iommu;
383 index = irq_iommu->irte_index + irq_iommu->sub_handle;
384
385 start = iommu->ir_table->base + index;
386 end = start + (1 << irq_iommu->irte_mask);
387
388 for (entry = start; entry < end; entry++) {
389 set_64bit((unsigned long *)&entry->low, 0);
390 set_64bit((unsigned long *)&entry->high, 0);
391 }
392
393 return qi_flush_iec(iommu, index, irq_iommu->irte_mask);
394}
395
372int free_irte(int irq) 396int free_irte(int irq)
373{ 397{
374 int rc = 0; 398 int rc = 0;
375 int index, i;
376 struct irte *irte;
377 struct intel_iommu *iommu;
378 struct irq_2_iommu *irq_iommu; 399 struct irq_2_iommu *irq_iommu;
379 unsigned long flags; 400 unsigned long flags;
380 401
@@ -385,16 +406,7 @@ int free_irte(int irq)
385 return -1; 406 return -1;
386 } 407 }
387 408
388 iommu = irq_iommu->iommu; 409 rc = clear_entries(irq_iommu);
389
390 index = irq_iommu->irte_index + irq_iommu->sub_handle;
391 irte = &iommu->ir_table->base[index];
392
393 if (!irq_iommu->sub_handle) {
394 for (i = 0; i < (1 << irq_iommu->irte_mask); i++)
395 set_64bit((unsigned long *)(irte + i), 0);
396 rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask);
397 }
398 410
399 irq_iommu->iommu = NULL; 411 irq_iommu->iommu = NULL;
400 irq_iommu->irte_index = 0; 412 irq_iommu->irte_index = 0;