Skip to content

Commit

Permalink
Merge remote-tracking branch 'korg/core' into x86/amd
Browse files Browse the repository at this point in the history
  • Loading branch information
Joerg Roedel committed Aug 2, 2021
2 parents a270be1 + 75cc101 commit 1d65b90
Show file tree
Hide file tree
Showing 14 changed files with 437 additions and 239 deletions.
12 changes: 4 additions & 8 deletions Documentation/admin-guide/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -290,10 +290,7 @@
amd_iommu= [HW,X86-64]
Pass parameters to the AMD IOMMU driver in the system.
Possible values are:
fullflush - enable flushing of IO/TLB entries when
they are unmapped. Otherwise they are
flushed before they will be reused, which
is a lot of faster
fullflush - Deprecated, equivalent to iommu.strict=1
off - do not initialize any AMD IOMMU found in
the system
force_isolation - Force device isolation for all
Expand Down Expand Up @@ -1944,9 +1941,7 @@
this case, gfx device will use physical address for
DMA.
strict [Default Off]
With this option on every unmap_single operation will
result in a hardware IOTLB flush operation as opposed
to batching them for performance.
Deprecated, equivalent to iommu.strict=1.
sp_off [Default Off]
By default, super page will be supported if Intel IOMMU
has the capability. With this option, super page will
Expand Down Expand Up @@ -2047,9 +2042,10 @@
throughput at the cost of reduced device isolation.
Will fall back to strict mode if not supported by
the relevant IOMMU driver.
1 - Strict mode (default).
1 - Strict mode.
DMA unmap operations invalidate IOMMU hardware TLBs
synchronously.
unset - Use value of CONFIG_IOMMU_DEFAULT_{LAZY,STRICT}.
Note: on x86, the default behaviour depends on the
equivalent driver-specific parameters, but a strict
mode explicitly specified by either method takes
Expand Down
41 changes: 41 additions & 0 deletions drivers/iommu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,47 @@ config IOMMU_DEFAULT_PASSTHROUGH

If unsure, say N here.

choice
prompt "IOMMU default DMA IOTLB invalidation mode"
depends on IOMMU_DMA

default IOMMU_DEFAULT_LAZY if (AMD_IOMMU || INTEL_IOMMU)
default IOMMU_DEFAULT_STRICT
help
This option allows an IOMMU DMA IOTLB invalidation mode to be
chosen at build time, to override the default mode of each ARCH,
removing the need to pass in kernel parameters through command line.
It is still possible to provide common boot params to override this
config.

If unsure, keep the default.

config IOMMU_DEFAULT_STRICT
bool "strict"
help
For every IOMMU DMA unmap operation, the flush operation of IOTLB and
the free operation of IOVA are guaranteed to be done in the unmap
function.

config IOMMU_DEFAULT_LAZY
bool "lazy"
help
Support lazy mode, where for every IOMMU DMA unmap operation, the
flush operation of IOTLB and the free operation of IOVA are deferred.
They are only guaranteed to be done before the related IOVA will be
reused.

The isolation provided in this mode is not as secure as STRICT mode,
such that a vulnerable time window may be created between the DMA
unmap and the mappings cached in the IOMMU IOTLB or device TLB
finally being invalidated, where the device could still access the
memory which has already been unmapped by the device driver.
However this mode may provide better performance in high throughput
scenarios, and is still considerably more secure than passthrough
mode or no IOMMU.

endchoice

config OF_IOMMU
def_bool y
depends on OF && IOMMU_API
Expand Down
6 changes: 0 additions & 6 deletions drivers/iommu/amd/amd_iommu_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -779,12 +779,6 @@ extern u16 amd_iommu_last_bdf;
/* allocation bitmap for domain ids */
extern unsigned long *amd_iommu_pd_alloc_bitmap;

/*
* If true, the addresses will be flushed on unmap time, not when
* they are reused
*/
extern bool amd_iommu_unmap_flush;

/* Smallest max PASID supported by any IOMMU in the system */
extern u32 amd_iommu_max_pasid;

Expand Down
7 changes: 4 additions & 3 deletions drivers/iommu/amd/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@ u16 amd_iommu_last_bdf; /* largest PCI device id we have
to handle */
LIST_HEAD(amd_iommu_unity_map); /* a list of required unity mappings
we find in ACPI */
bool amd_iommu_unmap_flush; /* if true, flush on every unmap */

LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the
system */
Expand Down Expand Up @@ -3103,8 +3102,10 @@ static int __init parse_amd_iommu_intr(char *str)
static int __init parse_amd_iommu_options(char *str)
{
for (; *str; ++str) {
if (strncmp(str, "fullflush", 9) == 0)
amd_iommu_unmap_flush = true;
if (strncmp(str, "fullflush", 9) == 0) {
pr_warn("amd_iommu=fullflush deprecated; use iommu.strict=1 instead\n");
iommu_set_dma_strict();
}
if (strncmp(str, "force_enable", 12) == 0)
amd_iommu_force_enable = true;
if (strncmp(str, "off", 3) == 0)
Expand Down
3 changes: 0 additions & 3 deletions drivers/iommu/amd/io_pgtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -493,9 +493,6 @@ static phys_addr_t iommu_v1_iova_to_phys(struct io_pgtable_ops *ops, unsigned lo
unsigned long offset_mask, pte_pgsize;
u64 *pte, __pte;

if (pgtable->mode == PAGE_MODE_NONE)
return iova;

pte = fetch_pte(pgtable, iova, &pte_pgsize);

if (!pte || !IOMMU_PTE_PRESENT(*pte))
Expand Down
6 changes: 0 additions & 6 deletions drivers/iommu/amd/iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1818,12 +1818,6 @@ void amd_iommu_domain_update(struct protection_domain *domain)
static void __init amd_iommu_init_dma_ops(void)
{
swiotlb = (iommu_default_passthrough() || sme_me_mask) ? 1 : 0;

if (amd_iommu_unmap_flush)
pr_info("IO/TLB flush on unmap enabled\n");
else
pr_info("Lazy IO/TLB flushing enabled\n");
iommu_set_dma_strict(amd_iommu_unmap_flush);
}

int __init amd_iommu_init_api(void)
Expand Down
3 changes: 0 additions & 3 deletions drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
Original file line number Diff line number Diff line change
Expand Up @@ -2488,9 +2488,6 @@ arm_smmu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova)
{
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;

if (domain->type == IOMMU_DOMAIN_IDENTITY)
return iova;

if (!ops)
return 0;

Expand Down
21 changes: 10 additions & 11 deletions drivers/iommu/arm/arm-smmu/arm-smmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1198,8 +1198,9 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
return ret;
}

static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
phys_addr_t paddr, size_t size, int prot, gfp_t gfp)
static int arm_smmu_map_pages(struct iommu_domain *domain, unsigned long iova,
phys_addr_t paddr, size_t pgsize, size_t pgcount,
int prot, gfp_t gfp, size_t *mapped)
{
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
Expand All @@ -1209,14 +1210,15 @@ static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
return -ENODEV;

arm_smmu_rpm_get(smmu);
ret = ops->map(ops, iova, paddr, size, prot, gfp);
ret = ops->map_pages(ops, iova, paddr, pgsize, pgcount, prot, gfp, mapped);
arm_smmu_rpm_put(smmu);

return ret;
}

static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
size_t size, struct iommu_iotlb_gather *gather)
static size_t arm_smmu_unmap_pages(struct iommu_domain *domain, unsigned long iova,
size_t pgsize, size_t pgcount,
struct iommu_iotlb_gather *iotlb_gather)
{
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
Expand All @@ -1226,7 +1228,7 @@ static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
return 0;

arm_smmu_rpm_get(smmu);
ret = ops->unmap(ops, iova, size, gather);
ret = ops->unmap_pages(ops, iova, pgsize, pgcount, iotlb_gather);
arm_smmu_rpm_put(smmu);

return ret;
Expand Down Expand Up @@ -1320,9 +1322,6 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain,
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;

if (domain->type == IOMMU_DOMAIN_IDENTITY)
return iova;

if (!ops)
return 0;

Expand Down Expand Up @@ -1582,8 +1581,8 @@ static struct iommu_ops arm_smmu_ops = {
.domain_alloc = arm_smmu_domain_alloc,
.domain_free = arm_smmu_domain_free,
.attach_dev = arm_smmu_attach_dev,
.map = arm_smmu_map,
.unmap = arm_smmu_unmap,
.map_pages = arm_smmu_map_pages,
.unmap_pages = arm_smmu_unmap_pages,
.flush_iotlb_all = arm_smmu_flush_iotlb_all,
.iotlb_sync = arm_smmu_iotlb_sync,
.iova_to_phys = arm_smmu_iova_to_phys,
Expand Down
Loading

0 comments on commit 1d65b90

Please sign in to comment.