diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2009-09-03 09:28:33 -0400 |
---|---|---|
committer | Joerg Roedel <joerg.roedel@amd.com> | 2009-09-03 09:41:34 -0400 |
commit | e394d72aa8b319211b8f947d151d9d50b0fde842 (patch) | |
tree | 84cea0138c4b0ec1886d4171521007f8ef6543eb /arch/x86/kernel/amd_iommu.c | |
parent | 945b4ac44e5700acd3d974c176c8ace34b4d2e8e (diff) |
x86/amd-iommu: Introduce function for iommu-local domain flush
This patch introduces a function to flush all domain tlbs
for on one given IOMMU. This is required later to reset the
command buffer on one IOMMU.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'arch/x86/kernel/amd_iommu.c')
-rw-r--r-- | arch/x86/kernel/amd_iommu.c | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index e62b35f5df1b..64cc582feb9b 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
@@ -465,38 +465,55 @@ static void iommu_flush_tlb_pde(struct amd_iommu *iommu, u16 domid) | |||
465 | } | 465 | } |
466 | 466 | ||
467 | /* | 467 | /* |
468 | * This function is used to flush the IO/TLB for a given protection domain | 468 | * This function flushes one domain on one IOMMU |
469 | * on every IOMMU in the system | ||
470 | */ | 469 | */ |
471 | static void iommu_flush_domain(u16 domid) | 470 | static void flush_domain_on_iommu(struct amd_iommu *iommu, u16 domid) |
472 | { | 471 | { |
473 | unsigned long flags; | ||
474 | struct amd_iommu *iommu; | ||
475 | struct iommu_cmd cmd; | 472 | struct iommu_cmd cmd; |
476 | 473 | unsigned long flags; | |
477 | INC_STATS_COUNTER(domain_flush_all); | ||
478 | 474 | ||
479 | __iommu_build_inv_iommu_pages(&cmd, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, | 475 | __iommu_build_inv_iommu_pages(&cmd, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, |
480 | domid, 1, 1); | 476 | domid, 1, 1); |
481 | 477 | ||
482 | for_each_iommu(iommu) { | 478 | spin_lock_irqsave(&iommu->lock, flags); |
483 | spin_lock_irqsave(&iommu->lock, flags); | 479 | __iommu_queue_command(iommu, &cmd); |
484 | __iommu_queue_command(iommu, &cmd); | 480 | __iommu_completion_wait(iommu); |
485 | __iommu_completion_wait(iommu); | 481 | __iommu_wait_for_completion(iommu); |
486 | __iommu_wait_for_completion(iommu); | 482 | spin_unlock_irqrestore(&iommu->lock, flags); |
487 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
488 | } | ||
489 | } | 483 | } |
490 | 484 | ||
491 | void amd_iommu_flush_all_domains(void) | 485 | static void flush_all_domains_on_iommu(struct amd_iommu *iommu) |
492 | { | 486 | { |
493 | int i; | 487 | int i; |
494 | 488 | ||
495 | for (i = 1; i < MAX_DOMAIN_ID; ++i) { | 489 | for (i = 1; i < MAX_DOMAIN_ID; ++i) { |
496 | if (!test_bit(i, amd_iommu_pd_alloc_bitmap)) | 490 | if (!test_bit(i, amd_iommu_pd_alloc_bitmap)) |
497 | continue; | 491 | continue; |
498 | iommu_flush_domain(i); | 492 | flush_domain_on_iommu(iommu, i); |
499 | } | 493 | } |
494 | |||
495 | } | ||
496 | |||
497 | /* | ||
498 | * This function is used to flush the IO/TLB for a given protection domain | ||
499 | * on every IOMMU in the system | ||
500 | */ | ||
501 | static void iommu_flush_domain(u16 domid) | ||
502 | { | ||
503 | struct amd_iommu *iommu; | ||
504 | |||
505 | INC_STATS_COUNTER(domain_flush_all); | ||
506 | |||
507 | for_each_iommu(iommu) | ||
508 | flush_domain_on_iommu(iommu, domid); | ||
509 | } | ||
510 | |||
511 | void amd_iommu_flush_all_domains(void) | ||
512 | { | ||
513 | struct amd_iommu *iommu; | ||
514 | |||
515 | for_each_iommu(iommu) | ||
516 | flush_all_domains_on_iommu(iommu); | ||
500 | } | 517 | } |
501 | 518 | ||
502 | void amd_iommu_flush_all_devices(void) | 519 | void amd_iommu_flush_all_devices(void) |