aboutsummaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorDave Martin <Dave.Martin@arm.com>2018-12-19 09:27:01 -0500
committerMarc Zyngier <marc.zyngier@arm.com>2019-03-29 10:41:54 -0400
commit7dd32a0d0103a5941efbb971f85a3e930cc5665e (patch)
tree55f342707eaa1a5ea0fa838091c79dff01d9df2b /virt
parent0f062bfe36b63cd24f16afe2822d0df7c27904d9 (diff)
KVM: arm/arm64: Add KVM_ARM_VCPU_FINALIZE ioctl
Some aspects of vcpu configuration may be too complex to be completed inside KVM_ARM_VCPU_INIT. Thus, there may be a requirement for userspace to do some additional configuration before various other ioctls will work in a consistent way. In particular this will be the case for SVE, where userspace will need to negotiate the set of vector lengths to be made available to the guest before the vcpu becomes fully usable. In order to provide an explicit way for userspace to confirm that it has finished setting up a particular vcpu feature, this patch adds a new ioctl KVM_ARM_VCPU_FINALIZE. When userspace has opted into a feature that requires finalization, typically by means of a feature flag passed to KVM_ARM_VCPU_INIT, a matching call to KVM_ARM_VCPU_FINALIZE is now required before KVM_RUN or KVM_GET_REG_LIST is allowed. Individual features may impose additional restrictions where appropriate. No existing vcpu features are affected by this, so current userspace implementations will continue to work exactly as before, with no need to issue KVM_ARM_VCPU_FINALIZE. As implemented in this patch, KVM_ARM_VCPU_FINALIZE is currently a placeholder: no finalizable features exist yet, so ioctl is not required and will always yield EINVAL. Subsequent patches will add the finalization logic to make use of this ioctl for SVE. No functional change for existing userspace. Signed-off-by: Dave Martin <Dave.Martin@arm.com> Reviewed-by: Julien Thierry <julien.thierry@arm.com> Tested-by: zhang.lei <zhang.lei@jp.fujitsu.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/arm/arm.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index c69e1370a5dc..9edbf0f676e7 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -545,6 +545,9 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
545 if (likely(vcpu->arch.has_run_once)) 545 if (likely(vcpu->arch.has_run_once))
546 return 0; 546 return 0;
547 547
548 if (!kvm_arm_vcpu_is_finalized(vcpu))
549 return -EPERM;
550
548 vcpu->arch.has_run_once = true; 551 vcpu->arch.has_run_once = true;
549 552
550 if (likely(irqchip_in_kernel(kvm))) { 553 if (likely(irqchip_in_kernel(kvm))) {
@@ -1116,6 +1119,10 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
1116 if (unlikely(!kvm_vcpu_initialized(vcpu))) 1119 if (unlikely(!kvm_vcpu_initialized(vcpu)))
1117 break; 1120 break;
1118 1121
1122 r = -EPERM;
1123 if (!kvm_arm_vcpu_is_finalized(vcpu))
1124 break;
1125
1119 r = -EFAULT; 1126 r = -EFAULT;
1120 if (copy_from_user(&reg_list, user_list, sizeof(reg_list))) 1127 if (copy_from_user(&reg_list, user_list, sizeof(reg_list)))
1121 break; 1128 break;
@@ -1169,6 +1176,17 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
1169 1176
1170 return kvm_arm_vcpu_set_events(vcpu, &events); 1177 return kvm_arm_vcpu_set_events(vcpu, &events);
1171 } 1178 }
1179 case KVM_ARM_VCPU_FINALIZE: {
1180 int what;
1181
1182 if (!kvm_vcpu_initialized(vcpu))
1183 return -ENOEXEC;
1184
1185 if (get_user(what, (const int __user *)argp))
1186 return -EFAULT;
1187
1188 return kvm_arm_vcpu_finalize(vcpu, what);
1189 }
1172 default: 1190 default:
1173 r = -EINVAL; 1191 r = -EINVAL;
1174 } 1192 }