diff options
author | Simon Horman <horms@verge.net.au> | 2008-03-04 12:13:45 +0900 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2008-03-04 12:13:45 +0900 |
commit | b1d9ab137fde1b5ab2b279ac739660e1789d8ced (patch) | |
tree | f94a21b9ef36cec295abbe15f051701e3e23218d | |
parent | 2b0088bb881680c5e8b062a9b0f0a6ef1b88d52c (diff) |
kexec-tools: [ia64] merge segments
A list of segments is passed into the kernel at kexec_load time
and these are subsequently passed to purgatory which uses
them to mangle the EFI memory table.
Each of these segments represents a PT_LOAD segment in the
elf image to be booted after purgatory. They are already
aligned 64k by this code,
The problem with the code as it stands is that it creates
a separate segment for each PT_LOAD segment. Which in the
end results in separate EFI memory regions for each
PT_LOAD segment. And when linux or xen goes to insert
its kernel/hypervisor regions into /proc/iomem
or /proc/iomem_mashine, they don't fit because those regions
actually span several of the new EFI regions created.
So it makes sense to merge these segments if they are adjacent
after alignment - which they always seem to be. This results
in one EFI region that can contain the relevent kernel/hypervisor
iomem region. Problem solved.
This merging could be done in purgatory. But its easier
and cleaner to do it here (IMHO).
The test for this code is to kexec a machine running kexec it
into linux and then inspect /proc/iomem to see of the kernel
code, text and bss regions are present. Without this fix,
they won't be. With it they should be.
This patch is part of the solution to the same problem for
the hypervisor, though it requires an additional change
to split the code from the heap as the later resides in
convential memory rather than the load segment created
by purgatory's mangling.
Signed-off-by: Simon Horman <horms@verge.net.au>
-rw-r--r-- | kexec/arch/ia64/crashdump-ia64.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/kexec/arch/ia64/crashdump-ia64.c b/kexec/arch/ia64/crashdump-ia64.c index 54747ac..338a6af 100644 --- a/kexec/arch/ia64/crashdump-ia64.c +++ b/kexec/arch/ia64/crashdump-ia64.c @@ -76,18 +76,29 @@ static void add_loaded_segments_info(struct kexec_info *info, { int i; for(i = 0; i < ehdr->e_phnum; i++) { - unsigned long start, end; struct mem_phdr *phdr; phdr = &ehdr->e_phdr[i]; if (phdr->p_type != PT_LOAD) continue; - start = phdr->p_paddr; - end = phdr->p_paddr + phdr->p_memsz; loaded_segments[loaded_segments_num].start = - start&~(ELF_PAGE_SIZE-1); + phdr->p_paddr & ~(ELF_PAGE_SIZE-1); loaded_segments[loaded_segments_num].end = - (end + ELF_PAGE_SIZE - 1)&~(ELF_PAGE_SIZE - 1); + loaded_segments[loaded_segments_num].start; + + while (i < ehdr->e_phnum) { + phdr = &ehdr->e_phdr[i]; + if (phdr->p_type != PT_LOAD) + break; + if (loaded_segments[loaded_segments_num].end != + phdr->p_paddr & ~(ELF_PAGE_SIZE-1)) + break; + loaded_segments[loaded_segments_num].end += + (phdr->p_memsz + ELF_PAGE_SIZE - 1) & + ~(ELF_PAGE_SIZE - 1); + i++; + } + loaded_segments_num++; } } |