All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/5] KVM: riscv: Fix stale FWFT feature exposure and enhance selftests
@ 2026-06-01 10:26 ` Yong-Xuan Wang
  0 siblings, 0 replies; 40+ messages in thread
From: Yong-Xuan Wang @ 2026-06-01 10:26 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan
  Cc: greentime.hu, vincent.chen, zong.li, kvm, kvm-riscv, linux-riscv,
	linux-kernel, linux-kselftest, inochiama, Yong-Xuan Wang

This series fixes three bugs in the SBI FWFT (Firmware Features) extension
and improves the related selftest infrastructure.
The bugs are:
1. Missing CSR dirty marking: When userspace sets FWFT feature values via
   KVM_SET_ONE_REG, modified CSRs (e.g., henvcfg.PMM for pointer masking)
   are not marked dirty, leading to stale state after vCPU scheduling or
   migration.
2. Hardware probing side effects: The try_to_set_pmm() function modifies
   HENVCFG.PMM during hardware capability detection but fails to restore
   the original value, leaving the CSR in an altered state that affects
   subsequent operations.
3. Stale feature exposure: FWFT feature support is cached at vCPU
   initialization time. When userspace subsequently disables ISA extensions
   via KVM_SET_ONE_REG, the cached support status is not updated, allowing
   guests to access features that depend on disabled extensions.
Patches 1-3 fix these bugs separately.

The selftest improvements (patches 4-5) enhance the get-reg-list test by
refactoring the extension sublist infrastructure and splitting FWFT
feature testing into separate, properly-gated sublists.

---
Changes in v5:
- Add CSR dirty marking fix (new patch 1/5) (sashiko-bot)
- Split original FWFT bug fix into two focused patches
  - Add init() callback with try_to_set_pmm() restoration fix (new patch
    2/5) (sashiko-bot)
  - Keep runtime supported() checks as separate patch (patch 3/5)
- Link to v4: https://patch.msgid.link/20260601-kvm-get_reg_list-v2-v4-0-c88abc81ebda@sifive.com

Changes in v4:
- Rename the title of cover letter
- Disable preemption when running try_to_set_pmm() (sashiko-bot)
- Remove check_supported_reg() (sashiko-bot)
- Link to v3: https://patch.msgid.link/20260528-kvm-get_reg_list-v2-v3-0-170969a8599f@sifive.com

Changes in v3:
- Restore 'supported' field with init() callback for initialization probing
  (sashiko-bot)
- Add NULL checks before calling feature->supported() in all functions
- Fix isa_ext_enabled tracking logic and restore isa_ext_cant_disable array
- Add sbi_ext_enabled tracking and enhance dependency checking (sashiko-bot)
- Refine code organization and variable naming consistency (sashiko-bot)
- Link to v2: https://patch.msgid.link/20260526-kvm-get_reg_list-v2-v2-0-7940a401454a@sifive.com

Changes in v2:
- Fix FWFT stale feature exposure by removing static 'supported' field
- Refactor get-reg-list test to use unified extension sublist macros
- Split FWFT testing into per-feature sublists with runtime checks
  (Andrew)

To: Anup Patel <anup@brainfault.org>
To: Atish Patra <atish.patra@linux.dev>
To: Paul Walmsley <pjw@kernel.org>
To: Palmer Dabbelt <palmer@dabbelt.com>
To: Albert Ou <aou@eecs.berkeley.edu>
To: Alexandre Ghiti <alex@ghiti.fr>
To: Clément Léger <cleger@rivosinc.com>
To: Andrew Jones <ajones@ventanamicro.com>
To: Paolo Bonzini <pbonzini@redhat.com>
To: Shuah Khan <shuah@kernel.org>
Cc: greentime.hu@sifive.com
Cc: vincent.chen@sifive.com
Cc: zong.li@sifive.com
Cc: kvm@vger.kernel.org
Cc: kvm-riscv@lists.infradead.org
Cc: linux-riscv@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-kselftest@vger.kernel.org

---
Yong-Xuan Wang (5):
      KVM: RISC-V: SBI FWFT: Mark vCPU CSRs dirty after setting feature value
      KVM: RISC-V: SBI FWFT: Add optional init() callback for hardware probing
      KVM: RISC-V: SBI FWFT: Fix stale feature exposure after runtime extension changes
      KVM: riscv: selftests: Refactor ISA and SBI extension sublist macros
      KVM: riscv: selftests: Split SBI FWFT into separate feature-specific sublists

 arch/riscv/kvm/vcpu_sbi_fwft.c                   |  44 +++++++-
 tools/testing/selftests/kvm/riscv/get-reg-list.c | 138 ++++++++++++++---------
 2 files changed, 125 insertions(+), 57 deletions(-)
---
base-commit: c7832534a8160276cccb9a8cc8cafb5614c579d0
change-id: 20260526-kvm-get_reg_list-v2-f9f36961ac6c


-- 
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v5 0/5] KVM: riscv: Fix stale FWFT feature exposure and enhance selftests
@ 2026-06-01 10:26 ` Yong-Xuan Wang
  0 siblings, 0 replies; 40+ messages in thread
From: Yong-Xuan Wang @ 2026-06-01 10:26 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan
  Cc: greentime.hu, vincent.chen, zong.li, kvm, kvm-riscv, linux-riscv,
	linux-kernel, linux-kselftest, inochiama, Yong-Xuan Wang

This series fixes three bugs in the SBI FWFT (Firmware Features) extension
and improves the related selftest infrastructure.
The bugs are:
1. Missing CSR dirty marking: When userspace sets FWFT feature values via
   KVM_SET_ONE_REG, modified CSRs (e.g., henvcfg.PMM for pointer masking)
   are not marked dirty, leading to stale state after vCPU scheduling or
   migration.
2. Hardware probing side effects: The try_to_set_pmm() function modifies
   HENVCFG.PMM during hardware capability detection but fails to restore
   the original value, leaving the CSR in an altered state that affects
   subsequent operations.
3. Stale feature exposure: FWFT feature support is cached at vCPU
   initialization time. When userspace subsequently disables ISA extensions
   via KVM_SET_ONE_REG, the cached support status is not updated, allowing
   guests to access features that depend on disabled extensions.
Patches 1-3 fix these bugs separately.

The selftest improvements (patches 4-5) enhance the get-reg-list test by
refactoring the extension sublist infrastructure and splitting FWFT
feature testing into separate, properly-gated sublists.

---
Changes in v5:
- Add CSR dirty marking fix (new patch 1/5) (sashiko-bot)
- Split original FWFT bug fix into two focused patches
  - Add init() callback with try_to_set_pmm() restoration fix (new patch
    2/5) (sashiko-bot)
  - Keep runtime supported() checks as separate patch (patch 3/5)
- Link to v4: https://patch.msgid.link/20260601-kvm-get_reg_list-v2-v4-0-c88abc81ebda@sifive.com

Changes in v4:
- Rename the title of cover letter
- Disable preemption when running try_to_set_pmm() (sashiko-bot)
- Remove check_supported_reg() (sashiko-bot)
- Link to v3: https://patch.msgid.link/20260528-kvm-get_reg_list-v2-v3-0-170969a8599f@sifive.com

Changes in v3:
- Restore 'supported' field with init() callback for initialization probing
  (sashiko-bot)
- Add NULL checks before calling feature->supported() in all functions
- Fix isa_ext_enabled tracking logic and restore isa_ext_cant_disable array
- Add sbi_ext_enabled tracking and enhance dependency checking (sashiko-bot)
- Refine code organization and variable naming consistency (sashiko-bot)
- Link to v2: https://patch.msgid.link/20260526-kvm-get_reg_list-v2-v2-0-7940a401454a@sifive.com

Changes in v2:
- Fix FWFT stale feature exposure by removing static 'supported' field
- Refactor get-reg-list test to use unified extension sublist macros
- Split FWFT testing into per-feature sublists with runtime checks
  (Andrew)

To: Anup Patel <anup@brainfault.org>
To: Atish Patra <atish.patra@linux.dev>
To: Paul Walmsley <pjw@kernel.org>
To: Palmer Dabbelt <palmer@dabbelt.com>
To: Albert Ou <aou@eecs.berkeley.edu>
To: Alexandre Ghiti <alex@ghiti.fr>
To: Clément Léger <cleger@rivosinc.com>
To: Andrew Jones <ajones@ventanamicro.com>
To: Paolo Bonzini <pbonzini@redhat.com>
To: Shuah Khan <shuah@kernel.org>
Cc: greentime.hu@sifive.com
Cc: vincent.chen@sifive.com
Cc: zong.li@sifive.com
Cc: kvm@vger.kernel.org
Cc: kvm-riscv@lists.infradead.org
Cc: linux-riscv@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-kselftest@vger.kernel.org

---
Yong-Xuan Wang (5):
      KVM: RISC-V: SBI FWFT: Mark vCPU CSRs dirty after setting feature value
      KVM: RISC-V: SBI FWFT: Add optional init() callback for hardware probing
      KVM: RISC-V: SBI FWFT: Fix stale feature exposure after runtime extension changes
      KVM: riscv: selftests: Refactor ISA and SBI extension sublist macros
      KVM: riscv: selftests: Split SBI FWFT into separate feature-specific sublists

 arch/riscv/kvm/vcpu_sbi_fwft.c                   |  44 +++++++-
 tools/testing/selftests/kvm/riscv/get-reg-list.c | 138 ++++++++++++++---------
 2 files changed, 125 insertions(+), 57 deletions(-)
---
base-commit: c7832534a8160276cccb9a8cc8cafb5614c579d0
change-id: 20260526-kvm-get_reg_list-v2-f9f36961ac6c


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v5 0/5] KVM: riscv: Fix stale FWFT feature exposure and enhance selftests
@ 2026-06-01 10:26 ` Yong-Xuan Wang
  0 siblings, 0 replies; 40+ messages in thread
From: Yong-Xuan Wang @ 2026-06-01 10:26 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan
  Cc: greentime.hu, vincent.chen, zong.li, kvm, kvm-riscv, linux-riscv,
	linux-kernel, linux-kselftest, inochiama, Yong-Xuan Wang

This series fixes three bugs in the SBI FWFT (Firmware Features) extension
and improves the related selftest infrastructure.
The bugs are:
1. Missing CSR dirty marking: When userspace sets FWFT feature values via
   KVM_SET_ONE_REG, modified CSRs (e.g., henvcfg.PMM for pointer masking)
   are not marked dirty, leading to stale state after vCPU scheduling or
   migration.
2. Hardware probing side effects: The try_to_set_pmm() function modifies
   HENVCFG.PMM during hardware capability detection but fails to restore
   the original value, leaving the CSR in an altered state that affects
   subsequent operations.
3. Stale feature exposure: FWFT feature support is cached at vCPU
   initialization time. When userspace subsequently disables ISA extensions
   via KVM_SET_ONE_REG, the cached support status is not updated, allowing
   guests to access features that depend on disabled extensions.
Patches 1-3 fix these bugs separately.

The selftest improvements (patches 4-5) enhance the get-reg-list test by
refactoring the extension sublist infrastructure and splitting FWFT
feature testing into separate, properly-gated sublists.

---
Changes in v5:
- Add CSR dirty marking fix (new patch 1/5) (sashiko-bot)
- Split original FWFT bug fix into two focused patches
  - Add init() callback with try_to_set_pmm() restoration fix (new patch
    2/5) (sashiko-bot)
  - Keep runtime supported() checks as separate patch (patch 3/5)
- Link to v4: https://patch.msgid.link/20260601-kvm-get_reg_list-v2-v4-0-c88abc81ebda@sifive.com

Changes in v4:
- Rename the title of cover letter
- Disable preemption when running try_to_set_pmm() (sashiko-bot)
- Remove check_supported_reg() (sashiko-bot)
- Link to v3: https://patch.msgid.link/20260528-kvm-get_reg_list-v2-v3-0-170969a8599f@sifive.com

Changes in v3:
- Restore 'supported' field with init() callback for initialization probing
  (sashiko-bot)
- Add NULL checks before calling feature->supported() in all functions
- Fix isa_ext_enabled tracking logic and restore isa_ext_cant_disable array
- Add sbi_ext_enabled tracking and enhance dependency checking (sashiko-bot)
- Refine code organization and variable naming consistency (sashiko-bot)
- Link to v2: https://patch.msgid.link/20260526-kvm-get_reg_list-v2-v2-0-7940a401454a@sifive.com

Changes in v2:
- Fix FWFT stale feature exposure by removing static 'supported' field
- Refactor get-reg-list test to use unified extension sublist macros
- Split FWFT testing into per-feature sublists with runtime checks
  (Andrew)

To: Anup Patel <anup@brainfault.org>
To: Atish Patra <atish.patra@linux.dev>
To: Paul Walmsley <pjw@kernel.org>
To: Palmer Dabbelt <palmer@dabbelt.com>
To: Albert Ou <aou@eecs.berkeley.edu>
To: Alexandre Ghiti <alex@ghiti.fr>
To: Clément Léger <cleger@rivosinc.com>
To: Andrew Jones <ajones@ventanamicro.com>
To: Paolo Bonzini <pbonzini@redhat.com>
To: Shuah Khan <shuah@kernel.org>
Cc: greentime.hu@sifive.com
Cc: vincent.chen@sifive.com
Cc: zong.li@sifive.com
Cc: kvm@vger.kernel.org
Cc: kvm-riscv@lists.infradead.org
Cc: linux-riscv@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-kselftest@vger.kernel.org

---
Yong-Xuan Wang (5):
      KVM: RISC-V: SBI FWFT: Mark vCPU CSRs dirty after setting feature value
      KVM: RISC-V: SBI FWFT: Add optional init() callback for hardware probing
      KVM: RISC-V: SBI FWFT: Fix stale feature exposure after runtime extension changes
      KVM: riscv: selftests: Refactor ISA and SBI extension sublist macros
      KVM: riscv: selftests: Split SBI FWFT into separate feature-specific sublists

 arch/riscv/kvm/vcpu_sbi_fwft.c                   |  44 +++++++-
 tools/testing/selftests/kvm/riscv/get-reg-list.c | 138 ++++++++++++++---------
 2 files changed, 125 insertions(+), 57 deletions(-)
---
base-commit: c7832534a8160276cccb9a8cc8cafb5614c579d0
change-id: 20260526-kvm-get_reg_list-v2-f9f36961ac6c


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v5 1/5] KVM: RISC-V: SBI FWFT: Mark vCPU CSRs dirty after setting feature value
  2026-06-01 10:26 ` Yong-Xuan Wang
  (?)
@ 2026-06-01 10:26   ` Yong-Xuan Wang
  -1 siblings, 0 replies; 40+ messages in thread
From: Yong-Xuan Wang @ 2026-06-01 10:26 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan
  Cc: greentime.hu, vincent.chen, zong.li, kvm, kvm-riscv, linux-riscv,
	linux-kernel, linux-kselftest, inochiama, Yong-Xuan Wang

Mark the vCPU CSRs as dirty after successfully setting an FWFT feature
value. FWFT features may modify CSRs (e.g., pointer masking modifies
henvcfg.PMM), and failing to mark them dirty can lead to the guest
observing stale CSR state after vCPU scheduling or migration.

Fixes: 1323a5cfe52c ("KVM: riscv: Skip CSR restore if VCPU is reloaded on the same core")

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
---
 arch/riscv/kvm/vcpu_sbi_fwft.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
index 2eab15339694..5e4aafb0cbf1 100644
--- a/arch/riscv/kvm/vcpu_sbi_fwft.c
+++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
@@ -521,6 +521,7 @@ static int kvm_sbi_ext_fwft_set_reg(struct kvm_vcpu *vcpu, unsigned long reg_num
 		break;
 	case 2:
 		ret = conf->feature->set(vcpu, conf, true, value);
+		vcpu->arch.csr_dirty = true;
 		break;
 	default:
 		return -ENOENT;

-- 
2.43.7


-- 
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 1/5] KVM: RISC-V: SBI FWFT: Mark vCPU CSRs dirty after setting feature value
@ 2026-06-01 10:26   ` Yong-Xuan Wang
  0 siblings, 0 replies; 40+ messages in thread
From: Yong-Xuan Wang @ 2026-06-01 10:26 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan
  Cc: greentime.hu, vincent.chen, zong.li, kvm, kvm-riscv, linux-riscv,
	linux-kernel, linux-kselftest, inochiama, Yong-Xuan Wang

Mark the vCPU CSRs as dirty after successfully setting an FWFT feature
value. FWFT features may modify CSRs (e.g., pointer masking modifies
henvcfg.PMM), and failing to mark them dirty can lead to the guest
observing stale CSR state after vCPU scheduling or migration.

Fixes: 1323a5cfe52c ("KVM: riscv: Skip CSR restore if VCPU is reloaded on the same core")

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
---
 arch/riscv/kvm/vcpu_sbi_fwft.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
index 2eab15339694..5e4aafb0cbf1 100644
--- a/arch/riscv/kvm/vcpu_sbi_fwft.c
+++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
@@ -521,6 +521,7 @@ static int kvm_sbi_ext_fwft_set_reg(struct kvm_vcpu *vcpu, unsigned long reg_num
 		break;
 	case 2:
 		ret = conf->feature->set(vcpu, conf, true, value);
+		vcpu->arch.csr_dirty = true;
 		break;
 	default:
 		return -ENOENT;

-- 
2.43.7


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 1/5] KVM: RISC-V: SBI FWFT: Mark vCPU CSRs dirty after setting feature value
@ 2026-06-01 10:26   ` Yong-Xuan Wang
  0 siblings, 0 replies; 40+ messages in thread
From: Yong-Xuan Wang @ 2026-06-01 10:26 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan
  Cc: greentime.hu, vincent.chen, zong.li, kvm, kvm-riscv, linux-riscv,
	linux-kernel, linux-kselftest, inochiama, Yong-Xuan Wang

Mark the vCPU CSRs as dirty after successfully setting an FWFT feature
value. FWFT features may modify CSRs (e.g., pointer masking modifies
henvcfg.PMM), and failing to mark them dirty can lead to the guest
observing stale CSR state after vCPU scheduling or migration.

Fixes: 1323a5cfe52c ("KVM: riscv: Skip CSR restore if VCPU is reloaded on the same core")

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
---
 arch/riscv/kvm/vcpu_sbi_fwft.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
index 2eab15339694..5e4aafb0cbf1 100644
--- a/arch/riscv/kvm/vcpu_sbi_fwft.c
+++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
@@ -521,6 +521,7 @@ static int kvm_sbi_ext_fwft_set_reg(struct kvm_vcpu *vcpu, unsigned long reg_num
 		break;
 	case 2:
 		ret = conf->feature->set(vcpu, conf, true, value);
+		vcpu->arch.csr_dirty = true;
 		break;
 	default:
 		return -ENOENT;

-- 
2.43.7


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 2/5] KVM: RISC-V: SBI FWFT: Add optional init() callback for hardware probing
  2026-06-01 10:26 ` Yong-Xuan Wang
  (?)
@ 2026-06-01 10:26   ` Yong-Xuan Wang
  -1 siblings, 0 replies; 40+ messages in thread
From: Yong-Xuan Wang @ 2026-06-01 10:26 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan
  Cc: greentime.hu, vincent.chen, zong.li, kvm, kvm-riscv, linux-riscv,
	linux-kernel, linux-kselftest, inochiama, Yong-Xuan Wang

Add an optional init() callback to separate one-time hardware probing
from runtime availability checks. For pointer masking, this allows
probing supported PMM lengths during initialization while checking ISA
extension availability at runtime.

Fix try_to_set_pmm() to restore the previous HENVCFG.PMM value after
probing, preventing side effects from hardware detection. Add preemption
protection to ensure CSR probe sequences complete atomically on the same
CPU.

Fixes: 6f576fc0aeb9 ("RISC-V: KVM: Add support for SBI_FWFT_POINTER_MASKING_PMLEN")

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
---
 arch/riscv/kvm/vcpu_sbi_fwft.c | 33 +++++++++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 4 deletions(-)

diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
index 5e4aafb0cbf1..aee951f2b8e6 100644
--- a/arch/riscv/kvm/vcpu_sbi_fwft.c
+++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
@@ -35,6 +35,16 @@ struct kvm_sbi_fwft_feature {
 	 */
 	bool (*supported)(struct kvm_vcpu *vcpu);
 
+	/**
+	 * @init: Probe and initialize the feature on the vcpu
+	 *
+	 * This callback is optional. If provided, it will be called during
+	 * vcpu initialization to probe the feature availability and perform
+	 * any necessary initialization. Returns true if the feature is supported
+	 * and initialized successfully, false otherwise.
+	 */
+	bool (*init)(struct kvm_vcpu *vcpu);
+
 	/**
 	 * @reset: Reset the feature value irrespective whether feature is supported or not
 	 *
@@ -131,19 +141,30 @@ static long kvm_sbi_fwft_get_misaligned_delegation(struct kvm_vcpu *vcpu,
 
 static bool try_to_set_pmm(unsigned long value)
 {
+	unsigned long prev;
+	bool ret;
+
+	prev = csr_read_clear(CSR_HENVCFG, ENVCFG_PMM);
 	csr_set(CSR_HENVCFG, value);
-	return (csr_read_clear(CSR_HENVCFG, ENVCFG_PMM) & ENVCFG_PMM) == value;
+	ret = (csr_read_clear(CSR_HENVCFG, ENVCFG_PMM) & ENVCFG_PMM) == value;
+	csr_write(CSR_HENVCFG, prev);
+
+	return ret;
 }
 
 static bool kvm_sbi_fwft_pointer_masking_pmlen_supported(struct kvm_vcpu *vcpu)
 {
-	struct kvm_sbi_fwft *fwft = vcpu_to_fwft(vcpu);
+	return riscv_isa_extension_available(vcpu->arch.isa, SMNPM);
+}
 
-	if (!riscv_isa_extension_available(vcpu->arch.isa, SMNPM))
-		return false;
+static bool kvm_sbi_fwft_pointer_masking_pmlen_init(struct kvm_vcpu *vcpu)
+{
+	struct kvm_sbi_fwft *fwft = vcpu_to_fwft(vcpu);
 
+	preempt_disable();
 	fwft->have_vs_pmlen_7 = try_to_set_pmm(ENVCFG_PMM_PMLEN_7);
 	fwft->have_vs_pmlen_16 = try_to_set_pmm(ENVCFG_PMM_PMLEN_16);
+	preempt_enable();
 
 	return fwft->have_vs_pmlen_7 || fwft->have_vs_pmlen_16;
 }
@@ -231,6 +252,7 @@ static const struct kvm_sbi_fwft_feature features[] = {
 		.first_reg_num = offsetof(struct kvm_riscv_sbi_fwft, pointer_masking.enable) /
 				 sizeof(unsigned long),
 		.supported = kvm_sbi_fwft_pointer_masking_pmlen_supported,
+		.init = kvm_sbi_fwft_pointer_masking_pmlen_init,
 		.reset = kvm_sbi_fwft_reset_pointer_masking_pmlen,
 		.set = kvm_sbi_fwft_set_pointer_masking_pmlen,
 		.get = kvm_sbi_fwft_get_pointer_masking_pmlen,
@@ -365,6 +387,9 @@ static int kvm_sbi_ext_fwft_init(struct kvm_vcpu *vcpu)
 		else
 			conf->supported = true;
 
+		if (conf->supported && feature->init)
+			conf->supported = feature->init(vcpu);
+
 		conf->enabled = conf->supported;
 		conf->feature = feature;
 	}

-- 
2.43.7


-- 
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 2/5] KVM: RISC-V: SBI FWFT: Add optional init() callback for hardware probing
@ 2026-06-01 10:26   ` Yong-Xuan Wang
  0 siblings, 0 replies; 40+ messages in thread
From: Yong-Xuan Wang @ 2026-06-01 10:26 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan
  Cc: greentime.hu, vincent.chen, zong.li, kvm, kvm-riscv, linux-riscv,
	linux-kernel, linux-kselftest, inochiama, Yong-Xuan Wang

Add an optional init() callback to separate one-time hardware probing
from runtime availability checks. For pointer masking, this allows
probing supported PMM lengths during initialization while checking ISA
extension availability at runtime.

Fix try_to_set_pmm() to restore the previous HENVCFG.PMM value after
probing, preventing side effects from hardware detection. Add preemption
protection to ensure CSR probe sequences complete atomically on the same
CPU.

Fixes: 6f576fc0aeb9 ("RISC-V: KVM: Add support for SBI_FWFT_POINTER_MASKING_PMLEN")

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
---
 arch/riscv/kvm/vcpu_sbi_fwft.c | 33 +++++++++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 4 deletions(-)

diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
index 5e4aafb0cbf1..aee951f2b8e6 100644
--- a/arch/riscv/kvm/vcpu_sbi_fwft.c
+++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
@@ -35,6 +35,16 @@ struct kvm_sbi_fwft_feature {
 	 */
 	bool (*supported)(struct kvm_vcpu *vcpu);
 
+	/**
+	 * @init: Probe and initialize the feature on the vcpu
+	 *
+	 * This callback is optional. If provided, it will be called during
+	 * vcpu initialization to probe the feature availability and perform
+	 * any necessary initialization. Returns true if the feature is supported
+	 * and initialized successfully, false otherwise.
+	 */
+	bool (*init)(struct kvm_vcpu *vcpu);
+
 	/**
 	 * @reset: Reset the feature value irrespective whether feature is supported or not
 	 *
@@ -131,19 +141,30 @@ static long kvm_sbi_fwft_get_misaligned_delegation(struct kvm_vcpu *vcpu,
 
 static bool try_to_set_pmm(unsigned long value)
 {
+	unsigned long prev;
+	bool ret;
+
+	prev = csr_read_clear(CSR_HENVCFG, ENVCFG_PMM);
 	csr_set(CSR_HENVCFG, value);
-	return (csr_read_clear(CSR_HENVCFG, ENVCFG_PMM) & ENVCFG_PMM) == value;
+	ret = (csr_read_clear(CSR_HENVCFG, ENVCFG_PMM) & ENVCFG_PMM) == value;
+	csr_write(CSR_HENVCFG, prev);
+
+	return ret;
 }
 
 static bool kvm_sbi_fwft_pointer_masking_pmlen_supported(struct kvm_vcpu *vcpu)
 {
-	struct kvm_sbi_fwft *fwft = vcpu_to_fwft(vcpu);
+	return riscv_isa_extension_available(vcpu->arch.isa, SMNPM);
+}
 
-	if (!riscv_isa_extension_available(vcpu->arch.isa, SMNPM))
-		return false;
+static bool kvm_sbi_fwft_pointer_masking_pmlen_init(struct kvm_vcpu *vcpu)
+{
+	struct kvm_sbi_fwft *fwft = vcpu_to_fwft(vcpu);
 
+	preempt_disable();
 	fwft->have_vs_pmlen_7 = try_to_set_pmm(ENVCFG_PMM_PMLEN_7);
 	fwft->have_vs_pmlen_16 = try_to_set_pmm(ENVCFG_PMM_PMLEN_16);
+	preempt_enable();
 
 	return fwft->have_vs_pmlen_7 || fwft->have_vs_pmlen_16;
 }
@@ -231,6 +252,7 @@ static const struct kvm_sbi_fwft_feature features[] = {
 		.first_reg_num = offsetof(struct kvm_riscv_sbi_fwft, pointer_masking.enable) /
 				 sizeof(unsigned long),
 		.supported = kvm_sbi_fwft_pointer_masking_pmlen_supported,
+		.init = kvm_sbi_fwft_pointer_masking_pmlen_init,
 		.reset = kvm_sbi_fwft_reset_pointer_masking_pmlen,
 		.set = kvm_sbi_fwft_set_pointer_masking_pmlen,
 		.get = kvm_sbi_fwft_get_pointer_masking_pmlen,
@@ -365,6 +387,9 @@ static int kvm_sbi_ext_fwft_init(struct kvm_vcpu *vcpu)
 		else
 			conf->supported = true;
 
+		if (conf->supported && feature->init)
+			conf->supported = feature->init(vcpu);
+
 		conf->enabled = conf->supported;
 		conf->feature = feature;
 	}

-- 
2.43.7


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 2/5] KVM: RISC-V: SBI FWFT: Add optional init() callback for hardware probing
@ 2026-06-01 10:26   ` Yong-Xuan Wang
  0 siblings, 0 replies; 40+ messages in thread
From: Yong-Xuan Wang @ 2026-06-01 10:26 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan
  Cc: greentime.hu, vincent.chen, zong.li, kvm, kvm-riscv, linux-riscv,
	linux-kernel, linux-kselftest, inochiama, Yong-Xuan Wang

Add an optional init() callback to separate one-time hardware probing
from runtime availability checks. For pointer masking, this allows
probing supported PMM lengths during initialization while checking ISA
extension availability at runtime.

Fix try_to_set_pmm() to restore the previous HENVCFG.PMM value after
probing, preventing side effects from hardware detection. Add preemption
protection to ensure CSR probe sequences complete atomically on the same
CPU.

Fixes: 6f576fc0aeb9 ("RISC-V: KVM: Add support for SBI_FWFT_POINTER_MASKING_PMLEN")

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
---
 arch/riscv/kvm/vcpu_sbi_fwft.c | 33 +++++++++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 4 deletions(-)

diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
index 5e4aafb0cbf1..aee951f2b8e6 100644
--- a/arch/riscv/kvm/vcpu_sbi_fwft.c
+++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
@@ -35,6 +35,16 @@ struct kvm_sbi_fwft_feature {
 	 */
 	bool (*supported)(struct kvm_vcpu *vcpu);
 
+	/**
+	 * @init: Probe and initialize the feature on the vcpu
+	 *
+	 * This callback is optional. If provided, it will be called during
+	 * vcpu initialization to probe the feature availability and perform
+	 * any necessary initialization. Returns true if the feature is supported
+	 * and initialized successfully, false otherwise.
+	 */
+	bool (*init)(struct kvm_vcpu *vcpu);
+
 	/**
 	 * @reset: Reset the feature value irrespective whether feature is supported or not
 	 *
@@ -131,19 +141,30 @@ static long kvm_sbi_fwft_get_misaligned_delegation(struct kvm_vcpu *vcpu,
 
 static bool try_to_set_pmm(unsigned long value)
 {
+	unsigned long prev;
+	bool ret;
+
+	prev = csr_read_clear(CSR_HENVCFG, ENVCFG_PMM);
 	csr_set(CSR_HENVCFG, value);
-	return (csr_read_clear(CSR_HENVCFG, ENVCFG_PMM) & ENVCFG_PMM) == value;
+	ret = (csr_read_clear(CSR_HENVCFG, ENVCFG_PMM) & ENVCFG_PMM) == value;
+	csr_write(CSR_HENVCFG, prev);
+
+	return ret;
 }
 
 static bool kvm_sbi_fwft_pointer_masking_pmlen_supported(struct kvm_vcpu *vcpu)
 {
-	struct kvm_sbi_fwft *fwft = vcpu_to_fwft(vcpu);
+	return riscv_isa_extension_available(vcpu->arch.isa, SMNPM);
+}
 
-	if (!riscv_isa_extension_available(vcpu->arch.isa, SMNPM))
-		return false;
+static bool kvm_sbi_fwft_pointer_masking_pmlen_init(struct kvm_vcpu *vcpu)
+{
+	struct kvm_sbi_fwft *fwft = vcpu_to_fwft(vcpu);
 
+	preempt_disable();
 	fwft->have_vs_pmlen_7 = try_to_set_pmm(ENVCFG_PMM_PMLEN_7);
 	fwft->have_vs_pmlen_16 = try_to_set_pmm(ENVCFG_PMM_PMLEN_16);
+	preempt_enable();
 
 	return fwft->have_vs_pmlen_7 || fwft->have_vs_pmlen_16;
 }
@@ -231,6 +252,7 @@ static const struct kvm_sbi_fwft_feature features[] = {
 		.first_reg_num = offsetof(struct kvm_riscv_sbi_fwft, pointer_masking.enable) /
 				 sizeof(unsigned long),
 		.supported = kvm_sbi_fwft_pointer_masking_pmlen_supported,
+		.init = kvm_sbi_fwft_pointer_masking_pmlen_init,
 		.reset = kvm_sbi_fwft_reset_pointer_masking_pmlen,
 		.set = kvm_sbi_fwft_set_pointer_masking_pmlen,
 		.get = kvm_sbi_fwft_get_pointer_masking_pmlen,
@@ -365,6 +387,9 @@ static int kvm_sbi_ext_fwft_init(struct kvm_vcpu *vcpu)
 		else
 			conf->supported = true;
 
+		if (conf->supported && feature->init)
+			conf->supported = feature->init(vcpu);
+
 		conf->enabled = conf->supported;
 		conf->feature = feature;
 	}

-- 
2.43.7


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 3/5] KVM: RISC-V: SBI FWFT: Fix stale feature exposure after runtime extension changes
  2026-06-01 10:26 ` Yong-Xuan Wang
  (?)
@ 2026-06-01 10:26   ` Yong-Xuan Wang
  -1 siblings, 0 replies; 40+ messages in thread
From: Yong-Xuan Wang @ 2026-06-01 10:26 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan
  Cc: greentime.hu, vincent.chen, zong.li, kvm, kvm-riscv, linux-riscv,
	linux-kernel, linux-kselftest, inochiama, Yong-Xuan Wang

Fix a bug where FWFT features could be incorrectly exposed to guests
after userspace disables their dependent ISA extensions at runtime.

The 'supported' field in kvm_sbi_fwft_config was set once during vCPU
initialization based on the initial hardware/extension availability.
However, when userspace subsequently disables ISA extensions via the KVM
ONE_REG interface, the 'supported' field was not updated. This caused
the following issues:
1. FWFT features would remain visible and accessible to guests even
   after their prerequisite ISA extensions were disabled
2. Guests could configure FWFT features that depend on disabled
   extensions, leading to undefined behavior
3. The static 'supported' flag and the dynamic supported() callback
   could disagree about feature availability

The fix introduces a two-layer checking mechanism:
1. Add an optional init() callback to the kvm_sbi_fwft_feature structure
   for features that require hardware probing during initialization. This
   separates the one-time hardware detection logic from the runtime
   availability check.
2. Add runtime checks in all FWFT-related functions that call
   feature->supported(vcpu) if the callback exists. This ensures feature
   availability is re-evaluated based on the current ISA extension state.

This approach maintains the cached 'supported' field for initialization-
time decisions while ensuring runtime availability is always determined
by the current vCPU configuration, not initialization-time snapshots.

Fixes: 6b72fd170592 ("RISC-V: KVM: add support for FWFT SBI extension")

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
---
 arch/riscv/kvm/vcpu_sbi_fwft.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
index aee951f2b8e6..ab39ac464ffd 100644
--- a/arch/riscv/kvm/vcpu_sbi_fwft.c
+++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
@@ -303,6 +303,8 @@ static int kvm_fwft_get_feature(struct kvm_vcpu *vcpu, u32 feature,
 
 	if (!tconf->supported || !tconf->enabled)
 		return SBI_ERR_NOT_SUPPORTED;
+	else if (tconf->feature->supported && !tconf->feature->supported(vcpu))
+		return SBI_ERR_NOT_SUPPORTED;
 
 	*conf = tconf;
 
@@ -433,6 +435,8 @@ static unsigned long kvm_sbi_ext_fwft_get_reg_count(struct kvm_vcpu *vcpu)
 		conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
 		if (!conf || !conf->supported)
 			continue;
+		else if (conf->feature->supported && !conf->feature->supported(vcpu))
+			continue;
 
 		ret++;
 	}
@@ -455,6 +459,8 @@ static int kvm_sbi_ext_fwft_get_reg_id(struct kvm_vcpu *vcpu, int index, u64 *re
 		conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
 		if (!conf || !conf->supported)
 			continue;
+		else if (conf->feature->supported && !conf->feature->supported(vcpu))
+			continue;
 
 		if (index == idx) {
 			*reg_id = KVM_REG_RISCV |
@@ -490,6 +496,8 @@ static int kvm_sbi_ext_fwft_get_reg(struct kvm_vcpu *vcpu, unsigned long reg_num
 	conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
 	if (!conf || !conf->supported)
 		return -ENOENT;
+	else if (conf->feature->supported && !conf->feature->supported(vcpu))
+		return -ENOENT;
 
 	switch (reg_num - feature->first_reg_num) {
 	case 0:
@@ -527,6 +535,8 @@ static int kvm_sbi_ext_fwft_set_reg(struct kvm_vcpu *vcpu, unsigned long reg_num
 	conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
 	if (!conf || !conf->supported)
 		return -ENOENT;
+	else if (conf->feature->supported && !conf->feature->supported(vcpu))
+		return -ENOENT;
 
 	switch (reg_num - feature->first_reg_num) {
 	case 0:

-- 
2.43.7


-- 
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 3/5] KVM: RISC-V: SBI FWFT: Fix stale feature exposure after runtime extension changes
@ 2026-06-01 10:26   ` Yong-Xuan Wang
  0 siblings, 0 replies; 40+ messages in thread
From: Yong-Xuan Wang @ 2026-06-01 10:26 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan
  Cc: greentime.hu, vincent.chen, zong.li, kvm, kvm-riscv, linux-riscv,
	linux-kernel, linux-kselftest, inochiama, Yong-Xuan Wang

Fix a bug where FWFT features could be incorrectly exposed to guests
after userspace disables their dependent ISA extensions at runtime.

The 'supported' field in kvm_sbi_fwft_config was set once during vCPU
initialization based on the initial hardware/extension availability.
However, when userspace subsequently disables ISA extensions via the KVM
ONE_REG interface, the 'supported' field was not updated. This caused
the following issues:
1. FWFT features would remain visible and accessible to guests even
   after their prerequisite ISA extensions were disabled
2. Guests could configure FWFT features that depend on disabled
   extensions, leading to undefined behavior
3. The static 'supported' flag and the dynamic supported() callback
   could disagree about feature availability

The fix introduces a two-layer checking mechanism:
1. Add an optional init() callback to the kvm_sbi_fwft_feature structure
   for features that require hardware probing during initialization. This
   separates the one-time hardware detection logic from the runtime
   availability check.
2. Add runtime checks in all FWFT-related functions that call
   feature->supported(vcpu) if the callback exists. This ensures feature
   availability is re-evaluated based on the current ISA extension state.

This approach maintains the cached 'supported' field for initialization-
time decisions while ensuring runtime availability is always determined
by the current vCPU configuration, not initialization-time snapshots.

Fixes: 6b72fd170592 ("RISC-V: KVM: add support for FWFT SBI extension")

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
---
 arch/riscv/kvm/vcpu_sbi_fwft.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
index aee951f2b8e6..ab39ac464ffd 100644
--- a/arch/riscv/kvm/vcpu_sbi_fwft.c
+++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
@@ -303,6 +303,8 @@ static int kvm_fwft_get_feature(struct kvm_vcpu *vcpu, u32 feature,
 
 	if (!tconf->supported || !tconf->enabled)
 		return SBI_ERR_NOT_SUPPORTED;
+	else if (tconf->feature->supported && !tconf->feature->supported(vcpu))
+		return SBI_ERR_NOT_SUPPORTED;
 
 	*conf = tconf;
 
@@ -433,6 +435,8 @@ static unsigned long kvm_sbi_ext_fwft_get_reg_count(struct kvm_vcpu *vcpu)
 		conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
 		if (!conf || !conf->supported)
 			continue;
+		else if (conf->feature->supported && !conf->feature->supported(vcpu))
+			continue;
 
 		ret++;
 	}
@@ -455,6 +459,8 @@ static int kvm_sbi_ext_fwft_get_reg_id(struct kvm_vcpu *vcpu, int index, u64 *re
 		conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
 		if (!conf || !conf->supported)
 			continue;
+		else if (conf->feature->supported && !conf->feature->supported(vcpu))
+			continue;
 
 		if (index == idx) {
 			*reg_id = KVM_REG_RISCV |
@@ -490,6 +496,8 @@ static int kvm_sbi_ext_fwft_get_reg(struct kvm_vcpu *vcpu, unsigned long reg_num
 	conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
 	if (!conf || !conf->supported)
 		return -ENOENT;
+	else if (conf->feature->supported && !conf->feature->supported(vcpu))
+		return -ENOENT;
 
 	switch (reg_num - feature->first_reg_num) {
 	case 0:
@@ -527,6 +535,8 @@ static int kvm_sbi_ext_fwft_set_reg(struct kvm_vcpu *vcpu, unsigned long reg_num
 	conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
 	if (!conf || !conf->supported)
 		return -ENOENT;
+	else if (conf->feature->supported && !conf->feature->supported(vcpu))
+		return -ENOENT;
 
 	switch (reg_num - feature->first_reg_num) {
 	case 0:

-- 
2.43.7


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 3/5] KVM: RISC-V: SBI FWFT: Fix stale feature exposure after runtime extension changes
@ 2026-06-01 10:26   ` Yong-Xuan Wang
  0 siblings, 0 replies; 40+ messages in thread
From: Yong-Xuan Wang @ 2026-06-01 10:26 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan
  Cc: greentime.hu, vincent.chen, zong.li, kvm, kvm-riscv, linux-riscv,
	linux-kernel, linux-kselftest, inochiama, Yong-Xuan Wang

Fix a bug where FWFT features could be incorrectly exposed to guests
after userspace disables their dependent ISA extensions at runtime.

The 'supported' field in kvm_sbi_fwft_config was set once during vCPU
initialization based on the initial hardware/extension availability.
However, when userspace subsequently disables ISA extensions via the KVM
ONE_REG interface, the 'supported' field was not updated. This caused
the following issues:
1. FWFT features would remain visible and accessible to guests even
   after their prerequisite ISA extensions were disabled
2. Guests could configure FWFT features that depend on disabled
   extensions, leading to undefined behavior
3. The static 'supported' flag and the dynamic supported() callback
   could disagree about feature availability

The fix introduces a two-layer checking mechanism:
1. Add an optional init() callback to the kvm_sbi_fwft_feature structure
   for features that require hardware probing during initialization. This
   separates the one-time hardware detection logic from the runtime
   availability check.
2. Add runtime checks in all FWFT-related functions that call
   feature->supported(vcpu) if the callback exists. This ensures feature
   availability is re-evaluated based on the current ISA extension state.

This approach maintains the cached 'supported' field for initialization-
time decisions while ensuring runtime availability is always determined
by the current vCPU configuration, not initialization-time snapshots.

Fixes: 6b72fd170592 ("RISC-V: KVM: add support for FWFT SBI extension")

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
---
 arch/riscv/kvm/vcpu_sbi_fwft.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
index aee951f2b8e6..ab39ac464ffd 100644
--- a/arch/riscv/kvm/vcpu_sbi_fwft.c
+++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
@@ -303,6 +303,8 @@ static int kvm_fwft_get_feature(struct kvm_vcpu *vcpu, u32 feature,
 
 	if (!tconf->supported || !tconf->enabled)
 		return SBI_ERR_NOT_SUPPORTED;
+	else if (tconf->feature->supported && !tconf->feature->supported(vcpu))
+		return SBI_ERR_NOT_SUPPORTED;
 
 	*conf = tconf;
 
@@ -433,6 +435,8 @@ static unsigned long kvm_sbi_ext_fwft_get_reg_count(struct kvm_vcpu *vcpu)
 		conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
 		if (!conf || !conf->supported)
 			continue;
+		else if (conf->feature->supported && !conf->feature->supported(vcpu))
+			continue;
 
 		ret++;
 	}
@@ -455,6 +459,8 @@ static int kvm_sbi_ext_fwft_get_reg_id(struct kvm_vcpu *vcpu, int index, u64 *re
 		conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
 		if (!conf || !conf->supported)
 			continue;
+		else if (conf->feature->supported && !conf->feature->supported(vcpu))
+			continue;
 
 		if (index == idx) {
 			*reg_id = KVM_REG_RISCV |
@@ -490,6 +496,8 @@ static int kvm_sbi_ext_fwft_get_reg(struct kvm_vcpu *vcpu, unsigned long reg_num
 	conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
 	if (!conf || !conf->supported)
 		return -ENOENT;
+	else if (conf->feature->supported && !conf->feature->supported(vcpu))
+		return -ENOENT;
 
 	switch (reg_num - feature->first_reg_num) {
 	case 0:
@@ -527,6 +535,8 @@ static int kvm_sbi_ext_fwft_set_reg(struct kvm_vcpu *vcpu, unsigned long reg_num
 	conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
 	if (!conf || !conf->supported)
 		return -ENOENT;
+	else if (conf->feature->supported && !conf->feature->supported(vcpu))
+		return -ENOENT;
 
 	switch (reg_num - feature->first_reg_num) {
 	case 0:

-- 
2.43.7


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 4/5] KVM: riscv: selftests: Refactor ISA and SBI extension sublist macros
  2026-06-01 10:26 ` Yong-Xuan Wang
  (?)
@ 2026-06-01 10:26   ` Yong-Xuan Wang
  -1 siblings, 0 replies; 40+ messages in thread
From: Yong-Xuan Wang @ 2026-06-01 10:26 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan
  Cc: greentime.hu, vincent.chen, zong.li, kvm, kvm-riscv, linux-riscv,
	linux-kernel, linux-kselftest, inochiama, Yong-Xuan Wang

Refactor the get-reg-list test to use unified sublist macros for ISA
and SBI extensions, eliminating code duplication and improving
maintainability.

Previously, each extension had its own hand-coded sublist definition
(e.g., SUBLIST_ZICBOM, SUBLIST_AIA, etc.) and the config structures
repeated the same pattern. This made the code verbose and error-prone.

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
---
 tools/testing/selftests/kvm/riscv/get-reg-list.c | 78 +++++++++---------------
 1 file changed, 28 insertions(+), 50 deletions(-)

diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
index 8d6fdb5d38b8..5033c09201ef 100644
--- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
+++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
@@ -1013,7 +1013,7 @@ static __u64 fp_d_regs[] = {
 };
 
 /* Define a default vector registers with length. This will be overwritten at runtime */
-static __u64 vector_regs[] = {
+static __u64 v_regs[] = {
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vstart),
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vl),
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vtype),
@@ -1057,37 +1057,17 @@ static __u64 vector_regs[] = {
 #define SUBLIST_BASE \
 	{"base", .regs = base_regs, .regs_n = ARRAY_SIZE(base_regs), \
 	 .skips_set = base_skips_set, .skips_set_n = ARRAY_SIZE(base_skips_set),}
-#define SUBLIST_SBI_BASE \
-	{"sbi-base", .feature_type = VCPU_FEATURE_SBI_EXT, .feature = KVM_RISCV_SBI_EXT_V01, \
-	 .regs = sbi_base_regs, .regs_n = ARRAY_SIZE(sbi_base_regs),}
-#define SUBLIST_SBI_STA \
-	{"sbi-sta", .feature_type = VCPU_FEATURE_SBI_EXT, .feature = KVM_RISCV_SBI_EXT_STA, \
-	 .regs = sbi_sta_regs, .regs_n = ARRAY_SIZE(sbi_sta_regs),}
-#define SUBLIST_SBI_FWFT \
-	{"sbi-fwft", .feature_type = VCPU_FEATURE_SBI_EXT, .feature = KVM_RISCV_SBI_EXT_FWFT, \
-	 .regs = sbi_fwft_regs, .regs_n = ARRAY_SIZE(sbi_fwft_regs),}
-#define SUBLIST_ZICBOM \
-	{"zicbom", .feature = KVM_RISCV_ISA_EXT_ZICBOM, .regs = zicbom_regs, .regs_n = ARRAY_SIZE(zicbom_regs),}
-#define SUBLIST_ZICBOP \
-	{"zicbop", .feature = KVM_RISCV_ISA_EXT_ZICBOP, .regs = zicbop_regs, .regs_n = ARRAY_SIZE(zicbop_regs),}
-#define SUBLIST_ZICBOZ \
-	{"zicboz", .feature = KVM_RISCV_ISA_EXT_ZICBOZ, .regs = zicboz_regs, .regs_n = ARRAY_SIZE(zicboz_regs),}
-#define SUBLIST_AIA \
-	{"aia", .feature = KVM_RISCV_ISA_EXT_SSAIA, .regs = aia_regs, .regs_n = ARRAY_SIZE(aia_regs),}
-#define SUBLIST_SMSTATEEN \
-	{"smstateen", .feature = KVM_RISCV_ISA_EXT_SMSTATEEN, .regs = smstateen_regs, .regs_n = ARRAY_SIZE(smstateen_regs),}
-#define SUBLIST_FP_F \
-	{"fp_f", .feature = KVM_RISCV_ISA_EXT_F, .regs = fp_f_regs, \
-		.regs_n = ARRAY_SIZE(fp_f_regs),}
-#define SUBLIST_FP_D \
-	{"fp_d", .feature = KVM_RISCV_ISA_EXT_D, .regs = fp_d_regs, \
-		.regs_n = ARRAY_SIZE(fp_d_regs),}
-
-#define SUBLIST_V \
-	{"v", .feature = KVM_RISCV_ISA_EXT_V, .regs = vector_regs, .regs_n = ARRAY_SIZE(vector_regs),}
+
+#define SUBLIST_ISA(ext, extu)				\
+	{						\
+		.name = #ext,				\
+		.feature = KVM_RISCV_ISA_EXT_##extu,	\
+		.regs = ext##_regs,			\
+		.regs_n = ARRAY_SIZE(ext##_regs),	\
+	}
 
 #define KVM_ISA_EXT_SIMPLE_CONFIG(ext, extu)			\
-static __u64 regs_##ext[] = {					\
+static __u64 ext##_regs[] = {					\
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG |			\
 	KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE |	\
 	KVM_RISCV_ISA_EXT_##extu,				\
@@ -1095,18 +1075,22 @@ static __u64 regs_##ext[] = {					\
 static struct vcpu_reg_list config_##ext = {			\
 	.sublists = {						\
 		SUBLIST_BASE,					\
-		{						\
-			.name = #ext,				\
-			.feature = KVM_RISCV_ISA_EXT_##extu,	\
-			.regs = regs_##ext,			\
-			.regs_n = ARRAY_SIZE(regs_##ext),	\
-		},						\
+		SUBLIST_ISA(ext, extu),				\
 		{0},						\
 	},							\
 }								\
 
+#define SUBLIST_SBI(ext, extu)					\
+	{							\
+		.name = "sbi-"#ext,				\
+		.feature_type = VCPU_FEATURE_SBI_EXT,		\
+		.feature = KVM_RISCV_SBI_EXT_##extu,		\
+		.regs = sbi_##ext##_regs,			\
+		.regs_n = ARRAY_SIZE(sbi_##ext##_regs),		\
+	}
+
 #define KVM_SBI_EXT_SIMPLE_CONFIG(ext, extu)			\
-static __u64 regs_sbi_##ext[] = {				\
+static __u64 sbi_##ext##_regs[] = {				\
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG |			\
 	KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE |	\
 	KVM_RISCV_SBI_EXT_##extu,				\
@@ -1114,13 +1098,7 @@ static __u64 regs_sbi_##ext[] = {				\
 static struct vcpu_reg_list config_sbi_##ext = {		\
 	.sublists = {						\
 		SUBLIST_BASE,					\
-		{						\
-			.name = "sbi-"#ext,			\
-			.feature_type = VCPU_FEATURE_SBI_EXT,	\
-			.feature = KVM_RISCV_SBI_EXT_##extu,	\
-			.regs = regs_sbi_##ext,			\
-			.regs_n = ARRAY_SIZE(regs_sbi_##ext),	\
-		},						\
+		SUBLIST_SBI(ext, extu),				\
 		{0},						\
 	},							\
 }								\
@@ -1129,7 +1107,7 @@ static struct vcpu_reg_list config_sbi_##ext = {		\
 static struct vcpu_reg_list config_##ext = {			\
 	.sublists = {						\
 		SUBLIST_BASE,					\
-		SUBLIST_##extu,					\
+		SUBLIST_ISA(ext, extu),				\
 		{0},						\
 	},							\
 }								\
@@ -1138,14 +1116,14 @@ static struct vcpu_reg_list config_##ext = {			\
 static struct vcpu_reg_list config_sbi_##ext = {		\
 	.sublists = {						\
 		SUBLIST_BASE,					\
-		SUBLIST_SBI_##extu,				\
+		SUBLIST_SBI(ext, extu),				\
 		{0},						\
 	},							\
 }								\
 
 /* Note: The below list is alphabetically sorted. */
 
-KVM_SBI_EXT_SUBLIST_CONFIG(base, BASE);
+KVM_SBI_EXT_SUBLIST_CONFIG(base, V01);
 KVM_SBI_EXT_SUBLIST_CONFIG(sta, STA);
 KVM_SBI_EXT_SIMPLE_CONFIG(pmu, PMU);
 KVM_SBI_EXT_SIMPLE_CONFIG(dbcn, DBCN);
@@ -1153,9 +1131,9 @@ KVM_SBI_EXT_SIMPLE_CONFIG(susp, SUSP);
 KVM_SBI_EXT_SIMPLE_CONFIG(mpxy, MPXY);
 KVM_SBI_EXT_SUBLIST_CONFIG(fwft, FWFT);
 
-KVM_ISA_EXT_SUBLIST_CONFIG(aia, AIA);
-KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, FP_F);
-KVM_ISA_EXT_SUBLIST_CONFIG(fp_d, FP_D);
+KVM_ISA_EXT_SUBLIST_CONFIG(aia, SSAIA);
+KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, F);
+KVM_ISA_EXT_SUBLIST_CONFIG(fp_d, D);
 KVM_ISA_EXT_SUBLIST_CONFIG(v, V);
 KVM_ISA_EXT_SIMPLE_CONFIG(h, H);
 KVM_ISA_EXT_SIMPLE_CONFIG(smnpm, SMNPM);

-- 
2.43.7


-- 
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 4/5] KVM: riscv: selftests: Refactor ISA and SBI extension sublist macros
@ 2026-06-01 10:26   ` Yong-Xuan Wang
  0 siblings, 0 replies; 40+ messages in thread
From: Yong-Xuan Wang @ 2026-06-01 10:26 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan
  Cc: greentime.hu, vincent.chen, zong.li, kvm, kvm-riscv, linux-riscv,
	linux-kernel, linux-kselftest, inochiama, Yong-Xuan Wang

Refactor the get-reg-list test to use unified sublist macros for ISA
and SBI extensions, eliminating code duplication and improving
maintainability.

Previously, each extension had its own hand-coded sublist definition
(e.g., SUBLIST_ZICBOM, SUBLIST_AIA, etc.) and the config structures
repeated the same pattern. This made the code verbose and error-prone.

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
---
 tools/testing/selftests/kvm/riscv/get-reg-list.c | 78 +++++++++---------------
 1 file changed, 28 insertions(+), 50 deletions(-)

diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
index 8d6fdb5d38b8..5033c09201ef 100644
--- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
+++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
@@ -1013,7 +1013,7 @@ static __u64 fp_d_regs[] = {
 };
 
 /* Define a default vector registers with length. This will be overwritten at runtime */
-static __u64 vector_regs[] = {
+static __u64 v_regs[] = {
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vstart),
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vl),
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vtype),
@@ -1057,37 +1057,17 @@ static __u64 vector_regs[] = {
 #define SUBLIST_BASE \
 	{"base", .regs = base_regs, .regs_n = ARRAY_SIZE(base_regs), \
 	 .skips_set = base_skips_set, .skips_set_n = ARRAY_SIZE(base_skips_set),}
-#define SUBLIST_SBI_BASE \
-	{"sbi-base", .feature_type = VCPU_FEATURE_SBI_EXT, .feature = KVM_RISCV_SBI_EXT_V01, \
-	 .regs = sbi_base_regs, .regs_n = ARRAY_SIZE(sbi_base_regs),}
-#define SUBLIST_SBI_STA \
-	{"sbi-sta", .feature_type = VCPU_FEATURE_SBI_EXT, .feature = KVM_RISCV_SBI_EXT_STA, \
-	 .regs = sbi_sta_regs, .regs_n = ARRAY_SIZE(sbi_sta_regs),}
-#define SUBLIST_SBI_FWFT \
-	{"sbi-fwft", .feature_type = VCPU_FEATURE_SBI_EXT, .feature = KVM_RISCV_SBI_EXT_FWFT, \
-	 .regs = sbi_fwft_regs, .regs_n = ARRAY_SIZE(sbi_fwft_regs),}
-#define SUBLIST_ZICBOM \
-	{"zicbom", .feature = KVM_RISCV_ISA_EXT_ZICBOM, .regs = zicbom_regs, .regs_n = ARRAY_SIZE(zicbom_regs),}
-#define SUBLIST_ZICBOP \
-	{"zicbop", .feature = KVM_RISCV_ISA_EXT_ZICBOP, .regs = zicbop_regs, .regs_n = ARRAY_SIZE(zicbop_regs),}
-#define SUBLIST_ZICBOZ \
-	{"zicboz", .feature = KVM_RISCV_ISA_EXT_ZICBOZ, .regs = zicboz_regs, .regs_n = ARRAY_SIZE(zicboz_regs),}
-#define SUBLIST_AIA \
-	{"aia", .feature = KVM_RISCV_ISA_EXT_SSAIA, .regs = aia_regs, .regs_n = ARRAY_SIZE(aia_regs),}
-#define SUBLIST_SMSTATEEN \
-	{"smstateen", .feature = KVM_RISCV_ISA_EXT_SMSTATEEN, .regs = smstateen_regs, .regs_n = ARRAY_SIZE(smstateen_regs),}
-#define SUBLIST_FP_F \
-	{"fp_f", .feature = KVM_RISCV_ISA_EXT_F, .regs = fp_f_regs, \
-		.regs_n = ARRAY_SIZE(fp_f_regs),}
-#define SUBLIST_FP_D \
-	{"fp_d", .feature = KVM_RISCV_ISA_EXT_D, .regs = fp_d_regs, \
-		.regs_n = ARRAY_SIZE(fp_d_regs),}
-
-#define SUBLIST_V \
-	{"v", .feature = KVM_RISCV_ISA_EXT_V, .regs = vector_regs, .regs_n = ARRAY_SIZE(vector_regs),}
+
+#define SUBLIST_ISA(ext, extu)				\
+	{						\
+		.name = #ext,				\
+		.feature = KVM_RISCV_ISA_EXT_##extu,	\
+		.regs = ext##_regs,			\
+		.regs_n = ARRAY_SIZE(ext##_regs),	\
+	}
 
 #define KVM_ISA_EXT_SIMPLE_CONFIG(ext, extu)			\
-static __u64 regs_##ext[] = {					\
+static __u64 ext##_regs[] = {					\
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG |			\
 	KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE |	\
 	KVM_RISCV_ISA_EXT_##extu,				\
@@ -1095,18 +1075,22 @@ static __u64 regs_##ext[] = {					\
 static struct vcpu_reg_list config_##ext = {			\
 	.sublists = {						\
 		SUBLIST_BASE,					\
-		{						\
-			.name = #ext,				\
-			.feature = KVM_RISCV_ISA_EXT_##extu,	\
-			.regs = regs_##ext,			\
-			.regs_n = ARRAY_SIZE(regs_##ext),	\
-		},						\
+		SUBLIST_ISA(ext, extu),				\
 		{0},						\
 	},							\
 }								\
 
+#define SUBLIST_SBI(ext, extu)					\
+	{							\
+		.name = "sbi-"#ext,				\
+		.feature_type = VCPU_FEATURE_SBI_EXT,		\
+		.feature = KVM_RISCV_SBI_EXT_##extu,		\
+		.regs = sbi_##ext##_regs,			\
+		.regs_n = ARRAY_SIZE(sbi_##ext##_regs),		\
+	}
+
 #define KVM_SBI_EXT_SIMPLE_CONFIG(ext, extu)			\
-static __u64 regs_sbi_##ext[] = {				\
+static __u64 sbi_##ext##_regs[] = {				\
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG |			\
 	KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE |	\
 	KVM_RISCV_SBI_EXT_##extu,				\
@@ -1114,13 +1098,7 @@ static __u64 regs_sbi_##ext[] = {				\
 static struct vcpu_reg_list config_sbi_##ext = {		\
 	.sublists = {						\
 		SUBLIST_BASE,					\
-		{						\
-			.name = "sbi-"#ext,			\
-			.feature_type = VCPU_FEATURE_SBI_EXT,	\
-			.feature = KVM_RISCV_SBI_EXT_##extu,	\
-			.regs = regs_sbi_##ext,			\
-			.regs_n = ARRAY_SIZE(regs_sbi_##ext),	\
-		},						\
+		SUBLIST_SBI(ext, extu),				\
 		{0},						\
 	},							\
 }								\
@@ -1129,7 +1107,7 @@ static struct vcpu_reg_list config_sbi_##ext = {		\
 static struct vcpu_reg_list config_##ext = {			\
 	.sublists = {						\
 		SUBLIST_BASE,					\
-		SUBLIST_##extu,					\
+		SUBLIST_ISA(ext, extu),				\
 		{0},						\
 	},							\
 }								\
@@ -1138,14 +1116,14 @@ static struct vcpu_reg_list config_##ext = {			\
 static struct vcpu_reg_list config_sbi_##ext = {		\
 	.sublists = {						\
 		SUBLIST_BASE,					\
-		SUBLIST_SBI_##extu,				\
+		SUBLIST_SBI(ext, extu),				\
 		{0},						\
 	},							\
 }								\
 
 /* Note: The below list is alphabetically sorted. */
 
-KVM_SBI_EXT_SUBLIST_CONFIG(base, BASE);
+KVM_SBI_EXT_SUBLIST_CONFIG(base, V01);
 KVM_SBI_EXT_SUBLIST_CONFIG(sta, STA);
 KVM_SBI_EXT_SIMPLE_CONFIG(pmu, PMU);
 KVM_SBI_EXT_SIMPLE_CONFIG(dbcn, DBCN);
@@ -1153,9 +1131,9 @@ KVM_SBI_EXT_SIMPLE_CONFIG(susp, SUSP);
 KVM_SBI_EXT_SIMPLE_CONFIG(mpxy, MPXY);
 KVM_SBI_EXT_SUBLIST_CONFIG(fwft, FWFT);
 
-KVM_ISA_EXT_SUBLIST_CONFIG(aia, AIA);
-KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, FP_F);
-KVM_ISA_EXT_SUBLIST_CONFIG(fp_d, FP_D);
+KVM_ISA_EXT_SUBLIST_CONFIG(aia, SSAIA);
+KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, F);
+KVM_ISA_EXT_SUBLIST_CONFIG(fp_d, D);
 KVM_ISA_EXT_SUBLIST_CONFIG(v, V);
 KVM_ISA_EXT_SIMPLE_CONFIG(h, H);
 KVM_ISA_EXT_SIMPLE_CONFIG(smnpm, SMNPM);

-- 
2.43.7


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 4/5] KVM: riscv: selftests: Refactor ISA and SBI extension sublist macros
@ 2026-06-01 10:26   ` Yong-Xuan Wang
  0 siblings, 0 replies; 40+ messages in thread
From: Yong-Xuan Wang @ 2026-06-01 10:26 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan
  Cc: greentime.hu, vincent.chen, zong.li, kvm, kvm-riscv, linux-riscv,
	linux-kernel, linux-kselftest, inochiama, Yong-Xuan Wang

Refactor the get-reg-list test to use unified sublist macros for ISA
and SBI extensions, eliminating code duplication and improving
maintainability.

Previously, each extension had its own hand-coded sublist definition
(e.g., SUBLIST_ZICBOM, SUBLIST_AIA, etc.) and the config structures
repeated the same pattern. This made the code verbose and error-prone.

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
---
 tools/testing/selftests/kvm/riscv/get-reg-list.c | 78 +++++++++---------------
 1 file changed, 28 insertions(+), 50 deletions(-)

diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
index 8d6fdb5d38b8..5033c09201ef 100644
--- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
+++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
@@ -1013,7 +1013,7 @@ static __u64 fp_d_regs[] = {
 };
 
 /* Define a default vector registers with length. This will be overwritten at runtime */
-static __u64 vector_regs[] = {
+static __u64 v_regs[] = {
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vstart),
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vl),
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vtype),
@@ -1057,37 +1057,17 @@ static __u64 vector_regs[] = {
 #define SUBLIST_BASE \
 	{"base", .regs = base_regs, .regs_n = ARRAY_SIZE(base_regs), \
 	 .skips_set = base_skips_set, .skips_set_n = ARRAY_SIZE(base_skips_set),}
-#define SUBLIST_SBI_BASE \
-	{"sbi-base", .feature_type = VCPU_FEATURE_SBI_EXT, .feature = KVM_RISCV_SBI_EXT_V01, \
-	 .regs = sbi_base_regs, .regs_n = ARRAY_SIZE(sbi_base_regs),}
-#define SUBLIST_SBI_STA \
-	{"sbi-sta", .feature_type = VCPU_FEATURE_SBI_EXT, .feature = KVM_RISCV_SBI_EXT_STA, \
-	 .regs = sbi_sta_regs, .regs_n = ARRAY_SIZE(sbi_sta_regs),}
-#define SUBLIST_SBI_FWFT \
-	{"sbi-fwft", .feature_type = VCPU_FEATURE_SBI_EXT, .feature = KVM_RISCV_SBI_EXT_FWFT, \
-	 .regs = sbi_fwft_regs, .regs_n = ARRAY_SIZE(sbi_fwft_regs),}
-#define SUBLIST_ZICBOM \
-	{"zicbom", .feature = KVM_RISCV_ISA_EXT_ZICBOM, .regs = zicbom_regs, .regs_n = ARRAY_SIZE(zicbom_regs),}
-#define SUBLIST_ZICBOP \
-	{"zicbop", .feature = KVM_RISCV_ISA_EXT_ZICBOP, .regs = zicbop_regs, .regs_n = ARRAY_SIZE(zicbop_regs),}
-#define SUBLIST_ZICBOZ \
-	{"zicboz", .feature = KVM_RISCV_ISA_EXT_ZICBOZ, .regs = zicboz_regs, .regs_n = ARRAY_SIZE(zicboz_regs),}
-#define SUBLIST_AIA \
-	{"aia", .feature = KVM_RISCV_ISA_EXT_SSAIA, .regs = aia_regs, .regs_n = ARRAY_SIZE(aia_regs),}
-#define SUBLIST_SMSTATEEN \
-	{"smstateen", .feature = KVM_RISCV_ISA_EXT_SMSTATEEN, .regs = smstateen_regs, .regs_n = ARRAY_SIZE(smstateen_regs),}
-#define SUBLIST_FP_F \
-	{"fp_f", .feature = KVM_RISCV_ISA_EXT_F, .regs = fp_f_regs, \
-		.regs_n = ARRAY_SIZE(fp_f_regs),}
-#define SUBLIST_FP_D \
-	{"fp_d", .feature = KVM_RISCV_ISA_EXT_D, .regs = fp_d_regs, \
-		.regs_n = ARRAY_SIZE(fp_d_regs),}
-
-#define SUBLIST_V \
-	{"v", .feature = KVM_RISCV_ISA_EXT_V, .regs = vector_regs, .regs_n = ARRAY_SIZE(vector_regs),}
+
+#define SUBLIST_ISA(ext, extu)				\
+	{						\
+		.name = #ext,				\
+		.feature = KVM_RISCV_ISA_EXT_##extu,	\
+		.regs = ext##_regs,			\
+		.regs_n = ARRAY_SIZE(ext##_regs),	\
+	}
 
 #define KVM_ISA_EXT_SIMPLE_CONFIG(ext, extu)			\
-static __u64 regs_##ext[] = {					\
+static __u64 ext##_regs[] = {					\
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG |			\
 	KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE |	\
 	KVM_RISCV_ISA_EXT_##extu,				\
@@ -1095,18 +1075,22 @@ static __u64 regs_##ext[] = {					\
 static struct vcpu_reg_list config_##ext = {			\
 	.sublists = {						\
 		SUBLIST_BASE,					\
-		{						\
-			.name = #ext,				\
-			.feature = KVM_RISCV_ISA_EXT_##extu,	\
-			.regs = regs_##ext,			\
-			.regs_n = ARRAY_SIZE(regs_##ext),	\
-		},						\
+		SUBLIST_ISA(ext, extu),				\
 		{0},						\
 	},							\
 }								\
 
+#define SUBLIST_SBI(ext, extu)					\
+	{							\
+		.name = "sbi-"#ext,				\
+		.feature_type = VCPU_FEATURE_SBI_EXT,		\
+		.feature = KVM_RISCV_SBI_EXT_##extu,		\
+		.regs = sbi_##ext##_regs,			\
+		.regs_n = ARRAY_SIZE(sbi_##ext##_regs),		\
+	}
+
 #define KVM_SBI_EXT_SIMPLE_CONFIG(ext, extu)			\
-static __u64 regs_sbi_##ext[] = {				\
+static __u64 sbi_##ext##_regs[] = {				\
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG |			\
 	KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE |	\
 	KVM_RISCV_SBI_EXT_##extu,				\
@@ -1114,13 +1098,7 @@ static __u64 regs_sbi_##ext[] = {				\
 static struct vcpu_reg_list config_sbi_##ext = {		\
 	.sublists = {						\
 		SUBLIST_BASE,					\
-		{						\
-			.name = "sbi-"#ext,			\
-			.feature_type = VCPU_FEATURE_SBI_EXT,	\
-			.feature = KVM_RISCV_SBI_EXT_##extu,	\
-			.regs = regs_sbi_##ext,			\
-			.regs_n = ARRAY_SIZE(regs_sbi_##ext),	\
-		},						\
+		SUBLIST_SBI(ext, extu),				\
 		{0},						\
 	},							\
 }								\
@@ -1129,7 +1107,7 @@ static struct vcpu_reg_list config_sbi_##ext = {		\
 static struct vcpu_reg_list config_##ext = {			\
 	.sublists = {						\
 		SUBLIST_BASE,					\
-		SUBLIST_##extu,					\
+		SUBLIST_ISA(ext, extu),				\
 		{0},						\
 	},							\
 }								\
@@ -1138,14 +1116,14 @@ static struct vcpu_reg_list config_##ext = {			\
 static struct vcpu_reg_list config_sbi_##ext = {		\
 	.sublists = {						\
 		SUBLIST_BASE,					\
-		SUBLIST_SBI_##extu,				\
+		SUBLIST_SBI(ext, extu),				\
 		{0},						\
 	},							\
 }								\
 
 /* Note: The below list is alphabetically sorted. */
 
-KVM_SBI_EXT_SUBLIST_CONFIG(base, BASE);
+KVM_SBI_EXT_SUBLIST_CONFIG(base, V01);
 KVM_SBI_EXT_SUBLIST_CONFIG(sta, STA);
 KVM_SBI_EXT_SIMPLE_CONFIG(pmu, PMU);
 KVM_SBI_EXT_SIMPLE_CONFIG(dbcn, DBCN);
@@ -1153,9 +1131,9 @@ KVM_SBI_EXT_SIMPLE_CONFIG(susp, SUSP);
 KVM_SBI_EXT_SIMPLE_CONFIG(mpxy, MPXY);
 KVM_SBI_EXT_SUBLIST_CONFIG(fwft, FWFT);
 
-KVM_ISA_EXT_SUBLIST_CONFIG(aia, AIA);
-KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, FP_F);
-KVM_ISA_EXT_SUBLIST_CONFIG(fp_d, FP_D);
+KVM_ISA_EXT_SUBLIST_CONFIG(aia, SSAIA);
+KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, F);
+KVM_ISA_EXT_SUBLIST_CONFIG(fp_d, D);
 KVM_ISA_EXT_SUBLIST_CONFIG(v, V);
 KVM_ISA_EXT_SIMPLE_CONFIG(h, H);
 KVM_ISA_EXT_SIMPLE_CONFIG(smnpm, SMNPM);

-- 
2.43.7


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 5/5] KVM: riscv: selftests: Split SBI FWFT into separate feature-specific sublists
  2026-06-01 10:26 ` Yong-Xuan Wang
  (?)
@ 2026-06-01 10:26   ` Yong-Xuan Wang
  -1 siblings, 0 replies; 40+ messages in thread
From: Yong-Xuan Wang @ 2026-06-01 10:26 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan
  Cc: greentime.hu, vincent.chen, zong.li, kvm, kvm-riscv, linux-riscv,
	linux-kernel, linux-kselftest, inochiama, Yong-Xuan Wang

Divide the monolithic SBI FWFT (Firmware Features) register list into
separate sublists, each testing a specific FWFT feature independently
with proper dependency checking.

Previously, all FWFT features were tested together in a single sublist.
This caused issues because:
1. Not all FWFT features are available on all platforms
2. Some features depend on specific ISA extensions (e.g., pointer_masking
requires Smnpm)
3. Tests would fail if any single feature was unavailable

Add the feature-specific SBI FWFT sublists with the following
improvements:
- Add check_fwft_feature() helper to verify FWFT feature availability
  at runtime
- Update filter_reg() to handle per-feature FWFT register filtering

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
---
 tools/testing/selftests/kvm/riscv/get-reg-list.c | 60 ++++++++++++++++++++++--
 1 file changed, 57 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
index 5033c09201ef..cb86cb6b3635 100644
--- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
+++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
@@ -27,6 +27,7 @@ enum {
 };
 
 static bool isa_ext_cant_disable[KVM_RISCV_ISA_EXT_MAX];
+static bool sbi_ext_enabled[KVM_RISCV_SBI_EXT_MAX];
 
 bool filter_reg(__u64 reg)
 {
@@ -149,6 +150,14 @@ bool filter_reg(__u64 reg)
 	case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(iprio1h):
 	case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(iprio2h):
 		return isa_ext_cant_disable[KVM_RISCV_ISA_EXT_SSAIA];
+	/*
+	 * FWFT misaligned delegation registers are always visible when the SBI FWFT
+	 * extension is enable and the host supports the misaligned delegation.
+	 */
+	case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.enable):
+	case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.flags):
+	case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.value):
+		return sbi_ext_enabled[KVM_RISCV_SBI_EXT_FWFT];
 	default:
 		break;
 	}
@@ -193,6 +202,27 @@ static int override_vector_reg_size(struct kvm_vcpu *vcpu, struct vcpu_reg_subli
 	return 0;
 }
 
+void check_fwft_feature(struct kvm_vcpu *vcpu, struct vcpu_reg_sublist *s, u64 feature)
+{
+	unsigned long value;
+	int rc;
+
+	/* Enable SBI FWFT extension so that we can check the supported register */
+	rc = __vcpu_set_reg(vcpu, feature, 1);
+	if (rc)
+		return;
+
+	for (int i = 0; i < s->regs_n; i++) {
+		if ((s->regs[i] & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_SBI_STATE) {
+			rc = __vcpu_get_reg(vcpu, s->regs[i], &value);
+			__TEST_REQUIRE(!rc, "%s not available, skipping tests", s->name);
+		}
+	}
+
+	/* We should assert if disabling failed here while enabling succeeded before */
+	vcpu_set_reg(vcpu, feature, 0);
+}
+
 void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
 {
 	unsigned long isa_ext_state[KVM_RISCV_ISA_EXT_MAX] = { 0 };
@@ -235,6 +265,9 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
 			break;
 		case VCPU_FEATURE_SBI_EXT:
 			feature = RISCV_SBI_EXT_REG(s->feature);
+			if (s->feature == KVM_RISCV_SBI_EXT_FWFT)
+				check_fwft_feature(vcpu, s, feature);
+			sbi_ext_enabled[s->feature] = true;
 			break;
 		default:
 			TEST_FAIL("Unknown feature type");
@@ -897,11 +930,15 @@ static __u64 sbi_sta_regs[] = {
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_STA | KVM_REG_RISCV_SBI_STA_REG(shmem_hi),
 };
 
-static __u64 sbi_fwft_regs[] = {
+static __u64 sbi_fwft_misaligned_deleg_regs[] = {
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_FWFT,
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.enable),
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.flags),
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.value),
+};
+
+static __u64 sbi_fwft_pointer_masking_regs[] = {
+	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_FWFT,
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.enable),
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.flags),
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.value),
@@ -1129,7 +1166,6 @@ KVM_SBI_EXT_SIMPLE_CONFIG(pmu, PMU);
 KVM_SBI_EXT_SIMPLE_CONFIG(dbcn, DBCN);
 KVM_SBI_EXT_SIMPLE_CONFIG(susp, SUSP);
 KVM_SBI_EXT_SIMPLE_CONFIG(mpxy, MPXY);
-KVM_SBI_EXT_SUBLIST_CONFIG(fwft, FWFT);
 
 KVM_ISA_EXT_SUBLIST_CONFIG(aia, SSAIA);
 KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, F);
@@ -1206,6 +1242,23 @@ KVM_ISA_EXT_SIMPLE_CONFIG(zvksed, ZVKSED);
 KVM_ISA_EXT_SIMPLE_CONFIG(zvksh, ZVKSH);
 KVM_ISA_EXT_SIMPLE_CONFIG(zvkt, ZVKT);
 
+static struct vcpu_reg_list config_sbi_fwft_misaligned_deleg = {
+	.sublists = {
+		SUBLIST_BASE,
+		SUBLIST_SBI(fwft_misaligned_deleg, FWFT),
+		{0},
+	},
+};
+
+static struct vcpu_reg_list config_sbi_fwft_pointer_masking = {
+	.sublists = {
+		SUBLIST_BASE,
+		SUBLIST_ISA(smnpm, SMNPM),
+		SUBLIST_SBI(fwft_pointer_masking, FWFT),
+		{0},
+	},
+};
+
 struct vcpu_reg_list *vcpu_configs[] = {
 	&config_sbi_base,
 	&config_sbi_sta,
@@ -1213,7 +1266,8 @@ struct vcpu_reg_list *vcpu_configs[] = {
 	&config_sbi_dbcn,
 	&config_sbi_susp,
 	&config_sbi_mpxy,
-	&config_sbi_fwft,
+	&config_sbi_fwft_misaligned_deleg,
+	&config_sbi_fwft_pointer_masking,
 	&config_aia,
 	&config_fp_f,
 	&config_fp_d,

-- 
2.43.7


-- 
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 5/5] KVM: riscv: selftests: Split SBI FWFT into separate feature-specific sublists
@ 2026-06-01 10:26   ` Yong-Xuan Wang
  0 siblings, 0 replies; 40+ messages in thread
From: Yong-Xuan Wang @ 2026-06-01 10:26 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan
  Cc: greentime.hu, vincent.chen, zong.li, kvm, kvm-riscv, linux-riscv,
	linux-kernel, linux-kselftest, inochiama, Yong-Xuan Wang

Divide the monolithic SBI FWFT (Firmware Features) register list into
separate sublists, each testing a specific FWFT feature independently
with proper dependency checking.

Previously, all FWFT features were tested together in a single sublist.
This caused issues because:
1. Not all FWFT features are available on all platforms
2. Some features depend on specific ISA extensions (e.g., pointer_masking
requires Smnpm)
3. Tests would fail if any single feature was unavailable

Add the feature-specific SBI FWFT sublists with the following
improvements:
- Add check_fwft_feature() helper to verify FWFT feature availability
  at runtime
- Update filter_reg() to handle per-feature FWFT register filtering

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
---
 tools/testing/selftests/kvm/riscv/get-reg-list.c | 60 ++++++++++++++++++++++--
 1 file changed, 57 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
index 5033c09201ef..cb86cb6b3635 100644
--- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
+++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
@@ -27,6 +27,7 @@ enum {
 };
 
 static bool isa_ext_cant_disable[KVM_RISCV_ISA_EXT_MAX];
+static bool sbi_ext_enabled[KVM_RISCV_SBI_EXT_MAX];
 
 bool filter_reg(__u64 reg)
 {
@@ -149,6 +150,14 @@ bool filter_reg(__u64 reg)
 	case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(iprio1h):
 	case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(iprio2h):
 		return isa_ext_cant_disable[KVM_RISCV_ISA_EXT_SSAIA];
+	/*
+	 * FWFT misaligned delegation registers are always visible when the SBI FWFT
+	 * extension is enable and the host supports the misaligned delegation.
+	 */
+	case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.enable):
+	case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.flags):
+	case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.value):
+		return sbi_ext_enabled[KVM_RISCV_SBI_EXT_FWFT];
 	default:
 		break;
 	}
@@ -193,6 +202,27 @@ static int override_vector_reg_size(struct kvm_vcpu *vcpu, struct vcpu_reg_subli
 	return 0;
 }
 
+void check_fwft_feature(struct kvm_vcpu *vcpu, struct vcpu_reg_sublist *s, u64 feature)
+{
+	unsigned long value;
+	int rc;
+
+	/* Enable SBI FWFT extension so that we can check the supported register */
+	rc = __vcpu_set_reg(vcpu, feature, 1);
+	if (rc)
+		return;
+
+	for (int i = 0; i < s->regs_n; i++) {
+		if ((s->regs[i] & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_SBI_STATE) {
+			rc = __vcpu_get_reg(vcpu, s->regs[i], &value);
+			__TEST_REQUIRE(!rc, "%s not available, skipping tests", s->name);
+		}
+	}
+
+	/* We should assert if disabling failed here while enabling succeeded before */
+	vcpu_set_reg(vcpu, feature, 0);
+}
+
 void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
 {
 	unsigned long isa_ext_state[KVM_RISCV_ISA_EXT_MAX] = { 0 };
@@ -235,6 +265,9 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
 			break;
 		case VCPU_FEATURE_SBI_EXT:
 			feature = RISCV_SBI_EXT_REG(s->feature);
+			if (s->feature == KVM_RISCV_SBI_EXT_FWFT)
+				check_fwft_feature(vcpu, s, feature);
+			sbi_ext_enabled[s->feature] = true;
 			break;
 		default:
 			TEST_FAIL("Unknown feature type");
@@ -897,11 +930,15 @@ static __u64 sbi_sta_regs[] = {
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_STA | KVM_REG_RISCV_SBI_STA_REG(shmem_hi),
 };
 
-static __u64 sbi_fwft_regs[] = {
+static __u64 sbi_fwft_misaligned_deleg_regs[] = {
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_FWFT,
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.enable),
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.flags),
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.value),
+};
+
+static __u64 sbi_fwft_pointer_masking_regs[] = {
+	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_FWFT,
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.enable),
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.flags),
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.value),
@@ -1129,7 +1166,6 @@ KVM_SBI_EXT_SIMPLE_CONFIG(pmu, PMU);
 KVM_SBI_EXT_SIMPLE_CONFIG(dbcn, DBCN);
 KVM_SBI_EXT_SIMPLE_CONFIG(susp, SUSP);
 KVM_SBI_EXT_SIMPLE_CONFIG(mpxy, MPXY);
-KVM_SBI_EXT_SUBLIST_CONFIG(fwft, FWFT);
 
 KVM_ISA_EXT_SUBLIST_CONFIG(aia, SSAIA);
 KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, F);
@@ -1206,6 +1242,23 @@ KVM_ISA_EXT_SIMPLE_CONFIG(zvksed, ZVKSED);
 KVM_ISA_EXT_SIMPLE_CONFIG(zvksh, ZVKSH);
 KVM_ISA_EXT_SIMPLE_CONFIG(zvkt, ZVKT);
 
+static struct vcpu_reg_list config_sbi_fwft_misaligned_deleg = {
+	.sublists = {
+		SUBLIST_BASE,
+		SUBLIST_SBI(fwft_misaligned_deleg, FWFT),
+		{0},
+	},
+};
+
+static struct vcpu_reg_list config_sbi_fwft_pointer_masking = {
+	.sublists = {
+		SUBLIST_BASE,
+		SUBLIST_ISA(smnpm, SMNPM),
+		SUBLIST_SBI(fwft_pointer_masking, FWFT),
+		{0},
+	},
+};
+
 struct vcpu_reg_list *vcpu_configs[] = {
 	&config_sbi_base,
 	&config_sbi_sta,
@@ -1213,7 +1266,8 @@ struct vcpu_reg_list *vcpu_configs[] = {
 	&config_sbi_dbcn,
 	&config_sbi_susp,
 	&config_sbi_mpxy,
-	&config_sbi_fwft,
+	&config_sbi_fwft_misaligned_deleg,
+	&config_sbi_fwft_pointer_masking,
 	&config_aia,
 	&config_fp_f,
 	&config_fp_d,

-- 
2.43.7


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 5/5] KVM: riscv: selftests: Split SBI FWFT into separate feature-specific sublists
@ 2026-06-01 10:26   ` Yong-Xuan Wang
  0 siblings, 0 replies; 40+ messages in thread
From: Yong-Xuan Wang @ 2026-06-01 10:26 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan
  Cc: greentime.hu, vincent.chen, zong.li, kvm, kvm-riscv, linux-riscv,
	linux-kernel, linux-kselftest, inochiama, Yong-Xuan Wang

Divide the monolithic SBI FWFT (Firmware Features) register list into
separate sublists, each testing a specific FWFT feature independently
with proper dependency checking.

Previously, all FWFT features were tested together in a single sublist.
This caused issues because:
1. Not all FWFT features are available on all platforms
2. Some features depend on specific ISA extensions (e.g., pointer_masking
requires Smnpm)
3. Tests would fail if any single feature was unavailable

Add the feature-specific SBI FWFT sublists with the following
improvements:
- Add check_fwft_feature() helper to verify FWFT feature availability
  at runtime
- Update filter_reg() to handle per-feature FWFT register filtering

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
---
 tools/testing/selftests/kvm/riscv/get-reg-list.c | 60 ++++++++++++++++++++++--
 1 file changed, 57 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
index 5033c09201ef..cb86cb6b3635 100644
--- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
+++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
@@ -27,6 +27,7 @@ enum {
 };
 
 static bool isa_ext_cant_disable[KVM_RISCV_ISA_EXT_MAX];
+static bool sbi_ext_enabled[KVM_RISCV_SBI_EXT_MAX];
 
 bool filter_reg(__u64 reg)
 {
@@ -149,6 +150,14 @@ bool filter_reg(__u64 reg)
 	case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(iprio1h):
 	case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(iprio2h):
 		return isa_ext_cant_disable[KVM_RISCV_ISA_EXT_SSAIA];
+	/*
+	 * FWFT misaligned delegation registers are always visible when the SBI FWFT
+	 * extension is enable and the host supports the misaligned delegation.
+	 */
+	case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.enable):
+	case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.flags):
+	case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.value):
+		return sbi_ext_enabled[KVM_RISCV_SBI_EXT_FWFT];
 	default:
 		break;
 	}
@@ -193,6 +202,27 @@ static int override_vector_reg_size(struct kvm_vcpu *vcpu, struct vcpu_reg_subli
 	return 0;
 }
 
+void check_fwft_feature(struct kvm_vcpu *vcpu, struct vcpu_reg_sublist *s, u64 feature)
+{
+	unsigned long value;
+	int rc;
+
+	/* Enable SBI FWFT extension so that we can check the supported register */
+	rc = __vcpu_set_reg(vcpu, feature, 1);
+	if (rc)
+		return;
+
+	for (int i = 0; i < s->regs_n; i++) {
+		if ((s->regs[i] & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_SBI_STATE) {
+			rc = __vcpu_get_reg(vcpu, s->regs[i], &value);
+			__TEST_REQUIRE(!rc, "%s not available, skipping tests", s->name);
+		}
+	}
+
+	/* We should assert if disabling failed here while enabling succeeded before */
+	vcpu_set_reg(vcpu, feature, 0);
+}
+
 void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
 {
 	unsigned long isa_ext_state[KVM_RISCV_ISA_EXT_MAX] = { 0 };
@@ -235,6 +265,9 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
 			break;
 		case VCPU_FEATURE_SBI_EXT:
 			feature = RISCV_SBI_EXT_REG(s->feature);
+			if (s->feature == KVM_RISCV_SBI_EXT_FWFT)
+				check_fwft_feature(vcpu, s, feature);
+			sbi_ext_enabled[s->feature] = true;
 			break;
 		default:
 			TEST_FAIL("Unknown feature type");
@@ -897,11 +930,15 @@ static __u64 sbi_sta_regs[] = {
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_STA | KVM_REG_RISCV_SBI_STA_REG(shmem_hi),
 };
 
-static __u64 sbi_fwft_regs[] = {
+static __u64 sbi_fwft_misaligned_deleg_regs[] = {
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_FWFT,
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.enable),
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.flags),
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.value),
+};
+
+static __u64 sbi_fwft_pointer_masking_regs[] = {
+	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_FWFT,
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.enable),
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.flags),
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.value),
@@ -1129,7 +1166,6 @@ KVM_SBI_EXT_SIMPLE_CONFIG(pmu, PMU);
 KVM_SBI_EXT_SIMPLE_CONFIG(dbcn, DBCN);
 KVM_SBI_EXT_SIMPLE_CONFIG(susp, SUSP);
 KVM_SBI_EXT_SIMPLE_CONFIG(mpxy, MPXY);
-KVM_SBI_EXT_SUBLIST_CONFIG(fwft, FWFT);
 
 KVM_ISA_EXT_SUBLIST_CONFIG(aia, SSAIA);
 KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, F);
@@ -1206,6 +1242,23 @@ KVM_ISA_EXT_SIMPLE_CONFIG(zvksed, ZVKSED);
 KVM_ISA_EXT_SIMPLE_CONFIG(zvksh, ZVKSH);
 KVM_ISA_EXT_SIMPLE_CONFIG(zvkt, ZVKT);
 
+static struct vcpu_reg_list config_sbi_fwft_misaligned_deleg = {
+	.sublists = {
+		SUBLIST_BASE,
+		SUBLIST_SBI(fwft_misaligned_deleg, FWFT),
+		{0},
+	},
+};
+
+static struct vcpu_reg_list config_sbi_fwft_pointer_masking = {
+	.sublists = {
+		SUBLIST_BASE,
+		SUBLIST_ISA(smnpm, SMNPM),
+		SUBLIST_SBI(fwft_pointer_masking, FWFT),
+		{0},
+	},
+};
+
 struct vcpu_reg_list *vcpu_configs[] = {
 	&config_sbi_base,
 	&config_sbi_sta,
@@ -1213,7 +1266,8 @@ struct vcpu_reg_list *vcpu_configs[] = {
 	&config_sbi_dbcn,
 	&config_sbi_susp,
 	&config_sbi_mpxy,
-	&config_sbi_fwft,
+	&config_sbi_fwft_misaligned_deleg,
+	&config_sbi_fwft_pointer_masking,
 	&config_aia,
 	&config_fp_f,
 	&config_fp_d,

-- 
2.43.7


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 1/5] KVM: RISC-V: SBI FWFT: Mark vCPU CSRs dirty after setting feature value
  2026-06-01 10:26   ` Yong-Xuan Wang
  (?)
  (?)
@ 2026-06-01 11:04   ` sashiko-bot
  -1 siblings, 0 replies; 40+ messages in thread
From: sashiko-bot @ 2026-06-01 11:04 UTC (permalink / raw)
  To: Yong-Xuan Wang; +Cc: kvm

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Unconditional setting of csr_dirty contradicts the commit message design intent.
--

commit acd5b6b18e2d1bc390b68230f877d70bd8155368
Author: Yong-Xuan Wang <yongxuan.wang@sifive.com>

KVM: RISC-V: SBI FWFT: Mark vCPU CSRs dirty after setting feature value

This commit updates KVM on RISC-V to mark vCPU CSRs as dirty when an FWFT
feature value is updated. This prevents the guest from observing stale CSR
states after vCPU scheduling or migration by ensuring the modified state is
properly synchronized.

> diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
> index 2eab15339694f..5e4aafb0cbf16 100644
> --- a/arch/riscv/kvm/vcpu_sbi_fwft.c
> +++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
> @@ -521,6 +521,7 @@ static int kvm_sbi_ext_fwft_set_reg(struct kvm_vcpu *vcpu, unsigned long reg_num
>  		break;
>  	case 2:
>  		ret = conf->feature->set(vcpu, conf, true, value);
> +		vcpu->arch.csr_dirty = true;

[Severity: Medium]
The commit message mentions marking the CSRs dirty after successfully setting
an FWFT feature value. Does kvm_sbi_ext_fwft_set_reg() unconditionally set
vcpu->arch.csr_dirty to true, even if conf->feature->set() fails and returns
an error?

Could this lead to unnecessary CSR hardware reloads on error paths since the
return value in ret is not checked before modifying the dirty flag?

>  		break;
>  	default:
>  		return -ENOENT;

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260601-kvm-get_reg_list-v2-v5-0-415d08a2813b@sifive.com?part=1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 3/5] KVM: RISC-V: SBI FWFT: Fix stale feature exposure after runtime extension changes
  2026-06-01 10:26   ` Yong-Xuan Wang
  (?)
  (?)
@ 2026-06-01 11:37   ` sashiko-bot
  -1 siblings, 0 replies; 40+ messages in thread
From: sashiko-bot @ 2026-06-01 11:37 UTC (permalink / raw)
  To: Yong-Xuan Wang; +Cc: kvm

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [High] State mutation on error path in SBI FWFT set operation permanently locks features on invalid requests.
- [High] Hiding FWFT features at runtime without reverting architectural state causes hardware to run with unadvertised features.
--

commit 7286cc45c5a1525ff749cb1b680b09d20f49fbe4
Author: Yong-Xuan Wang <yongxuan.wang@sifive.com>

KVM: RISC-V: SBI FWFT: Fix stale feature exposure after runtime extension changes

Fix a bug where FWFT features could be incorrectly exposed to guests
after userspace disables their dependent ISA extensions at runtime. The
fix adds a two-layer checking mechanism to ensure feature availability
is re-evaluated based on the current ISA extension state.

> diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
> index aee951f2b8e63..ab39ac464ffd8 100644
> --- a/arch/riscv/kvm/vcpu_sbi_fwft.c
> +++ b/arch/riscv/kvm/vcpu_sbi_fwft.c

[ ... ]

> @@ -527,6 +535,8 @@ static int kvm_sbi_ext_fwft_set_reg(struct kvm_vcpu *vcpu, unsigned long reg_num
>  	conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
>  	if (!conf || !conf->supported)
>  		return -ENOENT;
> +	else if (conf->feature->supported && !conf->feature->supported(vcpu))
> +		return -ENOENT;

[Severity: High]
This isn't a bug introduced by this patch, but this dynamic check might lock
userspace out of clearing the feature state.

If userspace disables the prerequisite ISA extension (e.g. SMNPM) via ONE_REG,
the extension is cleared from vcpu->arch.isa, but the dependent FWFT
architectural state in vcpu->arch.cfg.henvcfg remains intact.

If userspace then attempts to clear the FWFT feature state via ONE_REG, this
check returns -ENOENT because the underlying ISA extension is now disabled.

When the vCPU runs, kvm_riscv_vcpu_config_load() unconditionally writes the
stale henvcfg to the physical CSR_HENVCFG register:

arch/riscv/kvm/vcpu_config.c:kvm_riscv_vcpu_config_load() {
    ...
    csr_write(CSR_HENVCFG, cfg->henvcfg);
    ...
}

Will this cause the guest to run with unadvertised hardware features enabled?
Should the architectural state be reverted before hiding the feature, or should
userspace be permitted to clear the state even if the feature is unsupported?

>  
>  	switch (reg_num - feature->first_reg_num) {
>  	case 0:


[Severity: High]
This is a pre-existing issue, but I noticed a potential problem in how
feature flags are handled during guest set operations:

arch/riscv/kvm/vcpu_sbi_fwft.c:kvm_sbi_fwft_set() {
    ...
	if (conf->flags & SBI_FWFT_SET_FLAG_LOCK)
		return SBI_ERR_DENIED_LOCKED;

	conf->flags = flags;

	return conf->feature->set(vcpu, conf, false, value);
}

If a guest issues an SBI_EXT_FWFT_SET call with an invalid value but sets
the SBI_FWFT_SET_FLAG_LOCK flag, conf->flags is updated unconditionally.

If the feature-specific set() callback rejects the invalid value and returns
SBI_ERR_INVALID_PARAM, the hypervisor will return this error to the guest
but the lock flag remains permanently set.

Does this permanently lock the feature on invalid requests, preventing
subsequent attempts to set a valid value? Should conf->flags only be
updated if the set() callback succeeds?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260601-kvm-get_reg_list-v2-v5-0-415d08a2813b@sifive.com?part=3

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 5/5] KVM: riscv: selftests: Split SBI FWFT into separate feature-specific sublists
  2026-06-01 10:26   ` Yong-Xuan Wang
  (?)
  (?)
@ 2026-06-01 11:54   ` sashiko-bot
  2026-06-04  9:28     ` Yong-Xuan Wang
  -1 siblings, 1 reply; 40+ messages in thread
From: sashiko-bot @ 2026-06-01 11:54 UTC (permalink / raw)
  To: Yong-Xuan Wang; +Cc: kvm

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The `pointer_masking` FWFT registers are omitted from `filter_reg()`, causing spurious "new registers" output when testing other FWFT configurations.
--

commit aac064e5a6f0dbfa5efc45c4b208f71e477aa98e
Author: Yong-Xuan Wang <yongxuan.wang@sifive.com>

KVM: riscv: selftests: Split SBI FWFT into separate feature-specific sublists

Divide the monolithic SBI FWFT register list into separate sublists, each
testing a specific FWFT feature independently. This allows tests to run
correctly on platforms where not all FWFT features are available.

> diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> index 5033c09201ef1..cb86cb6b36355 100644
> --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
> +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
[ ... ]
> @@ -149,6 +150,14 @@ bool filter_reg(__u64 reg)
>  	case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(iprio1h):
>  	case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(iprio2h):
>  		return isa_ext_cant_disable[KVM_RISCV_ISA_EXT_SSAIA];
> +	/*
> +	 * FWFT misaligned delegation registers are always visible when the SBI FWFT
> +	 * extension is enable and the host supports the misaligned delegation.
> +	 */
> +	case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.enable):
> +	case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.flags):
> +	case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.value):
> +		return sbi_ext_enabled[KVM_RISCV_SBI_EXT_FWFT];

[Severity: Low]
Should the pointer_masking FWFT registers be included here as well?

If config_sbi_fwft_misaligned_deleg is tested on a host where the SMNPM
extension is available and cannot be disabled, KVM will expose the
pointer_masking registers. Because they are omitted from filter_reg(), won't
the test framework spuriously report them as new registers?

>  	default:
>  		break;
>  	}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260601-kvm-get_reg_list-v2-v5-0-415d08a2813b@sifive.com?part=5

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 5/5] KVM: riscv: selftests: Split SBI FWFT into separate feature-specific sublists
  2026-06-01 11:54   ` sashiko-bot
@ 2026-06-04  9:28     ` Yong-Xuan Wang
  0 siblings, 0 replies; 40+ messages in thread
From: Yong-Xuan Wang @ 2026-06-04  9:28 UTC (permalink / raw)
  To: sashiko-reviews; +Cc: kvm

On Mon, Jun 1, 2026 at 7:54 PM <sashiko-bot@kernel.org> wrote:
>
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Low] The `pointer_masking` FWFT registers are omitted from `filter_reg()`, causing spurious "new registers" output when testing other FWFT configurations.
> --
>
> commit aac064e5a6f0dbfa5efc45c4b208f71e477aa98e
> Author: Yong-Xuan Wang <yongxuan.wang@sifive.com>
>
> KVM: riscv: selftests: Split SBI FWFT into separate feature-specific sublists
>
> Divide the monolithic SBI FWFT register list into separate sublists, each
> testing a specific FWFT feature independently. This allows tests to run
> correctly on platforms where not all FWFT features are available.
>
> > diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> > index 5033c09201ef1..cb86cb6b36355 100644
> > --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
> > +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> [ ... ]
> > @@ -149,6 +150,14 @@ bool filter_reg(__u64 reg)
> >       case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(iprio1h):
> >       case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(iprio2h):
> >               return isa_ext_cant_disable[KVM_RISCV_ISA_EXT_SSAIA];
> > +     /*
> > +      * FWFT misaligned delegation registers are always visible when the SBI FWFT
> > +      * extension is enable and the host supports the misaligned delegation.
> > +      */
> > +     case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.enable):
> > +     case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.flags):
> > +     case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.value):
> > +             return sbi_ext_enabled[KVM_RISCV_SBI_EXT_FWFT];
>
> [Severity: Low]
> Should the pointer_masking FWFT registers be included here as well?
>
> If config_sbi_fwft_misaligned_deleg is tested on a host where the SMNPM
> extension is available and cannot be disabled, KVM will expose the
> pointer_masking registers. Because they are omitted from filter_reg(), won't
> the test framework spuriously report them as new registers?

The SMNPM extension can be disabled so the KVM won't expose the pointer_masking
registers when testing config_sbi_fwft_misaligned_deleg.

>
> >       default:
> >               break;
> >       }
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260601-kvm-get_reg_list-v2-v5-0-415d08a2813b@sifive.com?part=5

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 1/5] KVM: RISC-V: SBI FWFT: Mark vCPU CSRs dirty after setting feature value
  2026-06-01 10:26   ` Yong-Xuan Wang
  (?)
@ 2026-06-05 15:30     ` Anup Patel
  -1 siblings, 0 replies; 40+ messages in thread
From: Anup Patel @ 2026-06-05 15:30 UTC (permalink / raw)
  To: Yong-Xuan Wang
  Cc: Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan, greentime.hu, vincent.chen, zong.li,
	kvm, kvm-riscv, linux-riscv, linux-kernel, linux-kselftest,
	inochiama

On Mon, Jun 1, 2026 at 3:56 PM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
>
> Mark the vCPU CSRs as dirty after successfully setting an FWFT feature
> value. FWFT features may modify CSRs (e.g., pointer masking modifies
> henvcfg.PMM), and failing to mark them dirty can lead to the guest
> observing stale CSR state after vCPU scheduling or migration.
>
> Fixes: 1323a5cfe52c ("KVM: riscv: Skip CSR restore if VCPU is reloaded on the same core")
>
> Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Thanks,
Anup

> ---
>  arch/riscv/kvm/vcpu_sbi_fwft.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
> index 2eab15339694..5e4aafb0cbf1 100644
> --- a/arch/riscv/kvm/vcpu_sbi_fwft.c
> +++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
> @@ -521,6 +521,7 @@ static int kvm_sbi_ext_fwft_set_reg(struct kvm_vcpu *vcpu, unsigned long reg_num
>                 break;
>         case 2:
>                 ret = conf->feature->set(vcpu, conf, true, value);
> +               vcpu->arch.csr_dirty = true;
>                 break;
>         default:
>                 return -ENOENT;
>
> --
> 2.43.7
>

-- 
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 1/5] KVM: RISC-V: SBI FWFT: Mark vCPU CSRs dirty after setting feature value
@ 2026-06-05 15:30     ` Anup Patel
  0 siblings, 0 replies; 40+ messages in thread
From: Anup Patel @ 2026-06-05 15:30 UTC (permalink / raw)
  To: Yong-Xuan Wang
  Cc: Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan, greentime.hu, vincent.chen, zong.li,
	kvm, kvm-riscv, linux-riscv, linux-kernel, linux-kselftest,
	inochiama

On Mon, Jun 1, 2026 at 3:56 PM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
>
> Mark the vCPU CSRs as dirty after successfully setting an FWFT feature
> value. FWFT features may modify CSRs (e.g., pointer masking modifies
> henvcfg.PMM), and failing to mark them dirty can lead to the guest
> observing stale CSR state after vCPU scheduling or migration.
>
> Fixes: 1323a5cfe52c ("KVM: riscv: Skip CSR restore if VCPU is reloaded on the same core")
>
> Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Thanks,
Anup

> ---
>  arch/riscv/kvm/vcpu_sbi_fwft.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
> index 2eab15339694..5e4aafb0cbf1 100644
> --- a/arch/riscv/kvm/vcpu_sbi_fwft.c
> +++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
> @@ -521,6 +521,7 @@ static int kvm_sbi_ext_fwft_set_reg(struct kvm_vcpu *vcpu, unsigned long reg_num
>                 break;
>         case 2:
>                 ret = conf->feature->set(vcpu, conf, true, value);
> +               vcpu->arch.csr_dirty = true;
>                 break;
>         default:
>                 return -ENOENT;
>
> --
> 2.43.7
>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 1/5] KVM: RISC-V: SBI FWFT: Mark vCPU CSRs dirty after setting feature value
@ 2026-06-05 15:30     ` Anup Patel
  0 siblings, 0 replies; 40+ messages in thread
From: Anup Patel @ 2026-06-05 15:30 UTC (permalink / raw)
  To: Yong-Xuan Wang
  Cc: Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan, greentime.hu, vincent.chen, zong.li,
	kvm, kvm-riscv, linux-riscv, linux-kernel, linux-kselftest,
	inochiama

On Mon, Jun 1, 2026 at 3:56 PM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
>
> Mark the vCPU CSRs as dirty after successfully setting an FWFT feature
> value. FWFT features may modify CSRs (e.g., pointer masking modifies
> henvcfg.PMM), and failing to mark them dirty can lead to the guest
> observing stale CSR state after vCPU scheduling or migration.
>
> Fixes: 1323a5cfe52c ("KVM: riscv: Skip CSR restore if VCPU is reloaded on the same core")
>
> Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Thanks,
Anup

> ---
>  arch/riscv/kvm/vcpu_sbi_fwft.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
> index 2eab15339694..5e4aafb0cbf1 100644
> --- a/arch/riscv/kvm/vcpu_sbi_fwft.c
> +++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
> @@ -521,6 +521,7 @@ static int kvm_sbi_ext_fwft_set_reg(struct kvm_vcpu *vcpu, unsigned long reg_num
>                 break;
>         case 2:
>                 ret = conf->feature->set(vcpu, conf, true, value);
> +               vcpu->arch.csr_dirty = true;
>                 break;
>         default:
>                 return -ENOENT;
>
> --
> 2.43.7
>

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 2/5] KVM: RISC-V: SBI FWFT: Add optional init() callback for hardware probing
  2026-06-01 10:26   ` Yong-Xuan Wang
  (?)
@ 2026-06-05 16:11     ` Anup Patel
  -1 siblings, 0 replies; 40+ messages in thread
From: Anup Patel @ 2026-06-05 16:11 UTC (permalink / raw)
  To: Yong-Xuan Wang
  Cc: Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan, greentime.hu, vincent.chen, zong.li,
	kvm, kvm-riscv, linux-riscv, linux-kernel, linux-kselftest,
	inochiama

On Mon, Jun 1, 2026 at 3:56 PM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
>
> Add an optional init() callback to separate one-time hardware probing
> from runtime availability checks. For pointer masking, this allows
> probing supported PMM lengths during initialization while checking ISA
> extension availability at runtime.
>
> Fix try_to_set_pmm() to restore the previous HENVCFG.PMM value after
> probing, preventing side effects from hardware detection. Add preemption
> protection to ensure CSR probe sequences complete atomically on the same
> CPU.
>
> Fixes: 6f576fc0aeb9 ("RISC-V: KVM: Add support for SBI_FWFT_POINTER_MASKING_PMLEN")
>
> Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Thanks,
Anup

> ---
>  arch/riscv/kvm/vcpu_sbi_fwft.c | 33 +++++++++++++++++++++++++++++----
>  1 file changed, 29 insertions(+), 4 deletions(-)
>
> diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
> index 5e4aafb0cbf1..aee951f2b8e6 100644
> --- a/arch/riscv/kvm/vcpu_sbi_fwft.c
> +++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
> @@ -35,6 +35,16 @@ struct kvm_sbi_fwft_feature {
>          */
>         bool (*supported)(struct kvm_vcpu *vcpu);
>
> +       /**
> +        * @init: Probe and initialize the feature on the vcpu
> +        *
> +        * This callback is optional. If provided, it will be called during
> +        * vcpu initialization to probe the feature availability and perform
> +        * any necessary initialization. Returns true if the feature is supported
> +        * and initialized successfully, false otherwise.
> +        */
> +       bool (*init)(struct kvm_vcpu *vcpu);
> +
>         /**
>          * @reset: Reset the feature value irrespective whether feature is supported or not
>          *
> @@ -131,19 +141,30 @@ static long kvm_sbi_fwft_get_misaligned_delegation(struct kvm_vcpu *vcpu,
>
>  static bool try_to_set_pmm(unsigned long value)
>  {
> +       unsigned long prev;
> +       bool ret;
> +
> +       prev = csr_read_clear(CSR_HENVCFG, ENVCFG_PMM);
>         csr_set(CSR_HENVCFG, value);
> -       return (csr_read_clear(CSR_HENVCFG, ENVCFG_PMM) & ENVCFG_PMM) == value;
> +       ret = (csr_read_clear(CSR_HENVCFG, ENVCFG_PMM) & ENVCFG_PMM) == value;
> +       csr_write(CSR_HENVCFG, prev);
> +
> +       return ret;
>  }
>
>  static bool kvm_sbi_fwft_pointer_masking_pmlen_supported(struct kvm_vcpu *vcpu)
>  {
> -       struct kvm_sbi_fwft *fwft = vcpu_to_fwft(vcpu);
> +       return riscv_isa_extension_available(vcpu->arch.isa, SMNPM);
> +}
>
> -       if (!riscv_isa_extension_available(vcpu->arch.isa, SMNPM))
> -               return false;
> +static bool kvm_sbi_fwft_pointer_masking_pmlen_init(struct kvm_vcpu *vcpu)
> +{
> +       struct kvm_sbi_fwft *fwft = vcpu_to_fwft(vcpu);
>
> +       preempt_disable();
>         fwft->have_vs_pmlen_7 = try_to_set_pmm(ENVCFG_PMM_PMLEN_7);
>         fwft->have_vs_pmlen_16 = try_to_set_pmm(ENVCFG_PMM_PMLEN_16);
> +       preempt_enable();
>
>         return fwft->have_vs_pmlen_7 || fwft->have_vs_pmlen_16;
>  }
> @@ -231,6 +252,7 @@ static const struct kvm_sbi_fwft_feature features[] = {
>                 .first_reg_num = offsetof(struct kvm_riscv_sbi_fwft, pointer_masking.enable) /
>                                  sizeof(unsigned long),
>                 .supported = kvm_sbi_fwft_pointer_masking_pmlen_supported,
> +               .init = kvm_sbi_fwft_pointer_masking_pmlen_init,
>                 .reset = kvm_sbi_fwft_reset_pointer_masking_pmlen,
>                 .set = kvm_sbi_fwft_set_pointer_masking_pmlen,
>                 .get = kvm_sbi_fwft_get_pointer_masking_pmlen,
> @@ -365,6 +387,9 @@ static int kvm_sbi_ext_fwft_init(struct kvm_vcpu *vcpu)
>                 else
>                         conf->supported = true;
>
> +               if (conf->supported && feature->init)
> +                       conf->supported = feature->init(vcpu);
> +
>                 conf->enabled = conf->supported;
>                 conf->feature = feature;
>         }
>
> --
> 2.43.7
>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 2/5] KVM: RISC-V: SBI FWFT: Add optional init() callback for hardware probing
@ 2026-06-05 16:11     ` Anup Patel
  0 siblings, 0 replies; 40+ messages in thread
From: Anup Patel @ 2026-06-05 16:11 UTC (permalink / raw)
  To: Yong-Xuan Wang
  Cc: Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan, greentime.hu, vincent.chen, zong.li,
	kvm, kvm-riscv, linux-riscv, linux-kernel, linux-kselftest,
	inochiama

On Mon, Jun 1, 2026 at 3:56 PM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
>
> Add an optional init() callback to separate one-time hardware probing
> from runtime availability checks. For pointer masking, this allows
> probing supported PMM lengths during initialization while checking ISA
> extension availability at runtime.
>
> Fix try_to_set_pmm() to restore the previous HENVCFG.PMM value after
> probing, preventing side effects from hardware detection. Add preemption
> protection to ensure CSR probe sequences complete atomically on the same
> CPU.
>
> Fixes: 6f576fc0aeb9 ("RISC-V: KVM: Add support for SBI_FWFT_POINTER_MASKING_PMLEN")
>
> Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Thanks,
Anup

> ---
>  arch/riscv/kvm/vcpu_sbi_fwft.c | 33 +++++++++++++++++++++++++++++----
>  1 file changed, 29 insertions(+), 4 deletions(-)
>
> diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
> index 5e4aafb0cbf1..aee951f2b8e6 100644
> --- a/arch/riscv/kvm/vcpu_sbi_fwft.c
> +++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
> @@ -35,6 +35,16 @@ struct kvm_sbi_fwft_feature {
>          */
>         bool (*supported)(struct kvm_vcpu *vcpu);
>
> +       /**
> +        * @init: Probe and initialize the feature on the vcpu
> +        *
> +        * This callback is optional. If provided, it will be called during
> +        * vcpu initialization to probe the feature availability and perform
> +        * any necessary initialization. Returns true if the feature is supported
> +        * and initialized successfully, false otherwise.
> +        */
> +       bool (*init)(struct kvm_vcpu *vcpu);
> +
>         /**
>          * @reset: Reset the feature value irrespective whether feature is supported or not
>          *
> @@ -131,19 +141,30 @@ static long kvm_sbi_fwft_get_misaligned_delegation(struct kvm_vcpu *vcpu,
>
>  static bool try_to_set_pmm(unsigned long value)
>  {
> +       unsigned long prev;
> +       bool ret;
> +
> +       prev = csr_read_clear(CSR_HENVCFG, ENVCFG_PMM);
>         csr_set(CSR_HENVCFG, value);
> -       return (csr_read_clear(CSR_HENVCFG, ENVCFG_PMM) & ENVCFG_PMM) == value;
> +       ret = (csr_read_clear(CSR_HENVCFG, ENVCFG_PMM) & ENVCFG_PMM) == value;
> +       csr_write(CSR_HENVCFG, prev);
> +
> +       return ret;
>  }
>
>  static bool kvm_sbi_fwft_pointer_masking_pmlen_supported(struct kvm_vcpu *vcpu)
>  {
> -       struct kvm_sbi_fwft *fwft = vcpu_to_fwft(vcpu);
> +       return riscv_isa_extension_available(vcpu->arch.isa, SMNPM);
> +}
>
> -       if (!riscv_isa_extension_available(vcpu->arch.isa, SMNPM))
> -               return false;
> +static bool kvm_sbi_fwft_pointer_masking_pmlen_init(struct kvm_vcpu *vcpu)
> +{
> +       struct kvm_sbi_fwft *fwft = vcpu_to_fwft(vcpu);
>
> +       preempt_disable();
>         fwft->have_vs_pmlen_7 = try_to_set_pmm(ENVCFG_PMM_PMLEN_7);
>         fwft->have_vs_pmlen_16 = try_to_set_pmm(ENVCFG_PMM_PMLEN_16);
> +       preempt_enable();
>
>         return fwft->have_vs_pmlen_7 || fwft->have_vs_pmlen_16;
>  }
> @@ -231,6 +252,7 @@ static const struct kvm_sbi_fwft_feature features[] = {
>                 .first_reg_num = offsetof(struct kvm_riscv_sbi_fwft, pointer_masking.enable) /
>                                  sizeof(unsigned long),
>                 .supported = kvm_sbi_fwft_pointer_masking_pmlen_supported,
> +               .init = kvm_sbi_fwft_pointer_masking_pmlen_init,
>                 .reset = kvm_sbi_fwft_reset_pointer_masking_pmlen,
>                 .set = kvm_sbi_fwft_set_pointer_masking_pmlen,
>                 .get = kvm_sbi_fwft_get_pointer_masking_pmlen,
> @@ -365,6 +387,9 @@ static int kvm_sbi_ext_fwft_init(struct kvm_vcpu *vcpu)
>                 else
>                         conf->supported = true;
>
> +               if (conf->supported && feature->init)
> +                       conf->supported = feature->init(vcpu);
> +
>                 conf->enabled = conf->supported;
>                 conf->feature = feature;
>         }
>
> --
> 2.43.7
>

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 2/5] KVM: RISC-V: SBI FWFT: Add optional init() callback for hardware probing
@ 2026-06-05 16:11     ` Anup Patel
  0 siblings, 0 replies; 40+ messages in thread
From: Anup Patel @ 2026-06-05 16:11 UTC (permalink / raw)
  To: Yong-Xuan Wang
  Cc: Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan, greentime.hu, vincent.chen, zong.li,
	kvm, kvm-riscv, linux-riscv, linux-kernel, linux-kselftest,
	inochiama

On Mon, Jun 1, 2026 at 3:56 PM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
>
> Add an optional init() callback to separate one-time hardware probing
> from runtime availability checks. For pointer masking, this allows
> probing supported PMM lengths during initialization while checking ISA
> extension availability at runtime.
>
> Fix try_to_set_pmm() to restore the previous HENVCFG.PMM value after
> probing, preventing side effects from hardware detection. Add preemption
> protection to ensure CSR probe sequences complete atomically on the same
> CPU.
>
> Fixes: 6f576fc0aeb9 ("RISC-V: KVM: Add support for SBI_FWFT_POINTER_MASKING_PMLEN")
>
> Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Thanks,
Anup

> ---
>  arch/riscv/kvm/vcpu_sbi_fwft.c | 33 +++++++++++++++++++++++++++++----
>  1 file changed, 29 insertions(+), 4 deletions(-)
>
> diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
> index 5e4aafb0cbf1..aee951f2b8e6 100644
> --- a/arch/riscv/kvm/vcpu_sbi_fwft.c
> +++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
> @@ -35,6 +35,16 @@ struct kvm_sbi_fwft_feature {
>          */
>         bool (*supported)(struct kvm_vcpu *vcpu);
>
> +       /**
> +        * @init: Probe and initialize the feature on the vcpu
> +        *
> +        * This callback is optional. If provided, it will be called during
> +        * vcpu initialization to probe the feature availability and perform
> +        * any necessary initialization. Returns true if the feature is supported
> +        * and initialized successfully, false otherwise.
> +        */
> +       bool (*init)(struct kvm_vcpu *vcpu);
> +
>         /**
>          * @reset: Reset the feature value irrespective whether feature is supported or not
>          *
> @@ -131,19 +141,30 @@ static long kvm_sbi_fwft_get_misaligned_delegation(struct kvm_vcpu *vcpu,
>
>  static bool try_to_set_pmm(unsigned long value)
>  {
> +       unsigned long prev;
> +       bool ret;
> +
> +       prev = csr_read_clear(CSR_HENVCFG, ENVCFG_PMM);
>         csr_set(CSR_HENVCFG, value);
> -       return (csr_read_clear(CSR_HENVCFG, ENVCFG_PMM) & ENVCFG_PMM) == value;
> +       ret = (csr_read_clear(CSR_HENVCFG, ENVCFG_PMM) & ENVCFG_PMM) == value;
> +       csr_write(CSR_HENVCFG, prev);
> +
> +       return ret;
>  }
>
>  static bool kvm_sbi_fwft_pointer_masking_pmlen_supported(struct kvm_vcpu *vcpu)
>  {
> -       struct kvm_sbi_fwft *fwft = vcpu_to_fwft(vcpu);
> +       return riscv_isa_extension_available(vcpu->arch.isa, SMNPM);
> +}
>
> -       if (!riscv_isa_extension_available(vcpu->arch.isa, SMNPM))
> -               return false;
> +static bool kvm_sbi_fwft_pointer_masking_pmlen_init(struct kvm_vcpu *vcpu)
> +{
> +       struct kvm_sbi_fwft *fwft = vcpu_to_fwft(vcpu);
>
> +       preempt_disable();
>         fwft->have_vs_pmlen_7 = try_to_set_pmm(ENVCFG_PMM_PMLEN_7);
>         fwft->have_vs_pmlen_16 = try_to_set_pmm(ENVCFG_PMM_PMLEN_16);
> +       preempt_enable();
>
>         return fwft->have_vs_pmlen_7 || fwft->have_vs_pmlen_16;
>  }
> @@ -231,6 +252,7 @@ static const struct kvm_sbi_fwft_feature features[] = {
>                 .first_reg_num = offsetof(struct kvm_riscv_sbi_fwft, pointer_masking.enable) /
>                                  sizeof(unsigned long),
>                 .supported = kvm_sbi_fwft_pointer_masking_pmlen_supported,
> +               .init = kvm_sbi_fwft_pointer_masking_pmlen_init,
>                 .reset = kvm_sbi_fwft_reset_pointer_masking_pmlen,
>                 .set = kvm_sbi_fwft_set_pointer_masking_pmlen,
>                 .get = kvm_sbi_fwft_get_pointer_masking_pmlen,
> @@ -365,6 +387,9 @@ static int kvm_sbi_ext_fwft_init(struct kvm_vcpu *vcpu)
>                 else
>                         conf->supported = true;
>
> +               if (conf->supported && feature->init)
> +                       conf->supported = feature->init(vcpu);
> +
>                 conf->enabled = conf->supported;
>                 conf->feature = feature;
>         }
>
> --
> 2.43.7
>

-- 
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 3/5] KVM: RISC-V: SBI FWFT: Fix stale feature exposure after runtime extension changes
  2026-06-01 10:26   ` Yong-Xuan Wang
  (?)
@ 2026-06-05 16:12     ` Anup Patel
  -1 siblings, 0 replies; 40+ messages in thread
From: Anup Patel @ 2026-06-05 16:12 UTC (permalink / raw)
  To: Yong-Xuan Wang
  Cc: Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan, greentime.hu, vincent.chen, zong.li,
	kvm, kvm-riscv, linux-riscv, linux-kernel, linux-kselftest,
	inochiama

On Mon, Jun 1, 2026 at 3:56 PM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
>
> Fix a bug where FWFT features could be incorrectly exposed to guests
> after userspace disables their dependent ISA extensions at runtime.
>
> The 'supported' field in kvm_sbi_fwft_config was set once during vCPU
> initialization based on the initial hardware/extension availability.
> However, when userspace subsequently disables ISA extensions via the KVM
> ONE_REG interface, the 'supported' field was not updated. This caused
> the following issues:
> 1. FWFT features would remain visible and accessible to guests even
>    after their prerequisite ISA extensions were disabled
> 2. Guests could configure FWFT features that depend on disabled
>    extensions, leading to undefined behavior
> 3. The static 'supported' flag and the dynamic supported() callback
>    could disagree about feature availability
>
> The fix introduces a two-layer checking mechanism:
> 1. Add an optional init() callback to the kvm_sbi_fwft_feature structure
>    for features that require hardware probing during initialization. This
>    separates the one-time hardware detection logic from the runtime
>    availability check.
> 2. Add runtime checks in all FWFT-related functions that call
>    feature->supported(vcpu) if the callback exists. This ensures feature
>    availability is re-evaluated based on the current ISA extension state.
>
> This approach maintains the cached 'supported' field for initialization-
> time decisions while ensuring runtime availability is always determined
> by the current vCPU configuration, not initialization-time snapshots.
>
> Fixes: 6b72fd170592 ("RISC-V: KVM: add support for FWFT SBI extension")
>
> Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Thanks,
Anup

> ---
>  arch/riscv/kvm/vcpu_sbi_fwft.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
>
> diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
> index aee951f2b8e6..ab39ac464ffd 100644
> --- a/arch/riscv/kvm/vcpu_sbi_fwft.c
> +++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
> @@ -303,6 +303,8 @@ static int kvm_fwft_get_feature(struct kvm_vcpu *vcpu, u32 feature,
>
>         if (!tconf->supported || !tconf->enabled)
>                 return SBI_ERR_NOT_SUPPORTED;
> +       else if (tconf->feature->supported && !tconf->feature->supported(vcpu))
> +               return SBI_ERR_NOT_SUPPORTED;
>
>         *conf = tconf;
>
> @@ -433,6 +435,8 @@ static unsigned long kvm_sbi_ext_fwft_get_reg_count(struct kvm_vcpu *vcpu)
>                 conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
>                 if (!conf || !conf->supported)
>                         continue;
> +               else if (conf->feature->supported && !conf->feature->supported(vcpu))
> +                       continue;
>
>                 ret++;
>         }
> @@ -455,6 +459,8 @@ static int kvm_sbi_ext_fwft_get_reg_id(struct kvm_vcpu *vcpu, int index, u64 *re
>                 conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
>                 if (!conf || !conf->supported)
>                         continue;
> +               else if (conf->feature->supported && !conf->feature->supported(vcpu))
> +                       continue;
>
>                 if (index == idx) {
>                         *reg_id = KVM_REG_RISCV |
> @@ -490,6 +496,8 @@ static int kvm_sbi_ext_fwft_get_reg(struct kvm_vcpu *vcpu, unsigned long reg_num
>         conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
>         if (!conf || !conf->supported)
>                 return -ENOENT;
> +       else if (conf->feature->supported && !conf->feature->supported(vcpu))
> +               return -ENOENT;
>
>         switch (reg_num - feature->first_reg_num) {
>         case 0:
> @@ -527,6 +535,8 @@ static int kvm_sbi_ext_fwft_set_reg(struct kvm_vcpu *vcpu, unsigned long reg_num
>         conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
>         if (!conf || !conf->supported)
>                 return -ENOENT;
> +       else if (conf->feature->supported && !conf->feature->supported(vcpu))
> +               return -ENOENT;
>
>         switch (reg_num - feature->first_reg_num) {
>         case 0:
>
> --
> 2.43.7
>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 3/5] KVM: RISC-V: SBI FWFT: Fix stale feature exposure after runtime extension changes
@ 2026-06-05 16:12     ` Anup Patel
  0 siblings, 0 replies; 40+ messages in thread
From: Anup Patel @ 2026-06-05 16:12 UTC (permalink / raw)
  To: Yong-Xuan Wang
  Cc: Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan, greentime.hu, vincent.chen, zong.li,
	kvm, kvm-riscv, linux-riscv, linux-kernel, linux-kselftest,
	inochiama

On Mon, Jun 1, 2026 at 3:56 PM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
>
> Fix a bug where FWFT features could be incorrectly exposed to guests
> after userspace disables their dependent ISA extensions at runtime.
>
> The 'supported' field in kvm_sbi_fwft_config was set once during vCPU
> initialization based on the initial hardware/extension availability.
> However, when userspace subsequently disables ISA extensions via the KVM
> ONE_REG interface, the 'supported' field was not updated. This caused
> the following issues:
> 1. FWFT features would remain visible and accessible to guests even
>    after their prerequisite ISA extensions were disabled
> 2. Guests could configure FWFT features that depend on disabled
>    extensions, leading to undefined behavior
> 3. The static 'supported' flag and the dynamic supported() callback
>    could disagree about feature availability
>
> The fix introduces a two-layer checking mechanism:
> 1. Add an optional init() callback to the kvm_sbi_fwft_feature structure
>    for features that require hardware probing during initialization. This
>    separates the one-time hardware detection logic from the runtime
>    availability check.
> 2. Add runtime checks in all FWFT-related functions that call
>    feature->supported(vcpu) if the callback exists. This ensures feature
>    availability is re-evaluated based on the current ISA extension state.
>
> This approach maintains the cached 'supported' field for initialization-
> time decisions while ensuring runtime availability is always determined
> by the current vCPU configuration, not initialization-time snapshots.
>
> Fixes: 6b72fd170592 ("RISC-V: KVM: add support for FWFT SBI extension")
>
> Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Thanks,
Anup

> ---
>  arch/riscv/kvm/vcpu_sbi_fwft.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
>
> diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
> index aee951f2b8e6..ab39ac464ffd 100644
> --- a/arch/riscv/kvm/vcpu_sbi_fwft.c
> +++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
> @@ -303,6 +303,8 @@ static int kvm_fwft_get_feature(struct kvm_vcpu *vcpu, u32 feature,
>
>         if (!tconf->supported || !tconf->enabled)
>                 return SBI_ERR_NOT_SUPPORTED;
> +       else if (tconf->feature->supported && !tconf->feature->supported(vcpu))
> +               return SBI_ERR_NOT_SUPPORTED;
>
>         *conf = tconf;
>
> @@ -433,6 +435,8 @@ static unsigned long kvm_sbi_ext_fwft_get_reg_count(struct kvm_vcpu *vcpu)
>                 conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
>                 if (!conf || !conf->supported)
>                         continue;
> +               else if (conf->feature->supported && !conf->feature->supported(vcpu))
> +                       continue;
>
>                 ret++;
>         }
> @@ -455,6 +459,8 @@ static int kvm_sbi_ext_fwft_get_reg_id(struct kvm_vcpu *vcpu, int index, u64 *re
>                 conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
>                 if (!conf || !conf->supported)
>                         continue;
> +               else if (conf->feature->supported && !conf->feature->supported(vcpu))
> +                       continue;
>
>                 if (index == idx) {
>                         *reg_id = KVM_REG_RISCV |
> @@ -490,6 +496,8 @@ static int kvm_sbi_ext_fwft_get_reg(struct kvm_vcpu *vcpu, unsigned long reg_num
>         conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
>         if (!conf || !conf->supported)
>                 return -ENOENT;
> +       else if (conf->feature->supported && !conf->feature->supported(vcpu))
> +               return -ENOENT;
>
>         switch (reg_num - feature->first_reg_num) {
>         case 0:
> @@ -527,6 +535,8 @@ static int kvm_sbi_ext_fwft_set_reg(struct kvm_vcpu *vcpu, unsigned long reg_num
>         conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
>         if (!conf || !conf->supported)
>                 return -ENOENT;
> +       else if (conf->feature->supported && !conf->feature->supported(vcpu))
> +               return -ENOENT;
>
>         switch (reg_num - feature->first_reg_num) {
>         case 0:
>
> --
> 2.43.7
>

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 3/5] KVM: RISC-V: SBI FWFT: Fix stale feature exposure after runtime extension changes
@ 2026-06-05 16:12     ` Anup Patel
  0 siblings, 0 replies; 40+ messages in thread
From: Anup Patel @ 2026-06-05 16:12 UTC (permalink / raw)
  To: Yong-Xuan Wang
  Cc: Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan, greentime.hu, vincent.chen, zong.li,
	kvm, kvm-riscv, linux-riscv, linux-kernel, linux-kselftest,
	inochiama

On Mon, Jun 1, 2026 at 3:56 PM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
>
> Fix a bug where FWFT features could be incorrectly exposed to guests
> after userspace disables their dependent ISA extensions at runtime.
>
> The 'supported' field in kvm_sbi_fwft_config was set once during vCPU
> initialization based on the initial hardware/extension availability.
> However, when userspace subsequently disables ISA extensions via the KVM
> ONE_REG interface, the 'supported' field was not updated. This caused
> the following issues:
> 1. FWFT features would remain visible and accessible to guests even
>    after their prerequisite ISA extensions were disabled
> 2. Guests could configure FWFT features that depend on disabled
>    extensions, leading to undefined behavior
> 3. The static 'supported' flag and the dynamic supported() callback
>    could disagree about feature availability
>
> The fix introduces a two-layer checking mechanism:
> 1. Add an optional init() callback to the kvm_sbi_fwft_feature structure
>    for features that require hardware probing during initialization. This
>    separates the one-time hardware detection logic from the runtime
>    availability check.
> 2. Add runtime checks in all FWFT-related functions that call
>    feature->supported(vcpu) if the callback exists. This ensures feature
>    availability is re-evaluated based on the current ISA extension state.
>
> This approach maintains the cached 'supported' field for initialization-
> time decisions while ensuring runtime availability is always determined
> by the current vCPU configuration, not initialization-time snapshots.
>
> Fixes: 6b72fd170592 ("RISC-V: KVM: add support for FWFT SBI extension")
>
> Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Thanks,
Anup

> ---
>  arch/riscv/kvm/vcpu_sbi_fwft.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
>
> diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
> index aee951f2b8e6..ab39ac464ffd 100644
> --- a/arch/riscv/kvm/vcpu_sbi_fwft.c
> +++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
> @@ -303,6 +303,8 @@ static int kvm_fwft_get_feature(struct kvm_vcpu *vcpu, u32 feature,
>
>         if (!tconf->supported || !tconf->enabled)
>                 return SBI_ERR_NOT_SUPPORTED;
> +       else if (tconf->feature->supported && !tconf->feature->supported(vcpu))
> +               return SBI_ERR_NOT_SUPPORTED;
>
>         *conf = tconf;
>
> @@ -433,6 +435,8 @@ static unsigned long kvm_sbi_ext_fwft_get_reg_count(struct kvm_vcpu *vcpu)
>                 conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
>                 if (!conf || !conf->supported)
>                         continue;
> +               else if (conf->feature->supported && !conf->feature->supported(vcpu))
> +                       continue;
>
>                 ret++;
>         }
> @@ -455,6 +459,8 @@ static int kvm_sbi_ext_fwft_get_reg_id(struct kvm_vcpu *vcpu, int index, u64 *re
>                 conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
>                 if (!conf || !conf->supported)
>                         continue;
> +               else if (conf->feature->supported && !conf->feature->supported(vcpu))
> +                       continue;
>
>                 if (index == idx) {
>                         *reg_id = KVM_REG_RISCV |
> @@ -490,6 +496,8 @@ static int kvm_sbi_ext_fwft_get_reg(struct kvm_vcpu *vcpu, unsigned long reg_num
>         conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
>         if (!conf || !conf->supported)
>                 return -ENOENT;
> +       else if (conf->feature->supported && !conf->feature->supported(vcpu))
> +               return -ENOENT;
>
>         switch (reg_num - feature->first_reg_num) {
>         case 0:
> @@ -527,6 +535,8 @@ static int kvm_sbi_ext_fwft_set_reg(struct kvm_vcpu *vcpu, unsigned long reg_num
>         conf = kvm_sbi_fwft_get_config(vcpu, feature->id);
>         if (!conf || !conf->supported)
>                 return -ENOENT;
> +       else if (conf->feature->supported && !conf->feature->supported(vcpu))
> +               return -ENOENT;
>
>         switch (reg_num - feature->first_reg_num) {
>         case 0:
>
> --
> 2.43.7
>

-- 
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 4/5] KVM: riscv: selftests: Refactor ISA and SBI extension sublist macros
  2026-06-01 10:26   ` Yong-Xuan Wang
  (?)
@ 2026-06-05 16:13     ` Anup Patel
  -1 siblings, 0 replies; 40+ messages in thread
From: Anup Patel @ 2026-06-05 16:13 UTC (permalink / raw)
  To: Yong-Xuan Wang
  Cc: Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan, greentime.hu, vincent.chen, zong.li,
	kvm, kvm-riscv, linux-riscv, linux-kernel, linux-kselftest,
	inochiama

On Mon, Jun 1, 2026 at 3:56 PM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
>
> Refactor the get-reg-list test to use unified sublist macros for ISA
> and SBI extensions, eliminating code duplication and improving
> maintainability.
>
> Previously, each extension had its own hand-coded sublist definition
> (e.g., SUBLIST_ZICBOM, SUBLIST_AIA, etc.) and the config structures
> repeated the same pattern. This made the code verbose and error-prone.
>
> Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Thanks,
Anup

> ---
>  tools/testing/selftests/kvm/riscv/get-reg-list.c | 78 +++++++++---------------
>  1 file changed, 28 insertions(+), 50 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> index 8d6fdb5d38b8..5033c09201ef 100644
> --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
> +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> @@ -1013,7 +1013,7 @@ static __u64 fp_d_regs[] = {
>  };
>
>  /* Define a default vector registers with length. This will be overwritten at runtime */
> -static __u64 vector_regs[] = {
> +static __u64 v_regs[] = {
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vstart),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vl),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vtype),
> @@ -1057,37 +1057,17 @@ static __u64 vector_regs[] = {
>  #define SUBLIST_BASE \
>         {"base", .regs = base_regs, .regs_n = ARRAY_SIZE(base_regs), \
>          .skips_set = base_skips_set, .skips_set_n = ARRAY_SIZE(base_skips_set),}
> -#define SUBLIST_SBI_BASE \
> -       {"sbi-base", .feature_type = VCPU_FEATURE_SBI_EXT, .feature = KVM_RISCV_SBI_EXT_V01, \
> -        .regs = sbi_base_regs, .regs_n = ARRAY_SIZE(sbi_base_regs),}
> -#define SUBLIST_SBI_STA \
> -       {"sbi-sta", .feature_type = VCPU_FEATURE_SBI_EXT, .feature = KVM_RISCV_SBI_EXT_STA, \
> -        .regs = sbi_sta_regs, .regs_n = ARRAY_SIZE(sbi_sta_regs),}
> -#define SUBLIST_SBI_FWFT \
> -       {"sbi-fwft", .feature_type = VCPU_FEATURE_SBI_EXT, .feature = KVM_RISCV_SBI_EXT_FWFT, \
> -        .regs = sbi_fwft_regs, .regs_n = ARRAY_SIZE(sbi_fwft_regs),}
> -#define SUBLIST_ZICBOM \
> -       {"zicbom", .feature = KVM_RISCV_ISA_EXT_ZICBOM, .regs = zicbom_regs, .regs_n = ARRAY_SIZE(zicbom_regs),}
> -#define SUBLIST_ZICBOP \
> -       {"zicbop", .feature = KVM_RISCV_ISA_EXT_ZICBOP, .regs = zicbop_regs, .regs_n = ARRAY_SIZE(zicbop_regs),}
> -#define SUBLIST_ZICBOZ \
> -       {"zicboz", .feature = KVM_RISCV_ISA_EXT_ZICBOZ, .regs = zicboz_regs, .regs_n = ARRAY_SIZE(zicboz_regs),}
> -#define SUBLIST_AIA \
> -       {"aia", .feature = KVM_RISCV_ISA_EXT_SSAIA, .regs = aia_regs, .regs_n = ARRAY_SIZE(aia_regs),}
> -#define SUBLIST_SMSTATEEN \
> -       {"smstateen", .feature = KVM_RISCV_ISA_EXT_SMSTATEEN, .regs = smstateen_regs, .regs_n = ARRAY_SIZE(smstateen_regs),}
> -#define SUBLIST_FP_F \
> -       {"fp_f", .feature = KVM_RISCV_ISA_EXT_F, .regs = fp_f_regs, \
> -               .regs_n = ARRAY_SIZE(fp_f_regs),}
> -#define SUBLIST_FP_D \
> -       {"fp_d", .feature = KVM_RISCV_ISA_EXT_D, .regs = fp_d_regs, \
> -               .regs_n = ARRAY_SIZE(fp_d_regs),}
> -
> -#define SUBLIST_V \
> -       {"v", .feature = KVM_RISCV_ISA_EXT_V, .regs = vector_regs, .regs_n = ARRAY_SIZE(vector_regs),}
> +
> +#define SUBLIST_ISA(ext, extu)                         \
> +       {                                               \
> +               .name = #ext,                           \
> +               .feature = KVM_RISCV_ISA_EXT_##extu,    \
> +               .regs = ext##_regs,                     \
> +               .regs_n = ARRAY_SIZE(ext##_regs),       \
> +       }
>
>  #define KVM_ISA_EXT_SIMPLE_CONFIG(ext, extu)                   \
> -static __u64 regs_##ext[] = {                                  \
> +static __u64 ext##_regs[] = {                                  \
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG |                    \
>         KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE |      \
>         KVM_RISCV_ISA_EXT_##extu,                               \
> @@ -1095,18 +1075,22 @@ static __u64 regs_##ext[] = {                                   \
>  static struct vcpu_reg_list config_##ext = {                   \
>         .sublists = {                                           \
>                 SUBLIST_BASE,                                   \
> -               {                                               \
> -                       .name = #ext,                           \
> -                       .feature = KVM_RISCV_ISA_EXT_##extu,    \
> -                       .regs = regs_##ext,                     \
> -                       .regs_n = ARRAY_SIZE(regs_##ext),       \
> -               },                                              \
> +               SUBLIST_ISA(ext, extu),                         \
>                 {0},                                            \
>         },                                                      \
>  }                                                              \
>
> +#define SUBLIST_SBI(ext, extu)                                 \
> +       {                                                       \
> +               .name = "sbi-"#ext,                             \
> +               .feature_type = VCPU_FEATURE_SBI_EXT,           \
> +               .feature = KVM_RISCV_SBI_EXT_##extu,            \
> +               .regs = sbi_##ext##_regs,                       \
> +               .regs_n = ARRAY_SIZE(sbi_##ext##_regs),         \
> +       }
> +
>  #define KVM_SBI_EXT_SIMPLE_CONFIG(ext, extu)                   \
> -static __u64 regs_sbi_##ext[] = {                              \
> +static __u64 sbi_##ext##_regs[] = {                            \
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG |                    \
>         KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE |      \
>         KVM_RISCV_SBI_EXT_##extu,                               \
> @@ -1114,13 +1098,7 @@ static __u64 regs_sbi_##ext[] = {                                \
>  static struct vcpu_reg_list config_sbi_##ext = {               \
>         .sublists = {                                           \
>                 SUBLIST_BASE,                                   \
> -               {                                               \
> -                       .name = "sbi-"#ext,                     \
> -                       .feature_type = VCPU_FEATURE_SBI_EXT,   \
> -                       .feature = KVM_RISCV_SBI_EXT_##extu,    \
> -                       .regs = regs_sbi_##ext,                 \
> -                       .regs_n = ARRAY_SIZE(regs_sbi_##ext),   \
> -               },                                              \
> +               SUBLIST_SBI(ext, extu),                         \
>                 {0},                                            \
>         },                                                      \
>  }                                                              \
> @@ -1129,7 +1107,7 @@ static struct vcpu_reg_list config_sbi_##ext = {          \
>  static struct vcpu_reg_list config_##ext = {                   \
>         .sublists = {                                           \
>                 SUBLIST_BASE,                                   \
> -               SUBLIST_##extu,                                 \
> +               SUBLIST_ISA(ext, extu),                         \
>                 {0},                                            \
>         },                                                      \
>  }                                                              \
> @@ -1138,14 +1116,14 @@ static struct vcpu_reg_list config_##ext = {                    \
>  static struct vcpu_reg_list config_sbi_##ext = {               \
>         .sublists = {                                           \
>                 SUBLIST_BASE,                                   \
> -               SUBLIST_SBI_##extu,                             \
> +               SUBLIST_SBI(ext, extu),                         \
>                 {0},                                            \
>         },                                                      \
>  }                                                              \
>
>  /* Note: The below list is alphabetically sorted. */
>
> -KVM_SBI_EXT_SUBLIST_CONFIG(base, BASE);
> +KVM_SBI_EXT_SUBLIST_CONFIG(base, V01);
>  KVM_SBI_EXT_SUBLIST_CONFIG(sta, STA);
>  KVM_SBI_EXT_SIMPLE_CONFIG(pmu, PMU);
>  KVM_SBI_EXT_SIMPLE_CONFIG(dbcn, DBCN);
> @@ -1153,9 +1131,9 @@ KVM_SBI_EXT_SIMPLE_CONFIG(susp, SUSP);
>  KVM_SBI_EXT_SIMPLE_CONFIG(mpxy, MPXY);
>  KVM_SBI_EXT_SUBLIST_CONFIG(fwft, FWFT);
>
> -KVM_ISA_EXT_SUBLIST_CONFIG(aia, AIA);
> -KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, FP_F);
> -KVM_ISA_EXT_SUBLIST_CONFIG(fp_d, FP_D);
> +KVM_ISA_EXT_SUBLIST_CONFIG(aia, SSAIA);
> +KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, F);
> +KVM_ISA_EXT_SUBLIST_CONFIG(fp_d, D);
>  KVM_ISA_EXT_SUBLIST_CONFIG(v, V);
>  KVM_ISA_EXT_SIMPLE_CONFIG(h, H);
>  KVM_ISA_EXT_SIMPLE_CONFIG(smnpm, SMNPM);
>
> --
> 2.43.7
>

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 4/5] KVM: riscv: selftests: Refactor ISA and SBI extension sublist macros
@ 2026-06-05 16:13     ` Anup Patel
  0 siblings, 0 replies; 40+ messages in thread
From: Anup Patel @ 2026-06-05 16:13 UTC (permalink / raw)
  To: Yong-Xuan Wang
  Cc: Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan, greentime.hu, vincent.chen, zong.li,
	kvm, kvm-riscv, linux-riscv, linux-kernel, linux-kselftest,
	inochiama

On Mon, Jun 1, 2026 at 3:56 PM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
>
> Refactor the get-reg-list test to use unified sublist macros for ISA
> and SBI extensions, eliminating code duplication and improving
> maintainability.
>
> Previously, each extension had its own hand-coded sublist definition
> (e.g., SUBLIST_ZICBOM, SUBLIST_AIA, etc.) and the config structures
> repeated the same pattern. This made the code verbose and error-prone.
>
> Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Thanks,
Anup

> ---
>  tools/testing/selftests/kvm/riscv/get-reg-list.c | 78 +++++++++---------------
>  1 file changed, 28 insertions(+), 50 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> index 8d6fdb5d38b8..5033c09201ef 100644
> --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
> +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> @@ -1013,7 +1013,7 @@ static __u64 fp_d_regs[] = {
>  };
>
>  /* Define a default vector registers with length. This will be overwritten at runtime */
> -static __u64 vector_regs[] = {
> +static __u64 v_regs[] = {
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vstart),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vl),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vtype),
> @@ -1057,37 +1057,17 @@ static __u64 vector_regs[] = {
>  #define SUBLIST_BASE \
>         {"base", .regs = base_regs, .regs_n = ARRAY_SIZE(base_regs), \
>          .skips_set = base_skips_set, .skips_set_n = ARRAY_SIZE(base_skips_set),}
> -#define SUBLIST_SBI_BASE \
> -       {"sbi-base", .feature_type = VCPU_FEATURE_SBI_EXT, .feature = KVM_RISCV_SBI_EXT_V01, \
> -        .regs = sbi_base_regs, .regs_n = ARRAY_SIZE(sbi_base_regs),}
> -#define SUBLIST_SBI_STA \
> -       {"sbi-sta", .feature_type = VCPU_FEATURE_SBI_EXT, .feature = KVM_RISCV_SBI_EXT_STA, \
> -        .regs = sbi_sta_regs, .regs_n = ARRAY_SIZE(sbi_sta_regs),}
> -#define SUBLIST_SBI_FWFT \
> -       {"sbi-fwft", .feature_type = VCPU_FEATURE_SBI_EXT, .feature = KVM_RISCV_SBI_EXT_FWFT, \
> -        .regs = sbi_fwft_regs, .regs_n = ARRAY_SIZE(sbi_fwft_regs),}
> -#define SUBLIST_ZICBOM \
> -       {"zicbom", .feature = KVM_RISCV_ISA_EXT_ZICBOM, .regs = zicbom_regs, .regs_n = ARRAY_SIZE(zicbom_regs),}
> -#define SUBLIST_ZICBOP \
> -       {"zicbop", .feature = KVM_RISCV_ISA_EXT_ZICBOP, .regs = zicbop_regs, .regs_n = ARRAY_SIZE(zicbop_regs),}
> -#define SUBLIST_ZICBOZ \
> -       {"zicboz", .feature = KVM_RISCV_ISA_EXT_ZICBOZ, .regs = zicboz_regs, .regs_n = ARRAY_SIZE(zicboz_regs),}
> -#define SUBLIST_AIA \
> -       {"aia", .feature = KVM_RISCV_ISA_EXT_SSAIA, .regs = aia_regs, .regs_n = ARRAY_SIZE(aia_regs),}
> -#define SUBLIST_SMSTATEEN \
> -       {"smstateen", .feature = KVM_RISCV_ISA_EXT_SMSTATEEN, .regs = smstateen_regs, .regs_n = ARRAY_SIZE(smstateen_regs),}
> -#define SUBLIST_FP_F \
> -       {"fp_f", .feature = KVM_RISCV_ISA_EXT_F, .regs = fp_f_regs, \
> -               .regs_n = ARRAY_SIZE(fp_f_regs),}
> -#define SUBLIST_FP_D \
> -       {"fp_d", .feature = KVM_RISCV_ISA_EXT_D, .regs = fp_d_regs, \
> -               .regs_n = ARRAY_SIZE(fp_d_regs),}
> -
> -#define SUBLIST_V \
> -       {"v", .feature = KVM_RISCV_ISA_EXT_V, .regs = vector_regs, .regs_n = ARRAY_SIZE(vector_regs),}
> +
> +#define SUBLIST_ISA(ext, extu)                         \
> +       {                                               \
> +               .name = #ext,                           \
> +               .feature = KVM_RISCV_ISA_EXT_##extu,    \
> +               .regs = ext##_regs,                     \
> +               .regs_n = ARRAY_SIZE(ext##_regs),       \
> +       }
>
>  #define KVM_ISA_EXT_SIMPLE_CONFIG(ext, extu)                   \
> -static __u64 regs_##ext[] = {                                  \
> +static __u64 ext##_regs[] = {                                  \
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG |                    \
>         KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE |      \
>         KVM_RISCV_ISA_EXT_##extu,                               \
> @@ -1095,18 +1075,22 @@ static __u64 regs_##ext[] = {                                   \
>  static struct vcpu_reg_list config_##ext = {                   \
>         .sublists = {                                           \
>                 SUBLIST_BASE,                                   \
> -               {                                               \
> -                       .name = #ext,                           \
> -                       .feature = KVM_RISCV_ISA_EXT_##extu,    \
> -                       .regs = regs_##ext,                     \
> -                       .regs_n = ARRAY_SIZE(regs_##ext),       \
> -               },                                              \
> +               SUBLIST_ISA(ext, extu),                         \
>                 {0},                                            \
>         },                                                      \
>  }                                                              \
>
> +#define SUBLIST_SBI(ext, extu)                                 \
> +       {                                                       \
> +               .name = "sbi-"#ext,                             \
> +               .feature_type = VCPU_FEATURE_SBI_EXT,           \
> +               .feature = KVM_RISCV_SBI_EXT_##extu,            \
> +               .regs = sbi_##ext##_regs,                       \
> +               .regs_n = ARRAY_SIZE(sbi_##ext##_regs),         \
> +       }
> +
>  #define KVM_SBI_EXT_SIMPLE_CONFIG(ext, extu)                   \
> -static __u64 regs_sbi_##ext[] = {                              \
> +static __u64 sbi_##ext##_regs[] = {                            \
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG |                    \
>         KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE |      \
>         KVM_RISCV_SBI_EXT_##extu,                               \
> @@ -1114,13 +1098,7 @@ static __u64 regs_sbi_##ext[] = {                                \
>  static struct vcpu_reg_list config_sbi_##ext = {               \
>         .sublists = {                                           \
>                 SUBLIST_BASE,                                   \
> -               {                                               \
> -                       .name = "sbi-"#ext,                     \
> -                       .feature_type = VCPU_FEATURE_SBI_EXT,   \
> -                       .feature = KVM_RISCV_SBI_EXT_##extu,    \
> -                       .regs = regs_sbi_##ext,                 \
> -                       .regs_n = ARRAY_SIZE(regs_sbi_##ext),   \
> -               },                                              \
> +               SUBLIST_SBI(ext, extu),                         \
>                 {0},                                            \
>         },                                                      \
>  }                                                              \
> @@ -1129,7 +1107,7 @@ static struct vcpu_reg_list config_sbi_##ext = {          \
>  static struct vcpu_reg_list config_##ext = {                   \
>         .sublists = {                                           \
>                 SUBLIST_BASE,                                   \
> -               SUBLIST_##extu,                                 \
> +               SUBLIST_ISA(ext, extu),                         \
>                 {0},                                            \
>         },                                                      \
>  }                                                              \
> @@ -1138,14 +1116,14 @@ static struct vcpu_reg_list config_##ext = {                    \
>  static struct vcpu_reg_list config_sbi_##ext = {               \
>         .sublists = {                                           \
>                 SUBLIST_BASE,                                   \
> -               SUBLIST_SBI_##extu,                             \
> +               SUBLIST_SBI(ext, extu),                         \
>                 {0},                                            \
>         },                                                      \
>  }                                                              \
>
>  /* Note: The below list is alphabetically sorted. */
>
> -KVM_SBI_EXT_SUBLIST_CONFIG(base, BASE);
> +KVM_SBI_EXT_SUBLIST_CONFIG(base, V01);
>  KVM_SBI_EXT_SUBLIST_CONFIG(sta, STA);
>  KVM_SBI_EXT_SIMPLE_CONFIG(pmu, PMU);
>  KVM_SBI_EXT_SIMPLE_CONFIG(dbcn, DBCN);
> @@ -1153,9 +1131,9 @@ KVM_SBI_EXT_SIMPLE_CONFIG(susp, SUSP);
>  KVM_SBI_EXT_SIMPLE_CONFIG(mpxy, MPXY);
>  KVM_SBI_EXT_SUBLIST_CONFIG(fwft, FWFT);
>
> -KVM_ISA_EXT_SUBLIST_CONFIG(aia, AIA);
> -KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, FP_F);
> -KVM_ISA_EXT_SUBLIST_CONFIG(fp_d, FP_D);
> +KVM_ISA_EXT_SUBLIST_CONFIG(aia, SSAIA);
> +KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, F);
> +KVM_ISA_EXT_SUBLIST_CONFIG(fp_d, D);
>  KVM_ISA_EXT_SUBLIST_CONFIG(v, V);
>  KVM_ISA_EXT_SIMPLE_CONFIG(h, H);
>  KVM_ISA_EXT_SIMPLE_CONFIG(smnpm, SMNPM);
>
> --
> 2.43.7
>

-- 
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 4/5] KVM: riscv: selftests: Refactor ISA and SBI extension sublist macros
@ 2026-06-05 16:13     ` Anup Patel
  0 siblings, 0 replies; 40+ messages in thread
From: Anup Patel @ 2026-06-05 16:13 UTC (permalink / raw)
  To: Yong-Xuan Wang
  Cc: Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan, greentime.hu, vincent.chen, zong.li,
	kvm, kvm-riscv, linux-riscv, linux-kernel, linux-kselftest,
	inochiama

On Mon, Jun 1, 2026 at 3:56 PM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
>
> Refactor the get-reg-list test to use unified sublist macros for ISA
> and SBI extensions, eliminating code duplication and improving
> maintainability.
>
> Previously, each extension had its own hand-coded sublist definition
> (e.g., SUBLIST_ZICBOM, SUBLIST_AIA, etc.) and the config structures
> repeated the same pattern. This made the code verbose and error-prone.
>
> Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Thanks,
Anup

> ---
>  tools/testing/selftests/kvm/riscv/get-reg-list.c | 78 +++++++++---------------
>  1 file changed, 28 insertions(+), 50 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> index 8d6fdb5d38b8..5033c09201ef 100644
> --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
> +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> @@ -1013,7 +1013,7 @@ static __u64 fp_d_regs[] = {
>  };
>
>  /* Define a default vector registers with length. This will be overwritten at runtime */
> -static __u64 vector_regs[] = {
> +static __u64 v_regs[] = {
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vstart),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vl),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vtype),
> @@ -1057,37 +1057,17 @@ static __u64 vector_regs[] = {
>  #define SUBLIST_BASE \
>         {"base", .regs = base_regs, .regs_n = ARRAY_SIZE(base_regs), \
>          .skips_set = base_skips_set, .skips_set_n = ARRAY_SIZE(base_skips_set),}
> -#define SUBLIST_SBI_BASE \
> -       {"sbi-base", .feature_type = VCPU_FEATURE_SBI_EXT, .feature = KVM_RISCV_SBI_EXT_V01, \
> -        .regs = sbi_base_regs, .regs_n = ARRAY_SIZE(sbi_base_regs),}
> -#define SUBLIST_SBI_STA \
> -       {"sbi-sta", .feature_type = VCPU_FEATURE_SBI_EXT, .feature = KVM_RISCV_SBI_EXT_STA, \
> -        .regs = sbi_sta_regs, .regs_n = ARRAY_SIZE(sbi_sta_regs),}
> -#define SUBLIST_SBI_FWFT \
> -       {"sbi-fwft", .feature_type = VCPU_FEATURE_SBI_EXT, .feature = KVM_RISCV_SBI_EXT_FWFT, \
> -        .regs = sbi_fwft_regs, .regs_n = ARRAY_SIZE(sbi_fwft_regs),}
> -#define SUBLIST_ZICBOM \
> -       {"zicbom", .feature = KVM_RISCV_ISA_EXT_ZICBOM, .regs = zicbom_regs, .regs_n = ARRAY_SIZE(zicbom_regs),}
> -#define SUBLIST_ZICBOP \
> -       {"zicbop", .feature = KVM_RISCV_ISA_EXT_ZICBOP, .regs = zicbop_regs, .regs_n = ARRAY_SIZE(zicbop_regs),}
> -#define SUBLIST_ZICBOZ \
> -       {"zicboz", .feature = KVM_RISCV_ISA_EXT_ZICBOZ, .regs = zicboz_regs, .regs_n = ARRAY_SIZE(zicboz_regs),}
> -#define SUBLIST_AIA \
> -       {"aia", .feature = KVM_RISCV_ISA_EXT_SSAIA, .regs = aia_regs, .regs_n = ARRAY_SIZE(aia_regs),}
> -#define SUBLIST_SMSTATEEN \
> -       {"smstateen", .feature = KVM_RISCV_ISA_EXT_SMSTATEEN, .regs = smstateen_regs, .regs_n = ARRAY_SIZE(smstateen_regs),}
> -#define SUBLIST_FP_F \
> -       {"fp_f", .feature = KVM_RISCV_ISA_EXT_F, .regs = fp_f_regs, \
> -               .regs_n = ARRAY_SIZE(fp_f_regs),}
> -#define SUBLIST_FP_D \
> -       {"fp_d", .feature = KVM_RISCV_ISA_EXT_D, .regs = fp_d_regs, \
> -               .regs_n = ARRAY_SIZE(fp_d_regs),}
> -
> -#define SUBLIST_V \
> -       {"v", .feature = KVM_RISCV_ISA_EXT_V, .regs = vector_regs, .regs_n = ARRAY_SIZE(vector_regs),}
> +
> +#define SUBLIST_ISA(ext, extu)                         \
> +       {                                               \
> +               .name = #ext,                           \
> +               .feature = KVM_RISCV_ISA_EXT_##extu,    \
> +               .regs = ext##_regs,                     \
> +               .regs_n = ARRAY_SIZE(ext##_regs),       \
> +       }
>
>  #define KVM_ISA_EXT_SIMPLE_CONFIG(ext, extu)                   \
> -static __u64 regs_##ext[] = {                                  \
> +static __u64 ext##_regs[] = {                                  \
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG |                    \
>         KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE |      \
>         KVM_RISCV_ISA_EXT_##extu,                               \
> @@ -1095,18 +1075,22 @@ static __u64 regs_##ext[] = {                                   \
>  static struct vcpu_reg_list config_##ext = {                   \
>         .sublists = {                                           \
>                 SUBLIST_BASE,                                   \
> -               {                                               \
> -                       .name = #ext,                           \
> -                       .feature = KVM_RISCV_ISA_EXT_##extu,    \
> -                       .regs = regs_##ext,                     \
> -                       .regs_n = ARRAY_SIZE(regs_##ext),       \
> -               },                                              \
> +               SUBLIST_ISA(ext, extu),                         \
>                 {0},                                            \
>         },                                                      \
>  }                                                              \
>
> +#define SUBLIST_SBI(ext, extu)                                 \
> +       {                                                       \
> +               .name = "sbi-"#ext,                             \
> +               .feature_type = VCPU_FEATURE_SBI_EXT,           \
> +               .feature = KVM_RISCV_SBI_EXT_##extu,            \
> +               .regs = sbi_##ext##_regs,                       \
> +               .regs_n = ARRAY_SIZE(sbi_##ext##_regs),         \
> +       }
> +
>  #define KVM_SBI_EXT_SIMPLE_CONFIG(ext, extu)                   \
> -static __u64 regs_sbi_##ext[] = {                              \
> +static __u64 sbi_##ext##_regs[] = {                            \
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG |                    \
>         KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE |      \
>         KVM_RISCV_SBI_EXT_##extu,                               \
> @@ -1114,13 +1098,7 @@ static __u64 regs_sbi_##ext[] = {                                \
>  static struct vcpu_reg_list config_sbi_##ext = {               \
>         .sublists = {                                           \
>                 SUBLIST_BASE,                                   \
> -               {                                               \
> -                       .name = "sbi-"#ext,                     \
> -                       .feature_type = VCPU_FEATURE_SBI_EXT,   \
> -                       .feature = KVM_RISCV_SBI_EXT_##extu,    \
> -                       .regs = regs_sbi_##ext,                 \
> -                       .regs_n = ARRAY_SIZE(regs_sbi_##ext),   \
> -               },                                              \
> +               SUBLIST_SBI(ext, extu),                         \
>                 {0},                                            \
>         },                                                      \
>  }                                                              \
> @@ -1129,7 +1107,7 @@ static struct vcpu_reg_list config_sbi_##ext = {          \
>  static struct vcpu_reg_list config_##ext = {                   \
>         .sublists = {                                           \
>                 SUBLIST_BASE,                                   \
> -               SUBLIST_##extu,                                 \
> +               SUBLIST_ISA(ext, extu),                         \
>                 {0},                                            \
>         },                                                      \
>  }                                                              \
> @@ -1138,14 +1116,14 @@ static struct vcpu_reg_list config_##ext = {                    \
>  static struct vcpu_reg_list config_sbi_##ext = {               \
>         .sublists = {                                           \
>                 SUBLIST_BASE,                                   \
> -               SUBLIST_SBI_##extu,                             \
> +               SUBLIST_SBI(ext, extu),                         \
>                 {0},                                            \
>         },                                                      \
>  }                                                              \
>
>  /* Note: The below list is alphabetically sorted. */
>
> -KVM_SBI_EXT_SUBLIST_CONFIG(base, BASE);
> +KVM_SBI_EXT_SUBLIST_CONFIG(base, V01);
>  KVM_SBI_EXT_SUBLIST_CONFIG(sta, STA);
>  KVM_SBI_EXT_SIMPLE_CONFIG(pmu, PMU);
>  KVM_SBI_EXT_SIMPLE_CONFIG(dbcn, DBCN);
> @@ -1153,9 +1131,9 @@ KVM_SBI_EXT_SIMPLE_CONFIG(susp, SUSP);
>  KVM_SBI_EXT_SIMPLE_CONFIG(mpxy, MPXY);
>  KVM_SBI_EXT_SUBLIST_CONFIG(fwft, FWFT);
>
> -KVM_ISA_EXT_SUBLIST_CONFIG(aia, AIA);
> -KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, FP_F);
> -KVM_ISA_EXT_SUBLIST_CONFIG(fp_d, FP_D);
> +KVM_ISA_EXT_SUBLIST_CONFIG(aia, SSAIA);
> +KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, F);
> +KVM_ISA_EXT_SUBLIST_CONFIG(fp_d, D);
>  KVM_ISA_EXT_SUBLIST_CONFIG(v, V);
>  KVM_ISA_EXT_SIMPLE_CONFIG(h, H);
>  KVM_ISA_EXT_SIMPLE_CONFIG(smnpm, SMNPM);
>
> --
> 2.43.7
>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 5/5] KVM: riscv: selftests: Split SBI FWFT into separate feature-specific sublists
  2026-06-01 10:26   ` Yong-Xuan Wang
  (?)
@ 2026-06-05 16:14     ` Anup Patel
  -1 siblings, 0 replies; 40+ messages in thread
From: Anup Patel @ 2026-06-05 16:14 UTC (permalink / raw)
  To: Yong-Xuan Wang
  Cc: Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan, greentime.hu, vincent.chen, zong.li,
	kvm, kvm-riscv, linux-riscv, linux-kernel, linux-kselftest,
	inochiama

On Mon, Jun 1, 2026 at 3:56 PM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
>
> Divide the monolithic SBI FWFT (Firmware Features) register list into
> separate sublists, each testing a specific FWFT feature independently
> with proper dependency checking.
>
> Previously, all FWFT features were tested together in a single sublist.
> This caused issues because:
> 1. Not all FWFT features are available on all platforms
> 2. Some features depend on specific ISA extensions (e.g., pointer_masking
> requires Smnpm)
> 3. Tests would fail if any single feature was unavailable
>
> Add the feature-specific SBI FWFT sublists with the following
> improvements:
> - Add check_fwft_feature() helper to verify FWFT feature availability
>   at runtime
> - Update filter_reg() to handle per-feature FWFT register filtering
>
> Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Thanks,
Anup

> ---
>  tools/testing/selftests/kvm/riscv/get-reg-list.c | 60 ++++++++++++++++++++++--
>  1 file changed, 57 insertions(+), 3 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> index 5033c09201ef..cb86cb6b3635 100644
> --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
> +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> @@ -27,6 +27,7 @@ enum {
>  };
>
>  static bool isa_ext_cant_disable[KVM_RISCV_ISA_EXT_MAX];
> +static bool sbi_ext_enabled[KVM_RISCV_SBI_EXT_MAX];
>
>  bool filter_reg(__u64 reg)
>  {
> @@ -149,6 +150,14 @@ bool filter_reg(__u64 reg)
>         case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(iprio1h):
>         case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(iprio2h):
>                 return isa_ext_cant_disable[KVM_RISCV_ISA_EXT_SSAIA];
> +       /*
> +        * FWFT misaligned delegation registers are always visible when the SBI FWFT
> +        * extension is enable and the host supports the misaligned delegation.
> +        */
> +       case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.enable):
> +       case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.flags):
> +       case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.value):
> +               return sbi_ext_enabled[KVM_RISCV_SBI_EXT_FWFT];
>         default:
>                 break;
>         }
> @@ -193,6 +202,27 @@ static int override_vector_reg_size(struct kvm_vcpu *vcpu, struct vcpu_reg_subli
>         return 0;
>  }
>
> +void check_fwft_feature(struct kvm_vcpu *vcpu, struct vcpu_reg_sublist *s, u64 feature)
> +{
> +       unsigned long value;
> +       int rc;
> +
> +       /* Enable SBI FWFT extension so that we can check the supported register */
> +       rc = __vcpu_set_reg(vcpu, feature, 1);
> +       if (rc)
> +               return;
> +
> +       for (int i = 0; i < s->regs_n; i++) {
> +               if ((s->regs[i] & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_SBI_STATE) {
> +                       rc = __vcpu_get_reg(vcpu, s->regs[i], &value);
> +                       __TEST_REQUIRE(!rc, "%s not available, skipping tests", s->name);
> +               }
> +       }
> +
> +       /* We should assert if disabling failed here while enabling succeeded before */
> +       vcpu_set_reg(vcpu, feature, 0);
> +}
> +
>  void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
>  {
>         unsigned long isa_ext_state[KVM_RISCV_ISA_EXT_MAX] = { 0 };
> @@ -235,6 +265,9 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
>                         break;
>                 case VCPU_FEATURE_SBI_EXT:
>                         feature = RISCV_SBI_EXT_REG(s->feature);
> +                       if (s->feature == KVM_RISCV_SBI_EXT_FWFT)
> +                               check_fwft_feature(vcpu, s, feature);
> +                       sbi_ext_enabled[s->feature] = true;
>                         break;
>                 default:
>                         TEST_FAIL("Unknown feature type");
> @@ -897,11 +930,15 @@ static __u64 sbi_sta_regs[] = {
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_STA | KVM_REG_RISCV_SBI_STA_REG(shmem_hi),
>  };
>
> -static __u64 sbi_fwft_regs[] = {
> +static __u64 sbi_fwft_misaligned_deleg_regs[] = {
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_FWFT,
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.enable),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.flags),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.value),
> +};
> +
> +static __u64 sbi_fwft_pointer_masking_regs[] = {
> +       KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_FWFT,
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.enable),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.flags),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.value),
> @@ -1129,7 +1166,6 @@ KVM_SBI_EXT_SIMPLE_CONFIG(pmu, PMU);
>  KVM_SBI_EXT_SIMPLE_CONFIG(dbcn, DBCN);
>  KVM_SBI_EXT_SIMPLE_CONFIG(susp, SUSP);
>  KVM_SBI_EXT_SIMPLE_CONFIG(mpxy, MPXY);
> -KVM_SBI_EXT_SUBLIST_CONFIG(fwft, FWFT);
>
>  KVM_ISA_EXT_SUBLIST_CONFIG(aia, SSAIA);
>  KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, F);
> @@ -1206,6 +1242,23 @@ KVM_ISA_EXT_SIMPLE_CONFIG(zvksed, ZVKSED);
>  KVM_ISA_EXT_SIMPLE_CONFIG(zvksh, ZVKSH);
>  KVM_ISA_EXT_SIMPLE_CONFIG(zvkt, ZVKT);
>
> +static struct vcpu_reg_list config_sbi_fwft_misaligned_deleg = {
> +       .sublists = {
> +               SUBLIST_BASE,
> +               SUBLIST_SBI(fwft_misaligned_deleg, FWFT),
> +               {0},
> +       },
> +};
> +
> +static struct vcpu_reg_list config_sbi_fwft_pointer_masking = {
> +       .sublists = {
> +               SUBLIST_BASE,
> +               SUBLIST_ISA(smnpm, SMNPM),
> +               SUBLIST_SBI(fwft_pointer_masking, FWFT),
> +               {0},
> +       },
> +};
> +
>  struct vcpu_reg_list *vcpu_configs[] = {
>         &config_sbi_base,
>         &config_sbi_sta,
> @@ -1213,7 +1266,8 @@ struct vcpu_reg_list *vcpu_configs[] = {
>         &config_sbi_dbcn,
>         &config_sbi_susp,
>         &config_sbi_mpxy,
> -       &config_sbi_fwft,
> +       &config_sbi_fwft_misaligned_deleg,
> +       &config_sbi_fwft_pointer_masking,
>         &config_aia,
>         &config_fp_f,
>         &config_fp_d,
>
> --
> 2.43.7
>

-- 
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 5/5] KVM: riscv: selftests: Split SBI FWFT into separate feature-specific sublists
@ 2026-06-05 16:14     ` Anup Patel
  0 siblings, 0 replies; 40+ messages in thread
From: Anup Patel @ 2026-06-05 16:14 UTC (permalink / raw)
  To: Yong-Xuan Wang
  Cc: Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan, greentime.hu, vincent.chen, zong.li,
	kvm, kvm-riscv, linux-riscv, linux-kernel, linux-kselftest,
	inochiama

On Mon, Jun 1, 2026 at 3:56 PM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
>
> Divide the monolithic SBI FWFT (Firmware Features) register list into
> separate sublists, each testing a specific FWFT feature independently
> with proper dependency checking.
>
> Previously, all FWFT features were tested together in a single sublist.
> This caused issues because:
> 1. Not all FWFT features are available on all platforms
> 2. Some features depend on specific ISA extensions (e.g., pointer_masking
> requires Smnpm)
> 3. Tests would fail if any single feature was unavailable
>
> Add the feature-specific SBI FWFT sublists with the following
> improvements:
> - Add check_fwft_feature() helper to verify FWFT feature availability
>   at runtime
> - Update filter_reg() to handle per-feature FWFT register filtering
>
> Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Thanks,
Anup

> ---
>  tools/testing/selftests/kvm/riscv/get-reg-list.c | 60 ++++++++++++++++++++++--
>  1 file changed, 57 insertions(+), 3 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> index 5033c09201ef..cb86cb6b3635 100644
> --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
> +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> @@ -27,6 +27,7 @@ enum {
>  };
>
>  static bool isa_ext_cant_disable[KVM_RISCV_ISA_EXT_MAX];
> +static bool sbi_ext_enabled[KVM_RISCV_SBI_EXT_MAX];
>
>  bool filter_reg(__u64 reg)
>  {
> @@ -149,6 +150,14 @@ bool filter_reg(__u64 reg)
>         case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(iprio1h):
>         case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(iprio2h):
>                 return isa_ext_cant_disable[KVM_RISCV_ISA_EXT_SSAIA];
> +       /*
> +        * FWFT misaligned delegation registers are always visible when the SBI FWFT
> +        * extension is enable and the host supports the misaligned delegation.
> +        */
> +       case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.enable):
> +       case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.flags):
> +       case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.value):
> +               return sbi_ext_enabled[KVM_RISCV_SBI_EXT_FWFT];
>         default:
>                 break;
>         }
> @@ -193,6 +202,27 @@ static int override_vector_reg_size(struct kvm_vcpu *vcpu, struct vcpu_reg_subli
>         return 0;
>  }
>
> +void check_fwft_feature(struct kvm_vcpu *vcpu, struct vcpu_reg_sublist *s, u64 feature)
> +{
> +       unsigned long value;
> +       int rc;
> +
> +       /* Enable SBI FWFT extension so that we can check the supported register */
> +       rc = __vcpu_set_reg(vcpu, feature, 1);
> +       if (rc)
> +               return;
> +
> +       for (int i = 0; i < s->regs_n; i++) {
> +               if ((s->regs[i] & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_SBI_STATE) {
> +                       rc = __vcpu_get_reg(vcpu, s->regs[i], &value);
> +                       __TEST_REQUIRE(!rc, "%s not available, skipping tests", s->name);
> +               }
> +       }
> +
> +       /* We should assert if disabling failed here while enabling succeeded before */
> +       vcpu_set_reg(vcpu, feature, 0);
> +}
> +
>  void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
>  {
>         unsigned long isa_ext_state[KVM_RISCV_ISA_EXT_MAX] = { 0 };
> @@ -235,6 +265,9 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
>                         break;
>                 case VCPU_FEATURE_SBI_EXT:
>                         feature = RISCV_SBI_EXT_REG(s->feature);
> +                       if (s->feature == KVM_RISCV_SBI_EXT_FWFT)
> +                               check_fwft_feature(vcpu, s, feature);
> +                       sbi_ext_enabled[s->feature] = true;
>                         break;
>                 default:
>                         TEST_FAIL("Unknown feature type");
> @@ -897,11 +930,15 @@ static __u64 sbi_sta_regs[] = {
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_STA | KVM_REG_RISCV_SBI_STA_REG(shmem_hi),
>  };
>
> -static __u64 sbi_fwft_regs[] = {
> +static __u64 sbi_fwft_misaligned_deleg_regs[] = {
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_FWFT,
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.enable),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.flags),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.value),
> +};
> +
> +static __u64 sbi_fwft_pointer_masking_regs[] = {
> +       KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_FWFT,
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.enable),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.flags),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.value),
> @@ -1129,7 +1166,6 @@ KVM_SBI_EXT_SIMPLE_CONFIG(pmu, PMU);
>  KVM_SBI_EXT_SIMPLE_CONFIG(dbcn, DBCN);
>  KVM_SBI_EXT_SIMPLE_CONFIG(susp, SUSP);
>  KVM_SBI_EXT_SIMPLE_CONFIG(mpxy, MPXY);
> -KVM_SBI_EXT_SUBLIST_CONFIG(fwft, FWFT);
>
>  KVM_ISA_EXT_SUBLIST_CONFIG(aia, SSAIA);
>  KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, F);
> @@ -1206,6 +1242,23 @@ KVM_ISA_EXT_SIMPLE_CONFIG(zvksed, ZVKSED);
>  KVM_ISA_EXT_SIMPLE_CONFIG(zvksh, ZVKSH);
>  KVM_ISA_EXT_SIMPLE_CONFIG(zvkt, ZVKT);
>
> +static struct vcpu_reg_list config_sbi_fwft_misaligned_deleg = {
> +       .sublists = {
> +               SUBLIST_BASE,
> +               SUBLIST_SBI(fwft_misaligned_deleg, FWFT),
> +               {0},
> +       },
> +};
> +
> +static struct vcpu_reg_list config_sbi_fwft_pointer_masking = {
> +       .sublists = {
> +               SUBLIST_BASE,
> +               SUBLIST_ISA(smnpm, SMNPM),
> +               SUBLIST_SBI(fwft_pointer_masking, FWFT),
> +               {0},
> +       },
> +};
> +
>  struct vcpu_reg_list *vcpu_configs[] = {
>         &config_sbi_base,
>         &config_sbi_sta,
> @@ -1213,7 +1266,8 @@ struct vcpu_reg_list *vcpu_configs[] = {
>         &config_sbi_dbcn,
>         &config_sbi_susp,
>         &config_sbi_mpxy,
> -       &config_sbi_fwft,
> +       &config_sbi_fwft_misaligned_deleg,
> +       &config_sbi_fwft_pointer_masking,
>         &config_aia,
>         &config_fp_f,
>         &config_fp_d,
>
> --
> 2.43.7
>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 5/5] KVM: riscv: selftests: Split SBI FWFT into separate feature-specific sublists
@ 2026-06-05 16:14     ` Anup Patel
  0 siblings, 0 replies; 40+ messages in thread
From: Anup Patel @ 2026-06-05 16:14 UTC (permalink / raw)
  To: Yong-Xuan Wang
  Cc: Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan, greentime.hu, vincent.chen, zong.li,
	kvm, kvm-riscv, linux-riscv, linux-kernel, linux-kselftest,
	inochiama

On Mon, Jun 1, 2026 at 3:56 PM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
>
> Divide the monolithic SBI FWFT (Firmware Features) register list into
> separate sublists, each testing a specific FWFT feature independently
> with proper dependency checking.
>
> Previously, all FWFT features were tested together in a single sublist.
> This caused issues because:
> 1. Not all FWFT features are available on all platforms
> 2. Some features depend on specific ISA extensions (e.g., pointer_masking
> requires Smnpm)
> 3. Tests would fail if any single feature was unavailable
>
> Add the feature-specific SBI FWFT sublists with the following
> improvements:
> - Add check_fwft_feature() helper to verify FWFT feature availability
>   at runtime
> - Update filter_reg() to handle per-feature FWFT register filtering
>
> Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>

LGTM.

Reviewed-by: Anup Patel <anup@brainfault.org>

Thanks,
Anup

> ---
>  tools/testing/selftests/kvm/riscv/get-reg-list.c | 60 ++++++++++++++++++++++--
>  1 file changed, 57 insertions(+), 3 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> index 5033c09201ef..cb86cb6b3635 100644
> --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
> +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> @@ -27,6 +27,7 @@ enum {
>  };
>
>  static bool isa_ext_cant_disable[KVM_RISCV_ISA_EXT_MAX];
> +static bool sbi_ext_enabled[KVM_RISCV_SBI_EXT_MAX];
>
>  bool filter_reg(__u64 reg)
>  {
> @@ -149,6 +150,14 @@ bool filter_reg(__u64 reg)
>         case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(iprio1h):
>         case KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_AIA_REG(iprio2h):
>                 return isa_ext_cant_disable[KVM_RISCV_ISA_EXT_SSAIA];
> +       /*
> +        * FWFT misaligned delegation registers are always visible when the SBI FWFT
> +        * extension is enable and the host supports the misaligned delegation.
> +        */
> +       case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.enable):
> +       case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.flags):
> +       case KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.value):
> +               return sbi_ext_enabled[KVM_RISCV_SBI_EXT_FWFT];
>         default:
>                 break;
>         }
> @@ -193,6 +202,27 @@ static int override_vector_reg_size(struct kvm_vcpu *vcpu, struct vcpu_reg_subli
>         return 0;
>  }
>
> +void check_fwft_feature(struct kvm_vcpu *vcpu, struct vcpu_reg_sublist *s, u64 feature)
> +{
> +       unsigned long value;
> +       int rc;
> +
> +       /* Enable SBI FWFT extension so that we can check the supported register */
> +       rc = __vcpu_set_reg(vcpu, feature, 1);
> +       if (rc)
> +               return;
> +
> +       for (int i = 0; i < s->regs_n; i++) {
> +               if ((s->regs[i] & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_SBI_STATE) {
> +                       rc = __vcpu_get_reg(vcpu, s->regs[i], &value);
> +                       __TEST_REQUIRE(!rc, "%s not available, skipping tests", s->name);
> +               }
> +       }
> +
> +       /* We should assert if disabling failed here while enabling succeeded before */
> +       vcpu_set_reg(vcpu, feature, 0);
> +}
> +
>  void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
>  {
>         unsigned long isa_ext_state[KVM_RISCV_ISA_EXT_MAX] = { 0 };
> @@ -235,6 +265,9 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
>                         break;
>                 case VCPU_FEATURE_SBI_EXT:
>                         feature = RISCV_SBI_EXT_REG(s->feature);
> +                       if (s->feature == KVM_RISCV_SBI_EXT_FWFT)
> +                               check_fwft_feature(vcpu, s, feature);
> +                       sbi_ext_enabled[s->feature] = true;
>                         break;
>                 default:
>                         TEST_FAIL("Unknown feature type");
> @@ -897,11 +930,15 @@ static __u64 sbi_sta_regs[] = {
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_STA | KVM_REG_RISCV_SBI_STA_REG(shmem_hi),
>  };
>
> -static __u64 sbi_fwft_regs[] = {
> +static __u64 sbi_fwft_misaligned_deleg_regs[] = {
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_FWFT,
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.enable),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.flags),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(misaligned_deleg.value),
> +};
> +
> +static __u64 sbi_fwft_pointer_masking_regs[] = {
> +       KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_FWFT,
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.enable),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.flags),
>         KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.value),
> @@ -1129,7 +1166,6 @@ KVM_SBI_EXT_SIMPLE_CONFIG(pmu, PMU);
>  KVM_SBI_EXT_SIMPLE_CONFIG(dbcn, DBCN);
>  KVM_SBI_EXT_SIMPLE_CONFIG(susp, SUSP);
>  KVM_SBI_EXT_SIMPLE_CONFIG(mpxy, MPXY);
> -KVM_SBI_EXT_SUBLIST_CONFIG(fwft, FWFT);
>
>  KVM_ISA_EXT_SUBLIST_CONFIG(aia, SSAIA);
>  KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, F);
> @@ -1206,6 +1242,23 @@ KVM_ISA_EXT_SIMPLE_CONFIG(zvksed, ZVKSED);
>  KVM_ISA_EXT_SIMPLE_CONFIG(zvksh, ZVKSH);
>  KVM_ISA_EXT_SIMPLE_CONFIG(zvkt, ZVKT);
>
> +static struct vcpu_reg_list config_sbi_fwft_misaligned_deleg = {
> +       .sublists = {
> +               SUBLIST_BASE,
> +               SUBLIST_SBI(fwft_misaligned_deleg, FWFT),
> +               {0},
> +       },
> +};
> +
> +static struct vcpu_reg_list config_sbi_fwft_pointer_masking = {
> +       .sublists = {
> +               SUBLIST_BASE,
> +               SUBLIST_ISA(smnpm, SMNPM),
> +               SUBLIST_SBI(fwft_pointer_masking, FWFT),
> +               {0},
> +       },
> +};
> +
>  struct vcpu_reg_list *vcpu_configs[] = {
>         &config_sbi_base,
>         &config_sbi_sta,
> @@ -1213,7 +1266,8 @@ struct vcpu_reg_list *vcpu_configs[] = {
>         &config_sbi_dbcn,
>         &config_sbi_susp,
>         &config_sbi_mpxy,
> -       &config_sbi_fwft,
> +       &config_sbi_fwft_misaligned_deleg,
> +       &config_sbi_fwft_pointer_masking,
>         &config_aia,
>         &config_fp_f,
>         &config_fp_d,
>
> --
> 2.43.7
>

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 0/5] KVM: riscv: Fix stale FWFT feature exposure and enhance selftests
  2026-06-01 10:26 ` Yong-Xuan Wang
  (?)
@ 2026-06-05 16:16   ` Anup Patel
  -1 siblings, 0 replies; 40+ messages in thread
From: Anup Patel @ 2026-06-05 16:16 UTC (permalink / raw)
  To: Yong-Xuan Wang
  Cc: Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan, greentime.hu, vincent.chen, zong.li,
	kvm, kvm-riscv, linux-riscv, linux-kernel, linux-kselftest,
	inochiama

On Mon, Jun 1, 2026 at 3:56 PM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
>
> This series fixes three bugs in the SBI FWFT (Firmware Features) extension
> and improves the related selftest infrastructure.
> The bugs are:
> 1. Missing CSR dirty marking: When userspace sets FWFT feature values via
>    KVM_SET_ONE_REG, modified CSRs (e.g., henvcfg.PMM for pointer masking)
>    are not marked dirty, leading to stale state after vCPU scheduling or
>    migration.
> 2. Hardware probing side effects: The try_to_set_pmm() function modifies
>    HENVCFG.PMM during hardware capability detection but fails to restore
>    the original value, leaving the CSR in an altered state that affects
>    subsequent operations.
> 3. Stale feature exposure: FWFT feature support is cached at vCPU
>    initialization time. When userspace subsequently disables ISA extensions
>    via KVM_SET_ONE_REG, the cached support status is not updated, allowing
>    guests to access features that depend on disabled extensions.
> Patches 1-3 fix these bugs separately.
>
> The selftest improvements (patches 4-5) enhance the get-reg-list test by
> refactoring the extension sublist infrastructure and splitting FWFT
> feature testing into separate, properly-gated sublists.
>
> ---
> Changes in v5:
> - Add CSR dirty marking fix (new patch 1/5) (sashiko-bot)
> - Split original FWFT bug fix into two focused patches
>   - Add init() callback with try_to_set_pmm() restoration fix (new patch
>     2/5) (sashiko-bot)
>   - Keep runtime supported() checks as separate patch (patch 3/5)
> - Link to v4: https://patch.msgid.link/20260601-kvm-get_reg_list-v2-v4-0-c88abc81ebda@sifive.com
>
> Changes in v4:
> - Rename the title of cover letter
> - Disable preemption when running try_to_set_pmm() (sashiko-bot)
> - Remove check_supported_reg() (sashiko-bot)
> - Link to v3: https://patch.msgid.link/20260528-kvm-get_reg_list-v2-v3-0-170969a8599f@sifive.com
>
> Changes in v3:
> - Restore 'supported' field with init() callback for initialization probing
>   (sashiko-bot)
> - Add NULL checks before calling feature->supported() in all functions
> - Fix isa_ext_enabled tracking logic and restore isa_ext_cant_disable array
> - Add sbi_ext_enabled tracking and enhance dependency checking (sashiko-bot)
> - Refine code organization and variable naming consistency (sashiko-bot)
> - Link to v2: https://patch.msgid.link/20260526-kvm-get_reg_list-v2-v2-0-7940a401454a@sifive.com
>
> Changes in v2:
> - Fix FWFT stale feature exposure by removing static 'supported' field
> - Refactor get-reg-list test to use unified extension sublist macros
> - Split FWFT testing into per-feature sublists with runtime checks
>   (Andrew)
>
> To: Anup Patel <anup@brainfault.org>
> To: Atish Patra <atish.patra@linux.dev>
> To: Paul Walmsley <pjw@kernel.org>
> To: Palmer Dabbelt <palmer@dabbelt.com>
> To: Albert Ou <aou@eecs.berkeley.edu>
> To: Alexandre Ghiti <alex@ghiti.fr>
> To: Clément Léger <cleger@rivosinc.com>
> To: Andrew Jones <ajones@ventanamicro.com>
> To: Paolo Bonzini <pbonzini@redhat.com>
> To: Shuah Khan <shuah@kernel.org>
> Cc: greentime.hu@sifive.com
> Cc: vincent.chen@sifive.com
> Cc: zong.li@sifive.com
> Cc: kvm@vger.kernel.org
> Cc: kvm-riscv@lists.infradead.org
> Cc: linux-riscv@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-kselftest@vger.kernel.org
>
> ---
> Yong-Xuan Wang (5):
>       KVM: RISC-V: SBI FWFT: Mark vCPU CSRs dirty after setting feature value
>       KVM: RISC-V: SBI FWFT: Add optional init() callback for hardware probing
>       KVM: RISC-V: SBI FWFT: Fix stale feature exposure after runtime extension changes
>       KVM: riscv: selftests: Refactor ISA and SBI extension sublist macros
>       KVM: riscv: selftests: Split SBI FWFT into separate feature-specific sublists

Queued this series for Linux-7.2

Regards,
Anup

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 0/5] KVM: riscv: Fix stale FWFT feature exposure and enhance selftests
@ 2026-06-05 16:16   ` Anup Patel
  0 siblings, 0 replies; 40+ messages in thread
From: Anup Patel @ 2026-06-05 16:16 UTC (permalink / raw)
  To: Yong-Xuan Wang
  Cc: Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan, greentime.hu, vincent.chen, zong.li,
	kvm, kvm-riscv, linux-riscv, linux-kernel, linux-kselftest,
	inochiama

On Mon, Jun 1, 2026 at 3:56 PM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
>
> This series fixes three bugs in the SBI FWFT (Firmware Features) extension
> and improves the related selftest infrastructure.
> The bugs are:
> 1. Missing CSR dirty marking: When userspace sets FWFT feature values via
>    KVM_SET_ONE_REG, modified CSRs (e.g., henvcfg.PMM for pointer masking)
>    are not marked dirty, leading to stale state after vCPU scheduling or
>    migration.
> 2. Hardware probing side effects: The try_to_set_pmm() function modifies
>    HENVCFG.PMM during hardware capability detection but fails to restore
>    the original value, leaving the CSR in an altered state that affects
>    subsequent operations.
> 3. Stale feature exposure: FWFT feature support is cached at vCPU
>    initialization time. When userspace subsequently disables ISA extensions
>    via KVM_SET_ONE_REG, the cached support status is not updated, allowing
>    guests to access features that depend on disabled extensions.
> Patches 1-3 fix these bugs separately.
>
> The selftest improvements (patches 4-5) enhance the get-reg-list test by
> refactoring the extension sublist infrastructure and splitting FWFT
> feature testing into separate, properly-gated sublists.
>
> ---
> Changes in v5:
> - Add CSR dirty marking fix (new patch 1/5) (sashiko-bot)
> - Split original FWFT bug fix into two focused patches
>   - Add init() callback with try_to_set_pmm() restoration fix (new patch
>     2/5) (sashiko-bot)
>   - Keep runtime supported() checks as separate patch (patch 3/5)
> - Link to v4: https://patch.msgid.link/20260601-kvm-get_reg_list-v2-v4-0-c88abc81ebda@sifive.com
>
> Changes in v4:
> - Rename the title of cover letter
> - Disable preemption when running try_to_set_pmm() (sashiko-bot)
> - Remove check_supported_reg() (sashiko-bot)
> - Link to v3: https://patch.msgid.link/20260528-kvm-get_reg_list-v2-v3-0-170969a8599f@sifive.com
>
> Changes in v3:
> - Restore 'supported' field with init() callback for initialization probing
>   (sashiko-bot)
> - Add NULL checks before calling feature->supported() in all functions
> - Fix isa_ext_enabled tracking logic and restore isa_ext_cant_disable array
> - Add sbi_ext_enabled tracking and enhance dependency checking (sashiko-bot)
> - Refine code organization and variable naming consistency (sashiko-bot)
> - Link to v2: https://patch.msgid.link/20260526-kvm-get_reg_list-v2-v2-0-7940a401454a@sifive.com
>
> Changes in v2:
> - Fix FWFT stale feature exposure by removing static 'supported' field
> - Refactor get-reg-list test to use unified extension sublist macros
> - Split FWFT testing into per-feature sublists with runtime checks
>   (Andrew)
>
> To: Anup Patel <anup@brainfault.org>
> To: Atish Patra <atish.patra@linux.dev>
> To: Paul Walmsley <pjw@kernel.org>
> To: Palmer Dabbelt <palmer@dabbelt.com>
> To: Albert Ou <aou@eecs.berkeley.edu>
> To: Alexandre Ghiti <alex@ghiti.fr>
> To: Clément Léger <cleger@rivosinc.com>
> To: Andrew Jones <ajones@ventanamicro.com>
> To: Paolo Bonzini <pbonzini@redhat.com>
> To: Shuah Khan <shuah@kernel.org>
> Cc: greentime.hu@sifive.com
> Cc: vincent.chen@sifive.com
> Cc: zong.li@sifive.com
> Cc: kvm@vger.kernel.org
> Cc: kvm-riscv@lists.infradead.org
> Cc: linux-riscv@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-kselftest@vger.kernel.org
>
> ---
> Yong-Xuan Wang (5):
>       KVM: RISC-V: SBI FWFT: Mark vCPU CSRs dirty after setting feature value
>       KVM: RISC-V: SBI FWFT: Add optional init() callback for hardware probing
>       KVM: RISC-V: SBI FWFT: Fix stale feature exposure after runtime extension changes
>       KVM: riscv: selftests: Refactor ISA and SBI extension sublist macros
>       KVM: riscv: selftests: Split SBI FWFT into separate feature-specific sublists

Queued this series for Linux-7.2

Regards,
Anup

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 0/5] KVM: riscv: Fix stale FWFT feature exposure and enhance selftests
@ 2026-06-05 16:16   ` Anup Patel
  0 siblings, 0 replies; 40+ messages in thread
From: Anup Patel @ 2026-06-05 16:16 UTC (permalink / raw)
  To: Yong-Xuan Wang
  Cc: Atish Patra, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Clément Léger, Andrew Jones,
	Paolo Bonzini, Shuah Khan, greentime.hu, vincent.chen, zong.li,
	kvm, kvm-riscv, linux-riscv, linux-kernel, linux-kselftest,
	inochiama

On Mon, Jun 1, 2026 at 3:56 PM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
>
> This series fixes three bugs in the SBI FWFT (Firmware Features) extension
> and improves the related selftest infrastructure.
> The bugs are:
> 1. Missing CSR dirty marking: When userspace sets FWFT feature values via
>    KVM_SET_ONE_REG, modified CSRs (e.g., henvcfg.PMM for pointer masking)
>    are not marked dirty, leading to stale state after vCPU scheduling or
>    migration.
> 2. Hardware probing side effects: The try_to_set_pmm() function modifies
>    HENVCFG.PMM during hardware capability detection but fails to restore
>    the original value, leaving the CSR in an altered state that affects
>    subsequent operations.
> 3. Stale feature exposure: FWFT feature support is cached at vCPU
>    initialization time. When userspace subsequently disables ISA extensions
>    via KVM_SET_ONE_REG, the cached support status is not updated, allowing
>    guests to access features that depend on disabled extensions.
> Patches 1-3 fix these bugs separately.
>
> The selftest improvements (patches 4-5) enhance the get-reg-list test by
> refactoring the extension sublist infrastructure and splitting FWFT
> feature testing into separate, properly-gated sublists.
>
> ---
> Changes in v5:
> - Add CSR dirty marking fix (new patch 1/5) (sashiko-bot)
> - Split original FWFT bug fix into two focused patches
>   - Add init() callback with try_to_set_pmm() restoration fix (new patch
>     2/5) (sashiko-bot)
>   - Keep runtime supported() checks as separate patch (patch 3/5)
> - Link to v4: https://patch.msgid.link/20260601-kvm-get_reg_list-v2-v4-0-c88abc81ebda@sifive.com
>
> Changes in v4:
> - Rename the title of cover letter
> - Disable preemption when running try_to_set_pmm() (sashiko-bot)
> - Remove check_supported_reg() (sashiko-bot)
> - Link to v3: https://patch.msgid.link/20260528-kvm-get_reg_list-v2-v3-0-170969a8599f@sifive.com
>
> Changes in v3:
> - Restore 'supported' field with init() callback for initialization probing
>   (sashiko-bot)
> - Add NULL checks before calling feature->supported() in all functions
> - Fix isa_ext_enabled tracking logic and restore isa_ext_cant_disable array
> - Add sbi_ext_enabled tracking and enhance dependency checking (sashiko-bot)
> - Refine code organization and variable naming consistency (sashiko-bot)
> - Link to v2: https://patch.msgid.link/20260526-kvm-get_reg_list-v2-v2-0-7940a401454a@sifive.com
>
> Changes in v2:
> - Fix FWFT stale feature exposure by removing static 'supported' field
> - Refactor get-reg-list test to use unified extension sublist macros
> - Split FWFT testing into per-feature sublists with runtime checks
>   (Andrew)
>
> To: Anup Patel <anup@brainfault.org>
> To: Atish Patra <atish.patra@linux.dev>
> To: Paul Walmsley <pjw@kernel.org>
> To: Palmer Dabbelt <palmer@dabbelt.com>
> To: Albert Ou <aou@eecs.berkeley.edu>
> To: Alexandre Ghiti <alex@ghiti.fr>
> To: Clément Léger <cleger@rivosinc.com>
> To: Andrew Jones <ajones@ventanamicro.com>
> To: Paolo Bonzini <pbonzini@redhat.com>
> To: Shuah Khan <shuah@kernel.org>
> Cc: greentime.hu@sifive.com
> Cc: vincent.chen@sifive.com
> Cc: zong.li@sifive.com
> Cc: kvm@vger.kernel.org
> Cc: kvm-riscv@lists.infradead.org
> Cc: linux-riscv@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-kselftest@vger.kernel.org
>
> ---
> Yong-Xuan Wang (5):
>       KVM: RISC-V: SBI FWFT: Mark vCPU CSRs dirty after setting feature value
>       KVM: RISC-V: SBI FWFT: Add optional init() callback for hardware probing
>       KVM: RISC-V: SBI FWFT: Fix stale feature exposure after runtime extension changes
>       KVM: riscv: selftests: Refactor ISA and SBI extension sublist macros
>       KVM: riscv: selftests: Split SBI FWFT into separate feature-specific sublists

Queued this series for Linux-7.2

Regards,
Anup

-- 
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2026-06-05 16:17 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-01 10:26 [PATCH v5 0/5] KVM: riscv: Fix stale FWFT feature exposure and enhance selftests Yong-Xuan Wang
2026-06-01 10:26 ` Yong-Xuan Wang
2026-06-01 10:26 ` Yong-Xuan Wang
2026-06-01 10:26 ` [PATCH v5 1/5] KVM: RISC-V: SBI FWFT: Mark vCPU CSRs dirty after setting feature value Yong-Xuan Wang
2026-06-01 10:26   ` Yong-Xuan Wang
2026-06-01 10:26   ` Yong-Xuan Wang
2026-06-01 11:04   ` sashiko-bot
2026-06-05 15:30   ` Anup Patel
2026-06-05 15:30     ` Anup Patel
2026-06-05 15:30     ` Anup Patel
2026-06-01 10:26 ` [PATCH v5 2/5] KVM: RISC-V: SBI FWFT: Add optional init() callback for hardware probing Yong-Xuan Wang
2026-06-01 10:26   ` Yong-Xuan Wang
2026-06-01 10:26   ` Yong-Xuan Wang
2026-06-05 16:11   ` Anup Patel
2026-06-05 16:11     ` Anup Patel
2026-06-05 16:11     ` Anup Patel
2026-06-01 10:26 ` [PATCH v5 3/5] KVM: RISC-V: SBI FWFT: Fix stale feature exposure after runtime extension changes Yong-Xuan Wang
2026-06-01 10:26   ` Yong-Xuan Wang
2026-06-01 10:26   ` Yong-Xuan Wang
2026-06-01 11:37   ` sashiko-bot
2026-06-05 16:12   ` Anup Patel
2026-06-05 16:12     ` Anup Patel
2026-06-05 16:12     ` Anup Patel
2026-06-01 10:26 ` [PATCH v5 4/5] KVM: riscv: selftests: Refactor ISA and SBI extension sublist macros Yong-Xuan Wang
2026-06-01 10:26   ` Yong-Xuan Wang
2026-06-01 10:26   ` Yong-Xuan Wang
2026-06-05 16:13   ` Anup Patel
2026-06-05 16:13     ` Anup Patel
2026-06-05 16:13     ` Anup Patel
2026-06-01 10:26 ` [PATCH v5 5/5] KVM: riscv: selftests: Split SBI FWFT into separate feature-specific sublists Yong-Xuan Wang
2026-06-01 10:26   ` Yong-Xuan Wang
2026-06-01 10:26   ` Yong-Xuan Wang
2026-06-01 11:54   ` sashiko-bot
2026-06-04  9:28     ` Yong-Xuan Wang
2026-06-05 16:14   ` Anup Patel
2026-06-05 16:14     ` Anup Patel
2026-06-05 16:14     ` Anup Patel
2026-06-05 16:16 ` [PATCH v5 0/5] KVM: riscv: Fix stale FWFT feature exposure and enhance selftests Anup Patel
2026-06-05 16:16   ` Anup Patel
2026-06-05 16:16   ` Anup Patel

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.