mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
xen/dom0: Fix latent dom0 construction bugs on all architectures
* x86 PV and ARM dom0's must not clear _VPF_down from v->pause_flags until all state is actually set up. As it currently stands, d0v0 is eligible for scheduling before its registers have been set. This is latent as we also hold a systemcontroller pause reference at the time which prevents d0 from being scheduled. * x86 PVH previously was not setting v->is_initialised for d0v0, despite setting the vcpu running eventually. Therefore, a later VCPUOP_initialise hypercall will modify state under the feet of the running vcpu. This is latent as PVH dom0 construction don't yet function. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> Reviewed-by: Roger Pau Monné <roger.pau@citrix.com> Release-acked-by: Julien Grall <julien.grall@linaro.org>
This commit is contained in:
1 parent
24fb44e971
commit
0075bc1f02
4 files changed
+18
-8
No files matched your search
@@ -2197,9 +2197,6 @@ int construct_dom0(struct domain *d)
|
||||
|
||||
discard_initial_modules();
|
||||
|
||||
v->is_initialised = 1;
|
||||
clear_bit(_VPF_down, &v->pause_flags);
|
||||
|
||||
memset(regs, 0, sizeof(*regs));
|
||||
|
||||
regs->pc = (register_t)kinfo.entry;
|
||||
@@ -2247,6 +2244,9 @@ int construct_dom0(struct domain *d)
|
||||
vcpu_switch_to_aarch64_mode(d->vcpu[i]);
|
||||
}
|
||||
|
||||
v->is_initialised = 1;
|
||||
clear_bit(_VPF_down, &v->pause_flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -466,6 +466,8 @@ int __init construct_dom0(struct domain *d, const module_t *image,
|
||||
void *(*bootstrap_map)(const module_t *),
|
||||
char *cmdline)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* Sanity! */
|
||||
BUG_ON(d->domain_id != 0);
|
||||
BUG_ON(d->vcpu[0] == NULL);
|
||||
@@ -481,8 +483,15 @@ int __init construct_dom0(struct domain *d, const module_t *image,
|
||||
}
|
||||
#endif
|
||||
|
||||
return (is_hvm_domain(d) ? dom0_construct_pvh : dom0_construct_pv)
|
||||
(d, image, image_headroom, initrd,bootstrap_map, cmdline);
|
||||
rc = (is_hvm_domain(d) ? dom0_construct_pvh : dom0_construct_pv)
|
||||
(d, image, image_headroom, initrd, bootstrap_map, cmdline);
|
||||
if ( rc )
|
||||
return rc;
|
||||
|
||||
/* Sanity! */
|
||||
BUG_ON(!d->vcpu[0]->is_initialised);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -614,6 +614,7 @@ static int __init pvh_setup_cpus(struct domain *d, paddr_t entry,
|
||||
|
||||
update_domain_wallclock_time(d);
|
||||
|
||||
v->is_initialised = 1;
|
||||
clear_bit(_VPF_down, &v->pause_flags);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -847,9 +847,6 @@ int __init dom0_construct_pv(struct domain *d,
|
||||
|
||||
update_domain_wallclock_time(d);
|
||||
|
||||
v->is_initialised = 1;
|
||||
clear_bit(_VPF_down, &v->pause_flags);
|
||||
|
||||
/*
|
||||
* Initial register values:
|
||||
* DS,ES,FS,GS = FLAT_KERNEL_DS
|
||||
@@ -883,6 +880,9 @@ int __init dom0_construct_pv(struct domain *d,
|
||||
if ( d->domain_id == hardware_domid )
|
||||
iommu_hwdom_init(d);
|
||||
|
||||
v->is_initialised = 1;
|
||||
clear_bit(_VPF_down, &v->pause_flags);
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
|
||||