x86: correct asm() constraints when dealing with immediate selector values
authorJan Beulich <jbeulich@suse.com>
Tue, 28 Jun 2022 15:00:29 +0000 (17:00 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 28 Jun 2022 15:00:29 +0000 (17:00 +0200)
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.

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". And indeed clang does, oddly enough despite its
objection to "m" alone. Which means there the change also improves the
generated code.

While there also switch the two operand case to using named operands.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Roger Pau Monné <roger.pau@citrix.com>
xen/arch/x86/cpu/amd.c
xen/arch/x86/x86_64/traps.c

index 94b9e310161f93b332506af4941555a47954b4ab..f1d11a1cb73434c06a53aa3aa209b2801408e554 100644 (file)
@@ -736,7 +736,7 @@ void __init detect_zen2_null_seg_behaviour(void)
        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)
index 9d7f1f818b9368133f7a546154155b02f8787e61..f8cb8d9a9482f27cde40288aeeda8e325934a28e 100644 (file)
@@ -274,7 +274,8 @@ void do_double_fault(struct cpu_user_regs *regs)
 
     console_force_unlock();
 
-    asm ( "lsll %1, %0" : "=r" (cpu) : "rm" (PER_CPU_SELECTOR) );
+    asm ( "lsll %[sel], %[limit]" : [limit] "=r" (cpu)
+                                  : [sel] "r" (PER_CPU_SELECTOR) );
 
     /* Find information saved during fault and dump it to the console. */
     printk("*** DOUBLE FAULT ***\n");