Re: Overlapping reserved regions at boot

From: Petr Tesarik
Date: Wed Dec 07 2011 - 09:22:34 EST


Dne Út 29. listopadu 2011 15:01:51 Petr Tesarik napsal(a):
> Hello,
>
> while working on the upcoming SLES11 SP2, I ran into an issue with booting
> the panic kernel on a kernel crash. In the first iteration I found out
> that the initial register backing store gets overwritten with zeroes,
> causing a kernel crash shortly afterwards.
>
> Further investigation revealed that rsvd_region[] contains overlapping
> entries: find_memmap_space() returns a pointer which lies between
> KERNEL_START and _end. This is correct with the EFI memmap as patched by
> the kexec purgatory code. That code removes vmlinux LOAD segments from the
> usable map, but there is a pretty large hole between the gate section and
> the per-cpu section.
>
> With the following patch, the panic kernel can boot and save the crash
> dump.

OK guys, I take it that nobody is interested in ia64 any longer, but assuming
that there will probably be no other fix to the issue, can you at least
confirm that the fix is acceptable?

TIA,
Petr Tesarik

> Signed-off-by: Petr Tesarik <ptesarik@xxxxxxx>
>
> --- a/arch/ia64/kernel/setup.c
> +++ b/arch/ia64/kernel/setup.c
> @@ -225,6 +225,23 @@
> }
> }
>
> +/* merge overlaps */
> +static int __init
> +merge_regions (struct rsvd_region *rsvd_region, int max)
> +{
> + int i;
> + for (i = 1; i < max; ++i) {
> + if (rsvd_region[i].start >= rsvd_region[i-1].end)
> + continue;
> + if (rsvd_region[i].end > rsvd_region[i-1].end)
> + rsvd_region[i-1].end = rsvd_region[i].end;
> + --max;
> + memmove(&rsvd_region[i], &rsvd_region[i+1],
> + (max - i) * sizeof(struct rsvd_region));
> + }
> + return max;
> +}
> +
> /*
> * Request address space for all standard resources
> */
> @@ -275,6 +292,7 @@
> if (ret == 0 && size > 0) {
> if (!base) {
> sort_regions(rsvd_region, *n);
> + *n = merge_regions(rsvd_region, *n);
> base = kdump_find_rsvd_region(size,
> rsvd_region, *n);
> }
> @@ -392,6 +410,7 @@
> BUG_ON(IA64_MAX_RSVD_REGIONS + 1 < n);
>
> sort_regions(rsvd_region, num_rsvd_regions);
> + num_rsvd_regions = merge_regions(rsvd_region, num_rsvd_regions);
> }
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/