diff --git a/xen/arch/x86/include/asm/fsgsbase.h b/xen/arch/x86/include/asm/fsgsbase.h index 24862a6bfe..5faa3a3243 100644 --- a/xen/arch/x86/include/asm/fsgsbase.h +++ b/xen/arch/x86/include/asm/fsgsbase.h @@ -79,7 +79,9 @@ static inline unsigned long read_gs_base(void) static inline unsigned long read_gs_shadow(void) { - if ( read_cr4() & X86_CR4_FSGSBASE ) + unsigned long cr4 = read_cr4(); + + if ( !(cr4 & X86_CR4_FRED) && (cr4 & X86_CR4_FSGSBASE) ) return __rdgs_shadow(); else return rdmsr(MSR_SHADOW_GS_BASE); @@ -103,7 +105,9 @@ static inline void write_gs_base(unsigned long base) static inline void write_gs_shadow(unsigned long base) { - if ( read_cr4() & X86_CR4_FSGSBASE ) + unsigned long cr4 = read_cr4(); + + if ( !(cr4 & X86_CR4_FRED) && (cr4 & X86_CR4_FSGSBASE) ) __wrgs_shadow(base); else wrmsrns(MSR_SHADOW_GS_BASE, base); diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index f621b99a5f..3c01c5eb53 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -123,7 +123,7 @@ static void read_registers(struct extra_state *state) * 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 ) + if ( !(state->cr4 & X86_CR4_FRED) && (state->cr4 & X86_CR4_FSGSBASE) ) { state->fsb = __rdfsbase(); state->gsb = __rdgsbase();