mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Tian Zheng <zhengtian10@huawei.com>
To: Leonardo Bras <leo.bras@arm.com>
Cc: <maz@kernel.org>, <oupton@kernel.org>, <catalin.marinas@arm.com>,
	<will@kernel.org>, <yuzenghui@huawei.com>,
	<wangzhou1@hisilicon.com>, <yangjinqian1@huawei.com>,
	<caijian11@h-partners.com>, <liuyonglong@huawei.com>,
	<yezhenyu2@huawei.com>, <yubihong@huawei.com>,
	<linuxarm@huawei.com>, <joey.gouly@arm.com>,
	<kvmarm@lists.linux.dev>, <kvm@vger.kernel.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-kernel@vger.kernel.org>, <seiden@linux.ibm.com>,
	<suzuki.poulose@arm.com>
Subject: Re: [PATCH v4 5/6] KVM: arm64: Add HDBSS fault handling and buffer flush
Date: Tue, 14 Jul 2026 21:27:15 +0800	[thread overview]
Message-ID: <fa0839f9-7d83-4ad1-80e2-7e7dd0280222@huawei.com> (raw)
In-Reply-To: <alYUXkub43YxkeH1@LeoBrasDK>


On 7/14/2026 6:50 PM, Leonardo Bras wrote:
> On Tue, Jul 14, 2026 at 03:38:39PM +0800, Tian Zheng wrote:
>> On 7/13/2026 10:06 PM, Leonardo Bras wrote:
>>> On Thu, Jul 09, 2026 at 06:40:25PM +0800, Tian Zheng wrote:
>>>> From: eillon <yezhenyu2@huawei.com>
>>>>
>>>> Add HDBSS fault handling for buffer full, external abort, and general
>>>> protection fault (GPF) events. When the HDBSS buffer becomes full,
>>>> the hardware traps to EL2 with an HDBSSF event, which is handled by
>>>> setting a flush request.
>>>>
>>>> Add kvm_flush_hdbss_buffer() to consume HDBSS buffer entries and
>>>> propagate dirty information into the userspace-visible dirty bitmap.
>>>> Flush is triggered on vcpu_put, check_vcpu_requests, and
>>>> sync_dirty_log.
>>>>
>>>> Add esr_iss2_is_hdbssf() helper for HDBSS fault detection in guest
>>>> abort handling.
>>>>
>>>> Signed-off-by: Eillon <yezhenyu2@huawei.com>
>>>> Signed-off-by: Tian Zheng <zhengtian10@huawei.com>
>>>> ---
>>>>    arch/arm64/include/asm/esr.h           |  5 +++
>>>>    arch/arm64/include/asm/kvm_dirty_bit.h | 11 +++++
>>>>    arch/arm64/include/asm/kvm_host.h      |  1 +
>>>>    arch/arm64/kvm/arm.c                   | 14 ++++++
>>>>    arch/arm64/kvm/dirty_bit.c             | 62 ++++++++++++++++++++++++++
>>>>    arch/arm64/kvm/mmu.c                   |  4 ++
>>>>    6 files changed, 97 insertions(+)
>>>>
>>>> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
>>>> index 81c17320a588..2e6b679b5908 100644
>>>> --- a/arch/arm64/include/asm/esr.h
>>>> +++ b/arch/arm64/include/asm/esr.h
>>>> @@ -437,6 +437,11 @@
>>>>    #ifndef __ASSEMBLER__
>>>>    #include <asm/types.h>
>>>>
>>>> +static inline bool esr_iss2_is_hdbssf(unsigned long esr)
>>>> +{
>>>> +	return ESR_ELx_ISS2(esr) & ESR_ELx_HDBSSF;
>>> This will return a long, which will be casted as bool.
>>> In general, what I see in the kernel is something like:
>>>
>>> 	return !!(ESR_ELx_ISS2(esr) & ESR_ELx_HDBSSF)
>>
>> ok!
>>
>>
>>>> +}
>>>> +
>>>>    static inline unsigned long esr_brk_comment(unsigned long esr)
>>>>    {
>>>>    	return esr & ESR_ELx_BRK64_ISS_COMMENT_MASK;
>>>> diff --git a/arch/arm64/include/asm/kvm_dirty_bit.h b/arch/arm64/include/asm/kvm_dirty_bit.h
>>>> index 84b12f0a10af..4b28000e972f 100644
>>>> --- a/arch/arm64/include/asm/kvm_dirty_bit.h
>>>> +++ b/arch/arm64/include/asm/kvm_dirty_bit.h
>>>> @@ -10,7 +10,18 @@
>>>>    #include <asm/kvm_pgtable.h>
>>>>    #include <asm/sysreg.h>
>>>>
>>>> +/* HDBSS entry field definitions */
>>>> +#define HDBSS_ENTRY_VALID	BIT(0)
>>>> +#define HDBSS_ENTRY_TTWL_SHIFT (1)
>>>> +#define HDBSS_ENTRY_TTWL_MASK (GENMASK(3, 1))
>>>> +#define HDBSS_ENTRY_TTWL(x) \
>>>> +	(((x) << HDBSS_ENTRY_TTWL_SHIFT) & HDBSS_ENTRY_TTWL_MASK)
>>>> +#define HDBSS_ENTRY_TTWL_RESV HDBSS_ENTRY_TTWL(-4)
>>>> +#define HDBSS_ENTRY_IPA	GENMASK_ULL(55, 12)
>>>> +
>>>>    int kvm_arm_vcpu_alloc_hdbss(struct kvm_vcpu *vcpu, unsigned int order);
>>>>    void kvm_arm_vcpu_free_hdbss(struct kvm_vcpu *vcpu);
>>>> +void kvm_flush_hdbss_buffer(struct kvm_vcpu *vcpu);
>>>> +int kvm_handle_hdbss_fault(struct kvm_vcpu *vcpu);
>>>>
>>>>    #endif /* __ARM64_KVM_DIRTY_BIT_H__ */
>>>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
>>>> index c41ec6d9c45a..cecfb884a64f 100644
>>>> --- a/arch/arm64/include/asm/kvm_host.h
>>>> +++ b/arch/arm64/include/asm/kvm_host.h
>>>> @@ -55,6 +55,7 @@
>>>>    #define KVM_REQ_GUEST_HYP_IRQ_PENDING	KVM_ARCH_REQ(9)
>>>>    #define KVM_REQ_MAP_L1_VNCR_EL2		KVM_ARCH_REQ(10)
>>>>    #define KVM_REQ_VGIC_PROCESS_UPDATE	KVM_ARCH_REQ(11)
>>>> +#define KVM_REQ_FLUSH_HDBSS			KVM_ARCH_REQ(12)
>>>>
>>>>    #define KVM_DIRTY_LOG_MANUAL_CAPS   (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \
>>>>    				     KVM_DIRTY_LOG_INITIALLY_SET)
>>>> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
>>>> index bf6688245d83..566953a4e23a 100644
>>>> --- a/arch/arm64/kvm/arm.c
>>>> +++ b/arch/arm64/kvm/arm.c
>>>> @@ -755,6 +755,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
>>>>    		kvm_vcpu_put_hw_mmu(vcpu);
>>>>    	kvm_arm_vmid_clear_active();
>>>>
>>>> +	if (vcpu->kvm->arch.enable_hdbss)
>>>> +		kvm_flush_hdbss_buffer(vcpu);
>>>> +
>>>>    	vcpu_clear_on_unsupported_cpu(vcpu);
>>>>    	vcpu->cpu = -1;
>>>>    }
>>>> @@ -1157,6 +1160,9 @@ static int check_vcpu_requests(struct kvm_vcpu *vcpu)
>>>>    		if (kvm_dirty_ring_check_request(vcpu))
>>>>    			return 0;
>>>>
>>>> +		if (kvm_check_request(KVM_REQ_FLUSH_HDBSS, vcpu))
>>>> +			kvm_flush_hdbss_buffer(vcpu);
>>>> +
>>>>    		check_nested_vcpu_requests(vcpu);
>>>>    	}
>>>>
>>>> @@ -1971,7 +1977,15 @@ long kvm_arch_vcpu_unlocked_ioctl(struct file *filp, unsigned int ioctl,
>>>>
>>>>    void kvm_arch_sync_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot)
>>>>    {
>>>> +	/*
>>>> +	 * Flush all CPUs' dirty log buffers to the dirty_bitmap.  Called
>>>> +	 * before reporting dirty_bitmap to userspace. Send a request with
>>>> +	 * KVM_REQUEST_WAIT to flush buffer synchronously.
>>>> +	 */
>>>> +	if (!kvm->arch.enable_hdbss)
>>>> +		return;
>>>>
>>>> +	kvm_make_all_cpus_request(kvm, KVM_REQ_FLUSH_HDBSS | KVM_REQUEST_WAIT);
>>>>    }
>>>>
>>>>    static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm,
>>>> diff --git a/arch/arm64/kvm/dirty_bit.c b/arch/arm64/kvm/dirty_bit.c
>>>> index 6c7a6ef66b5a..002366337637 100644
>>>> --- a/arch/arm64/kvm/dirty_bit.c
>>>> +++ b/arch/arm64/kvm/dirty_bit.c
>>>> @@ -50,3 +50,65 @@ void kvm_arm_vcpu_free_hdbss(struct kvm_vcpu *vcpu)
>>>>
>>>>    	vcpu->arch.hdbss.hdbssbr_el2 = 0;
>>>>    }
>>>> +
>>>> +void kvm_flush_hdbss_buffer(struct kvm_vcpu *vcpu)
>>>> +{
>>>> +	int idx, curr_idx;
>>>> +	u64 *hdbss_buf;
>>>> +	struct kvm *kvm = vcpu->kvm;
>>>> +
>>>> +	if (!kvm->arch.enable_hdbss)
>>>> +		return;
>>>> +
>>>> +	curr_idx = HDBSSPROD_IDX(read_sysreg_s(SYS_HDBSSPROD_EL2));
>>>> +
>>>> +	/* Do nothing if HDBSS buffer is empty or br_el2 is NULL */
>>>> +	if (curr_idx == 0 || vcpu->arch.hdbss.hdbssbr_el2 == 0)
>>>> +		return;
>>>> +
>>>> +	hdbss_buf = page_address(phys_to_page(vcpu->arch.hdbss.base_phys));
>>>> +	if (!hdbss_buf)
>>>> +		return;
>>>> +
>>>> +	guard(write_lock_irqsave)(&vcpu->kvm->mmu_lock);
>>>> +	for (idx = 0; idx < curr_idx; idx++) {
>>>> +		u64 gpa;
>>>> +
>>>> +		gpa = hdbss_buf[idx];
>>>> +		if (!(gpa & HDBSS_ENTRY_VALID))
>>>> +			continue;
>>>> +
>>>> +		gpa &= HDBSS_ENTRY_IPA;
>>>> +		kvm_vcpu_mark_page_dirty(vcpu, gpa >> PAGE_SHIFT);
>>> You mention that it does not support dirty-ring, but above function will
>>> mark the page as dirty in the dirty-ring :/
>>>
>> In kvm_arm_enable_hdbss_global(), we explicitly check and reject HDBSS
>> enablement if dirty-ring is active:
>>
>> ```
>> if (kvm->dirty_ring_size)
>>      return 0;
>> ```
>>
>> So when kvm_flush_hdbss_buffer() runs (which requires enable_hdbss = true),
>> we know for certain that
>>
>> kvm->dirty_ring_size == 0. Therefore, kvm_vcpu_mark_page_dirty() will always
>> take the dirty_bitmap path,
>>
>> never the dirty-ring path.
>>
>> That said, I'll add a comment in kvm_flush_hdbss_buffer() before dirty ring
>> mode is supported, to make this explicit:
>>
>> ```
>> /*
>>   * HDBSS is mutually exclusive with dirty-ring mode (see
>>   * kvm_arm_enable_hdbss_global()), so kvm_vcpu_mark_page_dirty()
>>   * will update the dirty_bitmap, not the dirty-ring.
>>   */
>> ```
>>
> Got it :)
>
> Out of curiosity: which issues have you found on supporting dirty-ring at
> this point?
>
> Thanks!
> Leo
>   


I haven't looked deeply into dirty-ring yet — my main concern is that if 
both the dirty

ring and HDBSS buffer fill up, the flush path might get blocked or 
complicated.

For now, I'm planning to match the HDBSS buffer size to the dirty ring 
size in v5 and test it.

Ideally, the two buffers would be the same size, and the entire dirty 
tracking path would use

HDBSS exclusively — no fallback to the legacy dirty bitmap path. If that 
works, I think this approach should be fine.

Let me know if you have any insights on dirty ring's full-buffer 
behavior — that would be helpful.



  reply	other threads:[~2026-07-14 13:27 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-09 10:40 [PATCH v4 0/6] Support the FEAT_HDBSS introduced in Armv9.5 Tian Zheng
2026-07-09 10:40 ` [PATCH v4 1/6] KVM: arm64: Enable eager hugepage splitting if HDBSS is available Tian Zheng
2026-07-09 10:40 ` [PATCH v4 2/6] KVM: arm64: Add support for FEAT_HDBSS Tian Zheng
2026-07-09 10:40 ` [PATCH v4 3/6] KVM: arm64: Add auto DBM support for hardware dirty tracking Tian Zheng
2026-07-13 11:17   ` Leonardo Bras
2026-07-14  1:14     ` Tian Zheng
2026-07-14  7:23       ` Marc Zyngier
2026-07-14  7:44         ` Tian Zheng
2026-07-14 10:20           ` Leonardo Bras
2026-07-16  7:39   ` Oliver Upton
2026-07-17  3:58     ` Tian Zheng
2026-07-17 15:21       ` Leonardo Bras
2026-07-09 10:40 ` [PATCH v4 4/6] KVM: arm64: Add HDBSS per-vCPU buffer management Tian Zheng
2026-07-13 13:39   ` Leonardo Bras
2026-07-14  7:15     ` Tian Zheng
2026-07-14 10:47       ` Leonardo Bras
2026-07-15  9:16         ` Tian Zheng
2026-07-15 14:28           ` Leonardo Bras
2026-07-17  4:06             ` Tian Zheng
2026-07-09 10:40 ` [PATCH v4 5/6] KVM: arm64: Add HDBSS fault handling and buffer flush Tian Zheng
2026-07-13 14:06   ` Leonardo Bras
2026-07-14  7:38     ` Tian Zheng
2026-07-14 10:50       ` Leonardo Bras
2026-07-14 13:27         ` Tian Zheng [this message]
2026-07-14 14:19           ` Leonardo Bras
2026-07-17  6:51             ` Tian Zheng
2026-07-17 15:44               ` Leonardo Bras
2026-07-09 10:40 ` [PATCH v4 6/6] KVM: arm64: Add auto HDBSS enable/disable on dirty logging change Tian Zheng
2026-07-13 14:50   ` Leonardo Bras
2026-07-14  8:58     ` Tian Zheng
2026-07-14 11:16       ` Leonardo Bras
2026-07-14 14:33         ` Leonardo Bras
2026-07-16  8:37           ` Tian Zheng
2026-07-17  7:23         ` Tian Zheng
2026-07-17 15:50           ` Leonardo Bras
2026-07-16  7:15     ` Tian Zheng
2026-07-17 15:53       ` Leonardo Bras
2026-07-13 10:31 ` [PATCH v4 0/6] Support the FEAT_HDBSS introduced in Armv9.5 Leonardo Bras
2026-07-13 16:27   ` Leonardo Bras
2026-07-14 10:39     ` Tian Zheng
2026-07-14 11:20       ` Leonardo Bras
2026-07-14 13:29         ` Tian Zheng
2026-07-14  9:37   ` Tian Zheng
2026-07-14 10:19     ` Leonardo Bras
2026-07-14 13:34       ` Tian Zheng

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=fa0839f9-7d83-4ad1-80e2-7e7dd0280222@huawei.com \
    --to=zhengtian10@huawei.com \
    --cc=caijian11@h-partners.com \
    --cc=catalin.marinas@arm.com \
    --cc=joey.gouly@arm.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=leo.bras@arm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxarm@huawei.com \
    --cc=liuyonglong@huawei.com \
    --cc=maz@kernel.org \
    --cc=oupton@kernel.org \
    --cc=seiden@linux.ibm.com \
    --cc=suzuki.poulose@arm.com \
    --cc=wangzhou1@hisilicon.com \
    --cc=will@kernel.org \
    --cc=yangjinqian1@huawei.com \
    --cc=yezhenyu2@huawei.com \
    --cc=yubihong@huawei.com \
    --cc=yuzenghui@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox