aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2011-03-25 04:44:51 -0400
committerAvi Kivity <avi@redhat.com>2011-05-11 07:57:06 -0400
commit92a1f12d2598f429bd8639e21d89305e787115c5 (patch)
tree48a6b7d6c50b5583b5163185dd097db100a471c6 /arch/x86/kvm
parent857e40999e35906baa367a79137019912cfb5434 (diff)
KVM: X86: Implement userspace interface to set virtual_tsc_khz
This patch implements two new vm-ioctls to get and set the virtual_tsc_khz if the machine supports tsc-scaling. Setting the tsc-frequency is only possible before userspace creates any vcpu. Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r--arch/x86/kvm/svm.c20
-rw-r--r--arch/x86/kvm/x86.c35
2 files changed, 55 insertions, 0 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 8c4549bef4ed..a98873762433 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -64,6 +64,8 @@ MODULE_LICENSE("GPL");
64#define DEBUGCTL_RESERVED_BITS (~(0x3fULL)) 64#define DEBUGCTL_RESERVED_BITS (~(0x3fULL))
65 65
66#define TSC_RATIO_RSVD 0xffffff0000000000ULL 66#define TSC_RATIO_RSVD 0xffffff0000000000ULL
67#define TSC_RATIO_MIN 0x0000000000000001ULL
68#define TSC_RATIO_MAX 0x000000ffffffffffULL
67 69
68static bool erratum_383_found __read_mostly; 70static bool erratum_383_found __read_mostly;
69 71
@@ -189,6 +191,7 @@ static int nested_svm_intercept(struct vcpu_svm *svm);
189static int nested_svm_vmexit(struct vcpu_svm *svm); 191static int nested_svm_vmexit(struct vcpu_svm *svm);
190static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, 192static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
191 bool has_error_code, u32 error_code); 193 bool has_error_code, u32 error_code);
194static u64 __scale_tsc(u64 ratio, u64 tsc);
192 195
193enum { 196enum {
194 VMCB_INTERCEPTS, /* Intercept vectors, TSC offset, 197 VMCB_INTERCEPTS, /* Intercept vectors, TSC offset,
@@ -798,6 +801,23 @@ static __init int svm_hardware_setup(void)
798 if (boot_cpu_has(X86_FEATURE_FXSR_OPT)) 801 if (boot_cpu_has(X86_FEATURE_FXSR_OPT))
799 kvm_enable_efer_bits(EFER_FFXSR); 802 kvm_enable_efer_bits(EFER_FFXSR);
800 803
804 if (boot_cpu_has(X86_FEATURE_TSCRATEMSR)) {
805 u64 max;
806
807 kvm_has_tsc_control = true;
808
809 /*
810 * Make sure the user can only configure tsc_khz values that
811 * fit into a signed integer.
812 * A min value is not calculated needed because it will always
813 * be 1 on all machines and a value of 0 is used to disable
814 * tsc-scaling for the vcpu.
815 */
816 max = min(0x7fffffffULL, __scale_tsc(tsc_khz, TSC_RATIO_MAX));
817
818 kvm_max_guest_tsc_khz = max;
819 }
820
801 if (nested) { 821 if (nested) {
802 printk(KERN_INFO "kvm: Nested Virtualization enabled\n"); 822 printk(KERN_INFO "kvm: Nested Virtualization enabled\n");
803 kvm_enable_efer_bits(EFER_SVME | EFER_LMSLE); 823 kvm_enable_efer_bits(EFER_SVME | EFER_LMSLE);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 579ce34e7904..1d5a7f418795 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -87,6 +87,11 @@ EXPORT_SYMBOL_GPL(kvm_x86_ops);
87int ignore_msrs = 0; 87int ignore_msrs = 0;
88module_param_named(ignore_msrs, ignore_msrs, bool, S_IRUGO | S_IWUSR); 88module_param_named(ignore_msrs, ignore_msrs, bool, S_IRUGO | S_IWUSR);
89 89
90bool kvm_has_tsc_control;
91EXPORT_SYMBOL_GPL(kvm_has_tsc_control);
92u32 kvm_max_guest_tsc_khz;
93EXPORT_SYMBOL_GPL(kvm_max_guest_tsc_khz);
94
90#define KVM_NR_SHARED_MSRS 16 95#define KVM_NR_SHARED_MSRS 16
91 96
92struct kvm_shared_msrs_global { 97struct kvm_shared_msrs_global {
@@ -1986,6 +1991,7 @@ int kvm_dev_ioctl_check_extension(long ext)
1986 case KVM_CAP_X86_ROBUST_SINGLESTEP: 1991 case KVM_CAP_X86_ROBUST_SINGLESTEP:
1987 case KVM_CAP_XSAVE: 1992 case KVM_CAP_XSAVE:
1988 case KVM_CAP_ASYNC_PF: 1993 case KVM_CAP_ASYNC_PF:
1994 case KVM_CAP_GET_TSC_KHZ:
1989 r = 1; 1995 r = 1;
1990 break; 1996 break;
1991 case KVM_CAP_COALESCED_MMIO: 1997 case KVM_CAP_COALESCED_MMIO:
@@ -2012,6 +2018,9 @@ int kvm_dev_ioctl_check_extension(long ext)
2012 case KVM_CAP_XCRS: 2018 case KVM_CAP_XCRS:
2013 r = cpu_has_xsave; 2019 r = cpu_has_xsave;
2014 break; 2020 break;
2021 case KVM_CAP_TSC_CONTROL:
2022 r = kvm_has_tsc_control;
2023 break;
2015 default: 2024 default:
2016 r = 0; 2025 r = 0;
2017 break; 2026 break;
@@ -3045,6 +3054,32 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
3045 r = kvm_vcpu_ioctl_x86_set_xcrs(vcpu, u.xcrs); 3054 r = kvm_vcpu_ioctl_x86_set_xcrs(vcpu, u.xcrs);
3046 break; 3055 break;
3047 } 3056 }
3057 case KVM_SET_TSC_KHZ: {
3058 u32 user_tsc_khz;
3059
3060 r = -EINVAL;
3061 if (!kvm_has_tsc_control)
3062 break;
3063
3064 user_tsc_khz = (u32)arg;
3065
3066 if (user_tsc_khz >= kvm_max_guest_tsc_khz)
3067 goto out;
3068
3069 kvm_x86_ops->set_tsc_khz(vcpu, user_tsc_khz);
3070
3071 r = 0;
3072 goto out;
3073 }
3074 case KVM_GET_TSC_KHZ: {
3075 r = -EIO;
3076 if (check_tsc_unstable())
3077 goto out;
3078
3079 r = vcpu_tsc_khz(vcpu);
3080
3081 goto out;
3082 }
3048 default: 3083 default:
3049 r = -EINVAL; 3084 r = -EINVAL;
3050 } 3085 }