diff options
| -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; |
