[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v6.5 11/26] x86: Support indirect thunks from assembly code
On 04/01/18 09:23, Jan Beulich wrote: >>>> On 04.01.18 at 01:15, <andrew.cooper3@xxxxxxxxxx> wrote: >> --- a/xen/arch/x86/boot/trampoline.S >> +++ b/xen/arch/x86/boot/trampoline.S >> @@ -153,8 +153,28 @@ trampoline_protmode_entry: >> .code64 >> start64: >> /* Jump to high mappings. */ >> - movabs $__high_start,%rax >> - jmpq *%rax >> + movabs $__high_start, %rdi >> + >> +#ifdef CONFIG_INDIRECT_THUNK >> + /* >> + * If booting virtualised, or hot-onlining a CPU, sibling threads >> can >> + * attempt Branch Target Injection against this jmp. >> + * >> + * We've got no usable stack so can't use a RETPOLINE thunk, and are >> + * further than +- 2G from the high mappings so couldn't use >> JUMP_THUNK >> + * even if was a non-RETPOLINE thunk. Futhermore, an LFENCE isn't >> + * necesserily safe to use at this point. >> + * >> + * As this isn't a hotpath, use a fully serialising event to reduce >> + * the speculation window as much as possible. %ebx needs >> preserving >> + * for __high_start. >> + */ >> + mov %ebx, %esi >> + cpuid >> + mov %esi, %ebx >> +#endif >> + >> + jmpq *%rdi > Would there be anything wrong with omitting the #ifdef, slightly > improving readability? Functionally, not, but I'm not convinced it would make anything better either. > >> --- a/xen/arch/x86/pv/emul-priv-op.c >> +++ b/xen/arch/x86/pv/emul-priv-op.c >> @@ -73,37 +73,58 @@ void (*pv_post_outb_hook)(unsigned int port, u8 value); >> >> typedef void io_emul_stub_t(struct cpu_user_regs *); >> >> +#ifdef CONFIG_INDIRECT_THUNK >> +extern char ind_thunk_rcx[] asm ("__x86.indirect_thunk.rcx"); >> +#endif > Again I don't see the value of the #ifdef. This ifdef is strictly required. asm ("__x86.indirect_thunk.rcx"); doesn't exist when building with an incapable toolchain. > >> 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; >> + >> if ( !ctxt->io_emul_stub ) >> - ctxt->io_emul_stub = map_domain_page(_mfn(this_cpu(stubs.mfn))) + >> - (this_cpu(stubs.addr) & >> - ~PAGE_MASK) + >> - STUB_BUF_SIZE / 2; >> + 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] = >> + _p(ind_thunk_rcx) - _p(stub_va + 11 + 4); > Why two (hidden) casts when one (clearly visible one) would do: > > *(int32_t *)&ctxt->io_emul_stub[11] = > (unsigned long)ind_thunk_rcx - (stub_va + 11 + 4); > > ? > >> +#else >> /* callq *%rcx */ >> ctxt->io_emul_stub[10] = 0xff; >> ctxt->io_emul_stub[11] = 0xd1; >> + >> + /* >> + * 3 bytes of P6_NOPS. >> + * TODO: untangle ideal_nops from init/livepatch Kconfig options. >> + */ >> + memcpy(&ctxt->io_emul_stub[12], "\x0f\x1f\x00", 3); >> +#endif > Same here - rather than making everything more complicated to > read/understand, why don't we avoid conditionals in places where > performance is of no concern. Again, these are strictly required, because of ind_thunk_rcx[]. > In the end it may well be that we > wouldn't need CONFIG_INDIRECT_THUNK at all, unless it became > a user-selectable option (as suggested in reply to patch 9). > >> --- a/xen/include/asm-x86/asm_defns.h >> +++ b/xen/include/asm-x86/asm_defns.h >> @@ -13,6 +13,14 @@ >> #include <asm/cpufeature.h> >> #include <asm/alternative.h> >> >> +#ifdef __ASSEMBLY__ >> +# include <asm/indirect_thunk_asm.h> >> +#else >> +asm ( "\t.equ CONFIG_INDIRECT_THUNK, " >> + __stringify(IS_ENABLED(CONFIG_INDIRECT_THUNK)) ); >> +asm ( "\t.include \"asm/indirect_thunk_asm.h\"" ); >> +#endif > For this to work with all compilers, aren't you still missing the > addition of -Wa,-I$(BASEDIR)/include on top of the other > compiler option additions done in patch 9? Ah yes - I will fold that in. > >> --- /dev/null >> +++ b/xen/include/asm-x86/indirect_thunk_asm.h >> @@ -0,0 +1,41 @@ >> +/* >> + * Warning! This file is included at an assembler level for .c files, >> causing >> + * usual #ifdef'ary to turn into comments. >> + */ >> + >> +.macro IND_THUNK insn:req arg:req >> +/* >> + * Create an indirect branch. insn is one of call/jmp, arg is a single >> + * register. >> + * >> + * With no compiler support, this degrated into a plain indirect call/jmp. > "degrades" or "degenerates" or yet something else? Degrades. ~Andrew _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |