mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86/fsgsbase: Make SHADOW_GS accesses safe under FRED
Under FRED, the SWAPGS instruction is disallowed. Therefore we must use the
MSR path instead.
read_registers() is in the show_registers() path, so this change allows Xen to
render it's current state without suffering #UD (and recursing until the stack
guard page is hit).
All hardware with FRED is expected to have some kind of non-serialising access
to these registers.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
(cherry picked from commit 3ff1030ea7)
This commit is contained in:
1 parent
b7572954da
commit
1fd19a1bc5
2 files changed
+7
-3
No files matched your search
@@ -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);
|
||||
|
||||
@@ -124,7 +124,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();
|
||||
|
||||