Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1709638 > unrolled thread

[RFC v2 0/4] arm-smmu-v3 tlbi-on-map option

Started byEric Auger <eric.auger@redhat.com>
First post2017-08-11 15:50 +0200
Last post2017-08-11 15:50 +0200
Articles 4 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [RFC v2 0/4] arm-smmu-v3 tlbi-on-map option Eric Auger <eric.auger@redhat.com> - 2017-08-11 15:50 +0200
    [RFC v2 3/4] iommu/arm-smmu-v3: Add hypothetical caching mode model Eric Auger <eric.auger@redhat.com> - 2017-08-11 15:50 +0200
    [RFC v2 1/4] iommu/io-pgtable-arm: flush TLBs when IO_PGTABLE_QUIRK_TLBI_ON_MAP Eric Auger <eric.auger@redhat.com> - 2017-08-11 15:50 +0200
    [RFC v2 4/4] iommu/arm-smmu-v3: add CMD_TLBI_NH_VA_AM command for iova range invalidation Eric Auger <eric.auger@redhat.com> - 2017-08-11 15:50 +0200

#1709638 — [RFC v2 0/4] arm-smmu-v3 tlbi-on-map option

FromEric Auger <eric.auger@redhat.com>
Date2017-08-11 15:50 +0200
Subject[RFC v2 0/4] arm-smmu-v3 tlbi-on-map option
Message-ID<udiu5-4b4-7@gated-at.bofh.it>
This series adds a new tlbi-on-map option to the smmuv3 driver.
When set, the IO_PGTABLE_QUIRK_TLBI_ON_MAP quirk is applied for
LPAE tables and the smmuv3 driver sends TLB invalidations on map.

This mode is useful when running the driver on a guest as it allows
the virtualizer to trap any change to the translation structures.
This is similar to the Intel vtd caching mode (CM).

This is mandated for vSMMUv3/VFIO integration where guest mappings
must be applied to the physical IOMMU and also for VHOST.

When this mode is set we use an implementation defined TLBI
invalidation command which allows to invalidate a range of IOVA
instead of using CMD_TLBI_NH_VA which works by page. This
is needed for sake of efficiency when running DPDK use case on
guest as DPDK uses hugepages. As far as I understand the intel
IOMMU provides such invalidation command (using the address mask
parameter) and at the moment, I haven't found something similar
in the smmuv3 architecture specification.

Best Regards

Eric

Git: complete series available at
https://github.com/eauger/linux/tree/v4.13-rc3-tlbi-on-map-rfcv2

History:
v1 -> v2:
- add support for ACPI probing
- add implementation defined CMD_TLBI_NH_VA_AM which allows
  IOVA range invalidation


Eric Auger (4):
  iommu/io-pgtable-arm: flush TLBs when IO_PGTABLE_QUIRK_TLBI_ON_MAP
  iommu/arm-smmu-v3: Add tlbi_on_map option
  iommu/arm-smmu-v3: Add hypothetical caching mode model
  iommu/arm-smmu-v3: add CMD_TLBI_NH_VA_AM command for iova range
    invalidation

 .../devicetree/bindings/iommu/arm,smmu-v3.txt      |  4 +++
 drivers/iommu/arm-smmu-v3.c                        | 34 ++++++++++++++++++++--
 drivers/iommu/io-pgtable-arm.c                     | 14 +++++++--
 3 files changed, 48 insertions(+), 4 deletions(-)

-- 
2.5.5

[toc] | [next] | [standalone]


#1709639 — [RFC v2 3/4] iommu/arm-smmu-v3: Add hypothetical caching mode model

FromEric Auger <eric.auger@redhat.com>
Date2017-08-11 15:50 +0200
Subject[RFC v2 3/4] iommu/arm-smmu-v3: Add hypothetical caching mode model
Message-ID<udiu5-4b4-9@gated-at.bofh.it>
In reply to#1709638
Let's add an hypothetical "caching mode" smmuv3 model (not yet
discussed for IORT spec) and enable the TLBI_ON_MAP option for
this latter.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 drivers/iommu/arm-smmu-v3.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 690247b..a1c10af 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -422,6 +422,10 @@
 #define ACPI_IORT_SMMU_V3_CAVIUM_CN99XX		0x2
 #endif
 
+#ifndef ACPI_IORT_SMMU_V3_CACHING_MODE
+#define ACPI_IORT_SMMU_V3_CACHING_MODE		0x3
+#endif
+
 static bool disable_bypass;
 module_param_named(disable_bypass, disable_bypass, bool, S_IRUGO);
 MODULE_PARM_DESC(disable_bypass,
@@ -2673,6 +2677,9 @@ static void acpi_smmu_get_options(u32 model, struct arm_smmu_device *smmu)
 	case ACPI_IORT_SMMU_HISILICON_HI161X:
 		smmu->options |= ARM_SMMU_OPT_SKIP_PREFETCH;
 		break;
+	case ACPI_IORT_SMMU_V3_CACHING_MODE:
+		smmu->options |= ARM_SMMU_OPT_TLBI_ON_MAP;
+		break;
 	}
 
 	dev_notice(smmu->dev, "option mask 0x%x\n", smmu->options);
-- 
2.5.5

[toc] | [prev] | [next] | [standalone]


#1709641 — [RFC v2 1/4] iommu/io-pgtable-arm: flush TLBs when IO_PGTABLE_QUIRK_TLBI_ON_MAP

FromEric Auger <eric.auger@redhat.com>
Date2017-08-11 15:50 +0200
Subject[RFC v2 1/4] iommu/io-pgtable-arm: flush TLBs when IO_PGTABLE_QUIRK_TLBI_ON_MAP
Message-ID<udiu5-4b4-11@gated-at.bofh.it>
In reply to#1709638
This patch implements the IO_PGTABLE_QUIRK_TLBI_ON_MAP quirk for
LPAE page tables. It forces TLB invalidations on map.

Signed-off-by: Eric Auger <eric.auger@redhat.com>

---
v1 -> v2:
- rebase on v4.13-rc2
---
 drivers/iommu/io-pgtable-arm.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index b182039..198a042 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -447,6 +447,8 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova,
 	arm_lpae_iopte *ptep = data->pgd;
 	int ret, lvl = ARM_LPAE_START_LVL(data);
 	arm_lpae_iopte prot;
+	struct io_pgtable *iop = &data->iop;
+	struct io_pgtable_cfg *cfg = &data->iop.cfg;
 
 	/* If no access, then nothing to do */
 	if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE)))
@@ -454,6 +456,12 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova,
 
 	prot = arm_lpae_prot_to_pte(data, iommu_prot);
 	ret = __arm_lpae_map(data, iova, paddr, size, prot, lvl, ptep);
+
+	if (cfg->quirks & IO_PGTABLE_QUIRK_TLBI_ON_MAP) {
+		io_pgtable_tlb_add_flush(iop, iova, size,
+					 ARM_LPAE_GRANULE(data), false);
+		io_pgtable_tlb_sync(iop);
+	}
 	/*
 	 * Synchronise all PTE updates for the new mapping before there's
 	 * a chance for anything to kick off a table walk for the new iova.
@@ -739,7 +747,8 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
 	u64 reg;
 	struct arm_lpae_io_pgtable *data;
 
-	if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS | IO_PGTABLE_QUIRK_NO_DMA))
+	if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS | IO_PGTABLE_QUIRK_NO_DMA |
+			    IO_PGTABLE_QUIRK_TLBI_ON_MAP))
 		return NULL;
 
 	data = arm_lpae_alloc_pgtable(cfg);
@@ -828,7 +837,8 @@ arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
 	struct arm_lpae_io_pgtable *data;
 
 	/* The NS quirk doesn't apply at stage 2 */
-	if (cfg->quirks & ~IO_PGTABLE_QUIRK_NO_DMA)
+	if (cfg->quirks &
+		~(IO_PGTABLE_QUIRK_NO_DMA | IO_PGTABLE_QUIRK_TLBI_ON_MAP))
 		return NULL;
 
 	data = arm_lpae_alloc_pgtable(cfg);
-- 
2.5.5

[toc] | [prev] | [next] | [standalone]


#1709646 — [RFC v2 4/4] iommu/arm-smmu-v3: add CMD_TLBI_NH_VA_AM command for iova range invalidation

FromEric Auger <eric.auger@redhat.com>
Date2017-08-11 15:50 +0200
Subject[RFC v2 4/4] iommu/arm-smmu-v3: add CMD_TLBI_NH_VA_AM command for iova range invalidation
Message-ID<udiu6-4b4-27@gated-at.bofh.it>
In reply to#1709638
When using a virtual SMMU and running the driver in TLBI_ON_MAP
mode we need invalidate large IOVA ranges. This typically happens
in DPDK use case where hugepages are used. In that case, invalidating
pages by page is really inefficient and we would need to invalidate
by iova range. Unfortunately there is no such command specified in the
SMMUv3 architecture spec. Let's add a new implementation defined command
that takes an address mask.

The CMD_TLBI_NH_VA_AM command format is inherited from CMD_TLBI_NH_VA's
one, replace the currently unused VMID field by the AM field.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 drivers/iommu/arm-smmu-v3.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index a1c10af..9da2785 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -492,9 +492,15 @@ struct arm_smmu_cmdq_ent {
 		#define CMDQ_OP_TLBI_S12_VMALL	0x28
 		#define CMDQ_OP_TLBI_S2_IPA	0x2a
 		#define CMDQ_OP_TLBI_NSNH_ALL	0x30
+
+		/* vIOMMU ASID/IOVA Range Invalidation */
+		#define CMDQ_OP_TLBI_NH_VA_AM	0x8F
 		struct {
 			u16			asid;
-			u16			vmid;
+			union {
+				u16		vmid;
+				u16		am; /* address mask */
+			};
 			bool			leaf;
 			u64			addr;
 		} tlbi;
@@ -853,6 +859,12 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
 		cmd[1] |= ent->tlbi.leaf ? CMDQ_TLBI_1_LEAF : 0;
 		cmd[1] |= ent->tlbi.addr & CMDQ_TLBI_1_VA_MASK;
 		break;
+	case CMDQ_OP_TLBI_NH_VA_AM:
+		cmd[0] |= (u64)ent->tlbi.asid << CMDQ_TLBI_0_ASID_SHIFT;
+		cmd[0] |= (u64)ent->tlbi.am << CMDQ_TLBI_0_VMID_SHIFT;
+		cmd[1] |= ent->tlbi.leaf ? CMDQ_TLBI_1_LEAF : 0;
+		cmd[1] |= ent->tlbi.addr & CMDQ_TLBI_1_VA_MASK;
+		break;
 	case CMDQ_OP_TLBI_S2_IPA:
 		cmd[0] |= (u64)ent->tlbi.vmid << CMDQ_TLBI_0_VMID_SHIFT;
 		cmd[1] |= ent->tlbi.leaf ? CMDQ_TLBI_1_LEAF : 0;
@@ -1402,8 +1414,14 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
 	};
 
 	if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
-		cmd.opcode	= CMDQ_OP_TLBI_NH_VA;
 		cmd.tlbi.asid	= smmu_domain->s1_cfg.cd.asid;
+		if (smmu->options & ARM_SMMU_OPT_TLBI_ON_MAP) {
+			cmd.opcode	= CMDQ_OP_TLBI_NH_VA_AM;
+			cmd.tlbi.am   = size >> 12;
+			granule = size;
+		} else {
+			cmd.opcode	= CMDQ_OP_TLBI_NH_VA;
+		}
 	} else {
 		cmd.opcode	= CMDQ_OP_TLBI_S2_IPA;
 		cmd.tlbi.vmid	= smmu_domain->s2_cfg.vmid;
-- 
2.5.5

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web