public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [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