Commit 196dff71 authored by Vasant Hegde's avatar Vasant Hegde Committed by Joerg Roedel
Browse files

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: default avatarSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Signed-off-by: default avatarSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Signed-off-by: default avatarVasant Hegde <vasant.hegde@amd.com>
Link: https://lore.kernel.org/r/20220706113825.25582-35-vasant.hegde@amd.com


Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent b36a5b0f
Loading
Loading
Loading
Loading
+24 −34
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ struct pasid_state {

struct device_state {
	struct list_head list;
	u16 devid;
	u32 sbdf;
	atomic_t count;
	struct pci_dev *pdev;
	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 u16 device_id(struct pci_dev *pdev)
{
	u16 devid;

	devid = pdev->bus->number;
	devid = (devid << 8) | pdev->devfn;

	return devid;
}

static struct device_state *__get_device_state(u16 devid)
static struct device_state *__get_device_state(u32 sbdf)
{
	struct device_state *dev_state;

	list_for_each_entry(dev_state, &state_list, list) {
		if (dev_state->devid == devid)
		if (dev_state->sbdf == sbdf)
			return dev_state;
	}

	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;
	unsigned long flags;

	spin_lock_irqsave(&state_lock, flags);
	dev_state = __get_device_state(devid);
	dev_state = __get_device_state(sbdf);
	if (dev_state != NULL)
		atomic_inc(&dev_state->count);
	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 device_state *dev_state;
	struct mm_struct *mm;
	u16 devid;
	u32 sbdf;
	int ret;

	might_sleep();
@@ -617,8 +607,8 @@ int amd_iommu_bind_pasid(struct pci_dev *pdev, u32 pasid,
	if (!amd_iommu_v2_supported())
		return -ENODEV;

	devid     = device_id(pdev);
	dev_state = get_device_state(devid);
	sbdf      = get_pci_sbdf_id(pdev);
	dev_state = get_device_state(sbdf);

	if (dev_state == NULL)
		return -EINVAL;
@@ -692,15 +682,15 @@ void amd_iommu_unbind_pasid(struct pci_dev *pdev, u32 pasid)
{
	struct pasid_state *pasid_state;
	struct device_state *dev_state;
	u16 devid;
	u32 sbdf;

	might_sleep();

	if (!amd_iommu_v2_supported())
		return;

	devid = device_id(pdev);
	dev_state = get_device_state(devid);
	sbdf = get_pci_sbdf_id(pdev);
	dev_state = get_device_state(sbdf);
	if (dev_state == NULL)
		return;

@@ -742,7 +732,7 @@ int amd_iommu_init_device(struct pci_dev *pdev, int pasids)
	struct iommu_group *group;
	unsigned long flags;
	int ret, tmp;
	u16 devid;
	u32 sbdf;

	might_sleep();

@@ -759,7 +749,7 @@ int amd_iommu_init_device(struct pci_dev *pdev, int pasids)
	if (pasids <= 0 || pasids > (PASID_MASK + 1))
		return -EINVAL;

	devid = device_id(pdev);
	sbdf = get_pci_sbdf_id(pdev);

	dev_state = kzalloc(sizeof(*dev_state), GFP_KERNEL);
	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);
	init_waitqueue_head(&dev_state->wq);
	dev_state->pdev  = pdev;
	dev_state->devid = devid;
	dev_state->sbdf = sbdf;

	tmp = pasids;
	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);

	if (__get_device_state(devid) != NULL) {
	if (__get_device_state(sbdf) != NULL) {
		spin_unlock_irqrestore(&state_lock, flags);
		ret = -EBUSY;
		goto out_free_domain;
@@ -838,16 +828,16 @@ void amd_iommu_free_device(struct pci_dev *pdev)
{
	struct device_state *dev_state;
	unsigned long flags;
	u16 devid;
	u32 sbdf;

	if (!amd_iommu_v2_supported())
		return;

	devid = device_id(pdev);
	sbdf = get_pci_sbdf_id(pdev);

	spin_lock_irqsave(&state_lock, flags);

	dev_state = __get_device_state(devid);
	dev_state = __get_device_state(sbdf);
	if (dev_state == NULL) {
		spin_unlock_irqrestore(&state_lock, flags);
		return;
@@ -867,18 +857,18 @@ int amd_iommu_set_invalid_ppr_cb(struct pci_dev *pdev,
{
	struct device_state *dev_state;
	unsigned long flags;
	u16 devid;
	u32 sbdf;
	int ret;

	if (!amd_iommu_v2_supported())
		return -ENODEV;

	devid = device_id(pdev);
	sbdf = get_pci_sbdf_id(pdev);

	spin_lock_irqsave(&state_lock, flags);

	ret = -EINVAL;
	dev_state = __get_device_state(devid);
	dev_state = __get_device_state(sbdf);
	if (dev_state == NULL)
		goto out_unlock;

@@ -898,18 +888,18 @@ int amd_iommu_set_invalidate_ctx_cb(struct pci_dev *pdev,
{
	struct device_state *dev_state;
	unsigned long flags;
	u16 devid;
	u32 sbdf;
	int ret;

	if (!amd_iommu_v2_supported())
		return -ENODEV;

	devid = device_id(pdev);
	sbdf = get_pci_sbdf_id(pdev);

	spin_lock_irqsave(&state_lock, flags);

	ret = -EINVAL;
	dev_state = __get_device_state(devid);
	dev_state = __get_device_state(sbdf);
	if (dev_state == NULL)
		goto out_unlock;