With all the infrastructure in place, switch from using ALTERNATIVE() to
simply populating .alt_call_sites.
Before, _apply_alternatives() would devirtualise in two passes; the first
being opportunistic, and the second (signified by the force parameter) sealing
any call with a still-NULL function pointer.
Now, all devirtualising is performed together, at the point in time of the
second pass previously. The call to seal_endbr64() needs delaying until after
apply_alt_calls() is complete, or we have a narrow window with real indirect
branches and no ENDBR64 instructions.
Under the hood, the following changes are happening:
Section Old size New size Change (%)
.alt_call_sites 0 0x00730 +0x0730
.altinstructions 0x1350a 0x11fe0 -0x152a (-7%)
.altinstr_replacement 0x015f2 0x00e35 -0x07bd (-23%)
The changes aren't quite equal because inlining is affected by the smaller
asm() block. Nevertheless, the metadata is held in 1/3 of the space, and
there are no CALL instructions held in the replacement section any more.
No functional change.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
text_poke(orig, buf, total_len);
}
- /*
- * Clobber endbr64 instructions now that altcall has finished optimising
- * all indirect branches to direct ones.
- */
- if ( force && system_state < SYS_STATE_active )
- seal_endbr64();
-
return 0;
}
rc = apply_alt_calls(__alt_call_sites_start, __alt_call_sites_end);
if ( rc )
panic("Unable to apply alternative calls: %d\n", rc);
+
+ seal_endbr64();
}
/*
#ifndef X86_ALTERNATIVE_CALL_H
#define X86_ALTERNATIVE_CALL_H
-#include <asm/alternative.h>
+#include <xen/macros.h>
+#include <xen/stdint.h>
/* Simply the relative position of the source call. */
struct alt_call {
rettype ret_; \
register unsigned long r10_ asm("r10"); \
register unsigned long r11_ asm("r11"); \
- asm volatile (ALTERNATIVE("call *%c[addr](%%rip)", "call .", \
- X86_FEATURE_ALWAYS) \
+ asm volatile ("1: call *%c[addr](%%rip)\n\t" \
+ ".pushsection .alt_call_sites, \"a\", @progbits\n\t" \
+ ".long 1b - .\n\t" \
+ ".popsection" \
: ALT_CALL ## n ## _OUT, "=a" (ret_), \
"=r" (r10_), "=r" (r11_) ASM_CALL_CONSTRAINT \
: [addr] "i" (&(func)), "g" (func) \