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