|
[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 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?
> --- 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.
> 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. 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?
> --- /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?
> + * With compiler support, dispatch to the correct __x86.indirect_thunk.*
> + */
> + .if CONFIG_INDIRECT_THUNK == 1
If we really want/need to keep this config option, why not without
the "== 1"?
> + $done = 0
> + .irp reg, rax, rbx, rcx, rdx, rsi, rdi, rbp, r8, r9, r10, r11, r12,
> r13, r14, r15
Same cosmetic remark as earlier regarding the ordering and the
possible omission of the r-s here.
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |