* [PATCH v2] kexec support for Linux/m68k (kernel part)
@ 2013-10-15 17:48 Geert Uytterhoeven
2013-10-15 17:48 ` [PATCH 1/3] kexec: Add debug printing of kimage table entries Geert Uytterhoeven
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Geert Uytterhoeven @ 2013-10-15 17:48 UTC (permalink / raw)
To: linux-m68k; +Cc: kexec, linux-kernel
This is a set of patches to add kexec support for m68k to the Linux kernel.
- Kexec only, no kdump support yet (do you have enough RAM to keep a
crashdump kernel in memory at all times? ;-)
- Tested on ARAnyM, with emulated 68040.
I tested the behavior for machines where memory doesn't start at zero
(e.g. Amiga) by modifying the bootinfo to make ST-RAM memory start at
0x20000000, which also works (this does require a small patch to make
atari_stram_init() succeed).
- Tested on Amiga 4000/040, where it hangs :-(
Probably this is due to lack of memory. It also crashes on ARAnyM with only
12 MiB of RAM. It seems something is corrupted when copying, although I
couldn't detect any overlapping copies using the debug code in patch 1.
- Test results on real machines with more than 16 MiB of RAM and different
CPUs would be welcome!
You can download a kexec binary from
http://users.telenet.be/geertu/Download/kexec-m68k-2013-10-15.tar.bz2
- To have automatic "kexec -e" on reboot, copy /etc/rc6.d/S85kexec from
another system, and fix it up for kexec living in /usr/local/sbin instead
of /sbin.
- Sample invocation:
kexec -d -l vmlinux --reuse-cmdline
reboot
Patches:
- [PATCH 1/3] kexec: Add debug printing of kimage table entries
- v2: new patch
- [PATCH 2/3] m68k: Add kexec support
- v2:
- KEXEC depends on M68KCLASSIC,
- Fix handling of virtual and physical addresses, for machines where
memory doesn't start at zero,
- Support for other CPUs than 68040.
- [PATCH 3/3] m68k: Add support to export bootinfo in procfs
- v2: no changes
- "m68k: Add System RAM to /proc/iomem" was dropped in v2.
Have fun!
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/3] kexec: Add debug printing of kimage table entries
2013-10-15 17:48 [PATCH v2] kexec support for Linux/m68k (kernel part) Geert Uytterhoeven
@ 2013-10-15 17:48 ` Geert Uytterhoeven
2013-10-15 17:58 ` Joe Perches
2013-10-15 19:25 ` Eric W. Biederman
2013-10-15 17:48 ` [PATCH 2/3] m68k: Add kexec support Geert Uytterhoeven
2013-10-15 17:48 ` [PATCH 3/3] m68k: Add support to export bootinfo in procfs Geert Uytterhoeven
2 siblings, 2 replies; 7+ messages in thread
From: Geert Uytterhoeven @ 2013-10-15 17:48 UTC (permalink / raw)
To: linux-m68k; +Cc: kexec, linux-kernel, Geert Uytterhoeven, Eric Biederman
Print a list of pages to be copied if debugging is enabled.
Consecutive entries are merged to reduce screen clutter.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Eric Biederman <ebiederm@xmission.com>
---
kernel/kexec.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 490afc03627e..e25022ac229e 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -1073,6 +1073,80 @@ asmlinkage long compat_sys_kexec_load(unsigned long entry,
}
#endif
+#ifdef DEBUG
+struct kimage_block {
+ unsigned long dst, src, len;
+};
+
+static void kimage_print_block(const struct kimage_block *block)
+{
+ pr_info("Copy from 0x%lx-0x%lx to 0x%lx-0x%lx (0x%lx bytes)\n",
+ block->src, block->src + block->len - 1, block->dst,
+ block->dst + block->len - 1, block->len);
+}
+
+static void kimage_print(const struct kimage *image)
+{
+ void *control_code_page;
+ const kimage_entry_t *ptr;
+ kimage_entry_t entry;
+ struct kimage_block block;
+ unsigned long dnext = KIMAGE_NO_DEST, snext = KIMAGE_NO_DEST;
+ unsigned long total = 0;
+
+ control_code_page = page_address(image->control_code_page);
+ pr_info("Control code page 0x%p (phys 0x%lx)\n",
+ control_code_page, virt_to_phys(control_code_page));
+
+ ptr = &image->head;
+ block.dst = KIMAGE_NO_DEST;
+ block.src = KIMAGE_NO_DEST;
+ block.len = 0;
+ while ((entry = *ptr)) {
+ if (entry & IND_DONE)
+ break;
+
+ if (entry & IND_DESTINATION) {
+ if (block.len > 0) {
+ kimage_print_block(&block);
+ total += block.len;
+ }
+ dnext = block.dst = entry & PAGE_MASK;
+ block.src = KIMAGE_NO_DEST;
+ block.len = 0;
+ }
+
+ if (entry & IND_SOURCE) {
+ if (!block.len) {
+ snext = block.src = entry & PAGE_MASK;
+ } else if ((entry & PAGE_MASK) != snext) {
+ kimage_print_block(&block);
+ total += block.len;
+ block.dst = dnext;
+ snext = block.src = entry & PAGE_MASK;
+ block.len = 0;
+ }
+ dnext += PAGE_SIZE;
+ snext += PAGE_SIZE;
+ block.len += PAGE_SIZE;
+ }
+
+ if (entry & IND_INDIRECTION) {
+ pr_info("Indirection page 0x%lx\n", entry & PAGE_MASK);
+ ptr = phys_to_virt(entry & PAGE_MASK);
+ } else
+ ptr++;
+ }
+ if (block.len) {
+ kimage_print_block(&block);
+ total += block.len;
+ }
+ pr_info("Total: 0x%lx/%ld bytes\n", total, total);
+}
+#else
+static inline void kimage_print(const struct kimage *image) {}
+#endif
+
void crash_kexec(struct pt_regs *regs)
{
/* Take the kexec_mutex here to prevent sys_kexec_load
@@ -1090,6 +1164,7 @@ void crash_kexec(struct pt_regs *regs)
crash_setup_regs(&fixed_regs, regs);
crash_save_vmcoreinfo();
machine_crash_shutdown(&fixed_regs);
+ kimage_print(kexec_crash_image);
machine_kexec(kexec_crash_image);
}
mutex_unlock(&kexec_mutex);
@@ -1680,6 +1755,7 @@ int kernel_kexec(void)
machine_shutdown();
}
+ kimage_print(kexec_image);
machine_kexec(kexec_image);
#ifdef CONFIG_KEXEC_JUMP
--
1.7.9.5
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/3] m68k: Add kexec support
2013-10-15 17:48 [PATCH v2] kexec support for Linux/m68k (kernel part) Geert Uytterhoeven
2013-10-15 17:48 ` [PATCH 1/3] kexec: Add debug printing of kimage table entries Geert Uytterhoeven
@ 2013-10-15 17:48 ` Geert Uytterhoeven
2013-10-15 17:48 ` [PATCH 3/3] m68k: Add support to export bootinfo in procfs Geert Uytterhoeven
2 siblings, 0 replies; 7+ messages in thread
From: Geert Uytterhoeven @ 2013-10-15 17:48 UTC (permalink / raw)
To: linux-m68k; +Cc: kexec, linux-kernel, Geert Uytterhoeven
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
v2:
- KEXEC depends on M68KCLASSIC,
- Fix handling of virtual and physical addresses, for machines where
memory doesn't start at zero,
- Support for other CPUs than 68040.
arch/m68k/Kconfig | 17 ++++
arch/m68k/include/asm/kexec.h | 29 +++++++
arch/m68k/kernel/Makefile | 2 +
arch/m68k/kernel/asm-offsets.c | 3 +
arch/m68k/kernel/machine_kexec.c | 58 ++++++++++++++
arch/m68k/kernel/relocate_kernel.S | 155 ++++++++++++++++++++++++++++++++++++
include/uapi/linux/kexec.h | 1 +
7 files changed, 265 insertions(+)
create mode 100644 arch/m68k/include/asm/kexec.h
create mode 100644 arch/m68k/kernel/machine_kexec.c
create mode 100644 arch/m68k/kernel/relocate_kernel.S
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 311a300d48cc..5d65c39bfc69 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -86,6 +86,23 @@ config MMU_SUN3
bool
depends on MMU && !MMU_MOTOROLA && !MMU_COLDFIRE
+config KEXEC
+ bool "kexec system call"
+ depends on M68KCLASSIC
+ help
+ kexec is a system call that implements the ability to shutdown your
+ current kernel, and to start another kernel. It is like a reboot
+ but it is independent of the system firmware. And like a reboot
+ you can start any kernel with it, not just Linux.
+
+ The name comes from the similarity to the exec system call.
+
+ It is an ongoing process to be certain the hardware in a machine
+ is properly shutdown, so do not be surprised if this code does not
+ initially work for you. As of this writing the exact hardware
+ interface is strongly in flux, so no good recommendation can be
+ made.
+
menu "Platform setup"
source arch/m68k/Kconfig.cpu
diff --git a/arch/m68k/include/asm/kexec.h b/arch/m68k/include/asm/kexec.h
new file mode 100644
index 000000000000..3df97abac147
--- /dev/null
+++ b/arch/m68k/include/asm/kexec.h
@@ -0,0 +1,29 @@
+#ifndef _ASM_M68K_KEXEC_H
+#define _ASM_M68K_KEXEC_H
+
+#ifdef CONFIG_KEXEC
+
+/* Maximum physical address we can use pages from */
+#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
+/* Maximum address we can reach in physical address mode */
+#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
+/* Maximum address we can use for the control code buffer */
+#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL)
+
+#define KEXEC_CONTROL_PAGE_SIZE 4096
+
+#define KEXEC_ARCH KEXEC_ARCH_68K
+
+#ifndef __ASSEMBLY__
+
+static inline void crash_setup_regs(struct pt_regs *newregs,
+ struct pt_regs *oldregs)
+{
+ /* Dummy implementation for now */
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* CONFIG_KEXEC */
+
+#endif /* _ASM_M68K_KEXEC_H */
diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile
index 655347d80780..7ee5f00a9abb 100644
--- a/arch/m68k/kernel/Makefile
+++ b/arch/m68k/kernel/Makefile
@@ -22,3 +22,5 @@ obj-$(CONFIG_PCI) += pcibios.o
obj-$(CONFIG_HAS_DMA) += dma.o
+obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
+
diff --git a/arch/m68k/kernel/asm-offsets.c b/arch/m68k/kernel/asm-offsets.c
index 8b7b22846366..3a386341aa6e 100644
--- a/arch/m68k/kernel/asm-offsets.c
+++ b/arch/m68k/kernel/asm-offsets.c
@@ -98,6 +98,9 @@ int main(void)
DEFINE(CIABBASE, &ciab);
DEFINE(C_PRA, offsetof(struct CIA, pra));
DEFINE(ZTWOBASE, zTwoBase);
+
+ /* enum m68k_fixup_type */
+ DEFINE(M68K_FIXUP_MEMOFFSET, m68k_fixup_memoffset);
#endif
return 0;
diff --git a/arch/m68k/kernel/machine_kexec.c b/arch/m68k/kernel/machine_kexec.c
new file mode 100644
index 000000000000..d4affc917d9d
--- /dev/null
+++ b/arch/m68k/kernel/machine_kexec.c
@@ -0,0 +1,58 @@
+/*
+ * machine_kexec.c - handle transition of Linux booting another kernel
+ */
+#include <linux/compiler.h>
+#include <linux/kexec.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+
+#include <asm/cacheflush.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+
+extern const unsigned char relocate_new_kernel[];
+extern const size_t relocate_new_kernel_size;
+
+int machine_kexec_prepare(struct kimage *kimage)
+{
+ return 0;
+}
+
+void machine_kexec_cleanup(struct kimage *kimage)
+{
+}
+
+void machine_shutdown(void)
+{
+}
+
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+}
+
+typedef void (*relocate_kernel_t)(unsigned long ptr,
+ unsigned long start,
+ unsigned long cpu_mmu_flags) __noreturn;
+
+void machine_kexec(struct kimage *image)
+{
+ void *reboot_code_buffer;
+ unsigned long cpu_mmu_flags;
+
+ reboot_code_buffer = page_address(image->control_code_page);
+
+ memcpy(reboot_code_buffer, relocate_new_kernel,
+ relocate_new_kernel_size);
+
+ /*
+ * we do not want to be bothered.
+ */
+ local_irq_disable();
+
+ pr_info("Will call new kernel at 0x%08lx. Bye...\n", image->start);
+ __flush_cache_all();
+ cpu_mmu_flags = m68k_cputype | m68k_mmutype << 8;
+ ((relocate_kernel_t) reboot_code_buffer)(image->head & PAGE_MASK,
+ image->start,
+ cpu_mmu_flags);
+}
diff --git a/arch/m68k/kernel/relocate_kernel.S b/arch/m68k/kernel/relocate_kernel.S
new file mode 100644
index 000000000000..3ab533b0b6bc
--- /dev/null
+++ b/arch/m68k/kernel/relocate_kernel.S
@@ -0,0 +1,155 @@
+#include <linux/linkage.h>
+
+#include <asm/asm-offsets.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+
+
+#define MMU_BASE 8 /* MMU flags base in cpu_mmu_flags */
+
+.text
+
+ENTRY(relocate_new_kernel)
+ movel %sp@(4),%a0 /* a0 = ptr */
+ movel %sp@(8),%a1 /* a1 = start */
+ movel %sp@(12),%d1 /* d1 = cpu_mmu_flags */
+ movew #PAGE_MASK,%d2 /* d2 = PAGE_MASK */
+
+ /* Disable MMU */
+
+ btst #MMU_BASE + MMUB_68851,%d1
+ jeq 3f
+
+1: /* 68851 or 68030 */
+
+ lea %pc@(.Lcopy),%a4
+2: addl #0x00000000,%a4 /* virt_to_phys() */
+
+ .section ".m68k_fixup","aw"
+ .long M68K_FIXUP_MEMOFFSET, 2b+2
+ .previous
+
+ .chip 68030
+ pmove %tc,%d0 /* Disable MMU */
+ bclr #7,%d0
+ pmove %d0,%tc
+ jmp %a4@ /* Jump to physical .Lcopy */
+ .chip 68k
+
+3:
+ btst #MMU_BASE + MMUB_68030,%d1
+ jne 1b
+
+ btst #MMU_BASE + MMUB_68040,%d1
+ jeq 6f
+
+4: /* 68040 or 68060 */
+
+ lea %pc@(.Lcont040),%a4
+5: addl #0x00000000,%a4 /* virt_to_phys() */
+
+ .section ".m68k_fixup","aw"
+ .long M68K_FIXUP_MEMOFFSET, 5b+2
+ .previous
+
+ movel %a4,%d0
+ andl #0xff000000,%d0
+ orw #0xe020,%d0 /* Map 16 MiB, enable, cacheable */
+ .chip 68040
+ movec %d0,%itt0
+ movec %d0,%dtt0
+ .chip 68k
+ jmp %a4@ /* Jump to physical .Lcont040 */
+
+.Lcont040:
+ moveq #0,%d0
+ .chip 68040
+ movec %d0,%tc /* Disable MMU */
+ .chip 68k
+ jra .Lcopy
+
+6:
+ btst #MMU_BASE + MMUB_68060,%d1
+ jne 4b
+
+.Lcopy:
+ movel %a0@+,%d0 /* d0 = entry = *ptr */
+ jeq .Lflush
+
+ btst #2,%d0 /* entry & IND_DONE? */
+ jne .Lflush
+
+ btst #1,%d0 /* entry & IND_INDIRECTION? */
+ jeq 1f
+ andw %d2,%d0
+ movel %d0,%a0 /* ptr = entry & PAGE_MASK */
+ jra .Lcopy
+
+1:
+ btst #0,%d0 /* entry & IND_DESTINATION? */
+ jeq 2f
+ andw %d2,%d0
+ movel %d0,%a2 /* a2 = dst = entry & PAGE_MASK */
+ jra .Lcopy
+
+2:
+ btst #3,%d0 /* entry & IND_SOURCE? */
+ jeq .Lcopy
+
+ andw %d2,%d0
+ movel %d0,%a3 /* a3 = src = entry & PAGE_MASK */
+ movew #PAGE_SIZE/32 - 1,%d0 /* d0 = PAGE_SIZE/32 - 1 */
+3:
+ movel %a3@+,%a2@+ /* *dst++ = *src++ */
+ movel %a3@+,%a2@+ /* *dst++ = *src++ */
+ movel %a3@+,%a2@+ /* *dst++ = *src++ */
+ movel %a3@+,%a2@+ /* *dst++ = *src++ */
+ movel %a3@+,%a2@+ /* *dst++ = *src++ */
+ movel %a3@+,%a2@+ /* *dst++ = *src++ */
+ movel %a3@+,%a2@+ /* *dst++ = *src++ */
+ movel %a3@+,%a2@+ /* *dst++ = *src++ */
+ dbf %d0, 3b
+ jra .Lcopy
+
+.Lflush:
+ /* Flush all caches */
+
+ btst #CPUB_68020,%d1
+ jeq 2f
+
+1: /* 68020 or 68030 */
+ .chip 68030
+ movec %cacr,%d0
+ orw #0x808,%d0
+ movec %d0,%cacr
+ .chip 68k
+ jra .Lreincarnate
+
+2:
+ btst #CPUB_68030,%d1
+ jne 1b
+
+ btst #CPUB_68040,%d1
+ jeq 4f
+
+3: /* 68040 or 68060 */
+ .chip 68040
+ nop
+ cpusha %bc
+ nop
+ cinva %bc
+ nop
+ .chip 68k
+ jra .Lreincarnate
+
+4:
+ btst #CPUB_68060,%d1
+ jne 3b
+
+.Lreincarnate:
+ jmp %a1@
+
+relocate_new_kernel_end:
+
+ENTRY(relocate_new_kernel_size)
+ .long relocate_new_kernel_end - relocate_new_kernel
diff --git a/include/uapi/linux/kexec.h b/include/uapi/linux/kexec.h
index 104838f65bc1..d6629d49a243 100644
--- a/include/uapi/linux/kexec.h
+++ b/include/uapi/linux/kexec.h
@@ -18,6 +18,7 @@
*/
#define KEXEC_ARCH_DEFAULT ( 0 << 16)
#define KEXEC_ARCH_386 ( 3 << 16)
+#define KEXEC_ARCH_68K ( 4 << 16)
#define KEXEC_ARCH_X86_64 (62 << 16)
#define KEXEC_ARCH_PPC (20 << 16)
#define KEXEC_ARCH_PPC64 (21 << 16)
--
1.7.9.5
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/3] m68k: Add support to export bootinfo in procfs
2013-10-15 17:48 [PATCH v2] kexec support for Linux/m68k (kernel part) Geert Uytterhoeven
2013-10-15 17:48 ` [PATCH 1/3] kexec: Add debug printing of kimage table entries Geert Uytterhoeven
2013-10-15 17:48 ` [PATCH 2/3] m68k: Add kexec support Geert Uytterhoeven
@ 2013-10-15 17:48 ` Geert Uytterhoeven
2 siblings, 0 replies; 7+ messages in thread
From: Geert Uytterhoeven @ 2013-10-15 17:48 UTC (permalink / raw)
To: linux-m68k; +Cc: kexec, linux-kernel, Geert Uytterhoeven
Add optional support to export the bootinfo used to boot the kernel in a
"bootinfo" file in procfs. This is useful with kexec.
This is based on the similar feature for ATAGS on ARM.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
arch/m68k/Kconfig | 7 ++++
arch/m68k/include/asm/bootinfo.h | 6 +++
arch/m68k/kernel/Makefile | 1 +
arch/m68k/kernel/bootinfo_proc.c | 78 ++++++++++++++++++++++++++++++++++++++
arch/m68k/kernel/setup_mm.c | 2 +
5 files changed, 94 insertions(+)
create mode 100644 arch/m68k/kernel/bootinfo_proc.c
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 5d65c39bfc69..17044432f4f4 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -103,6 +103,13 @@ config KEXEC
interface is strongly in flux, so no good recommendation can be
made.
+config BOOTINFO_PROC
+ bool "Export bootinfo in procfs"
+ depends on KEXEC && M68KCLASSIC
+ help
+ Say Y to export the bootinfo used to boot the kernel in a
+ "bootinfo" file in procfs. This is useful with kexec.
+
menu "Platform setup"
source arch/m68k/Kconfig.cpu
diff --git a/arch/m68k/include/asm/bootinfo.h b/arch/m68k/include/asm/bootinfo.h
index fd5c26707013..007c95759e6b 100644
--- a/arch/m68k/include/asm/bootinfo.h
+++ b/arch/m68k/include/asm/bootinfo.h
@@ -46,6 +46,12 @@ struct bi_record {
unsigned long data[0]; /* data */
};
+#ifdef CONFIG_BOOTINFO_PROC
+extern void save_bootinfo(const struct bi_record *bi);
+#else
+static inline void save_bootinfo(const struct bi_record *bi) {}
+#endif
+
#endif /* __ASSEMBLY__ */
diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile
index 7ee5f00a9abb..2d5d9be16273 100644
--- a/arch/m68k/kernel/Makefile
+++ b/arch/m68k/kernel/Makefile
@@ -23,4 +23,5 @@ obj-$(CONFIG_PCI) += pcibios.o
obj-$(CONFIG_HAS_DMA) += dma.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
+obj-$(CONFIG_BOOTINFO_PROC) += bootinfo_proc.o
diff --git a/arch/m68k/kernel/bootinfo_proc.c b/arch/m68k/kernel/bootinfo_proc.c
new file mode 100644
index 000000000000..a22eac1dfdd1
--- /dev/null
+++ b/arch/m68k/kernel/bootinfo_proc.c
@@ -0,0 +1,78 @@
+/*
+ * Based on arch/arm/kernel/atags_proc.c
+ */
+
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/printk.h>
+#include <linux/proc_fs.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+
+static char bootinfo_tmp[1536] __initdata;
+
+static void *bootinfo_copy;
+static size_t bootinfo_size;
+
+static ssize_t bootinfo_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ return simple_read_from_buffer(buf, count, ppos, bootinfo_copy,
+ bootinfo_size);
+}
+
+static const struct file_operations bootinfo_fops = {
+ .read = bootinfo_read,
+ .llseek = default_llseek,
+};
+
+void __init save_bootinfo(const struct bi_record *bi)
+{
+ const void *start = bi;
+ size_t size = sizeof(bi->tag);
+
+ while (bi->tag != BI_LAST) {
+ size += bi->size;
+ bi = (struct bi_record *)((unsigned long)bi + bi->size);
+ }
+
+ if (size > sizeof(bootinfo_tmp)) {
+ pr_err("Cannot save %zu bytes of bootinfo\n", size);
+ return;
+ }
+
+ pr_info("Saving %zu bytes of bootinfo\n", size);
+ memcpy(bootinfo_tmp, start, size);
+ bootinfo_size = size;
+}
+
+static int __init init_bootinfo_procfs(void)
+{
+ /*
+ * This cannot go into save_bootinfo() because kmalloc and proc don't
+ * work yet when it is called.
+ */
+ struct proc_dir_entry *pde;
+
+ if (!bootinfo_size)
+ return -EINVAL;
+
+ bootinfo_copy = kmalloc(bootinfo_size, GFP_KERNEL);
+ if (!bootinfo_copy)
+ return -ENOMEM;
+
+ memcpy(bootinfo_copy, bootinfo_tmp, bootinfo_size);
+
+ pde = proc_create_data("bootinfo", 0400, NULL, &bootinfo_fops, NULL);
+ if (!pde) {
+ kfree(bootinfo_copy);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+arch_initcall(init_bootinfo_procfs);
diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c
index 1e3e2cbd455e..cb7b0c927869 100644
--- a/arch/m68k/kernel/setup_mm.c
+++ b/arch/m68k/kernel/setup_mm.c
@@ -143,6 +143,8 @@ extern void paging_init(void);
static void __init m68k_parse_bootinfo(const struct bi_record *record)
{
+ save_bootinfo(record);
+
while (record->tag != BI_LAST) {
int unknown = 0;
const unsigned long *data = record->data;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/3] kexec: Add debug printing of kimage table entries
2013-10-15 17:48 ` [PATCH 1/3] kexec: Add debug printing of kimage table entries Geert Uytterhoeven
@ 2013-10-15 17:58 ` Joe Perches
2013-10-15 19:25 ` Eric W. Biederman
1 sibling, 0 replies; 7+ messages in thread
From: Joe Perches @ 2013-10-15 17:58 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-m68k, kexec, linux-kernel, Eric Biederman
On Tue, 2013-10-15 at 19:48 +0200, Geert Uytterhoeven wrote:
> Print a list of pages to be copied if debugging is enabled.
> Consecutive entries are merged to reduce screen clutter.
[]
> diff --git a/kernel/kexec.c b/kernel/kexec.c
[]
> +static void kimage_print_block(const struct kimage_block *block)
> +{
> + pr_info("Copy from 0x%lx-0x%lx to 0x%lx-0x%lx (0x%lx bytes)\n",
> + block->src, block->src + block->len - 1, block->dst,
> + block->dst + block->len - 1, block->len);
> +}
Perhaps pr_debug and this maybe nicer to read like:
pr_debug("kimage: Copy from 0x%lx-0x%lx to 0x%lx-0x%lx (0x%lx bytes)\n",
block->src, block->src + block->len - 1,
block->dst, block->dst + block->len - 1,
block->len);
Using a "kimage: " prefix could help grep too.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/3] kexec: Add debug printing of kimage table entries
2013-10-15 17:48 ` [PATCH 1/3] kexec: Add debug printing of kimage table entries Geert Uytterhoeven
2013-10-15 17:58 ` Joe Perches
@ 2013-10-15 19:25 ` Eric W. Biederman
2013-10-15 20:03 ` Geert Uytterhoeven
1 sibling, 1 reply; 7+ messages in thread
From: Eric W. Biederman @ 2013-10-15 19:25 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-m68k, kexec, linux-kernel
Geert Uytterhoeven <geert@linux-m68k.org> writes:
> Print a list of pages to be copied if debugging is enabled.
> Consecutive entries are merged to reduce screen clutter.
Why is this desirable?
I can understand this as debugging code to understand what is happening,
but why would we want to maintain this print statement long term?
> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
> Cc: Eric Biederman <ebiederm@xmission.com>
> ---
> kernel/kexec.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 76 insertions(+)
>
> diff --git a/kernel/kexec.c b/kernel/kexec.c
> index 490afc03627e..e25022ac229e 100644
> --- a/kernel/kexec.c
> +++ b/kernel/kexec.c
> @@ -1073,6 +1073,80 @@ asmlinkage long compat_sys_kexec_load(unsigned long entry,
> }
> #endif
>
> +#ifdef DEBUG
> +struct kimage_block {
> + unsigned long dst, src, len;
> +};
> +
> +static void kimage_print_block(const struct kimage_block *block)
> +{
> + pr_info("Copy from 0x%lx-0x%lx to 0x%lx-0x%lx (0x%lx bytes)\n",
> + block->src, block->src + block->len - 1, block->dst,
> + block->dst + block->len - 1, block->len);
> +}
> +
> +static void kimage_print(const struct kimage *image)
> +{
> + void *control_code_page;
> + const kimage_entry_t *ptr;
> + kimage_entry_t entry;
> + struct kimage_block block;
> + unsigned long dnext = KIMAGE_NO_DEST, snext = KIMAGE_NO_DEST;
> + unsigned long total = 0;
> +
> + control_code_page = page_address(image->control_code_page);
> + pr_info("Control code page 0x%p (phys 0x%lx)\n",
> + control_code_page, virt_to_phys(control_code_page));
> +
> + ptr = &image->head;
> + block.dst = KIMAGE_NO_DEST;
> + block.src = KIMAGE_NO_DEST;
> + block.len = 0;
> + while ((entry = *ptr)) {
> + if (entry & IND_DONE)
> + break;
> +
> + if (entry & IND_DESTINATION) {
> + if (block.len > 0) {
> + kimage_print_block(&block);
> + total += block.len;
> + }
> + dnext = block.dst = entry & PAGE_MASK;
> + block.src = KIMAGE_NO_DEST;
> + block.len = 0;
> + }
> +
> + if (entry & IND_SOURCE) {
> + if (!block.len) {
> + snext = block.src = entry & PAGE_MASK;
> + } else if ((entry & PAGE_MASK) != snext) {
> + kimage_print_block(&block);
> + total += block.len;
> + block.dst = dnext;
> + snext = block.src = entry & PAGE_MASK;
> + block.len = 0;
> + }
> + dnext += PAGE_SIZE;
> + snext += PAGE_SIZE;
> + block.len += PAGE_SIZE;
> + }
> +
> + if (entry & IND_INDIRECTION) {
> + pr_info("Indirection page 0x%lx\n", entry & PAGE_MASK);
> + ptr = phys_to_virt(entry & PAGE_MASK);
> + } else
> + ptr++;
> + }
> + if (block.len) {
> + kimage_print_block(&block);
> + total += block.len;
> + }
> + pr_info("Total: 0x%lx/%ld bytes\n", total, total);
> +}
> +#else
> +static inline void kimage_print(const struct kimage *image) {}
> +#endif
> +
> void crash_kexec(struct pt_regs *regs)
> {
> /* Take the kexec_mutex here to prevent sys_kexec_load
> @@ -1090,6 +1164,7 @@ void crash_kexec(struct pt_regs *regs)
> crash_setup_regs(&fixed_regs, regs);
> crash_save_vmcoreinfo();
> machine_crash_shutdown(&fixed_regs);
> + kimage_print(kexec_crash_image);
> machine_kexec(kexec_crash_image);
> }
> mutex_unlock(&kexec_mutex);
> @@ -1680,6 +1755,7 @@ int kernel_kexec(void)
> machine_shutdown();
> }
>
> + kimage_print(kexec_image);
> machine_kexec(kexec_image);
>
> #ifdef CONFIG_KEXEC_JUMP
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/3] kexec: Add debug printing of kimage table entries
2013-10-15 19:25 ` Eric W. Biederman
@ 2013-10-15 20:03 ` Geert Uytterhoeven
0 siblings, 0 replies; 7+ messages in thread
From: Geert Uytterhoeven @ 2013-10-15 20:03 UTC (permalink / raw)
To: Eric W. Biederman; +Cc: linux-m68k, kexec, linux-kernel@vger.kernel.org
On Tue, Oct 15, 2013 at 9:25 PM, Eric W. Biederman
<ebiederm@xmission.com> wrote:
> Geert Uytterhoeven <geert@linux-m68k.org> writes:
>> Print a list of pages to be copied if debugging is enabled.
>> Consecutive entries are merged to reduce screen clutter.
>
> Why is this desirable?
>
> I can understand this as debugging code to understand what is happening,
> but why would we want to maintain this print statement long term?
Because the next person who ports kexec to a new platform may need it,
so he doesn't have to reimplement the wheel?
It's disabled by default.
It also serves as documentation for the indirection page.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2013-10-15 20:04 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-15 17:48 [PATCH v2] kexec support for Linux/m68k (kernel part) Geert Uytterhoeven
2013-10-15 17:48 ` [PATCH 1/3] kexec: Add debug printing of kimage table entries Geert Uytterhoeven
2013-10-15 17:58 ` Joe Perches
2013-10-15 19:25 ` Eric W. Biederman
2013-10-15 20:03 ` Geert Uytterhoeven
2013-10-15 17:48 ` [PATCH 2/3] m68k: Add kexec support Geert Uytterhoeven
2013-10-15 17:48 ` [PATCH 3/3] m68k: Add support to export bootinfo in procfs Geert Uytterhoeven
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox