KVM: x86: Allow userspace to set maximum VCPU id for VM
Introduce new max_vcpu_ids in KVM for x86 architecture. Userspace can assign maximum possible vcpu id for current VM session using KVM_CAP_MAX_VCPU_ID of KVM_ENABLE_CAP ioctl(). This is done for x86 only because the sole use case is to guide memory allocation for PID-pointer table, a structure needed to enable VMX IPI. By default, max_vcpu_ids set as KVM_MAX_VCPU_IDS. Suggested-by: Sean Christopherson <seanjc@google.com> Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com> Signed-off-by: Zeng Guang <guang.zeng@intel.com> Message-Id: <20220419154444.11888-1-guang.zeng@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
1d5e740d51
commit
3587531638
|
@ -7494,6 +7494,27 @@ The valid bits in cap.args[0] are:
|
|||
generate a #UD within the guest.
|
||||
=================================== ============================================
|
||||
|
||||
7.32 KVM_CAP_MAX_VCPU_ID
|
||||
------------------------
|
||||
|
||||
:Architectures: x86
|
||||
:Target: VM
|
||||
:Parameters: args[0] - maximum APIC ID value set for current VM
|
||||
:Returns: 0 on success, -EINVAL if args[0] is beyond KVM_MAX_VCPU_IDS
|
||||
supported in KVM or if it has been set.
|
||||
|
||||
This capability allows userspace to specify maximum possible APIC ID
|
||||
assigned for current VM session prior to the creation of vCPUs, saving
|
||||
memory for data structures indexed by the APIC ID. Userspace is able
|
||||
to calculate the limit to APIC ID values from designated
|
||||
CPU topology.
|
||||
|
||||
The value can be changed only until KVM_ENABLE_CAP is set to a nonzero
|
||||
value or until a vCPU is created. Upon creation of the first vCPU,
|
||||
if the value was set to zero or KVM_ENABLE_CAP was not invoked, KVM
|
||||
uses the return value of KVM_CHECK_EXTENSION(KVM_CAP_MAX_VCPU_ID) as
|
||||
the maximum APIC ID.
|
||||
|
||||
8. Other capabilities.
|
||||
======================
|
||||
|
||||
|
|
|
@ -1243,6 +1243,12 @@ struct kvm_arch {
|
|||
hpa_t hv_root_tdp;
|
||||
spinlock_t hv_root_tdp_lock;
|
||||
#endif
|
||||
/*
|
||||
* VM-scope maximum vCPU ID. Used to determine the size of structures
|
||||
* that increase along with the maximum vCPU ID, in which case, using
|
||||
* the global KVM_MAX_VCPU_IDS may lead to significant memory waste.
|
||||
*/
|
||||
u32 max_vcpu_ids;
|
||||
};
|
||||
|
||||
struct kvm_vm_stat {
|
||||
|
|
|
@ -6087,6 +6087,20 @@ split_irqchip_unlock:
|
|||
}
|
||||
mutex_unlock(&kvm->lock);
|
||||
break;
|
||||
case KVM_CAP_MAX_VCPU_ID:
|
||||
r = -EINVAL;
|
||||
if (cap->args[0] > KVM_MAX_VCPU_IDS)
|
||||
break;
|
||||
|
||||
mutex_lock(&kvm->lock);
|
||||
if (kvm->arch.max_vcpu_ids == cap->args[0]) {
|
||||
r = 0;
|
||||
} else if (!kvm->arch.max_vcpu_ids) {
|
||||
kvm->arch.max_vcpu_ids = cap->args[0];
|
||||
r = 0;
|
||||
}
|
||||
mutex_unlock(&kvm->lock);
|
||||
break;
|
||||
default:
|
||||
r = -EINVAL;
|
||||
break;
|
||||
|
@ -11246,6 +11260,12 @@ int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id)
|
|||
pr_warn_once("kvm: SMP vm created on host with unstable TSC; "
|
||||
"guest TSC will not be reliable\n");
|
||||
|
||||
if (!kvm->arch.max_vcpu_ids)
|
||||
kvm->arch.max_vcpu_ids = KVM_MAX_VCPU_IDS;
|
||||
|
||||
if (id >= kvm->arch.max_vcpu_ids)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue