[PATCH 038/104] KVM: Use alignment properties of vcpu to simplify FPU ops

!MAILaRCHIVE_VOTE_RePLACE
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: <kvm-devel@...>
Cc: <linux-kernel@...>, Rusty Russell <rusty@...>
Date: Monday, September 17, 2007 - 4:31 am

From: Rusty Russell <rusty@rustcorp.com.au>

Now we use a kmem cache for allocating vcpus, we can get the 16-byte
alignment required by fxsave & fxrstor instructions, and avoid
manually aligning the buffer.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
 drivers/kvm/kvm.h      |   13 ++++---------
 drivers/kvm/kvm_main.c |   45 +++++++++++++++++----------------------------
 drivers/kvm/svm.c      |    8 ++++----
 3 files changed, 25 insertions(+), 41 deletions(-)

diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index b362e8f..7a34706 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -45,10 +45,6 @@
 #define KVM_REFILL_PAGES 25
 #define KVM_MAX_CPUID_ENTRIES 40
 
-#define FX_IMAGE_SIZE 512
-#define FX_IMAGE_ALIGN 16
-#define FX_BUF_SIZE (2 * FX_IMAGE_SIZE + FX_IMAGE_ALIGN)
-
 #define DE_VECTOR 0
 #define NM_VECTOR 7
 #define DF_VECTOR 8
@@ -342,9 +338,8 @@ struct kvm_vcpu {
 
 	struct kvm_guest_debug guest_debug;
 
-	char fx_buf[FX_BUF_SIZE];
-	char *host_fx_image;
-	char *guest_fx_image;
+	struct i387_fxsave_struct host_fx_image;
+	struct i387_fxsave_struct guest_fx_image;
 	int fpu_active;
 	int guest_fpu_loaded;
 
@@ -704,12 +699,12 @@ static inline unsigned long read_msr(unsigned long msr)
 }
 #endif
 
-static inline void fx_save(void *image)
+static inline void fx_save(struct i387_fxsave_struct *image)
 {
 	asm ("fxsave (%0)":: "r" (image));
 }
 
-static inline void fx_restore(void *image)
+static inline void fx_restore(struct i387_fxsave_struct *image)
 {
 	asm ("fxrstor (%0)":: "r" (image));
 }
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 4166a08..bfb1b6d 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -154,8 +154,8 @@ void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
 		return;
 
 	vcpu->guest_fpu_loaded = 1;
-	fx_save(vcpu->host_fx_image);
-	fx_restore(vcpu->guest_fx_image);
+	fx_save(&vcpu->host_fx_image);
+	fx_restore(&vcpu->guest_fx_image);
 }
 EXPORT_SYMBOL_GPL(kvm_load_guest_fpu);
 
@@ -165,8 +165,8 @@ void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
 		return;
 
 	vcpu->guest_fpu_loaded = 0;
-	fx_save(vcpu->guest_fx_image);
-	fx_restore(vcpu->host_fx_image);
+	fx_save(&vcpu->guest_fx_image);
+	fx_restore(&vcpu->host_fx_image);
 }
 EXPORT_SYMBOL_GPL(kvm_put_guest_fpu);
 
@@ -262,10 +262,6 @@ int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
 	}
 	vcpu->pio_data = page_address(page);
 
-	vcpu->host_fx_image = (char*)ALIGN((hva_t)vcpu->fx_buf,
-					   FX_IMAGE_ALIGN);
-	vcpu->guest_fx_image = vcpu->host_fx_image + FX_IMAGE_SIZE;
-
 	r = kvm_mmu_create(vcpu);
 	if (r < 0)
 		goto fail_free_pio_data;
@@ -615,30 +611,20 @@ EXPORT_SYMBOL_GPL(set_cr8);
 
 void fx_init(struct kvm_vcpu *vcpu)
 {
-	struct __attribute__ ((__packed__)) fx_image_s {
-		u16 control; //fcw
-		u16 status; //fsw
-		u16 tag; // ftw
-		u16 opcode; //fop
-		u64 ip; // fpu ip
-		u64 operand;// fpu dp
-		u32 mxcsr;
-		u32 mxcsr_mask;
-
-	} *fx_image;
+	unsigned after_mxcsr_mask;
 
 	/* Initialize guest FPU by resetting ours and saving into guest's */
 	preempt_disable();
-	fx_save(vcpu->host_fx_image);
+	fx_save(&vcpu->host_fx_image);
 	fpu_init();
-	fx_save(vcpu->guest_fx_image);
-	fx_restore(vcpu->host_fx_image);
+	fx_save(&vcpu->guest_fx_image);
+	fx_restore(&vcpu->host_fx_image);
 	preempt_enable();
 
-	fx_image = (struct fx_image_s *)vcpu->guest_fx_image;
-	fx_image->mxcsr = 0x1f80;
-	memset(vcpu->guest_fx_image + sizeof(struct fx_image_s),
-	       0, FX_IMAGE_SIZE - sizeof(struct fx_image_s));
+	after_mxcsr_mask = offsetof(struct i387_fxsave_struct, st_space);
+	vcpu->guest_fx_image.mxcsr = 0x1f80;
+	memset((void *)&vcpu->guest_fx_image + after_mxcsr_mask,
+	       0, sizeof(struct i387_fxsave_struct) - after_mxcsr_mask);
 }
 EXPORT_SYMBOL_GPL(fx_init);
 
@@ -2356,6 +2342,9 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n)
 
 	preempt_notifier_init(&vcpu->preempt_notifier, &kvm_preempt_ops);
 
+	/* We do fxsave: this must be aligned. */
+	BUG_ON((unsigned long)&vcpu->host_fx_image & 0xF);
+
 	vcpu_load(vcpu);
 	r = kvm_mmu_setup(vcpu);
 	vcpu_put(vcpu);
@@ -2468,7 +2457,7 @@ struct fxsave {
 
 static int kvm_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 {
-	struct fxsave *fxsave = (struct fxsave *)vcpu->guest_fx_image;
+	struct fxsave *fxsave = (struct fxsave *)&vcpu->guest_fx_image;
 
 	vcpu_load(vcpu);
 
@@ -2488,7 +2477,7 @@ static int kvm_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 
 static int kvm_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 {
-	struct fxsave *fxsave = (struct fxsave *)vcpu->guest_fx_image;
+	struct fxsave *fxsave = (struct fxsave *)&vcpu->guest_fx_image;
 
 	vcpu_load(vcpu);
 
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 8193651..5277084 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -1557,8 +1557,8 @@ again:
 	}
 
 	if (vcpu->fpu_active) {
-		fx_save(vcpu->host_fx_image);
-		fx_restore(vcpu->guest_fx_image);
+		fx_save(&vcpu->host_fx_image);
+		fx_restore(&vcpu->guest_fx_image);
 	}
 
 	asm volatile (
@@ -1670,8 +1670,8 @@ again:
 	vcpu->guest_mode = 0;
 
 	if (vcpu->fpu_active) {
-		fx_save(vcpu->guest_fx_image);
-		fx_restore(vcpu->host_fx_image);
+		fx_save(&vcpu->guest_fx_image);
+		fx_restore(&vcpu->host_fx_image);
 	}
 
 	if ((svm->vmcb->save.dr7 & 0xff))
-- 
1.5.3

-
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
git-send-email creates duplicate Message-Id's, Adrian Bunk, (Mon Sep 17, 11:59 am)
Re: git-send-email creates duplicate Message-Id's, Junio C Hamano, (Mon Sep 17, 4:22 pm)
Re: git-send-email creates duplicate Message-Id's, Matti Aarnio, (Mon Sep 17, 4:47 pm)
[PATCH 023/104] KVM: load_pdptrs() cleanups, Avi Kivity, (Mon Sep 17, 4:31 am)
[PATCH 029/104] KVM: Convert vm lock to a mutex, Avi Kivity, (Mon Sep 17, 4:31 am)
[PATCH 036/104] KVM: Remove kvm_{read,write}_guest(), Avi Kivity, (Mon Sep 17, 4:31 am)
[PATCH 046/104] KVM: Remove stat_set from debugfs, Avi Kivity, (Mon Sep 17, 4:31 am)
[PATCH 031/104] KVM: VMX: pass vcpu_vmx internally, Avi Kivity, (Mon Sep 17, 4:31 am)
[PATCH 074/104] KVM: pending irq save/restore, Avi Kivity, (Mon Sep 17, 4:31 am)
[PATCH 085/104] KVM: Keep control regs in sync, Avi Kivity, (Mon Sep 17, 4:32 am)
[PATCH 093/104] KVM: x86 emulator: push imm8, Avi Kivity, (Mon Sep 17, 4:32 am)
[PATCH 094/104] KVM: x86 emulator: call near, Avi Kivity, (Mon Sep 17, 4:32 am)
[PATCH 095/104] KVM: x86 emulator: pushf, Avi Kivity, (Mon Sep 17, 4:32 am)
[PATCH 103/104] KVM: x86 emulator: popf, Avi Kivity, (Mon Sep 17, 4:32 am)
[PATCH 100/104] KVM: x86 emulator: lea, Avi Kivity, (Mon Sep 17, 4:32 am)
[PATCH 101/104] KVM: x86 emulator: jmp abs, Avi Kivity, (Mon Sep 17, 4:32 am)
[PATCH 087/104] KVM: Simplify memory allocation, Avi Kivity, (Mon Sep 17, 4:32 am)
[PATCH 066/104] KVM: Emulate local APIC in kernel, Avi Kivity, (Mon Sep 17, 4:31 am)
[PATCH 061/104] KVM: Support more memory slots, Avi Kivity, (Mon Sep 17, 4:31 am)
[PATCH 067/104] KVM: In-kernel I/O APIC model, Avi Kivity, (Mon Sep 17, 4:31 am)
[PATCH 068/104] KVM: Emulate hlt in the kernel, Avi Kivity, (Mon Sep 17, 4:31 am)
[PATCH 025/104] KVM: Dynamically allocate vcpus, Avi Kivity, (Mon Sep 17, 4:31 am)
[PATCH 053/104] KVM: Clean up kvm_setup_pio(), Avi Kivity, (Mon Sep 17, 4:31 am)
[PATCH 051/104] KVM: Remove useless assignment, Avi Kivity, (Mon Sep 17, 4:31 am)
[PATCH 033/104] KVM: SVM: de-containization, Avi Kivity, (Mon Sep 17, 4:31 am)
[PATCH 038/104] KVM: Use alignment properties of vcpu to sim..., Avi Kivity, (Mon Sep 17, 4:31 am)
[PATCH 040/104] KVM: VMX: Add cpu consistency check, Avi Kivity, (Mon Sep 17, 4:31 am)
[PATCH 042/104] KVM: Cleanup mark_page_dirty, Avi Kivity, (Mon Sep 17, 4:31 am)
[PATCH 032/104] KVM: Remove three magic numbers, Avi Kivity, (Mon Sep 17, 4:31 am)
[PATCH 027/104] KVM: add hypercall nr to kvm_run, Avi Kivity, (Mon Sep 17, 4:31 am)
[PATCH 001/104] KVM: Fix *nopage() in kvm_main.c, Avi Kivity, (Mon Sep 17, 4:30 am)
Re: [PATCH 001/104] KVM: Fix *nopage() in kvm_main.c, Christoph Hellwig, (Mon Sep 17, 5:13 am)
Re: [PATCH 001/104] KVM: Fix *nopage() in kvm_main.c, Avi Kivity, (Mon Sep 17, 5:15 am)
Re: [PATCH 001/104] KVM: Fix *nopage() in kvm_main.c, Avi Kivity, (Mon Sep 17, 5:18 am)
Re: [PATCH 001/104] KVM: Fix *nopage() in kvm_main.c, Nick Piggin, (Sun Sep 16, 5:29 pm)
Re: [PATCH 001/104] KVM: Fix *nopage() in kvm_main.c, Avi Kivity, (Mon Sep 17, 2:19 pm)
Re: [PATCH 001/104] KVM: Fix *nopage() in kvm_main.c, Nick Piggin, (Mon Sep 17, 1:17 pm)
Re: [PATCH 001/104] KVM: Fix *nopage() in kvm_main.c, Avi Kivity, (Tue Sep 18, 6:44 am)