|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] x86/domctl: Stop using XLAT_cpu_user_regs()
commit 9f892f84c27970840d255aef7e2851b762967de7
Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Mon Dec 30 11:49:14 2024 +0000
Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Fri Aug 8 13:23:11 2025 +0100
x86/domctl: Stop using XLAT_cpu_user_regs()
In order to support FRED, we're going to have to remove the {ds..gs} fields
from struct cpu_user_regs, meaning that it is going to have to become a
different type to the structure embedded in vcpu_guest_context_u.
In both arch_{get,set}_info_guest(), expand the
memcpy()/XLAT_cpu_user_regs()
to copy the fields individually. This will allow us to eventually make them
different types.
This does cause some minor changes in behaviour for the hypercalls.
It is specifically not the case that a toolstack could set_info();
get_info();
and get an identical bit pattern back. Amongst other things, the
architectural sticky bits in registers are applied during setting.
Previously, XLAT_cpu_user_regs() omitted the _pad fields in the compat case
whereas the non-compat case included them owing to the single memcpy().
Omit the _pad fields in the non-compat case too; for all but the oldest of
CPUs, the segment selectors are zero-extended by hardware when pushed onto
the
stack, so non-zero values here get lost naturally. Furthermore, FRED reuses
the space above cs and ss for extra state, and a PV guest for now at least
must not be able to write the control state.
Omit the error_code and entry_vector fields too. They're already identified
as private fields in the public API, and are stale outside of Xen's
interrupt/exception/syscall handler. They're also a very minor information
leak of which event caused the last deschedule of a vCPU.
Finally, omit saved_upcall_mask. Xen doesn't consume this, and only
produces
it in {compat_,}create_bounce_frame(), based on the vcpu_info shared state
and
settings about the event being injected. Similar to
error_code/entry_vector,
it is stale outside of the guest's event handler.
No change that toolstacks or guests are expected to notice or care about.
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
---
xen/arch/x86/domain.c | 38 ++++++++++++++++++++++++++++++++++++--
xen/arch/x86/domctl.c | 38 ++++++++++++++++++++++++++++++++++++--
xen/include/xlat.lst | 2 --
3 files changed, 72 insertions(+), 6 deletions(-)
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 56c3816187..41d75dde42 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -1231,9 +1231,27 @@ int arch_set_info_guest(
else
vcpu_reset_fpu(v);
+ memset(&v->arch.user_regs, 0, sizeof(v->arch.user_regs));
+
if ( !compat )
{
- memcpy(&v->arch.user_regs, &c.nat->user_regs,
sizeof(c.nat->user_regs));
+ v->arch.user_regs.rbx = c.nat->user_regs.rbx;
+ v->arch.user_regs.rcx = c.nat->user_regs.rcx;
+ v->arch.user_regs.rdx = c.nat->user_regs.rdx;
+ v->arch.user_regs.rsi = c.nat->user_regs.rsi;
+ v->arch.user_regs.rdi = c.nat->user_regs.rdi;
+ v->arch.user_regs.rbp = c.nat->user_regs.rbp;
+ v->arch.user_regs.rax = c.nat->user_regs.rax;
+ v->arch.user_regs.rip = c.nat->user_regs.rip;
+ v->arch.user_regs.cs = c.nat->user_regs.cs;
+ v->arch.user_regs.rflags = c.nat->user_regs.rflags;
+ v->arch.user_regs.rsp = c.nat->user_regs.rsp;
+ v->arch.user_regs.ss = c.nat->user_regs.ss;
+ v->arch.user_regs.es = c.nat->user_regs.es;
+ v->arch.user_regs.ds = c.nat->user_regs.ds;
+ v->arch.user_regs.fs = c.nat->user_regs.fs;
+ v->arch.user_regs.gs = c.nat->user_regs.gs;
+
if ( is_pv_domain(d) )
memcpy(v->arch.pv.trap_ctxt, c.nat->trap_ctxt,
sizeof(c.nat->trap_ctxt));
@@ -1241,7 +1259,23 @@ int arch_set_info_guest(
#ifdef CONFIG_COMPAT
else
{
- XLAT_cpu_user_regs(&v->arch.user_regs, &c.cmp->user_regs);
+ v->arch.user_regs.ebx = c.cmp->user_regs.ebx;
+ v->arch.user_regs.ecx = c.cmp->user_regs.ecx;
+ v->arch.user_regs.edx = c.cmp->user_regs.edx;
+ v->arch.user_regs.esi = c.cmp->user_regs.esi;
+ v->arch.user_regs.edi = c.cmp->user_regs.edi;
+ v->arch.user_regs.ebp = c.cmp->user_regs.ebp;
+ v->arch.user_regs.eax = c.cmp->user_regs.eax;
+ v->arch.user_regs.eip = c.cmp->user_regs.eip;
+ v->arch.user_regs.cs = c.cmp->user_regs.cs;
+ v->arch.user_regs.eflags = c.cmp->user_regs.eflags;
+ v->arch.user_regs.esp = c.cmp->user_regs.esp;
+ v->arch.user_regs.ss = c.cmp->user_regs.ss;
+ v->arch.user_regs.es = c.cmp->user_regs.es;
+ v->arch.user_regs.ds = c.cmp->user_regs.ds;
+ v->arch.user_regs.fs = c.cmp->user_regs.fs;
+ v->arch.user_regs.gs = c.cmp->user_regs.gs;
+
if ( is_pv_domain(d) )
{
for ( i = 0; i < ARRAY_SIZE(c.cmp->trap_ctxt); ++i )
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index 3044f706de..28fec0e12d 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -1399,7 +1399,24 @@ void arch_get_info_guest(struct vcpu *v,
vcpu_guest_context_u c)
c(flags |= VGCF_online);
if ( !compat )
{
- memcpy(&c.nat->user_regs, &v->arch.user_regs,
sizeof(c.nat->user_regs));
+ /* Backing memory is pre-zeroed. */
+ c.nat->user_regs.rbx = v->arch.user_regs.rbx;
+ c.nat->user_regs.rcx = v->arch.user_regs.rcx;
+ c.nat->user_regs.rdx = v->arch.user_regs.rdx;
+ c.nat->user_regs.rsi = v->arch.user_regs.rsi;
+ c.nat->user_regs.rdi = v->arch.user_regs.rdi;
+ c.nat->user_regs.rbp = v->arch.user_regs.rbp;
+ c.nat->user_regs.rax = v->arch.user_regs.rax;
+ c.nat->user_regs.rip = v->arch.user_regs.rip;
+ c.nat->user_regs.cs = v->arch.user_regs.cs;
+ c.nat->user_regs.rflags = v->arch.user_regs.rflags;
+ c.nat->user_regs.rsp = v->arch.user_regs.rsp;
+ c.nat->user_regs.ss = v->arch.user_regs.ss;
+ c.nat->user_regs.es = v->arch.user_regs.es;
+ c.nat->user_regs.ds = v->arch.user_regs.ds;
+ c.nat->user_regs.fs = v->arch.user_regs.fs;
+ c.nat->user_regs.gs = v->arch.user_regs.gs;
+
if ( is_pv_domain(d) )
memcpy(c.nat->trap_ctxt, v->arch.pv.trap_ctxt,
sizeof(c.nat->trap_ctxt));
@@ -1407,7 +1424,24 @@ void arch_get_info_guest(struct vcpu *v,
vcpu_guest_context_u c)
#ifdef CONFIG_COMPAT
else
{
- XLAT_cpu_user_regs(&c.cmp->user_regs, &v->arch.user_regs);
+ /* Backing memory is pre-zeroed. */
+ c.cmp->user_regs.ebx = v->arch.user_regs.ebx;
+ c.cmp->user_regs.ecx = v->arch.user_regs.ecx;
+ c.cmp->user_regs.edx = v->arch.user_regs.edx;
+ c.cmp->user_regs.esi = v->arch.user_regs.esi;
+ c.cmp->user_regs.edi = v->arch.user_regs.edi;
+ c.cmp->user_regs.ebp = v->arch.user_regs.ebp;
+ c.cmp->user_regs.eax = v->arch.user_regs.eax;
+ c.cmp->user_regs.eip = v->arch.user_regs.eip;
+ c.cmp->user_regs.cs = v->arch.user_regs.cs;
+ c.cmp->user_regs.eflags = v->arch.user_regs.eflags;
+ c.cmp->user_regs.esp = v->arch.user_regs.esp;
+ c.cmp->user_regs.ss = v->arch.user_regs.ss;
+ c.cmp->user_regs.es = v->arch.user_regs.es;
+ c.cmp->user_regs.ds = v->arch.user_regs.ds;
+ c.cmp->user_regs.fs = v->arch.user_regs.fs;
+ c.cmp->user_regs.gs = v->arch.user_regs.gs;
+
if ( is_pv_domain(d) )
{
for ( i = 0; i < ARRAY_SIZE(c.cmp->trap_ctxt); ++i )
diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst
index 3c7b6c6830..6d6c6cfab2 100644
--- a/xen/include/xlat.lst
+++ b/xen/include/xlat.lst
@@ -34,8 +34,6 @@
? pmu_intel_ctxt arch-x86/pmu.h
? pmu_regs arch-x86/pmu.h
-! cpu_user_regs arch-x86/xen-@arch@.h
-
? cpu_offline_action arch-x86/xen-mca.h
? mc arch-x86/xen-mca.h
! mc_fetch arch-x86/xen-mca.h
--
generated by git-patchbot for /home/xen/git/xen.git#master
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |