x86/emul: Remove fallback path from SWAPGS

In real hardware, accesses to the registers cannot fail.  The error paths are
just an artefact of the hook functions needing to return something.

The best effort unwind is also something that doesn't exist in real hardware,
and makes the logic more complicated to follow.  Instead, use an
ASSERT_UNREACHABLE() with a fallback of injecting #DF.  Hitting this path is
an error in Xen.

While adjusting, remove {read,write}_segment() and use {read,write}_msr() to
access MSR_GS_BASE.  There's no need to access the other parts of the GS
segment, and this is less work behind the scenes.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Andrew Cooper committed 2026-04-07 16:26:34 +01:00
1 parent 3bcce461a3
commit 4bedbe47ee
1 file changed
+15 -13
+15 -13
View File
@@ -189,22 +189,24 @@ int x86emul_0f01(struct x86_emulate_state *s,
generate_exception_if(!mode_ring0(), X86_EXC_GP, 0); generate_exception_if(!mode_ring0(), X86_EXC_GP, 0);
fail_if(!ops->read_segment || !ops->read_msr || fail_if(!ops->read_segment || !ops->read_msr ||
!ops->write_segment || !ops->write_msr); !ops->write_segment || !ops->write_msr);
if ( (rc = ops->read_segment(x86_seg_gs, &sreg, if ( (rc = ops->read_msr(MSR_GS_BASE, &sreg.base,
ctxt)) != X86EMUL_OKAY ||
(rc = ops->read_msr(MSR_SHADOW_GS_BASE, &msr_val,
ctxt)) != X86EMUL_OKAY || ctxt)) != X86EMUL_OKAY ||
(rc = ops->write_msr(MSR_SHADOW_GS_BASE, sreg.base, (rc = ops->read_msr(MSR_SHADOW_GS_BASE, &msr_val,
ctxt)) != X86EMUL_OKAY )
goto done;
if ( (rc = ops->write_msr(MSR_SHADOW_GS_BASE, sreg.base,
ctxt, false)) != X86EMUL_OKAY ||
(rc = ops->write_msr(MSR_GS_BASE, msr_val,
ctxt, false)) != X86EMUL_OKAY ) ctxt, false)) != X86EMUL_OKAY )
goto done;
sreg.base = msr_val;
if ( (rc = ops->write_segment(x86_seg_gs, &sreg,
ctxt)) != X86EMUL_OKAY )
{ {
/* Best effort unwind (i.e. no real error checking). */ /*
if ( ops->write_msr(MSR_SHADOW_GS_BASE, msr_val, * In real hardware, access to the registers cannot fail. It is
ctxt, false) == X86EMUL_EXCEPTION ) * an error in Xen if the writes fail given that both MSRs have
x86_emul_reset_event(ctxt); * equivalent checks.
goto done; */
ASSERT_UNREACHABLE();
x86_emul_reset_event(ctxt);
generate_exception(X86_EXC_DF, 0);
} }
break; break;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.