mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86/hvm: No need to arch_set_info_guest() before restoring per-vcpu HVM state.
Signed-off-by: Keir Fraser <keir@xen.org>
This commit is contained in:
1 parent
acbae3dcf6
commit
9346f6cfbf
5 files changed
+26
-50
No files matched your search
+19
-28
@@ -709,13 +709,7 @@ CHECK_FIELD_(struct, vcpu_guest_context, fpu_ctxt);
|
||||
#undef xen_vcpu_guest_context
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is called by do_domctl(XEN_DOMCTL_setvcpucontext, ...), boot_vcpu(),
|
||||
* and hvm_load_cpu_ctxt().
|
||||
*
|
||||
* Note that for a HVM guest NULL may be passed for the context pointer,
|
||||
* meaning "use current values".
|
||||
*/
|
||||
/* Called by XEN_DOMCTL_setvcpucontext and VCPUOP_initialise. */
|
||||
int arch_set_info_guest(
|
||||
struct vcpu *v, vcpu_guest_context_u c)
|
||||
{
|
||||
@@ -735,7 +729,7 @@ int arch_set_info_guest(
|
||||
#else
|
||||
#define c(fld) (c.nat->fld)
|
||||
#endif
|
||||
flags = c.nat ? c(flags) : v->arch.vgc_flags;
|
||||
flags = c(flags);
|
||||
|
||||
if ( !is_hvm_vcpu(v) )
|
||||
{
|
||||
@@ -791,28 +785,25 @@ int arch_set_info_guest(
|
||||
|
||||
v->arch.vgc_flags = flags;
|
||||
|
||||
if ( c.nat )
|
||||
memcpy(v->arch.fpu_ctxt, &c.nat->fpu_ctxt, sizeof(c.nat->fpu_ctxt));
|
||||
if ( !compat )
|
||||
{
|
||||
memcpy(v->arch.fpu_ctxt, &c.nat->fpu_ctxt, sizeof(c.nat->fpu_ctxt));
|
||||
if ( !compat )
|
||||
{
|
||||
memcpy(&v->arch.user_regs, &c.nat->user_regs, sizeof(c.nat->user_regs));
|
||||
if ( !is_hvm_vcpu(v) )
|
||||
memcpy(v->arch.pv_vcpu.trap_ctxt, c.nat->trap_ctxt,
|
||||
sizeof(c.nat->trap_ctxt));
|
||||
}
|
||||
#ifdef CONFIG_COMPAT
|
||||
else
|
||||
{
|
||||
XLAT_cpu_user_regs(&v->arch.user_regs, &c.cmp->user_regs);
|
||||
for ( i = 0; i < ARRAY_SIZE(c.cmp->trap_ctxt); ++i )
|
||||
XLAT_trap_info(v->arch.pv_vcpu.trap_ctxt + i,
|
||||
c.cmp->trap_ctxt + i);
|
||||
}
|
||||
#endif
|
||||
for ( i = 0; i < ARRAY_SIZE(v->arch.debugreg); ++i )
|
||||
v->arch.debugreg[i] = c(debugreg[i]);
|
||||
memcpy(&v->arch.user_regs, &c.nat->user_regs, sizeof(c.nat->user_regs));
|
||||
if ( !is_hvm_vcpu(v) )
|
||||
memcpy(v->arch.pv_vcpu.trap_ctxt, c.nat->trap_ctxt,
|
||||
sizeof(c.nat->trap_ctxt));
|
||||
}
|
||||
#ifdef CONFIG_COMPAT
|
||||
else
|
||||
{
|
||||
XLAT_cpu_user_regs(&v->arch.user_regs, &c.cmp->user_regs);
|
||||
for ( i = 0; i < ARRAY_SIZE(c.cmp->trap_ctxt); ++i )
|
||||
XLAT_trap_info(v->arch.pv_vcpu.trap_ctxt + i,
|
||||
c.cmp->trap_ctxt + i);
|
||||
}
|
||||
#endif
|
||||
for ( i = 0; i < ARRAY_SIZE(v->arch.debugreg); ++i )
|
||||
v->arch.debugreg[i] = c(debugreg[i]);
|
||||
|
||||
v->arch.user_regs.eflags |= 2;
|
||||
|
||||
|
||||
@@ -670,7 +670,7 @@ static bool_t hvm_efer_valid(struct domain *d,
|
||||
|
||||
static int hvm_load_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
|
||||
{
|
||||
int vcpuid, rc;
|
||||
int vcpuid;
|
||||
struct vcpu *v;
|
||||
struct hvm_hw_cpu ctxt;
|
||||
struct segment_register seg;
|
||||
@@ -684,11 +684,6 @@ static int hvm_load_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Need to init this vcpu before loading its contents */
|
||||
rc = boot_vcpu(d, vcpuid, NULL);
|
||||
if ( (rc != 0) && (rc != -EEXIST) )
|
||||
return rc;
|
||||
|
||||
if ( hvm_load_entry(CPU, h, &ctxt) != 0 )
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -46,7 +46,9 @@ int compat_vcpu_op(int cmd, int vcpuid, XEN_GUEST_HANDLE(void) arg)
|
||||
break;
|
||||
}
|
||||
|
||||
rc = boot_vcpu(d, vcpuid, cmp_ctxt);
|
||||
domain_lock(d);
|
||||
rc = v->is_initialised ? -EEXIST : arch_set_info_guest(v, cmp_ctxt);
|
||||
domain_unlock(d);
|
||||
|
||||
xfree(cmp_ctxt);
|
||||
break;
|
||||
|
||||
+3
-13
@@ -778,18 +778,6 @@ void domain_unpause_by_systemcontroller(struct domain *d)
|
||||
domain_unpause(d);
|
||||
}
|
||||
|
||||
int boot_vcpu(struct domain *d, int vcpuid, vcpu_guest_context_u ctxt)
|
||||
{
|
||||
struct vcpu *v = d->vcpu[vcpuid];
|
||||
int rc;
|
||||
|
||||
domain_lock(d);
|
||||
rc = v->is_initialised ? -EEXIST : arch_set_info_guest(v, ctxt);
|
||||
domain_unlock(d);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void vcpu_reset(struct vcpu *v)
|
||||
{
|
||||
struct domain *d = v->domain;
|
||||
@@ -847,7 +835,9 @@ long do_vcpu_op(int cmd, int vcpuid, XEN_GUEST_HANDLE(void) arg)
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
rc = boot_vcpu(d, vcpuid, ctxt);
|
||||
domain_lock(d);
|
||||
rc = v->is_initialised ? -EEXIST : arch_set_info_guest(v, ctxt);
|
||||
domain_unlock(d);
|
||||
|
||||
free_vcpu_guest_context(ctxt);
|
||||
break;
|
||||
|
||||
@@ -12,8 +12,6 @@ typedef union {
|
||||
|
||||
struct vcpu *alloc_vcpu(
|
||||
struct domain *d, unsigned int vcpu_id, unsigned int cpu_id);
|
||||
int boot_vcpu(
|
||||
struct domain *d, int vcpuid, vcpu_guest_context_u ctxt);
|
||||
struct vcpu *alloc_dom0_vcpu0(void);
|
||||
void vcpu_reset(struct vcpu *v);
|
||||
|
||||
|
||||