diff options
-rw-r--r-- | arch/x86/kernel/amd_iommu.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 1c60554537c3..9372f0406ad4 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
@@ -434,6 +434,16 @@ static void iommu_flush_tlb(struct amd_iommu *iommu, u16 domid) | |||
434 | iommu_queue_inv_iommu_pages(iommu, address, domid, 0, 1); | 434 | iommu_queue_inv_iommu_pages(iommu, address, domid, 0, 1); |
435 | } | 435 | } |
436 | 436 | ||
437 | /* Flush the whole IO/TLB for a given protection domain - including PDE */ | ||
438 | static void iommu_flush_tlb_pde(struct amd_iommu *iommu, u16 domid) | ||
439 | { | ||
440 | u64 address = CMD_INV_IOMMU_ALL_PAGES_ADDRESS; | ||
441 | |||
442 | INC_STATS_COUNTER(domain_flush_single); | ||
443 | |||
444 | iommu_queue_inv_iommu_pages(iommu, address, domid, 1, 1); | ||
445 | } | ||
446 | |||
437 | /* | 447 | /* |
438 | * This function is used to flush the IO/TLB for a given protection domain | 448 | * This function is used to flush the IO/TLB for a given protection domain |
439 | * on every IOMMU in the system | 449 | * on every IOMMU in the system |
@@ -1078,7 +1088,13 @@ static void attach_device(struct amd_iommu *iommu, | |||
1078 | amd_iommu_pd_table[devid] = domain; | 1088 | amd_iommu_pd_table[devid] = domain; |
1079 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); | 1089 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); |
1080 | 1090 | ||
1091 | /* | ||
1092 | * We might boot into a crash-kernel here. The crashed kernel | ||
1093 | * left the caches in the IOMMU dirty. So we have to flush | ||
1094 | * here to evict all dirty stuff. | ||
1095 | */ | ||
1081 | iommu_queue_inv_dev_entry(iommu, devid); | 1096 | iommu_queue_inv_dev_entry(iommu, devid); |
1097 | iommu_flush_tlb_pde(iommu, domain->id); | ||
1082 | } | 1098 | } |
1083 | 1099 | ||
1084 | /* | 1100 | /* |