Skip to content

Commit a2ce608

Browse files
ssuthiku-amdjoergroedel
authored andcommitted
iommu/amd: Introduce helper function get_dte256()
And use it in clone_alias() along with update_dte256(). Also use get_dte256() in dump_dte_entry(). Reviewed-by: Jason Gunthorpe <[email protected]> Signed-off-by: Suravee Suthikulpanit <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent fd5dff9 commit a2ce608

File tree

1 file changed

+51
-11
lines changed

1 file changed

+51
-11
lines changed

drivers/iommu/amd/iommu.c

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ static void set_dte_entry(struct amd_iommu *iommu,
8585

8686
static void iommu_flush_dte_sync(struct amd_iommu *iommu, u16 devid);
8787

88+
static struct iommu_dev_data *find_dev_data(struct amd_iommu *iommu, u16 devid);
89+
8890
/****************************************************************************
8991
*
9092
* Helper functions
@@ -202,6 +204,21 @@ static void update_dte256(struct amd_iommu *iommu, struct iommu_dev_data *dev_da
202204
spin_unlock_irqrestore(&dev_data->dte_lock, flags);
203205
}
204206

207+
static void get_dte256(struct amd_iommu *iommu, struct iommu_dev_data *dev_data,
208+
struct dev_table_entry *dte)
209+
{
210+
unsigned long flags;
211+
struct dev_table_entry *ptr;
212+
struct dev_table_entry *dev_table = get_dev_table(iommu);
213+
214+
ptr = &dev_table[dev_data->devid];
215+
216+
spin_lock_irqsave(&dev_data->dte_lock, flags);
217+
dte->data128[0] = ptr->data128[0];
218+
dte->data128[1] = ptr->data128[1];
219+
spin_unlock_irqrestore(&dev_data->dte_lock, flags);
220+
}
221+
205222
static inline bool pdom_is_v2_pgtbl_mode(struct protection_domain *pdom)
206223
{
207224
return (pdom && (pdom->pd_mode == PD_MODE_V2));
@@ -350,9 +367,11 @@ static struct iommu_dev_data *search_dev_data(struct amd_iommu *iommu, u16 devid
350367

351368
static int clone_alias(struct pci_dev *pdev, u16 alias, void *data)
352369
{
370+
struct dev_table_entry new;
353371
struct amd_iommu *iommu;
354-
struct dev_table_entry *dev_table;
372+
struct iommu_dev_data *dev_data, *alias_data;
355373
u16 devid = pci_dev_id(pdev);
374+
int ret = 0;
356375

357376
if (devid == alias)
358377
return 0;
@@ -361,13 +380,27 @@ static int clone_alias(struct pci_dev *pdev, u16 alias, void *data)
361380
if (!iommu)
362381
return 0;
363382

364-
amd_iommu_set_rlookup_table(iommu, alias);
365-
dev_table = get_dev_table(iommu);
366-
memcpy(dev_table[alias].data,
367-
dev_table[devid].data,
368-
sizeof(dev_table[alias].data));
383+
/* Copy the data from pdev */
384+
dev_data = dev_iommu_priv_get(&pdev->dev);
385+
if (!dev_data) {
386+
pr_err("%s : Failed to get dev_data for 0x%x\n", __func__, devid);
387+
ret = -EINVAL;
388+
goto out;
389+
}
390+
get_dte256(iommu, dev_data, &new);
369391

370-
return 0;
392+
/* Setup alias */
393+
alias_data = find_dev_data(iommu, alias);
394+
if (!alias_data) {
395+
pr_err("%s : Failed to get alias dev_data for 0x%x\n", __func__, alias);
396+
ret = -EINVAL;
397+
goto out;
398+
}
399+
update_dte256(iommu, alias_data, &new);
400+
401+
amd_iommu_set_rlookup_table(iommu, alias);
402+
out:
403+
return ret;
371404
}
372405

373406
static void clone_aliases(struct amd_iommu *iommu, struct device *dev)
@@ -640,6 +673,12 @@ static int iommu_init_device(struct amd_iommu *iommu, struct device *dev)
640673
return -ENOMEM;
641674

642675
dev_data->dev = dev;
676+
677+
/*
678+
* The dev_iommu_priv_set() needes to be called before setup_aliases.
679+
* Otherwise, subsequent call to dev_iommu_priv_get() will fail.
680+
*/
681+
dev_iommu_priv_set(dev, dev_data);
643682
setup_aliases(iommu, dev);
644683

645684
/*
@@ -653,8 +692,6 @@ static int iommu_init_device(struct amd_iommu *iommu, struct device *dev)
653692
dev_data->flags = pdev_get_caps(to_pci_dev(dev));
654693
}
655694

656-
dev_iommu_priv_set(dev, dev_data);
657-
658695
return 0;
659696
}
660697

@@ -685,10 +722,13 @@ static void iommu_ignore_device(struct amd_iommu *iommu, struct device *dev)
685722
static void dump_dte_entry(struct amd_iommu *iommu, u16 devid)
686723
{
687724
int i;
688-
struct dev_table_entry *dev_table = get_dev_table(iommu);
725+
struct dev_table_entry dte;
726+
struct iommu_dev_data *dev_data = find_dev_data(iommu, devid);
727+
728+
get_dte256(iommu, dev_data, &dte);
689729

690730
for (i = 0; i < 4; ++i)
691-
pr_err("DTE[%d]: %016llx\n", i, dev_table[devid].data[i]);
731+
pr_err("DTE[%d]: %016llx\n", i, dte.data[i]);
692732
}
693733

694734
static void dump_command(unsigned long phys_addr)

0 commit comments

Comments
 (0)