From: Oliver Upton <oliver.upton@linux.dev>
To: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Cc: kvmarm@lists.linux.dev, kvm@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, maz@kernel.org,
will@kernel.org, catalin.marinas@arm.com, james.morse@arm.com,
suzuki.poulose@arm.com, yuzenghui@huawei.com,
zhukeqian1@huawei.com, jonathan.cameron@huawei.com,
linuxarm@huawei.com
Subject: Re: [RFC PATCH v2 3/8] KVM: arm64: Add some HW_DBM related pgtable interfaces
Date: Fri, 15 Sep 2023 22:22:42 +0000 [thread overview]
Message-ID: <ZQTZMl7RP8ZYQ6tr@linux.dev> (raw)
In-Reply-To: <20230825093528.1637-4-shameerali.kolothum.thodi@huawei.com>
Hi Shameer,
On Fri, Aug 25, 2023 at 10:35:23AM +0100, Shameer Kolothum wrote:
> From: Keqian Zhu <zhukeqian1@huawei.com>
>
> This adds set_dbm, clear_dbm and sync_dirty interfaces in pgtable
> layer. (1) set_dbm: Set DBM bit for last level PTE of a specified
> range. TLBI is completed. (2) clear_dbm: Clear DBM bit for last
> level PTE of a specified range. TLBI is not acted. (3) sync_dirty:
> Scan last level PTE of a specific range. Log dirty if PTE is writeable.
>
> Besides, save the dirty state of PTE if it's invalided by map or
> unmap.
>
> Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
> ---
> arch/arm64/include/asm/kvm_pgtable.h | 45 +++++++++++++
> arch/arm64/kernel/image-vars.h | 2 +
> arch/arm64/kvm/hyp/pgtable.c | 98 ++++++++++++++++++++++++++++
> 3 files changed, 145 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> index 3f96bdd2086f..a12add002b89 100644
> --- a/arch/arm64/include/asm/kvm_pgtable.h
> +++ b/arch/arm64/include/asm/kvm_pgtable.h
> @@ -578,6 +578,51 @@ int kvm_pgtable_stage2_set_owner(struct kvm_pgtable *pgt, u64 addr, u64 size,
> */
> int kvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size);
>
> +/**
> + * kvm_pgtable_stage2_clear_dbm() - Clear DBM of guest stage-2 address range
> + * without TLB invalidation (only last level).
> + * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init().
> + * @addr: Intermediate physical address from which to clear DBM,
> + * @size: Size of the range.
> + *
> + * The offset of @addr within a page is ignored and @size is rounded-up to
> + * the next page boundary.
> + *
> + * Note that it is the caller's responsibility to invalidate the TLB after
> + * calling this function to ensure that the disabled HW dirty are visible
> + * to the CPUs.
> + *
> + * Return: 0 on success, negative error code on failure.
> + */
> +int kvm_pgtable_stage2_clear_dbm(struct kvm_pgtable *pgt, u64 addr, u64 size);
> +
> +/**
> + * kvm_pgtable_stage2_set_dbm() - Set DBM of guest stage-2 address range to
> + * enable HW dirty (only last level).
> + * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init().
> + * @addr: Intermediate physical address from which to set DBM.
> + * @size: Size of the range.
> + *
> + * The offset of @addr within a page is ignored and @size is rounded-up to
> + * the next page boundary.
> + *
> + * Return: 0 on success, negative error code on failure.
> + */
> +int kvm_pgtable_stage2_set_dbm(struct kvm_pgtable *pgt, u64 addr, u64 size);
> +
> +/**
> + * kvm_pgtable_stage2_sync_dirty() - Sync HW dirty state into memslot.
> + * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init().
> + * @addr: Intermediate physical address from which to sync.
> + * @size: Size of the range.
> + *
> + * The offset of @addr within a page is ignored and @size is rounded-up to
> + * the next page boundary.
> + *
> + * Return: 0 on success, negative error code on failure.
> + */
> +int kvm_pgtable_stage2_sync_dirty(struct kvm_pgtable *pgt, u64 addr, u64 size);
> +
> /**
> * kvm_pgtable_stage2_wrprotect() - Write-protect guest stage-2 address range
> * without TLB invalidation.
> diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
> index 35f3c7959513..2ca600e3d637 100644
> --- a/arch/arm64/kernel/image-vars.h
> +++ b/arch/arm64/kernel/image-vars.h
> @@ -68,6 +68,8 @@ KVM_NVHE_ALIAS(__hyp_stub_vectors);
> KVM_NVHE_ALIAS(vgic_v2_cpuif_trap);
> KVM_NVHE_ALIAS(vgic_v3_cpuif_trap);
>
> +KVM_NVHE_ALIAS(mark_page_dirty);
> +
This doesn't make any sense besides satisfying the linker. The hyp page
table walkers will *never* need to mark a page as dirty.
Consider adding a new function pointer to kvm_pgtable_mm_ops and only
set it for the 'normal' stage-2 mm ops in mmu.c.
> +static bool stage2_pte_writeable(kvm_pte_t pte)
> +{
> + return pte & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W;
> +}
> +
> +static void kvm_update_hw_dbm(const struct kvm_pgtable_visit_ctx *ctx,
> + kvm_pte_t new)
> +{
> + kvm_pte_t old_pte, pte = ctx->old;
> +
> + /* Only set DBM if page is writeable */
> + if ((new & KVM_PTE_LEAF_ATTR_HI_S2_DBM) && !stage2_pte_writeable(pte))
> + return;
> +
> + /* Clear DBM walk is not shared, update */
> + if (!kvm_pgtable_walk_shared(ctx)) {
> + WRITE_ONCE(*ctx->ptep, new);
> + return;
> + }
> +
> + do {
> + old_pte = pte;
> + pte = new;
> +
> + if (old_pte == pte)
> + break;
> +
> + pte = cmpxchg_relaxed(ctx->ptep, old_pte, pte);
> + } while (pte != old_pte);
> +}
> +
We don't need a separate walker for updating the DBM state in the
page tables. Can't we treat it like any other permission bit and use
something like kvm_pgtable_stage2_relax_perms()?
Also, what is the purpose of retrying the update on a descriptor if the
cmpxchg() fails? Everywhere else in the page table walker code we bail
and retry execution since that is a clear indication of a race. In all
likelihood the other vCPU thread was either trying to update DBM or
service a permission fault.
> static bool stage2_try_set_pte(const struct kvm_pgtable_visit_ctx *ctx, kvm_pte_t new)
> {
> + if (kvm_pgtable_walk_hw_dbm(ctx)) {
> + kvm_update_hw_dbm(ctx, new);
> + return true;
> + }
> +
Why are you trying to circumvent the primitive for setting stage-2 PTEs?
> if (!kvm_pgtable_walk_shared(ctx)) {
> WRITE_ONCE(*ctx->ptep, new);
> return true;
> @@ -952,6 +990,11 @@ static int stage2_map_walker_try_leaf(const struct kvm_pgtable_visit_ctx *ctx,
> stage2_pte_executable(new))
> mm_ops->icache_inval_pou(kvm_pte_follow(new, mm_ops), granule);
>
> + /* Save the possible hardware dirty info */
> + if ((ctx->level == KVM_PGTABLE_MAX_LEVELS - 1) &&
> + stage2_pte_writeable(ctx->old))
> + mark_page_dirty(kvm_s2_mmu_to_kvm(pgt->mmu), ctx->addr >> PAGE_SHIFT);
> +
> stage2_make_pte(ctx, new);
>
> return 0;
> @@ -1125,6 +1168,11 @@ static int stage2_unmap_walker(const struct kvm_pgtable_visit_ctx *ctx,
> */
> stage2_unmap_put_pte(ctx, mmu, mm_ops);
>
> + /* Save the possible hardware dirty info */
> + if ((ctx->level == KVM_PGTABLE_MAX_LEVELS - 1) &&
> + stage2_pte_writeable(ctx->old))
> + mark_page_dirty(kvm_s2_mmu_to_kvm(mmu), ctx->addr >> PAGE_SHIFT);
> +
> if (need_flush && mm_ops->dcache_clean_inval_poc)
> mm_ops->dcache_clean_inval_poc(kvm_pte_follow(ctx->old, mm_ops),
> kvm_granule_size(ctx->level));
> @@ -1230,6 +1278,30 @@ static int stage2_update_leaf_attrs(struct kvm_pgtable *pgt, u64 addr,
> return 0;
> }
>
> +int kvm_pgtable_stage2_set_dbm(struct kvm_pgtable *pgt, u64 addr, u64 size)
> +{
> + int ret;
> + u64 offset;
> +
> + ret = stage2_update_leaf_attrs(pgt, addr, size, KVM_PTE_LEAF_ATTR_HI_S2_DBM, 0,
> + NULL, NULL, KVM_PGTABLE_WALK_HW_DBM |
> + KVM_PGTABLE_WALK_SHARED);
> + if (!ret)
> + return ret;
> +
> + for (offset = 0; offset < size; offset += PAGE_SIZE)
> + kvm_call_hyp(__kvm_tlb_flush_vmid_ipa_nsh, pgt->mmu, addr + offset, 3);
> +
> + return 0;
> +}
> +
> +int kvm_pgtable_stage2_clear_dbm(struct kvm_pgtable *pgt, u64 addr, u64 size)
> +{
> + return stage2_update_leaf_attrs(pgt, addr, size,
> + 0, KVM_PTE_LEAF_ATTR_HI_S2_DBM,
> + NULL, NULL, KVM_PGTABLE_WALK_HW_DBM);
> +}
> +
> int kvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
> {
> return stage2_update_leaf_attrs(pgt, addr, size, 0,
> @@ -1329,6 +1401,32 @@ int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
> return ret;
> }
>
> +static int stage2_sync_dirty_walker(const struct kvm_pgtable_visit_ctx *ctx,
> + enum kvm_pgtable_walk_flags visit)
> +{
> + kvm_pte_t pte = READ_ONCE(*ctx->ptep);
ctx->old is fetched in __kvm_pgtable_visit(), and the whole
parallelization scheme for page table walkers depends on us being
careful to read the PTE once per level. Do you need to reread it here?
--
Thanks,
Oliver
WARNING: multiple messages have this Message-ID (diff)
From: Oliver Upton <oliver.upton@linux.dev>
To: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Cc: kvmarm@lists.linux.dev, kvm@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, maz@kernel.org,
will@kernel.org, catalin.marinas@arm.com, james.morse@arm.com,
suzuki.poulose@arm.com, yuzenghui@huawei.com,
zhukeqian1@huawei.com, jonathan.cameron@huawei.com,
linuxarm@huawei.com
Subject: Re: [RFC PATCH v2 3/8] KVM: arm64: Add some HW_DBM related pgtable interfaces
Date: Fri, 15 Sep 2023 22:22:42 +0000 [thread overview]
Message-ID: <ZQTZMl7RP8ZYQ6tr@linux.dev> (raw)
In-Reply-To: <20230825093528.1637-4-shameerali.kolothum.thodi@huawei.com>
Hi Shameer,
On Fri, Aug 25, 2023 at 10:35:23AM +0100, Shameer Kolothum wrote:
> From: Keqian Zhu <zhukeqian1@huawei.com>
>
> This adds set_dbm, clear_dbm and sync_dirty interfaces in pgtable
> layer. (1) set_dbm: Set DBM bit for last level PTE of a specified
> range. TLBI is completed. (2) clear_dbm: Clear DBM bit for last
> level PTE of a specified range. TLBI is not acted. (3) sync_dirty:
> Scan last level PTE of a specific range. Log dirty if PTE is writeable.
>
> Besides, save the dirty state of PTE if it's invalided by map or
> unmap.
>
> Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
> ---
> arch/arm64/include/asm/kvm_pgtable.h | 45 +++++++++++++
> arch/arm64/kernel/image-vars.h | 2 +
> arch/arm64/kvm/hyp/pgtable.c | 98 ++++++++++++++++++++++++++++
> 3 files changed, 145 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> index 3f96bdd2086f..a12add002b89 100644
> --- a/arch/arm64/include/asm/kvm_pgtable.h
> +++ b/arch/arm64/include/asm/kvm_pgtable.h
> @@ -578,6 +578,51 @@ int kvm_pgtable_stage2_set_owner(struct kvm_pgtable *pgt, u64 addr, u64 size,
> */
> int kvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size);
>
> +/**
> + * kvm_pgtable_stage2_clear_dbm() - Clear DBM of guest stage-2 address range
> + * without TLB invalidation (only last level).
> + * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init().
> + * @addr: Intermediate physical address from which to clear DBM,
> + * @size: Size of the range.
> + *
> + * The offset of @addr within a page is ignored and @size is rounded-up to
> + * the next page boundary.
> + *
> + * Note that it is the caller's responsibility to invalidate the TLB after
> + * calling this function to ensure that the disabled HW dirty are visible
> + * to the CPUs.
> + *
> + * Return: 0 on success, negative error code on failure.
> + */
> +int kvm_pgtable_stage2_clear_dbm(struct kvm_pgtable *pgt, u64 addr, u64 size);
> +
> +/**
> + * kvm_pgtable_stage2_set_dbm() - Set DBM of guest stage-2 address range to
> + * enable HW dirty (only last level).
> + * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init().
> + * @addr: Intermediate physical address from which to set DBM.
> + * @size: Size of the range.
> + *
> + * The offset of @addr within a page is ignored and @size is rounded-up to
> + * the next page boundary.
> + *
> + * Return: 0 on success, negative error code on failure.
> + */
> +int kvm_pgtable_stage2_set_dbm(struct kvm_pgtable *pgt, u64 addr, u64 size);
> +
> +/**
> + * kvm_pgtable_stage2_sync_dirty() - Sync HW dirty state into memslot.
> + * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init().
> + * @addr: Intermediate physical address from which to sync.
> + * @size: Size of the range.
> + *
> + * The offset of @addr within a page is ignored and @size is rounded-up to
> + * the next page boundary.
> + *
> + * Return: 0 on success, negative error code on failure.
> + */
> +int kvm_pgtable_stage2_sync_dirty(struct kvm_pgtable *pgt, u64 addr, u64 size);
> +
> /**
> * kvm_pgtable_stage2_wrprotect() - Write-protect guest stage-2 address range
> * without TLB invalidation.
> diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
> index 35f3c7959513..2ca600e3d637 100644
> --- a/arch/arm64/kernel/image-vars.h
> +++ b/arch/arm64/kernel/image-vars.h
> @@ -68,6 +68,8 @@ KVM_NVHE_ALIAS(__hyp_stub_vectors);
> KVM_NVHE_ALIAS(vgic_v2_cpuif_trap);
> KVM_NVHE_ALIAS(vgic_v3_cpuif_trap);
>
> +KVM_NVHE_ALIAS(mark_page_dirty);
> +
This doesn't make any sense besides satisfying the linker. The hyp page
table walkers will *never* need to mark a page as dirty.
Consider adding a new function pointer to kvm_pgtable_mm_ops and only
set it for the 'normal' stage-2 mm ops in mmu.c.
> +static bool stage2_pte_writeable(kvm_pte_t pte)
> +{
> + return pte & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W;
> +}
> +
> +static void kvm_update_hw_dbm(const struct kvm_pgtable_visit_ctx *ctx,
> + kvm_pte_t new)
> +{
> + kvm_pte_t old_pte, pte = ctx->old;
> +
> + /* Only set DBM if page is writeable */
> + if ((new & KVM_PTE_LEAF_ATTR_HI_S2_DBM) && !stage2_pte_writeable(pte))
> + return;
> +
> + /* Clear DBM walk is not shared, update */
> + if (!kvm_pgtable_walk_shared(ctx)) {
> + WRITE_ONCE(*ctx->ptep, new);
> + return;
> + }
> +
> + do {
> + old_pte = pte;
> + pte = new;
> +
> + if (old_pte == pte)
> + break;
> +
> + pte = cmpxchg_relaxed(ctx->ptep, old_pte, pte);
> + } while (pte != old_pte);
> +}
> +
We don't need a separate walker for updating the DBM state in the
page tables. Can't we treat it like any other permission bit and use
something like kvm_pgtable_stage2_relax_perms()?
Also, what is the purpose of retrying the update on a descriptor if the
cmpxchg() fails? Everywhere else in the page table walker code we bail
and retry execution since that is a clear indication of a race. In all
likelihood the other vCPU thread was either trying to update DBM or
service a permission fault.
> static bool stage2_try_set_pte(const struct kvm_pgtable_visit_ctx *ctx, kvm_pte_t new)
> {
> + if (kvm_pgtable_walk_hw_dbm(ctx)) {
> + kvm_update_hw_dbm(ctx, new);
> + return true;
> + }
> +
Why are you trying to circumvent the primitive for setting stage-2 PTEs?
> if (!kvm_pgtable_walk_shared(ctx)) {
> WRITE_ONCE(*ctx->ptep, new);
> return true;
> @@ -952,6 +990,11 @@ static int stage2_map_walker_try_leaf(const struct kvm_pgtable_visit_ctx *ctx,
> stage2_pte_executable(new))
> mm_ops->icache_inval_pou(kvm_pte_follow(new, mm_ops), granule);
>
> + /* Save the possible hardware dirty info */
> + if ((ctx->level == KVM_PGTABLE_MAX_LEVELS - 1) &&
> + stage2_pte_writeable(ctx->old))
> + mark_page_dirty(kvm_s2_mmu_to_kvm(pgt->mmu), ctx->addr >> PAGE_SHIFT);
> +
> stage2_make_pte(ctx, new);
>
> return 0;
> @@ -1125,6 +1168,11 @@ static int stage2_unmap_walker(const struct kvm_pgtable_visit_ctx *ctx,
> */
> stage2_unmap_put_pte(ctx, mmu, mm_ops);
>
> + /* Save the possible hardware dirty info */
> + if ((ctx->level == KVM_PGTABLE_MAX_LEVELS - 1) &&
> + stage2_pte_writeable(ctx->old))
> + mark_page_dirty(kvm_s2_mmu_to_kvm(mmu), ctx->addr >> PAGE_SHIFT);
> +
> if (need_flush && mm_ops->dcache_clean_inval_poc)
> mm_ops->dcache_clean_inval_poc(kvm_pte_follow(ctx->old, mm_ops),
> kvm_granule_size(ctx->level));
> @@ -1230,6 +1278,30 @@ static int stage2_update_leaf_attrs(struct kvm_pgtable *pgt, u64 addr,
> return 0;
> }
>
> +int kvm_pgtable_stage2_set_dbm(struct kvm_pgtable *pgt, u64 addr, u64 size)
> +{
> + int ret;
> + u64 offset;
> +
> + ret = stage2_update_leaf_attrs(pgt, addr, size, KVM_PTE_LEAF_ATTR_HI_S2_DBM, 0,
> + NULL, NULL, KVM_PGTABLE_WALK_HW_DBM |
> + KVM_PGTABLE_WALK_SHARED);
> + if (!ret)
> + return ret;
> +
> + for (offset = 0; offset < size; offset += PAGE_SIZE)
> + kvm_call_hyp(__kvm_tlb_flush_vmid_ipa_nsh, pgt->mmu, addr + offset, 3);
> +
> + return 0;
> +}
> +
> +int kvm_pgtable_stage2_clear_dbm(struct kvm_pgtable *pgt, u64 addr, u64 size)
> +{
> + return stage2_update_leaf_attrs(pgt, addr, size,
> + 0, KVM_PTE_LEAF_ATTR_HI_S2_DBM,
> + NULL, NULL, KVM_PGTABLE_WALK_HW_DBM);
> +}
> +
> int kvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size)
> {
> return stage2_update_leaf_attrs(pgt, addr, size, 0,
> @@ -1329,6 +1401,32 @@ int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
> return ret;
> }
>
> +static int stage2_sync_dirty_walker(const struct kvm_pgtable_visit_ctx *ctx,
> + enum kvm_pgtable_walk_flags visit)
> +{
> + kvm_pte_t pte = READ_ONCE(*ctx->ptep);
ctx->old is fetched in __kvm_pgtable_visit(), and the whole
parallelization scheme for page table walkers depends on us being
careful to read the PTE once per level. Do you need to reread it here?
--
Thanks,
Oliver
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2023-09-15 22:22 UTC|newest]
Thread overview: 66+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-25 9:35 [RFC PATCH v2 0/8] KVM: arm64: Implement SW/HW combined dirty log Shameer Kolothum
2023-08-25 9:35 ` Shameer Kolothum
2023-08-25 9:35 ` [RFC PATCH v2 1/8] arm64: cpufeature: Add API to report system support of HWDBM Shameer Kolothum
2023-08-25 9:35 ` Shameer Kolothum
2023-08-25 9:35 ` [RFC PATCH v2 2/8] KVM: arm64: Add KVM_PGTABLE_WALK_HW_DBM for HW DBM support Shameer Kolothum
2023-08-25 9:35 ` Shameer Kolothum
2023-09-15 22:05 ` Oliver Upton
2023-09-15 22:05 ` Oliver Upton
2023-09-18 9:52 ` Shameerali Kolothum Thodi
2023-09-18 9:52 ` Shameerali Kolothum Thodi
2023-08-25 9:35 ` [RFC PATCH v2 3/8] KVM: arm64: Add some HW_DBM related pgtable interfaces Shameer Kolothum
2023-08-25 9:35 ` Shameer Kolothum
2023-09-15 22:22 ` Oliver Upton [this message]
2023-09-15 22:22 ` Oliver Upton
2023-09-18 9:53 ` Shameerali Kolothum Thodi
2023-09-18 9:53 ` Shameerali Kolothum Thodi
2023-09-22 15:24 ` Catalin Marinas
2023-09-22 15:24 ` Catalin Marinas
2023-09-22 17:49 ` Oliver Upton
2023-09-22 17:49 ` Oliver Upton
2023-09-25 8:04 ` Shameerali Kolothum Thodi
2023-09-25 8:04 ` Shameerali Kolothum Thodi
2023-09-26 15:20 ` Catalin Marinas
2023-09-26 15:20 ` Catalin Marinas
2023-09-26 15:52 ` Shameerali Kolothum Thodi
2023-09-26 15:52 ` Shameerali Kolothum Thodi
2023-09-26 16:37 ` Catalin Marinas
2023-09-26 16:37 ` Catalin Marinas
2023-08-25 9:35 ` [RFC PATCH v2 4/8] KVM: arm64: Set DBM for previously writeable pages Shameer Kolothum
2023-08-25 9:35 ` Shameer Kolothum
2023-09-15 22:54 ` Oliver Upton
2023-09-15 22:54 ` Oliver Upton
2023-09-18 9:54 ` Shameerali Kolothum Thodi
2023-09-18 9:54 ` Shameerali Kolothum Thodi
2023-09-22 15:40 ` Catalin Marinas
2023-09-22 15:40 ` Catalin Marinas
2023-09-25 8:04 ` Shameerali Kolothum Thodi
2023-09-25 8:04 ` Shameerali Kolothum Thodi
2023-08-25 9:35 ` [RFC PATCH v2 5/8] KVM: arm64: Add some HW_DBM related mmu interfaces Shameer Kolothum
2023-08-25 9:35 ` Shameer Kolothum
2023-08-25 9:35 ` [RFC PATCH v2 6/8] KVM: arm64: Only write protect selected PTE Shameer Kolothum
2023-08-25 9:35 ` Shameer Kolothum
2023-09-22 16:00 ` Catalin Marinas
2023-09-22 16:00 ` Catalin Marinas
2023-09-22 16:59 ` Oliver Upton
2023-09-22 16:59 ` Oliver Upton
2023-09-26 15:58 ` Catalin Marinas
2023-09-26 15:58 ` Catalin Marinas
2023-09-26 16:10 ` Catalin Marinas
2023-09-26 16:10 ` Catalin Marinas
2023-08-25 9:35 ` [RFC PATCH v2 7/8] KVM: arm64: Add KVM_CAP_ARM_HW_DBM Shameer Kolothum
2023-08-25 9:35 ` Shameer Kolothum
2023-08-25 9:35 ` [RFC PATCH v2 8/8] KVM: arm64: Start up SW/HW combined dirty log Shameer Kolothum
2023-08-25 9:35 ` Shameer Kolothum
2023-09-13 17:30 ` [RFC PATCH v2 0/8] KVM: arm64: Implement " Oliver Upton
2023-09-13 17:30 ` Oliver Upton
2023-09-14 9:47 ` Shameerali Kolothum Thodi
2023-09-14 9:47 ` Shameerali Kolothum Thodi
2023-09-15 0:36 ` Oliver Upton
2023-09-15 0:36 ` Oliver Upton
2023-09-18 9:55 ` Shameerali Kolothum Thodi
2023-09-18 9:55 ` Shameerali Kolothum Thodi
2023-09-20 21:12 ` Oliver Upton
2023-09-20 21:12 ` Oliver Upton
2023-10-12 7:51 ` Shameerali Kolothum Thodi
2023-10-12 7:51 ` 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=ZQTZMl7RP8ZYQ6tr@linux.dev \
--to=oliver.upton@linux.dev \
--cc=catalin.marinas@arm.com \
--cc=james.morse@arm.com \
--cc=jonathan.cameron@huawei.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linuxarm@huawei.com \
--cc=maz@kernel.org \
--cc=shameerali.kolothum.thodi@huawei.com \
--cc=suzuki.poulose@arm.com \
--cc=will@kernel.org \
--cc=yuzenghui@huawei.com \
--cc=zhukeqian1@huawei.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.