kvm-riscv.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [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, &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, &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, &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, &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).