[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH] x86: correct asm() constraints when dealing with immediate selector values
On 09/09/2021 15:56, Jan Beulich wrote: > asm() constraints need to fit both the intended insn(s) which the > respective operands are going to be used with as well as the actual kind > of value specified. "m" (alone) together with a constant, however, leads > to gcc saying > > error: memory input <N> is not directly addressable > > while clang complains > > error: invalid lvalue in asm input for constraint 'm' > > And rightly so - in order to access a memory operand, an address needs > to be specified to the insn. In some cases it might be possible for a > compiler to synthesize a memory operand holding the requested constant, > but I think any solution there would have sharp edges. It's precisely what happens in the other uses of constants which you haven't adjusted below. Constants are fine if being propagated into a static inline which has properly typed parameters. Or are you saying automatic spilling when a width isn't necessarily known? > If "m" alone doesn't work with constants, it is at best pointless (and > perhaps misleading or even risky - the compiler might decide to actually > pick "m" and not try very hard to find a suitable register) to specify > it alongside "r". > > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> I'm slightly surprised you didn't spot and comment about what Clang does with this. https://godbolt.org/z/M4nrerrWM For "rm" (0), clang really does spill the constant into a global and generate a rip-relative mov to fs, which is especially funny considering the rejection of "m" as a constraint. Clang even spills "rm" (local) into a global, while "m" (local) does come from the stack. I think there is a reasonable argument to say "m" (const) doesn't have enough type (width) information for a compiler to do anything sensible with, and therefore it is fair to be dropped. But for "rm" (var), where there is enough width information, I don't think it is reasonable to drop the "m" and restrict the flexibility. Furthermore, I'm going to argue that we shouldn't work around this behaviour by removing "m" elsewhere. This code generation bug/misfeature affects every use of "rm", even when the referenced operand is on the stack and can be used without unspilling first. > > --- a/xen/arch/x86/cpu/amd.c > +++ b/xen/arch/x86/cpu/amd.c > @@ -736,7 +736,7 @@ void __init detect_zen2_null_seg_behavio > uint64_t base; > > wrmsrl(MSR_FS_BASE, 1); > - asm volatile ( "mov %0, %%fs" :: "rm" (0) ); > + asm volatile ( "mov %0, %%fs" :: "r" (0) ); > rdmsrl(MSR_FS_BASE, base); > > if (base == 0) > --- a/xen/arch/x86/x86_64/traps.c > +++ b/xen/arch/x86/x86_64/traps.c > @@ -248,7 +248,7 @@ void do_double_fault(struct cpu_user_reg > > console_force_unlock(); > > - asm ( "lsll %1, %0" : "=r" (cpu) : "rm" (PER_CPU_SELECTOR) ); > + asm ( "lsll %1, %0" : "=r" (cpu) : "r" (PER_CPU_SELECTOR) ); Any chance we can clean this up to: lsl %[lim], %[sel] seeing as the line is being edited? ~Andrew
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |