* [PATCH 0/3] Convert KVM to use FPU API
@ 2010-05-14 3:16 Sheng Yang
2010-05-14 3:16 ` [PATCH 1/3] x86: Split fpu_save_init() to fpu_save() and fpu_clear() Sheng Yang
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Sheng Yang @ 2010-05-14 3:16 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti
Cc: Ingo Molnar, H. Peter Anvin, kvm, linux-kernel, Sheng Yang
This patchset based on Avi's FPU API patchset.
Sheng Yang (3):
x86: Split fpu_save_init() to fpu_save() and fpu_clear()
x86: Export FPU API for KVM use
KVM: x86: Use FPU API
arch/x86/include/asm/i387.h | 73 ++++++++++++++++++++++++---------------
arch/x86/include/asm/kvm_host.h | 18 +---------
arch/x86/include/asm/xsave.h | 3 ++
arch/x86/kernel/i387.c | 3 +-
arch/x86/kernel/process.c | 1 +
arch/x86/kvm/x86.c | 73 ++++++++++++---------------------------
6 files changed, 74 insertions(+), 97 deletions(-)
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/3] x86: Split fpu_save_init() to fpu_save() and fpu_clear()
2010-05-14 3:16 [PATCH 0/3] Convert KVM to use FPU API Sheng Yang
@ 2010-05-14 3:16 ` Sheng Yang
2010-05-14 3:16 ` [PATCH 2/3] x86: Export FPU API for KVM use Sheng Yang
2010-05-14 3:16 ` [PATCH 3/3] KVM: x86: Use FPU API Sheng Yang
2 siblings, 0 replies; 8+ messages in thread
From: Sheng Yang @ 2010-05-14 3:16 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti
Cc: Ingo Molnar, H. Peter Anvin, kvm, linux-kernel, Sheng Yang
fpu_save() would be used later by KVM.
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
---
arch/x86/include/asm/i387.h | 71 ++++++++++++++++++++++++++-----------------
1 files changed, 43 insertions(+), 28 deletions(-)
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h
index 1a8cca3..989d3b7 100644
--- a/arch/x86/include/asm/i387.h
+++ b/arch/x86/include/asm/i387.h
@@ -180,13 +180,17 @@ static inline void fpu_fxsave(struct fpu *fpu)
#endif
}
-static inline void fpu_save_init(struct fpu *fpu)
+static inline void fpu_save(struct fpu *fpu)
{
if (use_xsave())
fpu_xsave(fpu);
else
fpu_fxsave(fpu);
+}
+static inline void fpu_save_init(struct fpu *fpu)
+{
+ fpu_save(fpu);
fpu_clear(fpu);
}
@@ -237,19 +241,41 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
/*
* These must be called with preempt disabled
*/
-static inline void fpu_save_init(struct fpu *fpu)
+static inline void fpu_fxsave(struct fpu *fpu)
{
- if (use_xsave()) {
- struct xsave_struct *xstate = &fpu->state->xsave;
- struct i387_fxsave_struct *fx = &fpu->state->fxsave;
+ /* Use more nops than strictly needed in case the compiler
+ varies code */
+ alternative_input(
+ "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4,
+ "fxsave %[fx]\n"
+ "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:",
+ X86_FEATURE_FXSR,
+ [fx] "m" (fpu->state->fxsave),
+ [fsw] "m" (fpu->state->fxsave.swd) : "memory");
+}
+static inline void fpu_save(struct fpu *fpu)
+{
+ if (use_xsave())
fpu_xsave(fpu);
+ else
+ fpu_fxsave(fpu);
+}
+
+/* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
+ is pending. Clear the x87 state here by setting it to fixed
+ values. safe_address is a random variable that should be in L1 */
+static inline void fpu_clear(struct fpu *fpu)
+{
+ struct xsave_struct *xstate = &fpu->state->xsave;
+ struct i387_fxsave_struct *fx = &fpu->state->fxsave;
+ if (use_xsave()) {
/*
* xsave header may indicate the init state of the FP.
*/
if (!(xstate->xsave_hdr.xstate_bv & XSTATE_FP))
- goto end;
+ return;
if (unlikely(fx->swd & X87_FSW_ES))
asm volatile("fnclex");
@@ -257,30 +283,19 @@ static inline void fpu_save_init(struct fpu *fpu)
/*
* we can do a simple return here or be paranoid :)
*/
- goto clear_state;
}
+ alternative_input(
+ GENERIC_NOP8 GENERIC_NOP2,
+ "emms\n\t" /* clear stack tags */
+ "fildl %[addr]", /* set F?P to defined value */
+ X86_FEATURE_FXSAVE_LEAK,
+ [addr] "m" (safe_address));
+}
- /* Use more nops than strictly needed in case the compiler
- varies code */
- alternative_input(
- "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4,
- "fxsave %[fx]\n"
- "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:",
- X86_FEATURE_FXSR,
- [fx] "m" (fpu->state->fxsave),
- [fsw] "m" (fpu->state->fxsave.swd) : "memory");
-clear_state:
- /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
- is pending. Clear the x87 state here by setting it to fixed
- values. safe_address is a random variable that should be in L1 */
- alternative_input(
- GENERIC_NOP8 GENERIC_NOP2,
- "emms\n\t" /* clear stack tags */
- "fildl %[addr]", /* set F?P to defined value */
- X86_FEATURE_FXSAVE_LEAK,
- [addr] "m" (safe_address));
-end:
- ;
+static inline void fpu_save_init(struct fpu *fpu)
+{
+ fpu_save(fpu);
+ fpu_clear(fpu);
}
static inline void __save_init_fpu(struct task_struct *tsk)
--
1.7.0.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/3] x86: Export FPU API for KVM use
2010-05-14 3:16 [PATCH 0/3] Convert KVM to use FPU API Sheng Yang
2010-05-14 3:16 ` [PATCH 1/3] x86: Split fpu_save_init() to fpu_save() and fpu_clear() Sheng Yang
@ 2010-05-14 3:16 ` Sheng Yang
2010-05-14 3:16 ` [PATCH 3/3] KVM: x86: Use FPU API Sheng Yang
2 siblings, 0 replies; 8+ messages in thread
From: Sheng Yang @ 2010-05-14 3:16 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti
Cc: Ingo Molnar, H. Peter Anvin, kvm, linux-kernel, Sheng Yang
Also add some more constants.
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
---
Do we need to rename "task_xstate_cachep"? It's not only for task struct now.
arch/x86/include/asm/i387.h | 2 ++
arch/x86/include/asm/xsave.h | 3 +++
arch/x86/kernel/i387.c | 3 ++-
arch/x86/kernel/process.c | 1 +
4 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h
index 989d3b7..f19bdf9 100644
--- a/arch/x86/include/asm/i387.h
+++ b/arch/x86/include/asm/i387.h
@@ -503,6 +503,8 @@ static inline void fpu_copy(struct fpu *dst, struct fpu *src)
memcpy(dst->state, src->state, xstate_size);
}
+extern void fpu_finit(struct fpu *fpu);
+
#endif /* __ASSEMBLY__ */
#define PSHUFB_XMM5_XMM0 .byte 0x66, 0x0f, 0x38, 0x00, 0xc5
diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h
index 2c4390c..29ee4e4 100644
--- a/arch/x86/include/asm/xsave.h
+++ b/arch/x86/include/asm/xsave.h
@@ -13,6 +13,9 @@
#define FXSAVE_SIZE 512
+#define XSTATE_YMM_SIZE 256
+#define XSTATE_YMM_OFFSET (512 + 64)
+
/*
* These are the features that the OS can handle currently.
*/
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c
index 86cef6b..c4444bc 100644
--- a/arch/x86/kernel/i387.c
+++ b/arch/x86/kernel/i387.c
@@ -107,7 +107,7 @@ void __cpuinit fpu_init(void)
}
#endif /* CONFIG_X86_64 */
-static void fpu_finit(struct fpu *fpu)
+void fpu_finit(struct fpu *fpu)
{
#ifdef CONFIG_X86_32
if (!HAVE_HWFP) {
@@ -132,6 +132,7 @@ static void fpu_finit(struct fpu *fpu)
fp->fos = 0xffff0000u;
}
}
+EXPORT_SYMBOL_GPL(fpu_finit);
/*
* The _current_ task is using the FPU for the first time
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 8bcc21f..373fec9 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -28,6 +28,7 @@ unsigned long idle_nomwait;
EXPORT_SYMBOL(idle_nomwait);
struct kmem_cache *task_xstate_cachep;
+EXPORT_SYMBOL(task_xstate_cachep);
int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
{
--
1.7.0.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/3] KVM: x86: Use FPU API
2010-05-14 3:16 [PATCH 0/3] Convert KVM to use FPU API Sheng Yang
2010-05-14 3:16 ` [PATCH 1/3] x86: Split fpu_save_init() to fpu_save() and fpu_clear() Sheng Yang
2010-05-14 3:16 ` [PATCH 2/3] x86: Export FPU API for KVM use Sheng Yang
@ 2010-05-14 3:16 ` Sheng Yang
2010-05-15 8:06 ` Avi Kivity
2 siblings, 1 reply; 8+ messages in thread
From: Sheng Yang @ 2010-05-14 3:16 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti
Cc: Ingo Molnar, H. Peter Anvin, kvm, linux-kernel, Sheng Yang
Convert KVM to use generic FPU API.
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
---
arch/x86/include/asm/kvm_host.h | 18 +---------
arch/x86/kvm/x86.c | 73 ++++++++++++---------------------------
2 files changed, 23 insertions(+), 68 deletions(-)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index ed48904..beba6f5 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -300,8 +300,7 @@ struct kvm_vcpu_arch {
unsigned long mmu_seq;
} update_pte;
- struct i387_fxsave_struct host_fx_image;
- struct i387_fxsave_struct guest_fx_image;
+ struct fpu host_fpu, guest_fpu;
gva_t mmio_fault_cr2;
struct kvm_pio_request pio;
@@ -709,21 +708,6 @@ static inline unsigned long read_msr(unsigned long msr)
}
#endif
-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 kvm_fx_finit(void)
-{
- asm("finit");
-}
-
static inline u32 get_rdx_init_val(void)
{
return 0x600; /* P6 family */
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index cd8a606..2313f76 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -52,6 +52,8 @@
#include <asm/desc.h>
#include <asm/mtrr.h>
#include <asm/mce.h>
+#include <asm/i387.h>
+#include <asm/xcr.h>
#define MAX_IO_MSRS 256
#define CR0_RESERVED_BITS \
@@ -5069,27 +5071,6 @@ unlock_out:
}
/*
- * fxsave fpu state. Taken from x86_64/processor.h. To be killed when
- * we have asm/x86/processor.h
- */
-struct fxsave {
- u16 cwd;
- u16 swd;
- u16 twd;
- u16 fop;
- u64 rip;
- u64 rdp;
- u32 mxcsr;
- u32 mxcsr_mask;
- u32 st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
-#ifdef CONFIG_X86_64
- u32 xmm_space[64]; /* 16*16 bytes for each XMM-reg = 256 bytes */
-#else
- u32 xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
-#endif
-};
-
-/*
* Translate a guest virtual address to a guest physical address.
*/
int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
@@ -5114,7 +5095,8 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
{
- struct fxsave *fxsave = (struct fxsave *)&vcpu->arch.guest_fx_image;
+ struct i387_fxsave_struct *fxsave =
+ &vcpu->arch.guest_fpu.state->fxsave;
vcpu_load(vcpu);
@@ -5134,7 +5116,8 @@ int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
{
- struct fxsave *fxsave = (struct fxsave *)&vcpu->arch.guest_fx_image;
+ struct i387_fxsave_struct *fxsave =
+ &vcpu->arch.guest_fpu.state->fxsave;
vcpu_load(vcpu);
@@ -5154,41 +5137,30 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
void fx_init(struct kvm_vcpu *vcpu)
{
- 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(&vcpu->arch.host_fx_image);
+ fpu_alloc(&vcpu->arch.host_fpu);
+ fpu_alloc(&vcpu->arch.guest_fpu);
- /* Initialize guest FPU by resetting ours and saving into guest's */
- preempt_disable();
- kvm_fx_save(&vcpu->arch.host_fx_image);
- kvm_fx_finit();
- kvm_fx_save(&vcpu->arch.guest_fx_image);
- kvm_fx_restore(&vcpu->arch.host_fx_image);
- preempt_enable();
+ fpu_save(&vcpu->arch.host_fpu);
+ fpu_finit(&vcpu->arch.guest_fpu);
vcpu->arch.cr0 |= X86_CR0_ET;
- after_mxcsr_mask = offsetof(struct i387_fxsave_struct, st_space);
- vcpu->arch.guest_fx_image.mxcsr = 0x1f80;
- memset((void *)&vcpu->arch.guest_fx_image + after_mxcsr_mask,
- 0, sizeof(struct i387_fxsave_struct) - after_mxcsr_mask);
}
EXPORT_SYMBOL_GPL(fx_init);
+static void fx_free(struct kvm_vcpu *vcpu)
+{
+ fpu_free(&vcpu->arch.host_fpu);
+ fpu_free(&vcpu->arch.guest_fpu);
+}
+
void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
{
if (vcpu->guest_fpu_loaded)
return;
vcpu->guest_fpu_loaded = 1;
- kvm_fx_save(&vcpu->arch.host_fx_image);
- kvm_fx_restore(&vcpu->arch.guest_fx_image);
+ fpu_save(&vcpu->arch.host_fpu);
+ fpu_restore_checking(&vcpu->arch.guest_fpu);
trace_kvm_fpu(1);
}
@@ -5198,8 +5170,8 @@ void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
return;
vcpu->guest_fpu_loaded = 0;
- kvm_fx_save(&vcpu->arch.guest_fx_image);
- kvm_fx_restore(&vcpu->arch.host_fx_image);
+ fpu_save(&vcpu->arch.guest_fpu);
+ fpu_restore_checking(&vcpu->arch.host_fpu);
++vcpu->stat.fpu_reload;
set_bit(KVM_REQ_DEACTIVATE_FPU, &vcpu->requests);
trace_kvm_fpu(0);
@@ -5212,6 +5184,7 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
vcpu->arch.time_page = NULL;
}
+ fx_free(vcpu);
kvm_x86_ops->vcpu_free(vcpu);
}
@@ -5225,9 +5198,6 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
{
int r;
- /* We do fxsave: this must be aligned. */
- BUG_ON((unsigned long)&vcpu->arch.host_fx_image & 0xF);
-
vcpu->arch.mtrr_state.have_fixed = 1;
vcpu_load(vcpu);
r = kvm_arch_vcpu_reset(vcpu);
@@ -5249,6 +5219,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
kvm_mmu_unload(vcpu);
vcpu_put(vcpu);
+ fx_free(vcpu);
kvm_x86_ops->vcpu_free(vcpu);
}
--
1.7.0.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 3/3] KVM: x86: Use FPU API
2010-05-14 3:16 ` [PATCH 3/3] KVM: x86: Use FPU API Sheng Yang
@ 2010-05-15 8:06 ` Avi Kivity
2010-05-17 8:09 ` Sheng Yang
0 siblings, 1 reply; 8+ messages in thread
From: Avi Kivity @ 2010-05-15 8:06 UTC (permalink / raw)
To: Sheng Yang
Cc: Marcelo Tosatti, Ingo Molnar, H. Peter Anvin, kvm, linux-kernel
On 05/14/2010 06:16 AM, Sheng Yang wrote:
> Convert KVM to use generic FPU API.
>
> Signed-off-by: Sheng Yang<sheng@linux.intel.com>
> ---
> arch/x86/include/asm/kvm_host.h | 18 +---------
> arch/x86/kvm/x86.c | 73 ++++++++++++---------------------------
> 2 files changed, 23 insertions(+), 68 deletions(-)
>
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index ed48904..beba6f5 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -300,8 +300,7 @@ struct kvm_vcpu_arch {
> unsigned long mmu_seq;
> } update_pte;
>
> - struct i387_fxsave_struct host_fx_image;
> - struct i387_fxsave_struct guest_fx_image;
> + struct fpu host_fpu, guest_fpu;
>
>
Do we really need host_fpu? I think we can call unlazy_fpu() instead
and drop host_fpu completely. This might reduce the need for changes in
patch 1 (as well as generally improving the code).
--
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/3] KVM: x86: Use FPU API
2010-05-15 8:06 ` Avi Kivity
@ 2010-05-17 8:09 ` Sheng Yang
2010-05-17 8:18 ` Avi Kivity
0 siblings, 1 reply; 8+ messages in thread
From: Sheng Yang @ 2010-05-17 8:09 UTC (permalink / raw)
To: Avi Kivity; +Cc: Marcelo Tosatti, kvm, H. Peter Anvin, Ingo Molnar, Sheng Yang
Convert KVM to use generic FPU API.
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
---
Like this? (Drop patch 1)
arch/x86/include/asm/kvm_host.h | 18 +---------
arch/x86/kvm/x86.c | 70 ++++++++++-----------------------------
2 files changed, 19 insertions(+), 69 deletions(-)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 0c06148..d08bb4a 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -301,8 +301,7 @@ struct kvm_vcpu_arch {
unsigned long mmu_seq;
} update_pte;
- struct i387_fxsave_struct host_fx_image;
- struct i387_fxsave_struct guest_fx_image;
+ struct fpu guest_fpu;
gva_t mmio_fault_cr2;
struct kvm_pio_request pio;
@@ -709,21 +708,6 @@ static inline unsigned long read_msr(unsigned long msr)
}
#endif
-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 kvm_fx_finit(void)
-{
- asm("finit");
-}
-
static inline u32 get_rdx_init_val(void)
{
return 0x600; /* P6 family */
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 7500cba..7be1d36 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -52,6 +52,8 @@
#include <asm/desc.h>
#include <asm/mtrr.h>
#include <asm/mce.h>
+#include <asm/i387.h>
+#include <asm/xcr.h>
#define MAX_IO_MSRS 256
#define CR0_RESERVED_BITS \
@@ -5057,27 +5059,6 @@ out:
}
/*
- * fxsave fpu state. Taken from x86_64/processor.h. To be killed when
- * we have asm/x86/processor.h
- */
-struct fxsave {
- u16 cwd;
- u16 swd;
- u16 twd;
- u16 fop;
- u64 rip;
- u64 rdp;
- u32 mxcsr;
- u32 mxcsr_mask;
- u32 st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
-#ifdef CONFIG_X86_64
- u32 xmm_space[64]; /* 16*16 bytes for each XMM-reg = 256 bytes */
-#else
- u32 xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
-#endif
-};
-
-/*
* Translate a guest virtual address to a guest physical address.
*/
int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
@@ -5100,7 +5081,8 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
{
- struct fxsave *fxsave = (struct fxsave *)&vcpu->arch.guest_fx_image;
+ struct i387_fxsave_struct *fxsave =
+ &vcpu->arch.guest_fpu.state->fxsave;
memcpy(fpu->fpr, fxsave->st_space, 128);
fpu->fcw = fxsave->cwd;
@@ -5116,7 +5098,8 @@ int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
{
- struct fxsave *fxsave = (struct fxsave *)&vcpu->arch.guest_fx_image;
+ struct i387_fxsave_struct *fxsave =
+ &vcpu->arch.guest_fpu.state->fxsave;
memcpy(fxsave->st_space, fpu->fpr, 128);
fxsave->cwd = fpu->fcw;
@@ -5132,41 +5115,26 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
void fx_init(struct kvm_vcpu *vcpu)
{
- 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(&vcpu->arch.host_fx_image);
-
- /* Initialize guest FPU by resetting ours and saving into guest's */
- preempt_disable();
- kvm_fx_save(&vcpu->arch.host_fx_image);
- kvm_fx_finit();
- kvm_fx_save(&vcpu->arch.guest_fx_image);
- kvm_fx_restore(&vcpu->arch.host_fx_image);
- preempt_enable();
+ fpu_alloc(&vcpu->arch.guest_fpu);
+ fpu_finit(&vcpu->arch.guest_fpu);
vcpu->arch.cr0 |= X86_CR0_ET;
- after_mxcsr_mask = offsetof(struct i387_fxsave_struct, st_space);
- vcpu->arch.guest_fx_image.mxcsr = 0x1f80;
- memset((void *)&vcpu->arch.guest_fx_image + after_mxcsr_mask,
- 0, sizeof(struct i387_fxsave_struct) - after_mxcsr_mask);
}
EXPORT_SYMBOL_GPL(fx_init);
+static void fx_free(struct kvm_vcpu *vcpu)
+{
+ fpu_free(&vcpu->arch.guest_fpu);
+}
+
void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
{
if (vcpu->guest_fpu_loaded)
return;
vcpu->guest_fpu_loaded = 1;
- kvm_fx_save(&vcpu->arch.host_fx_image);
- kvm_fx_restore(&vcpu->arch.guest_fx_image);
+ unlazy_fpu(current);
+ fpu_restore_checking(&vcpu->arch.guest_fpu);
trace_kvm_fpu(1);
}
@@ -5176,8 +5144,7 @@ void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
return;
vcpu->guest_fpu_loaded = 0;
- kvm_fx_save(&vcpu->arch.guest_fx_image);
- kvm_fx_restore(&vcpu->arch.host_fx_image);
+ fpu_save_init(&vcpu->arch.guest_fpu);
++vcpu->stat.fpu_reload;
set_bit(KVM_REQ_DEACTIVATE_FPU, &vcpu->requests);
trace_kvm_fpu(0);
@@ -5190,6 +5157,7 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
vcpu->arch.time_page = NULL;
}
+ fx_free(vcpu);
kvm_x86_ops->vcpu_free(vcpu);
}
@@ -5203,9 +5171,6 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
{
int r;
- /* We do fxsave: this must be aligned. */
- BUG_ON((unsigned long)&vcpu->arch.host_fx_image & 0xF);
-
vcpu->arch.mtrr_state.have_fixed = 1;
vcpu_load(vcpu);
r = kvm_arch_vcpu_reset(vcpu);
@@ -5227,6 +5192,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
kvm_mmu_unload(vcpu);
vcpu_put(vcpu);
+ fx_free(vcpu);
kvm_x86_ops->vcpu_free(vcpu);
}
--
1.7.0.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 3/3] KVM: x86: Use FPU API
2010-05-17 8:09 ` Sheng Yang
@ 2010-05-17 8:18 ` Avi Kivity
2010-05-17 8:22 ` Sheng Yang
0 siblings, 1 reply; 8+ messages in thread
From: Avi Kivity @ 2010-05-17 8:18 UTC (permalink / raw)
To: Sheng Yang; +Cc: Marcelo Tosatti, kvm, H. Peter Anvin, Ingo Molnar
On 05/17/2010 11:09 AM, Sheng Yang wrote:
> Convert KVM to use generic FPU API.
>
> Signed-off-by: Sheng Yang<sheng@linux.intel.com>
> ---
> Like this? (Drop patch 1)
>
>
Will be more readable with a patch that converts host_fx_image to
unlazy_fpu(), and a second patch that converts guest_fx_image to the fpu
API.
I think unlazy_fpu() is even a performance win in case userspace doesn't
do a lot of floating point (which is the case with qemu). I wonder why
we didn't think of it before.
--
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 3/3] KVM: x86: Use FPU API
2010-05-17 8:18 ` Avi Kivity
@ 2010-05-17 8:22 ` Sheng Yang
0 siblings, 0 replies; 8+ messages in thread
From: Sheng Yang @ 2010-05-17 8:22 UTC (permalink / raw)
To: Avi Kivity; +Cc: Marcelo Tosatti, kvm, H. Peter Anvin, Ingo Molnar
On Monday 17 May 2010 16:18:22 Avi Kivity wrote:
> On 05/17/2010 11:09 AM, Sheng Yang wrote:
> > Convert KVM to use generic FPU API.
> >
> > Signed-off-by: Sheng Yang<sheng@linux.intel.com>
> > ---
> > Like this? (Drop patch 1)
>
> Will be more readable with a patch that converts host_fx_image to
> unlazy_fpu(), and a second patch that converts guest_fx_image to the fpu
> API.
OK.
> I think unlazy_fpu() is even a performance win in case userspace doesn't
> do a lot of floating point (which is the case with qemu). I wonder why
> we didn't think of it before.
...
--
regards
Yang, Sheng
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-05-17 8:24 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-14 3:16 [PATCH 0/3] Convert KVM to use FPU API Sheng Yang
2010-05-14 3:16 ` [PATCH 1/3] x86: Split fpu_save_init() to fpu_save() and fpu_clear() Sheng Yang
2010-05-14 3:16 ` [PATCH 2/3] x86: Export FPU API for KVM use Sheng Yang
2010-05-14 3:16 ` [PATCH 3/3] KVM: x86: Use FPU API Sheng Yang
2010-05-15 8:06 ` Avi Kivity
2010-05-17 8:09 ` Sheng Yang
2010-05-17 8:18 ` Avi Kivity
2010-05-17 8:22 ` Sheng Yang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).