From 94afdd9f7ab2b07997f80a297741842f9cdbdc25 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Tue, 4 Mar 2008 12:13:49 +0900 Subject: kexec-tools: [ia64] redivide efi memory in purgatory From my observations the way that the EFI_LOAD_DATA is provided on the inital boot works like this: There is a large EFI_CONVENTIONAL_MEMORY region. The portion begining at the first load segment of the image to be loading and ending with the last segment, aligned to 64K, is turned into a separate region of type EFI_LOAD_DATA. A truncated example of this: ... mem04: type= 7, attr=0x0000000000000008, range=[0x0000000000100000-0x0000000004000000) ( 63MB) mem05: type= 2, attr=0x0000000000000008, range=[0x0000000004000000-0x000000000481f000) ( 8MB) mem06: type= 7, attr=0x0000000000000008, range=[0x000000000481f000-0x000000003e876000) ( 928MB) ... Where type 7 is EFI_CONVENTIONAL_MEMORY and type 3 is EFI_LOAD_DATA. There is a patch to the user-space portion of kexec-tools that merges the segments supplied to this code if they are adjacent. This seems to always result in a single segment being passed to this code, that should start at the same address as the existing EFI_LOAD_DATA segment. So all that should be left to do is to merge the existing EFI_LOAD_DATA region with the following EFI_CONVENTIONAL_MEMORY region, and then split it up to accommodate the segment passed from user-space. The new EFI_LOAD_DATA region created with this code will always start at the same address as the old EFI_LOAD_DATA region. If this proves to be overly simplistic it should be easy to update. This code also allows merging of multiple regions to accommodate the new EFI_LOAD_DATA region. I strongly doubt this will ever be used, but it is in line with the way the existing code works. If the same image is used after kexec, then the EFI regions in question will turn out the same as the original regions. This is important, otherwise kernel / hypervisor regions will not be able to be inserted into /proc/iomem / /proc/iomem_machine. Signed-off-by: Simon Horman --- purgatory/arch/ia64/purgatory-ia64.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/purgatory/arch/ia64/purgatory-ia64.c b/purgatory/arch/ia64/purgatory-ia64.c index 275f9f5..b2fe6d4 100644 --- a/purgatory/arch/ia64/purgatory-ia64.c +++ b/purgatory/arch/ia64/purgatory-ia64.c @@ -190,6 +190,22 @@ patch_efi_memmap(struct kexec_boot_params *params, mend = src_md->phys_addr + (src_md->num_pages << EFI_PAGE_SHIFT); } + if (seg->end < mend && src < src_end) { + void *src_next; + efi_memory_desc_t *src_next_md; + src_next = src + boot_param->efi_memdesc_size; + src_next_md = src_next; + if (src_next_md->type == + EFI_CONVENTIONAL_MEMORY) { + /* TODO check contig and attribute */ + src += boot_param->efi_memdesc_size; + src_md = src; + mend = src_md->phys_addr + + (src_md->num_pages << + EFI_PAGE_SHIFT); + } + + } start_pages = (seg->start - mstart) >> EFI_PAGE_SHIFT; mid_pages = (seg->end - seg->start) >> EFI_PAGE_SHIFT; end_pages = (mend - seg->end) >> EFI_PAGE_SHIFT; -- cgit