Skip to content

Commit 4ebd4c7

Browse files
ssuthiku-amdjoergroedel
authored andcommitted
iommu/amd: Refactor attaching / detaching device functions
If domain is configured with V2 page table then setup default GCR3 with domain GCR3 pointer. So that all devices in the domain uses same page table for translation. Also return page table setup status from do_attach() function. Signed-off-by: Suravee Suthikulpanit <[email protected]> Co-developed-by: Vasant Hegde <[email protected]> Signed-off-by: Vasant Hegde <[email protected]> Reviewed-by: Jason Gunthorpe <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent e8e1aac commit 4ebd4c7

File tree

1 file changed

+27
-3
lines changed

1 file changed

+27
-3
lines changed

drivers/iommu/amd/iommu.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1901,10 +1901,11 @@ static void clear_dte_entry(struct amd_iommu *iommu, u16 devid)
19011901
amd_iommu_apply_erratum_63(iommu, devid);
19021902
}
19031903

1904-
static void do_attach(struct iommu_dev_data *dev_data,
1905-
struct protection_domain *domain)
1904+
static int do_attach(struct iommu_dev_data *dev_data,
1905+
struct protection_domain *domain)
19061906
{
19071907
struct amd_iommu *iommu = get_amd_iommu_from_dev_data(dev_data);
1908+
int ret = 0;
19081909

19091910
/* Update data structures */
19101911
dev_data->domain = domain;
@@ -1918,18 +1919,41 @@ static void do_attach(struct iommu_dev_data *dev_data,
19181919
domain->dev_iommu[iommu->index] += 1;
19191920
domain->dev_cnt += 1;
19201921

1922+
/* Init GCR3 table and update device table */
1923+
if (domain->pd_mode == PD_MODE_V2) {
1924+
/* By default, setup GCR3 table to support single PASID */
1925+
ret = setup_gcr3_table(dev_data->domain, 1);
1926+
if (ret)
1927+
return ret;
1928+
1929+
ret = update_gcr3(dev_data, 0,
1930+
iommu_virt_to_phys(domain->iop.pgd), true);
1931+
if (ret) {
1932+
free_gcr3_table(dev_data->domain);
1933+
return ret;
1934+
}
1935+
}
1936+
19211937
/* Update device table */
19221938
set_dte_entry(iommu, dev_data);
19231939
clone_aliases(iommu, dev_data->dev);
19241940

19251941
device_flush_dte(dev_data);
1942+
1943+
return ret;
19261944
}
19271945

19281946
static void do_detach(struct iommu_dev_data *dev_data)
19291947
{
19301948
struct protection_domain *domain = dev_data->domain;
19311949
struct amd_iommu *iommu = get_amd_iommu_from_dev_data(dev_data);
19321950

1951+
/* Clear GCR3 table */
1952+
if (domain->pd_mode == PD_MODE_V2) {
1953+
update_gcr3(dev_data, 0, 0, false);
1954+
free_gcr3_table(dev_data->domain);
1955+
}
1956+
19331957
/* Update data structures */
19341958
dev_data->domain = NULL;
19351959
list_del(&dev_data->list);
@@ -1972,7 +1996,7 @@ static int attach_device(struct device *dev,
19721996
if (dev_is_pci(dev))
19731997
pdev_enable_caps(to_pci_dev(dev));
19741998

1975-
do_attach(dev_data, domain);
1999+
ret = do_attach(dev_data, domain);
19762000

19772001
out:
19782002
spin_unlock(&dev_data->lock);

0 commit comments

Comments
 (0)