Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+52
+35
drivers/iommu/amd_iommu_v2.c
··· 63 63 int pasid_levels; 64 64 int max_pasids; 65 65 amd_iommu_invalid_ppr_cb inv_ppr_cb; 66 + amd_iommu_invalidate_ctx inv_ctx_cb; 66 67 spinlock_t lock; 67 68 wait_queue_head_t wq; 68 69 }; ··· 638 637 dev_state = pasid_state->device_state; 639 638 pasid = pasid_state->pasid; 640 639 640 + if (pasid_state->device_state->inv_ctx_cb) 641 + dev_state->inv_ctx_cb(dev_state->pdev, pasid); 642 + 641 643 unbind_pasid(dev_state, pasid); 642 644 643 645 /* Task may be in the list multiple times */ ··· 884 880 return ret; 885 881 } 886 882 EXPORT_SYMBOL(amd_iommu_set_invalid_ppr_cb); 883 + 884 + int amd_iommu_set_invalidate_ctx_cb(struct pci_dev *pdev, 885 + amd_iommu_invalidate_ctx cb) 886 + { 887 + struct device_state *dev_state; 888 + unsigned long flags; 889 + u16 devid; 890 + int ret; 891 + 892 + if (!amd_iommu_v2_supported()) 893 + return -ENODEV; 894 + 895 + devid = device_id(pdev); 896 + 897 + spin_lock_irqsave(&state_lock, flags); 898 + 899 + ret = -EINVAL; 900 + dev_state = state_table[devid]; 901 + if (dev_state == NULL) 902 + goto out_unlock; 903 + 904 + dev_state->inv_ctx_cb = cb; 905 + 906 + ret = 0; 907 + 908 + out_unlock: 909 + spin_unlock_irqrestore(&state_lock, flags); 910 + 911 + return ret; 912 + } 913 + EXPORT_SYMBOL(amd_iommu_set_invalidate_ctx_cb); 887 914 888 915 static int __init amd_iommu_v2_init(void) 889 916 {
+17
include/linux/amd-iommu.h
··· 145 145 extern int amd_iommu_device_info(struct pci_dev *pdev, 146 146 struct amd_iommu_device_info *info); 147 147 148 + /** 149 + * amd_iommu_set_invalidate_ctx_cb() - Register a call-back for invalidating 150 + * a pasid context. This call-back is 151 + * invoked when the IOMMUv2 driver needs to 152 + * invalidate a PASID context, for example 153 + * because the task that is bound to that 154 + * context is about to exit. 155 + * 156 + * @pdev: The PCI device the call-back should be registered for 157 + * @cb: The call-back function 158 + */ 159 + 160 + typedef void (*amd_iommu_invalidate_ctx)(struct pci_dev *pdev, int pasid); 161 + 162 + extern int amd_iommu_set_invalidate_ctx_cb(struct pci_dev *pdev, 163 + amd_iommu_invalidate_ctx cb); 164 + 148 165 #else 149 166 150 167 static inline int amd_iommu_detect(void) { return -ENODEV; }