[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