quoted
From: Fangyu Yu <redacted>
This capability allows userspace to explicitly select the HGATP mode
for the VM. The selected mode must be less than or equal to the max
HGATP mode supported by the hardware. This capability must be enabled
before creating any vCPUs, and can only be set once per VM.
Signed-off-by: Fangyu Yu <redacted>
---
diff --git a/arch/riscv/kvm/vm.c b/arch/riscv/kvm/vm.c
@@ -212,12 +219,27 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
{
+ if (cap->flags)
+ return -EINVAL;
switch (cap->cap) {
+ case KVM_CAP_RISCV_SET_HGATP_MODE:
+#ifdef CONFIG_64BIT
+ if (cap->args[0] < HGATP_MODE_SV39X4 ||
+ cap->args[0] > kvm_riscv_gstage_max_mode)
+ return -EINVAL;
+ if (kvm->arch.gstage_mode_initialized)
+ return 0;
"must be enabled before creating any vCPUs" check is missing.
Agreed, I'll add the missing "must be enabled before creating any vCPUs" check by
rejecting the capability once kvm->created_vcpus is non-zero.
quoted
+ kvm->arch.gstage_mode_initialized = true;
+ kvm->arch.kvm_riscv_gstage_mode = cap->args[0];
+ kvm->arch.kvm_riscv_gstage_pgd_levels = 3 +
+ kvm->arch.kvm_riscv_gstage_mode - HGATP_MODE_SV39X4;
Even before creating VCPUs, I don't see enough protections to make this
work.
Userspace can only provide a hint about the physical address space size
before any other KVM code could have acted on the information.
It would be a serious issue if some code would operate on hgatp as if it
were X and others as Y.
The simplest solution would be to ensure that the CAP_SET VM ioctl can
only be executed before any other IOCTL, but a change in generic code to
achieve it would be frowned upon...
I would recommend looking at kvm_are_all_memslots_empty() first, as it's
quite likely that it could be sufficient for the purposes of changing
hgatp.
Using kvm_are_all_memslots_empty might be a good idea, and I will add a
check for this function in the v2.
Thanks.
Thanks,
Fangyu