diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2011-12-07 06:24:42 -0500 |
---|---|---|
committer | Joerg Roedel <joerg.roedel@amd.com> | 2011-12-15 05:15:39 -0500 |
commit | bc21662f729cd17d2af93e149f4eccafc7b10181 (patch) | |
tree | cb980b6412dc1b42383fefe9898c808167d4a4c6 /drivers/iommu | |
parent | 52efdb89d60a0f19949129a08af3437a7aab70be (diff) |
iommu/amd: Add invalidate-context call-back
This call-back is invoked when the task that is bound to a
pasid is about to exit. The driver can use it to shutdown
all context related to that context in a safe way.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'drivers/iommu')
-rw-r--r-- | drivers/iommu/amd_iommu_v2.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c index fe812e2a0474..8add9f125d3e 100644 --- a/drivers/iommu/amd_iommu_v2.c +++ b/drivers/iommu/amd_iommu_v2.c | |||
@@ -63,6 +63,7 @@ struct device_state { | |||
63 | int pasid_levels; | 63 | int pasid_levels; |
64 | int max_pasids; | 64 | int max_pasids; |
65 | amd_iommu_invalid_ppr_cb inv_ppr_cb; | 65 | amd_iommu_invalid_ppr_cb inv_ppr_cb; |
66 | amd_iommu_invalidate_ctx inv_ctx_cb; | ||
66 | spinlock_t lock; | 67 | spinlock_t lock; |
67 | wait_queue_head_t wq; | 68 | wait_queue_head_t wq; |
68 | }; | 69 | }; |
@@ -637,6 +638,9 @@ again: | |||
637 | dev_state = pasid_state->device_state; | 638 | dev_state = pasid_state->device_state; |
638 | pasid = pasid_state->pasid; | 639 | pasid = pasid_state->pasid; |
639 | 640 | ||
641 | if (pasid_state->device_state->inv_ctx_cb) | ||
642 | dev_state->inv_ctx_cb(dev_state->pdev, pasid); | ||
643 | |||
640 | unbind_pasid(dev_state, pasid); | 644 | unbind_pasid(dev_state, pasid); |
641 | 645 | ||
642 | /* Task may be in the list multiple times */ | 646 | /* Task may be in the list multiple times */ |
@@ -881,6 +885,37 @@ out_unlock: | |||
881 | } | 885 | } |
882 | EXPORT_SYMBOL(amd_iommu_set_invalid_ppr_cb); | 886 | EXPORT_SYMBOL(amd_iommu_set_invalid_ppr_cb); |
883 | 887 | ||
888 | int amd_iommu_set_invalidate_ctx_cb(struct pci_dev *pdev, | ||
889 | amd_iommu_invalidate_ctx cb) | ||
890 | { | ||
891 | struct device_state *dev_state; | ||
892 | unsigned long flags; | ||
893 | u16 devid; | ||
894 | int ret; | ||
895 | |||
896 | if (!amd_iommu_v2_supported()) | ||
897 | return -ENODEV; | ||
898 | |||
899 | devid = device_id(pdev); | ||
900 | |||
901 | spin_lock_irqsave(&state_lock, flags); | ||
902 | |||
903 | ret = -EINVAL; | ||
904 | dev_state = state_table[devid]; | ||
905 | if (dev_state == NULL) | ||
906 | goto out_unlock; | ||
907 | |||
908 | dev_state->inv_ctx_cb = cb; | ||
909 | |||
910 | ret = 0; | ||
911 | |||
912 | out_unlock: | ||
913 | spin_unlock_irqrestore(&state_lock, flags); | ||
914 | |||
915 | return ret; | ||
916 | } | ||
917 | EXPORT_SYMBOL(amd_iommu_set_invalidate_ctx_cb); | ||
918 | |||
884 | static int __init amd_iommu_v2_init(void) | 919 | static int __init amd_iommu_v2_init(void) |
885 | { | 920 | { |
886 | size_t state_table_size; | 921 | size_t state_table_size; |