Commit af9c5ba6 authored by Kunkun Jiang's avatar Kunkun Jiang Committed by Jia Qingtong
Browse files

iommu/io-pgtable-arm: Add quirk ARM_HD and ARM_BBMLx

virt inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I3ZUKK


CVE: NA

------------------------------

These features are essential to support dirty log tracking for
SMMU with io-pgtable mapping.

The dirty state information is encoded using the access permission
bits AP[2] (stage 1) or S2AP[1] (stage 2) in conjunction with the
DBM (Dirty Bit Modifier) bit, where DBM means writable and AP[2]/
S2AP[1] means dirty.

When has ARM_HD, we set DBM bit for S1 mapping. As SMMU nested
mode is not upstreamed for now, we just aim to support dirty
log tracking for stage1 with io-pgtable mapping (means not support
SVA).

Signed-off-by: default avatarKeqian Zhu <zhukeqian1@huawei.com>
Signed-off-by: default avatarKunkun Jiang <jiangkunkun@huawei.com>
Signed-off-by: default avatarJia Qingtong <jiaqingtong@huawei.com>
parent 03b784a5
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@

#define ARM_LPAE_PTE_NSTABLE		(((arm_lpae_iopte)1) << 63)
#define ARM_LPAE_PTE_XN			(((arm_lpae_iopte)3) << 53)
#define ARM_LPAE_PTE_DBM		(((arm_lpae_iopte)1) << 51)
#define ARM_LPAE_PTE_AF			(((arm_lpae_iopte)1) << 10)
#define ARM_LPAE_PTE_SH_NS		(((arm_lpae_iopte)0) << 8)
#define ARM_LPAE_PTE_SH_OS		(((arm_lpae_iopte)2) << 8)
@@ -84,7 +85,7 @@

#define ARM_LPAE_PTE_ATTR_LO_MASK	(((arm_lpae_iopte)0x3ff) << 2)
/* Ignore the contiguous bit for block splitting */
#define ARM_LPAE_PTE_ATTR_HI_MASK	(((arm_lpae_iopte)6) << 52)
#define ARM_LPAE_PTE_ATTR_HI_MASK	(((arm_lpae_iopte)13) << 51)
#define ARM_LPAE_PTE_ATTR_MASK		(ARM_LPAE_PTE_ATTR_LO_MASK |	\
					 ARM_LPAE_PTE_ATTR_HI_MASK)
/* Software bit for solving coherency races */
@@ -400,6 +401,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
					   int prot)
{
	struct io_pgtable_cfg *cfg = &data->iop.cfg;
	arm_lpae_iopte pte;

	if (data->iop.fmt == ARM_64_LPAE_S1 ||
@@ -407,6 +409,10 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
		pte = ARM_LPAE_PTE_nG;
		if (!(prot & IOMMU_WRITE) && (prot & IOMMU_READ))
			pte |= ARM_LPAE_PTE_AP_RDONLY;
		else if (data->iop.fmt == ARM_64_LPAE_S1 &&
			 cfg->quirks & IO_PGTABLE_QUIRK_ARM_HD)
			pte |= ARM_LPAE_PTE_DBM;

		if (!(prot & IOMMU_PRIV))
			pte |= ARM_LPAE_PTE_AP_UNPRIV;
	} else {
@@ -804,7 +810,10 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)

	if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
			    IO_PGTABLE_QUIRK_ARM_TTBR1 |
			    IO_PGTABLE_QUIRK_ARM_OUTER_WBWA))
			    IO_PGTABLE_QUIRK_ARM_OUTER_WBWA |
			    IO_PGTABLE_QUIRK_ARM_HD |
			    IO_PGTABLE_QUIRK_ARM_BBML1 |
			    IO_PGTABLE_QUIRK_ARM_BBML2))
		return NULL;

	data = arm_lpae_alloc_pgtable(cfg);
@@ -906,7 +915,9 @@ arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
	typeof(&cfg->arm_lpae_s2_cfg.vtcr) vtcr = &cfg->arm_lpae_s2_cfg.vtcr;

	/* The NS quirk doesn't apply at stage 2 */
	if (cfg->quirks)
	if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_HD |
			    IO_PGTABLE_QUIRK_ARM_BBML1 |
			    IO_PGTABLE_QUIRK_ARM_BBML2))
		return NULL;

	data = arm_lpae_alloc_pgtable(cfg);
+11 −0
Original line number Diff line number Diff line
@@ -85,6 +85,14 @@ struct io_pgtable_cfg {
	 *
	 * IO_PGTABLE_QUIRK_ARM_OUTER_WBWA: Override the outer-cacheability
	 *	attributes set in the TCR for a non-coherent page-table walker.
	 *
	 * IO_PGTABLE_QUIRK_ARM_HD: Support hardware management of dirty status.
	 *
	 * IO_PGTABLE_QUIRK_ARM_BBML1: ARM SMMU supports BBM Level 1 behavior
	 *	when changing block size.
	 *
	 * IO_PGTABLE_QUIRK_ARM_BBML2: ARM SMMU supports BBM Level 2 behavior
	 *	when changing block size.
	 */
	#define IO_PGTABLE_QUIRK_ARM_NS			BIT(0)
	#define IO_PGTABLE_QUIRK_NO_PERMS		BIT(1)
@@ -92,6 +100,9 @@ struct io_pgtable_cfg {
	#define IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT	BIT(4)
	#define IO_PGTABLE_QUIRK_ARM_TTBR1		BIT(5)
	#define IO_PGTABLE_QUIRK_ARM_OUTER_WBWA		BIT(6)
	#define IO_PGTABLE_QUIRK_ARM_HD			BIT(7)
	#define IO_PGTABLE_QUIRK_ARM_BBML1		BIT(8)
	#define IO_PGTABLE_QUIRK_ARM_BBML2		BIT(9)
	unsigned long			quirks;
	unsigned long			pgsize_bitmap;
	unsigned int			ias;