[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen staging] x86/fsgsbase: Improve code generation in read_registers()



commit 42a0709f374966573851236589583c86b603e704
Author:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Tue Aug 12 12:48:06 2025 +0100
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Fri Dec 5 23:00:32 2025 +0000

    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@xxxxxxxxxx>
    Acked-by: Jan Beulich <jbeulich@xxxxxxxx>
---
 xen/arch/x86/traps.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 0c5393cb21..505cae4d26 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -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) );
--
generated by git-patchbot for /home/xen/git/xen.git#staging



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.