@ -63,6 +63,7 @@ struct device_state {
int pasid_levels ;
int max_pasids ;
amd_iommu_invalid_ppr_cb inv_ppr_cb ;
amd_iommu_invalidate_ctx inv_ctx_cb ;
spinlock_t lock ;
wait_queue_head_t wq ;
} ;
@ -637,6 +638,9 @@ again:
dev_state = pasid_state - > device_state ;
pasid = pasid_state - > pasid ;
if ( pasid_state - > device_state - > inv_ctx_cb )
dev_state - > inv_ctx_cb ( dev_state - > pdev , pasid ) ;
unbind_pasid ( dev_state , pasid ) ;
/* Task may be in the list multiple times */
@ -881,6 +885,37 @@ out_unlock:
}
EXPORT_SYMBOL ( amd_iommu_set_invalid_ppr_cb ) ;
int amd_iommu_set_invalidate_ctx_cb ( struct pci_dev * pdev ,
amd_iommu_invalidate_ctx cb )
{
struct device_state * dev_state ;
unsigned long flags ;
u16 devid ;
int ret ;
if ( ! amd_iommu_v2_supported ( ) )
return - ENODEV ;
devid = device_id ( pdev ) ;
spin_lock_irqsave ( & state_lock , flags ) ;
ret = - EINVAL ;
dev_state = state_table [ devid ] ;
if ( dev_state = = NULL )
goto out_unlock ;
dev_state - > inv_ctx_cb = cb ;
ret = 0 ;
out_unlock :
spin_unlock_irqrestore ( & state_lock , flags ) ;
return ret ;
}
EXPORT_SYMBOL ( amd_iommu_set_invalidate_ctx_cb ) ;
static int __init amd_iommu_v2_init ( void )
{
size_t state_table_size ;