[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [linux-2.6.18-xen] kexec adjustments
# HG changeset patch # User Jan Beulich <jbeulich@xxxxxxxx> # Date 1323177913 -3600 # Node ID 1a0d68a3b3f99222a23a9e4b3d3c799cd8892033 # Parent da0850ab55d66d74a4a304484f9a1933919306bf kexec adjustments - fix error path after retrieving vmcoreinfo (must no directly return, special casing -EINVAL should only happen if absolutely needed) - improve detection of number of CPUs (utilize platform hypercall) - clean up in error path as far as possible (only after possibly having inserted some or all resources it would be problematic to free the allocated space) - leverage the fact that alloc_bootmem() already clears the memory Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> --- diff -r da0850ab55d6 -r 1a0d68a3b3f9 drivers/xen/core/machine_kexec.c --- a/drivers/xen/core/machine_kexec.c Tue Nov 22 09:17:12 2011 +0100 +++ b/drivers/xen/core/machine_kexec.c Tue Dec 06 14:25:13 2011 +0100 @@ -5,6 +5,7 @@ #include <linux/kexec.h> #include <xen/interface/kexec.h> +#include <xen/interface/platform.h> #include <linux/mm.h> #include <linux/bootmem.h> @@ -17,7 +18,7 @@ static int __initdata xen_max_nr_phys_cpus; static struct resource xen_hypervisor_res; -static struct resource *xen_phys_cpus; +static struct resource *__initdata xen_phys_cpus; size_t vmcoreinfo_size_xen; unsigned long paddr_vmcoreinfo_xen; @@ -25,16 +26,21 @@ void __init xen_machine_kexec_setup_resources(void) { xen_kexec_range_t range; + xen_platform_op_t op; struct resource *res; - int k = 0; + unsigned int k = 0, nr = 0; int rc; if (!is_initial_xendomain()) return; /* determine maximum number of physical cpus */ - - while (1) { + op.cmd = XENPF_get_cpuinfo; + op.u.pcpu_info.xen_cpuid = 0; + if (HYPERVISOR_platform_op(&op) == 0) + k = op.u.pcpu_info.max_present + 1; +#if CONFIG_XEN_COMPAT < 0x040000 + else while (1) { memset(&range, 0, sizeof(range)); range.range = KEXEC_RANGE_MA_CPU; range.nr = k; @@ -44,6 +50,7 @@ k++; } +#endif if (k == 0) return; @@ -62,25 +69,27 @@ range.range = KEXEC_RANGE_MA_CPU; range.nr = k; - if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range)) - goto err; + if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range) + || range.size == 0) + continue; - res = xen_phys_cpus + k; - - memset(res, 0, sizeof(*res)); + res = xen_phys_cpus + nr++; res->name = "Crash note"; res->start = range.start; res->end = range.start + range.size - 1; res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; } + if (nr == 0) + goto free; + /* fill in xen_hypervisor_res with hypervisor machine address range */ memset(&range, 0, sizeof(range)); range.range = KEXEC_RANGE_MA_XEN; if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range)) - goto err; + goto free; xen_hypervisor_res.name = "Hypervisor code and data"; xen_hypervisor_res.start = range.start; @@ -93,7 +102,7 @@ range.range = KEXEC_RANGE_MA_CRASH; if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range)) - goto err; + goto free; if (range.size) { crashk_res.start = range.start; @@ -118,28 +127,35 @@ vmcoreinfo_size_xen = 0; paddr_vmcoreinfo_xen = 0; +#if CONFIG_XEN_COMPAT < 0x030300 /* The KEXEC_CMD_kexec_get_range hypercall did not implement * KEXEC_RANGE_MA_VMCOREINFO until Xen 3.3. * Do not bail out if it fails for this reason. */ if (rc != -EINVAL) - return; +#endif + goto free; } if (machine_kexec_setup_resources(&xen_hypervisor_res, xen_phys_cpus, - xen_max_nr_phys_cpus)) + nr)) { + /* + * It's too cumbersome to properly free xen_phys_cpus here. + * Failure at this stage is unexpected and the amount of + * memory is small therefore we tolerate the potential leak. + */ goto err; + } + + xen_max_nr_phys_cpus = nr; return; + free: + free_bootmem(__pa(xen_phys_cpus), + xen_max_nr_phys_cpus * sizeof(*xen_phys_cpus)); err: - /* - * It isn't possible to free xen_phys_cpus this early in the - * boot. Failure at this stage is unexpected and the amount of - * memory is small therefore we tolerate the potential leak. - */ xen_max_nr_phys_cpus = 0; - return; } void __init xen_machine_kexec_register_resources(struct resource *res) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |