3131#include <linux/irqdomain.h>
3232#include <linux/percpu.h>
3333#include <linux/iova.h>
34+ #include <linux/io-pgtable.h>
3435#include <asm/irq_remapping.h>
3536#include <asm/io_apic.h>
3637#include <asm/apic.h>
@@ -1900,7 +1901,7 @@ static void protection_domain_free(struct protection_domain *domain)
19001901 kfree (domain );
19011902}
19021903
1903- static int protection_domain_init (struct protection_domain * domain , int mode )
1904+ static int protection_domain_init_v1 (struct protection_domain * domain , int mode )
19041905{
19051906 u64 * pt_root = NULL ;
19061907
@@ -1923,34 +1924,55 @@ static int protection_domain_init(struct protection_domain *domain, int mode)
19231924 return 0 ;
19241925}
19251926
1926- static struct protection_domain * protection_domain_alloc (int mode )
1927+ static struct protection_domain * protection_domain_alloc (unsigned int type )
19271928{
1929+ struct io_pgtable_ops * pgtbl_ops ;
19281930 struct protection_domain * domain ;
1931+ int pgtable = amd_iommu_pgtable ;
1932+ int mode = DEFAULT_PGTABLE_LEVEL ;
1933+ int ret ;
19291934
19301935 domain = kzalloc (sizeof (* domain ), GFP_KERNEL );
19311936 if (!domain )
19321937 return NULL ;
19331938
1934- if (protection_domain_init (domain , mode ))
1939+ /*
1940+ * Force IOMMU v1 page table when iommu=pt and
1941+ * when allocating domain for pass-through devices.
1942+ */
1943+ if (type == IOMMU_DOMAIN_IDENTITY ) {
1944+ pgtable = AMD_IOMMU_V1 ;
1945+ mode = PAGE_MODE_NONE ;
1946+ } else if (type == IOMMU_DOMAIN_UNMANAGED ) {
1947+ pgtable = AMD_IOMMU_V1 ;
1948+ }
1949+
1950+ switch (pgtable ) {
1951+ case AMD_IOMMU_V1 :
1952+ ret = protection_domain_init_v1 (domain , mode );
1953+ break ;
1954+ default :
1955+ ret = - EINVAL ;
1956+ }
1957+
1958+ if (ret )
19351959 goto out_err ;
19361960
1937- return domain ;
1961+ pgtbl_ops = alloc_io_pgtable_ops (pgtable , & domain -> iop .pgtbl_cfg , domain );
1962+ if (!pgtbl_ops )
1963+ goto out_err ;
19381964
1965+ return domain ;
19391966out_err :
19401967 kfree (domain );
1941-
19421968 return NULL ;
19431969}
19441970
19451971static struct iommu_domain * amd_iommu_domain_alloc (unsigned type )
19461972{
19471973 struct protection_domain * domain ;
1948- int mode = DEFAULT_PGTABLE_LEVEL ;
1949-
1950- if (type == IOMMU_DOMAIN_IDENTITY )
1951- mode = PAGE_MODE_NONE ;
19521974
1953- domain = protection_domain_alloc (mode );
1975+ domain = protection_domain_alloc (type );
19541976 if (!domain )
19551977 return NULL ;
19561978
@@ -2069,7 +2091,8 @@ static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova,
20692091 int prot = 0 ;
20702092 int ret = - EINVAL ;
20712093
2072- if (domain -> iop .mode == PAGE_MODE_NONE )
2094+ if ((amd_iommu_pgtable == AMD_IOMMU_V1 ) &&
2095+ (domain -> iop .mode == PAGE_MODE_NONE ))
20732096 return - EINVAL ;
20742097
20752098 if (iommu_prot & IOMMU_READ )
@@ -2092,7 +2115,8 @@ static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova,
20922115 struct protection_domain * domain = to_pdomain (dom );
20932116 struct io_pgtable_ops * ops = & domain -> iop .iop .ops ;
20942117
2095- if (domain -> iop .mode == PAGE_MODE_NONE )
2118+ if ((amd_iommu_pgtable == AMD_IOMMU_V1 ) &&
2119+ (domain -> iop .mode == PAGE_MODE_NONE ))
20962120 return 0 ;
20972121
20982122 return (ops -> unmap ) ? ops -> unmap (ops , iova , page_size , gather ) : 0 ;
0 commit comments