diff options
Diffstat (limited to 'arch/x86')
| -rw-r--r-- | arch/x86/include/asm/xen/hypercall.h | 21 | ||||
| -rw-r--r-- | arch/x86/kvm/cpuid.h | 3 | ||||
| -rw-r--r-- | arch/x86/kvm/vmx.c | 11 | ||||
| -rw-r--r-- | arch/x86/kvm/x86.c | 3 | 
4 files changed, 20 insertions, 18 deletions
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h index 59c226d120c..c20d1ce62dc 100644 --- a/arch/x86/include/asm/xen/hypercall.h +++ b/arch/x86/include/asm/xen/hypercall.h @@ -359,18 +359,14 @@ HYPERVISOR_update_va_mapping(unsigned long va, pte_t new_val,  		return _hypercall4(int, update_va_mapping, va,  				   new_val.pte, new_val.pte >> 32, flags);  } +extern int __must_check xen_event_channel_op_compat(int, void *);  static inline int  HYPERVISOR_event_channel_op(int cmd, void *arg)  {  	int rc = _hypercall2(int, event_channel_op, cmd, arg); -	if (unlikely(rc == -ENOSYS)) { -		struct evtchn_op op; -		op.cmd = cmd; -		memcpy(&op.u, arg, sizeof(op.u)); -		rc = _hypercall1(int, event_channel_op_compat, &op); -		memcpy(arg, &op.u, sizeof(op.u)); -	} +	if (unlikely(rc == -ENOSYS)) +		rc = xen_event_channel_op_compat(cmd, arg);  	return rc;  } @@ -386,17 +382,14 @@ HYPERVISOR_console_io(int cmd, int count, char *str)  	return _hypercall3(int, console_io, cmd, count, str);  } +extern int __must_check HYPERVISOR_physdev_op_compat(int, void *); +  static inline int  HYPERVISOR_physdev_op(int cmd, void *arg)  {  	int rc = _hypercall2(int, physdev_op, cmd, arg); -	if (unlikely(rc == -ENOSYS)) { -		struct physdev_op op; -		op.cmd = cmd; -		memcpy(&op.u, arg, sizeof(op.u)); -		rc = _hypercall1(int, physdev_op_compat, &op); -		memcpy(arg, &op.u, sizeof(op.u)); -	} +	if (unlikely(rc == -ENOSYS)) +		rc = HYPERVISOR_physdev_op_compat(cmd, arg);  	return rc;  } diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index a10e4601685..58fc5148882 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h @@ -24,6 +24,9 @@ static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu)  {  	struct kvm_cpuid_entry2 *best; +	if (!static_cpu_has(X86_FEATURE_XSAVE)) +		return 0; +  	best = kvm_find_cpuid_entry(vcpu, 1, 0);  	return best && (best->ecx & bit(X86_FEATURE_XSAVE));  } diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ad6b1dd06f8..f85815945fc 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -6549,19 +6549,22 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)  		}  	} -	exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);  	/* Exposing INVPCID only when PCID is exposed */  	best = kvm_find_cpuid_entry(vcpu, 0x7, 0);  	if (vmx_invpcid_supported() &&  	    best && (best->ebx & bit(X86_FEATURE_INVPCID)) &&  	    guest_cpuid_has_pcid(vcpu)) { +		exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);  		exec_control |= SECONDARY_EXEC_ENABLE_INVPCID;  		vmcs_write32(SECONDARY_VM_EXEC_CONTROL,  			     exec_control);  	} else { -		exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID; -		vmcs_write32(SECONDARY_VM_EXEC_CONTROL, -			     exec_control); +		if (cpu_has_secondary_exec_ctrls()) { +			exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); +			exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID; +			vmcs_write32(SECONDARY_VM_EXEC_CONTROL, +				     exec_control); +		}  		if (best)  			best->ebx &= ~bit(X86_FEATURE_INVPCID);  	} diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 224a7e78cb6..4f7641756be 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5781,6 +5781,9 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,  	int pending_vec, max_bits, idx;  	struct desc_ptr dt; +	if (!guest_cpuid_has_xsave(vcpu) && (sregs->cr4 & X86_CR4_OSXSAVE)) +		return -EINVAL; +  	dt.size = sregs->idt.limit;  	dt.address = sregs->idt.base;  	kvm_x86_ops->set_idt(vcpu, &dt);  |