* handle x86_64 xen code/data relocation
@ 2008-04-22 8:32 ` Itsuro ODA
0 siblings, 0 replies; 14+ messages in thread
From: Itsuro ODA @ 2008-04-22 8:32 UTC (permalink / raw)
To: kexec; +Cc: xen-devel, crash-utility
Hi all,
Recent version of xen (ex. RHEL5.2, 3.2.0) on the x86_64
moves the physical(machine) address of xen code/data area after
the system started up. The start address of this is stored in
'xen_phys_start'. Thus to get a machine address of a xen text symbol
from its virtual address, calculate
"va - __XEN_VIRT_START + xen_phys_start".
crash and makedumpfile command need the value of xen_phys_start.
They know the virtual address of 'xen_phys_start' symbol but
no way to extract the value of xen_phys_start.
I think adding the xen_phys_start value to the CRASHINFO ElfNote
section at first. (Plan A: patch for xen hypervisor code attaced)
It is smallest modification necessary over all.
On the other hand there is a opinion that it is better to upgrade
a user-package than a hypervisor or kernel package.
The xen_phys_start value can be got from /proc/iomem.
-------------------------------------------------------
# cat /proc/iomem
...
7e600000-7f5fffff : Hypervisor code and data *** this line
...
-------------------------------------------------------
So the kexec-tools can handle it theoretically.
The Plan B is that kexec-tools adds another ElfNote section which
holds the xen_phys_start value. The attached patch works well
though I am concern about it is a bit tricky.
Which plan is better ? Or more good implementation ?
Please comment.
(note that crash and makedumpfile modification is same degree
for both plan.)
Thanks.
Itsuro Oda
=== Plan A (modify the xen hypervisor. It is for RHEL5.2 but almost same for other version) ===
--- include/xen/elfcore.h.org 2008-04-17 14:11:41.000000000 +0900
+++ include/xen/elfcore.h 2008-04-17 14:11:57.000000000 +0900
@@ -66,6 +66,7 @@
unsigned long xen_compile_time;
unsigned long tainted;
#ifdef CONFIG_X86
+ unsigned long xen_phys_start;
unsigned long dom0_pfn_to_mfn_frame_list_list;
#endif
} crash_xen_info_t;
--- arch/x86/crash.c.org 2008-04-17 14:12:51.000000000 +0900
+++ arch/x86/crash.c 2008-04-17 14:13:13.000000000 +0900
@@ -102,6 +102,7 @@
hvm_disable();
info = kexec_crash_save_info();
+ info->xen_phys_start = xen_phys_start;
info->dom0_pfn_to_mfn_frame_list_list =
arch_get_pfn_to_mfn_frame_list_list(dom0);
}
================================================================
=== Plan B (modify the kexec-tools. proof of concept version) ===
diff -ru kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c
--- kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c 2008-03-21 13:16:28.000000000 +0900
+++ kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c 2008-04-22 15:15:08.000000000 +0900
@@ -73,6 +73,25 @@
return -1;
}
+static int get_hypervisor_paddr(struct kexec_info *info)
+{
+ uint64_t start;
+
+ if (!xen_present())
+ return 0;
+
+ if (parse_iomem_single("Hypervisor code and data\n", &start, NULL) == 0) {
+ info->hypervisor_paddr_start = start;
+#ifdef DEBUG
+ printf("kernel load physical addr start = 0x%016Lx\n", start);
+#endif
+ return 0;
+ }
+
+ fprintf(stderr, "Cannot determine hypervisor physical load addr\n");
+ return -1;
+}
+
/* Retrieve info regarding virtual address kernel has been compiled for and
* size of the kernel from /proc/kcore. Current /proc/kcore parsing from
* from kexec-tools fails because of malformed elf notes. A kernel patch has
@@ -581,6 +600,9 @@
if (get_kernel_paddr(info))
return -1;
+ if (get_hypervisor_paddr(info))
+ return -1;
+
if (get_kernel_vaddr_and_size(info))
return -1;
@@ -620,6 +642,9 @@
*/
elfcorehdr = add_buffer(info, tmp, sz, 16*1024, align, min_base,
max_addr, -1);
+ if (info->hypervisor_paddr_start && xen_present()) {
+ *(info->hypervisor_paddr_loc) += elfcorehdr;
+ }
if (delete_memmap(memmap_p, elfcorehdr, sz) < 0)
return -1;
cmdline_add_memmap(mod_cmdline, memmap_p);
diff -ru kexec-tools-testing-20080324.org/kexec/crashdump.c kexec-tools-testing-20080324/kexec/crashdump.c
--- kexec-tools-testing-20080324.org/kexec/crashdump.c 2008-03-21 13:16:28.000000000 +0900
+++ kexec-tools-testing-20080324/kexec/crashdump.c 2008-04-22 15:33:47.000000000 +0900
@@ -36,8 +36,10 @@
#define FUNC crash_create_elf64_headers
#define EHDR Elf64_Ehdr
#define PHDR Elf64_Phdr
+#define NHDR Elf64_Nhdr
#include "crashdump-elf.c"
#undef ELF_WIDTH
+#undef NHDR
#undef PHDR
#undef EHDR
#undef FUNC
@@ -46,8 +48,10 @@
#define FUNC crash_create_elf32_headers
#define EHDR Elf32_Ehdr
#define PHDR Elf32_Phdr
+#define NHDR Elf32_Nhdr
#include "crashdump-elf.c"
#undef ELF_WIDTH
+#undef NHDR
#undef PHDR
#undef EHDR
#undef FUNC
diff -ru kexec-tools-testing-20080324.org/kexec/crashdump-elf.c kexec-tools-testing-20080324/kexec/crashdump-elf.c
--- kexec-tools-testing-20080324.org/kexec/crashdump-elf.c 2008-01-11 12:13:48.000000000 +0900
+++ kexec-tools-testing-20080324/kexec/crashdump-elf.c 2008-04-22 15:35:16.000000000 +0900
@@ -1,6 +1,6 @@
-#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR)
-#error FUNC, EHDR and PHDR must be defined
+#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR) || !defined(NHDR)
+#error FUNC, EHDR, PHDR and NHDR must be defined
#endif
#if (ELF_WIDTH == 64)
@@ -37,6 +37,7 @@
uint64_t vmcoreinfo_addr, vmcoreinfo_len;
int has_vmcoreinfo = 0;
int (*get_note_info)(int cpu, uint64_t *addr, uint64_t *len);
+ int has_hypervisor_paddr_start = 0;
if (xen_present())
nr_cpus = xen_get_nr_phys_cpus();
@@ -78,6 +79,11 @@
sz += sizeof(PHDR);
}
+ if (info->hypervisor_paddr_start && xen_present()) {
+ sz += sizeof(PHDR) + sizeof(NHDR) + 4 + sizeof(unsigned long);
+ has_hypervisor_paddr_start = 1;
+ }
+
/*
* Make sure the ELF core header is aligned to at least 1024.
* We do this because the secondary kernel gets the ELF core
@@ -168,6 +174,22 @@
dbgprintf_phdr("vmcoreinfo header", phdr);
}
+ if (has_hypervisor_paddr_start) {
+ phdr = (PHDR *) bufp;
+ bufp += sizeof(PHDR);
+ phdr->p_type = PT_NOTE;
+ phdr->p_flags = 0;
+ phdr->p_offset = phdr->p_paddr = 0;
+ phdr->p_vaddr = 0;
+ phdr->p_filesz = phdr->p_memsz = sizeof(NHDR) + 4 + sizeof(unsigned long);
+ phdr->p_align = 0;
+
+ (elf->e_phnum)++;
+ dbgprintf_phdr("hypervisor phys addr header", phdr);
+
+ info->hypervisor_paddr_loc = (unsigned long *)&phdr->p_offset;
+ }
+
/* Setup an PT_LOAD type program header for the region where
* Kernel is mapped if info->kern_size is non-zero.
*/
@@ -225,6 +247,24 @@
(elf->e_phnum)++;
dbgprintf_phdr("Elf header", phdr);
}
+
+ if (has_hypervisor_paddr_start) {
+ NHDR *nhdr;
+ unsigned int offset = (void *)bufp - *buf;
+
+ nhdr = (NHDR *) bufp;
+ bufp += sizeof(NHDR);
+ nhdr->n_namesz = 4;
+ nhdr->n_descsz = sizeof(unsigned long);
+ nhdr->n_type = 0x1000003;
+ memcpy(bufp, "Xen", 4);
+ bufp += 4;
+ *((unsigned long *)bufp) = info->hypervisor_paddr_start;
+ bufp += sizeof(unsigned long);
+
+ *(info->hypervisor_paddr_loc) = offset;
+ }
+
return 0;
}
diff -ru kexec-tools-testing-20080324.org/kexec/kexec.h kexec-tools-testing-20080324/kexec/kexec.h
--- kexec-tools-testing-20080324.org/kexec/kexec.h 2008-03-21 13:16:28.000000000 +0900
+++ kexec-tools-testing-20080324/kexec/kexec.h 2008-04-22 15:08:57.000000000 +0900
@@ -123,6 +123,8 @@
unsigned long kern_vaddr_start;
unsigned long kern_paddr_start;
unsigned long kern_size;
+ unsigned long hypervisor_paddr_start;
+ unsigned long *hypervisor_paddr_loc;
};
void usage(void);
======================================================================================
--
Itsuro ODA <oda@valinux.co.jp>
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 14+ messages in thread
* handle x86_64 xen code/data relocation
@ 2008-04-22 8:32 ` Itsuro ODA
0 siblings, 0 replies; 14+ messages in thread
From: Itsuro ODA @ 2008-04-22 8:32 UTC (permalink / raw)
To: kexec; +Cc: xen-devel, crash-utility
Hi all,
Recent version of xen (ex. RHEL5.2, 3.2.0) on the x86_64
moves the physical(machine) address of xen code/data area after
the system started up. The start address of this is stored in
'xen_phys_start'. Thus to get a machine address of a xen text symbol
from its virtual address, calculate
"va - __XEN_VIRT_START + xen_phys_start".
crash and makedumpfile command need the value of xen_phys_start.
They know the virtual address of 'xen_phys_start' symbol but
no way to extract the value of xen_phys_start.
I think adding the xen_phys_start value to the CRASHINFO ElfNote
section at first. (Plan A: patch for xen hypervisor code attaced)
It is smallest modification necessary over all.
On the other hand there is a opinion that it is better to upgrade
a user-package than a hypervisor or kernel package.
The xen_phys_start value can be got from /proc/iomem.
-------------------------------------------------------
# cat /proc/iomem
...
7e600000-7f5fffff : Hypervisor code and data *** this line
...
-------------------------------------------------------
So the kexec-tools can handle it theoretically.
The Plan B is that kexec-tools adds another ElfNote section which
holds the xen_phys_start value. The attached patch works well
though I am concern about it is a bit tricky.
Which plan is better ? Or more good implementation ?
Please comment.
(note that crash and makedumpfile modification is same degree
for both plan.)
Thanks.
Itsuro Oda
=== Plan A (modify the xen hypervisor. It is for RHEL5.2 but almost same for other version) ===
--- include/xen/elfcore.h.org 2008-04-17 14:11:41.000000000 +0900
+++ include/xen/elfcore.h 2008-04-17 14:11:57.000000000 +0900
@@ -66,6 +66,7 @@
unsigned long xen_compile_time;
unsigned long tainted;
#ifdef CONFIG_X86
+ unsigned long xen_phys_start;
unsigned long dom0_pfn_to_mfn_frame_list_list;
#endif
} crash_xen_info_t;
--- arch/x86/crash.c.org 2008-04-17 14:12:51.000000000 +0900
+++ arch/x86/crash.c 2008-04-17 14:13:13.000000000 +0900
@@ -102,6 +102,7 @@
hvm_disable();
info = kexec_crash_save_info();
+ info->xen_phys_start = xen_phys_start;
info->dom0_pfn_to_mfn_frame_list_list =
arch_get_pfn_to_mfn_frame_list_list(dom0);
}
================================================================
=== Plan B (modify the kexec-tools. proof of concept version) ===
diff -ru kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c
--- kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c 2008-03-21 13:16:28.000000000 +0900
+++ kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c 2008-04-22 15:15:08.000000000 +0900
@@ -73,6 +73,25 @@
return -1;
}
+static int get_hypervisor_paddr(struct kexec_info *info)
+{
+ uint64_t start;
+
+ if (!xen_present())
+ return 0;
+
+ if (parse_iomem_single("Hypervisor code and data\n", &start, NULL) == 0) {
+ info->hypervisor_paddr_start = start;
+#ifdef DEBUG
+ printf("kernel load physical addr start = 0x%016Lx\n", start);
+#endif
+ return 0;
+ }
+
+ fprintf(stderr, "Cannot determine hypervisor physical load addr\n");
+ return -1;
+}
+
/* Retrieve info regarding virtual address kernel has been compiled for and
* size of the kernel from /proc/kcore. Current /proc/kcore parsing from
* from kexec-tools fails because of malformed elf notes. A kernel patch has
@@ -581,6 +600,9 @@
if (get_kernel_paddr(info))
return -1;
+ if (get_hypervisor_paddr(info))
+ return -1;
+
if (get_kernel_vaddr_and_size(info))
return -1;
@@ -620,6 +642,9 @@
*/
elfcorehdr = add_buffer(info, tmp, sz, 16*1024, align, min_base,
max_addr, -1);
+ if (info->hypervisor_paddr_start && xen_present()) {
+ *(info->hypervisor_paddr_loc) += elfcorehdr;
+ }
if (delete_memmap(memmap_p, elfcorehdr, sz) < 0)
return -1;
cmdline_add_memmap(mod_cmdline, memmap_p);
diff -ru kexec-tools-testing-20080324.org/kexec/crashdump.c kexec-tools-testing-20080324/kexec/crashdump.c
--- kexec-tools-testing-20080324.org/kexec/crashdump.c 2008-03-21 13:16:28.000000000 +0900
+++ kexec-tools-testing-20080324/kexec/crashdump.c 2008-04-22 15:33:47.000000000 +0900
@@ -36,8 +36,10 @@
#define FUNC crash_create_elf64_headers
#define EHDR Elf64_Ehdr
#define PHDR Elf64_Phdr
+#define NHDR Elf64_Nhdr
#include "crashdump-elf.c"
#undef ELF_WIDTH
+#undef NHDR
#undef PHDR
#undef EHDR
#undef FUNC
@@ -46,8 +48,10 @@
#define FUNC crash_create_elf32_headers
#define EHDR Elf32_Ehdr
#define PHDR Elf32_Phdr
+#define NHDR Elf32_Nhdr
#include "crashdump-elf.c"
#undef ELF_WIDTH
+#undef NHDR
#undef PHDR
#undef EHDR
#undef FUNC
diff -ru kexec-tools-testing-20080324.org/kexec/crashdump-elf.c kexec-tools-testing-20080324/kexec/crashdump-elf.c
--- kexec-tools-testing-20080324.org/kexec/crashdump-elf.c 2008-01-11 12:13:48.000000000 +0900
+++ kexec-tools-testing-20080324/kexec/crashdump-elf.c 2008-04-22 15:35:16.000000000 +0900
@@ -1,6 +1,6 @@
-#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR)
-#error FUNC, EHDR and PHDR must be defined
+#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR) || !defined(NHDR)
+#error FUNC, EHDR, PHDR and NHDR must be defined
#endif
#if (ELF_WIDTH == 64)
@@ -37,6 +37,7 @@
uint64_t vmcoreinfo_addr, vmcoreinfo_len;
int has_vmcoreinfo = 0;
int (*get_note_info)(int cpu, uint64_t *addr, uint64_t *len);
+ int has_hypervisor_paddr_start = 0;
if (xen_present())
nr_cpus = xen_get_nr_phys_cpus();
@@ -78,6 +79,11 @@
sz += sizeof(PHDR);
}
+ if (info->hypervisor_paddr_start && xen_present()) {
+ sz += sizeof(PHDR) + sizeof(NHDR) + 4 + sizeof(unsigned long);
+ has_hypervisor_paddr_start = 1;
+ }
+
/*
* Make sure the ELF core header is aligned to at least 1024.
* We do this because the secondary kernel gets the ELF core
@@ -168,6 +174,22 @@
dbgprintf_phdr("vmcoreinfo header", phdr);
}
+ if (has_hypervisor_paddr_start) {
+ phdr = (PHDR *) bufp;
+ bufp += sizeof(PHDR);
+ phdr->p_type = PT_NOTE;
+ phdr->p_flags = 0;
+ phdr->p_offset = phdr->p_paddr = 0;
+ phdr->p_vaddr = 0;
+ phdr->p_filesz = phdr->p_memsz = sizeof(NHDR) + 4 + sizeof(unsigned long);
+ phdr->p_align = 0;
+
+ (elf->e_phnum)++;
+ dbgprintf_phdr("hypervisor phys addr header", phdr);
+
+ info->hypervisor_paddr_loc = (unsigned long *)&phdr->p_offset;
+ }
+
/* Setup an PT_LOAD type program header for the region where
* Kernel is mapped if info->kern_size is non-zero.
*/
@@ -225,6 +247,24 @@
(elf->e_phnum)++;
dbgprintf_phdr("Elf header", phdr);
}
+
+ if (has_hypervisor_paddr_start) {
+ NHDR *nhdr;
+ unsigned int offset = (void *)bufp - *buf;
+
+ nhdr = (NHDR *) bufp;
+ bufp += sizeof(NHDR);
+ nhdr->n_namesz = 4;
+ nhdr->n_descsz = sizeof(unsigned long);
+ nhdr->n_type = 0x1000003;
+ memcpy(bufp, "Xen", 4);
+ bufp += 4;
+ *((unsigned long *)bufp) = info->hypervisor_paddr_start;
+ bufp += sizeof(unsigned long);
+
+ *(info->hypervisor_paddr_loc) = offset;
+ }
+
return 0;
}
diff -ru kexec-tools-testing-20080324.org/kexec/kexec.h kexec-tools-testing-20080324/kexec/kexec.h
--- kexec-tools-testing-20080324.org/kexec/kexec.h 2008-03-21 13:16:28.000000000 +0900
+++ kexec-tools-testing-20080324/kexec/kexec.h 2008-04-22 15:08:57.000000000 +0900
@@ -123,6 +123,8 @@
unsigned long kern_vaddr_start;
unsigned long kern_paddr_start;
unsigned long kern_size;
+ unsigned long hypervisor_paddr_start;
+ unsigned long *hypervisor_paddr_loc;
};
void usage(void);
======================================================================================
--
Itsuro ODA <oda@valinux.co.jp>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xen-devel] handle x86_64 xen code/data relocation
2008-04-22 8:32 ` Itsuro ODA
@ 2008-04-22 8:53 ` Keir Fraser
-1 siblings, 0 replies; 14+ messages in thread
From: Keir Fraser @ 2008-04-22 8:53 UTC (permalink / raw)
To: Itsuro ODA, kexec; +Cc: xen-devel, crash-utility
While you're thinking about this, I'll also point out that the 'xen heap'
will be going away quite soon. That's an inconvenience for kdump since
currently Xen's own allocations are conveniently squashed up in a small
range of a few megabytes of memory. I'm not sure what the right fix is for
kdump -- either you don't get Xen's dynamically-allocated state, or you'll
have to gather it up at kdump time somehow.
-- Keir
On 22/4/08 09:32, "Itsuro ODA" <oda@valinux.co.jp> wrote:
> Hi all,
>
> Recent version of xen (ex. RHEL5.2, 3.2.0) on the x86_64
> moves the physical(machine) address of xen code/data area after
> the system started up. The start address of this is stored in
> 'xen_phys_start'. Thus to get a machine address of a xen text symbol
> from its virtual address, calculate
> "va - __XEN_VIRT_START + xen_phys_start".
>
> crash and makedumpfile command need the value of xen_phys_start.
> They know the virtual address of 'xen_phys_start' symbol but
> no way to extract the value of xen_phys_start.
>
> I think adding the xen_phys_start value to the CRASHINFO ElfNote
> section at first. (Plan A: patch for xen hypervisor code attaced)
> It is smallest modification necessary over all.
>
> On the other hand there is a opinion that it is better to upgrade
> a user-package than a hypervisor or kernel package.
> The xen_phys_start value can be got from /proc/iomem.
> -------------------------------------------------------
> # cat /proc/iomem
> ...
> 7e600000-7f5fffff : Hypervisor code and data *** this line
> ...
> -------------------------------------------------------
> So the kexec-tools can handle it theoretically.
>
> The Plan B is that kexec-tools adds another ElfNote section which
> holds the xen_phys_start value. The attached patch works well
> though I am concern about it is a bit tricky.
>
> Which plan is better ? Or more good implementation ?
> Please comment.
>
> (note that crash and makedumpfile modification is same degree
> for both plan.)
>
> Thanks.
> Itsuro Oda
>
> === Plan A (modify the xen hypervisor. It is for RHEL5.2 but almost same for
> other version) ===
> --- include/xen/elfcore.h.org 2008-04-17 14:11:41.000000000 +0900
> +++ include/xen/elfcore.h 2008-04-17 14:11:57.000000000 +0900
> @@ -66,6 +66,7 @@
> unsigned long xen_compile_time;
> unsigned long tainted;
> #ifdef CONFIG_X86
> + unsigned long xen_phys_start;
> unsigned long dom0_pfn_to_mfn_frame_list_list;
> #endif
> } crash_xen_info_t;
> --- arch/x86/crash.c.org 2008-04-17 14:12:51.000000000 +0900
> +++ arch/x86/crash.c 2008-04-17 14:13:13.000000000 +0900
> @@ -102,6 +102,7 @@
> hvm_disable();
>
> info = kexec_crash_save_info();
> + info->xen_phys_start = xen_phys_start;
> info->dom0_pfn_to_mfn_frame_list_list =
> arch_get_pfn_to_mfn_frame_list_list(dom0);
> }
> ================================================================
>
> === Plan B (modify the kexec-tools. proof of concept version) ===
> diff -ru kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c
> kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c
> ---
> kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c 2008-03-
> 21 13:16:28.000000000 +0900
> +++
> kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c 2008-04-22
> 15:15:08.000000000 +0900
> @@ -73,6 +73,25 @@
> return -1;
> }
>
> +static int get_hypervisor_paddr(struct kexec_info *info)
> +{
> + uint64_t start;
> +
> + if (!xen_present())
> + return 0;
> +
> + if (parse_iomem_single("Hypervisor code and data\n", &start, NULL) == 0) {
> + info->hypervisor_paddr_start = start;
> +#ifdef DEBUG
> + printf("kernel load physical addr start = 0x%016Lx\n", start);
> +#endif
> + return 0;
> + }
> +
> + fprintf(stderr, "Cannot determine hypervisor physical load addr\n");
> + return -1;
> +}
> +
> /* Retrieve info regarding virtual address kernel has been compiled for and
> * size of the kernel from /proc/kcore. Current /proc/kcore parsing from
> * from kexec-tools fails because of malformed elf notes. A kernel patch has
> @@ -581,6 +600,9 @@
> if (get_kernel_paddr(info))
> return -1;
>
> + if (get_hypervisor_paddr(info))
> + return -1;
> +
> if (get_kernel_vaddr_and_size(info))
> return -1;
>
> @@ -620,6 +642,9 @@
> */
> elfcorehdr = add_buffer(info, tmp, sz, 16*1024, align, min_base,
> max_addr, -1);
> + if (info->hypervisor_paddr_start && xen_present()) {
> + *(info->hypervisor_paddr_loc) += elfcorehdr;
> + }
> if (delete_memmap(memmap_p, elfcorehdr, sz) < 0)
> return -1;
> cmdline_add_memmap(mod_cmdline, memmap_p);
> diff -ru kexec-tools-testing-20080324.org/kexec/crashdump.c
> kexec-tools-testing-20080324/kexec/crashdump.c
> --- kexec-tools-testing-20080324.org/kexec/crashdump.c 2008-03-21
> 13:16:28.000000000 +0900
> +++ kexec-tools-testing-20080324/kexec/crashdump.c 2008-04-22
> 15:33:47.000000000 +0900
> @@ -36,8 +36,10 @@
> #define FUNC crash_create_elf64_headers
> #define EHDR Elf64_Ehdr
> #define PHDR Elf64_Phdr
> +#define NHDR Elf64_Nhdr
> #include "crashdump-elf.c"
> #undef ELF_WIDTH
> +#undef NHDR
> #undef PHDR
> #undef EHDR
> #undef FUNC
> @@ -46,8 +48,10 @@
> #define FUNC crash_create_elf32_headers
> #define EHDR Elf32_Ehdr
> #define PHDR Elf32_Phdr
> +#define NHDR Elf32_Nhdr
> #include "crashdump-elf.c"
> #undef ELF_WIDTH
> +#undef NHDR
> #undef PHDR
> #undef EHDR
> #undef FUNC
> diff -ru kexec-tools-testing-20080324.org/kexec/crashdump-elf.c
> kexec-tools-testing-20080324/kexec/crashdump-elf.c
> --- kexec-tools-testing-20080324.org/kexec/crashdump-elf.c 2008-01-11
> 12:13:48.000000000 +0900
> +++ kexec-tools-testing-20080324/kexec/crashdump-elf.c 2008-04-22
> 15:35:16.000000000 +0900
> @@ -1,6 +1,6 @@
>
> -#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR)
> -#error FUNC, EHDR and PHDR must be defined
> +#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR) || !defined(NHDR)
> +#error FUNC, EHDR, PHDR and NHDR must be defined
> #endif
>
> #if (ELF_WIDTH == 64)
> @@ -37,6 +37,7 @@
> uint64_t vmcoreinfo_addr, vmcoreinfo_len;
> int has_vmcoreinfo = 0;
> int (*get_note_info)(int cpu, uint64_t *addr, uint64_t *len);
> + int has_hypervisor_paddr_start = 0;
>
> if (xen_present())
> nr_cpus = xen_get_nr_phys_cpus();
> @@ -78,6 +79,11 @@
> sz += sizeof(PHDR);
> }
>
> + if (info->hypervisor_paddr_start && xen_present()) {
> + sz += sizeof(PHDR) + sizeof(NHDR) + 4 + sizeof(unsigned long);
> + has_hypervisor_paddr_start = 1;
> + }
> +
> /*
> * Make sure the ELF core header is aligned to at least 1024.
> * We do this because the secondary kernel gets the ELF core
> @@ -168,6 +174,22 @@
> dbgprintf_phdr("vmcoreinfo header", phdr);
> }
>
> + if (has_hypervisor_paddr_start) {
> + phdr = (PHDR *) bufp;
> + bufp += sizeof(PHDR);
> + phdr->p_type = PT_NOTE;
> + phdr->p_flags = 0;
> + phdr->p_offset = phdr->p_paddr = 0;
> + phdr->p_vaddr = 0;
> + phdr->p_filesz = phdr->p_memsz = sizeof(NHDR) + 4 + sizeof(unsigned long);
> + phdr->p_align = 0;
> +
> + (elf->e_phnum)++;
> + dbgprintf_phdr("hypervisor phys addr header", phdr);
> +
> + info->hypervisor_paddr_loc = (unsigned long *)&phdr->p_offset;
> + }
> +
> /* Setup an PT_LOAD type program header for the region where
> * Kernel is mapped if info->kern_size is non-zero.
> */
> @@ -225,6 +247,24 @@
> (elf->e_phnum)++;
> dbgprintf_phdr("Elf header", phdr);
> }
> +
> + if (has_hypervisor_paddr_start) {
> + NHDR *nhdr;
> + unsigned int offset = (void *)bufp - *buf;
> +
> + nhdr = (NHDR *) bufp;
> + bufp += sizeof(NHDR);
> + nhdr->n_namesz = 4;
> + nhdr->n_descsz = sizeof(unsigned long);
> + nhdr->n_type = 0x1000003;
> + memcpy(bufp, "Xen", 4);
> + bufp += 4;
> + *((unsigned long *)bufp) = info->hypervisor_paddr_start;
> + bufp += sizeof(unsigned long);
> +
> + *(info->hypervisor_paddr_loc) = offset;
> + }
> +
> return 0;
> }
>
> diff -ru kexec-tools-testing-20080324.org/kexec/kexec.h
> kexec-tools-testing-20080324/kexec/kexec.h
> --- kexec-tools-testing-20080324.org/kexec/kexec.h 2008-03-21
> 13:16:28.000000000 +0900
> +++ kexec-tools-testing-20080324/kexec/kexec.h 2008-04-22 15:08:57.000000000
> +0900
> @@ -123,6 +123,8 @@
> unsigned long kern_vaddr_start;
> unsigned long kern_paddr_start;
> unsigned long kern_size;
> + unsigned long hypervisor_paddr_start;
> + unsigned long *hypervisor_paddr_loc;
> };
>
> void usage(void);
> ==============================================================================
> ========
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: handle x86_64 xen code/data relocation
@ 2008-04-22 8:53 ` Keir Fraser
0 siblings, 0 replies; 14+ messages in thread
From: Keir Fraser @ 2008-04-22 8:53 UTC (permalink / raw)
To: Itsuro ODA, kexec; +Cc: xen-devel, crash-utility
While you're thinking about this, I'll also point out that the 'xen heap'
will be going away quite soon. That's an inconvenience for kdump since
currently Xen's own allocations are conveniently squashed up in a small
range of a few megabytes of memory. I'm not sure what the right fix is for
kdump -- either you don't get Xen's dynamically-allocated state, or you'll
have to gather it up at kdump time somehow.
-- Keir
On 22/4/08 09:32, "Itsuro ODA" <oda@valinux.co.jp> wrote:
> Hi all,
>
> Recent version of xen (ex. RHEL5.2, 3.2.0) on the x86_64
> moves the physical(machine) address of xen code/data area after
> the system started up. The start address of this is stored in
> 'xen_phys_start'. Thus to get a machine address of a xen text symbol
> from its virtual address, calculate
> "va - __XEN_VIRT_START + xen_phys_start".
>
> crash and makedumpfile command need the value of xen_phys_start.
> They know the virtual address of 'xen_phys_start' symbol but
> no way to extract the value of xen_phys_start.
>
> I think adding the xen_phys_start value to the CRASHINFO ElfNote
> section at first. (Plan A: patch for xen hypervisor code attaced)
> It is smallest modification necessary over all.
>
> On the other hand there is a opinion that it is better to upgrade
> a user-package than a hypervisor or kernel package.
> The xen_phys_start value can be got from /proc/iomem.
> -------------------------------------------------------
> # cat /proc/iomem
> ...
> 7e600000-7f5fffff : Hypervisor code and data *** this line
> ...
> -------------------------------------------------------
> So the kexec-tools can handle it theoretically.
>
> The Plan B is that kexec-tools adds another ElfNote section which
> holds the xen_phys_start value. The attached patch works well
> though I am concern about it is a bit tricky.
>
> Which plan is better ? Or more good implementation ?
> Please comment.
>
> (note that crash and makedumpfile modification is same degree
> for both plan.)
>
> Thanks.
> Itsuro Oda
>
> === Plan A (modify the xen hypervisor. It is for RHEL5.2 but almost same for
> other version) ===
> --- include/xen/elfcore.h.org 2008-04-17 14:11:41.000000000 +0900
> +++ include/xen/elfcore.h 2008-04-17 14:11:57.000000000 +0900
> @@ -66,6 +66,7 @@
> unsigned long xen_compile_time;
> unsigned long tainted;
> #ifdef CONFIG_X86
> + unsigned long xen_phys_start;
> unsigned long dom0_pfn_to_mfn_frame_list_list;
> #endif
> } crash_xen_info_t;
> --- arch/x86/crash.c.org 2008-04-17 14:12:51.000000000 +0900
> +++ arch/x86/crash.c 2008-04-17 14:13:13.000000000 +0900
> @@ -102,6 +102,7 @@
> hvm_disable();
>
> info = kexec_crash_save_info();
> + info->xen_phys_start = xen_phys_start;
> info->dom0_pfn_to_mfn_frame_list_list =
> arch_get_pfn_to_mfn_frame_list_list(dom0);
> }
> ================================================================
>
> === Plan B (modify the kexec-tools. proof of concept version) ===
> diff -ru kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c
> kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c
> ---
> kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c 2008-03-
> 21 13:16:28.000000000 +0900
> +++
> kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c 2008-04-22
> 15:15:08.000000000 +0900
> @@ -73,6 +73,25 @@
> return -1;
> }
>
> +static int get_hypervisor_paddr(struct kexec_info *info)
> +{
> + uint64_t start;
> +
> + if (!xen_present())
> + return 0;
> +
> + if (parse_iomem_single("Hypervisor code and data\n", &start, NULL) == 0) {
> + info->hypervisor_paddr_start = start;
> +#ifdef DEBUG
> + printf("kernel load physical addr start = 0x%016Lx\n", start);
> +#endif
> + return 0;
> + }
> +
> + fprintf(stderr, "Cannot determine hypervisor physical load addr\n");
> + return -1;
> +}
> +
> /* Retrieve info regarding virtual address kernel has been compiled for and
> * size of the kernel from /proc/kcore. Current /proc/kcore parsing from
> * from kexec-tools fails because of malformed elf notes. A kernel patch has
> @@ -581,6 +600,9 @@
> if (get_kernel_paddr(info))
> return -1;
>
> + if (get_hypervisor_paddr(info))
> + return -1;
> +
> if (get_kernel_vaddr_and_size(info))
> return -1;
>
> @@ -620,6 +642,9 @@
> */
> elfcorehdr = add_buffer(info, tmp, sz, 16*1024, align, min_base,
> max_addr, -1);
> + if (info->hypervisor_paddr_start && xen_present()) {
> + *(info->hypervisor_paddr_loc) += elfcorehdr;
> + }
> if (delete_memmap(memmap_p, elfcorehdr, sz) < 0)
> return -1;
> cmdline_add_memmap(mod_cmdline, memmap_p);
> diff -ru kexec-tools-testing-20080324.org/kexec/crashdump.c
> kexec-tools-testing-20080324/kexec/crashdump.c
> --- kexec-tools-testing-20080324.org/kexec/crashdump.c 2008-03-21
> 13:16:28.000000000 +0900
> +++ kexec-tools-testing-20080324/kexec/crashdump.c 2008-04-22
> 15:33:47.000000000 +0900
> @@ -36,8 +36,10 @@
> #define FUNC crash_create_elf64_headers
> #define EHDR Elf64_Ehdr
> #define PHDR Elf64_Phdr
> +#define NHDR Elf64_Nhdr
> #include "crashdump-elf.c"
> #undef ELF_WIDTH
> +#undef NHDR
> #undef PHDR
> #undef EHDR
> #undef FUNC
> @@ -46,8 +48,10 @@
> #define FUNC crash_create_elf32_headers
> #define EHDR Elf32_Ehdr
> #define PHDR Elf32_Phdr
> +#define NHDR Elf32_Nhdr
> #include "crashdump-elf.c"
> #undef ELF_WIDTH
> +#undef NHDR
> #undef PHDR
> #undef EHDR
> #undef FUNC
> diff -ru kexec-tools-testing-20080324.org/kexec/crashdump-elf.c
> kexec-tools-testing-20080324/kexec/crashdump-elf.c
> --- kexec-tools-testing-20080324.org/kexec/crashdump-elf.c 2008-01-11
> 12:13:48.000000000 +0900
> +++ kexec-tools-testing-20080324/kexec/crashdump-elf.c 2008-04-22
> 15:35:16.000000000 +0900
> @@ -1,6 +1,6 @@
>
> -#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR)
> -#error FUNC, EHDR and PHDR must be defined
> +#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR) || !defined(NHDR)
> +#error FUNC, EHDR, PHDR and NHDR must be defined
> #endif
>
> #if (ELF_WIDTH == 64)
> @@ -37,6 +37,7 @@
> uint64_t vmcoreinfo_addr, vmcoreinfo_len;
> int has_vmcoreinfo = 0;
> int (*get_note_info)(int cpu, uint64_t *addr, uint64_t *len);
> + int has_hypervisor_paddr_start = 0;
>
> if (xen_present())
> nr_cpus = xen_get_nr_phys_cpus();
> @@ -78,6 +79,11 @@
> sz += sizeof(PHDR);
> }
>
> + if (info->hypervisor_paddr_start && xen_present()) {
> + sz += sizeof(PHDR) + sizeof(NHDR) + 4 + sizeof(unsigned long);
> + has_hypervisor_paddr_start = 1;
> + }
> +
> /*
> * Make sure the ELF core header is aligned to at least 1024.
> * We do this because the secondary kernel gets the ELF core
> @@ -168,6 +174,22 @@
> dbgprintf_phdr("vmcoreinfo header", phdr);
> }
>
> + if (has_hypervisor_paddr_start) {
> + phdr = (PHDR *) bufp;
> + bufp += sizeof(PHDR);
> + phdr->p_type = PT_NOTE;
> + phdr->p_flags = 0;
> + phdr->p_offset = phdr->p_paddr = 0;
> + phdr->p_vaddr = 0;
> + phdr->p_filesz = phdr->p_memsz = sizeof(NHDR) + 4 + sizeof(unsigned long);
> + phdr->p_align = 0;
> +
> + (elf->e_phnum)++;
> + dbgprintf_phdr("hypervisor phys addr header", phdr);
> +
> + info->hypervisor_paddr_loc = (unsigned long *)&phdr->p_offset;
> + }
> +
> /* Setup an PT_LOAD type program header for the region where
> * Kernel is mapped if info->kern_size is non-zero.
> */
> @@ -225,6 +247,24 @@
> (elf->e_phnum)++;
> dbgprintf_phdr("Elf header", phdr);
> }
> +
> + if (has_hypervisor_paddr_start) {
> + NHDR *nhdr;
> + unsigned int offset = (void *)bufp - *buf;
> +
> + nhdr = (NHDR *) bufp;
> + bufp += sizeof(NHDR);
> + nhdr->n_namesz = 4;
> + nhdr->n_descsz = sizeof(unsigned long);
> + nhdr->n_type = 0x1000003;
> + memcpy(bufp, "Xen", 4);
> + bufp += 4;
> + *((unsigned long *)bufp) = info->hypervisor_paddr_start;
> + bufp += sizeof(unsigned long);
> +
> + *(info->hypervisor_paddr_loc) = offset;
> + }
> +
> return 0;
> }
>
> diff -ru kexec-tools-testing-20080324.org/kexec/kexec.h
> kexec-tools-testing-20080324/kexec/kexec.h
> --- kexec-tools-testing-20080324.org/kexec/kexec.h 2008-03-21
> 13:16:28.000000000 +0900
> +++ kexec-tools-testing-20080324/kexec/kexec.h 2008-04-22 15:08:57.000000000
> +0900
> @@ -123,6 +123,8 @@
> unsigned long kern_vaddr_start;
> unsigned long kern_paddr_start;
> unsigned long kern_size;
> + unsigned long hypervisor_paddr_start;
> + unsigned long *hypervisor_paddr_loc;
> };
>
> void usage(void);
> ==============================================================================
> ========
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: handle x86_64 xen code/data relocation
2008-04-22 8:32 ` Itsuro ODA
@ 2008-05-20 3:58 ` Simon Horman
-1 siblings, 0 replies; 14+ messages in thread
From: Simon Horman @ 2008-05-20 3:58 UTC (permalink / raw)
To: Itsuro ODA; +Cc: xen-devel, kexec, crash-utility
[-- Attachment #1: Type: text/plain, Size: 8734 bytes --]
On Tue, Apr 22, 2008 at 05:32:03PM +0900, Itsuro ODA wrote:
> Hi all,
>
> Recent version of xen (ex. RHEL5.2, 3.2.0) on the x86_64
> moves the physical(machine) address of xen code/data area after
> the system started up. The start address of this is stored in
> 'xen_phys_start'. Thus to get a machine address of a xen text symbol
> from its virtual address, calculate
> "va - __XEN_VIRT_START + xen_phys_start".
>
> crash and makedumpfile command need the value of xen_phys_start.
> They know the virtual address of 'xen_phys_start' symbol but
> no way to extract the value of xen_phys_start.
>
> I think adding the xen_phys_start value to the CRASHINFO ElfNote
> section at first. (Plan A: patch for xen hypervisor code attaced)
> It is smallest modification necessary over all.
>
> On the other hand there is a opinion that it is better to upgrade
> a user-package than a hypervisor or kernel package.
> The xen_phys_start value can be got from /proc/iomem.
> -------------------------------------------------------
> # cat /proc/iomem
> ...
> 7e600000-7f5fffff : Hypervisor code and data *** this line
> ...
> -------------------------------------------------------
> So the kexec-tools can handle it theoretically.
>
> The Plan B is that kexec-tools adds another ElfNote section which
> holds the xen_phys_start value. The attached patch works well
> though I am concern about it is a bit tricky.
>
> Which plan is better ? Or more good implementation ?
> Please comment.
>
> (note that crash and makedumpfile modification is same degree
> for both plan.)
Hi Oda-san,
I think that in terms of simplicity plan A is a clear
winner. That is assuming tha the changes to crash
and makedumpfile are more or less the same for both
plan A and plan B.
However, if there is a reason that it makes sense to include
the change in kexec-tools and make a fresh release, I'm happy to do so.
> === Plan A (modify the xen hypervisor. It is for RHEL5.2 but almost same for other version) ===
> --- include/xen/elfcore.h.org 2008-04-17 14:11:41.000000000 +0900
> +++ include/xen/elfcore.h 2008-04-17 14:11:57.000000000 +0900
> @@ -66,6 +66,7 @@
> unsigned long xen_compile_time;
> unsigned long tainted;
> #ifdef CONFIG_X86
> + unsigned long xen_phys_start;
> unsigned long dom0_pfn_to_mfn_frame_list_list;
> #endif
> } crash_xen_info_t;
> --- arch/x86/crash.c.org 2008-04-17 14:12:51.000000000 +0900
> +++ arch/x86/crash.c 2008-04-17 14:13:13.000000000 +0900
> @@ -102,6 +102,7 @@
> hvm_disable();
>
> info = kexec_crash_save_info();
> + info->xen_phys_start = xen_phys_start;
> info->dom0_pfn_to_mfn_frame_list_list =
> arch_get_pfn_to_mfn_frame_list_list(dom0);
> }
> ================================================================
>
> === Plan B (modify the kexec-tools. proof of concept version) ===
> diff -ru kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c
> --- kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c 2008-03-21 13:16:28.000000000 +0900
> +++ kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c 2008-04-22 15:15:08.000000000 +0900
> @@ -73,6 +73,25 @@
> return -1;
> }
>
> +static int get_hypervisor_paddr(struct kexec_info *info)
> +{
> + uint64_t start;
> +
> + if (!xen_present())
> + return 0;
> +
> + if (parse_iomem_single("Hypervisor code and data\n", &start, NULL) == 0) {
> + info->hypervisor_paddr_start = start;
> +#ifdef DEBUG
> + printf("kernel load physical addr start = 0x%016Lx\n", start);
> +#endif
> + return 0;
> + }
> +
> + fprintf(stderr, "Cannot determine hypervisor physical load addr\n");
> + return -1;
> +}
> +
> /* Retrieve info regarding virtual address kernel has been compiled for and
> * size of the kernel from /proc/kcore. Current /proc/kcore parsing from
> * from kexec-tools fails because of malformed elf notes. A kernel patch has
> @@ -581,6 +600,9 @@
> if (get_kernel_paddr(info))
> return -1;
>
> + if (get_hypervisor_paddr(info))
> + return -1;
> +
> if (get_kernel_vaddr_and_size(info))
> return -1;
>
> @@ -620,6 +642,9 @@
> */
> elfcorehdr = add_buffer(info, tmp, sz, 16*1024, align, min_base,
> max_addr, -1);
> + if (info->hypervisor_paddr_start && xen_present()) {
> + *(info->hypervisor_paddr_loc) += elfcorehdr;
> + }
> if (delete_memmap(memmap_p, elfcorehdr, sz) < 0)
> return -1;
> cmdline_add_memmap(mod_cmdline, memmap_p);
> diff -ru kexec-tools-testing-20080324.org/kexec/crashdump.c kexec-tools-testing-20080324/kexec/crashdump.c
> --- kexec-tools-testing-20080324.org/kexec/crashdump.c 2008-03-21 13:16:28.000000000 +0900
> +++ kexec-tools-testing-20080324/kexec/crashdump.c 2008-04-22 15:33:47.000000000 +0900
> @@ -36,8 +36,10 @@
> #define FUNC crash_create_elf64_headers
> #define EHDR Elf64_Ehdr
> #define PHDR Elf64_Phdr
> +#define NHDR Elf64_Nhdr
> #include "crashdump-elf.c"
> #undef ELF_WIDTH
> +#undef NHDR
> #undef PHDR
> #undef EHDR
> #undef FUNC
> @@ -46,8 +48,10 @@
> #define FUNC crash_create_elf32_headers
> #define EHDR Elf32_Ehdr
> #define PHDR Elf32_Phdr
> +#define NHDR Elf32_Nhdr
> #include "crashdump-elf.c"
> #undef ELF_WIDTH
> +#undef NHDR
> #undef PHDR
> #undef EHDR
> #undef FUNC
> diff -ru kexec-tools-testing-20080324.org/kexec/crashdump-elf.c kexec-tools-testing-20080324/kexec/crashdump-elf.c
> --- kexec-tools-testing-20080324.org/kexec/crashdump-elf.c 2008-01-11 12:13:48.000000000 +0900
> +++ kexec-tools-testing-20080324/kexec/crashdump-elf.c 2008-04-22 15:35:16.000000000 +0900
> @@ -1,6 +1,6 @@
>
> -#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR)
> -#error FUNC, EHDR and PHDR must be defined
> +#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR) || !defined(NHDR)
> +#error FUNC, EHDR, PHDR and NHDR must be defined
> #endif
>
> #if (ELF_WIDTH == 64)
> @@ -37,6 +37,7 @@
> uint64_t vmcoreinfo_addr, vmcoreinfo_len;
> int has_vmcoreinfo = 0;
> int (*get_note_info)(int cpu, uint64_t *addr, uint64_t *len);
> + int has_hypervisor_paddr_start = 0;
>
> if (xen_present())
> nr_cpus = xen_get_nr_phys_cpus();
> @@ -78,6 +79,11 @@
> sz += sizeof(PHDR);
> }
>
> + if (info->hypervisor_paddr_start && xen_present()) {
> + sz += sizeof(PHDR) + sizeof(NHDR) + 4 + sizeof(unsigned long);
> + has_hypervisor_paddr_start = 1;
> + }
> +
> /*
> * Make sure the ELF core header is aligned to at least 1024.
> * We do this because the secondary kernel gets the ELF core
> @@ -168,6 +174,22 @@
> dbgprintf_phdr("vmcoreinfo header", phdr);
> }
>
> + if (has_hypervisor_paddr_start) {
> + phdr = (PHDR *) bufp;
> + bufp += sizeof(PHDR);
> + phdr->p_type = PT_NOTE;
> + phdr->p_flags = 0;
> + phdr->p_offset = phdr->p_paddr = 0;
> + phdr->p_vaddr = 0;
> + phdr->p_filesz = phdr->p_memsz = sizeof(NHDR) + 4 + sizeof(unsigned long);
> + phdr->p_align = 0;
> +
> + (elf->e_phnum)++;
> + dbgprintf_phdr("hypervisor phys addr header", phdr);
> +
> + info->hypervisor_paddr_loc = (unsigned long *)&phdr->p_offset;
> + }
> +
> /* Setup an PT_LOAD type program header for the region where
> * Kernel is mapped if info->kern_size is non-zero.
> */
> @@ -225,6 +247,24 @@
> (elf->e_phnum)++;
> dbgprintf_phdr("Elf header", phdr);
> }
> +
> + if (has_hypervisor_paddr_start) {
> + NHDR *nhdr;
> + unsigned int offset = (void *)bufp - *buf;
> +
> + nhdr = (NHDR *) bufp;
> + bufp += sizeof(NHDR);
> + nhdr->n_namesz = 4;
> + nhdr->n_descsz = sizeof(unsigned long);
> + nhdr->n_type = 0x1000003;
> + memcpy(bufp, "Xen", 4);
> + bufp += 4;
> + *((unsigned long *)bufp) = info->hypervisor_paddr_start;
> + bufp += sizeof(unsigned long);
> +
> + *(info->hypervisor_paddr_loc) = offset;
> + }
> +
> return 0;
> }
>
> diff -ru kexec-tools-testing-20080324.org/kexec/kexec.h kexec-tools-testing-20080324/kexec/kexec.h
> --- kexec-tools-testing-20080324.org/kexec/kexec.h 2008-03-21 13:16:28.000000000 +0900
> +++ kexec-tools-testing-20080324/kexec/kexec.h 2008-04-22 15:08:57.000000000 +0900
> @@ -123,6 +123,8 @@
> unsigned long kern_vaddr_start;
> unsigned long kern_paddr_start;
> unsigned long kern_size;
> + unsigned long hypervisor_paddr_start;
> + unsigned long *hypervisor_paddr_loc;
> };
>
> void usage(void);
> ======================================================================================
> --
> Itsuro ODA <oda@valinux.co.jp>
>
>
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec
--
宝曼 西門 (ホウマン・サイモン) | Simon Horman (Horms)
[-- Attachment #2: Type: text/plain, Size: 143 bytes --]
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: handle x86_64 xen code/data relocation
@ 2008-05-20 3:58 ` Simon Horman
0 siblings, 0 replies; 14+ messages in thread
From: Simon Horman @ 2008-05-20 3:58 UTC (permalink / raw)
To: Itsuro ODA; +Cc: xen-devel, kexec, crash-utility
On Tue, Apr 22, 2008 at 05:32:03PM +0900, Itsuro ODA wrote:
> Hi all,
>
> Recent version of xen (ex. RHEL5.2, 3.2.0) on the x86_64
> moves the physical(machine) address of xen code/data area after
> the system started up. The start address of this is stored in
> 'xen_phys_start'. Thus to get a machine address of a xen text symbol
> from its virtual address, calculate
> "va - __XEN_VIRT_START + xen_phys_start".
>
> crash and makedumpfile command need the value of xen_phys_start.
> They know the virtual address of 'xen_phys_start' symbol but
> no way to extract the value of xen_phys_start.
>
> I think adding the xen_phys_start value to the CRASHINFO ElfNote
> section at first. (Plan A: patch for xen hypervisor code attaced)
> It is smallest modification necessary over all.
>
> On the other hand there is a opinion that it is better to upgrade
> a user-package than a hypervisor or kernel package.
> The xen_phys_start value can be got from /proc/iomem.
> -------------------------------------------------------
> # cat /proc/iomem
> ...
> 7e600000-7f5fffff : Hypervisor code and data *** this line
> ...
> -------------------------------------------------------
> So the kexec-tools can handle it theoretically.
>
> The Plan B is that kexec-tools adds another ElfNote section which
> holds the xen_phys_start value. The attached patch works well
> though I am concern about it is a bit tricky.
>
> Which plan is better ? Or more good implementation ?
> Please comment.
>
> (note that crash and makedumpfile modification is same degree
> for both plan.)
Hi Oda-san,
I think that in terms of simplicity plan A is a clear
winner. That is assuming tha the changes to crash
and makedumpfile are more or less the same for both
plan A and plan B.
However, if there is a reason that it makes sense to include
the change in kexec-tools and make a fresh release, I'm happy to do so.
> === Plan A (modify the xen hypervisor. It is for RHEL5.2 but almost same for other version) ===
> --- include/xen/elfcore.h.org 2008-04-17 14:11:41.000000000 +0900
> +++ include/xen/elfcore.h 2008-04-17 14:11:57.000000000 +0900
> @@ -66,6 +66,7 @@
> unsigned long xen_compile_time;
> unsigned long tainted;
> #ifdef CONFIG_X86
> + unsigned long xen_phys_start;
> unsigned long dom0_pfn_to_mfn_frame_list_list;
> #endif
> } crash_xen_info_t;
> --- arch/x86/crash.c.org 2008-04-17 14:12:51.000000000 +0900
> +++ arch/x86/crash.c 2008-04-17 14:13:13.000000000 +0900
> @@ -102,6 +102,7 @@
> hvm_disable();
>
> info = kexec_crash_save_info();
> + info->xen_phys_start = xen_phys_start;
> info->dom0_pfn_to_mfn_frame_list_list =
> arch_get_pfn_to_mfn_frame_list_list(dom0);
> }
> ================================================================
>
> === Plan B (modify the kexec-tools. proof of concept version) ===
> diff -ru kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c
> --- kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c 2008-03-21 13:16:28.000000000 +0900
> +++ kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c 2008-04-22 15:15:08.000000000 +0900
> @@ -73,6 +73,25 @@
> return -1;
> }
>
> +static int get_hypervisor_paddr(struct kexec_info *info)
> +{
> + uint64_t start;
> +
> + if (!xen_present())
> + return 0;
> +
> + if (parse_iomem_single("Hypervisor code and data\n", &start, NULL) == 0) {
> + info->hypervisor_paddr_start = start;
> +#ifdef DEBUG
> + printf("kernel load physical addr start = 0x%016Lx\n", start);
> +#endif
> + return 0;
> + }
> +
> + fprintf(stderr, "Cannot determine hypervisor physical load addr\n");
> + return -1;
> +}
> +
> /* Retrieve info regarding virtual address kernel has been compiled for and
> * size of the kernel from /proc/kcore. Current /proc/kcore parsing from
> * from kexec-tools fails because of malformed elf notes. A kernel patch has
> @@ -581,6 +600,9 @@
> if (get_kernel_paddr(info))
> return -1;
>
> + if (get_hypervisor_paddr(info))
> + return -1;
> +
> if (get_kernel_vaddr_and_size(info))
> return -1;
>
> @@ -620,6 +642,9 @@
> */
> elfcorehdr = add_buffer(info, tmp, sz, 16*1024, align, min_base,
> max_addr, -1);
> + if (info->hypervisor_paddr_start && xen_present()) {
> + *(info->hypervisor_paddr_loc) += elfcorehdr;
> + }
> if (delete_memmap(memmap_p, elfcorehdr, sz) < 0)
> return -1;
> cmdline_add_memmap(mod_cmdline, memmap_p);
> diff -ru kexec-tools-testing-20080324.org/kexec/crashdump.c kexec-tools-testing-20080324/kexec/crashdump.c
> --- kexec-tools-testing-20080324.org/kexec/crashdump.c 2008-03-21 13:16:28.000000000 +0900
> +++ kexec-tools-testing-20080324/kexec/crashdump.c 2008-04-22 15:33:47.000000000 +0900
> @@ -36,8 +36,10 @@
> #define FUNC crash_create_elf64_headers
> #define EHDR Elf64_Ehdr
> #define PHDR Elf64_Phdr
> +#define NHDR Elf64_Nhdr
> #include "crashdump-elf.c"
> #undef ELF_WIDTH
> +#undef NHDR
> #undef PHDR
> #undef EHDR
> #undef FUNC
> @@ -46,8 +48,10 @@
> #define FUNC crash_create_elf32_headers
> #define EHDR Elf32_Ehdr
> #define PHDR Elf32_Phdr
> +#define NHDR Elf32_Nhdr
> #include "crashdump-elf.c"
> #undef ELF_WIDTH
> +#undef NHDR
> #undef PHDR
> #undef EHDR
> #undef FUNC
> diff -ru kexec-tools-testing-20080324.org/kexec/crashdump-elf.c kexec-tools-testing-20080324/kexec/crashdump-elf.c
> --- kexec-tools-testing-20080324.org/kexec/crashdump-elf.c 2008-01-11 12:13:48.000000000 +0900
> +++ kexec-tools-testing-20080324/kexec/crashdump-elf.c 2008-04-22 15:35:16.000000000 +0900
> @@ -1,6 +1,6 @@
>
> -#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR)
> -#error FUNC, EHDR and PHDR must be defined
> +#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR) || !defined(NHDR)
> +#error FUNC, EHDR, PHDR and NHDR must be defined
> #endif
>
> #if (ELF_WIDTH == 64)
> @@ -37,6 +37,7 @@
> uint64_t vmcoreinfo_addr, vmcoreinfo_len;
> int has_vmcoreinfo = 0;
> int (*get_note_info)(int cpu, uint64_t *addr, uint64_t *len);
> + int has_hypervisor_paddr_start = 0;
>
> if (xen_present())
> nr_cpus = xen_get_nr_phys_cpus();
> @@ -78,6 +79,11 @@
> sz += sizeof(PHDR);
> }
>
> + if (info->hypervisor_paddr_start && xen_present()) {
> + sz += sizeof(PHDR) + sizeof(NHDR) + 4 + sizeof(unsigned long);
> + has_hypervisor_paddr_start = 1;
> + }
> +
> /*
> * Make sure the ELF core header is aligned to at least 1024.
> * We do this because the secondary kernel gets the ELF core
> @@ -168,6 +174,22 @@
> dbgprintf_phdr("vmcoreinfo header", phdr);
> }
>
> + if (has_hypervisor_paddr_start) {
> + phdr = (PHDR *) bufp;
> + bufp += sizeof(PHDR);
> + phdr->p_type = PT_NOTE;
> + phdr->p_flags = 0;
> + phdr->p_offset = phdr->p_paddr = 0;
> + phdr->p_vaddr = 0;
> + phdr->p_filesz = phdr->p_memsz = sizeof(NHDR) + 4 + sizeof(unsigned long);
> + phdr->p_align = 0;
> +
> + (elf->e_phnum)++;
> + dbgprintf_phdr("hypervisor phys addr header", phdr);
> +
> + info->hypervisor_paddr_loc = (unsigned long *)&phdr->p_offset;
> + }
> +
> /* Setup an PT_LOAD type program header for the region where
> * Kernel is mapped if info->kern_size is non-zero.
> */
> @@ -225,6 +247,24 @@
> (elf->e_phnum)++;
> dbgprintf_phdr("Elf header", phdr);
> }
> +
> + if (has_hypervisor_paddr_start) {
> + NHDR *nhdr;
> + unsigned int offset = (void *)bufp - *buf;
> +
> + nhdr = (NHDR *) bufp;
> + bufp += sizeof(NHDR);
> + nhdr->n_namesz = 4;
> + nhdr->n_descsz = sizeof(unsigned long);
> + nhdr->n_type = 0x1000003;
> + memcpy(bufp, "Xen", 4);
> + bufp += 4;
> + *((unsigned long *)bufp) = info->hypervisor_paddr_start;
> + bufp += sizeof(unsigned long);
> +
> + *(info->hypervisor_paddr_loc) = offset;
> + }
> +
> return 0;
> }
>
> diff -ru kexec-tools-testing-20080324.org/kexec/kexec.h kexec-tools-testing-20080324/kexec/kexec.h
> --- kexec-tools-testing-20080324.org/kexec/kexec.h 2008-03-21 13:16:28.000000000 +0900
> +++ kexec-tools-testing-20080324/kexec/kexec.h 2008-04-22 15:08:57.000000000 +0900
> @@ -123,6 +123,8 @@
> unsigned long kern_vaddr_start;
> unsigned long kern_paddr_start;
> unsigned long kern_size;
> + unsigned long hypervisor_paddr_start;
> + unsigned long *hypervisor_paddr_loc;
> };
>
> void usage(void);
> ======================================================================================
> --
> Itsuro ODA <oda@valinux.co.jp>
>
>
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec
--
宝曼 西門 (ホウマン・サイモン) | Simon Horman (Horms)
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: handle x86_64 xen code/data relocation
2008-05-20 3:58 ` Simon Horman
@ 2008-05-20 4:39 ` Itsuro ODA
-1 siblings, 0 replies; 14+ messages in thread
From: Itsuro ODA @ 2008-05-20 4:39 UTC (permalink / raw)
To: kexec; +Cc: xen-devel, Simon Horman, crash-utility
[-- Attachment #1: Type: text/plain, Size: 9850 bytes --]
Hi all,
On Tue, 20 May 2008 13:58:39 +1000
Simon Horman <horms@verge.net.au> wrote:
> On Tue, Apr 22, 2008 at 05:32:03PM +0900, Itsuro ODA wrote:
> > Hi all,
> >
> > Recent version of xen (ex. RHEL5.2, 3.2.0) on the x86_64
> > moves the physical(machine) address of xen code/data area after
> > the system started up. The start address of this is stored in
> > 'xen_phys_start'. Thus to get a machine address of a xen text symbol
> > from its virtual address, calculate
> > "va - __XEN_VIRT_START + xen_phys_start".
> >
> > crash and makedumpfile command need the value of xen_phys_start.
> > They know the virtual address of 'xen_phys_start' symbol but
> > no way to extract the value of xen_phys_start.
> >
> > I think adding the xen_phys_start value to the CRASHINFO ElfNote
> > section at first. (Plan A: patch for xen hypervisor code attaced)
> > It is smallest modification necessary over all.
> >
> > On the other hand there is a opinion that it is better to upgrade
> > a user-package than a hypervisor or kernel package.
> > The xen_phys_start value can be got from /proc/iomem.
> > -------------------------------------------------------
> > # cat /proc/iomem
> > ...
> > 7e600000-7f5fffff : Hypervisor code and data *** this line
> > ...
> > -------------------------------------------------------
> > So the kexec-tools can handle it theoretically.
> >
> > The Plan B is that kexec-tools adds another ElfNote section which
> > holds the xen_phys_start value. The attached patch works well
> > though I am concern about it is a bit tricky.
> >
> > Which plan is better ? Or more good implementation ?
> > Please comment.
> >
> > (note that crash and makedumpfile modification is same degree
> > for both plan.)
>
> Hi Oda-san,
>
> I think that in terms of simplicity plan A is a clear
> winner. That is assuming tha the changes to crash
> and makedumpfile are more or less the same for both
> plan A and plan B.
The changes to crash and makedumpfile is almost same
for both plan A and plan B.
Yes, Plan A is simple.
The point under discussion is that the already released
versions of xen need to apply the fix, and from the view point
of the users for such versions they may prefer to update
the kexec-tools rather than the hypervisor.
> However, if there is a reason that it makes sense to include
> the change in kexec-tools and make a fresh release, I'm happy to do so.
Thanks.
I am concerned about the changes of the Plan B is little tricky.
So I will think that the changes become simpler or more reasonable.
Thanks.
Itsuro Oda
>
> > === Plan A (modify the xen hypervisor. It is for RHEL5.2 but almost same for other version) ===
> > --- include/xen/elfcore.h.org 2008-04-17 14:11:41.000000000 +0900
> > +++ include/xen/elfcore.h 2008-04-17 14:11:57.000000000 +0900
> > @@ -66,6 +66,7 @@
> > unsigned long xen_compile_time;
> > unsigned long tainted;
> > #ifdef CONFIG_X86
> > + unsigned long xen_phys_start;
> > unsigned long dom0_pfn_to_mfn_frame_list_list;
> > #endif
> > } crash_xen_info_t;
> > --- arch/x86/crash.c.org 2008-04-17 14:12:51.000000000 +0900
> > +++ arch/x86/crash.c 2008-04-17 14:13:13.000000000 +0900
> > @@ -102,6 +102,7 @@
> > hvm_disable();
> >
> > info = kexec_crash_save_info();
> > + info->xen_phys_start = xen_phys_start;
> > info->dom0_pfn_to_mfn_frame_list_list =
> > arch_get_pfn_to_mfn_frame_list_list(dom0);
> > }
> > ================================================================
> >
> > === Plan B (modify the kexec-tools. proof of concept version) ===
> > diff -ru kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c
> > --- kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c 2008-03-21 13:16:28.000000000 +0900
> > +++ kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c 2008-04-22 15:15:08.000000000 +0900
> > @@ -73,6 +73,25 @@
> > return -1;
> > }
> >
> > +static int get_hypervisor_paddr(struct kexec_info *info)
> > +{
> > + uint64_t start;
> > +
> > + if (!xen_present())
> > + return 0;
> > +
> > + if (parse_iomem_single("Hypervisor code and data\n", &start, NULL) == 0) {
> > + info->hypervisor_paddr_start = start;
> > +#ifdef DEBUG
> > + printf("kernel load physical addr start = 0x%016Lx\n", start);
> > +#endif
> > + return 0;
> > + }
> > +
> > + fprintf(stderr, "Cannot determine hypervisor physical load addr\n");
> > + return -1;
> > +}
> > +
> > /* Retrieve info regarding virtual address kernel has been compiled for and
> > * size of the kernel from /proc/kcore. Current /proc/kcore parsing from
> > * from kexec-tools fails because of malformed elf notes. A kernel patch has
> > @@ -581,6 +600,9 @@
> > if (get_kernel_paddr(info))
> > return -1;
> >
> > + if (get_hypervisor_paddr(info))
> > + return -1;
> > +
> > if (get_kernel_vaddr_and_size(info))
> > return -1;
> >
> > @@ -620,6 +642,9 @@
> > */
> > elfcorehdr = add_buffer(info, tmp, sz, 16*1024, align, min_base,
> > max_addr, -1);
> > + if (info->hypervisor_paddr_start && xen_present()) {
> > + *(info->hypervisor_paddr_loc) += elfcorehdr;
> > + }
> > if (delete_memmap(memmap_p, elfcorehdr, sz) < 0)
> > return -1;
> > cmdline_add_memmap(mod_cmdline, memmap_p);
> > diff -ru kexec-tools-testing-20080324.org/kexec/crashdump.c kexec-tools-testing-20080324/kexec/crashdump.c
> > --- kexec-tools-testing-20080324.org/kexec/crashdump.c 2008-03-21 13:16:28.000000000 +0900
> > +++ kexec-tools-testing-20080324/kexec/crashdump.c 2008-04-22 15:33:47.000000000 +0900
> > @@ -36,8 +36,10 @@
> > #define FUNC crash_create_elf64_headers
> > #define EHDR Elf64_Ehdr
> > #define PHDR Elf64_Phdr
> > +#define NHDR Elf64_Nhdr
> > #include "crashdump-elf.c"
> > #undef ELF_WIDTH
> > +#undef NHDR
> > #undef PHDR
> > #undef EHDR
> > #undef FUNC
> > @@ -46,8 +48,10 @@
> > #define FUNC crash_create_elf32_headers
> > #define EHDR Elf32_Ehdr
> > #define PHDR Elf32_Phdr
> > +#define NHDR Elf32_Nhdr
> > #include "crashdump-elf.c"
> > #undef ELF_WIDTH
> > +#undef NHDR
> > #undef PHDR
> > #undef EHDR
> > #undef FUNC
> > diff -ru kexec-tools-testing-20080324.org/kexec/crashdump-elf.c kexec-tools-testing-20080324/kexec/crashdump-elf.c
> > --- kexec-tools-testing-20080324.org/kexec/crashdump-elf.c 2008-01-11 12:13:48.000000000 +0900
> > +++ kexec-tools-testing-20080324/kexec/crashdump-elf.c 2008-04-22 15:35:16.000000000 +0900
> > @@ -1,6 +1,6 @@
> >
> > -#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR)
> > -#error FUNC, EHDR and PHDR must be defined
> > +#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR) || !defined(NHDR)
> > +#error FUNC, EHDR, PHDR and NHDR must be defined
> > #endif
> >
> > #if (ELF_WIDTH == 64)
> > @@ -37,6 +37,7 @@
> > uint64_t vmcoreinfo_addr, vmcoreinfo_len;
> > int has_vmcoreinfo = 0;
> > int (*get_note_info)(int cpu, uint64_t *addr, uint64_t *len);
> > + int has_hypervisor_paddr_start = 0;
> >
> > if (xen_present())
> > nr_cpus = xen_get_nr_phys_cpus();
> > @@ -78,6 +79,11 @@
> > sz += sizeof(PHDR);
> > }
> >
> > + if (info->hypervisor_paddr_start && xen_present()) {
> > + sz += sizeof(PHDR) + sizeof(NHDR) + 4 + sizeof(unsigned long);
> > + has_hypervisor_paddr_start = 1;
> > + }
> > +
> > /*
> > * Make sure the ELF core header is aligned to at least 1024.
> > * We do this because the secondary kernel gets the ELF core
> > @@ -168,6 +174,22 @@
> > dbgprintf_phdr("vmcoreinfo header", phdr);
> > }
> >
> > + if (has_hypervisor_paddr_start) {
> > + phdr = (PHDR *) bufp;
> > + bufp += sizeof(PHDR);
> > + phdr->p_type = PT_NOTE;
> > + phdr->p_flags = 0;
> > + phdr->p_offset = phdr->p_paddr = 0;
> > + phdr->p_vaddr = 0;
> > + phdr->p_filesz = phdr->p_memsz = sizeof(NHDR) + 4 + sizeof(unsigned long);
> > + phdr->p_align = 0;
> > +
> > + (elf->e_phnum)++;
> > + dbgprintf_phdr("hypervisor phys addr header", phdr);
> > +
> > + info->hypervisor_paddr_loc = (unsigned long *)&phdr->p_offset;
> > + }
> > +
> > /* Setup an PT_LOAD type program header for the region where
> > * Kernel is mapped if info->kern_size is non-zero.
> > */
> > @@ -225,6 +247,24 @@
> > (elf->e_phnum)++;
> > dbgprintf_phdr("Elf header", phdr);
> > }
> > +
> > + if (has_hypervisor_paddr_start) {
> > + NHDR *nhdr;
> > + unsigned int offset = (void *)bufp - *buf;
> > +
> > + nhdr = (NHDR *) bufp;
> > + bufp += sizeof(NHDR);
> > + nhdr->n_namesz = 4;
> > + nhdr->n_descsz = sizeof(unsigned long);
> > + nhdr->n_type = 0x1000003;
> > + memcpy(bufp, "Xen", 4);
> > + bufp += 4;
> > + *((unsigned long *)bufp) = info->hypervisor_paddr_start;
> > + bufp += sizeof(unsigned long);
> > +
> > + *(info->hypervisor_paddr_loc) = offset;
> > + }
> > +
> > return 0;
> > }
> >
> > diff -ru kexec-tools-testing-20080324.org/kexec/kexec.h kexec-tools-testing-20080324/kexec/kexec.h
> > --- kexec-tools-testing-20080324.org/kexec/kexec.h 2008-03-21 13:16:28.000000000 +0900
> > +++ kexec-tools-testing-20080324/kexec/kexec.h 2008-04-22 15:08:57.000000000 +0900
> > @@ -123,6 +123,8 @@
> > unsigned long kern_vaddr_start;
> > unsigned long kern_paddr_start;
> > unsigned long kern_size;
> > + unsigned long hypervisor_paddr_start;
> > + unsigned long *hypervisor_paddr_loc;
> > };
> >
> > void usage(void);
> > ======================================================================================
> > --
> > Itsuro ODA <oda@valinux.co.jp>
> >
> >
> > _______________________________________________
> > kexec mailing list
> > kexec@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/kexec
>
> --
> 宝曼 西門 (ホウマン・サイモン) | Simon Horman (Horms)
--
Itsuro ODA <oda@valinux.co.jp>
[-- Attachment #2: Type: text/plain, Size: 143 bytes --]
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: handle x86_64 xen code/data relocation
@ 2008-05-20 4:39 ` Itsuro ODA
0 siblings, 0 replies; 14+ messages in thread
From: Itsuro ODA @ 2008-05-20 4:39 UTC (permalink / raw)
To: kexec; +Cc: xen-devel, Simon Horman, crash-utility
Hi all,
On Tue, 20 May 2008 13:58:39 +1000
Simon Horman <horms@verge.net.au> wrote:
> On Tue, Apr 22, 2008 at 05:32:03PM +0900, Itsuro ODA wrote:
> > Hi all,
> >
> > Recent version of xen (ex. RHEL5.2, 3.2.0) on the x86_64
> > moves the physical(machine) address of xen code/data area after
> > the system started up. The start address of this is stored in
> > 'xen_phys_start'. Thus to get a machine address of a xen text symbol
> > from its virtual address, calculate
> > "va - __XEN_VIRT_START + xen_phys_start".
> >
> > crash and makedumpfile command need the value of xen_phys_start.
> > They know the virtual address of 'xen_phys_start' symbol but
> > no way to extract the value of xen_phys_start.
> >
> > I think adding the xen_phys_start value to the CRASHINFO ElfNote
> > section at first. (Plan A: patch for xen hypervisor code attaced)
> > It is smallest modification necessary over all.
> >
> > On the other hand there is a opinion that it is better to upgrade
> > a user-package than a hypervisor or kernel package.
> > The xen_phys_start value can be got from /proc/iomem.
> > -------------------------------------------------------
> > # cat /proc/iomem
> > ...
> > 7e600000-7f5fffff : Hypervisor code and data *** this line
> > ...
> > -------------------------------------------------------
> > So the kexec-tools can handle it theoretically.
> >
> > The Plan B is that kexec-tools adds another ElfNote section which
> > holds the xen_phys_start value. The attached patch works well
> > though I am concern about it is a bit tricky.
> >
> > Which plan is better ? Or more good implementation ?
> > Please comment.
> >
> > (note that crash and makedumpfile modification is same degree
> > for both plan.)
>
> Hi Oda-san,
>
> I think that in terms of simplicity plan A is a clear
> winner. That is assuming tha the changes to crash
> and makedumpfile are more or less the same for both
> plan A and plan B.
The changes to crash and makedumpfile is almost same
for both plan A and plan B.
Yes, Plan A is simple.
The point under discussion is that the already released
versions of xen need to apply the fix, and from the view point
of the users for such versions they may prefer to update
the kexec-tools rather than the hypervisor.
> However, if there is a reason that it makes sense to include
> the change in kexec-tools and make a fresh release, I'm happy to do so.
Thanks.
I am concerned about the changes of the Plan B is little tricky.
So I will think that the changes become simpler or more reasonable.
Thanks.
Itsuro Oda
>
> > === Plan A (modify the xen hypervisor. It is for RHEL5.2 but almost same for other version) ===
> > --- include/xen/elfcore.h.org 2008-04-17 14:11:41.000000000 +0900
> > +++ include/xen/elfcore.h 2008-04-17 14:11:57.000000000 +0900
> > @@ -66,6 +66,7 @@
> > unsigned long xen_compile_time;
> > unsigned long tainted;
> > #ifdef CONFIG_X86
> > + unsigned long xen_phys_start;
> > unsigned long dom0_pfn_to_mfn_frame_list_list;
> > #endif
> > } crash_xen_info_t;
> > --- arch/x86/crash.c.org 2008-04-17 14:12:51.000000000 +0900
> > +++ arch/x86/crash.c 2008-04-17 14:13:13.000000000 +0900
> > @@ -102,6 +102,7 @@
> > hvm_disable();
> >
> > info = kexec_crash_save_info();
> > + info->xen_phys_start = xen_phys_start;
> > info->dom0_pfn_to_mfn_frame_list_list =
> > arch_get_pfn_to_mfn_frame_list_list(dom0);
> > }
> > ================================================================
> >
> > === Plan B (modify the kexec-tools. proof of concept version) ===
> > diff -ru kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c
> > --- kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c 2008-03-21 13:16:28.000000000 +0900
> > +++ kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c 2008-04-22 15:15:08.000000000 +0900
> > @@ -73,6 +73,25 @@
> > return -1;
> > }
> >
> > +static int get_hypervisor_paddr(struct kexec_info *info)
> > +{
> > + uint64_t start;
> > +
> > + if (!xen_present())
> > + return 0;
> > +
> > + if (parse_iomem_single("Hypervisor code and data\n", &start, NULL) == 0) {
> > + info->hypervisor_paddr_start = start;
> > +#ifdef DEBUG
> > + printf("kernel load physical addr start = 0x%016Lx\n", start);
> > +#endif
> > + return 0;
> > + }
> > +
> > + fprintf(stderr, "Cannot determine hypervisor physical load addr\n");
> > + return -1;
> > +}
> > +
> > /* Retrieve info regarding virtual address kernel has been compiled for and
> > * size of the kernel from /proc/kcore. Current /proc/kcore parsing from
> > * from kexec-tools fails because of malformed elf notes. A kernel patch has
> > @@ -581,6 +600,9 @@
> > if (get_kernel_paddr(info))
> > return -1;
> >
> > + if (get_hypervisor_paddr(info))
> > + return -1;
> > +
> > if (get_kernel_vaddr_and_size(info))
> > return -1;
> >
> > @@ -620,6 +642,9 @@
> > */
> > elfcorehdr = add_buffer(info, tmp, sz, 16*1024, align, min_base,
> > max_addr, -1);
> > + if (info->hypervisor_paddr_start && xen_present()) {
> > + *(info->hypervisor_paddr_loc) += elfcorehdr;
> > + }
> > if (delete_memmap(memmap_p, elfcorehdr, sz) < 0)
> > return -1;
> > cmdline_add_memmap(mod_cmdline, memmap_p);
> > diff -ru kexec-tools-testing-20080324.org/kexec/crashdump.c kexec-tools-testing-20080324/kexec/crashdump.c
> > --- kexec-tools-testing-20080324.org/kexec/crashdump.c 2008-03-21 13:16:28.000000000 +0900
> > +++ kexec-tools-testing-20080324/kexec/crashdump.c 2008-04-22 15:33:47.000000000 +0900
> > @@ -36,8 +36,10 @@
> > #define FUNC crash_create_elf64_headers
> > #define EHDR Elf64_Ehdr
> > #define PHDR Elf64_Phdr
> > +#define NHDR Elf64_Nhdr
> > #include "crashdump-elf.c"
> > #undef ELF_WIDTH
> > +#undef NHDR
> > #undef PHDR
> > #undef EHDR
> > #undef FUNC
> > @@ -46,8 +48,10 @@
> > #define FUNC crash_create_elf32_headers
> > #define EHDR Elf32_Ehdr
> > #define PHDR Elf32_Phdr
> > +#define NHDR Elf32_Nhdr
> > #include "crashdump-elf.c"
> > #undef ELF_WIDTH
> > +#undef NHDR
> > #undef PHDR
> > #undef EHDR
> > #undef FUNC
> > diff -ru kexec-tools-testing-20080324.org/kexec/crashdump-elf.c kexec-tools-testing-20080324/kexec/crashdump-elf.c
> > --- kexec-tools-testing-20080324.org/kexec/crashdump-elf.c 2008-01-11 12:13:48.000000000 +0900
> > +++ kexec-tools-testing-20080324/kexec/crashdump-elf.c 2008-04-22 15:35:16.000000000 +0900
> > @@ -1,6 +1,6 @@
> >
> > -#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR)
> > -#error FUNC, EHDR and PHDR must be defined
> > +#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR) || !defined(NHDR)
> > +#error FUNC, EHDR, PHDR and NHDR must be defined
> > #endif
> >
> > #if (ELF_WIDTH == 64)
> > @@ -37,6 +37,7 @@
> > uint64_t vmcoreinfo_addr, vmcoreinfo_len;
> > int has_vmcoreinfo = 0;
> > int (*get_note_info)(int cpu, uint64_t *addr, uint64_t *len);
> > + int has_hypervisor_paddr_start = 0;
> >
> > if (xen_present())
> > nr_cpus = xen_get_nr_phys_cpus();
> > @@ -78,6 +79,11 @@
> > sz += sizeof(PHDR);
> > }
> >
> > + if (info->hypervisor_paddr_start && xen_present()) {
> > + sz += sizeof(PHDR) + sizeof(NHDR) + 4 + sizeof(unsigned long);
> > + has_hypervisor_paddr_start = 1;
> > + }
> > +
> > /*
> > * Make sure the ELF core header is aligned to at least 1024.
> > * We do this because the secondary kernel gets the ELF core
> > @@ -168,6 +174,22 @@
> > dbgprintf_phdr("vmcoreinfo header", phdr);
> > }
> >
> > + if (has_hypervisor_paddr_start) {
> > + phdr = (PHDR *) bufp;
> > + bufp += sizeof(PHDR);
> > + phdr->p_type = PT_NOTE;
> > + phdr->p_flags = 0;
> > + phdr->p_offset = phdr->p_paddr = 0;
> > + phdr->p_vaddr = 0;
> > + phdr->p_filesz = phdr->p_memsz = sizeof(NHDR) + 4 + sizeof(unsigned long);
> > + phdr->p_align = 0;
> > +
> > + (elf->e_phnum)++;
> > + dbgprintf_phdr("hypervisor phys addr header", phdr);
> > +
> > + info->hypervisor_paddr_loc = (unsigned long *)&phdr->p_offset;
> > + }
> > +
> > /* Setup an PT_LOAD type program header for the region where
> > * Kernel is mapped if info->kern_size is non-zero.
> > */
> > @@ -225,6 +247,24 @@
> > (elf->e_phnum)++;
> > dbgprintf_phdr("Elf header", phdr);
> > }
> > +
> > + if (has_hypervisor_paddr_start) {
> > + NHDR *nhdr;
> > + unsigned int offset = (void *)bufp - *buf;
> > +
> > + nhdr = (NHDR *) bufp;
> > + bufp += sizeof(NHDR);
> > + nhdr->n_namesz = 4;
> > + nhdr->n_descsz = sizeof(unsigned long);
> > + nhdr->n_type = 0x1000003;
> > + memcpy(bufp, "Xen", 4);
> > + bufp += 4;
> > + *((unsigned long *)bufp) = info->hypervisor_paddr_start;
> > + bufp += sizeof(unsigned long);
> > +
> > + *(info->hypervisor_paddr_loc) = offset;
> > + }
> > +
> > return 0;
> > }
> >
> > diff -ru kexec-tools-testing-20080324.org/kexec/kexec.h kexec-tools-testing-20080324/kexec/kexec.h
> > --- kexec-tools-testing-20080324.org/kexec/kexec.h 2008-03-21 13:16:28.000000000 +0900
> > +++ kexec-tools-testing-20080324/kexec/kexec.h 2008-04-22 15:08:57.000000000 +0900
> > @@ -123,6 +123,8 @@
> > unsigned long kern_vaddr_start;
> > unsigned long kern_paddr_start;
> > unsigned long kern_size;
> > + unsigned long hypervisor_paddr_start;
> > + unsigned long *hypervisor_paddr_loc;
> > };
> >
> > void usage(void);
> > ======================================================================================
> > --
> > Itsuro ODA <oda@valinux.co.jp>
> >
> >
> > _______________________________________________
> > kexec mailing list
> > kexec@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/kexec
>
> --
> 宝曼 西門 (ホウマン・サイモン) | Simon Horman (Horms)
--
Itsuro ODA <oda@valinux.co.jp>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: handle x86_64 xen code/data relocation
2008-05-20 4:39 ` Itsuro ODA
@ 2008-05-20 4:45 ` Simon Horman
-1 siblings, 0 replies; 14+ messages in thread
From: Simon Horman @ 2008-05-20 4:45 UTC (permalink / raw)
To: Itsuro ODA; +Cc: xen-devel, kexec, crash-utility
[-- Attachment #1: Type: text/plain, Size: 2884 bytes --]
On Tue, May 20, 2008 at 01:39:26PM +0900, Itsuro ODA wrote:
> Hi all,
>
> On Tue, 20 May 2008 13:58:39 +1000
> Simon Horman <horms@verge.net.au> wrote:
>
> > On Tue, Apr 22, 2008 at 05:32:03PM +0900, Itsuro ODA wrote:
> > > Hi all,
> > >
> > > Recent version of xen (ex. RHEL5.2, 3.2.0) on the x86_64
> > > moves the physical(machine) address of xen code/data area after
> > > the system started up. The start address of this is stored in
> > > 'xen_phys_start'. Thus to get a machine address of a xen text symbol
> > > from its virtual address, calculate
> > > "va - __XEN_VIRT_START + xen_phys_start".
> > >
> > > crash and makedumpfile command need the value of xen_phys_start.
> > > They know the virtual address of 'xen_phys_start' symbol but
> > > no way to extract the value of xen_phys_start.
> > >
> > > I think adding the xen_phys_start value to the CRASHINFO ElfNote
> > > section at first. (Plan A: patch for xen hypervisor code attaced)
> > > It is smallest modification necessary over all.
> > >
> > > On the other hand there is a opinion that it is better to upgrade
> > > a user-package than a hypervisor or kernel package.
> > > The xen_phys_start value can be got from /proc/iomem.
> > > -------------------------------------------------------
> > > # cat /proc/iomem
> > > ...
> > > 7e600000-7f5fffff : Hypervisor code and data *** this line
> > > ...
> > > -------------------------------------------------------
> > > So the kexec-tools can handle it theoretically.
> > >
> > > The Plan B is that kexec-tools adds another ElfNote section which
> > > holds the xen_phys_start value. The attached patch works well
> > > though I am concern about it is a bit tricky.
> > >
> > > Which plan is better ? Or more good implementation ?
> > > Please comment.
> > >
> > > (note that crash and makedumpfile modification is same degree
> > > for both plan.)
> >
> > Hi Oda-san,
> >
> > I think that in terms of simplicity plan A is a clear
> > winner. That is assuming tha the changes to crash
> > and makedumpfile are more or less the same for both
> > plan A and plan B.
>
> The changes to crash and makedumpfile is almost same
> for both plan A and plan B.
>
> Yes, Plan A is simple.
> The point under discussion is that the already released
> versions of xen need to apply the fix, and from the view point
> of the users for such versions they may prefer to update
> the kexec-tools rather than the hypervisor.
>
> > However, if there is a reason that it makes sense to include
> > the change in kexec-tools and make a fresh release, I'm happy to do so.
>
> Thanks.
>
> I am concerned about the changes of the Plan B is little tricky.
> So I will think that the changes become simpler or more reasonable.
Yes, i am concerned about that too.
--
宝曼 西門 (ホウマン・サイモン) | Simon Horman (Horms)
[-- Attachment #2: Type: text/plain, Size: 143 bytes --]
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: handle x86_64 xen code/data relocation
@ 2008-05-20 4:45 ` Simon Horman
0 siblings, 0 replies; 14+ messages in thread
From: Simon Horman @ 2008-05-20 4:45 UTC (permalink / raw)
To: Itsuro ODA; +Cc: xen-devel, kexec, crash-utility
On Tue, May 20, 2008 at 01:39:26PM +0900, Itsuro ODA wrote:
> Hi all,
>
> On Tue, 20 May 2008 13:58:39 +1000
> Simon Horman <horms@verge.net.au> wrote:
>
> > On Tue, Apr 22, 2008 at 05:32:03PM +0900, Itsuro ODA wrote:
> > > Hi all,
> > >
> > > Recent version of xen (ex. RHEL5.2, 3.2.0) on the x86_64
> > > moves the physical(machine) address of xen code/data area after
> > > the system started up. The start address of this is stored in
> > > 'xen_phys_start'. Thus to get a machine address of a xen text symbol
> > > from its virtual address, calculate
> > > "va - __XEN_VIRT_START + xen_phys_start".
> > >
> > > crash and makedumpfile command need the value of xen_phys_start.
> > > They know the virtual address of 'xen_phys_start' symbol but
> > > no way to extract the value of xen_phys_start.
> > >
> > > I think adding the xen_phys_start value to the CRASHINFO ElfNote
> > > section at first. (Plan A: patch for xen hypervisor code attaced)
> > > It is smallest modification necessary over all.
> > >
> > > On the other hand there is a opinion that it is better to upgrade
> > > a user-package than a hypervisor or kernel package.
> > > The xen_phys_start value can be got from /proc/iomem.
> > > -------------------------------------------------------
> > > # cat /proc/iomem
> > > ...
> > > 7e600000-7f5fffff : Hypervisor code and data *** this line
> > > ...
> > > -------------------------------------------------------
> > > So the kexec-tools can handle it theoretically.
> > >
> > > The Plan B is that kexec-tools adds another ElfNote section which
> > > holds the xen_phys_start value. The attached patch works well
> > > though I am concern about it is a bit tricky.
> > >
> > > Which plan is better ? Or more good implementation ?
> > > Please comment.
> > >
> > > (note that crash and makedumpfile modification is same degree
> > > for both plan.)
> >
> > Hi Oda-san,
> >
> > I think that in terms of simplicity plan A is a clear
> > winner. That is assuming tha the changes to crash
> > and makedumpfile are more or less the same for both
> > plan A and plan B.
>
> The changes to crash and makedumpfile is almost same
> for both plan A and plan B.
>
> Yes, Plan A is simple.
> The point under discussion is that the already released
> versions of xen need to apply the fix, and from the view point
> of the users for such versions they may prefer to update
> the kexec-tools rather than the hypervisor.
>
> > However, if there is a reason that it makes sense to include
> > the change in kexec-tools and make a fresh release, I'm happy to do so.
>
> Thanks.
>
> I am concerned about the changes of the Plan B is little tricky.
> So I will think that the changes become simpler or more reasonable.
Yes, i am concerned about that too.
--
宝曼 西門 (ホウマン・サイモン) | Simon Horman (Horms)
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Crash-utility] Re: handle x86_64 xen code/data relocation
2008-05-20 3:58 ` Simon Horman
@ 2008-05-20 12:49 ` Dave Anderson
-1 siblings, 0 replies; 14+ messages in thread
From: Dave Anderson @ 2008-05-20 12:49 UTC (permalink / raw)
To: Discussion list for crash utility usage, maintenance and development
Cc: Itsuro ODA, xen-devel, kexec
[-- Attachment #1: Type: text/plain, Size: 9422 bytes --]
Simon Horman wrote:
> On Tue, Apr 22, 2008 at 05:32:03PM +0900, Itsuro ODA wrote:
>> Hi all,
>>
>> Recent version of xen (ex. RHEL5.2, 3.2.0) on the x86_64
>> moves the physical(machine) address of xen code/data area after
>> the system started up. The start address of this is stored in
>> 'xen_phys_start'. Thus to get a machine address of a xen text symbol
>> from its virtual address, calculate
>> "va - __XEN_VIRT_START + xen_phys_start".
>>
>> crash and makedumpfile command need the value of xen_phys_start.
>> They know the virtual address of 'xen_phys_start' symbol but
>> no way to extract the value of xen_phys_start.
>>
>> I think adding the xen_phys_start value to the CRASHINFO ElfNote
>> section at first. (Plan A: patch for xen hypervisor code attaced)
>> It is smallest modification necessary over all.
>>
>> On the other hand there is a opinion that it is better to upgrade
>> a user-package than a hypervisor or kernel package.
>> The xen_phys_start value can be got from /proc/iomem.
>> -------------------------------------------------------
>> # cat /proc/iomem
>> ...
>> 7e600000-7f5fffff : Hypervisor code and data *** this line
>> ...
>> -------------------------------------------------------
>> So the kexec-tools can handle it theoretically.
>>
>> The Plan B is that kexec-tools adds another ElfNote section which
>> holds the xen_phys_start value. The attached patch works well
>> though I am concern about it is a bit tricky.
>>
>> Which plan is better ? Or more good implementation ?
>> Please comment.
>>
>> (note that crash and makedumpfile modification is same degree
>> for both plan.)
>
> Hi Oda-san,
>
> I think that in terms of simplicity plan A is a clear
> winner. That is assuming tha the changes to crash
> and makedumpfile are more or less the same for both
> plan A and plan B.
>
> However, if there is a reason that it makes sense to include
> the change in kexec-tools and make a fresh release, I'm happy to do so.
I was the one who suggested a user-space alternative, but reconsidering it,
I also agree that plan A is preferable, primarily for simplicity's sake in
both kexec-tools (no changes) and in the crash utility (a couple lines that
have already been added in the latest version).
My original concern was the need to upgrade the hypervisor, but since that
time, we've put in a workaround for the crash utility to allow the
xen_phys_start value to be passed in as a command line argument.
Dave
>
>> === Plan A (modify the xen hypervisor. It is for RHEL5.2 but almost same for other version) ===
>> --- include/xen/elfcore.h.org 2008-04-17 14:11:41.000000000 +0900
>> +++ include/xen/elfcore.h 2008-04-17 14:11:57.000000000 +0900
>> @@ -66,6 +66,7 @@
>> unsigned long xen_compile_time;
>> unsigned long tainted;
>> #ifdef CONFIG_X86
>> + unsigned long xen_phys_start;
>> unsigned long dom0_pfn_to_mfn_frame_list_list;
>> #endif
>> } crash_xen_info_t;
>> --- arch/x86/crash.c.org 2008-04-17 14:12:51.000000000 +0900
>> +++ arch/x86/crash.c 2008-04-17 14:13:13.000000000 +0900
>> @@ -102,6 +102,7 @@
>> hvm_disable();
>>
>> info = kexec_crash_save_info();
>> + info->xen_phys_start = xen_phys_start;
>> info->dom0_pfn_to_mfn_frame_list_list =
>> arch_get_pfn_to_mfn_frame_list_list(dom0);
>> }
>> ================================================================
>>
>> === Plan B (modify the kexec-tools. proof of concept version) ===
>> diff -ru kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c
>> --- kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c 2008-03-21 13:16:28.000000000 +0900
>> +++ kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c 2008-04-22 15:15:08.000000000 +0900
>> @@ -73,6 +73,25 @@
>> return -1;
>> }
>>
>> +static int get_hypervisor_paddr(struct kexec_info *info)
>> +{
>> + uint64_t start;
>> +
>> + if (!xen_present())
>> + return 0;
>> +
>> + if (parse_iomem_single("Hypervisor code and data\n", &start, NULL) == 0) {
>> + info->hypervisor_paddr_start = start;
>> +#ifdef DEBUG
>> + printf("kernel load physical addr start = 0x%016Lx\n", start);
>> +#endif
>> + return 0;
>> + }
>> +
>> + fprintf(stderr, "Cannot determine hypervisor physical load addr\n");
>> + return -1;
>> +}
>> +
>> /* Retrieve info regarding virtual address kernel has been compiled for and
>> * size of the kernel from /proc/kcore. Current /proc/kcore parsing from
>> * from kexec-tools fails because of malformed elf notes. A kernel patch has
>> @@ -581,6 +600,9 @@
>> if (get_kernel_paddr(info))
>> return -1;
>>
>> + if (get_hypervisor_paddr(info))
>> + return -1;
>> +
>> if (get_kernel_vaddr_and_size(info))
>> return -1;
>>
>> @@ -620,6 +642,9 @@
>> */
>> elfcorehdr = add_buffer(info, tmp, sz, 16*1024, align, min_base,
>> max_addr, -1);
>> + if (info->hypervisor_paddr_start && xen_present()) {
>> + *(info->hypervisor_paddr_loc) += elfcorehdr;
>> + }
>> if (delete_memmap(memmap_p, elfcorehdr, sz) < 0)
>> return -1;
>> cmdline_add_memmap(mod_cmdline, memmap_p);
>> diff -ru kexec-tools-testing-20080324.org/kexec/crashdump.c kexec-tools-testing-20080324/kexec/crashdump.c
>> --- kexec-tools-testing-20080324.org/kexec/crashdump.c 2008-03-21 13:16:28.000000000 +0900
>> +++ kexec-tools-testing-20080324/kexec/crashdump.c 2008-04-22 15:33:47.000000000 +0900
>> @@ -36,8 +36,10 @@
>> #define FUNC crash_create_elf64_headers
>> #define EHDR Elf64_Ehdr
>> #define PHDR Elf64_Phdr
>> +#define NHDR Elf64_Nhdr
>> #include "crashdump-elf.c"
>> #undef ELF_WIDTH
>> +#undef NHDR
>> #undef PHDR
>> #undef EHDR
>> #undef FUNC
>> @@ -46,8 +48,10 @@
>> #define FUNC crash_create_elf32_headers
>> #define EHDR Elf32_Ehdr
>> #define PHDR Elf32_Phdr
>> +#define NHDR Elf32_Nhdr
>> #include "crashdump-elf.c"
>> #undef ELF_WIDTH
>> +#undef NHDR
>> #undef PHDR
>> #undef EHDR
>> #undef FUNC
>> diff -ru kexec-tools-testing-20080324.org/kexec/crashdump-elf.c kexec-tools-testing-20080324/kexec/crashdump-elf.c
>> --- kexec-tools-testing-20080324.org/kexec/crashdump-elf.c 2008-01-11 12:13:48.000000000 +0900
>> +++ kexec-tools-testing-20080324/kexec/crashdump-elf.c 2008-04-22 15:35:16.000000000 +0900
>> @@ -1,6 +1,6 @@
>>
>> -#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR)
>> -#error FUNC, EHDR and PHDR must be defined
>> +#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR) || !defined(NHDR)
>> +#error FUNC, EHDR, PHDR and NHDR must be defined
>> #endif
>>
>> #if (ELF_WIDTH == 64)
>> @@ -37,6 +37,7 @@
>> uint64_t vmcoreinfo_addr, vmcoreinfo_len;
>> int has_vmcoreinfo = 0;
>> int (*get_note_info)(int cpu, uint64_t *addr, uint64_t *len);
>> + int has_hypervisor_paddr_start = 0;
>>
>> if (xen_present())
>> nr_cpus = xen_get_nr_phys_cpus();
>> @@ -78,6 +79,11 @@
>> sz += sizeof(PHDR);
>> }
>>
>> + if (info->hypervisor_paddr_start && xen_present()) {
>> + sz += sizeof(PHDR) + sizeof(NHDR) + 4 + sizeof(unsigned long);
>> + has_hypervisor_paddr_start = 1;
>> + }
>> +
>> /*
>> * Make sure the ELF core header is aligned to at least 1024.
>> * We do this because the secondary kernel gets the ELF core
>> @@ -168,6 +174,22 @@
>> dbgprintf_phdr("vmcoreinfo header", phdr);
>> }
>>
>> + if (has_hypervisor_paddr_start) {
>> + phdr = (PHDR *) bufp;
>> + bufp += sizeof(PHDR);
>> + phdr->p_type = PT_NOTE;
>> + phdr->p_flags = 0;
>> + phdr->p_offset = phdr->p_paddr = 0;
>> + phdr->p_vaddr = 0;
>> + phdr->p_filesz = phdr->p_memsz = sizeof(NHDR) + 4 + sizeof(unsigned long);
>> + phdr->p_align = 0;
>> +
>> + (elf->e_phnum)++;
>> + dbgprintf_phdr("hypervisor phys addr header", phdr);
>> +
>> + info->hypervisor_paddr_loc = (unsigned long *)&phdr->p_offset;
>> + }
>> +
>> /* Setup an PT_LOAD type program header for the region where
>> * Kernel is mapped if info->kern_size is non-zero.
>> */
>> @@ -225,6 +247,24 @@
>> (elf->e_phnum)++;
>> dbgprintf_phdr("Elf header", phdr);
>> }
>> +
>> + if (has_hypervisor_paddr_start) {
>> + NHDR *nhdr;
>> + unsigned int offset = (void *)bufp - *buf;
>> +
>> + nhdr = (NHDR *) bufp;
>> + bufp += sizeof(NHDR);
>> + nhdr->n_namesz = 4;
>> + nhdr->n_descsz = sizeof(unsigned long);
>> + nhdr->n_type = 0x1000003;
>> + memcpy(bufp, "Xen", 4);
>> + bufp += 4;
>> + *((unsigned long *)bufp) = info->hypervisor_paddr_start;
>> + bufp += sizeof(unsigned long);
>> +
>> + *(info->hypervisor_paddr_loc) = offset;
>> + }
>> +
>> return 0;
>> }
>>
>> diff -ru kexec-tools-testing-20080324.org/kexec/kexec.h kexec-tools-testing-20080324/kexec/kexec.h
>> --- kexec-tools-testing-20080324.org/kexec/kexec.h 2008-03-21 13:16:28.000000000 +0900
>> +++ kexec-tools-testing-20080324/kexec/kexec.h 2008-04-22 15:08:57.000000000 +0900
>> @@ -123,6 +123,8 @@
>> unsigned long kern_vaddr_start;
>> unsigned long kern_paddr_start;
>> unsigned long kern_size;
>> + unsigned long hypervisor_paddr_start;
>> + unsigned long *hypervisor_paddr_loc;
>> };
>>
>> void usage(void);
>> ======================================================================================
>> --
>> Itsuro ODA <oda@valinux.co.jp>
>>
>>
>> _______________________________________________
>> kexec mailing list
>> kexec@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec
>
[-- Attachment #2: Type: text/plain, Size: 143 bytes --]
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Re: handle x86_64 xen code/data relocation
@ 2008-05-20 12:49 ` Dave Anderson
0 siblings, 0 replies; 14+ messages in thread
From: Dave Anderson @ 2008-05-20 12:49 UTC (permalink / raw)
To: Discussion list for crash utility usage, maintenance and development
Cc: xen-devel, kexec
Simon Horman wrote:
> On Tue, Apr 22, 2008 at 05:32:03PM +0900, Itsuro ODA wrote:
>> Hi all,
>>
>> Recent version of xen (ex. RHEL5.2, 3.2.0) on the x86_64
>> moves the physical(machine) address of xen code/data area after
>> the system started up. The start address of this is stored in
>> 'xen_phys_start'. Thus to get a machine address of a xen text symbol
>> from its virtual address, calculate
>> "va - __XEN_VIRT_START + xen_phys_start".
>>
>> crash and makedumpfile command need the value of xen_phys_start.
>> They know the virtual address of 'xen_phys_start' symbol but
>> no way to extract the value of xen_phys_start.
>>
>> I think adding the xen_phys_start value to the CRASHINFO ElfNote
>> section at first. (Plan A: patch for xen hypervisor code attaced)
>> It is smallest modification necessary over all.
>>
>> On the other hand there is a opinion that it is better to upgrade
>> a user-package than a hypervisor or kernel package.
>> The xen_phys_start value can be got from /proc/iomem.
>> -------------------------------------------------------
>> # cat /proc/iomem
>> ...
>> 7e600000-7f5fffff : Hypervisor code and data *** this line
>> ...
>> -------------------------------------------------------
>> So the kexec-tools can handle it theoretically.
>>
>> The Plan B is that kexec-tools adds another ElfNote section which
>> holds the xen_phys_start value. The attached patch works well
>> though I am concern about it is a bit tricky.
>>
>> Which plan is better ? Or more good implementation ?
>> Please comment.
>>
>> (note that crash and makedumpfile modification is same degree
>> for both plan.)
>
> Hi Oda-san,
>
> I think that in terms of simplicity plan A is a clear
> winner. That is assuming tha the changes to crash
> and makedumpfile are more or less the same for both
> plan A and plan B.
>
> However, if there is a reason that it makes sense to include
> the change in kexec-tools and make a fresh release, I'm happy to do so.
I was the one who suggested a user-space alternative, but reconsidering it,
I also agree that plan A is preferable, primarily for simplicity's sake in
both kexec-tools (no changes) and in the crash utility (a couple lines that
have already been added in the latest version).
My original concern was the need to upgrade the hypervisor, but since that
time, we've put in a workaround for the crash utility to allow the
xen_phys_start value to be passed in as a command line argument.
Dave
>
>> === Plan A (modify the xen hypervisor. It is for RHEL5.2 but almost same for other version) ===
>> --- include/xen/elfcore.h.org 2008-04-17 14:11:41.000000000 +0900
>> +++ include/xen/elfcore.h 2008-04-17 14:11:57.000000000 +0900
>> @@ -66,6 +66,7 @@
>> unsigned long xen_compile_time;
>> unsigned long tainted;
>> #ifdef CONFIG_X86
>> + unsigned long xen_phys_start;
>> unsigned long dom0_pfn_to_mfn_frame_list_list;
>> #endif
>> } crash_xen_info_t;
>> --- arch/x86/crash.c.org 2008-04-17 14:12:51.000000000 +0900
>> +++ arch/x86/crash.c 2008-04-17 14:13:13.000000000 +0900
>> @@ -102,6 +102,7 @@
>> hvm_disable();
>>
>> info = kexec_crash_save_info();
>> + info->xen_phys_start = xen_phys_start;
>> info->dom0_pfn_to_mfn_frame_list_list =
>> arch_get_pfn_to_mfn_frame_list_list(dom0);
>> }
>> ================================================================
>>
>> === Plan B (modify the kexec-tools. proof of concept version) ===
>> diff -ru kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c
>> --- kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c 2008-03-21 13:16:28.000000000 +0900
>> +++ kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c 2008-04-22 15:15:08.000000000 +0900
>> @@ -73,6 +73,25 @@
>> return -1;
>> }
>>
>> +static int get_hypervisor_paddr(struct kexec_info *info)
>> +{
>> + uint64_t start;
>> +
>> + if (!xen_present())
>> + return 0;
>> +
>> + if (parse_iomem_single("Hypervisor code and data\n", &start, NULL) == 0) {
>> + info->hypervisor_paddr_start = start;
>> +#ifdef DEBUG
>> + printf("kernel load physical addr start = 0x%016Lx\n", start);
>> +#endif
>> + return 0;
>> + }
>> +
>> + fprintf(stderr, "Cannot determine hypervisor physical load addr\n");
>> + return -1;
>> +}
>> +
>> /* Retrieve info regarding virtual address kernel has been compiled for and
>> * size of the kernel from /proc/kcore. Current /proc/kcore parsing from
>> * from kexec-tools fails because of malformed elf notes. A kernel patch has
>> @@ -581,6 +600,9 @@
>> if (get_kernel_paddr(info))
>> return -1;
>>
>> + if (get_hypervisor_paddr(info))
>> + return -1;
>> +
>> if (get_kernel_vaddr_and_size(info))
>> return -1;
>>
>> @@ -620,6 +642,9 @@
>> */
>> elfcorehdr = add_buffer(info, tmp, sz, 16*1024, align, min_base,
>> max_addr, -1);
>> + if (info->hypervisor_paddr_start && xen_present()) {
>> + *(info->hypervisor_paddr_loc) += elfcorehdr;
>> + }
>> if (delete_memmap(memmap_p, elfcorehdr, sz) < 0)
>> return -1;
>> cmdline_add_memmap(mod_cmdline, memmap_p);
>> diff -ru kexec-tools-testing-20080324.org/kexec/crashdump.c kexec-tools-testing-20080324/kexec/crashdump.c
>> --- kexec-tools-testing-20080324.org/kexec/crashdump.c 2008-03-21 13:16:28.000000000 +0900
>> +++ kexec-tools-testing-20080324/kexec/crashdump.c 2008-04-22 15:33:47.000000000 +0900
>> @@ -36,8 +36,10 @@
>> #define FUNC crash_create_elf64_headers
>> #define EHDR Elf64_Ehdr
>> #define PHDR Elf64_Phdr
>> +#define NHDR Elf64_Nhdr
>> #include "crashdump-elf.c"
>> #undef ELF_WIDTH
>> +#undef NHDR
>> #undef PHDR
>> #undef EHDR
>> #undef FUNC
>> @@ -46,8 +48,10 @@
>> #define FUNC crash_create_elf32_headers
>> #define EHDR Elf32_Ehdr
>> #define PHDR Elf32_Phdr
>> +#define NHDR Elf32_Nhdr
>> #include "crashdump-elf.c"
>> #undef ELF_WIDTH
>> +#undef NHDR
>> #undef PHDR
>> #undef EHDR
>> #undef FUNC
>> diff -ru kexec-tools-testing-20080324.org/kexec/crashdump-elf.c kexec-tools-testing-20080324/kexec/crashdump-elf.c
>> --- kexec-tools-testing-20080324.org/kexec/crashdump-elf.c 2008-01-11 12:13:48.000000000 +0900
>> +++ kexec-tools-testing-20080324/kexec/crashdump-elf.c 2008-04-22 15:35:16.000000000 +0900
>> @@ -1,6 +1,6 @@
>>
>> -#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR)
>> -#error FUNC, EHDR and PHDR must be defined
>> +#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR) || !defined(NHDR)
>> +#error FUNC, EHDR, PHDR and NHDR must be defined
>> #endif
>>
>> #if (ELF_WIDTH == 64)
>> @@ -37,6 +37,7 @@
>> uint64_t vmcoreinfo_addr, vmcoreinfo_len;
>> int has_vmcoreinfo = 0;
>> int (*get_note_info)(int cpu, uint64_t *addr, uint64_t *len);
>> + int has_hypervisor_paddr_start = 0;
>>
>> if (xen_present())
>> nr_cpus = xen_get_nr_phys_cpus();
>> @@ -78,6 +79,11 @@
>> sz += sizeof(PHDR);
>> }
>>
>> + if (info->hypervisor_paddr_start && xen_present()) {
>> + sz += sizeof(PHDR) + sizeof(NHDR) + 4 + sizeof(unsigned long);
>> + has_hypervisor_paddr_start = 1;
>> + }
>> +
>> /*
>> * Make sure the ELF core header is aligned to at least 1024.
>> * We do this because the secondary kernel gets the ELF core
>> @@ -168,6 +174,22 @@
>> dbgprintf_phdr("vmcoreinfo header", phdr);
>> }
>>
>> + if (has_hypervisor_paddr_start) {
>> + phdr = (PHDR *) bufp;
>> + bufp += sizeof(PHDR);
>> + phdr->p_type = PT_NOTE;
>> + phdr->p_flags = 0;
>> + phdr->p_offset = phdr->p_paddr = 0;
>> + phdr->p_vaddr = 0;
>> + phdr->p_filesz = phdr->p_memsz = sizeof(NHDR) + 4 + sizeof(unsigned long);
>> + phdr->p_align = 0;
>> +
>> + (elf->e_phnum)++;
>> + dbgprintf_phdr("hypervisor phys addr header", phdr);
>> +
>> + info->hypervisor_paddr_loc = (unsigned long *)&phdr->p_offset;
>> + }
>> +
>> /* Setup an PT_LOAD type program header for the region where
>> * Kernel is mapped if info->kern_size is non-zero.
>> */
>> @@ -225,6 +247,24 @@
>> (elf->e_phnum)++;
>> dbgprintf_phdr("Elf header", phdr);
>> }
>> +
>> + if (has_hypervisor_paddr_start) {
>> + NHDR *nhdr;
>> + unsigned int offset = (void *)bufp - *buf;
>> +
>> + nhdr = (NHDR *) bufp;
>> + bufp += sizeof(NHDR);
>> + nhdr->n_namesz = 4;
>> + nhdr->n_descsz = sizeof(unsigned long);
>> + nhdr->n_type = 0x1000003;
>> + memcpy(bufp, "Xen", 4);
>> + bufp += 4;
>> + *((unsigned long *)bufp) = info->hypervisor_paddr_start;
>> + bufp += sizeof(unsigned long);
>> +
>> + *(info->hypervisor_paddr_loc) = offset;
>> + }
>> +
>> return 0;
>> }
>>
>> diff -ru kexec-tools-testing-20080324.org/kexec/kexec.h kexec-tools-testing-20080324/kexec/kexec.h
>> --- kexec-tools-testing-20080324.org/kexec/kexec.h 2008-03-21 13:16:28.000000000 +0900
>> +++ kexec-tools-testing-20080324/kexec/kexec.h 2008-04-22 15:08:57.000000000 +0900
>> @@ -123,6 +123,8 @@
>> unsigned long kern_vaddr_start;
>> unsigned long kern_paddr_start;
>> unsigned long kern_size;
>> + unsigned long hypervisor_paddr_start;
>> + unsigned long *hypervisor_paddr_loc;
>> };
>>
>> void usage(void);
>> ======================================================================================
>> --
>> Itsuro ODA <oda@valinux.co.jp>
>>
>>
>> _______________________________________________
>> kexec mailing list
>> kexec@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: handle x86_64 xen code/data relocation
2008-05-20 12:49 ` Dave Anderson
@ 2008-05-30 0:56 ` Itsuro ODA
-1 siblings, 0 replies; 14+ messages in thread
From: Itsuro ODA @ 2008-05-30 0:56 UTC (permalink / raw)
To: kexec; +Cc: xen-devel, crash-utility
Hi,
> My original concern was the need to upgrade the hypervisor, but since that
> time, we've put in a workaround for the crash utility to allow the
> xen_phys_start value to be passed in as a command line argument.
Yes. There is no problem for us to analyze a dump. I think the makedumpfile
utility can have a workaround too.
I like the Plan A too. So I will send a patch of Plan A to the xen-devel
mailing list.
Thanks.
Itsuro Oda
On Tue, 20 May 2008 08:49:19 -0400
Dave Anderson <anderson@redhat.com> wrote:
> Simon Horman wrote:
> > On Tue, Apr 22, 2008 at 05:32:03PM +0900, Itsuro ODA wrote:
> >> Hi all,
> >>
> >> Recent version of xen (ex. RHEL5.2, 3.2.0) on the x86_64
> >> moves the physical(machine) address of xen code/data area after
> >> the system started up. The start address of this is stored in
> >> 'xen_phys_start'. Thus to get a machine address of a xen text symbol
> >> from its virtual address, calculate
> >> "va - __XEN_VIRT_START + xen_phys_start".
> >>
> >> crash and makedumpfile command need the value of xen_phys_start.
> >> They know the virtual address of 'xen_phys_start' symbol but
> >> no way to extract the value of xen_phys_start.
> >>
> >> I think adding the xen_phys_start value to the CRASHINFO ElfNote
> >> section at first. (Plan A: patch for xen hypervisor code attaced)
> >> It is smallest modification necessary over all.
> >>
> >> On the other hand there is a opinion that it is better to upgrade
> >> a user-package than a hypervisor or kernel package.
> >> The xen_phys_start value can be got from /proc/iomem.
> >> -------------------------------------------------------
> >> # cat /proc/iomem
> >> ...
> >> 7e600000-7f5fffff : Hypervisor code and data *** this line
> >> ...
> >> -------------------------------------------------------
> >> So the kexec-tools can handle it theoretically.
> >>
> >> The Plan B is that kexec-tools adds another ElfNote section which
> >> holds the xen_phys_start value. The attached patch works well
> >> though I am concern about it is a bit tricky.
> >>
> >> Which plan is better ? Or more good implementation ?
> >> Please comment.
> >>
> >> (note that crash and makedumpfile modification is same degree
> >> for both plan.)
> >
> > Hi Oda-san,
> >
> > I think that in terms of simplicity plan A is a clear
> > winner. That is assuming tha the changes to crash
> > and makedumpfile are more or less the same for both
> > plan A and plan B.
> >
> > However, if there is a reason that it makes sense to include
> > the change in kexec-tools and make a fresh release, I'm happy to do so.
>
> I was the one who suggested a user-space alternative, but reconsidering it,
> I also agree that plan A is preferable, primarily for simplicity's sake in
> both kexec-tools (no changes) and in the crash utility (a couple lines that
> have already been added in the latest version).
>
> My original concern was the need to upgrade the hypervisor, but since that
> time, we've put in a workaround for the crash utility to allow the
> xen_phys_start value to be passed in as a command line argument.
>
> Dave
>
> >
> >> === Plan A (modify the xen hypervisor. It is for RHEL5.2 but almost same for other version) ===
> >> --- include/xen/elfcore.h.org 2008-04-17 14:11:41.000000000 +0900
> >> +++ include/xen/elfcore.h 2008-04-17 14:11:57.000000000 +0900
> >> @@ -66,6 +66,7 @@
> >> unsigned long xen_compile_time;
> >> unsigned long tainted;
> >> #ifdef CONFIG_X86
> >> + unsigned long xen_phys_start;
> >> unsigned long dom0_pfn_to_mfn_frame_list_list;
> >> #endif
> >> } crash_xen_info_t;
> >> --- arch/x86/crash.c.org 2008-04-17 14:12:51.000000000 +0900
> >> +++ arch/x86/crash.c 2008-04-17 14:13:13.000000000 +0900
> >> @@ -102,6 +102,7 @@
> >> hvm_disable();
> >>
> >> info = kexec_crash_save_info();
> >> + info->xen_phys_start = xen_phys_start;
> >> info->dom0_pfn_to_mfn_frame_list_list =
> >> arch_get_pfn_to_mfn_frame_list_list(dom0);
> >> }
> >> ================================================================
> >>
> >> === Plan B (modify the kexec-tools. proof of concept version) ===
> >> diff -ru kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c
> >> --- kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c 2008-03-21 13:16:28.000000000 +0900
> >> +++ kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c 2008-04-22 15:15:08.000000000 +0900
> >> @@ -73,6 +73,25 @@
> >> return -1;
> >> }
> >>
> >> +static int get_hypervisor_paddr(struct kexec_info *info)
> >> +{
> >> + uint64_t start;
> >> +
> >> + if (!xen_present())
> >> + return 0;
> >> +
> >> + if (parse_iomem_single("Hypervisor code and data\n", &start, NULL) == 0) {
> >> + info->hypervisor_paddr_start = start;
> >> +#ifdef DEBUG
> >> + printf("kernel load physical addr start = 0x%016Lx\n", start);
> >> +#endif
> >> + return 0;
> >> + }
> >> +
> >> + fprintf(stderr, "Cannot determine hypervisor physical load addr\n");
> >> + return -1;
> >> +}
> >> +
> >> /* Retrieve info regarding virtual address kernel has been compiled for and
> >> * size of the kernel from /proc/kcore. Current /proc/kcore parsing from
> >> * from kexec-tools fails because of malformed elf notes. A kernel patch has
> >> @@ -581,6 +600,9 @@
> >> if (get_kernel_paddr(info))
> >> return -1;
> >>
> >> + if (get_hypervisor_paddr(info))
> >> + return -1;
> >> +
> >> if (get_kernel_vaddr_and_size(info))
> >> return -1;
> >>
> >> @@ -620,6 +642,9 @@
> >> */
> >> elfcorehdr = add_buffer(info, tmp, sz, 16*1024, align, min_base,
> >> max_addr, -1);
> >> + if (info->hypervisor_paddr_start && xen_present()) {
> >> + *(info->hypervisor_paddr_loc) += elfcorehdr;
> >> + }
> >> if (delete_memmap(memmap_p, elfcorehdr, sz) < 0)
> >> return -1;
> >> cmdline_add_memmap(mod_cmdline, memmap_p);
> >> diff -ru kexec-tools-testing-20080324.org/kexec/crashdump.c kexec-tools-testing-20080324/kexec/crashdump.c
> >> --- kexec-tools-testing-20080324.org/kexec/crashdump.c 2008-03-21 13:16:28.000000000 +0900
> >> +++ kexec-tools-testing-20080324/kexec/crashdump.c 2008-04-22 15:33:47.000000000 +0900
> >> @@ -36,8 +36,10 @@
> >> #define FUNC crash_create_elf64_headers
> >> #define EHDR Elf64_Ehdr
> >> #define PHDR Elf64_Phdr
> >> +#define NHDR Elf64_Nhdr
> >> #include "crashdump-elf.c"
> >> #undef ELF_WIDTH
> >> +#undef NHDR
> >> #undef PHDR
> >> #undef EHDR
> >> #undef FUNC
> >> @@ -46,8 +48,10 @@
> >> #define FUNC crash_create_elf32_headers
> >> #define EHDR Elf32_Ehdr
> >> #define PHDR Elf32_Phdr
> >> +#define NHDR Elf32_Nhdr
> >> #include "crashdump-elf.c"
> >> #undef ELF_WIDTH
> >> +#undef NHDR
> >> #undef PHDR
> >> #undef EHDR
> >> #undef FUNC
> >> diff -ru kexec-tools-testing-20080324.org/kexec/crashdump-elf.c kexec-tools-testing-20080324/kexec/crashdump-elf.c
> >> --- kexec-tools-testing-20080324.org/kexec/crashdump-elf.c 2008-01-11 12:13:48.000000000 +0900
> >> +++ kexec-tools-testing-20080324/kexec/crashdump-elf.c 2008-04-22 15:35:16.000000000 +0900
> >> @@ -1,6 +1,6 @@
> >>
> >> -#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR)
> >> -#error FUNC, EHDR and PHDR must be defined
> >> +#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR) || !defined(NHDR)
> >> +#error FUNC, EHDR, PHDR and NHDR must be defined
> >> #endif
> >>
> >> #if (ELF_WIDTH == 64)
> >> @@ -37,6 +37,7 @@
> >> uint64_t vmcoreinfo_addr, vmcoreinfo_len;
> >> int has_vmcoreinfo = 0;
> >> int (*get_note_info)(int cpu, uint64_t *addr, uint64_t *len);
> >> + int has_hypervisor_paddr_start = 0;
> >>
> >> if (xen_present())
> >> nr_cpus = xen_get_nr_phys_cpus();
> >> @@ -78,6 +79,11 @@
> >> sz += sizeof(PHDR);
> >> }
> >>
> >> + if (info->hypervisor_paddr_start && xen_present()) {
> >> + sz += sizeof(PHDR) + sizeof(NHDR) + 4 + sizeof(unsigned long);
> >> + has_hypervisor_paddr_start = 1;
> >> + }
> >> +
> >> /*
> >> * Make sure the ELF core header is aligned to at least 1024.
> >> * We do this because the secondary kernel gets the ELF core
> >> @@ -168,6 +174,22 @@
> >> dbgprintf_phdr("vmcoreinfo header", phdr);
> >> }
> >>
> >> + if (has_hypervisor_paddr_start) {
> >> + phdr = (PHDR *) bufp;
> >> + bufp += sizeof(PHDR);
> >> + phdr->p_type = PT_NOTE;
> >> + phdr->p_flags = 0;
> >> + phdr->p_offset = phdr->p_paddr = 0;
> >> + phdr->p_vaddr = 0;
> >> + phdr->p_filesz = phdr->p_memsz = sizeof(NHDR) + 4 + sizeof(unsigned long);
> >> + phdr->p_align = 0;
> >> +
> >> + (elf->e_phnum)++;
> >> + dbgprintf_phdr("hypervisor phys addr header", phdr);
> >> +
> >> + info->hypervisor_paddr_loc = (unsigned long *)&phdr->p_offset;
> >> + }
> >> +
> >> /* Setup an PT_LOAD type program header for the region where
> >> * Kernel is mapped if info->kern_size is non-zero.
> >> */
> >> @@ -225,6 +247,24 @@
> >> (elf->e_phnum)++;
> >> dbgprintf_phdr("Elf header", phdr);
> >> }
> >> +
> >> + if (has_hypervisor_paddr_start) {
> >> + NHDR *nhdr;
> >> + unsigned int offset = (void *)bufp - *buf;
> >> +
> >> + nhdr = (NHDR *) bufp;
> >> + bufp += sizeof(NHDR);
> >> + nhdr->n_namesz = 4;
> >> + nhdr->n_descsz = sizeof(unsigned long);
> >> + nhdr->n_type = 0x1000003;
> >> + memcpy(bufp, "Xen", 4);
> >> + bufp += 4;
> >> + *((unsigned long *)bufp) = info->hypervisor_paddr_start;
> >> + bufp += sizeof(unsigned long);
> >> +
> >> + *(info->hypervisor_paddr_loc) = offset;
> >> + }
> >> +
> >> return 0;
> >> }
> >>
> >> diff -ru kexec-tools-testing-20080324.org/kexec/kexec.h kexec-tools-testing-20080324/kexec/kexec.h
> >> --- kexec-tools-testing-20080324.org/kexec/kexec.h 2008-03-21 13:16:28.000000000 +0900
> >> +++ kexec-tools-testing-20080324/kexec/kexec.h 2008-04-22 15:08:57.000000000 +0900
> >> @@ -123,6 +123,8 @@
> >> unsigned long kern_vaddr_start;
> >> unsigned long kern_paddr_start;
> >> unsigned long kern_size;
> >> + unsigned long hypervisor_paddr_start;
> >> + unsigned long *hypervisor_paddr_loc;
> >> };
> >>
> >> void usage(void);
> >> ======================================================================================
> >> --
> >> Itsuro ODA <oda@valinux.co.jp>
> >>
> >>
> >> _______________________________________________
> >> kexec mailing list
> >> kexec@lists.infradead.org
> >> http://lists.infradead.org/mailman/listinfo/kexec
> >
>
--
Itsuro ODA <oda@valinux.co.jp>
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: handle x86_64 xen code/data relocation
@ 2008-05-30 0:56 ` Itsuro ODA
0 siblings, 0 replies; 14+ messages in thread
From: Itsuro ODA @ 2008-05-30 0:56 UTC (permalink / raw)
To: kexec; +Cc: xen-devel, crash-utility
Hi,
> My original concern was the need to upgrade the hypervisor, but since that
> time, we've put in a workaround for the crash utility to allow the
> xen_phys_start value to be passed in as a command line argument.
Yes. There is no problem for us to analyze a dump. I think the makedumpfile
utility can have a workaround too.
I like the Plan A too. So I will send a patch of Plan A to the xen-devel
mailing list.
Thanks.
Itsuro Oda
On Tue, 20 May 2008 08:49:19 -0400
Dave Anderson <anderson@redhat.com> wrote:
> Simon Horman wrote:
> > On Tue, Apr 22, 2008 at 05:32:03PM +0900, Itsuro ODA wrote:
> >> Hi all,
> >>
> >> Recent version of xen (ex. RHEL5.2, 3.2.0) on the x86_64
> >> moves the physical(machine) address of xen code/data area after
> >> the system started up. The start address of this is stored in
> >> 'xen_phys_start'. Thus to get a machine address of a xen text symbol
> >> from its virtual address, calculate
> >> "va - __XEN_VIRT_START + xen_phys_start".
> >>
> >> crash and makedumpfile command need the value of xen_phys_start.
> >> They know the virtual address of 'xen_phys_start' symbol but
> >> no way to extract the value of xen_phys_start.
> >>
> >> I think adding the xen_phys_start value to the CRASHINFO ElfNote
> >> section at first. (Plan A: patch for xen hypervisor code attaced)
> >> It is smallest modification necessary over all.
> >>
> >> On the other hand there is a opinion that it is better to upgrade
> >> a user-package than a hypervisor or kernel package.
> >> The xen_phys_start value can be got from /proc/iomem.
> >> -------------------------------------------------------
> >> # cat /proc/iomem
> >> ...
> >> 7e600000-7f5fffff : Hypervisor code and data *** this line
> >> ...
> >> -------------------------------------------------------
> >> So the kexec-tools can handle it theoretically.
> >>
> >> The Plan B is that kexec-tools adds another ElfNote section which
> >> holds the xen_phys_start value. The attached patch works well
> >> though I am concern about it is a bit tricky.
> >>
> >> Which plan is better ? Or more good implementation ?
> >> Please comment.
> >>
> >> (note that crash and makedumpfile modification is same degree
> >> for both plan.)
> >
> > Hi Oda-san,
> >
> > I think that in terms of simplicity plan A is a clear
> > winner. That is assuming tha the changes to crash
> > and makedumpfile are more or less the same for both
> > plan A and plan B.
> >
> > However, if there is a reason that it makes sense to include
> > the change in kexec-tools and make a fresh release, I'm happy to do so.
>
> I was the one who suggested a user-space alternative, but reconsidering it,
> I also agree that plan A is preferable, primarily for simplicity's sake in
> both kexec-tools (no changes) and in the crash utility (a couple lines that
> have already been added in the latest version).
>
> My original concern was the need to upgrade the hypervisor, but since that
> time, we've put in a workaround for the crash utility to allow the
> xen_phys_start value to be passed in as a command line argument.
>
> Dave
>
> >
> >> === Plan A (modify the xen hypervisor. It is for RHEL5.2 but almost same for other version) ===
> >> --- include/xen/elfcore.h.org 2008-04-17 14:11:41.000000000 +0900
> >> +++ include/xen/elfcore.h 2008-04-17 14:11:57.000000000 +0900
> >> @@ -66,6 +66,7 @@
> >> unsigned long xen_compile_time;
> >> unsigned long tainted;
> >> #ifdef CONFIG_X86
> >> + unsigned long xen_phys_start;
> >> unsigned long dom0_pfn_to_mfn_frame_list_list;
> >> #endif
> >> } crash_xen_info_t;
> >> --- arch/x86/crash.c.org 2008-04-17 14:12:51.000000000 +0900
> >> +++ arch/x86/crash.c 2008-04-17 14:13:13.000000000 +0900
> >> @@ -102,6 +102,7 @@
> >> hvm_disable();
> >>
> >> info = kexec_crash_save_info();
> >> + info->xen_phys_start = xen_phys_start;
> >> info->dom0_pfn_to_mfn_frame_list_list =
> >> arch_get_pfn_to_mfn_frame_list_list(dom0);
> >> }
> >> ================================================================
> >>
> >> === Plan B (modify the kexec-tools. proof of concept version) ===
> >> diff -ru kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c
> >> --- kexec-tools-testing-20080324.org/kexec/arch/x86_64/crashdump-x86_64.c 2008-03-21 13:16:28.000000000 +0900
> >> +++ kexec-tools-testing-20080324/kexec/arch/x86_64/crashdump-x86_64.c 2008-04-22 15:15:08.000000000 +0900
> >> @@ -73,6 +73,25 @@
> >> return -1;
> >> }
> >>
> >> +static int get_hypervisor_paddr(struct kexec_info *info)
> >> +{
> >> + uint64_t start;
> >> +
> >> + if (!xen_present())
> >> + return 0;
> >> +
> >> + if (parse_iomem_single("Hypervisor code and data\n", &start, NULL) == 0) {
> >> + info->hypervisor_paddr_start = start;
> >> +#ifdef DEBUG
> >> + printf("kernel load physical addr start = 0x%016Lx\n", start);
> >> +#endif
> >> + return 0;
> >> + }
> >> +
> >> + fprintf(stderr, "Cannot determine hypervisor physical load addr\n");
> >> + return -1;
> >> +}
> >> +
> >> /* Retrieve info regarding virtual address kernel has been compiled for and
> >> * size of the kernel from /proc/kcore. Current /proc/kcore parsing from
> >> * from kexec-tools fails because of malformed elf notes. A kernel patch has
> >> @@ -581,6 +600,9 @@
> >> if (get_kernel_paddr(info))
> >> return -1;
> >>
> >> + if (get_hypervisor_paddr(info))
> >> + return -1;
> >> +
> >> if (get_kernel_vaddr_and_size(info))
> >> return -1;
> >>
> >> @@ -620,6 +642,9 @@
> >> */
> >> elfcorehdr = add_buffer(info, tmp, sz, 16*1024, align, min_base,
> >> max_addr, -1);
> >> + if (info->hypervisor_paddr_start && xen_present()) {
> >> + *(info->hypervisor_paddr_loc) += elfcorehdr;
> >> + }
> >> if (delete_memmap(memmap_p, elfcorehdr, sz) < 0)
> >> return -1;
> >> cmdline_add_memmap(mod_cmdline, memmap_p);
> >> diff -ru kexec-tools-testing-20080324.org/kexec/crashdump.c kexec-tools-testing-20080324/kexec/crashdump.c
> >> --- kexec-tools-testing-20080324.org/kexec/crashdump.c 2008-03-21 13:16:28.000000000 +0900
> >> +++ kexec-tools-testing-20080324/kexec/crashdump.c 2008-04-22 15:33:47.000000000 +0900
> >> @@ -36,8 +36,10 @@
> >> #define FUNC crash_create_elf64_headers
> >> #define EHDR Elf64_Ehdr
> >> #define PHDR Elf64_Phdr
> >> +#define NHDR Elf64_Nhdr
> >> #include "crashdump-elf.c"
> >> #undef ELF_WIDTH
> >> +#undef NHDR
> >> #undef PHDR
> >> #undef EHDR
> >> #undef FUNC
> >> @@ -46,8 +48,10 @@
> >> #define FUNC crash_create_elf32_headers
> >> #define EHDR Elf32_Ehdr
> >> #define PHDR Elf32_Phdr
> >> +#define NHDR Elf32_Nhdr
> >> #include "crashdump-elf.c"
> >> #undef ELF_WIDTH
> >> +#undef NHDR
> >> #undef PHDR
> >> #undef EHDR
> >> #undef FUNC
> >> diff -ru kexec-tools-testing-20080324.org/kexec/crashdump-elf.c kexec-tools-testing-20080324/kexec/crashdump-elf.c
> >> --- kexec-tools-testing-20080324.org/kexec/crashdump-elf.c 2008-01-11 12:13:48.000000000 +0900
> >> +++ kexec-tools-testing-20080324/kexec/crashdump-elf.c 2008-04-22 15:35:16.000000000 +0900
> >> @@ -1,6 +1,6 @@
> >>
> >> -#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR)
> >> -#error FUNC, EHDR and PHDR must be defined
> >> +#if !defined(FUNC) || !defined(EHDR) || !defined(PHDR) || !defined(NHDR)
> >> +#error FUNC, EHDR, PHDR and NHDR must be defined
> >> #endif
> >>
> >> #if (ELF_WIDTH == 64)
> >> @@ -37,6 +37,7 @@
> >> uint64_t vmcoreinfo_addr, vmcoreinfo_len;
> >> int has_vmcoreinfo = 0;
> >> int (*get_note_info)(int cpu, uint64_t *addr, uint64_t *len);
> >> + int has_hypervisor_paddr_start = 0;
> >>
> >> if (xen_present())
> >> nr_cpus = xen_get_nr_phys_cpus();
> >> @@ -78,6 +79,11 @@
> >> sz += sizeof(PHDR);
> >> }
> >>
> >> + if (info->hypervisor_paddr_start && xen_present()) {
> >> + sz += sizeof(PHDR) + sizeof(NHDR) + 4 + sizeof(unsigned long);
> >> + has_hypervisor_paddr_start = 1;
> >> + }
> >> +
> >> /*
> >> * Make sure the ELF core header is aligned to at least 1024.
> >> * We do this because the secondary kernel gets the ELF core
> >> @@ -168,6 +174,22 @@
> >> dbgprintf_phdr("vmcoreinfo header", phdr);
> >> }
> >>
> >> + if (has_hypervisor_paddr_start) {
> >> + phdr = (PHDR *) bufp;
> >> + bufp += sizeof(PHDR);
> >> + phdr->p_type = PT_NOTE;
> >> + phdr->p_flags = 0;
> >> + phdr->p_offset = phdr->p_paddr = 0;
> >> + phdr->p_vaddr = 0;
> >> + phdr->p_filesz = phdr->p_memsz = sizeof(NHDR) + 4 + sizeof(unsigned long);
> >> + phdr->p_align = 0;
> >> +
> >> + (elf->e_phnum)++;
> >> + dbgprintf_phdr("hypervisor phys addr header", phdr);
> >> +
> >> + info->hypervisor_paddr_loc = (unsigned long *)&phdr->p_offset;
> >> + }
> >> +
> >> /* Setup an PT_LOAD type program header for the region where
> >> * Kernel is mapped if info->kern_size is non-zero.
> >> */
> >> @@ -225,6 +247,24 @@
> >> (elf->e_phnum)++;
> >> dbgprintf_phdr("Elf header", phdr);
> >> }
> >> +
> >> + if (has_hypervisor_paddr_start) {
> >> + NHDR *nhdr;
> >> + unsigned int offset = (void *)bufp - *buf;
> >> +
> >> + nhdr = (NHDR *) bufp;
> >> + bufp += sizeof(NHDR);
> >> + nhdr->n_namesz = 4;
> >> + nhdr->n_descsz = sizeof(unsigned long);
> >> + nhdr->n_type = 0x1000003;
> >> + memcpy(bufp, "Xen", 4);
> >> + bufp += 4;
> >> + *((unsigned long *)bufp) = info->hypervisor_paddr_start;
> >> + bufp += sizeof(unsigned long);
> >> +
> >> + *(info->hypervisor_paddr_loc) = offset;
> >> + }
> >> +
> >> return 0;
> >> }
> >>
> >> diff -ru kexec-tools-testing-20080324.org/kexec/kexec.h kexec-tools-testing-20080324/kexec/kexec.h
> >> --- kexec-tools-testing-20080324.org/kexec/kexec.h 2008-03-21 13:16:28.000000000 +0900
> >> +++ kexec-tools-testing-20080324/kexec/kexec.h 2008-04-22 15:08:57.000000000 +0900
> >> @@ -123,6 +123,8 @@
> >> unsigned long kern_vaddr_start;
> >> unsigned long kern_paddr_start;
> >> unsigned long kern_size;
> >> + unsigned long hypervisor_paddr_start;
> >> + unsigned long *hypervisor_paddr_loc;
> >> };
> >>
> >> void usage(void);
> >> ======================================================================================
> >> --
> >> Itsuro ODA <oda@valinux.co.jp>
> >>
> >>
> >> _______________________________________________
> >> kexec mailing list
> >> kexec@lists.infradead.org
> >> http://lists.infradead.org/mailman/listinfo/kexec
> >
>
--
Itsuro ODA <oda@valinux.co.jp>
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2008-05-30 0:56 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-22 8:32 handle x86_64 xen code/data relocation Itsuro ODA
2008-04-22 8:32 ` Itsuro ODA
2008-04-22 8:53 ` [Xen-devel] " Keir Fraser
2008-04-22 8:53 ` Keir Fraser
2008-05-20 3:58 ` Simon Horman
2008-05-20 3:58 ` Simon Horman
2008-05-20 4:39 ` Itsuro ODA
2008-05-20 4:39 ` Itsuro ODA
2008-05-20 4:45 ` Simon Horman
2008-05-20 4:45 ` Simon Horman
2008-05-20 12:49 ` [Crash-utility] " Dave Anderson
2008-05-20 12:49 ` Dave Anderson
2008-05-30 0:56 ` Itsuro ODA
2008-05-30 0:56 ` Itsuro ODA
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.