2017-05-30 12:15+0200, Paolo Bonzini: > On 30/05/2017 00:48, Nick Desaulniers wrote: >> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c >> @@ -3985,57 +3985,45 @@ static int em_fxsave(struct x86_emulate_ctxt *ctxt) >> static int em_fxrstor(struct x86_emulate_ctxt *ctxt) >> { >> struct fxregs_state fx_state; >> int rc; >> + unsigned int size; >> >> rc = check_fxsr(ctxt); >> if (rc != X86EMUL_CONTINUE) >> return rc; >> >> - rc = segmented_read_std(ctxt, ctxt->memop.addr.mem, &fx_state, 512); >> - if (rc != X86EMUL_CONTINUE) >> - return rc; >> + ctxt->ops->get_fpu(ctxt); >> + >> + if (ctxt->mode < X86EMUL_MODE_PROT64) { >> + rc = asm_safe("fxsave %[fx]", , [fx] "+m"(fx_state)); >> + if (rc != X86EMUL_CONTINUE) >> + return rc;
Please call ctxt->ops->put_fpu() before returning. (Don't be afraid to use 'goto', the will likely be more of them.) >> + /* >> + * Hardware doesn't save and restore XMM 0-7 without >> + * CR4.OSFXSR, but does save and restore MXCSR. >> + */ >> + if (ctxt->ops->get_cr(ctxt, 4) & X86_CR4_OSFXSR) >> + size = offsetof(struct fxregs_state, xmm_space[8]); This should be the size of first 8 XMM registers, but xmm_space is of type u32, so the correct size is xmm_space[8 * 16/sizeof(*fx_state.xmm_space)]. Adding a separate function to compute the size and call it from em_fxrstor and em_fxsave would make sense at this point. >> + else >> + size = offsetof(struct fxregs_state, xmm_space[0]); >> + rc = segmented_read_std(ctxt, ctxt->memop.addr.mem, &fx_state, >> + size); >> + if (rc != X86EMUL_CONTINUE) >> + return rc; >> + } else if (ctxt->mode == X86EMUL_MODE_PROT64) { >> + size = offsetof(struct fxregs_state, xmm_space[16]); >> + rc = segmented_read_std(ctxt, ctxt->memop.addr.mem, &fx_state, >> + size); >> + if (rc != X86EMUL_CONTINUE) >> + return rc; >> + } > > You can just remove the "if (ctxt->mode == X86EMUL_MODE_PROT64)". This > way, the call of segmented_read_std and the "if (rc != > X86EMUL_CONTINUE)" can move outside the conditional. Good idea. check_fxsr() doesn't allow X86EMUL_MODE_PROT64 and the condition was an artefact from older iterations. I'll refresh the kvm-unit-test ([kvm-unit-tests PATCH] x86: realmode: add FXSR tests).