[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] x86/PV: avoid indirect call/thunk in I/O emulation
On 15/02/18 16:03, Jan Beulich wrote: > The stub is within reach from the .text section, so there's no point > using an indirect call here. This has the added benefit of there no > longer being two sufficiently different approaches, breaking one of > which people may not even notice. > > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Wow - after all effort I've spent changing (and breaking) this, it hadn't even occurred to me that a plain jmp was fine. > > --- a/xen/arch/x86/pv/emul-priv-op.c > +++ b/xen/arch/x86/pv/emul-priv-op.c > @@ -73,55 +73,42 @@ void (*pv_post_outb_hook)(unsigned int p > > typedef void io_emul_stub_t(struct cpu_user_regs *); > > -void __x86_indirect_thunk_rcx(void); > - > static io_emul_stub_t *io_emul_stub_setup(struct priv_op_ctxt *ctxt, u8 > opcode, > unsigned int port, unsigned int > bytes) > { > struct stubs *this_stubs = &this_cpu(stubs); > unsigned long stub_va = this_stubs->addr + STUB_BUF_SIZE / 2; > + signed long disp; I'm not in favour of sprinkling 'signed' all over the code base. long is already unambiguous, and a far more common construct to encounter. > bool use_quirk_stub = false; > > if ( !ctxt->io_emul_stub ) > ctxt->io_emul_stub = > map_domain_page(_mfn(this_stubs->mfn)) + (stub_va & ~PAGE_MASK); > > - /* movq $host_to_guest_gpr_switch,%rcx */ > - ctxt->io_emul_stub[0] = 0x48; > - ctxt->io_emul_stub[1] = 0xb9; > - *(void **)&ctxt->io_emul_stub[2] = (void *)host_to_guest_gpr_switch; > - > -#ifdef CONFIG_INDIRECT_THUNK > - /* callq __x86_indirect_thunk_rcx */ > - ctxt->io_emul_stub[10] = 0xe8; > - *(int32_t *)&ctxt->io_emul_stub[11] = > - (long)__x86_indirect_thunk_rcx - (stub_va + 11 + 4); > -#else > - /* callq *%rcx */ > - ctxt->io_emul_stub[10] = 0xff; > - ctxt->io_emul_stub[11] = 0xd1; > - /* TODO: untangle ideal_nops from init/livepatch Kconfig options. */ > - memcpy(&ctxt->io_emul_stub[12], "\x0f\x1f\x00", 3); /* P6_NOP3 */ > -#endif > + /* call host_to_guest_gpr_switch */ > + ctxt->io_emul_stub[0] = 0xe8; > + disp = (long)host_to_guest_gpr_switch - (stub_va + 1 + 4); The 1 in the middle here only aids clarity in the context above, where it was part of a direct assignment to offset 11 in io_emul_stub[]. It is marginal, but in this case, I think stub_va + 5 would be slightly clearer, as call opcode is obviously at 0, and the length of a call instruction is 5. ~Andrew > + BUG_ON((int32_t)disp != disp); > + *(int32_t *)&ctxt->io_emul_stub[1] = disp; > > if ( unlikely(ioemul_handle_quirk) ) > - use_quirk_stub = ioemul_handle_quirk(opcode, &ctxt->io_emul_stub[15], > + use_quirk_stub = ioemul_handle_quirk(opcode, &ctxt->io_emul_stub[5], > ctxt->ctxt.regs); > > if ( !use_quirk_stub ) > { > /* data16 or nop */ > - ctxt->io_emul_stub[15] = (bytes != 2) ? 0x90 : 0x66; > + ctxt->io_emul_stub[5] = (bytes != 2) ? 0x90 : 0x66; > /* <io-access opcode> */ > - ctxt->io_emul_stub[16] = opcode; > + ctxt->io_emul_stub[6] = opcode; > /* imm8 or nop */ > - ctxt->io_emul_stub[17] = !(opcode & 8) ? port : 0x90; > + ctxt->io_emul_stub[7] = !(opcode & 8) ? port : 0x90; > /* ret (jumps to guest_to_host_gpr_switch) */ > - ctxt->io_emul_stub[18] = 0xc3; > + ctxt->io_emul_stub[8] = 0xc3; > } > > - BUILD_BUG_ON(STUB_BUF_SIZE / 2 < MAX(19, /* Default emul stub */ > - 15 + IOEMUL_QUIRK_STUB_BYTES)); > + BUILD_BUG_ON(STUB_BUF_SIZE / 2 < MAX(9, /* Default emul stub */ > + 5 + IOEMUL_QUIRK_STUB_BYTES)); > > /* Handy function-typed pointer to the stub. */ > return (void *)stub_va; > > > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |