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 <[email protected]>
---
 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

_______________________________________________
pve-devel mailing list
[email protected]
http://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to