iommu/amd: Update device_state structure to include PCI seg ID
Rename struct device_state.devid variable to struct device_state.sbdf and extend it to 32-bit to include the 16-bit PCI segment ID via the helper function get_pci_sbdf_id(). Co-developed-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Signed-off-by: Vasant Hegde <vasant.hegde@amd.com> Link: https://lore.kernel.org/r/20220706113825.25582-35-vasant.hegde@amd.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
b36a5b0f1c
commit
196dff712e
|
@ -51,7 +51,7 @@ struct pasid_state {
|
||||||
|
|
||||||
struct device_state {
|
struct device_state {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
u16 devid;
|
u32 sbdf;
|
||||||
atomic_t count;
|
atomic_t count;
|
||||||
struct pci_dev *pdev;
|
struct pci_dev *pdev;
|
||||||
struct pasid_state **states;
|
struct pasid_state **states;
|
||||||
|
@ -83,35 +83,25 @@ static struct workqueue_struct *iommu_wq;
|
||||||
|
|
||||||
static void free_pasid_states(struct device_state *dev_state);
|
static void free_pasid_states(struct device_state *dev_state);
|
||||||
|
|
||||||
static u16 device_id(struct pci_dev *pdev)
|
static struct device_state *__get_device_state(u32 sbdf)
|
||||||
{
|
|
||||||
u16 devid;
|
|
||||||
|
|
||||||
devid = pdev->bus->number;
|
|
||||||
devid = (devid << 8) | pdev->devfn;
|
|
||||||
|
|
||||||
return devid;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct device_state *__get_device_state(u16 devid)
|
|
||||||
{
|
{
|
||||||
struct device_state *dev_state;
|
struct device_state *dev_state;
|
||||||
|
|
||||||
list_for_each_entry(dev_state, &state_list, list) {
|
list_for_each_entry(dev_state, &state_list, list) {
|
||||||
if (dev_state->devid == devid)
|
if (dev_state->sbdf == sbdf)
|
||||||
return dev_state;
|
return dev_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct device_state *get_device_state(u16 devid)
|
static struct device_state *get_device_state(u32 sbdf)
|
||||||
{
|
{
|
||||||
struct device_state *dev_state;
|
struct device_state *dev_state;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&state_lock, flags);
|
spin_lock_irqsave(&state_lock, flags);
|
||||||
dev_state = __get_device_state(devid);
|
dev_state = __get_device_state(sbdf);
|
||||||
if (dev_state != NULL)
|
if (dev_state != NULL)
|
||||||
atomic_inc(&dev_state->count);
|
atomic_inc(&dev_state->count);
|
||||||
spin_unlock_irqrestore(&state_lock, flags);
|
spin_unlock_irqrestore(&state_lock, flags);
|
||||||
|
@ -609,7 +599,7 @@ int amd_iommu_bind_pasid(struct pci_dev *pdev, u32 pasid,
|
||||||
struct pasid_state *pasid_state;
|
struct pasid_state *pasid_state;
|
||||||
struct device_state *dev_state;
|
struct device_state *dev_state;
|
||||||
struct mm_struct *mm;
|
struct mm_struct *mm;
|
||||||
u16 devid;
|
u32 sbdf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
might_sleep();
|
might_sleep();
|
||||||
|
@ -617,8 +607,8 @@ int amd_iommu_bind_pasid(struct pci_dev *pdev, u32 pasid,
|
||||||
if (!amd_iommu_v2_supported())
|
if (!amd_iommu_v2_supported())
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
devid = device_id(pdev);
|
sbdf = get_pci_sbdf_id(pdev);
|
||||||
dev_state = get_device_state(devid);
|
dev_state = get_device_state(sbdf);
|
||||||
|
|
||||||
if (dev_state == NULL)
|
if (dev_state == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -692,15 +682,15 @@ void amd_iommu_unbind_pasid(struct pci_dev *pdev, u32 pasid)
|
||||||
{
|
{
|
||||||
struct pasid_state *pasid_state;
|
struct pasid_state *pasid_state;
|
||||||
struct device_state *dev_state;
|
struct device_state *dev_state;
|
||||||
u16 devid;
|
u32 sbdf;
|
||||||
|
|
||||||
might_sleep();
|
might_sleep();
|
||||||
|
|
||||||
if (!amd_iommu_v2_supported())
|
if (!amd_iommu_v2_supported())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
devid = device_id(pdev);
|
sbdf = get_pci_sbdf_id(pdev);
|
||||||
dev_state = get_device_state(devid);
|
dev_state = get_device_state(sbdf);
|
||||||
if (dev_state == NULL)
|
if (dev_state == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -742,7 +732,7 @@ int amd_iommu_init_device(struct pci_dev *pdev, int pasids)
|
||||||
struct iommu_group *group;
|
struct iommu_group *group;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int ret, tmp;
|
int ret, tmp;
|
||||||
u16 devid;
|
u32 sbdf;
|
||||||
|
|
||||||
might_sleep();
|
might_sleep();
|
||||||
|
|
||||||
|
@ -759,7 +749,7 @@ int amd_iommu_init_device(struct pci_dev *pdev, int pasids)
|
||||||
if (pasids <= 0 || pasids > (PASID_MASK + 1))
|
if (pasids <= 0 || pasids > (PASID_MASK + 1))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
devid = device_id(pdev);
|
sbdf = get_pci_sbdf_id(pdev);
|
||||||
|
|
||||||
dev_state = kzalloc(sizeof(*dev_state), GFP_KERNEL);
|
dev_state = kzalloc(sizeof(*dev_state), GFP_KERNEL);
|
||||||
if (dev_state == NULL)
|
if (dev_state == NULL)
|
||||||
|
@ -768,7 +758,7 @@ int amd_iommu_init_device(struct pci_dev *pdev, int pasids)
|
||||||
spin_lock_init(&dev_state->lock);
|
spin_lock_init(&dev_state->lock);
|
||||||
init_waitqueue_head(&dev_state->wq);
|
init_waitqueue_head(&dev_state->wq);
|
||||||
dev_state->pdev = pdev;
|
dev_state->pdev = pdev;
|
||||||
dev_state->devid = devid;
|
dev_state->sbdf = sbdf;
|
||||||
|
|
||||||
tmp = pasids;
|
tmp = pasids;
|
||||||
for (dev_state->pasid_levels = 0; (tmp - 1) & ~0x1ff; tmp >>= 9)
|
for (dev_state->pasid_levels = 0; (tmp - 1) & ~0x1ff; tmp >>= 9)
|
||||||
|
@ -806,7 +796,7 @@ int amd_iommu_init_device(struct pci_dev *pdev, int pasids)
|
||||||
|
|
||||||
spin_lock_irqsave(&state_lock, flags);
|
spin_lock_irqsave(&state_lock, flags);
|
||||||
|
|
||||||
if (__get_device_state(devid) != NULL) {
|
if (__get_device_state(sbdf) != NULL) {
|
||||||
spin_unlock_irqrestore(&state_lock, flags);
|
spin_unlock_irqrestore(&state_lock, flags);
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
goto out_free_domain;
|
goto out_free_domain;
|
||||||
|
@ -838,16 +828,16 @@ void amd_iommu_free_device(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
struct device_state *dev_state;
|
struct device_state *dev_state;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u16 devid;
|
u32 sbdf;
|
||||||
|
|
||||||
if (!amd_iommu_v2_supported())
|
if (!amd_iommu_v2_supported())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
devid = device_id(pdev);
|
sbdf = get_pci_sbdf_id(pdev);
|
||||||
|
|
||||||
spin_lock_irqsave(&state_lock, flags);
|
spin_lock_irqsave(&state_lock, flags);
|
||||||
|
|
||||||
dev_state = __get_device_state(devid);
|
dev_state = __get_device_state(sbdf);
|
||||||
if (dev_state == NULL) {
|
if (dev_state == NULL) {
|
||||||
spin_unlock_irqrestore(&state_lock, flags);
|
spin_unlock_irqrestore(&state_lock, flags);
|
||||||
return;
|
return;
|
||||||
|
@ -867,18 +857,18 @@ int amd_iommu_set_invalid_ppr_cb(struct pci_dev *pdev,
|
||||||
{
|
{
|
||||||
struct device_state *dev_state;
|
struct device_state *dev_state;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u16 devid;
|
u32 sbdf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!amd_iommu_v2_supported())
|
if (!amd_iommu_v2_supported())
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
devid = device_id(pdev);
|
sbdf = get_pci_sbdf_id(pdev);
|
||||||
|
|
||||||
spin_lock_irqsave(&state_lock, flags);
|
spin_lock_irqsave(&state_lock, flags);
|
||||||
|
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
dev_state = __get_device_state(devid);
|
dev_state = __get_device_state(sbdf);
|
||||||
if (dev_state == NULL)
|
if (dev_state == NULL)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
|
@ -898,18 +888,18 @@ int amd_iommu_set_invalidate_ctx_cb(struct pci_dev *pdev,
|
||||||
{
|
{
|
||||||
struct device_state *dev_state;
|
struct device_state *dev_state;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u16 devid;
|
u32 sbdf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!amd_iommu_v2_supported())
|
if (!amd_iommu_v2_supported())
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
devid = device_id(pdev);
|
sbdf = get_pci_sbdf_id(pdev);
|
||||||
|
|
||||||
spin_lock_irqsave(&state_lock, flags);
|
spin_lock_irqsave(&state_lock, flags);
|
||||||
|
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
dev_state = __get_device_state(devid);
|
dev_state = __get_device_state(sbdf);
|
||||||
if (dev_state == NULL)
|
if (dev_state == NULL)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue