xen/vcpu: Handle xen_vcpu_setup() failure in hotplug
The hypercall VCPUOP_register_vcpu_info can fail. This failure is handled by making per_cpu(xen_vcpu, cpu) point to its shared_info slot and those without one (cpu >= MAX_VIRT_CPUS) be NULL. For PVH/PVHVM, this is not enough, because we also need to pull these VCPUs out of circulation. Fix for PVH/PVHVM: on registration failure in the cpuhp prepare callback (xen_cpu_up_prepare_hvm()), return an error to the cpuhp state-machine so it can fail the CPU init. Fix for PV: the registration happens before smp_init(), so, in the failure case we clamp setup_max_cpus and limit the number of VCPUs that smp_init() will bring-up to MAX_VIRT_CPUS. This is functionally correct but it makes the code a bit simpler if we get rid of this explicit clamping: for VCPUs that don't have valid xen_vcpu, fail the CPU init in the cpuhp prepare callback (xen_cpu_up_prepare_pv()). Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> Signed-off-by: Ankur Arora <ankur.a.arora@oracle.com> Signed-off-by: Juergen Gross <jgross@suse.com>
This commit is contained in:

committed by
Juergen Gross

parent
0e4d583723
commit
c9b5d98b25
@@ -958,7 +958,16 @@ void __ref xen_setup_vcpu_info_placement(void)
|
||||
for_each_possible_cpu(cpu) {
|
||||
/* Set up direct vCPU id mapping for PV guests. */
|
||||
per_cpu(xen_vcpu_id, cpu) = cpu;
|
||||
xen_vcpu_setup(cpu);
|
||||
|
||||
/*
|
||||
* xen_vcpu_setup(cpu) can fail -- in which case it
|
||||
* falls back to the shared_info version for cpus
|
||||
* where xen_vcpu_nr(cpu) < MAX_VIRT_CPUS.
|
||||
*
|
||||
* xen_cpu_up_prepare_pv() handles the rest by failing
|
||||
* them in hotplug.
|
||||
*/
|
||||
(void) xen_vcpu_setup(cpu);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1432,6 +1441,9 @@ static int xen_cpu_up_prepare_pv(unsigned int cpu)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (per_cpu(xen_vcpu, cpu) == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
xen_setup_timer(cpu);
|
||||
|
||||
rc = xen_smp_intr_init(cpu);
|
||||
|
Reference in New Issue
Block a user