* [PATCH v2] KVM: riscv: selftests: Add riscv vm satp modes
@ 2025-10-29 11:20 wu.fei9
2025-10-31 19:26 ` Andrew Jones
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: wu.fei9 @ 2025-10-29 11:20 UTC (permalink / raw)
To: kvm-riscv, ajones, rkrcmar
Current vm modes cannot represent riscv guest modes precisely, here add
all 9 combinations of P(56,40,41) x V(57,48,39). Also the default vm
mode is detected on runtime instead of hardcoded one, which might not be
supported on specific machine.
Signed-off-by: Wu Fei <wu.fei9@sanechips.com.cn>
---
.../testing/selftests/kvm/include/kvm_util.h | 17 ++++-
.../selftests/kvm/include/riscv/processor.h | 2 +
tools/testing/selftests/kvm/lib/guest_modes.c | 41 +++++++++---
tools/testing/selftests/kvm/lib/kvm_util.c | 33 ++++++++++
.../selftests/kvm/lib/riscv/processor.c | 63 +++++++++++++++++--
5 files changed, 142 insertions(+), 14 deletions(-)
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index bee65ca08721..2055f0f5df82 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -179,6 +179,17 @@ enum vm_guest_mode {
VM_MODE_P36V48_64K,
VM_MODE_P47V47_16K,
VM_MODE_P36V47_16K,
+
+ VM_MODE_P56V57_4K, /* For riscv64 */
+ VM_MODE_P56V48_4K,
+ VM_MODE_P56V39_4K,
+ VM_MODE_P50V57_4K,
+ VM_MODE_P50V48_4K,
+ VM_MODE_P50V39_4K,
+ VM_MODE_P41V57_4K,
+ VM_MODE_P41V48_4K,
+ VM_MODE_P41V39_4K,
+
NUM_VM_MODES,
};
@@ -203,10 +214,10 @@ kvm_static_assert(sizeof(struct vm_shape) == sizeof(uint64_t));
shape; \
})
-#if defined(__aarch64__)
-
extern enum vm_guest_mode vm_mode_default;
+#if defined(__aarch64__)
+
#define VM_MODE_DEFAULT vm_mode_default
#define MIN_PAGE_SHIFT 12U
#define ptes_per_page(page_size) ((page_size) / 8)
@@ -229,7 +240,7 @@ extern enum vm_guest_mode vm_mode_default;
#error "RISC-V 32-bit kvm selftests not supported"
#endif
-#define VM_MODE_DEFAULT VM_MODE_P40V48_4K
+#define VM_MODE_DEFAULT vm_mode_default
#define MIN_PAGE_SHIFT 12U
#define ptes_per_page(page_size) ((page_size) / 8)
diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
index 162f303d9daa..2d5a5548e698 100644
--- a/tools/testing/selftests/kvm/include/riscv/processor.h
+++ b/tools/testing/selftests/kvm/include/riscv/processor.h
@@ -191,4 +191,6 @@ static inline void local_irq_disable(void)
csr_clear(CSR_SSTATUS, SR_SIE);
}
+unsigned long riscv64_get_satp_mode(void);
+
#endif /* SELFTEST_KVM_PROCESSOR_H */
diff --git a/tools/testing/selftests/kvm/lib/guest_modes.c b/tools/testing/selftests/kvm/lib/guest_modes.c
index b04901e55138..ce3099630397 100644
--- a/tools/testing/selftests/kvm/lib/guest_modes.c
+++ b/tools/testing/selftests/kvm/lib/guest_modes.c
@@ -4,7 +4,7 @@
*/
#include "guest_modes.h"
-#ifdef __aarch64__
+#if defined(__aarch64__) || defined(__riscv)
#include "processor.h"
enum vm_guest_mode vm_mode_default;
#endif
@@ -13,9 +13,11 @@ struct guest_mode guest_modes[NUM_VM_MODES];
void guest_modes_append_default(void)
{
-#ifndef __aarch64__
+#if !defined(__aarch64__) && !defined(__riscv)
guest_mode_append(VM_MODE_DEFAULT, true);
-#else
+#endif
+
+#ifdef __aarch64__
{
unsigned int limit = kvm_check_cap(KVM_CAP_ARM_VM_IPA_SIZE);
uint32_t ipa4k, ipa16k, ipa64k;
@@ -74,11 +76,36 @@ void guest_modes_append_default(void)
#ifdef __riscv
{
unsigned int sz = kvm_check_cap(KVM_CAP_VM_GPA_BITS);
+ unsigned long satp_mode = riscv64_get_satp_mode() << SATP_MODE_SHIFT;
+ int i;
- if (sz >= 52)
- guest_mode_append(VM_MODE_P52V48_4K, true);
- if (sz >= 48)
- guest_mode_append(VM_MODE_P48V48_4K, true);
+ switch (sz) {
+ case 59:
+ guest_mode_append(VM_MODE_P56V57_4K, satp_mode >= SATP_MODE_57);
+ guest_mode_append(VM_MODE_P56V48_4K, satp_mode >= SATP_MODE_48);
+ guest_mode_append(VM_MODE_P56V39_4K, satp_mode >= SATP_MODE_39);
+ break;
+ case 50:
+ guest_mode_append(VM_MODE_P50V57_4K, satp_mode >= SATP_MODE_57);
+ guest_mode_append(VM_MODE_P50V48_4K, satp_mode >= SATP_MODE_48);
+ guest_mode_append(VM_MODE_P50V39_4K, satp_mode >= SATP_MODE_39);
+ break;
+ case 41:
+ guest_mode_append(VM_MODE_P41V57_4K, satp_mode >= SATP_MODE_57);
+ guest_mode_append(VM_MODE_P41V48_4K, satp_mode >= SATP_MODE_48);
+ guest_mode_append(VM_MODE_P41V39_4K, satp_mode >= SATP_MODE_39);
+ break;
+ default:
+ break;
+ }
+
+ /* set the first supported mode as default */
+ vm_mode_default = NUM_VM_MODES;
+ for (i = 0; vm_mode_default == NUM_VM_MODES && i < NUM_VM_MODES; i++) {
+ if (guest_modes[i].supported && guest_modes[i].enabled)
+ vm_mode_default = i;
+ }
+ TEST_ASSERT(vm_mode_default != NUM_VM_MODES, "No supported mode!");
}
#endif
}
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index a055343a7bf7..9803e61ae7db 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -224,6 +224,15 @@ const char *vm_guest_mode_string(uint32_t i)
[VM_MODE_P36V48_64K] = "PA-bits:36, VA-bits:48, 64K pages",
[VM_MODE_P47V47_16K] = "PA-bits:47, VA-bits:47, 16K pages",
[VM_MODE_P36V47_16K] = "PA-bits:36, VA-bits:47, 16K pages",
+ [VM_MODE_P56V57_4K] = "PA-bits:56, VA-bits:57, 4K pages",
+ [VM_MODE_P56V48_4K] = "PA-bits:56, VA-bits:48, 4K pages",
+ [VM_MODE_P56V39_4K] = "PA-bits:56, VA-bits:39, 4K pages",
+ [VM_MODE_P50V57_4K] = "PA-bits:50, VA-bits:57, 4K pages",
+ [VM_MODE_P50V48_4K] = "PA-bits:50, VA-bits:48, 4K pages",
+ [VM_MODE_P50V39_4K] = "PA-bits:50, VA-bits:39, 4K pages",
+ [VM_MODE_P41V57_4K] = "PA-bits:41, VA-bits:57, 4K pages",
+ [VM_MODE_P41V48_4K] = "PA-bits:41, VA-bits:48, 4K pages",
+ [VM_MODE_P41V39_4K] = "PA-bits:41, VA-bits:39, 4K pages",
};
_Static_assert(sizeof(strings)/sizeof(char *) == NUM_VM_MODES,
"Missing new mode strings?");
@@ -251,6 +260,15 @@ const struct vm_guest_mode_params vm_guest_mode_params[] = {
[VM_MODE_P36V48_64K] = { 36, 48, 0x10000, 16 },
[VM_MODE_P47V47_16K] = { 47, 47, 0x4000, 14 },
[VM_MODE_P36V47_16K] = { 36, 47, 0x4000, 14 },
+ [VM_MODE_P56V57_4K] = { 56, 57, 0x1000, 12 },
+ [VM_MODE_P56V48_4K] = { 56, 48, 0x1000, 12 },
+ [VM_MODE_P56V39_4K] = { 56, 39, 0x1000, 12 },
+ [VM_MODE_P50V57_4K] = { 50, 57, 0x1000, 12 },
+ [VM_MODE_P50V48_4K] = { 50, 48, 0x1000, 12 },
+ [VM_MODE_P50V39_4K] = { 50, 39, 0x1000, 12 },
+ [VM_MODE_P41V57_4K] = { 41, 57, 0x1000, 12 },
+ [VM_MODE_P41V48_4K] = { 41, 48, 0x1000, 12 },
+ [VM_MODE_P41V39_4K] = { 41, 39, 0x1000, 12 },
};
_Static_assert(sizeof(vm_guest_mode_params)/sizeof(struct vm_guest_mode_params) == NUM_VM_MODES,
"Missing new mode params?");
@@ -351,6 +369,21 @@ struct kvm_vm *____vm_create(struct vm_shape shape)
case VM_MODE_P44V64_4K:
vm->pgtable_levels = 5;
break;
+ case VM_MODE_P56V57_4K:
+ case VM_MODE_P50V57_4K:
+ case VM_MODE_P41V57_4K:
+ vm->pgtable_levels = 5;
+ break;
+ case VM_MODE_P56V48_4K:
+ case VM_MODE_P50V48_4K:
+ case VM_MODE_P41V48_4K:
+ vm->pgtable_levels = 4;
+ break;
+ case VM_MODE_P56V39_4K:
+ case VM_MODE_P50V39_4K:
+ case VM_MODE_P41V39_4K:
+ vm->pgtable_levels = 3;
+ break;
default:
TEST_FAIL("Unknown guest mode: 0x%x", vm->mode);
}
diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
index 2eac7d4b59e9..53675292b8eb 100644
--- a/tools/testing/selftests/kvm/lib/riscv/processor.c
+++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
@@ -8,6 +8,7 @@
#include <linux/compiler.h>
#include <assert.h>
+#include "guest_modes.h"
#include "kvm_util.h"
#include "processor.h"
#include "ucall_common.h"
@@ -197,22 +198,41 @@ void riscv_vcpu_mmu_setup(struct kvm_vcpu *vcpu)
{
struct kvm_vm *vm = vcpu->vm;
unsigned long satp;
+ unsigned long satp_mode;
+ unsigned long max_satp_mode;
/*
* The RISC-V Sv48 MMU mode supports 56-bit physical address
* for 48-bit virtual address with 4KB last level page size.
*/
switch (vm->mode) {
- case VM_MODE_P52V48_4K:
- case VM_MODE_P48V48_4K:
- case VM_MODE_P40V48_4K:
+ case VM_MODE_P56V57_4K:
+ case VM_MODE_P50V57_4K:
+ case VM_MODE_P41V57_4K:
+ satp_mode = SATP_MODE_57;
+ break;
+ case VM_MODE_P56V48_4K:
+ case VM_MODE_P50V48_4K:
+ case VM_MODE_P41V48_4K:
+ satp_mode = SATP_MODE_48;
+ break;
+ case VM_MODE_P56V39_4K:
+ case VM_MODE_P50V39_4K:
+ case VM_MODE_P41V39_4K:
+ satp_mode = SATP_MODE_39;
break;
default:
TEST_FAIL("Unknown guest mode, mode: 0x%x", vm->mode);
}
+ max_satp_mode = vcpu_get_reg(vcpu, RISCV_CONFIG_REG(satp_mode));
+
+ if ((satp_mode >> SATP_MODE_SHIFT) > max_satp_mode)
+ TEST_FAIL("Unable to set satp mode 0x%lx, max mode 0x%lx\n",
+ satp_mode >> SATP_MODE_SHIFT, max_satp_mode);
+
satp = (vm->pgd >> PGTBL_PAGE_SIZE_SHIFT) & SATP_PPN;
- satp |= SATP_MODE_48;
+ satp |= satp_mode;
vcpu_set_reg(vcpu, RISCV_GENERAL_CSR_REG(satp), satp);
}
@@ -515,3 +535,38 @@ unsigned long get_host_sbi_spec_version(void)
return ret.value;
}
+
+void kvm_selftest_arch_init(void)
+{
+ /*
+ * riscv64 doesn't have a true default mode, so start by detecting the
+ * supported vm mode.
+ */
+ guest_modes_append_default();
+}
+
+unsigned long riscv64_get_satp_mode(void)
+{
+ int kvm_fd, vm_fd, vcpu_fd, err;
+ uint64_t val;
+ struct kvm_one_reg reg = {
+ .id = RISCV_CONFIG_REG(satp_mode),
+ .addr = (uint64_t)&val,
+ };
+
+ kvm_fd = open_kvm_dev_path_or_exit();
+ vm_fd = __kvm_ioctl(kvm_fd, KVM_CREATE_VM, NULL);
+ TEST_ASSERT(vm_fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VM, vm_fd));
+
+ vcpu_fd = ioctl(vm_fd, KVM_CREATE_VCPU, 0);
+ TEST_ASSERT(vcpu_fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VCPU, vcpu_fd));
+
+ err = ioctl(vcpu_fd, KVM_GET_ONE_REG, ®);
+ TEST_ASSERT(err == 0, KVM_IOCTL_ERROR(KVM_GET_ONE_REG, vcpu_fd));
+
+ close(vcpu_fd);
+ close(vm_fd);
+ close(kvm_fd);
+
+ return val;
+}
--
2.43.0
--
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2] KVM: riscv: selftests: Add riscv vm satp modes
2025-10-29 11:20 [PATCH v2] KVM: riscv: selftests: Add riscv vm satp modes wu.fei9
@ 2025-10-31 19:26 ` Andrew Jones
2025-11-04 3:38 ` Nutty.Liu
2025-11-04 7:41 ` Anup Patel
2 siblings, 0 replies; 6+ messages in thread
From: Andrew Jones @ 2025-10-31 19:26 UTC (permalink / raw)
To: wu.fei9; +Cc: kvm-riscv, rkrcmar
On Wed, Oct 29, 2025 at 07:20:08PM +0800, wu.fei9@sanechips.com.cn wrote:
> Current vm modes cannot represent riscv guest modes precisely, here add
> all 9 combinations of P(56,40,41) x V(57,48,39). Also the default vm
> mode is detected on runtime instead of hardcoded one, which might not be
> supported on specific machine.
>
> Signed-off-by: Wu Fei <wu.fei9@sanechips.com.cn>
> ---
> .../testing/selftests/kvm/include/kvm_util.h | 17 ++++-
> .../selftests/kvm/include/riscv/processor.h | 2 +
> tools/testing/selftests/kvm/lib/guest_modes.c | 41 +++++++++---
> tools/testing/selftests/kvm/lib/kvm_util.c | 33 ++++++++++
> .../selftests/kvm/lib/riscv/processor.c | 63 +++++++++++++++++--
> 5 files changed, 142 insertions(+), 14 deletions(-)
>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
--
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] KVM: riscv: selftests: Add riscv vm satp modes
2025-10-29 11:20 [PATCH v2] KVM: riscv: selftests: Add riscv vm satp modes wu.fei9
2025-10-31 19:26 ` Andrew Jones
@ 2025-11-04 3:38 ` Nutty.Liu
2025-11-04 7:41 ` Anup Patel
2 siblings, 0 replies; 6+ messages in thread
From: Nutty.Liu @ 2025-11-04 3:38 UTC (permalink / raw)
To: wu.fei9, kvm-riscv, ajones, rkrcmar
On 10/29/2025 7:20 PM, wu.fei9@sanechips.com.cn wrote:
> Current vm modes cannot represent riscv guest modes precisely, here add
> all 9 combinations of P(56,40,41) x V(57,48,39). Also the default vm
> mode is detected on runtime instead of hardcoded one, which might not be
> supported on specific machine.
>
> Signed-off-by: Wu Fei <wu.fei9@sanechips.com.cn>
> ---
> .../testing/selftests/kvm/include/kvm_util.h | 17 ++++-
> .../selftests/kvm/include/riscv/processor.h | 2 +
> tools/testing/selftests/kvm/lib/guest_modes.c | 41 +++++++++---
> tools/testing/selftests/kvm/lib/kvm_util.c | 33 ++++++++++
> .../selftests/kvm/lib/riscv/processor.c | 63 +++++++++++++++++--
> 5 files changed, 142 insertions(+), 14 deletions(-)
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Thanks,
Nutty
--
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] KVM: riscv: selftests: Add riscv vm satp modes
2025-10-29 11:20 [PATCH v2] KVM: riscv: selftests: Add riscv vm satp modes wu.fei9
2025-10-31 19:26 ` Andrew Jones
2025-11-04 3:38 ` Nutty.Liu
@ 2025-11-04 7:41 ` Anup Patel
2025-11-04 12:53 ` Wu Fei
2 siblings, 1 reply; 6+ messages in thread
From: Anup Patel @ 2025-11-04 7:41 UTC (permalink / raw)
To: wu.fei9; +Cc: kvm-riscv, ajones, rkrcmar
On Wed, Oct 29, 2025 at 5:09 PM <wu.fei9@sanechips.com.cn> wrote:
>
> Current vm modes cannot represent riscv guest modes precisely, here add
> all 9 combinations of P(56,40,41) x V(57,48,39). Also the default vm
> mode is detected on runtime instead of hardcoded one, which might not be
> supported on specific machine.
>
> Signed-off-by: Wu Fei <wu.fei9@sanechips.com.cn>
LGTM.
Reviewed-by: Anup Patel <anup@brainfault.org>
Please resend the patch CC'ing kvm@vger.kernel.org so that
folks working other architectures can also review.
Regards,
Anup
> ---
> .../testing/selftests/kvm/include/kvm_util.h | 17 ++++-
> .../selftests/kvm/include/riscv/processor.h | 2 +
> tools/testing/selftests/kvm/lib/guest_modes.c | 41 +++++++++---
> tools/testing/selftests/kvm/lib/kvm_util.c | 33 ++++++++++
> .../selftests/kvm/lib/riscv/processor.c | 63 +++++++++++++++++--
> 5 files changed, 142 insertions(+), 14 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
> index bee65ca08721..2055f0f5df82 100644
> --- a/tools/testing/selftests/kvm/include/kvm_util.h
> +++ b/tools/testing/selftests/kvm/include/kvm_util.h
> @@ -179,6 +179,17 @@ enum vm_guest_mode {
> VM_MODE_P36V48_64K,
> VM_MODE_P47V47_16K,
> VM_MODE_P36V47_16K,
> +
> + VM_MODE_P56V57_4K, /* For riscv64 */
> + VM_MODE_P56V48_4K,
> + VM_MODE_P56V39_4K,
> + VM_MODE_P50V57_4K,
> + VM_MODE_P50V48_4K,
> + VM_MODE_P50V39_4K,
> + VM_MODE_P41V57_4K,
> + VM_MODE_P41V48_4K,
> + VM_MODE_P41V39_4K,
> +
> NUM_VM_MODES,
> };
>
> @@ -203,10 +214,10 @@ kvm_static_assert(sizeof(struct vm_shape) == sizeof(uint64_t));
> shape; \
> })
>
> -#if defined(__aarch64__)
> -
> extern enum vm_guest_mode vm_mode_default;
>
> +#if defined(__aarch64__)
> +
> #define VM_MODE_DEFAULT vm_mode_default
> #define MIN_PAGE_SHIFT 12U
> #define ptes_per_page(page_size) ((page_size) / 8)
> @@ -229,7 +240,7 @@ extern enum vm_guest_mode vm_mode_default;
> #error "RISC-V 32-bit kvm selftests not supported"
> #endif
>
> -#define VM_MODE_DEFAULT VM_MODE_P40V48_4K
> +#define VM_MODE_DEFAULT vm_mode_default
> #define MIN_PAGE_SHIFT 12U
> #define ptes_per_page(page_size) ((page_size) / 8)
>
> diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
> index 162f303d9daa..2d5a5548e698 100644
> --- a/tools/testing/selftests/kvm/include/riscv/processor.h
> +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
> @@ -191,4 +191,6 @@ static inline void local_irq_disable(void)
> csr_clear(CSR_SSTATUS, SR_SIE);
> }
>
> +unsigned long riscv64_get_satp_mode(void);
> +
> #endif /* SELFTEST_KVM_PROCESSOR_H */
> diff --git a/tools/testing/selftests/kvm/lib/guest_modes.c b/tools/testing/selftests/kvm/lib/guest_modes.c
> index b04901e55138..ce3099630397 100644
> --- a/tools/testing/selftests/kvm/lib/guest_modes.c
> +++ b/tools/testing/selftests/kvm/lib/guest_modes.c
> @@ -4,7 +4,7 @@
> */
> #include "guest_modes.h"
>
> -#ifdef __aarch64__
> +#if defined(__aarch64__) || defined(__riscv)
> #include "processor.h"
> enum vm_guest_mode vm_mode_default;
> #endif
> @@ -13,9 +13,11 @@ struct guest_mode guest_modes[NUM_VM_MODES];
>
> void guest_modes_append_default(void)
> {
> -#ifndef __aarch64__
> +#if !defined(__aarch64__) && !defined(__riscv)
> guest_mode_append(VM_MODE_DEFAULT, true);
> -#else
> +#endif
> +
> +#ifdef __aarch64__
> {
> unsigned int limit = kvm_check_cap(KVM_CAP_ARM_VM_IPA_SIZE);
> uint32_t ipa4k, ipa16k, ipa64k;
> @@ -74,11 +76,36 @@ void guest_modes_append_default(void)
> #ifdef __riscv
> {
> unsigned int sz = kvm_check_cap(KVM_CAP_VM_GPA_BITS);
> + unsigned long satp_mode = riscv64_get_satp_mode() << SATP_MODE_SHIFT;
> + int i;
>
> - if (sz >= 52)
> - guest_mode_append(VM_MODE_P52V48_4K, true);
> - if (sz >= 48)
> - guest_mode_append(VM_MODE_P48V48_4K, true);
> + switch (sz) {
> + case 59:
> + guest_mode_append(VM_MODE_P56V57_4K, satp_mode >= SATP_MODE_57);
> + guest_mode_append(VM_MODE_P56V48_4K, satp_mode >= SATP_MODE_48);
> + guest_mode_append(VM_MODE_P56V39_4K, satp_mode >= SATP_MODE_39);
> + break;
> + case 50:
> + guest_mode_append(VM_MODE_P50V57_4K, satp_mode >= SATP_MODE_57);
> + guest_mode_append(VM_MODE_P50V48_4K, satp_mode >= SATP_MODE_48);
> + guest_mode_append(VM_MODE_P50V39_4K, satp_mode >= SATP_MODE_39);
> + break;
> + case 41:
> + guest_mode_append(VM_MODE_P41V57_4K, satp_mode >= SATP_MODE_57);
> + guest_mode_append(VM_MODE_P41V48_4K, satp_mode >= SATP_MODE_48);
> + guest_mode_append(VM_MODE_P41V39_4K, satp_mode >= SATP_MODE_39);
> + break;
> + default:
> + break;
> + }
> +
> + /* set the first supported mode as default */
> + vm_mode_default = NUM_VM_MODES;
> + for (i = 0; vm_mode_default == NUM_VM_MODES && i < NUM_VM_MODES; i++) {
> + if (guest_modes[i].supported && guest_modes[i].enabled)
> + vm_mode_default = i;
> + }
> + TEST_ASSERT(vm_mode_default != NUM_VM_MODES, "No supported mode!");
> }
> #endif
> }
> diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
> index a055343a7bf7..9803e61ae7db 100644
> --- a/tools/testing/selftests/kvm/lib/kvm_util.c
> +++ b/tools/testing/selftests/kvm/lib/kvm_util.c
> @@ -224,6 +224,15 @@ const char *vm_guest_mode_string(uint32_t i)
> [VM_MODE_P36V48_64K] = "PA-bits:36, VA-bits:48, 64K pages",
> [VM_MODE_P47V47_16K] = "PA-bits:47, VA-bits:47, 16K pages",
> [VM_MODE_P36V47_16K] = "PA-bits:36, VA-bits:47, 16K pages",
> + [VM_MODE_P56V57_4K] = "PA-bits:56, VA-bits:57, 4K pages",
> + [VM_MODE_P56V48_4K] = "PA-bits:56, VA-bits:48, 4K pages",
> + [VM_MODE_P56V39_4K] = "PA-bits:56, VA-bits:39, 4K pages",
> + [VM_MODE_P50V57_4K] = "PA-bits:50, VA-bits:57, 4K pages",
> + [VM_MODE_P50V48_4K] = "PA-bits:50, VA-bits:48, 4K pages",
> + [VM_MODE_P50V39_4K] = "PA-bits:50, VA-bits:39, 4K pages",
> + [VM_MODE_P41V57_4K] = "PA-bits:41, VA-bits:57, 4K pages",
> + [VM_MODE_P41V48_4K] = "PA-bits:41, VA-bits:48, 4K pages",
> + [VM_MODE_P41V39_4K] = "PA-bits:41, VA-bits:39, 4K pages",
> };
> _Static_assert(sizeof(strings)/sizeof(char *) == NUM_VM_MODES,
> "Missing new mode strings?");
> @@ -251,6 +260,15 @@ const struct vm_guest_mode_params vm_guest_mode_params[] = {
> [VM_MODE_P36V48_64K] = { 36, 48, 0x10000, 16 },
> [VM_MODE_P47V47_16K] = { 47, 47, 0x4000, 14 },
> [VM_MODE_P36V47_16K] = { 36, 47, 0x4000, 14 },
> + [VM_MODE_P56V57_4K] = { 56, 57, 0x1000, 12 },
> + [VM_MODE_P56V48_4K] = { 56, 48, 0x1000, 12 },
> + [VM_MODE_P56V39_4K] = { 56, 39, 0x1000, 12 },
> + [VM_MODE_P50V57_4K] = { 50, 57, 0x1000, 12 },
> + [VM_MODE_P50V48_4K] = { 50, 48, 0x1000, 12 },
> + [VM_MODE_P50V39_4K] = { 50, 39, 0x1000, 12 },
> + [VM_MODE_P41V57_4K] = { 41, 57, 0x1000, 12 },
> + [VM_MODE_P41V48_4K] = { 41, 48, 0x1000, 12 },
> + [VM_MODE_P41V39_4K] = { 41, 39, 0x1000, 12 },
> };
> _Static_assert(sizeof(vm_guest_mode_params)/sizeof(struct vm_guest_mode_params) == NUM_VM_MODES,
> "Missing new mode params?");
> @@ -351,6 +369,21 @@ struct kvm_vm *____vm_create(struct vm_shape shape)
> case VM_MODE_P44V64_4K:
> vm->pgtable_levels = 5;
> break;
> + case VM_MODE_P56V57_4K:
> + case VM_MODE_P50V57_4K:
> + case VM_MODE_P41V57_4K:
> + vm->pgtable_levels = 5;
> + break;
> + case VM_MODE_P56V48_4K:
> + case VM_MODE_P50V48_4K:
> + case VM_MODE_P41V48_4K:
> + vm->pgtable_levels = 4;
> + break;
> + case VM_MODE_P56V39_4K:
> + case VM_MODE_P50V39_4K:
> + case VM_MODE_P41V39_4K:
> + vm->pgtable_levels = 3;
> + break;
> default:
> TEST_FAIL("Unknown guest mode: 0x%x", vm->mode);
> }
> diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
> index 2eac7d4b59e9..53675292b8eb 100644
> --- a/tools/testing/selftests/kvm/lib/riscv/processor.c
> +++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
> @@ -8,6 +8,7 @@
> #include <linux/compiler.h>
> #include <assert.h>
>
> +#include "guest_modes.h"
> #include "kvm_util.h"
> #include "processor.h"
> #include "ucall_common.h"
> @@ -197,22 +198,41 @@ void riscv_vcpu_mmu_setup(struct kvm_vcpu *vcpu)
> {
> struct kvm_vm *vm = vcpu->vm;
> unsigned long satp;
> + unsigned long satp_mode;
> + unsigned long max_satp_mode;
>
> /*
> * The RISC-V Sv48 MMU mode supports 56-bit physical address
> * for 48-bit virtual address with 4KB last level page size.
> */
> switch (vm->mode) {
> - case VM_MODE_P52V48_4K:
> - case VM_MODE_P48V48_4K:
> - case VM_MODE_P40V48_4K:
> + case VM_MODE_P56V57_4K:
> + case VM_MODE_P50V57_4K:
> + case VM_MODE_P41V57_4K:
> + satp_mode = SATP_MODE_57;
> + break;
> + case VM_MODE_P56V48_4K:
> + case VM_MODE_P50V48_4K:
> + case VM_MODE_P41V48_4K:
> + satp_mode = SATP_MODE_48;
> + break;
> + case VM_MODE_P56V39_4K:
> + case VM_MODE_P50V39_4K:
> + case VM_MODE_P41V39_4K:
> + satp_mode = SATP_MODE_39;
> break;
> default:
> TEST_FAIL("Unknown guest mode, mode: 0x%x", vm->mode);
> }
>
> + max_satp_mode = vcpu_get_reg(vcpu, RISCV_CONFIG_REG(satp_mode));
> +
> + if ((satp_mode >> SATP_MODE_SHIFT) > max_satp_mode)
> + TEST_FAIL("Unable to set satp mode 0x%lx, max mode 0x%lx\n",
> + satp_mode >> SATP_MODE_SHIFT, max_satp_mode);
> +
> satp = (vm->pgd >> PGTBL_PAGE_SIZE_SHIFT) & SATP_PPN;
> - satp |= SATP_MODE_48;
> + satp |= satp_mode;
>
> vcpu_set_reg(vcpu, RISCV_GENERAL_CSR_REG(satp), satp);
> }
> @@ -515,3 +535,38 @@ unsigned long get_host_sbi_spec_version(void)
>
> return ret.value;
> }
> +
> +void kvm_selftest_arch_init(void)
> +{
> + /*
> + * riscv64 doesn't have a true default mode, so start by detecting the
> + * supported vm mode.
> + */
> + guest_modes_append_default();
> +}
> +
> +unsigned long riscv64_get_satp_mode(void)
> +{
> + int kvm_fd, vm_fd, vcpu_fd, err;
> + uint64_t val;
> + struct kvm_one_reg reg = {
> + .id = RISCV_CONFIG_REG(satp_mode),
> + .addr = (uint64_t)&val,
> + };
> +
> + kvm_fd = open_kvm_dev_path_or_exit();
> + vm_fd = __kvm_ioctl(kvm_fd, KVM_CREATE_VM, NULL);
> + TEST_ASSERT(vm_fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VM, vm_fd));
> +
> + vcpu_fd = ioctl(vm_fd, KVM_CREATE_VCPU, 0);
> + TEST_ASSERT(vcpu_fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VCPU, vcpu_fd));
> +
> + err = ioctl(vcpu_fd, KVM_GET_ONE_REG, ®);
> + TEST_ASSERT(err == 0, KVM_IOCTL_ERROR(KVM_GET_ONE_REG, vcpu_fd));
> +
> + close(vcpu_fd);
> + close(vm_fd);
> + close(kvm_fd);
> +
> + return val;
> +}
> --
> 2.43.0
>
> --
> kvm-riscv mailing list
> kvm-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kvm-riscv
--
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] KVM: riscv: selftests: Add riscv vm satp modes
2025-11-04 7:41 ` Anup Patel
@ 2025-11-04 12:53 ` Wu Fei
2025-11-04 14:23 ` Andrew Jones
0 siblings, 1 reply; 6+ messages in thread
From: Wu Fei @ 2025-11-04 12:53 UTC (permalink / raw)
To: Anup Patel, wu.fei9; +Cc: kvm-riscv, ajones, rkrcmar
On 11/4/25 15:41, Anup Patel wrote:
> On Wed, Oct 29, 2025 at 5:09 PM <wu.fei9@sanechips.com.cn> wrote:
>>
>> Current vm modes cannot represent riscv guest modes precisely, here add
>> all 9 combinations of P(56,40,41) x V(57,48,39). Also the default vm
>> mode is detected on runtime instead of hardcoded one, which might not be
>> supported on specific machine.
>>
>> Signed-off-by: Wu Fei <wu.fei9@sanechips.com.cn>
>
> LGTM.
>
> Reviewed-by: Anup Patel <anup@brainfault.org>
>
> Please resend the patch CC'ing kvm@vger.kernel.org so that
> folks working other architectures can also review.
OK. As my company account is not working with git-send-email yet, is it
a valid option to use my personal email to send the patch on behalf of
company account?
Thanks,
Fei.
>
> Regards,
> Anup
>
>> ---
>> .../testing/selftests/kvm/include/kvm_util.h | 17 ++++-
>> .../selftests/kvm/include/riscv/processor.h | 2 +
>> tools/testing/selftests/kvm/lib/guest_modes.c | 41 +++++++++---
>> tools/testing/selftests/kvm/lib/kvm_util.c | 33 ++++++++++
>> .../selftests/kvm/lib/riscv/processor.c | 63 +++++++++++++++++--
>> 5 files changed, 142 insertions(+), 14 deletions(-)
>>
>> diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
>> index bee65ca08721..2055f0f5df82 100644
>> --- a/tools/testing/selftests/kvm/include/kvm_util.h
>> +++ b/tools/testing/selftests/kvm/include/kvm_util.h
>> @@ -179,6 +179,17 @@ enum vm_guest_mode {
>> VM_MODE_P36V48_64K,
>> VM_MODE_P47V47_16K,
>> VM_MODE_P36V47_16K,
>> +
>> + VM_MODE_P56V57_4K, /* For riscv64 */
>> + VM_MODE_P56V48_4K,
>> + VM_MODE_P56V39_4K,
>> + VM_MODE_P50V57_4K,
>> + VM_MODE_P50V48_4K,
>> + VM_MODE_P50V39_4K,
>> + VM_MODE_P41V57_4K,
>> + VM_MODE_P41V48_4K,
>> + VM_MODE_P41V39_4K,
>> +
>> NUM_VM_MODES,
>> };
>>
>> @@ -203,10 +214,10 @@ kvm_static_assert(sizeof(struct vm_shape) == sizeof(uint64_t));
>> shape; \
>> })
>>
>> -#if defined(__aarch64__)
>> -
>> extern enum vm_guest_mode vm_mode_default;
>>
>> +#if defined(__aarch64__)
>> +
>> #define VM_MODE_DEFAULT vm_mode_default
>> #define MIN_PAGE_SHIFT 12U
>> #define ptes_per_page(page_size) ((page_size) / 8)
>> @@ -229,7 +240,7 @@ extern enum vm_guest_mode vm_mode_default;
>> #error "RISC-V 32-bit kvm selftests not supported"
>> #endif
>>
>> -#define VM_MODE_DEFAULT VM_MODE_P40V48_4K
>> +#define VM_MODE_DEFAULT vm_mode_default
>> #define MIN_PAGE_SHIFT 12U
>> #define ptes_per_page(page_size) ((page_size) / 8)
>>
>> diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
>> index 162f303d9daa..2d5a5548e698 100644
>> --- a/tools/testing/selftests/kvm/include/riscv/processor.h
>> +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
>> @@ -191,4 +191,6 @@ static inline void local_irq_disable(void)
>> csr_clear(CSR_SSTATUS, SR_SIE);
>> }
>>
>> +unsigned long riscv64_get_satp_mode(void);
>> +
>> #endif /* SELFTEST_KVM_PROCESSOR_H */
>> diff --git a/tools/testing/selftests/kvm/lib/guest_modes.c b/tools/testing/selftests/kvm/lib/guest_modes.c
>> index b04901e55138..ce3099630397 100644
>> --- a/tools/testing/selftests/kvm/lib/guest_modes.c
>> +++ b/tools/testing/selftests/kvm/lib/guest_modes.c
>> @@ -4,7 +4,7 @@
>> */
>> #include "guest_modes.h"
>>
>> -#ifdef __aarch64__
>> +#if defined(__aarch64__) || defined(__riscv)
>> #include "processor.h"
>> enum vm_guest_mode vm_mode_default;
>> #endif
>> @@ -13,9 +13,11 @@ struct guest_mode guest_modes[NUM_VM_MODES];
>>
>> void guest_modes_append_default(void)
>> {
>> -#ifndef __aarch64__
>> +#if !defined(__aarch64__) && !defined(__riscv)
>> guest_mode_append(VM_MODE_DEFAULT, true);
>> -#else
>> +#endif
>> +
>> +#ifdef __aarch64__
>> {
>> unsigned int limit = kvm_check_cap(KVM_CAP_ARM_VM_IPA_SIZE);
>> uint32_t ipa4k, ipa16k, ipa64k;
>> @@ -74,11 +76,36 @@ void guest_modes_append_default(void)
>> #ifdef __riscv
>> {
>> unsigned int sz = kvm_check_cap(KVM_CAP_VM_GPA_BITS);
>> + unsigned long satp_mode = riscv64_get_satp_mode() << SATP_MODE_SHIFT;
>> + int i;
>>
>> - if (sz >= 52)
>> - guest_mode_append(VM_MODE_P52V48_4K, true);
>> - if (sz >= 48)
>> - guest_mode_append(VM_MODE_P48V48_4K, true);
>> + switch (sz) {
>> + case 59:
>> + guest_mode_append(VM_MODE_P56V57_4K, satp_mode >= SATP_MODE_57);
>> + guest_mode_append(VM_MODE_P56V48_4K, satp_mode >= SATP_MODE_48);
>> + guest_mode_append(VM_MODE_P56V39_4K, satp_mode >= SATP_MODE_39);
>> + break;
>> + case 50:
>> + guest_mode_append(VM_MODE_P50V57_4K, satp_mode >= SATP_MODE_57);
>> + guest_mode_append(VM_MODE_P50V48_4K, satp_mode >= SATP_MODE_48);
>> + guest_mode_append(VM_MODE_P50V39_4K, satp_mode >= SATP_MODE_39);
>> + break;
>> + case 41:
>> + guest_mode_append(VM_MODE_P41V57_4K, satp_mode >= SATP_MODE_57);
>> + guest_mode_append(VM_MODE_P41V48_4K, satp_mode >= SATP_MODE_48);
>> + guest_mode_append(VM_MODE_P41V39_4K, satp_mode >= SATP_MODE_39);
>> + break;
>> + default:
>> + break;
>> + }
>> +
>> + /* set the first supported mode as default */
>> + vm_mode_default = NUM_VM_MODES;
>> + for (i = 0; vm_mode_default == NUM_VM_MODES && i < NUM_VM_MODES; i++) {
>> + if (guest_modes[i].supported && guest_modes[i].enabled)
>> + vm_mode_default = i;
>> + }
>> + TEST_ASSERT(vm_mode_default != NUM_VM_MODES, "No supported mode!");
>> }
>> #endif
>> }
>> diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
>> index a055343a7bf7..9803e61ae7db 100644
>> --- a/tools/testing/selftests/kvm/lib/kvm_util.c
>> +++ b/tools/testing/selftests/kvm/lib/kvm_util.c
>> @@ -224,6 +224,15 @@ const char *vm_guest_mode_string(uint32_t i)
>> [VM_MODE_P36V48_64K] = "PA-bits:36, VA-bits:48, 64K pages",
>> [VM_MODE_P47V47_16K] = "PA-bits:47, VA-bits:47, 16K pages",
>> [VM_MODE_P36V47_16K] = "PA-bits:36, VA-bits:47, 16K pages",
>> + [VM_MODE_P56V57_4K] = "PA-bits:56, VA-bits:57, 4K pages",
>> + [VM_MODE_P56V48_4K] = "PA-bits:56, VA-bits:48, 4K pages",
>> + [VM_MODE_P56V39_4K] = "PA-bits:56, VA-bits:39, 4K pages",
>> + [VM_MODE_P50V57_4K] = "PA-bits:50, VA-bits:57, 4K pages",
>> + [VM_MODE_P50V48_4K] = "PA-bits:50, VA-bits:48, 4K pages",
>> + [VM_MODE_P50V39_4K] = "PA-bits:50, VA-bits:39, 4K pages",
>> + [VM_MODE_P41V57_4K] = "PA-bits:41, VA-bits:57, 4K pages",
>> + [VM_MODE_P41V48_4K] = "PA-bits:41, VA-bits:48, 4K pages",
>> + [VM_MODE_P41V39_4K] = "PA-bits:41, VA-bits:39, 4K pages",
>> };
>> _Static_assert(sizeof(strings)/sizeof(char *) == NUM_VM_MODES,
>> "Missing new mode strings?");
>> @@ -251,6 +260,15 @@ const struct vm_guest_mode_params vm_guest_mode_params[] = {
>> [VM_MODE_P36V48_64K] = { 36, 48, 0x10000, 16 },
>> [VM_MODE_P47V47_16K] = { 47, 47, 0x4000, 14 },
>> [VM_MODE_P36V47_16K] = { 36, 47, 0x4000, 14 },
>> + [VM_MODE_P56V57_4K] = { 56, 57, 0x1000, 12 },
>> + [VM_MODE_P56V48_4K] = { 56, 48, 0x1000, 12 },
>> + [VM_MODE_P56V39_4K] = { 56, 39, 0x1000, 12 },
>> + [VM_MODE_P50V57_4K] = { 50, 57, 0x1000, 12 },
>> + [VM_MODE_P50V48_4K] = { 50, 48, 0x1000, 12 },
>> + [VM_MODE_P50V39_4K] = { 50, 39, 0x1000, 12 },
>> + [VM_MODE_P41V57_4K] = { 41, 57, 0x1000, 12 },
>> + [VM_MODE_P41V48_4K] = { 41, 48, 0x1000, 12 },
>> + [VM_MODE_P41V39_4K] = { 41, 39, 0x1000, 12 },
>> };
>> _Static_assert(sizeof(vm_guest_mode_params)/sizeof(struct vm_guest_mode_params) == NUM_VM_MODES,
>> "Missing new mode params?");
>> @@ -351,6 +369,21 @@ struct kvm_vm *____vm_create(struct vm_shape shape)
>> case VM_MODE_P44V64_4K:
>> vm->pgtable_levels = 5;
>> break;
>> + case VM_MODE_P56V57_4K:
>> + case VM_MODE_P50V57_4K:
>> + case VM_MODE_P41V57_4K:
>> + vm->pgtable_levels = 5;
>> + break;
>> + case VM_MODE_P56V48_4K:
>> + case VM_MODE_P50V48_4K:
>> + case VM_MODE_P41V48_4K:
>> + vm->pgtable_levels = 4;
>> + break;
>> + case VM_MODE_P56V39_4K:
>> + case VM_MODE_P50V39_4K:
>> + case VM_MODE_P41V39_4K:
>> + vm->pgtable_levels = 3;
>> + break;
>> default:
>> TEST_FAIL("Unknown guest mode: 0x%x", vm->mode);
>> }
>> diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
>> index 2eac7d4b59e9..53675292b8eb 100644
>> --- a/tools/testing/selftests/kvm/lib/riscv/processor.c
>> +++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
>> @@ -8,6 +8,7 @@
>> #include <linux/compiler.h>
>> #include <assert.h>
>>
>> +#include "guest_modes.h"
>> #include "kvm_util.h"
>> #include "processor.h"
>> #include "ucall_common.h"
>> @@ -197,22 +198,41 @@ void riscv_vcpu_mmu_setup(struct kvm_vcpu *vcpu)
>> {
>> struct kvm_vm *vm = vcpu->vm;
>> unsigned long satp;
>> + unsigned long satp_mode;
>> + unsigned long max_satp_mode;
>>
>> /*
>> * The RISC-V Sv48 MMU mode supports 56-bit physical address
>> * for 48-bit virtual address with 4KB last level page size.
>> */
>> switch (vm->mode) {
>> - case VM_MODE_P52V48_4K:
>> - case VM_MODE_P48V48_4K:
>> - case VM_MODE_P40V48_4K:
>> + case VM_MODE_P56V57_4K:
>> + case VM_MODE_P50V57_4K:
>> + case VM_MODE_P41V57_4K:
>> + satp_mode = SATP_MODE_57;
>> + break;
>> + case VM_MODE_P56V48_4K:
>> + case VM_MODE_P50V48_4K:
>> + case VM_MODE_P41V48_4K:
>> + satp_mode = SATP_MODE_48;
>> + break;
>> + case VM_MODE_P56V39_4K:
>> + case VM_MODE_P50V39_4K:
>> + case VM_MODE_P41V39_4K:
>> + satp_mode = SATP_MODE_39;
>> break;
>> default:
>> TEST_FAIL("Unknown guest mode, mode: 0x%x", vm->mode);
>> }
>>
>> + max_satp_mode = vcpu_get_reg(vcpu, RISCV_CONFIG_REG(satp_mode));
>> +
>> + if ((satp_mode >> SATP_MODE_SHIFT) > max_satp_mode)
>> + TEST_FAIL("Unable to set satp mode 0x%lx, max mode 0x%lx\n",
>> + satp_mode >> SATP_MODE_SHIFT, max_satp_mode);
>> +
>> satp = (vm->pgd >> PGTBL_PAGE_SIZE_SHIFT) & SATP_PPN;
>> - satp |= SATP_MODE_48;
>> + satp |= satp_mode;
>>
>> vcpu_set_reg(vcpu, RISCV_GENERAL_CSR_REG(satp), satp);
>> }
>> @@ -515,3 +535,38 @@ unsigned long get_host_sbi_spec_version(void)
>>
>> return ret.value;
>> }
>> +
>> +void kvm_selftest_arch_init(void)
>> +{
>> + /*
>> + * riscv64 doesn't have a true default mode, so start by detecting the
>> + * supported vm mode.
>> + */
>> + guest_modes_append_default();
>> +}
>> +
>> +unsigned long riscv64_get_satp_mode(void)
>> +{
>> + int kvm_fd, vm_fd, vcpu_fd, err;
>> + uint64_t val;
>> + struct kvm_one_reg reg = {
>> + .id = RISCV_CONFIG_REG(satp_mode),
>> + .addr = (uint64_t)&val,
>> + };
>> +
>> + kvm_fd = open_kvm_dev_path_or_exit();
>> + vm_fd = __kvm_ioctl(kvm_fd, KVM_CREATE_VM, NULL);
>> + TEST_ASSERT(vm_fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VM, vm_fd));
>> +
>> + vcpu_fd = ioctl(vm_fd, KVM_CREATE_VCPU, 0);
>> + TEST_ASSERT(vcpu_fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VCPU, vcpu_fd));
>> +
>> + err = ioctl(vcpu_fd, KVM_GET_ONE_REG, ®);
>> + TEST_ASSERT(err == 0, KVM_IOCTL_ERROR(KVM_GET_ONE_REG, vcpu_fd));
>> +
>> + close(vcpu_fd);
>> + close(vm_fd);
>> + close(kvm_fd);
>> +
>> + return val;
>> +}
>> --
>> 2.43.0
>>
>> --
>> kvm-riscv mailing list
>> kvm-riscv@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kvm-riscv
>
--
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] KVM: riscv: selftests: Add riscv vm satp modes
2025-11-04 12:53 ` Wu Fei
@ 2025-11-04 14:23 ` Andrew Jones
0 siblings, 0 replies; 6+ messages in thread
From: Andrew Jones @ 2025-11-04 14:23 UTC (permalink / raw)
To: Wu Fei; +Cc: Anup Patel, wu.fei9, kvm-riscv, rkrcmar
On Tue, Nov 04, 2025 at 08:53:27PM +0800, Wu Fei wrote:
> On 11/4/25 15:41, Anup Patel wrote:
> > On Wed, Oct 29, 2025 at 5:09 PM <wu.fei9@sanechips.com.cn> wrote:
> > >
> > > Current vm modes cannot represent riscv guest modes precisely, here add
> > > all 9 combinations of P(56,40,41) x V(57,48,39). Also the default vm
> > > mode is detected on runtime instead of hardcoded one, which might not be
> > > supported on specific machine.
> > >
> > > Signed-off-by: Wu Fei <wu.fei9@sanechips.com.cn>
> >
> > LGTM.
> >
> > Reviewed-by: Anup Patel <anup@brainfault.org>
> >
> > Please resend the patch CC'ing kvm@vger.kernel.org so that
> > folks working other architectures can also review.
>
> OK. As my company account is not working with git-send-email yet, is it a
> valid option to use my personal email to send the patch on behalf of company
> account?
Yes, what likely matters to your company is that your sign-off is with
your company email address, but there is no requirement for either the
address that sends the patch nor what address is used for the sign-off
on the community / mailing list side.
Thanks,
drew
>
> Thanks,
> Fei.
>
> >
> > Regards,
> > Anup
> >
> > > ---
> > > .../testing/selftests/kvm/include/kvm_util.h | 17 ++++-
> > > .../selftests/kvm/include/riscv/processor.h | 2 +
> > > tools/testing/selftests/kvm/lib/guest_modes.c | 41 +++++++++---
> > > tools/testing/selftests/kvm/lib/kvm_util.c | 33 ++++++++++
> > > .../selftests/kvm/lib/riscv/processor.c | 63 +++++++++++++++++--
> > > 5 files changed, 142 insertions(+), 14 deletions(-)
> > >
> > > diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
> > > index bee65ca08721..2055f0f5df82 100644
> > > --- a/tools/testing/selftests/kvm/include/kvm_util.h
> > > +++ b/tools/testing/selftests/kvm/include/kvm_util.h
> > > @@ -179,6 +179,17 @@ enum vm_guest_mode {
> > > VM_MODE_P36V48_64K,
> > > VM_MODE_P47V47_16K,
> > > VM_MODE_P36V47_16K,
> > > +
> > > + VM_MODE_P56V57_4K, /* For riscv64 */
> > > + VM_MODE_P56V48_4K,
> > > + VM_MODE_P56V39_4K,
> > > + VM_MODE_P50V57_4K,
> > > + VM_MODE_P50V48_4K,
> > > + VM_MODE_P50V39_4K,
> > > + VM_MODE_P41V57_4K,
> > > + VM_MODE_P41V48_4K,
> > > + VM_MODE_P41V39_4K,
> > > +
> > > NUM_VM_MODES,
> > > };
> > >
> > > @@ -203,10 +214,10 @@ kvm_static_assert(sizeof(struct vm_shape) == sizeof(uint64_t));
> > > shape; \
> > > })
> > >
> > > -#if defined(__aarch64__)
> > > -
> > > extern enum vm_guest_mode vm_mode_default;
> > >
> > > +#if defined(__aarch64__)
> > > +
> > > #define VM_MODE_DEFAULT vm_mode_default
> > > #define MIN_PAGE_SHIFT 12U
> > > #define ptes_per_page(page_size) ((page_size) / 8)
> > > @@ -229,7 +240,7 @@ extern enum vm_guest_mode vm_mode_default;
> > > #error "RISC-V 32-bit kvm selftests not supported"
> > > #endif
> > >
> > > -#define VM_MODE_DEFAULT VM_MODE_P40V48_4K
> > > +#define VM_MODE_DEFAULT vm_mode_default
> > > #define MIN_PAGE_SHIFT 12U
> > > #define ptes_per_page(page_size) ((page_size) / 8)
> > >
> > > diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
> > > index 162f303d9daa..2d5a5548e698 100644
> > > --- a/tools/testing/selftests/kvm/include/riscv/processor.h
> > > +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
> > > @@ -191,4 +191,6 @@ static inline void local_irq_disable(void)
> > > csr_clear(CSR_SSTATUS, SR_SIE);
> > > }
> > >
> > > +unsigned long riscv64_get_satp_mode(void);
> > > +
> > > #endif /* SELFTEST_KVM_PROCESSOR_H */
> > > diff --git a/tools/testing/selftests/kvm/lib/guest_modes.c b/tools/testing/selftests/kvm/lib/guest_modes.c
> > > index b04901e55138..ce3099630397 100644
> > > --- a/tools/testing/selftests/kvm/lib/guest_modes.c
> > > +++ b/tools/testing/selftests/kvm/lib/guest_modes.c
> > > @@ -4,7 +4,7 @@
> > > */
> > > #include "guest_modes.h"
> > >
> > > -#ifdef __aarch64__
> > > +#if defined(__aarch64__) || defined(__riscv)
> > > #include "processor.h"
> > > enum vm_guest_mode vm_mode_default;
> > > #endif
> > > @@ -13,9 +13,11 @@ struct guest_mode guest_modes[NUM_VM_MODES];
> > >
> > > void guest_modes_append_default(void)
> > > {
> > > -#ifndef __aarch64__
> > > +#if !defined(__aarch64__) && !defined(__riscv)
> > > guest_mode_append(VM_MODE_DEFAULT, true);
> > > -#else
> > > +#endif
> > > +
> > > +#ifdef __aarch64__
> > > {
> > > unsigned int limit = kvm_check_cap(KVM_CAP_ARM_VM_IPA_SIZE);
> > > uint32_t ipa4k, ipa16k, ipa64k;
> > > @@ -74,11 +76,36 @@ void guest_modes_append_default(void)
> > > #ifdef __riscv
> > > {
> > > unsigned int sz = kvm_check_cap(KVM_CAP_VM_GPA_BITS);
> > > + unsigned long satp_mode = riscv64_get_satp_mode() << SATP_MODE_SHIFT;
> > > + int i;
> > >
> > > - if (sz >= 52)
> > > - guest_mode_append(VM_MODE_P52V48_4K, true);
> > > - if (sz >= 48)
> > > - guest_mode_append(VM_MODE_P48V48_4K, true);
> > > + switch (sz) {
> > > + case 59:
> > > + guest_mode_append(VM_MODE_P56V57_4K, satp_mode >= SATP_MODE_57);
> > > + guest_mode_append(VM_MODE_P56V48_4K, satp_mode >= SATP_MODE_48);
> > > + guest_mode_append(VM_MODE_P56V39_4K, satp_mode >= SATP_MODE_39);
> > > + break;
> > > + case 50:
> > > + guest_mode_append(VM_MODE_P50V57_4K, satp_mode >= SATP_MODE_57);
> > > + guest_mode_append(VM_MODE_P50V48_4K, satp_mode >= SATP_MODE_48);
> > > + guest_mode_append(VM_MODE_P50V39_4K, satp_mode >= SATP_MODE_39);
> > > + break;
> > > + case 41:
> > > + guest_mode_append(VM_MODE_P41V57_4K, satp_mode >= SATP_MODE_57);
> > > + guest_mode_append(VM_MODE_P41V48_4K, satp_mode >= SATP_MODE_48);
> > > + guest_mode_append(VM_MODE_P41V39_4K, satp_mode >= SATP_MODE_39);
> > > + break;
> > > + default:
> > > + break;
> > > + }
> > > +
> > > + /* set the first supported mode as default */
> > > + vm_mode_default = NUM_VM_MODES;
> > > + for (i = 0; vm_mode_default == NUM_VM_MODES && i < NUM_VM_MODES; i++) {
> > > + if (guest_modes[i].supported && guest_modes[i].enabled)
> > > + vm_mode_default = i;
> > > + }
> > > + TEST_ASSERT(vm_mode_default != NUM_VM_MODES, "No supported mode!");
> > > }
> > > #endif
> > > }
> > > diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
> > > index a055343a7bf7..9803e61ae7db 100644
> > > --- a/tools/testing/selftests/kvm/lib/kvm_util.c
> > > +++ b/tools/testing/selftests/kvm/lib/kvm_util.c
> > > @@ -224,6 +224,15 @@ const char *vm_guest_mode_string(uint32_t i)
> > > [VM_MODE_P36V48_64K] = "PA-bits:36, VA-bits:48, 64K pages",
> > > [VM_MODE_P47V47_16K] = "PA-bits:47, VA-bits:47, 16K pages",
> > > [VM_MODE_P36V47_16K] = "PA-bits:36, VA-bits:47, 16K pages",
> > > + [VM_MODE_P56V57_4K] = "PA-bits:56, VA-bits:57, 4K pages",
> > > + [VM_MODE_P56V48_4K] = "PA-bits:56, VA-bits:48, 4K pages",
> > > + [VM_MODE_P56V39_4K] = "PA-bits:56, VA-bits:39, 4K pages",
> > > + [VM_MODE_P50V57_4K] = "PA-bits:50, VA-bits:57, 4K pages",
> > > + [VM_MODE_P50V48_4K] = "PA-bits:50, VA-bits:48, 4K pages",
> > > + [VM_MODE_P50V39_4K] = "PA-bits:50, VA-bits:39, 4K pages",
> > > + [VM_MODE_P41V57_4K] = "PA-bits:41, VA-bits:57, 4K pages",
> > > + [VM_MODE_P41V48_4K] = "PA-bits:41, VA-bits:48, 4K pages",
> > > + [VM_MODE_P41V39_4K] = "PA-bits:41, VA-bits:39, 4K pages",
> > > };
> > > _Static_assert(sizeof(strings)/sizeof(char *) == NUM_VM_MODES,
> > > "Missing new mode strings?");
> > > @@ -251,6 +260,15 @@ const struct vm_guest_mode_params vm_guest_mode_params[] = {
> > > [VM_MODE_P36V48_64K] = { 36, 48, 0x10000, 16 },
> > > [VM_MODE_P47V47_16K] = { 47, 47, 0x4000, 14 },
> > > [VM_MODE_P36V47_16K] = { 36, 47, 0x4000, 14 },
> > > + [VM_MODE_P56V57_4K] = { 56, 57, 0x1000, 12 },
> > > + [VM_MODE_P56V48_4K] = { 56, 48, 0x1000, 12 },
> > > + [VM_MODE_P56V39_4K] = { 56, 39, 0x1000, 12 },
> > > + [VM_MODE_P50V57_4K] = { 50, 57, 0x1000, 12 },
> > > + [VM_MODE_P50V48_4K] = { 50, 48, 0x1000, 12 },
> > > + [VM_MODE_P50V39_4K] = { 50, 39, 0x1000, 12 },
> > > + [VM_MODE_P41V57_4K] = { 41, 57, 0x1000, 12 },
> > > + [VM_MODE_P41V48_4K] = { 41, 48, 0x1000, 12 },
> > > + [VM_MODE_P41V39_4K] = { 41, 39, 0x1000, 12 },
> > > };
> > > _Static_assert(sizeof(vm_guest_mode_params)/sizeof(struct vm_guest_mode_params) == NUM_VM_MODES,
> > > "Missing new mode params?");
> > > @@ -351,6 +369,21 @@ struct kvm_vm *____vm_create(struct vm_shape shape)
> > > case VM_MODE_P44V64_4K:
> > > vm->pgtable_levels = 5;
> > > break;
> > > + case VM_MODE_P56V57_4K:
> > > + case VM_MODE_P50V57_4K:
> > > + case VM_MODE_P41V57_4K:
> > > + vm->pgtable_levels = 5;
> > > + break;
> > > + case VM_MODE_P56V48_4K:
> > > + case VM_MODE_P50V48_4K:
> > > + case VM_MODE_P41V48_4K:
> > > + vm->pgtable_levels = 4;
> > > + break;
> > > + case VM_MODE_P56V39_4K:
> > > + case VM_MODE_P50V39_4K:
> > > + case VM_MODE_P41V39_4K:
> > > + vm->pgtable_levels = 3;
> > > + break;
> > > default:
> > > TEST_FAIL("Unknown guest mode: 0x%x", vm->mode);
> > > }
> > > diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
> > > index 2eac7d4b59e9..53675292b8eb 100644
> > > --- a/tools/testing/selftests/kvm/lib/riscv/processor.c
> > > +++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
> > > @@ -8,6 +8,7 @@
> > > #include <linux/compiler.h>
> > > #include <assert.h>
> > >
> > > +#include "guest_modes.h"
> > > #include "kvm_util.h"
> > > #include "processor.h"
> > > #include "ucall_common.h"
> > > @@ -197,22 +198,41 @@ void riscv_vcpu_mmu_setup(struct kvm_vcpu *vcpu)
> > > {
> > > struct kvm_vm *vm = vcpu->vm;
> > > unsigned long satp;
> > > + unsigned long satp_mode;
> > > + unsigned long max_satp_mode;
> > >
> > > /*
> > > * The RISC-V Sv48 MMU mode supports 56-bit physical address
> > > * for 48-bit virtual address with 4KB last level page size.
> > > */
> > > switch (vm->mode) {
> > > - case VM_MODE_P52V48_4K:
> > > - case VM_MODE_P48V48_4K:
> > > - case VM_MODE_P40V48_4K:
> > > + case VM_MODE_P56V57_4K:
> > > + case VM_MODE_P50V57_4K:
> > > + case VM_MODE_P41V57_4K:
> > > + satp_mode = SATP_MODE_57;
> > > + break;
> > > + case VM_MODE_P56V48_4K:
> > > + case VM_MODE_P50V48_4K:
> > > + case VM_MODE_P41V48_4K:
> > > + satp_mode = SATP_MODE_48;
> > > + break;
> > > + case VM_MODE_P56V39_4K:
> > > + case VM_MODE_P50V39_4K:
> > > + case VM_MODE_P41V39_4K:
> > > + satp_mode = SATP_MODE_39;
> > > break;
> > > default:
> > > TEST_FAIL("Unknown guest mode, mode: 0x%x", vm->mode);
> > > }
> > >
> > > + max_satp_mode = vcpu_get_reg(vcpu, RISCV_CONFIG_REG(satp_mode));
> > > +
> > > + if ((satp_mode >> SATP_MODE_SHIFT) > max_satp_mode)
> > > + TEST_FAIL("Unable to set satp mode 0x%lx, max mode 0x%lx\n",
> > > + satp_mode >> SATP_MODE_SHIFT, max_satp_mode);
> > > +
> > > satp = (vm->pgd >> PGTBL_PAGE_SIZE_SHIFT) & SATP_PPN;
> > > - satp |= SATP_MODE_48;
> > > + satp |= satp_mode;
> > >
> > > vcpu_set_reg(vcpu, RISCV_GENERAL_CSR_REG(satp), satp);
> > > }
> > > @@ -515,3 +535,38 @@ unsigned long get_host_sbi_spec_version(void)
> > >
> > > return ret.value;
> > > }
> > > +
> > > +void kvm_selftest_arch_init(void)
> > > +{
> > > + /*
> > > + * riscv64 doesn't have a true default mode, so start by detecting the
> > > + * supported vm mode.
> > > + */
> > > + guest_modes_append_default();
> > > +}
> > > +
> > > +unsigned long riscv64_get_satp_mode(void)
> > > +{
> > > + int kvm_fd, vm_fd, vcpu_fd, err;
> > > + uint64_t val;
> > > + struct kvm_one_reg reg = {
> > > + .id = RISCV_CONFIG_REG(satp_mode),
> > > + .addr = (uint64_t)&val,
> > > + };
> > > +
> > > + kvm_fd = open_kvm_dev_path_or_exit();
> > > + vm_fd = __kvm_ioctl(kvm_fd, KVM_CREATE_VM, NULL);
> > > + TEST_ASSERT(vm_fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VM, vm_fd));
> > > +
> > > + vcpu_fd = ioctl(vm_fd, KVM_CREATE_VCPU, 0);
> > > + TEST_ASSERT(vcpu_fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VCPU, vcpu_fd));
> > > +
> > > + err = ioctl(vcpu_fd, KVM_GET_ONE_REG, ®);
> > > + TEST_ASSERT(err == 0, KVM_IOCTL_ERROR(KVM_GET_ONE_REG, vcpu_fd));
> > > +
> > > + close(vcpu_fd);
> > > + close(vm_fd);
> > > + close(kvm_fd);
> > > +
> > > + return val;
> > > +}
> > > --
> > > 2.43.0
> > >
> > > --
> > > kvm-riscv mailing list
> > > kvm-riscv@lists.infradead.org
> > > http://lists.infradead.org/mailman/listinfo/kvm-riscv
> >
>
>
> --
> kvm-riscv mailing list
> kvm-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kvm-riscv
--
kvm-riscv mailing list
kvm-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kvm-riscv
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-11-04 14:23 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-29 11:20 [PATCH v2] KVM: riscv: selftests: Add riscv vm satp modes wu.fei9
2025-10-31 19:26 ` Andrew Jones
2025-11-04 3:38 ` Nutty.Liu
2025-11-04 7:41 ` Anup Patel
2025-11-04 12:53 ` Wu Fei
2025-11-04 14:23 ` Andrew Jones
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).