diff options
author | Sheng Yang <sheng@linux.intel.com> | 2010-05-17 05:08:28 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-08-01 03:35:49 -0400 |
commit | 98918833a3e21ffc5619535955e7a003cb788163 (patch) | |
tree | 7b073bb8888927391b11810e104d2cd4a694f86e /arch/x86 | |
parent | 7cf30855e02be7a207ffebb8b9350986f2ba83e9 (diff) |
KVM: x86: Use FPU API
Convert KVM to use generic FPU API.
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 17 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 52 |
2 files changed, 17 insertions, 52 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index d93601c52902..d08bb4a202de 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -301,7 +301,7 @@ struct kvm_vcpu_arch { | |||
301 | unsigned long mmu_seq; | 301 | unsigned long mmu_seq; |
302 | } update_pte; | 302 | } update_pte; |
303 | 303 | ||
304 | struct i387_fxsave_struct guest_fx_image; | 304 | struct fpu guest_fpu; |
305 | 305 | ||
306 | gva_t mmio_fault_cr2; | 306 | gva_t mmio_fault_cr2; |
307 | struct kvm_pio_request pio; | 307 | struct kvm_pio_request pio; |
@@ -708,21 +708,6 @@ static inline unsigned long read_msr(unsigned long msr) | |||
708 | } | 708 | } |
709 | #endif | 709 | #endif |
710 | 710 | ||
711 | static inline void kvm_fx_save(struct i387_fxsave_struct *image) | ||
712 | { | ||
713 | asm("fxsave (%0)":: "r" (image)); | ||
714 | } | ||
715 | |||
716 | static inline void kvm_fx_restore(struct i387_fxsave_struct *image) | ||
717 | { | ||
718 | asm("fxrstor (%0)":: "r" (image)); | ||
719 | } | ||
720 | |||
721 | static inline void kvm_fx_finit(void) | ||
722 | { | ||
723 | asm("finit"); | ||
724 | } | ||
725 | |||
726 | static inline u32 get_rdx_init_val(void) | 711 | static inline u32 get_rdx_init_val(void) |
727 | { | 712 | { |
728 | return 0x600; /* P6 family */ | 713 | return 0x600; /* P6 family */ |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 54ce77582eda..84b1788489de 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #include <asm/mtrr.h> | 53 | #include <asm/mtrr.h> |
54 | #include <asm/mce.h> | 54 | #include <asm/mce.h> |
55 | #include <asm/i387.h> | 55 | #include <asm/i387.h> |
56 | #include <asm/xcr.h> | ||
56 | 57 | ||
57 | #define MAX_IO_MSRS 256 | 58 | #define MAX_IO_MSRS 256 |
58 | #define CR0_RESERVED_BITS \ | 59 | #define CR0_RESERVED_BITS \ |
@@ -5058,27 +5059,6 @@ out: | |||
5058 | } | 5059 | } |
5059 | 5060 | ||
5060 | /* | 5061 | /* |
5061 | * fxsave fpu state. Taken from x86_64/processor.h. To be killed when | ||
5062 | * we have asm/x86/processor.h | ||
5063 | */ | ||
5064 | struct fxsave { | ||
5065 | u16 cwd; | ||
5066 | u16 swd; | ||
5067 | u16 twd; | ||
5068 | u16 fop; | ||
5069 | u64 rip; | ||
5070 | u64 rdp; | ||
5071 | u32 mxcsr; | ||
5072 | u32 mxcsr_mask; | ||
5073 | u32 st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ | ||
5074 | #ifdef CONFIG_X86_64 | ||
5075 | u32 xmm_space[64]; /* 16*16 bytes for each XMM-reg = 256 bytes */ | ||
5076 | #else | ||
5077 | u32 xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */ | ||
5078 | #endif | ||
5079 | }; | ||
5080 | |||
5081 | /* | ||
5082 | * Translate a guest virtual address to a guest physical address. | 5062 | * Translate a guest virtual address to a guest physical address. |
5083 | */ | 5063 | */ |
5084 | int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, | 5064 | int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, |
@@ -5101,7 +5081,8 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, | |||
5101 | 5081 | ||
5102 | int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) | 5082 | int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) |
5103 | { | 5083 | { |
5104 | struct fxsave *fxsave = (struct fxsave *)&vcpu->arch.guest_fx_image; | 5084 | struct i387_fxsave_struct *fxsave = |
5085 | &vcpu->arch.guest_fpu.state->fxsave; | ||
5105 | 5086 | ||
5106 | memcpy(fpu->fpr, fxsave->st_space, 128); | 5087 | memcpy(fpu->fpr, fxsave->st_space, 128); |
5107 | fpu->fcw = fxsave->cwd; | 5088 | fpu->fcw = fxsave->cwd; |
@@ -5117,7 +5098,8 @@ int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) | |||
5117 | 5098 | ||
5118 | int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) | 5099 | int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) |
5119 | { | 5100 | { |
5120 | struct fxsave *fxsave = (struct fxsave *)&vcpu->arch.guest_fx_image; | 5101 | struct i387_fxsave_struct *fxsave = |
5102 | &vcpu->arch.guest_fpu.state->fxsave; | ||
5121 | 5103 | ||
5122 | memcpy(fxsave->st_space, fpu->fpr, 128); | 5104 | memcpy(fxsave->st_space, fpu->fpr, 128); |
5123 | fxsave->cwd = fpu->fcw; | 5105 | fxsave->cwd = fpu->fcw; |
@@ -5133,22 +5115,18 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) | |||
5133 | 5115 | ||
5134 | void fx_init(struct kvm_vcpu *vcpu) | 5116 | void fx_init(struct kvm_vcpu *vcpu) |
5135 | { | 5117 | { |
5136 | unsigned after_mxcsr_mask; | 5118 | fpu_alloc(&vcpu->arch.guest_fpu); |
5137 | 5119 | fpu_finit(&vcpu->arch.guest_fpu); | |
5138 | /* Initialize guest FPU by resetting ours and saving into guest's */ | ||
5139 | preempt_disable(); | ||
5140 | kvm_fx_finit(); | ||
5141 | kvm_fx_save(&vcpu->arch.guest_fx_image); | ||
5142 | preempt_enable(); | ||
5143 | 5120 | ||
5144 | vcpu->arch.cr0 |= X86_CR0_ET; | 5121 | vcpu->arch.cr0 |= X86_CR0_ET; |
5145 | after_mxcsr_mask = offsetof(struct i387_fxsave_struct, st_space); | ||
5146 | vcpu->arch.guest_fx_image.mxcsr = 0x1f80; | ||
5147 | memset((void *)&vcpu->arch.guest_fx_image + after_mxcsr_mask, | ||
5148 | 0, sizeof(struct i387_fxsave_struct) - after_mxcsr_mask); | ||
5149 | } | 5122 | } |
5150 | EXPORT_SYMBOL_GPL(fx_init); | 5123 | EXPORT_SYMBOL_GPL(fx_init); |
5151 | 5124 | ||
5125 | static void fx_free(struct kvm_vcpu *vcpu) | ||
5126 | { | ||
5127 | fpu_free(&vcpu->arch.guest_fpu); | ||
5128 | } | ||
5129 | |||
5152 | void kvm_load_guest_fpu(struct kvm_vcpu *vcpu) | 5130 | void kvm_load_guest_fpu(struct kvm_vcpu *vcpu) |
5153 | { | 5131 | { |
5154 | if (vcpu->guest_fpu_loaded) | 5132 | if (vcpu->guest_fpu_loaded) |
@@ -5156,7 +5134,7 @@ void kvm_load_guest_fpu(struct kvm_vcpu *vcpu) | |||
5156 | 5134 | ||
5157 | vcpu->guest_fpu_loaded = 1; | 5135 | vcpu->guest_fpu_loaded = 1; |
5158 | unlazy_fpu(current); | 5136 | unlazy_fpu(current); |
5159 | kvm_fx_restore(&vcpu->arch.guest_fx_image); | 5137 | fpu_restore_checking(&vcpu->arch.guest_fpu); |
5160 | trace_kvm_fpu(1); | 5138 | trace_kvm_fpu(1); |
5161 | } | 5139 | } |
5162 | 5140 | ||
@@ -5166,7 +5144,7 @@ void kvm_put_guest_fpu(struct kvm_vcpu *vcpu) | |||
5166 | return; | 5144 | return; |
5167 | 5145 | ||
5168 | vcpu->guest_fpu_loaded = 0; | 5146 | vcpu->guest_fpu_loaded = 0; |
5169 | kvm_fx_save(&vcpu->arch.guest_fx_image); | 5147 | fpu_save_init(&vcpu->arch.guest_fpu); |
5170 | ++vcpu->stat.fpu_reload; | 5148 | ++vcpu->stat.fpu_reload; |
5171 | set_bit(KVM_REQ_DEACTIVATE_FPU, &vcpu->requests); | 5149 | set_bit(KVM_REQ_DEACTIVATE_FPU, &vcpu->requests); |
5172 | trace_kvm_fpu(0); | 5150 | trace_kvm_fpu(0); |
@@ -5179,6 +5157,7 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu) | |||
5179 | vcpu->arch.time_page = NULL; | 5157 | vcpu->arch.time_page = NULL; |
5180 | } | 5158 | } |
5181 | 5159 | ||
5160 | fx_free(vcpu); | ||
5182 | kvm_x86_ops->vcpu_free(vcpu); | 5161 | kvm_x86_ops->vcpu_free(vcpu); |
5183 | } | 5162 | } |
5184 | 5163 | ||
@@ -5213,6 +5192,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) | |||
5213 | kvm_mmu_unload(vcpu); | 5192 | kvm_mmu_unload(vcpu); |
5214 | vcpu_put(vcpu); | 5193 | vcpu_put(vcpu); |
5215 | 5194 | ||
5195 | fx_free(vcpu); | ||
5216 | kvm_x86_ops->vcpu_free(vcpu); | 5196 | kvm_x86_ops->vcpu_free(vcpu); |
5217 | } | 5197 | } |
5218 | 5198 | ||