aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c45
1 files changed, 33 insertions, 12 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 464da936c53d..02363e37d4a6 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1763,6 +1763,7 @@ u64 get_kvmclock_ns(struct kvm *kvm)
1763{ 1763{
1764 struct kvm_arch *ka = &kvm->arch; 1764 struct kvm_arch *ka = &kvm->arch;
1765 struct pvclock_vcpu_time_info hv_clock; 1765 struct pvclock_vcpu_time_info hv_clock;
1766 u64 ret;
1766 1767
1767 spin_lock(&ka->pvclock_gtod_sync_lock); 1768 spin_lock(&ka->pvclock_gtod_sync_lock);
1768 if (!ka->use_master_clock) { 1769 if (!ka->use_master_clock) {
@@ -1774,10 +1775,17 @@ u64 get_kvmclock_ns(struct kvm *kvm)
1774 hv_clock.system_time = ka->master_kernel_ns + ka->kvmclock_offset; 1775 hv_clock.system_time = ka->master_kernel_ns + ka->kvmclock_offset;
1775 spin_unlock(&ka->pvclock_gtod_sync_lock); 1776 spin_unlock(&ka->pvclock_gtod_sync_lock);
1776 1777
1778 /* both __this_cpu_read() and rdtsc() should be on the same cpu */
1779 get_cpu();
1780
1777 kvm_get_time_scale(NSEC_PER_SEC, __this_cpu_read(cpu_tsc_khz) * 1000LL, 1781 kvm_get_time_scale(NSEC_PER_SEC, __this_cpu_read(cpu_tsc_khz) * 1000LL,
1778 &hv_clock.tsc_shift, 1782 &hv_clock.tsc_shift,
1779 &hv_clock.tsc_to_system_mul); 1783 &hv_clock.tsc_to_system_mul);
1780 return __pvclock_read_cycles(&hv_clock, rdtsc()); 1784 ret = __pvclock_read_cycles(&hv_clock, rdtsc());
1785
1786 put_cpu();
1787
1788 return ret;
1781} 1789}
1782 1790
1783static void kvm_setup_pvclock_page(struct kvm_vcpu *v) 1791static void kvm_setup_pvclock_page(struct kvm_vcpu *v)
@@ -3288,11 +3296,14 @@ static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu,
3288 } 3296 }
3289} 3297}
3290 3298
3299#define XSAVE_MXCSR_OFFSET 24
3300
3291static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu, 3301static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
3292 struct kvm_xsave *guest_xsave) 3302 struct kvm_xsave *guest_xsave)
3293{ 3303{
3294 u64 xstate_bv = 3304 u64 xstate_bv =
3295 *(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)]; 3305 *(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)];
3306 u32 mxcsr = *(u32 *)&guest_xsave->region[XSAVE_MXCSR_OFFSET / sizeof(u32)];
3296 3307
3297 if (boot_cpu_has(X86_FEATURE_XSAVE)) { 3308 if (boot_cpu_has(X86_FEATURE_XSAVE)) {
3298 /* 3309 /*
@@ -3300,11 +3311,13 @@ static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
3300 * CPUID leaf 0xD, index 0, EDX:EAX. This is for compatibility 3311 * CPUID leaf 0xD, index 0, EDX:EAX. This is for compatibility
3301 * with old userspace. 3312 * with old userspace.
3302 */ 3313 */
3303 if (xstate_bv & ~kvm_supported_xcr0()) 3314 if (xstate_bv & ~kvm_supported_xcr0() ||
3315 mxcsr & ~mxcsr_feature_mask)
3304 return -EINVAL; 3316 return -EINVAL;
3305 load_xsave(vcpu, (u8 *)guest_xsave->region); 3317 load_xsave(vcpu, (u8 *)guest_xsave->region);
3306 } else { 3318 } else {
3307 if (xstate_bv & ~XFEATURE_MASK_FPSSE) 3319 if (xstate_bv & ~XFEATURE_MASK_FPSSE ||
3320 mxcsr & ~mxcsr_feature_mask)
3308 return -EINVAL; 3321 return -EINVAL;
3309 memcpy(&vcpu->arch.guest_fpu.state.fxsave, 3322 memcpy(&vcpu->arch.guest_fpu.state.fxsave,
3310 guest_xsave->region, sizeof(struct fxregs_state)); 3323 guest_xsave->region, sizeof(struct fxregs_state));
@@ -4818,16 +4831,20 @@ emul_write:
4818 4831
4819static int kernel_pio(struct kvm_vcpu *vcpu, void *pd) 4832static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
4820{ 4833{
4821 /* TODO: String I/O for in kernel device */ 4834 int r = 0, i;
4822 int r;
4823 4835
4824 if (vcpu->arch.pio.in) 4836 for (i = 0; i < vcpu->arch.pio.count; i++) {
4825 r = kvm_io_bus_read(vcpu, KVM_PIO_BUS, vcpu->arch.pio.port, 4837 if (vcpu->arch.pio.in)
4826 vcpu->arch.pio.size, pd); 4838 r = kvm_io_bus_read(vcpu, KVM_PIO_BUS, vcpu->arch.pio.port,
4827 else 4839 vcpu->arch.pio.size, pd);
4828 r = kvm_io_bus_write(vcpu, KVM_PIO_BUS, 4840 else
4829 vcpu->arch.pio.port, vcpu->arch.pio.size, 4841 r = kvm_io_bus_write(vcpu, KVM_PIO_BUS,
4830 pd); 4842 vcpu->arch.pio.port, vcpu->arch.pio.size,
4843 pd);
4844 if (r)
4845 break;
4846 pd += vcpu->arch.pio.size;
4847 }
4831 return r; 4848 return r;
4832} 4849}
4833 4850
@@ -4865,6 +4882,8 @@ static int emulator_pio_in_emulated(struct x86_emulate_ctxt *ctxt,
4865 if (vcpu->arch.pio.count) 4882 if (vcpu->arch.pio.count)
4866 goto data_avail; 4883 goto data_avail;
4867 4884
4885 memset(vcpu->arch.pio_data, 0, size * count);
4886
4868 ret = emulator_pio_in_out(vcpu, size, port, val, count, true); 4887 ret = emulator_pio_in_out(vcpu, size, port, val, count, true);
4869 if (ret) { 4888 if (ret) {
4870data_avail: 4889data_avail:
@@ -5048,6 +5067,8 @@ static bool emulator_get_segment(struct x86_emulate_ctxt *ctxt, u16 *selector,
5048 5067
5049 if (var.unusable) { 5068 if (var.unusable) {
5050 memset(desc, 0, sizeof(*desc)); 5069 memset(desc, 0, sizeof(*desc));
5070 if (base3)
5071 *base3 = 0;
5051 return false; 5072 return false;
5052 } 5073 }
5053 5074