[PATCH 1/2] kexec: add phys_offset field

Mika Westerberg ext-mika.1.westerberg at nokia.com
Thu Apr 29 04:16:17 EDT 2010


On Wed, Apr 28, 2010 at 05:28:55PM +0200, ext Dave Anderson wrote:
> ----- "Mika Westerberg" <ext-mika.1.westerberg at nokia.com> wrote:
> > > But for x86, their is no concept of a mapped kernel region in addition
> > > to the unity-mapped region(s), as there is with x86_64 and ia64.  It's
> > > presumed that the primary kernel is based at physical adress 0, so when
> > > the PAGE_OFFSET is stripped off, you have the physical address.
> > 
> > With ARM we have (for the kernel direct mapped region):
> > 
> > 	paddr = vaddr - PAGE_OFFSET + PHYS_OFFSET
> > 
> > so it is related to PHYS_OFFSET.
> > 
> > Is there any (other) way of doing this so that we could get p_vaddr correct? I
> > checked makedumpfile but it seems not to handle p_vaddr at all so it probably
> > won't help if we run the dump through it.
> 
> When you say "we" do you mean ARM only?  

Yes :)

> All I'm saying is that things "just work" for the currently-supported 
> architectures.  The most recent sample x86 kdump vmcore I have looks like this:
> 
> Program Headers:
>   Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
>   NOTE           0x0000b4 0x00000000 0x00000000 0x00450 0x00450     0
>   LOAD           0x000504 0xc0000000 0x00000000 0xa0000 0xa0000 RWE 0
>   LOAD           0x0a0504 0xc0100000 0x00100000 0xf00000 0xf00000 RWE 0
>   LOAD           0xfa0504 0xc5000000 0x05000000 0x1afc0000 0x1afc0000 RWE 0
> 
> Regardless whether the virtual address is in the static kernel text and
> data section (which is mapped in a special region on x86_64 and ia64) or
> just generic physical memory above that, it's all zero-based, where the
> virtual-to-physical translation simply requires stripping of the PAGE_OFFSET.
> The p_vaddr values above match the kernel virtual addresses used by the
> corresponding x86 vmlinux.
> 
> So all I'm asking is that you don't muck with that!  ;-)

I'll promise that I don't break it.

So how about following? This allows ARM (and maybe some future archs as well) to
redefine phys_to_virt() but default implementation should work with others.

Thanks,
MW

>From dcfda0e78ae9bfe3c9ff5d186c660e5ce1892fbb Mon Sep 17 00:00:00 2001
From: Mika Westerberg <ext-mika.1.westerberg at nokia.com>
Date: Thu, 29 Apr 2010 11:07:14 +0300
Subject: [PATCH] kexec: introduce phys_to_virt() function

This function is used by ELF crashdump code which prepares crash memory headers
for the dump capture kernel. Most architecture can use default version which
just adds PAGE_OFFSET to the virtual address but some architectures might need
some special handling.

Signed-off-by: Mika Westerberg <ext-mika.1.westerberg at nokia.com>
---
 kexec/Makefile        |    2 ++
 kexec/crashdump-elf.c |    2 +-
 kexec/crashdump.h     |    3 +++
 kexec/phys_to_virt.c  |   16 ++++++++++++++++
 4 files changed, 22 insertions(+), 1 deletions(-)
 create mode 100644 kexec/phys_to_virt.c

diff --git a/kexec/Makefile b/kexec/Makefile
index 4e091ba..77f37ae 100644
--- a/kexec/Makefile
+++ b/kexec/Makefile
@@ -39,6 +39,8 @@ $(ARCH)_PROC_IOMEM		= kexec/proc_iomem.c
 KEXEC_SRCS += $($(ARCH)_PROC_IOMEM)
 $(ARCH)_VIRT_TO_PHYS		= kexec/virt_to_phys.c
 KEXEC_SRCS += $($(ARCH)_VIRT_TO_PHYS)
+$(ARCH)_PHYS_TO_VIRT		= kexec/phys_to_virt.c
+KEXEC_SRCS += $($(ARCH)_PHYS_TO_VIRT)
 $(ARCH)_ADD_SEGMENT		= kexec/add_segment.c
 KEXEC_SRCS += $($(ARCH)_ADD_SEGMENT)
 $(ARCH)_ADD_BUFFER		= kexec/add_buffer.c
diff --git a/kexec/crashdump-elf.c b/kexec/crashdump-elf.c
index 6bcef8d..f000e42 100644
--- a/kexec/crashdump-elf.c
+++ b/kexec/crashdump-elf.c
@@ -236,7 +236,7 @@ int FUNC(struct kexec_info *info,
 		 * memory region.
 		 */
 		phdr->p_paddr = mstart;
-		phdr->p_vaddr = mstart + elf_info->page_offset;
+		phdr->p_vaddr = phys_to_virt(elf_info, mstart);
 		phdr->p_filesz	= phdr->p_memsz	= mend - mstart + 1;
 		/* Do we need any alignment of segments? */
 		phdr->p_align	= 0;
diff --git a/kexec/crashdump.h b/kexec/crashdump.h
index 30d6f29..b6e60cc 100644
--- a/kexec/crashdump.h
+++ b/kexec/crashdump.h
@@ -46,6 +46,9 @@ int crash_create_elf64_headers(struct kexec_info *info,
 
 unsigned long crash_architecture(struct crash_elf_info *elf_info);
 
+unsigned long phys_to_virt(struct crash_elf_info *elf_info,
+			   unsigned long paddr);
+
 int xen_present(void);
 unsigned long xen_architecture(struct crash_elf_info *elf_info);
 int xen_get_nr_phys_cpus(void);
diff --git a/kexec/phys_to_virt.c b/kexec/phys_to_virt.c
new file mode 100644
index 0000000..2370e56
--- /dev/null
+++ b/kexec/phys_to_virt.c
@@ -0,0 +1,16 @@
+#include "kexec.h"
+#include "crashdump.h"
+
+/**
+ * virt_to_phys() - translate physical address to virtual address
+ * @paddr: physical address to translate
+ *
+ * For most architectures physical address is simply virtual address minus
+ * PAGE_OFFSET. Architectures that don't follow this convention should provide
+ * their own implementation.
+ */
+unsigned long
+phys_to_virt(struct crash_elf_info *elf_info, unsigned long paddr)
+{
+	return paddr + elf_info->page_offset;
+}
-- 
1.5.6.5




More information about the kexec mailing list