Skip to content

Commit 25c776d

Browse files
Kunkun Jiangwilldeacon
authored andcommitted
iommu/arm-smmu-v3: Enable HTTU for stage1 with io-pgtable mapping
If io-pgtable quirk flag indicates support for hardware update of dirty state, enable HA/HD bits in the SMMU CD and also set the DBM bit in the page descriptor. Now report the dirty page tracking capability of SMMUv3 and select IOMMUFD_DRIVER for ARM_SMMU_V3 if IOMMUFD is enabled. Co-developed-by: Keqian Zhu <[email protected]> Signed-off-by: Keqian Zhu <[email protected]> Signed-off-by: Kunkun Jiang <[email protected]> Signed-off-by: Joao Martins <[email protected]> Reviewed-by: Ryan Roberts <[email protected]> Reviewed-by: Jason Gunthorpe <[email protected]> Reviewed-by: Nicolin Chen <[email protected]> Signed-off-by: Shameer Kolothum <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent eb054d6 commit 25c776d

File tree

4 files changed

+23
-1
lines changed

4 files changed

+23
-1
lines changed

drivers/iommu/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ config ARM_SMMU_V3
394394
select IOMMU_API
395395
select IOMMU_IO_PGTABLE_LPAE
396396
select GENERIC_MSI_IRQ
397+
select IOMMUFD_DRIVER if IOMMUFD
397398
help
398399
Support for implementations of the ARM System MMU architecture
399400
version 3 providing translation support to a PCIe root complex.

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,6 +1352,12 @@ void arm_smmu_make_s1_cd(struct arm_smmu_cd *target,
13521352
CTXDESC_CD_0_ASET |
13531353
FIELD_PREP(CTXDESC_CD_0_ASID, cd->asid)
13541354
);
1355+
1356+
/* To enable dirty flag update, set both Access flag and dirty state update */
1357+
if (pgtbl_cfg->quirks & IO_PGTABLE_QUIRK_ARM_HD)
1358+
target->data[0] |= cpu_to_le64(CTXDESC_CD_0_TCR_HA |
1359+
CTXDESC_CD_0_TCR_HD);
1360+
13551361
target->data[1] = cpu_to_le64(pgtbl_cfg->arm_lpae_s1_cfg.ttbr &
13561362
CTXDESC_CD_1_TTB0_MASK);
13571363
target->data[3] = cpu_to_le64(pgtbl_cfg->arm_lpae_s1_cfg.mair);
@@ -2235,6 +2241,13 @@ static const struct iommu_flush_ops arm_smmu_flush_ops = {
22352241
.tlb_add_page = arm_smmu_tlb_inv_page_nosync,
22362242
};
22372243

2244+
static bool arm_smmu_dbm_capable(struct arm_smmu_device *smmu)
2245+
{
2246+
u32 features = (ARM_SMMU_FEAT_HD | ARM_SMMU_FEAT_COHERENCY);
2247+
2248+
return (smmu->features & features) == features;
2249+
}
2250+
22382251
/* IOMMU API */
22392252
static bool arm_smmu_capable(struct device *dev, enum iommu_cap cap)
22402253
{
@@ -2247,6 +2260,8 @@ static bool arm_smmu_capable(struct device *dev, enum iommu_cap cap)
22472260
case IOMMU_CAP_NOEXEC:
22482261
case IOMMU_CAP_DEFERRED_FLUSH:
22492262
return true;
2263+
case IOMMU_CAP_DIRTY_TRACKING:
2264+
return arm_smmu_dbm_capable(master->smmu);
22502265
default:
22512266
return false;
22522267
}

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,9 @@ struct arm_smmu_cd {
304304
#define CTXDESC_CD_0_TCR_IPS GENMASK_ULL(34, 32)
305305
#define CTXDESC_CD_0_TCR_TBI0 (1ULL << 38)
306306

307+
#define CTXDESC_CD_0_TCR_HA (1UL << 43)
308+
#define CTXDESC_CD_0_TCR_HD (1UL << 42)
309+
307310
#define CTXDESC_CD_0_AA64 (1UL << 41)
308311
#define CTXDESC_CD_0_S (1UL << 44)
309312
#define CTXDESC_CD_0_R (1UL << 45)

drivers/iommu/io-pgtable-arm.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,8 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
440440
pte = ARM_LPAE_PTE_nG;
441441
if (!(prot & IOMMU_WRITE) && (prot & IOMMU_READ))
442442
pte |= ARM_LPAE_PTE_AP_RDONLY;
443+
else if (data->iop.cfg.quirks & IO_PGTABLE_QUIRK_ARM_HD)
444+
pte |= ARM_LPAE_PTE_DBM;
443445
if (!(prot & IOMMU_PRIV))
444446
pte |= ARM_LPAE_PTE_AP_UNPRIV;
445447
} else {
@@ -929,7 +931,8 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
929931

930932
if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
931933
IO_PGTABLE_QUIRK_ARM_TTBR1 |
932-
IO_PGTABLE_QUIRK_ARM_OUTER_WBWA))
934+
IO_PGTABLE_QUIRK_ARM_OUTER_WBWA |
935+
IO_PGTABLE_QUIRK_ARM_HD))
933936
return NULL;
934937

935938
data = arm_lpae_alloc_pgtable(cfg);

0 commit comments

Comments
 (0)