KVM: x86: Accept KVM_[GS]ET_TSC_KHZ as a VM ioctl.

This sets the default TSC frequency for subsequently created vCPUs.

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Message-Id: <20220225145304.36166-2-dwmw2@infradead.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
David Woodhouse 2022-02-25 14:53:02 +00:00 коммит произвёл Paolo Bonzini
Родитель fe3787a0d1
Коммит ffbb61d09f
4 изменённых файлов: 37 добавлений и 6 удалений

Просмотреть файл

@ -1897,22 +1897,25 @@ the future.
4.55 KVM_SET_TSC_KHZ 4.55 KVM_SET_TSC_KHZ
-------------------- --------------------
:Capability: KVM_CAP_TSC_CONTROL :Capability: KVM_CAP_TSC_CONTROL / KVM_CAP_VM_TSC_CONTROL
:Architectures: x86 :Architectures: x86
:Type: vcpu ioctl :Type: vcpu ioctl / vm ioctl
:Parameters: virtual tsc_khz :Parameters: virtual tsc_khz
:Returns: 0 on success, -1 on error :Returns: 0 on success, -1 on error
Specifies the tsc frequency for the virtual machine. The unit of the Specifies the tsc frequency for the virtual machine. The unit of the
frequency is KHz. frequency is KHz.
If the KVM_CAP_VM_TSC_CONTROL capability is advertised, this can also
be used as a vm ioctl to set the initial tsc frequency of subsequently
created vCPUs.
4.56 KVM_GET_TSC_KHZ 4.56 KVM_GET_TSC_KHZ
-------------------- --------------------
:Capability: KVM_CAP_GET_TSC_KHZ :Capability: KVM_CAP_GET_TSC_KHZ / KVM_CAP_VM_TSC_CONTROL
:Architectures: x86 :Architectures: x86
:Type: vcpu ioctl :Type: vcpu ioctl / vm ioctl
:Parameters: none :Parameters: none
:Returns: virtual tsc-khz on success, negative value on error :Returns: virtual tsc-khz on success, negative value on error

Просмотреть файл

@ -1126,6 +1126,8 @@ struct kvm_arch {
u64 cur_tsc_generation; u64 cur_tsc_generation;
int nr_vcpus_matched_tsc; int nr_vcpus_matched_tsc;
u32 default_tsc_khz;
seqcount_raw_spinlock_t pvclock_sc; seqcount_raw_spinlock_t pvclock_sc;
bool use_master_clock; bool use_master_clock;
u64 master_kernel_ns; u64 master_kernel_ns;

Просмотреть файл

@ -4324,6 +4324,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
r = boot_cpu_has(X86_FEATURE_XSAVE); r = boot_cpu_has(X86_FEATURE_XSAVE);
break; break;
case KVM_CAP_TSC_CONTROL: case KVM_CAP_TSC_CONTROL:
case KVM_CAP_VM_TSC_CONTROL:
r = kvm_has_tsc_control; r = kvm_has_tsc_control;
break; break;
case KVM_CAP_X2APIC_API: case KVM_CAP_X2APIC_API:
@ -6522,6 +6523,28 @@ set_pit2_out:
case KVM_GET_CLOCK: case KVM_GET_CLOCK:
r = kvm_vm_ioctl_get_clock(kvm, argp); r = kvm_vm_ioctl_get_clock(kvm, argp);
break; break;
case KVM_SET_TSC_KHZ: {
u32 user_tsc_khz;
r = -EINVAL;
user_tsc_khz = (u32)arg;
if (kvm_has_tsc_control &&
user_tsc_khz >= kvm_max_guest_tsc_khz)
goto out;
if (user_tsc_khz == 0)
user_tsc_khz = tsc_khz;
WRITE_ONCE(kvm->arch.default_tsc_khz, user_tsc_khz);
r = 0;
goto out;
}
case KVM_GET_TSC_KHZ: {
r = READ_ONCE(kvm->arch.default_tsc_khz);
goto out;
}
case KVM_MEMORY_ENCRYPT_OP: { case KVM_MEMORY_ENCRYPT_OP: {
r = -ENOTTY; r = -ENOTTY;
if (!kvm_x86_ops.mem_enc_ioctl) if (!kvm_x86_ops.mem_enc_ioctl)
@ -11266,7 +11289,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
kvm_xen_init_vcpu(vcpu); kvm_xen_init_vcpu(vcpu);
kvm_vcpu_mtrr_init(vcpu); kvm_vcpu_mtrr_init(vcpu);
vcpu_load(vcpu); vcpu_load(vcpu);
kvm_set_tsc_khz(vcpu, max_tsc_khz); kvm_set_tsc_khz(vcpu, vcpu->kvm->arch.default_tsc_khz);
kvm_vcpu_reset(vcpu, false); kvm_vcpu_reset(vcpu, false);
kvm_init_mmu(vcpu); kvm_init_mmu(vcpu);
vcpu_put(vcpu); vcpu_put(vcpu);
@ -11714,6 +11737,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
pvclock_update_vm_gtod_copy(kvm); pvclock_update_vm_gtod_copy(kvm);
raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags); raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags);
kvm->arch.default_tsc_khz = max_tsc_khz;
kvm->arch.guest_can_read_msr_platform_info = true; kvm->arch.guest_can_read_msr_platform_info = true;
kvm->arch.enable_pmu = enable_pmu; kvm->arch.enable_pmu = enable_pmu;

Просмотреть файл

@ -1144,6 +1144,7 @@ struct kvm_ppc_resize_hpt {
#define KVM_CAP_S390_MEM_OP_EXTENSION 211 #define KVM_CAP_S390_MEM_OP_EXTENSION 211
#define KVM_CAP_PMU_CAPABILITY 212 #define KVM_CAP_PMU_CAPABILITY 212
#define KVM_CAP_DISABLE_QUIRKS2 213 #define KVM_CAP_DISABLE_QUIRKS2 213
#define KVM_CAP_VM_TSC_CONTROL 214
#ifdef KVM_CAP_IRQ_ROUTING #ifdef KVM_CAP_IRQ_ROUTING
@ -1471,7 +1472,8 @@ struct kvm_s390_ucas_mapping {
#define KVM_SET_PIT2 _IOW(KVMIO, 0xa0, struct kvm_pit_state2) #define KVM_SET_PIT2 _IOW(KVMIO, 0xa0, struct kvm_pit_state2)
/* Available with KVM_CAP_PPC_GET_PVINFO */ /* Available with KVM_CAP_PPC_GET_PVINFO */
#define KVM_PPC_GET_PVINFO _IOW(KVMIO, 0xa1, struct kvm_ppc_pvinfo) #define KVM_PPC_GET_PVINFO _IOW(KVMIO, 0xa1, struct kvm_ppc_pvinfo)
/* Available with KVM_CAP_TSC_CONTROL */ /* Available with KVM_CAP_TSC_CONTROL for a vCPU, or with
* KVM_CAP_VM_TSC_CONTROL to set defaults for a VM */
#define KVM_SET_TSC_KHZ _IO(KVMIO, 0xa2) #define KVM_SET_TSC_KHZ _IO(KVMIO, 0xa2)
#define KVM_GET_TSC_KHZ _IO(KVMIO, 0xa3) #define KVM_GET_TSC_KHZ _IO(KVMIO, 0xa3)
/* Available with KVM_CAP_PCI_2_3 */ /* Available with KVM_CAP_PCI_2_3 */