[PATCH 1/2] KVM: riscv: selftests: Add riscv vm satp modes

Wu Fei atwufei at 163.com
Mon Oct 20 06:09:52 PDT 2025


On 10/17/25 23:38, Andrew Jones wrote:
> On Fri, Oct 17, 2025 at 11:13:33AM +0800, wu.fei9 at sanechips.com.cn wrote:
>> Current vm modes cannot represent riscv guest modes precisely, here add
>> P41V39, P50V48 and P56V57.
>>
>> Signed-off-by: Wu Fei <wu.fei9 at sanechips.com.cn>
>> ---
>>   .../testing/selftests/kvm/include/kvm_util.h  |  7 ++++++-
>>   tools/testing/selftests/kvm/lib/guest_modes.c |  7 +++----
>>   tools/testing/selftests/kvm/lib/kvm_util.c    | 15 +++++++++++++
>>   .../selftests/kvm/lib/riscv/processor.c       | 21 +++++++++++++++----
>>   4 files changed, 41 insertions(+), 9 deletions(-)
>>
>> diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
>> index bee65ca08721..02224bc514d4 100644
>> --- a/tools/testing/selftests/kvm/include/kvm_util.h
>> +++ b/tools/testing/selftests/kvm/include/kvm_util.h
>> @@ -179,6 +179,11 @@ enum vm_guest_mode {
>>          VM_MODE_P36V48_64K,
>>          VM_MODE_P47V47_16K,
>>          VM_MODE_P36V47_16K,
>> +
>> +       VM_MODE_P56V57_4K,      /* For riscv64 */
> 
> This should be P59

Although sv57x4 in hgatp does support P59, sv57 itself doesn't, so guest 
can only address 56bits gpa.

> 
>> +       VM_MODE_P50V48_4K,
>> +       VM_MODE_P41V39_4K,
>> +
>>          NUM_VM_MODES,
>>   };
>>
>> @@ -229,7 +234,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_P50V48_4K
>>   #define MIN_PAGE_SHIFT                 12U
>>   #define ptes_per_page(page_size)       ((page_size) / 8)
>>
>> diff --git a/tools/testing/selftests/kvm/lib/guest_modes.c b/tools/testing/selftests/kvm/lib/guest_modes.c
>> index b04901e55138..63d0d5479188 100644
>> --- a/tools/testing/selftests/kvm/lib/guest_modes.c
>> +++ b/tools/testing/selftests/kvm/lib/guest_modes.c
>> @@ -75,10 +75,9 @@ void guest_modes_append_default(void)
>>          {
>>                  unsigned int sz = kvm_check_cap(KVM_CAP_VM_GPA_BITS);
>>
>> -               if (sz >= 52)
>> -                       guest_mode_append(VM_MODE_P52V48_4K, true);
>> -               if (sz >= 48)
>> -                       guest_mode_append(VM_MODE_P48V48_4K, true);
>> +               guest_mode_append(VM_MODE_P56V57_4K, sz >= 59);
>> +               guest_mode_append(VM_MODE_P50V48_4K, sz >= 50);
>> +               guest_mode_append(VM_MODE_P41V39_4K, sz >= 41);
> 
> Even when the host doesn't support P59 a guest may still use V57 (and when
> a host doesn't support P50 a guest may still use V57 or V48). The host
> simply doesn't describe physical memory with address bit widths greater
> than its limits to the guest. Then the guest is free to use whatever
> virtual address width is supported by the MMU. IOW, we need all
> combinations of P and V widths for modes and then select similarly to how
> Arm has multiple modes to manage all the different page sizes. Also in
> order to know the maximum supported virtual bit width we need to
> get-one-reg satp_mode. We should do that here instead of in
> riscv_vcpu_mmu_setup() in order to filter out invalid modes when
> appending them.

Make sense, modes in satp/hgatp/vsatp are independent, more discussions 
in next patch.

Thanks,
Fei.

> 
> Thanks,
> drew
> 
>>          }
>>   #endif
>>   }
>> diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
>> index a055343a7bf7..4cd69fffa06d 100644
>> --- a/tools/testing/selftests/kvm/lib/kvm_util.c
>> +++ b/tools/testing/selftests/kvm/lib/kvm_util.c
>> @@ -224,6 +224,9 @@ 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_P50V48_4K]     = "PA-bits:50,  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 +254,9 @@ 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_P50V48_4K]     = { 50, 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 +357,15 @@ struct kvm_vm *____vm_create(struct vm_shape shape)
>>          case VM_MODE_P44V64_4K:
>>                  vm->pgtable_levels = 5;
>>                  break;
>> +       case VM_MODE_P56V57_4K:
>> +               vm->pgtable_levels = 5;
>> +               break;
>> +       case VM_MODE_P50V48_4K:
>> +               vm->pgtable_levels = 4;
>> +               break;
>> +       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..de84c092f982 100644
>> --- a/tools/testing/selftests/kvm/lib/riscv/processor.c
>> +++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
>> @@ -197,22 +197,35 @@ 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:
>> +               satp_mode = SATP_MODE_57;
>> +               break;
>> +       case VM_MODE_P50V48_4K:
>> +               satp_mode = SATP_MODE_48;
>> +               break;
>> +       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);
>>   }
>> --
>> 2.43.0
> 




More information about the kvm-riscv mailing list