Kernel KVM virtualization development
 help / color / mirror / Atom feed
* [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

* [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 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

* 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