From: Joao Martins <joao.m.martins@oracle.com>
To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi@huawei.com>
Cc: Jason Gunthorpe <jgg@nvidia.com>,
Kevin Tian <kevin.tian@intel.com>,
Lu Baolu <baolu.lu@linux.intel.com>, Yi Liu <yi.l.liu@intel.com>,
Yi Y Sun <yi.y.sun@intel.com>,
"iommu@lists.linux.dev" <iommu@lists.linux.dev>,
Eric Auger <eric.auger@redhat.com>,
Nicolin Chen <nicolinc@nvidia.com>,
Joerg Roedel <joro@8bytes.org>,
Jean-Philippe Brucker <jean-philippe@linaro.org>,
Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>,
Will Deacon <will@kernel.org>,
Robin Murphy <robin.murphy@arm.com>,
Alex Williamson <alex.williamson@redhat.com>,
"kvm@vger.kernel.org" <kvm@vger.kernel.org>
Subject: Re: [PATCH RFCv2 22/24] iommu/arm-smmu-v3: Add read_and_clear_dirty() support
Date: Fri, 16 Jun 2023 19:10:23 +0100 [thread overview]
Message-ID: <154bf412-95d3-b069-89a4-35fc7ed11108@oracle.com> (raw)
In-Reply-To: <c4696aad77ef49e7b3c550c19b354223@huawei.com>
On 16/06/2023 17:46, Shameerali Kolothum Thodi wrote:
> Hi Joao,
>
>> -----Original Message-----
>> From: Joao Martins [mailto:joao.m.martins@oracle.com]
>> Sent: 18 May 2023 21:47
>> To: iommu@lists.linux.dev
>> Cc: Jason Gunthorpe <jgg@nvidia.com>; Kevin Tian <kevin.tian@intel.com>;
>> Shameerali Kolothum Thodi <shameerali.kolothum.thodi@huawei.com>; Lu
>> Baolu <baolu.lu@linux.intel.com>; Yi Liu <yi.l.liu@intel.com>; Yi Y Sun
>> <yi.y.sun@intel.com>; Eric Auger <eric.auger@redhat.com>; Nicolin Chen
>> <nicolinc@nvidia.com>; Joerg Roedel <joro@8bytes.org>; Jean-Philippe
>> Brucker <jean-philippe@linaro.org>; Suravee Suthikulpanit
>> <suravee.suthikulpanit@amd.com>; Will Deacon <will@kernel.org>; Robin
>> Murphy <robin.murphy@arm.com>; Alex Williamson
>> <alex.williamson@redhat.com>; kvm@vger.kernel.org; Joao Martins
>> <joao.m.martins@oracle.com>
>> Subject: [PATCH RFCv2 22/24] iommu/arm-smmu-v3: Add
>> read_and_clear_dirty() support
>>
>> From: Keqian Zhu <zhukeqian1@huawei.com>
>>
>> .read_and_clear_dirty() IOMMU domain op takes care of reading the dirty
>> bits (i.e. PTE has both DBM and AP[2] set) and marshalling into a bitmap of
>> a given page size.
>>
>> While reading the dirty bits we also clear the PTE AP[2] bit to mark it as
>> writable-clean depending on read_and_clear_dirty() flags.
>>
>> Structure it in a way that the IOPTE walker is generic, and so we pass a
>> function pointer over what to do on a per-PTE basis.
>>
>> [Link below points to the original version that was based on]
>>
>> Link:
>> https://lore.kernel.org/lkml/20210413085457.25400-11-zhukeqian1@huaw
>> ei.com/
>> Co-developed-by: Keqian Zhu <zhukeqian1@huawei.com>
>> Co-developed-by: Kunkun Jiang <jiangkunkun@huawei.com>
>> Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com>
>> [joaomart: Massage commit message]
>> Co-developed-by: Joao Martins <joao.m.martins@oracle.com>
>> Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
>> ---
>> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 23 +++++
>> drivers/iommu/io-pgtable-arm.c | 104
>> ++++++++++++++++++++
>> 2 files changed, 127 insertions(+)
>>
>> 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 e2b98a6a6b74..2cde14003469 100644
>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> @@ -2765,6 +2765,28 @@ static int arm_smmu_enable_nesting(struct
>> iommu_domain *domain)
>> return ret;
>> }
>>
>> +static int arm_smmu_read_and_clear_dirty(struct iommu_domain
>> *domain,
>> + unsigned long iova, size_t size,
>> + unsigned long flags,
>> + struct iommu_dirty_bitmap *dirty)
>> +{
>> + struct arm_smmu_domain *smmu_domain =
>> to_smmu_domain(domain);
>> + struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
>> + int ret;
>> +
>> + if (smmu_domain->stage != ARM_SMMU_DOMAIN_S1)
>> + return -EINVAL;
>> +
>> + if (!ops || !ops->read_and_clear_dirty) {
>> + pr_err_once("io-pgtable don't support dirty tracking\n");
>> + return -ENODEV;
>> + }
>> +
>> + ret = ops->read_and_clear_dirty(ops, iova, size, flags, dirty);
>> +
>> + return ret;
>> +}
>> +
>> static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args
>> *args)
>> {
>> return iommu_fwspec_add_ids(dev, args->args, 1);
>> @@ -2893,6 +2915,7 @@ static struct iommu_ops arm_smmu_ops = {
>> .iova_to_phys = arm_smmu_iova_to_phys,
>> .enable_nesting = arm_smmu_enable_nesting,
>> .free = arm_smmu_domain_free,
>> + .read_and_clear_dirty = arm_smmu_read_and_clear_dirty,
>> }
>> };
>>
>> diff --git a/drivers/iommu/io-pgtable-arm.c
>> b/drivers/iommu/io-pgtable-arm.c
>> index b2f470529459..de9e61f8452d 100644
>> --- a/drivers/iommu/io-pgtable-arm.c
>> +++ b/drivers/iommu/io-pgtable-arm.c
>> @@ -717,6 +717,109 @@ static phys_addr_t arm_lpae_iova_to_phys(struct
>> io_pgtable_ops *ops,
>> return iopte_to_paddr(pte, data) | iova;
>> }
>>
>> +struct arm_lpae_iopte_read_dirty {
>> + unsigned long flags;
>> + struct iommu_dirty_bitmap *dirty;
>> +};
>> +
>> +static int __arm_lpae_read_and_clear_dirty(unsigned long iova, size_t size,
>> + arm_lpae_iopte *ptep, void *opaque)
>> +{
>> + struct arm_lpae_iopte_read_dirty *arg = opaque;
>> + struct iommu_dirty_bitmap *dirty = arg->dirty;
>> + arm_lpae_iopte pte;
>> +
>> + pte = READ_ONCE(*ptep);
>> + if (WARN_ON(!pte))
>> + return -EINVAL;
>> +
>> + if ((pte & ARM_LPAE_PTE_AP_WRITABLE) ==
>> ARM_LPAE_PTE_AP_WRITABLE)
>> + return 0;
>> +
>> + iommu_dirty_bitmap_record(dirty, iova, size);
>> + if (!(arg->flags & IOMMU_DIRTY_NO_CLEAR))
>> + set_bit(ARM_LPAE_PTE_AP_RDONLY_BIT, (unsigned long *)ptep);
>> + return 0;
>> +}
>> +
>> +static int __arm_lpae_iopte_walk(struct arm_lpae_io_pgtable *data,
>> + unsigned long iova, size_t size,
>> + int lvl, arm_lpae_iopte *ptep,
>> + int (*fn)(unsigned long iova, size_t size,
>> + arm_lpae_iopte *pte, void *opaque),
>> + void *opaque)
>> +{
>> + arm_lpae_iopte pte;
>> + struct io_pgtable *iop = &data->iop;
>> + size_t base, next_size;
>> + int ret;
>> +
>> + if (WARN_ON_ONCE(!fn))
>> + return -EINVAL;
>> +
>> + if (WARN_ON(lvl == ARM_LPAE_MAX_LEVELS))
>> + return -EINVAL;
>> +
>> + ptep += ARM_LPAE_LVL_IDX(iova, lvl, data);
>> + pte = READ_ONCE(*ptep);
>> + if (WARN_ON(!pte))
>> + return -EINVAL;
>> +
>> + if (size == ARM_LPAE_BLOCK_SIZE(lvl, data)) {
>> + if (iopte_leaf(pte, lvl, iop->fmt))
>> + return fn(iova, size, ptep, opaque);
>> +
>> + /* Current level is table, traverse next level */
>> + next_size = ARM_LPAE_BLOCK_SIZE(lvl + 1, data);
>> + ptep = iopte_deref(pte, data);
>> + for (base = 0; base < size; base += next_size) {
>> + ret = __arm_lpae_iopte_walk(data, iova + base,
>> + next_size, lvl + 1, ptep,
>> + fn, opaque);
>> + if (ret)
>> + return ret;
>> + }
>> + return 0;
>> + } else if (iopte_leaf(pte, lvl, iop->fmt)) {
>> + return fn(iova, size, ptep, opaque);
>> + }
>> +
>> + /* Keep on walkin */
>> + ptep = iopte_deref(pte, data);
>> + return __arm_lpae_iopte_walk(data, iova, size, lvl + 1, ptep,
>> + fn, opaque);
>> +}
>> +
>> +static int arm_lpae_read_and_clear_dirty(struct io_pgtable_ops *ops,
>> + unsigned long iova, size_t size,
>> + unsigned long flags,
>> + struct iommu_dirty_bitmap *dirty)
>> +{
>> + struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
>> + struct io_pgtable_cfg *cfg = &data->iop.cfg;
>> + struct arm_lpae_iopte_read_dirty arg = {
>> + .flags = flags, .dirty = dirty,
>> + };
>> + arm_lpae_iopte *ptep = data->pgd;
>> + int lvl = data->start_level;
>> + long iaext = (s64)iova >> cfg->ias;
>> +
>> + if (WARN_ON(!size || (size & cfg->pgsize_bitmap) != size))
>> + return -EINVAL;
>
> I guess the size here is supposed to be one of the pgsize that iommu supports.
> But looking at the code, it looks like we are passing the iova mapped length and
> it fails here in my test setup. Could you please check and confirm.
>
I think this might be from the original patch, and it's meant to test that
length is aligned to the page size, but I failed to removed it this snip. We
should remove this.
> Thanks,
> Shameer
>
>
>> +
>> + if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1)
>> + iaext = ~iaext;
>> + if (WARN_ON(iaext))
>> + return -EINVAL;
>> +
>> + if (data->iop.fmt != ARM_64_LPAE_S1 &&
>> + data->iop.fmt != ARM_32_LPAE_S1)
>> + return -EINVAL;
>> +
>> + return __arm_lpae_iopte_walk(data, iova, size, lvl, ptep,
>> + __arm_lpae_read_and_clear_dirty, &arg);
>> +}
>> +
>> static void arm_lpae_restrict_pgsizes(struct io_pgtable_cfg *cfg)
>> {
>> unsigned long granule, page_sizes;
>> @@ -795,6 +898,7 @@ arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg)
>> .map_pages = arm_lpae_map_pages,
>> .unmap_pages = arm_lpae_unmap_pages,
>> .iova_to_phys = arm_lpae_iova_to_phys,
>> + .read_and_clear_dirty = arm_lpae_read_and_clear_dirty,
>> };
>>
>> return data;
>> --
>> 2.17.2
>
next prev parent reply other threads:[~2023-06-16 18:10 UTC|newest]
Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-18 20:46 [PATCH RFCv2 00/24] IOMMUFD Dirty Tracking Joao Martins
2023-05-18 20:46 ` [PATCH RFCv2 01/24] iommu: Add RCU-protected page free support Joao Martins
2023-05-19 13:32 ` Jason Gunthorpe
2023-05-19 16:48 ` Joao Martins
2023-05-18 20:46 ` [PATCH RFCv2 02/24] iommu: Replace put_pages_list() with iommu_free_pgtbl_pages() Joao Martins
2023-05-18 20:46 ` [PATCH RFCv2 03/24] vfio: Move iova_bitmap into iommu core Joao Martins
2023-05-18 22:35 ` Alex Williamson
2023-05-19 9:06 ` Joao Martins
2023-05-19 9:01 ` Liu, Jingqi
2023-05-19 9:07 ` Joao Martins
2023-05-18 20:46 ` [PATCH RFCv2 04/24] iommu: Add iommu_domain ops for dirty tracking Joao Martins
2023-05-19 8:42 ` Baolu Lu
2023-05-19 9:28 ` Joao Martins
2023-05-19 11:40 ` Jason Gunthorpe
2023-05-19 11:47 ` Joao Martins
2023-05-19 11:51 ` Jason Gunthorpe
2023-05-19 11:56 ` Joao Martins
2023-05-19 13:29 ` Jason Gunthorpe
2023-05-19 13:46 ` Joao Martins
2023-08-10 18:23 ` Joao Martins
2023-08-10 18:55 ` Jason Gunthorpe
2023-08-10 20:36 ` Joao Martins
2023-08-11 1:09 ` Jason Gunthorpe
2023-05-19 12:13 ` Baolu Lu
2023-05-19 13:22 ` Robin Murphy
2023-05-19 13:43 ` Joao Martins
2023-05-19 18:12 ` Robin Murphy
2023-05-18 20:46 ` [PATCH RFCv2 05/24] iommufd: Add a flag to enforce dirty tracking on attach Joao Martins
2023-05-19 13:34 ` Jason Gunthorpe
2023-05-18 20:46 ` [PATCH RFCv2 06/24] iommufd/selftest: Add a flags to _test_cmd_{hwpt_alloc,mock_domain} Joao Martins
2023-05-18 20:46 ` [PATCH RFCv2 07/24] iommufd/selftest: Test IOMMU_HWPT_ALLOC_ENFORCE_DIRTY Joao Martins
2023-05-19 13:35 ` Jason Gunthorpe
2023-05-19 13:52 ` Joao Martins
2023-05-19 13:55 ` Joao Martins
2023-05-18 20:46 ` [PATCH RFCv2 08/24] iommufd: Dirty tracking data support Joao Martins
2023-05-18 20:46 ` [PATCH RFCv2 09/24] iommufd: Add IOMMU_HWPT_SET_DIRTY Joao Martins
2023-05-19 13:49 ` Jason Gunthorpe
2023-05-19 14:21 ` Joao Martins
2023-05-18 20:46 ` [PATCH RFCv2 10/24] iommufd/selftest: Test IOMMU_HWPT_SET_DIRTY Joao Martins
2023-05-18 20:46 ` [PATCH RFCv2 11/24] iommufd: Add IOMMU_HWPT_GET_DIRTY_IOVA Joao Martins
2023-05-18 20:46 ` [PATCH RFCv2 12/24] iommufd/selftest: Test IOMMU_HWPT_GET_DIRTY_IOVA Joao Martins
2023-05-18 20:46 ` [PATCH RFCv2 13/24] iommufd: Add IOMMU_DEVICE_GET_CAPS Joao Martins
2023-05-18 20:46 ` [PATCH RFCv2 14/24] iommufd/selftest: Test IOMMU_DEVICE_GET_CAPS Joao Martins
2023-05-18 20:46 ` [PATCH RFCv2 15/24] iommufd: Add a flag to skip clearing of IOPTE dirty Joao Martins
2023-05-19 13:54 ` Jason Gunthorpe
2023-05-18 20:46 ` [PATCH RFCv2 16/24] iommufd/selftest: Test IOMMU_GET_DIRTY_IOVA_NO_CLEAR flag Joao Martins
2023-05-18 20:46 ` [PATCH RFCv2 17/24] iommu/amd: Access/Dirty bit support in IOPTEs Joao Martins
2023-05-18 20:46 ` [PATCH RFCv2 18/24] iommu/amd: Print access/dirty bits if supported Joao Martins
2023-05-18 20:46 ` [PATCH RFCv2 19/24] iommu/intel: Access/Dirty bit support for SL domains Joao Martins
2023-05-18 20:46 ` [PATCH RFCv2 20/24] iommu/arm-smmu-v3: Add feature detection for HTTU Joao Martins
2023-05-18 20:46 ` [PATCH RFCv2 21/24] iommu/arm-smmu-v3: Enable HTTU for stage1 with io-pgtable mapping Joao Martins
2023-05-19 13:49 ` Robin Murphy
2023-05-19 14:05 ` Joao Martins
2023-05-22 10:34 ` Shameerali Kolothum Thodi
2023-05-22 10:43 ` Joao Martins
2023-06-16 17:00 ` Shameerali Kolothum Thodi
2023-06-16 18:11 ` Joao Martins
2023-05-18 20:46 ` [PATCH RFCv2 22/24] iommu/arm-smmu-v3: Add read_and_clear_dirty() support Joao Martins
2023-06-16 16:46 ` Shameerali Kolothum Thodi
2023-06-16 18:10 ` Joao Martins [this message]
2023-05-18 20:46 ` [PATCH RFCv2 23/24] iommu/arm-smmu-v3: Add set_dirty_tracking() support Joao Martins
2023-05-18 20:46 ` [PATCH RFCv2 24/24] iommu/arm-smmu-v3: Advertise IOMMU_DOMAIN_F_ENFORCE_DIRTY Joao Martins
2023-05-30 14:10 ` Shameerali Kolothum Thodi
2023-05-30 19:19 ` Joao Martins
2023-05-31 9:21 ` Shameerali Kolothum Thodi
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=154bf412-95d3-b069-89a4-35fc7ed11108@oracle.com \
--to=joao.m.martins@oracle.com \
--cc=alex.williamson@redhat.com \
--cc=baolu.lu@linux.intel.com \
--cc=eric.auger@redhat.com \
--cc=iommu@lists.linux.dev \
--cc=jean-philippe@linaro.org \
--cc=jgg@nvidia.com \
--cc=joro@8bytes.org \
--cc=kevin.tian@intel.com \
--cc=kvm@vger.kernel.org \
--cc=nicolinc@nvidia.com \
--cc=robin.murphy@arm.com \
--cc=shameerali.kolothum.thodi@huawei.com \
--cc=suravee.suthikulpanit@amd.com \
--cc=will@kernel.org \
--cc=yi.l.liu@intel.com \
--cc=yi.y.sun@intel.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