Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Samiullah Khawaja <skhawaja@google.com>
To: Robin Murphy <robin.murphy@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>, Will Deacon <will@kernel.org>,
	 Jason Gunthorpe <jgg@ziepe.ca>,
	Kevin Tian <kevin.tian@intel.com>,
	 Alex Williamson <alex@shazbot.org>,
	iommu@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
	 linux-kernel@vger.kernel.org,
	Pasha Tatashin <pasha.tatashin@soleen.com>,
	 David Matlack <dmatlack@google.com>,
	Lu Baolu <baolu.lu@linux.intel.com>,
	 Pranjal Shrivastava <praan@google.com>
Subject: Re: [RFC PATCH 3/3] iommu/arm-smmu-v3: Add support for hitless replace of S1 domains
Date: Fri, 23 Oct 2026 23:31:03 +0000	[thread overview]
Message-ID: <atvppceAqBVx8G9S@google.com> (raw)
In-Reply-To: <3d1eb92f-3447-49f0-a210-fd4fa015304b@arm.com>

On Fri, Oct 23, 2026 at 02:43:28PM +0100, Robin Murphy wrote:
>On 25/09/2026 2:13 am, Samiullah Khawaja wrote:
>>S1 domains are programmed by CD entries in the CD table. During a new
>>domain attach these are updated using write_cd_entry. Since ASID and
>>TTB0 are in different 64-bit words, the write_cd_entry considers it a
>>non-hitless update and sets V=0. This means such an update is disruptive
>>and would generate translation faults if there are ongoing DMAs.
>>
>>Replace the CD entries by using an unused temporary ASID in following
>>sequence to allow hitless replacement of CD entry,
>>
>>- Update the CD entry with temporary ASID.
>>- Update the CD entry with the target TTB0.
>>- Update the CD entry with the target ASID.
>>
>>Signed-off-by: Samiullah Khawaja <skhawaja@google.com>
>>---
>>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 66 ++++++++++++++++++++-
>>  1 file changed, 64 insertions(+), 2 deletions(-)
>>
>>diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>index 5732f3ba0122..59f4b8cf89f6 100644
>>--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>@@ -1641,6 +1641,68 @@ void arm_smmu_write_cd_entry(struct arm_smmu_master *master, int ssid,
>>  	arm_smmu_write_entry(&cd_writer.writer, cdptr->data, target->data);
>>  }
>>+/* Invalidate every stage-1 TLB entry tagged with @asid. */
>>+static void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid)
>>+{
>>+	enum arm_smmu_cmdq_opcode op = (smmu->features & ARM_SMMU_FEAT_E2H) ?
>>+					       CMDQ_OP_TLBI_EL2_ASID :
>>+					       CMDQ_OP_TLBI_NH_ASID;
>>+
>>+	arm_smmu_cmdq_issue_cmd_with_sync(smmu,
>>+					  arm_smmu_make_cmd_tlbi(op, asid, 0));
>>+}
>
>Feels like this should probably use the existing invalidation machinery...

I see, I can use the arm_smmu_inv_flush_iotlb_tag() to issue
invalidation for the ASID.
>
>>+
>>+static void arm_smmu_cd_set_asid(struct arm_smmu_cd *cd, u16 asid)
>>+{
>>+	cd->data[0] &= ~cpu_to_le64(CTXDESC_CD_0_ASID);
>>+	cd->data[0] |= cpu_to_le64(FIELD_PREP(CTXDESC_CD_0_ASID, asid));
>>+}
>>+
>>+static void arm_smmu_replace_cd_entry(struct arm_smmu_master *master, int ssid,
>>+				      struct arm_smmu_cd *cdptr,
>>+				      const struct arm_smmu_cd *target)
>>+{
>>+	struct arm_smmu_device *smmu = master->smmu;
>>+	struct arm_smmu_cd stage;
>>+	u32 tmp_asid;
>>+
>>+	lockdep_assert_held(&arm_smmu_asid_lock);
>>+
>>+	/*
>>+	 * Nothing is translating through an invalid CD, and an update that
>>+	 * invalidates one cannot be made hitless anyway.
>>+	 */
>>+	if (!(cdptr->data[0] & cpu_to_le64(CTXDESC_CD_0_V)) ||
>>+	    !(target->data[0] & cpu_to_le64(CTXDESC_CD_0_V)))
>>+		goto write_directly;
>>+
>>+	if (xa_alloc(&arm_smmu_asid_xa, &tmp_asid, XA_ZERO_ENTRY,
>>+		     XA_LIMIT(1, (1 << smmu->asid_bits) - 1), GFP_KERNEL))
>>+		goto write_directly;
>>+
>>+	/* Copy the existing cd entry and update only the ASID. */
>>+	stage = *cdptr;
>>+	arm_smmu_cd_set_asid(&stage, tmp_asid);
>>+	arm_smmu_write_cd_entry(master, ssid, cdptr, &stage);
>>+
>>+	/* Copy the target cd entry and update ASID to the temporary ASID. */
>>+	stage = *target;
>>+	arm_smmu_cd_set_asid(&stage, tmp_asid);
>>+	arm_smmu_write_cd_entry(master, ssid, cdptr, &stage);
>>+
>>+	arm_smmu_tlb_inv_asid(smmu, tmp_asid);
>>+
>>+	/* Update to the target cd entry as it should be hitless now. */
>>+	arm_smmu_write_cd_entry(master, ssid, cdptr, target);
>>+
>>+	arm_smmu_tlb_inv_asid(smmu, tmp_asid);
>>+	xa_erase(&arm_smmu_asid_xa, tmp_asid);
>>+	return;
>>+
>>+write_directly:
>>+	arm_smmu_write_cd_entry(master, ssid, cdptr, target);
>>+}
>>+
>>  void arm_smmu_make_s1_cd(struct arm_smmu_cd *target,
>>  			 struct arm_smmu_master *master,
>>  			 struct arm_smmu_domain *smmu_domain)
>>@@ -3664,8 +3726,8 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev,
>>  		struct arm_smmu_cd target_cd;
>>  		arm_smmu_make_s1_cd(&target_cd, master, smmu_domain);
>>-		arm_smmu_write_cd_entry(master, IOMMU_NO_PASID, cdptr,
>>-					&target_cd);
>>+		arm_smmu_replace_cd_entry(master, IOMMU_NO_PASID, cdptr,
>>+					  &target_cd);
>
>No, we cannot blindly do this for arbitrary ->attach_dev calls - the 
>majority of S1->S1 transitions are going to be moving back and forth 
>between the default domain and user domains, where there is zero 
>expectation, let alone guarantee, that the translations would be 
>equivalent and thus not liable to lead to TLB conflict aborts or 
>amalgamation hell.
>
>This needs to be in a dedicated "I know what I'm doing and I fully 
>accept the consequences if I get it wrong" call path.

Agreed.

I will update this to only be triggered with explicit request from the
Core to satisfy my live update use case where a preserved iommu domain
is being replaced by a new domain setup by the user.

Thanks,
Sami
>
>Thanks,
>Robin.
>
>>  		arm_smmu_make_cdtable_ste(&target, master, state.ats_enabled,
>>  					  STRTAB_STE_1_S1DSS_SSID0);
>>  		arm_smmu_install_ste_for_dev(master, &target);
>


  parent reply	other threads:[~2026-10-23 23:31 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-25  1:13 [RFC PATCH 0/3] iommu/arm-smmu-v3: Add support for hitless replace of CD entries Samiullah Khawaja
2026-09-25  1:13 ` [RFC PATCH 1/3] vfio: selftests: Add support of creating iommus from iommufd Samiullah Khawaja
2026-10-21 22:19   ` David Matlack
2026-10-23 23:04     ` Samiullah Khawaja
2026-09-25  1:13 ` [RFC PATCH 2/3] vfio: selftests: Add iommufd hwpt replace test Samiullah Khawaja
2026-10-21 22:39   ` David Matlack
2026-10-23 23:10     ` Samiullah Khawaja
2026-09-25  1:13 ` [RFC PATCH 3/3] iommu/arm-smmu-v3: Add support for hitless replace of S1 domains Samiullah Khawaja
2026-10-23 13:43   ` Robin Murphy
2026-10-23 13:49     ` Jason Gunthorpe
2026-10-23 14:04       ` Robin Murphy
2026-10-23 14:29         ` Jason Gunthorpe
2026-10-23 23:31     ` Samiullah Khawaja [this message]
2026-09-25 21:44 ` [RFC PATCH 0/3] iommu/arm-smmu-v3: Add support for hitless replace of CD entries David Matlack
2026-09-25 22:27   ` Samiullah Khawaja
2026-10-23 12:10 ` Robin Murphy
2026-10-23 13:46   ` Jason Gunthorpe
2026-10-23 14:12     ` Robin Murphy
2026-10-23 22:59     ` Samiullah Khawaja

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=atvppceAqBVx8G9S@google.com \
    --to=skhawaja@google.com \
    --cc=alex@shazbot.org \
    --cc=baolu.lu@linux.intel.com \
    --cc=dmatlack@google.com \
    --cc=iommu@lists.linux.dev \
    --cc=jgg@ziepe.ca \
    --cc=joro@8bytes.org \
    --cc=kevin.tian@intel.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pasha.tatashin@soleen.com \
    --cc=praan@google.com \
    --cc=robin.murphy@arm.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox