[pve-devel] [PATCH] kvm : kvm: x86: fix xsave cpuid exposing bug

Alexandre Derumier aderumier at odiso.com
Tue Mar 4 06:51:41 CET 2014


This fix boot of freebsd on last opterons generation (61xx -> 63xx)

ref: http://www.spinics.net/lists/kvm/msg100398.html

Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
 Makefile    |    1 +
 xsave.patch |   67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+)
 create mode 100644 xsave.patch

diff --git a/Makefile b/Makefile
index b1d1a3b..ea57bc0 100644
--- a/Makefile
+++ b/Makefile
@@ -140,6 +140,7 @@ ${KERNEL_SRC}/README: ${KERNEL_SRC}.org/README
 	#cd ${KERNEL_SRC}; patch -p1 <../${RHKERSRCDIR}/patch-042stab083
 	#cd ${KERNEL_SRC}; patch -p1 <../do-not-use-barrier-on-ext3.patch
 	cd ${KERNEL_SRC}; patch -p1 <../bridge-patch.diff
+	cd ${KERNEL_SRC}; patch -p1 <../xsave.patch
 	#cd ${KERNEL_SRC}; patch -p1 <../kvm-fix-invalid-secondary-exec-controls.patch
 	#cd ${KERNEL_SRC}; patch -p1 <../fix-aspm-policy.patch
 	#cd ${KERNEL_SRC}; patch -p1 <../kbuild-generate-mudules-builtin.patch
diff --git a/xsave.patch b/xsave.patch
new file mode 100644
index 0000000..aadc8f2
--- /dev/null
+++ b/xsave.patch
@@ -0,0 +1,67 @@
+diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h
+index 5547389..dcd047b 100644
+--- a/arch/x86/include/asm/xsave.h
++++ b/arch/x86/include/asm/xsave.h
+@@ -13,6 +13,8 @@ 
+ #define XSTATE_BNDCSR	0x10
+ 
+ #define XSTATE_FPSSE	(XSTATE_FP | XSTATE_SSE)
++/* Bit 63 of XCR0 is reserved for future expansion */
++#define XSTATE_EXTEND_MASK	(~(XSTATE_FPSSE | (1ULL << 63)))
+ 
+ #define FXSAVE_SIZE	512
+ 
+diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
+index a951ae4..b241325 100644
+--- a/arch/x86/kvm/cpuid.c
++++ b/arch/x86/kvm/cpuid.c
+@@ -28,7 +28,7 @@  static u32 xstate_required_size(u64 xstate_bv)
+ 	int feature_bit = 0;
+ 	u32 ret = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET;
+ 
+-	xstate_bv &= ~XSTATE_FPSSE;
++	xstate_bv &= XSTATE_EXTEND_MASK;
+ 	while (xstate_bv) {
+ 		if (xstate_bv & 0x1) {
+ 		        u32 eax, ebx, ecx, edx;
+@@ -74,8 +74,8 @@  void kvm_update_cpuid(struct kvm_vcpu *vcpu)
+ 		vcpu->arch.guest_supported_xcr0 =
+ 			(best->eax | ((u64)best->edx << 32)) &
+ 			host_xcr0 & KVM_SUPPORTED_XCR0;
+-		vcpu->arch.guest_xstate_size =
+-			xstate_required_size(vcpu->arch.guest_supported_xcr0);
++		vcpu->arch.guest_xstate_size = best->ebx =
++			xstate_required_size(vcpu->arch.xcr0);
+ 	}
+ 
+ 	kvm_pmu_cpuid_update(vcpu);
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 39c28f0..7c52acb 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -595,13 +595,13 @@  static void kvm_put_guest_xcr0(struct kvm_vcpu *vcpu)
+ 
+ int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
+ {
+-	u64 xcr0;
++	u64 xcr0 = xcr;
++	u64 old_xcr0 = vcpu->arch.xcr0;
+ 	u64 valid_bits;
+ 
+ 	/* Only support XCR_XFEATURE_ENABLED_MASK(xcr0) now  */
+ 	if (index != XCR_XFEATURE_ENABLED_MASK)
+ 		return 1;
+-	xcr0 = xcr;
+ 	if (!(xcr0 & XSTATE_FP))
+ 		return 1;
+ 	if ((xcr0 & XSTATE_YMM) && !(xcr0 & XSTATE_SSE))
+@@ -618,6 +618,9 @@  int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
+ 
+ 	kvm_put_guest_xcr0(vcpu);
+ 	vcpu->arch.xcr0 = xcr0;
++
++	if ((xcr0 ^ old_xcr0) & XSTATE_EXTEND_MASK)
++		kvm_update_cpuid(vcpu);
+ 	return 0;
+ }
+ 
-- 
1.7.10.4




More information about the pve-devel mailing list