Skip to content

Commit 89c9a09

Browse files
ssuthiku-amdjoergroedel
authored andcommitted
iommu/amd: Adopt IO page table framework for AMD IOMMU v1 page table
Switch to using IO page table framework for AMD IOMMU v1 page table. Signed-off-by: Suravee Suthikulpanit <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent fd86c95 commit 89c9a09

File tree

3 files changed

+39
-12
lines changed

3 files changed

+39
-12
lines changed

drivers/iommu/amd/amd_iommu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ extern void amd_iommu_disable(void);
3636
extern int amd_iommu_reenable(int);
3737
extern int amd_iommu_enable_faulting(void);
3838
extern int amd_iommu_guest_ir;
39+
extern enum io_pgtable_fmt amd_iommu_pgtable;
3940

4041
/* IOMMUv2 specific functions */
4142
struct iommu_domain;

drivers/iommu/amd/init.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ struct ivmd_header {
147147
bool amd_iommu_dump;
148148
bool amd_iommu_irq_remap __read_mostly;
149149

150+
enum io_pgtable_fmt amd_iommu_pgtable = AMD_IOMMU_V1;
151+
150152
int amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_VAPIC;
151153
static int amd_iommu_xt_mode = IRQ_REMAP_XAPIC_MODE;
152154

drivers/iommu/amd/iommu.c

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
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;
19391966
out_err:
19401967
kfree(domain);
1941-
19421968
return NULL;
19431969
}
19441970

19451971
static 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

Comments
 (0)