* [PATCH 0/2] RISC-V: KVM: Optimize hfence request handling for SMP guests
@ 2026-07-07 11:37 Wang Yechao
2026-07-07 11:37 ` [PATCH 1/2] RISC-V: KVM: Move hfence type check out of loop Wang Yechao
2026-07-07 11:37 ` [PATCH 2/2] RISC-V: KVM: Separate req and fallback_req masks in make_xfence_request Wang Yechao
0 siblings, 2 replies; 5+ messages in thread
From: Wang Yechao @ 2026-07-07 11:37 UTC (permalink / raw)
To: Anup Patel, kvm, kvm-riscv, linux-riscv, linux-kernel
Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Atish Patra,
Alexandre Ghiti, Wang Yechao
This series improves the hfence request handling in RISC-V KVM,
targeting scenarios where multiple VCPUs are running an SMP guest.
The first patch moves the hfence data/type validation out of the
VCPU loop to avoid redundant checks on every iteration.
The second patch fixes a more subtle performance issue: when one
VCPU's hfence queue becomes full and triggers a fallback, the
current code applies the fallback to all VCPUs indiscriminately.
This unnecessarily degrades healthy VCPUs and can cause their
queues to fill up prematurely due to lack of processing it.
With these changes, fallback is applied only to the VCPUs that
actually need it, preserving the efficiency of the normal path
for others.
Wang Yechao (2):
RISC-V: KVM: Move hfence type check out of loop
RISC-V: KVM: Separate req and fallback_req masks in
make_xfence_request
arch/riscv/kvm/tlb.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
--
2.43.5
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 1/2] RISC-V: KVM: Move hfence type check out of loop 2026-07-07 11:37 [PATCH 0/2] RISC-V: KVM: Optimize hfence request handling for SMP guests Wang Yechao @ 2026-07-07 11:37 ` Wang Yechao 2026-07-07 11:45 ` sashiko-bot 2026-07-07 11:37 ` [PATCH 2/2] RISC-V: KVM: Separate req and fallback_req masks in make_xfence_request Wang Yechao 1 sibling, 1 reply; 5+ messages in thread From: Wang Yechao @ 2026-07-07 11:37 UTC (permalink / raw) To: Anup Patel, kvm, kvm-riscv, linux-riscv, linux-kernel Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Atish Patra, Alexandre Ghiti, Wang Yechao Currently, the check for `data` and `data->type` is performed inside the loop iterating over each VCPU. Since these values are invariant during the loop, this check is redundant and adds unnecessary overhead. Move the validation to the beginning of the function, returning early if the hfence data or its type is invalid. This avoids repeated checks and reduces CPU cycles, which is particularly beneficial for SMP guests with a large number of VCPUs. Signed-off-by: Wang Yechao <wang.yechao255@zte.com.cn> --- arch/riscv/kvm/tlb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/riscv/kvm/tlb.c b/arch/riscv/kvm/tlb.c index 993b25ea94d67..a67b44a4d1d7a 100644 --- a/arch/riscv/kvm/tlb.c +++ b/arch/riscv/kvm/tlb.c @@ -335,6 +335,9 @@ static void make_xfence_request(struct kvm *kvm, unsigned int actual_req = req; DECLARE_BITMAP(vcpu_mask, KVM_MAX_VCPUS); + if (!data || !data->type) + return; + bitmap_zero(vcpu_mask, KVM_MAX_VCPUS); kvm_for_each_vcpu(i, vcpu, kvm) { if (hbase != -1UL) { @@ -347,9 +350,6 @@ static void make_xfence_request(struct kvm *kvm, bitmap_set(vcpu_mask, i, 1); - if (!data || !data->type) - continue; - /* * Enqueue hfence data to VCPU hfence queue. If we don't * have space in the VCPU hfence queue then fallback to -- 2.43.5 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] RISC-V: KVM: Move hfence type check out of loop 2026-07-07 11:37 ` [PATCH 1/2] RISC-V: KVM: Move hfence type check out of loop Wang Yechao @ 2026-07-07 11:45 ` sashiko-bot 0 siblings, 0 replies; 5+ messages in thread From: sashiko-bot @ 2026-07-07 11:45 UTC (permalink / raw) To: Wang Yechao; +Cc: kvm Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [High] The patch completely breaks KVM_REQ_FENCE_I requests by unconditionally returning early from `make_xfence_request` when `data` is NULL, silently dropping guest instruction cache invalidations. -- --- Patch [1]: [PATCH 1/2] RISC-V: KVM: Move hfence type check out of loop --- commit 7dbdb7321dcb98c78f1282572934fc7ae89bab7e Author: Wang Yechao <wang.yechao255@zte.com.cn> RISC-V: KVM: Move hfence type check out of loop This commit moves the validation of data and data->type outside the VCPU iteration loop in make_xfence_request() to reduce overhead. It adds an early return if the hfence data or its type is invalid. > diff --git a/arch/riscv/kvm/tlb.c b/arch/riscv/kvm/tlb.c > index 993b25ea94d67..a67b44a4d1d7a 100644 > --- a/arch/riscv/kvm/tlb.c > +++ b/arch/riscv/kvm/tlb.c > @@ -335,6 +335,9 @@ static void make_xfence_request(struct kvm *kvm, > unsigned int actual_req = req; > DECLARE_BITMAP(vcpu_mask, KVM_MAX_VCPUS); > > + if (!data || !data->type) > + return; > + [Severity: High] Does this early return break callers that intentionally pass NULL for data? For example, kvm_riscv_fence_i() calls make_xfence_request() with data=NULL to broadcast a KVM_REQ_FENCE_I request: arch/riscv/kvm/tlb.c:kvm_riscv_fence_i() { ... make_xfence_request(kvm, hbase, hmask, KVM_REQ_FENCE_I, KVM_REQ_FENCE_I, NULL); ... } In the old code, passing NULL skipped enqueueing to the hfence queue but still allowed the loop to populate vcpu_mask, so the request was properly broadcast. With this change, the function returns immediately, dropping guest instruction cache invalidations. Could this lead to guests executing stale instructions? > bitmap_zero(vcpu_mask, KVM_MAX_VCPUS); > kvm_for_each_vcpu(i, vcpu, kvm) { > if (hbase != -1UL) { [ ... ] > @@ -347,9 +350,6 @@ static void make_xfence_request(struct kvm *kvm, > > bitmap_set(vcpu_mask, i, 1); > > - if (!data || !data->type) > - continue; > - > /* > * Enqueue hfence data to VCPU hfence queue. If we don't > * have space in the VCPU hfence queue then fallback to -- Sashiko AI review · https://sashiko.dev/#/patchset/20260707113715.413265-1-wang.yechao255@zte.com.cn?part=1 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/2] RISC-V: KVM: Separate req and fallback_req masks in make_xfence_request 2026-07-07 11:37 [PATCH 0/2] RISC-V: KVM: Optimize hfence request handling for SMP guests Wang Yechao 2026-07-07 11:37 ` [PATCH 1/2] RISC-V: KVM: Move hfence type check out of loop Wang Yechao @ 2026-07-07 11:37 ` Wang Yechao 2026-07-07 11:47 ` sashiko-bot 1 sibling, 1 reply; 5+ messages in thread From: Wang Yechao @ 2026-07-07 11:37 UTC (permalink / raw) To: Anup Patel, kvm, kvm-riscv, linux-riscv, linux-kernel Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Atish Patra, Alexandre Ghiti, Wang Yechao When handling hfence requests in make_xfence_request(), the current code uses a single 'actual_req' variable and a single vcpu_mask. If any VCPU fails to enqueue the hfence data (because its queue is full), the request falls back to 'fallback_req' for all VCPUs, even if other VCPUs still have available queue space. This can cause unnecessary fallback for healthy VCPUs, and more seriously, those healthy VCPUs will not process their already-enqueued hfence requests because no 'req' is set for them. As a result, their queues will quickly become full as well, degrading performance for SMP guests. Fix this by maintaining two separate bitmaps: one for VCPUs that successfully enqueued the hfence data (req_vcpu_mask) and another for those that failed (fallback_req_vcpu_mask). Then send the appropriate requests to each group. This ensures that fallback is only applied to VCPUs that actually need it, preserving the efficiency of the normal path for others. Fixes: 13acfec2dbcc ("RISC-V: KVM: Add remote HFENCE functions based on VCPU requests") Signed-off-by: Wang Yechao <wang.yechao255@zte.com.cn> --- arch/riscv/kvm/tlb.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/arch/riscv/kvm/tlb.c b/arch/riscv/kvm/tlb.c index a67b44a4d1d7a..916e2b1e0b366 100644 --- a/arch/riscv/kvm/tlb.c +++ b/arch/riscv/kvm/tlb.c @@ -332,13 +332,14 @@ static void make_xfence_request(struct kvm *kvm, { unsigned long i; struct kvm_vcpu *vcpu; - unsigned int actual_req = req; - DECLARE_BITMAP(vcpu_mask, KVM_MAX_VCPUS); + DECLARE_BITMAP(req_vcpu_mask, KVM_MAX_VCPUS); + DECLARE_BITMAP(fallback_req_vcpu_mask, KVM_MAX_VCPUS); if (!data || !data->type) return; - bitmap_zero(vcpu_mask, KVM_MAX_VCPUS); + bitmap_zero(req_vcpu_mask, KVM_MAX_VCPUS); + bitmap_zero(fallback_req_vcpu_mask, KVM_MAX_VCPUS); kvm_for_each_vcpu(i, vcpu, kvm) { if (hbase != -1UL) { if (vcpu->vcpu_id < hbase || @@ -348,18 +349,19 @@ static void make_xfence_request(struct kvm *kvm, continue; } - bitmap_set(vcpu_mask, i, 1); - /* * Enqueue hfence data to VCPU hfence queue. If we don't * have space in the VCPU hfence queue then fallback to * a more conservative hfence request. */ if (!vcpu_hfence_enqueue(vcpu, data)) - actual_req = fallback_req; + bitmap_set(fallback_req_vcpu_mask, i, 1); + else + bitmap_set(req_vcpu_mask, i, 1); } - kvm_make_vcpus_request_mask(kvm, actual_req, vcpu_mask); + kvm_make_vcpus_request_mask(kvm, req, req_vcpu_mask); + kvm_make_vcpus_request_mask(kvm, fallback_req, fallback_req_vcpu_mask); } void kvm_riscv_fence_i(struct kvm *kvm, -- 2.43.5 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] RISC-V: KVM: Separate req and fallback_req masks in make_xfence_request 2026-07-07 11:37 ` [PATCH 2/2] RISC-V: KVM: Separate req and fallback_req masks in make_xfence_request Wang Yechao @ 2026-07-07 11:47 ` sashiko-bot 0 siblings, 0 replies; 5+ messages in thread From: sashiko-bot @ 2026-07-07 11:47 UTC (permalink / raw) To: Wang Yechao; +Cc: kvm Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [High] The patch series silently drops FENCE.I requests by introducing an early return when `data` is NULL, breaking guest I-cache synchronization. -- --- Patch [2]: [PATCH 2/2] RISC-V: KVM: Separate req and fallback_req masks in make_xfence_request --- commit dc6a1097782a407911f8597843403d3a551a9225 Author: Wang Yechao <wang.yechao255@zte.com.cn> RISC-V: KVM: Separate req and fallback_req masks in make_xfence_request This commit modifies make_xfence_request() to maintain separate bitmaps for vCPUs that successfully enqueue hfence data and those that require fallback requests. It then applies the appropriate request to each group separately. > diff --git a/arch/riscv/kvm/tlb.c b/arch/riscv/kvm/tlb.c > index a67b44a4d1d7a..916e2b1e0b366 100644 > --- a/arch/riscv/kvm/tlb.c > +++ b/arch/riscv/kvm/tlb.c > @@ -332,13 +332,14 @@ static void make_xfence_request(struct kvm *kvm, > { > unsigned long i; > struct kvm_vcpu *vcpu; > - unsigned int actual_req = req; > - DECLARE_BITMAP(vcpu_mask, KVM_MAX_VCPUS); > + DECLARE_BITMAP(req_vcpu_mask, KVM_MAX_VCPUS); > + DECLARE_BITMAP(fallback_req_vcpu_mask, KVM_MAX_VCPUS); > > if (!data || !data->type) > return; [Severity: High] Does this early return unconditionally abort the function when data is NULL, preventing KVM_REQ_FENCE_I from ever being processed and skipping the vCPU mask creation? Looking at kvm_riscv_fence_i() in arch/riscv/kvm/tlb.c, it explicitly passes NULL for data: void kvm_riscv_fence_i(struct kvm *kvm, unsigned long hbase, unsigned long hmask) { make_xfence_request(kvm, hbase, hmask, KVM_REQ_FENCE_I, KVM_REQ_FENCE_I, NULL); } When a guest triggers SBI_EXT_RFENCE_REMOTE_FENCE_I, it invokes kvm_riscv_fence_i(). Because data is NULL, make_xfence_request() returns immediately without setting the KVM_REQ_FENCE_I bit or kicking the target vCPUs. Can this missing I-cache flush cause a guest to execute stale instructions, leading to unpredictable guest behavior, kernel panics, or data corruption? -- Sashiko AI review · https://sashiko.dev/#/patchset/20260707113715.413265-1-wang.yechao255@zte.com.cn?part=2 ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-07-07 11:47 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-07-07 11:37 [PATCH 0/2] RISC-V: KVM: Optimize hfence request handling for SMP guests Wang Yechao 2026-07-07 11:37 ` [PATCH 1/2] RISC-V: KVM: Move hfence type check out of loop Wang Yechao 2026-07-07 11:45 ` sashiko-bot 2026-07-07 11:37 ` [PATCH 2/2] RISC-V: KVM: Separate req and fallback_req masks in make_xfence_request Wang Yechao 2026-07-07 11:47 ` sashiko-bot
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox