diff options
-rw-r--r-- | drivers/iommu/amd_iommu_v2.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c index f7ca009bda67..a195c78b63c6 100644 --- a/drivers/iommu/amd_iommu_v2.c +++ b/drivers/iommu/amd_iommu_v2.c | |||
@@ -52,7 +52,8 @@ struct pasid_state { | |||
52 | struct pri_queue pri[PRI_QUEUE_SIZE]; /* PRI tag states */ | 52 | struct pri_queue pri[PRI_QUEUE_SIZE]; /* PRI tag states */ |
53 | struct device_state *device_state; /* Link to our device_state */ | 53 | struct device_state *device_state; /* Link to our device_state */ |
54 | int pasid; /* PASID index */ | 54 | int pasid; /* PASID index */ |
55 | bool invalid; /* Used during teardown */ | 55 | bool invalid; /* Used during setup and |
56 | teardown of the pasid */ | ||
56 | spinlock_t lock; /* Protect pri_queues and | 57 | spinlock_t lock; /* Protect pri_queues and |
57 | mmu_notifer_count */ | 58 | mmu_notifer_count */ |
58 | wait_queue_head_t wq; /* To wait for count == 0 */ | 59 | wait_queue_head_t wq; /* To wait for count == 0 */ |
@@ -473,13 +474,15 @@ static void mn_release(struct mmu_notifier *mn, struct mm_struct *mm) | |||
473 | { | 474 | { |
474 | struct pasid_state *pasid_state; | 475 | struct pasid_state *pasid_state; |
475 | struct device_state *dev_state; | 476 | struct device_state *dev_state; |
477 | bool run_inv_ctx_cb; | ||
476 | 478 | ||
477 | might_sleep(); | 479 | might_sleep(); |
478 | 480 | ||
479 | pasid_state = mn_to_state(mn); | 481 | pasid_state = mn_to_state(mn); |
480 | dev_state = pasid_state->device_state; | 482 | dev_state = pasid_state->device_state; |
483 | run_inv_ctx_cb = !pasid_state->invalid; | ||
481 | 484 | ||
482 | if (pasid_state->device_state->inv_ctx_cb) | 485 | if (run_inv_ctx_cb && pasid_state->device_state->inv_ctx_cb) |
483 | dev_state->inv_ctx_cb(dev_state->pdev, pasid_state->pasid); | 486 | dev_state->inv_ctx_cb(dev_state->pdev, pasid_state->pasid); |
484 | 487 | ||
485 | unbind_pasid(pasid_state); | 488 | unbind_pasid(pasid_state); |
@@ -674,7 +677,8 @@ int amd_iommu_bind_pasid(struct pci_dev *pdev, int pasid, | |||
674 | pasid_state->mm = mm; | 677 | pasid_state->mm = mm; |
675 | pasid_state->device_state = dev_state; | 678 | pasid_state->device_state = dev_state; |
676 | pasid_state->pasid = pasid; | 679 | pasid_state->pasid = pasid; |
677 | pasid_state->invalid = false; | 680 | pasid_state->invalid = true; /* Mark as valid only if we are |
681 | done with setting up the pasid */ | ||
678 | pasid_state->mn.ops = &iommu_mn; | 682 | pasid_state->mn.ops = &iommu_mn; |
679 | 683 | ||
680 | if (pasid_state->mm == NULL) | 684 | if (pasid_state->mm == NULL) |
@@ -691,6 +695,9 @@ int amd_iommu_bind_pasid(struct pci_dev *pdev, int pasid, | |||
691 | if (ret) | 695 | if (ret) |
692 | goto out_clear_state; | 696 | goto out_clear_state; |
693 | 697 | ||
698 | /* Now we are ready to handle faults */ | ||
699 | pasid_state->invalid = false; | ||
700 | |||
694 | /* | 701 | /* |
695 | * Drop the reference to the mm_struct here. We rely on the | 702 | * Drop the reference to the mm_struct here. We rely on the |
696 | * mmu_notifier release call-back to inform us when the mm | 703 | * mmu_notifier release call-back to inform us when the mm |