mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86/fsgsbase: Improve code generation in read_registers()
It turns out that using the higher level helpers adjacent like this leads to terrible code generation. Due to -fno-strict-aliasing, the store into state invalidates the read_cr4() address calculation (which is really cpu_info->cr4 under the hood), meaning that it can't be hoisted. As a result we get "locate the top of stack block, get cr4, and see if FSGSBASE is set" repeated 3 times, and an unreasonable number of basic blocks. Hoist the calculation manually, which results in two basic blocks. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
6b448a92a3
commit
42a0709f37
1 file changed
+18
-3
+18
-3
@@ -118,9 +118,24 @@ static void read_registers(struct extra_state *state)
|
||||
state->cr3 = read_cr3();
|
||||
state->cr4 = read_cr4();
|
||||
|
||||
state->fsb = read_fs_base();
|
||||
state->gsb = read_gs_base();
|
||||
state->gss = read_gs_shadow();
|
||||
/*
|
||||
* Help the optimiser out by opencoding read_*_base() and rearranging the
|
||||
* expression. -fno-strict-aliasing causes the store into state to
|
||||
* invalidate the read_cr4() address calculation (really cpu_info->cr4
|
||||
* under the hood), forcing the cr4 check to be re-evaluated every time.
|
||||
*/
|
||||
if ( state->cr4 & X86_CR4_FSGSBASE )
|
||||
{
|
||||
state->fsb = __rdfsbase();
|
||||
state->gsb = __rdgsbase();
|
||||
state->gss = __rdgs_shadow();
|
||||
}
|
||||
else
|
||||
{
|
||||
state->fsb = rdmsr(MSR_FS_BASE);
|
||||
state->gsb = rdmsr(MSR_GS_BASE);
|
||||
state->gss = rdmsr(MSR_SHADOW_GS_BASE);
|
||||
}
|
||||
|
||||
asm ( "mov %%ds, %0" : "=m" (state->ds) );
|
||||
asm ( "mov %%es, %0" : "=m" (state->es) );
|
||||
|
||||