diff options
author | Weidong Han <weidong.han@intel.com> | 2009-05-22 12:41:14 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2009-06-23 17:09:15 -0400 |
commit | c4658b4e777bebf69884f4884a9bfb2f84dd71d9 (patch) | |
tree | c38cf0924b01e42a936b56d9f5c3d254822d3471 /drivers/pci | |
parent | 2c2e2c389d03bb16b8cdf9db3ac615385fac100f (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.c | 40 |
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 | ||
373 | static 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 | |||
372 | int free_irte(int irq) | 396 | int 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; |