Hey Jonathan,

Thanks for trying out the release candidate and tracking down this problem.

On 3/28/07, Jonathan Lim <[EMAIL PROTECTED]> wrote:
In kexec-tools-1.101/kexec/arch/ia64/crashdump-ia64.c,
prepare_crash_memory_elf64_headers() has the following:

  p_vaddr = mstart + LOAD_OFFSET

where

  LOAD_OFFSET = 0xa000000000000000UL + 0x100000000UL - kernel_code_start

and mstart <= kernel_code_start, with kernel_code_start assigned to the
physical address of the kernel code region as read from /proc/iomem.

                    ----------------------------------------

However, in kexec-tools-testing/kexec/arch/ia64/crashdump-ia64.c where
load_crashdump_segments() calls crash_create_elf64_headers(), p_vaddr is simply
set to LOAD_OFFSET.

This is my fault. When I introduced crashdump-elf.c I must have missed
porting over the mstart variable. Sorry about that.

I made the following change to kexec-tools-testing/kexec/crashdump-elf.c to get
past the read error:

161c161,168
<               phdr->p_vaddr   = info->kern_vaddr_start;
---
>               for (i = 0; i < ranges; i++) {
>                   unsigned long long mstart = range[i].start;
>                   unsigned long long mend = range[i].end;
>                   if (!mstart && !mend)
>                       continue;
>                   if (info->kern_paddr_start >= mstart &&
>                   info->kern_paddr_start < mend)
>                       phdr->p_vaddr = mstart + info->kern_vaddr_start;
>               }

Does this look right?

I think the idea looks good, but the file crashdump-elf.c is shared
between multiple architectures. So we should really try to avoid
breaking x86_64.

Can you please give some feedback on the attached patch? It applies on
top of kexec-tools-testing-20070319-rc.

Thanks!

/ magnus
--- 0001/kexec/arch/ia64/crashdump-ia64.c
+++ work/kexec/arch/ia64/crashdump-ia64.c	2007-03-28 13:05:21.000000000 +0900
@@ -224,7 +224,7 @@ int load_crashdump_segments(struct kexec
 		if (get_crash_memory_ranges(&mem_range, &nr_ranges) == 0) {
 
 			info->kern_paddr_start = kernel_code_start;
-			info->kern_vaddr_start = LOAD_OFFSET;
+			info->kern_vaddr_offset = LOAD_OFFSET;
 			info->kern_size = kernel_code_end - kernel_code_start + 1;
 			if (crash_create_elf64_headers(info, &elf_info,
 						       crash_memory_range,
--- 0001/kexec/crashdump-elf.c
+++ work/kexec/crashdump-elf.c	2007-03-28 13:19:39.000000000 +0900
@@ -158,7 +158,36 @@ int FUNC(struct kexec_info *info,
 		phdr->p_type	= PT_LOAD;
 		phdr->p_flags	= PF_R|PF_W|PF_X;
 		phdr->p_offset	= phdr->p_paddr = info->kern_paddr_start;
-		phdr->p_vaddr	= info->kern_vaddr_start;
+
+		/*
+		 * Kernel regions with fixed vaddr should use kern_vaddr_start,
+		 * regions where vaddr depends on the physical adresses of 
+		 * ranges should use kern_vaddr_offset (IA64).
+		 *
+		 * In the future it may be possible to replace the arch-
+		 * specific program header parsing code in crashdump-x86_64.c
+		 * get_kernel_vaddr_and_size() with this code as well.
+		 */
+
+		if (info->kern_vaddr_offset) {
+			for (i = 0; i < ranges; i++) {
+				unsigned long long mstart = range[i].start;
+				unsigned long long mend = range[i].end;
+
+				if (!mstart && !mend)
+					continue;
+
+				if (info->kern_paddr_start < mstart ||
+				    info->kern_paddr_start >= mend)
+					continue;
+
+				phdr->p_vaddr = mstart;
+				phdr->p_vaddr += info->kern_vaddr_offset;
+			}
+		}
+		else
+			phdr->p_vaddr	= info->kern_vaddr_start;
+
 		phdr->p_filesz	= phdr->p_memsz	= info->kern_size;
 		phdr->p_align	= 0;
 		(elf->e_phnum)++;
--- 0001/kexec/kexec.h
+++ work/kexec/kexec.h	2007-03-28 12:59:49.000000000 +0900
@@ -119,6 +119,7 @@ struct kexec_info {
 	unsigned long backup_start;
 	unsigned long kexec_flags;
 	unsigned long kern_vaddr_start;
+	unsigned long kern_vaddr_offset;
 	unsigned long kern_paddr_start;
 	unsigned long kern_size;
 };
_______________________________________________
fastboot mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/fastboot

Reply via email to