|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH] x86/pv: Fix multiple bugs with SEGBASE_GS_USER_SEL
On 31.08.2020 13:18, Andrew Cooper wrote:
> --- a/xen/arch/x86/x86_64/mm.c
> +++ b/xen/arch/x86/x86_64/mm.c
> @@ -1059,16 +1059,52 @@ long do_set_segment_base(unsigned int which, unsigned
> long base)
> break;
>
> case SEGBASE_GS_USER_SEL:
> - __asm__ __volatile__ (
> - " swapgs \n"
> - "1: movl %k0,%%gs \n"
> - " "safe_swapgs" \n"
> - ".section .fixup,\"ax\" \n"
> - "2: xorl %k0,%k0 \n"
> - " jmp 1b \n"
> - ".previous \n"
> - _ASM_EXTABLE(1b, 2b)
> - : "+r" (base) );
> + /*
> + * We wish to update the user %gs from the GDT/LDT. Currently, the
> + * guest kernel's GS_BASE is in context.
> + */
> + asm volatile ( "swapgs" );
> +
> + if ( base <= 3 )
Either !(base & 0xfffc) or you want to truncate the input to
uint16_t first. The upper 48 bits have always been ignored. With
this addressed one way or another
Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
Yet two more minor comments:
> + {
> + /* Work around NUL segment behaviour on AMD hardware. */
> + if ( boot_cpu_data.x86_vendor &
> + (X86_VENDOR_AMD | X86_VENDOR_HYGON) )
> + asm volatile ( "mov %[sel], %%gs"
> + :: [sel] "rm" (FLAT_USER_DS32) );
> + }
> + else
> + /* Fix up RPL. */
> + base |= 3;
For a fair part of this block you could save a level of indentation
by inverting the initial condition and using "else if" later on.
> + /*
> + * Load the chosen selector, with fault handling.
> + *
> + * Errors ought to fail the hypercall, but that was never built in
> + * originally, and Linux will BUG() if this call fails.
> + *
> + * NUL the selector in the case of an error. This too needs to deal
> + * with the AMD NUL segment behaviour, but it is already a slowpath
> in
> + * #GP context so perform the flat load unconditionally to avoid
> + * complicated logic.
> + *
> + * Anyone wanting to check for errors from this hypercall should
> + * re-read %gs and compare against the input 'base' selector.
> + */
> + asm volatile ( "1: mov %k[sel], %%gs\n\t"
> + ".section .fixup, \"ax\", @progbits\n\t"
> + "2: mov %k[flat], %%gs\n\t"
> + " xor %k[sel], %k[sel]\n\t"
> + " jmp 1b\n\t"
> + ".previous\n\t"
> + _ASM_EXTABLE(1b, 2b)
> + : [sel] "+r" (base)
> + : [flat] "rm" (FLAT_USER_DS32) );
"m" is pointless to specify here - the compiler won't instantiate a
memory variable when the value is an immediate. This can be observed
best when you specify _just_ "m" here.
Jan
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |