From: fangyu.yu@linux.alibaba.com
To: gong.shuai@sanechips.com.cn
Cc: alex@ghiti.fr, andrew.jones@linux.dev, anup@brainfault.org,
aou@eecs.berkeley.edu, atish.patra@linux.dev,
baolu.lu@linux.intel.com, fangyu.yu@linux.alibaba.com,
guoren@kernel.org, iommu@lists.linux.dev, jgg@nvidia.com,
jgg@ziepe.ca, joerg.roedel@amd.com, joro@8bytes.org,
jroedel@suse.de, kevin.tian@intel.com,
kvm-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
linux-riscv@lists.infradead.org, nutty.liu@hotmail.com,
palmer@dabbelt.com, pjw@kernel.org, robin.murphy@arm.com,
skhawaja@google.com, tanchi25@mails.ucas.ac.cn,
tomasz.jeznach@linux.dev, vasant.hegde@amd.com, will@kernel.org,
zong.li@sifive.com
Subject: Re: [PATCH v7 09/10] iommu/riscv: Add dirty tracking support for second-stage domains
Date: Wed, 4 Nov 2026 19:50:01 +0800 [thread overview]
Message-ID: <20261104115001.71362-1-fangyu.yu@linux.alibaba.com> (raw)
In-Reply-To: <20261104084503.118083-1-gong.shuai@sanechips.com.cn>
>Hi Fangyu,
>
>> From: Fangyu Yu <fangyu.yu@linux.alibaba.com>
>>
>> Add hardware dirty tracking support for second-stage (iohgatp) domains
>> used in KVM VFIO device pass-through.
>>
>> The RISC-V IOMMU can automatically set the dirty bit in PTEs on write
>> access when DC.tc.GADE is set and the hardware has AMO_HWAD capability.
>> Wire this up to the iommufd dirty tracking interface:
>>
>> - riscv_iommu_set_dirty_tracking(): Return success without toggling GADE.
>>
>> - riscv_iommu_dirty_ops: Exposes set_dirty_tracking and the generic
>> page-table read_and_clear_dirty via IOMMU_PT_DIRTY_OPS(riscv_64).
>>
>> - domain_alloc_paging_flags: Assigns dirty_ops to second-stage domains
>> when IOMMU_HWPT_ALLOC_DIRTY_TRACKING is requested.
>>
>> - riscv_iommu_capable: Reports IOMMU_CAP_DIRTY_TRACKING when
>> AMO_HWAD is present.
>>
>> Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
>> Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
>> ---
>> drivers/iommu/riscv/iommu.c | 32 ++++++++++++++++++++++++++++++--
>> 1 file changed, 30 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
>> index b3f05dfdf278..ff1043afe973 100644
>> --- a/drivers/iommu/riscv/iommu.c
>> +++ b/drivers/iommu/riscv/iommu.c
>> @@ -1350,6 +1350,10 @@ static int riscv_iommu_attach_paging_domain(struct iommu_domain *iommu_domain,
>> if (domain->gscid) {
>> if (!riscv_iommu_iohgatp_supported(iommu, pt_info.iohgatp_mode))
>> return -EINVAL;
>> + /* Dirty tracking requires AMO_HWAD on every attached IOMMU */
>> + if (iommu_domain->dirty_ops &&
>> + !(iommu->caps & RISCV_IOMMU_CAPABILITIES_AMO_HWAD))
>> + return -EINVAL;
>>
>> dc.iohgatp =
>> FIELD_PREP(RISCV_IOMMU_DC_IOHGATP_MODE, pt_info.iohgatp_mode) |
>> @@ -1377,6 +1381,21 @@ static int riscv_iommu_attach_paging_domain(struct iommu_domain *iommu_domain,
>> return 0;
>> }
>>
>> +static int riscv_iommu_set_dirty_tracking(struct iommu_domain *iommu_domain,
>> + bool enable)
>> +{
>> + /*
>> + * Always enabled and the dirty bitmap is cleared prior to
>> + * set_dirty_tracking().
>> + */
>> + return 0;
>> +}
>> +
>> +static const struct iommu_dirty_ops riscv_iommu_dirty_ops = {
>> + IOMMU_PT_DIRTY_OPS(riscv_64),
>> + .set_dirty_tracking = riscv_iommu_set_dirty_tracking,
>> +};
>> +
>> static const struct iommu_domain_ops riscv_iommu_paging_domain_ops = {
>> IOMMU_PT_DOMAIN_OPS(riscv_64),
>> .attach_dev = riscv_iommu_attach_paging_domain,
>> @@ -1418,7 +1437,8 @@ static int riscv_iommu_init_domain_s1(struct device *dev,
>> */
>> static int riscv_iommu_init_domain_s2(struct device *dev,
>> struct riscv_iommu_domain *domain,
>> - struct pt_iommu_riscv_64_cfg *cfg)
>> + struct pt_iommu_riscv_64_cfg *cfg,
>> + u32 flags)
>> {
>> struct riscv_iommu_device *iommu = dev_to_iommu(dev);
>>
>> @@ -1439,6 +1459,10 @@ static int riscv_iommu_init_domain_s2(struct device *dev,
>> if (domain->gscid < 0)
>> return -ENOMEM;
>>
>> + /* AMO_HWAD is checked by iommufd via IOMMU_CAP_DIRTY_TRACKING */
>> + if (flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING)
>> + domain->domain.dirty_ops = &riscv_iommu_dirty_ops;
>> +
>> return 0;
>> }
>>
>> @@ -1481,7 +1505,7 @@ riscv_iommu_domain_alloc_paging_flags(struct device *dev, u32 flags,
>> case IOMMU_HWPT_ALLOC_NEST_PARENT:
>> case IOMMU_HWPT_ALLOC_DIRTY_TRACKING:
>> case IOMMU_HWPT_ALLOC_DIRTY_TRACKING | IOMMU_HWPT_ALLOC_NEST_PARENT:
>> - ret = riscv_iommu_init_domain_s2(dev, domain, &cfg);
>> + ret = riscv_iommu_init_domain_s2(dev, domain, &cfg, flags);
>> break;
>> default:
>> ret = -EOPNOTSUPP;
>> @@ -1559,9 +1583,13 @@ static struct iommu_group *riscv_iommu_device_group(struct device *dev)
>>
>> static bool riscv_iommu_capable(struct device *dev, enum iommu_cap cap)
>> {
>> + struct riscv_iommu_device *iommu = dev_to_iommu(dev);
>> +
>> switch (cap) {
>> case IOMMU_CAP_CACHE_COHERENCY:
>> return dev_is_dma_coherent(dev);
>> + case IOMMU_CAP_DIRTY_TRACKING:
>> + return !!(iommu->caps & RISCV_IOMMU_CAPABILITIES_AMO_HWAD);
>
>I'm not quite sure about this. Could there be a device that supports
>AMO_HWAD but not any of the S2 modes? GET_HW_INFO would report
>DIRTY_TRACKING as supported, but HWPT_ALLOC would then fail in
>riscv_iommu_init_domain_s2(). Should this check also include the
>S2 modes, like
>
> AMO_HWAD && (SV39X4|SV48X4|SV57X4) ?
>
Good question, I had also considered this.
From the IOMMU spec alone, I could not confirm whether
AMO_HWAD implies support for S2 modes.
However, I found this statement in the IOMMU spec:
"The IOMMU must support all the virtual memory
extensions that are supported by any of the harts in
the system."
For virtualization scenarios, we assume the CPU hart
must support at least one S2 mode (hgatp). From this
perspective, the IOMMU should support at least one S2
mode in a virtualization setup, regardless of
AMO_HWAD.
>BTW, in riscv_iommu_init_domain_s1/s2, why not return -EOPNOTSUPP
>instead of -ENODEV for "cannot find supported page table mode"?
>
I used -ENODEV to follow the existing S1 behavior:
no compatible paging mode is available on this IOMMU.
While -EOPNOTSUPP would also be reasonable, I suggest
keeping S1 and S2 consistent and leaving this unchanged
in this series.
Thanks,
Fangyu
>Thanks,
>Shuai
>
>> default:
>> return false;
>> }
>> --
>> 2.50.1
>>
next prev parent reply other threads:[~2026-11-04 11:50 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-03 12:02 [PATCH v7 00/10] iommu/riscv: Add hardware dirty tracking " fangyu.yu
2026-11-03 12:02 ` [PATCH v7 01/10] iommu/generic_pt: Fix the RISC-V supported feature mask fangyu.yu
2026-11-03 12:02 ` [PATCH v7 02/10] iommupt: Add RISC-V Second-stage (iohgatp) page table support fangyu.yu
2026-11-03 12:02 ` [PATCH v7 03/10] iommupt: Add RISC-V dirty tracking PTE ops fangyu.yu
2026-11-03 12:02 ` [PATCH v7 04/10] iommu/riscv: use data structure instead of individual values fangyu.yu
2026-11-03 12:02 ` [PATCH v7 05/10] iommu/riscv: support GSCID and GVMA invalidation command fangyu.yu
2026-11-04 9:21 ` Gong Shuai
2026-11-04 11:27 ` fangyu.yu
2026-11-03 12:02 ` [PATCH v7 06/10] RISC-V: KVM: Enable KVM_VFIO interfaces on RISC-V arch fangyu.yu
2026-11-04 6:45 ` Gong Shuai
2026-11-04 10:59 ` fangyu.yu
2026-11-03 12:02 ` [PATCH v7 07/10] iommu/riscv: Add domain_alloc_paging_flags for second-stage domain fangyu.yu
2026-11-03 12:02 ` [PATCH v7 08/10] iommu/riscv: Pre-enable GADE for second-stage domains fangyu.yu
2026-11-03 12:02 ` [PATCH v7 09/10] iommu/riscv: Add dirty tracking support " fangyu.yu
2026-11-04 8:45 ` Gong Shuai
2026-11-04 11:50 ` fangyu.yu [this message]
2026-11-03 12:02 ` [PATCH v7 10/10] iommu/riscv: Add IOTINVAL.GVMA invalidations fangyu.yu
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=20261104115001.71362-1-fangyu.yu@linux.alibaba.com \
--to=fangyu.yu@linux.alibaba.com \
--cc=alex@ghiti.fr \
--cc=andrew.jones@linux.dev \
--cc=anup@brainfault.org \
--cc=aou@eecs.berkeley.edu \
--cc=atish.patra@linux.dev \
--cc=baolu.lu@linux.intel.com \
--cc=gong.shuai@sanechips.com.cn \
--cc=guoren@kernel.org \
--cc=iommu@lists.linux.dev \
--cc=jgg@nvidia.com \
--cc=jgg@ziepe.ca \
--cc=joerg.roedel@amd.com \
--cc=joro@8bytes.org \
--cc=jroedel@suse.de \
--cc=kevin.tian@intel.com \
--cc=kvm-riscv@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=nutty.liu@hotmail.com \
--cc=palmer@dabbelt.com \
--cc=pjw@kernel.org \
--cc=robin.murphy@arm.com \
--cc=skhawaja@google.com \
--cc=tanchi25@mails.ucas.ac.cn \
--cc=tomasz.jeznach@linux.dev \
--cc=vasant.hegde@amd.com \
--cc=will@kernel.org \
--cc=zong.li@sifive.com \
/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
all inboxes | Powered by JetHome®