[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 2/4] x86emul: centralize put_fpu() invocations
On 13/03/17 11:03, Jan Beulich wrote: > ..., splitting parts of it into check_*() macros. This is in > preparation of making ->put_fpu() do further adjustments to register > state. (Some of the check_xmm() invocations could be avoided, as in > some of the cases no insns handled there can actually raise #XM, but I > think we're better off keeping them to avoid later additions of further > insn patterns rendering the lack of the check a bug.) > > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> > > --- a/xen/arch/x86/x86_emulate/x86_emulate.c > +++ b/xen/arch/x86/x86_emulate/x86_emulate.c > @@ -937,6 +937,7 @@ do { > > struct fpu_insn_ctxt { > uint8_t insn_bytes; > + uint8_t type; > int8_t exn_raised; > }; > > @@ -956,8 +957,6 @@ static int _get_fpu( > { > int rc; > > - fic->exn_raised = -1; > - > fail_if(!ops->get_fpu); > rc = ops->get_fpu(fpu_handle_exception, fic, type, ctxt); > > @@ -965,6 +964,8 @@ static int _get_fpu( > { > unsigned long cr0; > > + fic->type = type; > + > fail_if(!ops->read_cr); > if ( type >= X86EMUL_FPU_xmm ) > { > @@ -1006,22 +1007,31 @@ do { > rc = _get_fpu(_type, _fic, ctxt, ops); \ > if ( rc ) goto done; \ > } while (0) > -#define _put_fpu() \ > + > +#define check_fpu(_fic) \ > do { \ > - if ( ops->put_fpu != NULL ) \ > - (ops->put_fpu)(ctxt); \ > + generate_exception_if((_fic)->exn_raised >= 0, \ > + (_fic)->exn_raised); \ > } while (0) > -#define put_fpu(_fic) \ > + > +#define check_xmm(_fic) \ > do { \ > - _put_fpu(); \ > if ( (_fic)->exn_raised == EXC_XM && ops->read_cr && \ > ops->read_cr(4, &cr4, ctxt) == X86EMUL_OKAY && \ > !(cr4 & X86_CR4_OSXMMEXCPT) ) \ > (_fic)->exn_raised = EXC_UD; \ > - generate_exception_if((_fic)->exn_raised >= 0, \ > - (_fic)->exn_raised); \ > + check_fpu(_fic); \ > } while (0) These two check macros seem like they should have an _exn() suffix to make it clearer what they are actually doing. > > +static void put_fpu( > + struct fpu_insn_ctxt *fic, > + struct x86_emulate_ctxt *ctxt, > + const struct x86_emulate_ops *ops) > +{ > + if ( fic->type != X86EMUL_FPU_none && ops->put_fpu ) > + ops->put_fpu(ctxt); > +} > + > static inline bool fpu_check_write(void) > { > uint16_t fsw; > @@ -7905,7 +7912,8 @@ x86_emulate( > ctxt->regs->eflags &= ~X86_EFLAGS_RF; > > done: > - _put_fpu(); > + if ( rc != X86EMUL_OKAY ) > + put_fpu(&fic, ctxt, ops); Unless you assert at complete_insn that rc == X86EMUL_OKAY, you still might call put_fpu() twice. You can avoid the conditional here by setting fic->type to X86EMUL_FPU_none at the end of put_fpu(), which looks like it is compatible with your later modifications. > put_stub(stub); > return rc; > #undef state > --- a/xen/arch/x86/x86_emulate/x86_emulate.h > +++ b/xen/arch/x86/x86_emulate/x86_emulate.h > @@ -161,7 +161,9 @@ enum x86_emulate_fpu_type { > X86EMUL_FPU_wait, /* WAIT/FWAIT instruction */ > X86EMUL_FPU_mmx, /* MMX instruction set (%mm0-%mm7) */ > X86EMUL_FPU_xmm, /* SSE instruction set (%xmm0-%xmm7/15) */ > - X86EMUL_FPU_ymm /* AVX/XOP instruction set (%ymm0-%ymm7/15) */ > + X86EMUL_FPU_ymm, /* AVX/XOP instruction set (%ymm0-%ymm7/15) */ > + /* This sentinel will never be passed to ->get_fpu(). */ Don't you mean ->put_fpu() here? Either way, can we assert this fact? ~Andrew > + X86EMUL_FPU_none > }; > > struct cpuid_leaf > > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |