Commit eef26553c782c26646c8b5b63afa6182187104eb

Authored by aliguori
1 parent 059cef40

Implement FFXSR (Alexander Graf)

Newer AMD CPUs have the FFXSR capability. This leaves out XMM
register in FXSAVE/FXRESTORE when in CPL=0 and 64-bit mode.

This is required for Hyper-V.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6500 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 20 additions and 8 deletions
target-i386/op_helper.c
@@ -3030,6 +3030,8 @@ void helper_wrmsr(void) @@ -3030,6 +3030,8 @@ void helper_wrmsr(void)
3030 update_mask |= MSR_EFER_NXE; 3030 update_mask |= MSR_EFER_NXE;
3031 if (env->cpuid_ext3_features & CPUID_EXT3_SVM) 3031 if (env->cpuid_ext3_features & CPUID_EXT3_SVM)
3032 update_mask |= MSR_EFER_SVME; 3032 update_mask |= MSR_EFER_SVME;
  3033 + if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR)
  3034 + update_mask |= MSR_EFER_FFXSR;
3033 cpu_load_efer(env, (env->efer & ~update_mask) | 3035 cpu_load_efer(env, (env->efer & ~update_mask) |
3034 (val & update_mask)); 3036 (val & update_mask));
3035 } 3037 }
@@ -4352,10 +4354,15 @@ void helper_fxsave(target_ulong ptr, int data64) @@ -4352,10 +4354,15 @@ void helper_fxsave(target_ulong ptr, int data64)
4352 else 4354 else
4353 nb_xmm_regs = 8; 4355 nb_xmm_regs = 8;
4354 addr = ptr + 0xa0; 4356 addr = ptr + 0xa0;
4355 - for(i = 0; i < nb_xmm_regs; i++) {  
4356 - stq(addr, env->xmm_regs[i].XMM_Q(0));  
4357 - stq(addr + 8, env->xmm_regs[i].XMM_Q(1));  
4358 - addr += 16; 4357 + /* Fast FXSAVE leaves out the XMM registers */
  4358 + if (!(env->efer & MSR_EFER_FFXSR)
  4359 + || (env->hflags & HF_CPL_MASK)
  4360 + || !(env->hflags & HF_LMA_MASK)) {
  4361 + for(i = 0; i < nb_xmm_regs; i++) {
  4362 + stq(addr, env->xmm_regs[i].XMM_Q(0));
  4363 + stq(addr + 8, env->xmm_regs[i].XMM_Q(1));
  4364 + addr += 16;
  4365 + }
4359 } 4366 }
4360 } 4367 }
4361 } 4368 }
@@ -4392,10 +4399,15 @@ void helper_fxrstor(target_ulong ptr, int data64) @@ -4392,10 +4399,15 @@ void helper_fxrstor(target_ulong ptr, int data64)
4392 else 4399 else
4393 nb_xmm_regs = 8; 4400 nb_xmm_regs = 8;
4394 addr = ptr + 0xa0; 4401 addr = ptr + 0xa0;
4395 - for(i = 0; i < nb_xmm_regs; i++) {  
4396 - env->xmm_regs[i].XMM_Q(0) = ldq(addr);  
4397 - env->xmm_regs[i].XMM_Q(1) = ldq(addr + 8);  
4398 - addr += 16; 4402 + /* Fast FXRESTORE leaves out the XMM registers */
  4403 + if (!(env->efer & MSR_EFER_FFXSR)
  4404 + || (env->hflags & HF_CPL_MASK)
  4405 + || !(env->hflags & HF_LMA_MASK)) {
  4406 + for(i = 0; i < nb_xmm_regs; i++) {
  4407 + env->xmm_regs[i].XMM_Q(0) = ldq(addr);
  4408 + env->xmm_regs[i].XMM_Q(1) = ldq(addr + 8);
  4409 + addr += 16;
  4410 + }
4399 } 4411 }
4400 } 4412 }
4401 } 4413 }