diff options
author | Joerg Roedel <jroedel@suse.de> | 2014-07-09 09:43:11 -0400 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2014-07-10 09:37:03 -0400 |
commit | d9e1611e7347b41bae8894e957a398fa41162dab (patch) | |
tree | f89a6c9f8917b1efe25e0154a822f2071bfb1df2 /drivers/iommu | |
parent | dba3838d7af38b15bcc8ff3437362d449408b547 (diff) |
iommu/amd: Don't call the inv_ctx_cb when pasid is not set up
On the error path of amd_iommu_bind_pasid() we call
mmu_notifier_unregister() for cleanup. This calls
mn_release() which calls the users inv_ctx_cb function if
one is available. Since the pasid is not set up yet there is
nothing the user can to tear down in this call-back. So
don't call inv_ctx_cb on the error path of
amd_iommu_unbind_pasid() and make life of the users simpler.
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Tested-by: Oded Gabbay <Oded.Gabbay@amd.com>
Diffstat (limited to 'drivers/iommu')
-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 |