@@ -788,3 +788,87 @@ struct kvm_pvclock_vcpu_time_info {
#else
#define kvm_pvclock_vcpu_time_info pvclock_vcpu_time_info
#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)
+#include <asm/processor.h>
+#include <asm/i387.h>
+struct _fpu {
+ struct i387_fxsave_struct fxsave;
+ struct i387_fxsave_struct host_fx_image;
+};
+
+struct fpu {
+ struct _fpu *state;
+ struct _fpu state_static;
+};
+
+static inline bool fpu_allocated(struct fpu *fpu)
+{
+ fpu->state = &fpu->state_static;
+ return true;
+}
+
+static inline int fpu_alloc(struct fpu *fpu)
+{
+ fpu->state = &fpu->state_static;
+ return 0;
+}
+
+static inline void fpu_free(struct fpu *fpu)
+{
+}
+
+static inline void kvm_fx_finit(void)
+{
+ asm("finit");
+}
+
+static inline void kvm_fx_save(struct i387_fxsave_struct *image)
+{
+ asm("fxsave (%0)":: "r" (image));
+}
+
+static inline void kvm_fx_restore(struct i387_fxsave_struct *image)
+{
+ asm("fxrstor (%0)":: "r" (image));
+}
+
+static inline void fpu_finit(struct fpu *fpu)
+{
+ unsigned after_mxcsr_mask;
+
+ /*
+ * Touch the fpu the first time in non atomic context as if
+ * this is the first fpu instruction the exception handler
+ * will fire before the instruction returns and it'll have to
+ * allocate ram with GFP_KERNEL.
+ */
+ if (!used_math())
+ kvm_fx_save(&fpu->state->host_fx_image);
+
+ /* Initialize guest FPU by resetting ours and saving into guest's */
+ preempt_disable();
+ kvm_fx_save(&fpu->state->host_fx_image);
+ kvm_fx_finit();
+ kvm_fx_save(&fpu->state->fxsave);
+ kvm_fx_restore(&fpu->state->host_fx_image);
+ preempt_enable();
+
+ after_mxcsr_mask = offsetof(struct i387_fxsave_struct, st_space);
+ fpu->state->fxsave.mxcsr = 0x1f80;
+ memset((void *)&fpu->state->fxsave + after_mxcsr_mask,
+ 0, sizeof(struct i387_fxsave_struct) - after_mxcsr_mask);
+}
+
+static inline void fpu_restore_checking(struct fpu *fpu)
+{
+ kvm_fx_save(&fpu->state->host_fx_image);
+ kvm_fx_restore(&fpu->state->fxsave);
+}
+
+static inline void fpu_save_init(struct fpu *fpu)
+{
+ kvm_fx_save(&fpu->state->fxsave);
+ kvm_fx_restore(&fpu->state->host_fx_image);
+}
+#endif