Linux-parisc archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 0/4] kexec support for PARISC
@ 2019-09-08  9:33 Sven Schnelle
  2019-09-08  9:33 ` [PATCH 1/4] parisc: add __pdc_cpu_rendezvous() Sven Schnelle
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Sven Schnelle @ 2019-09-08  9:33 UTC (permalink / raw)
  To: Helge Deller; +Cc: linux-parisc, Sven Schnelle

Hi,

this series adds support for the kexec syscalls to the PARISC architecture.
Note that kexec() on PA8800/PA8900 doesn't work yet as i haven't figured
out how to restart the CPUs on these systems.

For testing you can use my patched kexec-tools:

https://git.stackframe.org/cgit/kexec-tools/log/

I will submit these patches as soon as kexec is merged into the linux
kernel.

Thanks,
Sven

Sven Schnelle (4):
  parisc: add __pdc_cpu_rendezvous()
  parisc: add kexec syscall support
  parisc: wire up kexec_file_load syscall
  parisc: add support for kexec_file_load() syscall

 arch/parisc/Kconfig                     |  23 ++++
 arch/parisc/include/asm/fixmap.h        |   1 +
 arch/parisc/include/asm/kexec.h         |  37 ++++++
 arch/parisc/include/asm/pdc.h           |   1 +
 arch/parisc/kernel/Makefile             |   2 +
 arch/parisc/kernel/firmware.c           |  13 +++
 arch/parisc/kernel/kexec.c              | 109 +++++++++++++++++
 arch/parisc/kernel/kexec_file.c         |  86 ++++++++++++++
 arch/parisc/kernel/relocate_kernel.S    | 149 ++++++++++++++++++++++++
 arch/parisc/kernel/smp.c                |   1 +
 arch/parisc/kernel/syscalls/syscall.tbl |   3 +-
 include/uapi/linux/kexec.h              |   1 +
 12 files changed, 425 insertions(+), 1 deletion(-)
 create mode 100644 arch/parisc/include/asm/kexec.h
 create mode 100644 arch/parisc/kernel/kexec.c
 create mode 100644 arch/parisc/kernel/kexec_file.c
 create mode 100644 arch/parisc/kernel/relocate_kernel.S

-- 
2.23.0.rc1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] parisc: add __pdc_cpu_rendezvous()
  2019-09-08  9:33 [PATCH 0/4] kexec support for PARISC Sven Schnelle
@ 2019-09-08  9:33 ` Sven Schnelle
  2019-09-08  9:33 ` [PATCH 2/4] parisc: add kexec syscall support Sven Schnelle
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Sven Schnelle @ 2019-09-08  9:33 UTC (permalink / raw)
  To: Helge Deller; +Cc: linux-parisc, Sven Schnelle

When stopping SMP cpus send them into rendezvous, so we can
start them again later (when kexec'ing a new kernel).

Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
 arch/parisc/include/asm/pdc.h |  1 +
 arch/parisc/kernel/firmware.c | 13 +++++++++++++
 arch/parisc/kernel/smp.c      |  1 +
 3 files changed, 15 insertions(+)

diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h
index 19bb2e46cd36..b388d8176588 100644
--- a/arch/parisc/include/asm/pdc.h
+++ b/arch/parisc/include/asm/pdc.h
@@ -91,6 +91,7 @@ int pdc_sti_call(unsigned long func, unsigned long flags,
                  unsigned long inptr, unsigned long outputr,
                  unsigned long glob_cfg);
 
+int __pdc_cpu_rendezvous(void);
 static inline char * os_id_to_string(u16 os_id) {
 	switch(os_id) {
 	case OS_ID_NONE:	return "No OS";
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
index 58cc08e7fd12..1d976f2ebff0 100644
--- a/arch/parisc/kernel/firmware.c
+++ b/arch/parisc/kernel/firmware.c
@@ -311,6 +311,19 @@ int pdc_chassis_disp(unsigned long disp)
 	return retval;
 }
 
+/**
+ * pdc_cpu_rendenzvous - Stop currently executing CPU
+ * @retval: -1 on error, 0 on success
+ */
+int __pdc_cpu_rendezvous(void)
+{
+	if (is_pdc_pat())
+		return mem_pdc_call(PDC_PAT_CPU, PDC_PAT_CPU_RENDEZVOUS);
+	else
+		return mem_pdc_call(PDC_PROC, 1, 0);
+}
+
+
 /**
  * pdc_chassis_warn - Fetches chassis warnings
  * @retval: -1 on error, 0 on success
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index cbd074ba22da..e202c37e56af 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -109,6 +109,7 @@ halt_processor(void)
 	/* REVISIT : does PM *know* this CPU isn't available? */
 	set_cpu_online(smp_processor_id(), false);
 	local_irq_disable();
+	__pdc_cpu_rendezvous();
 	for (;;)
 		;
 }
-- 
2.23.0.rc1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/4] parisc: add kexec syscall support
  2019-09-08  9:33 [PATCH 0/4] kexec support for PARISC Sven Schnelle
  2019-09-08  9:33 ` [PATCH 1/4] parisc: add __pdc_cpu_rendezvous() Sven Schnelle
@ 2019-09-08  9:33 ` Sven Schnelle
  2019-09-08  9:33 ` [PATCH 3/4] parisc: wire up kexec_file_load syscall Sven Schnelle
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Sven Schnelle @ 2019-09-08  9:33 UTC (permalink / raw)
  To: Helge Deller; +Cc: linux-parisc, Sven Schnelle

---
 arch/parisc/Kconfig                  |  13 +++
 arch/parisc/include/asm/fixmap.h     |   1 +
 arch/parisc/include/asm/kexec.h      |  37 +++++++
 arch/parisc/kernel/Makefile          |   1 +
 arch/parisc/kernel/kexec.c           | 102 ++++++++++++++++++
 arch/parisc/kernel/relocate_kernel.S | 149 +++++++++++++++++++++++++++
 include/uapi/linux/kexec.h           |   1 +
 7 files changed, 304 insertions(+)
 create mode 100644 arch/parisc/include/asm/kexec.h
 create mode 100644 arch/parisc/kernel/kexec.c
 create mode 100644 arch/parisc/kernel/relocate_kernel.S

diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index ee59171edffe..548c767f4358 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -346,6 +346,19 @@ config NR_CPUS
 	depends on SMP
 	default "4"
 
+config KEXEC
+	bool "Kexec system call"
+	select KEXEC_CORE
+	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.
+
+	  It is an ongoing process to be certain the hardware in a machine
+	  shutdown, so do not be surprised if this code does not
+	  initially work for you.
+
 endmenu
 
 
diff --git a/arch/parisc/include/asm/fixmap.h b/arch/parisc/include/asm/fixmap.h
index 288da73d4cc0..e480b2c05407 100644
--- a/arch/parisc/include/asm/fixmap.h
+++ b/arch/parisc/include/asm/fixmap.h
@@ -30,6 +30,7 @@
 enum fixed_addresses {
 	/* Support writing RO kernel text via kprobes, jump labels, etc. */
 	FIX_TEXT_POKE0,
+	FIX_TEXT_KEXEC,
 	FIX_BITMAP_COUNT
 };
 
diff --git a/arch/parisc/include/asm/kexec.h b/arch/parisc/include/asm/kexec.h
new file mode 100644
index 000000000000..a99ea747d7ed
--- /dev/null
+++ b/arch/parisc/include/asm/kexec.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_PARISC_KEXEC_H
+#define _ASM_PARISC_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_PARISC
+#define ARCH_HAS_KIMAGE_ARCH
+
+#ifndef __ASSEMBLY__
+
+struct kimage_arch {
+	unsigned long initrd_start;
+	unsigned long initrd_end;
+	unsigned long cmdline;
+};
+
+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_PARISC_KEXEC_H */
diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile
index c232266b517c..487cf88866a8 100644
--- a/arch/parisc/kernel/Makefile
+++ b/arch/parisc/kernel/Makefile
@@ -37,3 +37,4 @@ obj-$(CONFIG_FUNCTION_GRAPH_TRACER)	+= ftrace.o
 obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
 obj-$(CONFIG_KGDB)			+= kgdb.o
 obj-$(CONFIG_KPROBES)			+= kprobes.o
+obj-$(CONFIG_KEXEC)			+= kexec.o relocate_kernel.o
diff --git a/arch/parisc/kernel/kexec.c b/arch/parisc/kernel/kexec.c
new file mode 100644
index 000000000000..deeb0466d359
--- /dev/null
+++ b/arch/parisc/kernel/kexec.c
@@ -0,0 +1,102 @@
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/kexec.h>
+#include <linux/delay.h>
+#include <asm/cacheflush.h>
+#include <asm/sections.h>
+
+extern void relocate_new_kernel(unsigned long head,
+				unsigned long start,
+				unsigned long phys);
+
+extern const unsigned int relocate_new_kernel_size;
+extern unsigned int kexec_initrd_start_offset;
+extern unsigned int kexec_initrd_end_offset;
+extern unsigned int kexec_cmdline_offset;
+extern unsigned int kexec_free_mem_offset;
+
+static void kexec_show_segment_info(const struct kimage *kimage, unsigned long n)
+{
+	pr_debug("    segment[%lu]: %016lx - %016lx, 0x%lx bytes, %lu pages\n",
+			n,
+			kimage->segment[n].mem,
+			kimage->segment[n].mem + kimage->segment[n].memsz,
+			(unsigned long)kimage->segment[n].memsz,
+			(unsigned long)kimage->segment[n].memsz /  PAGE_SIZE);
+}
+
+static void kexec_image_info(const struct kimage *kimage)
+{
+	unsigned long i;
+
+	pr_debug("kexec kimage info:\n");
+	pr_debug("  type:        %d\n", kimage->type);
+	pr_debug("  start:       %lx\n", kimage->start);
+	pr_debug("  head:        %lx\n", kimage->head);
+	pr_debug("  nr_segments: %lu\n", kimage->nr_segments);
+
+	for (i = 0; i < kimage->nr_segments; i++)
+		kexec_show_segment_info(kimage, i);
+}
+
+void machine_kexec_cleanup(struct kimage *kimage)
+{
+}
+
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+}
+
+void machine_shutdown(void)
+{
+	smp_send_stop();
+	while(num_online_cpus() > 1) {
+		cpu_relax();
+		mdelay(1);
+	}
+}
+
+void machine_kexec(struct kimage *image)
+{
+#ifdef CONFIG_64BIT
+	Elf64_Fdesc desc;
+#endif
+	void (*reloc)(unsigned long head,
+		      unsigned long start,
+		      unsigned long phys);
+
+	unsigned long phys = page_to_phys(image->control_code_page);
+	void *virt = (void *)__fix_to_virt(FIX_TEXT_KEXEC);
+	struct kimage_arch *arch = &image->arch;
+
+	set_fixmap(FIX_TEXT_KEXEC, phys);
+
+	flush_cache_all();
+
+#ifdef CONFIG_64BIT
+	reloc = (void *)&desc;
+	desc.addr = (long long)virt;
+#else
+	reloc = (void *)virt;
+#endif
+
+	memcpy(virt, dereference_function_descriptor(relocate_new_kernel),
+		relocate_new_kernel_size);
+
+	*(unsigned long *)(virt + kexec_cmdline_offset) = arch->cmdline;
+	*(unsigned long *)(virt + kexec_initrd_start_offset) = arch->initrd_start;
+	*(unsigned long *)(virt + kexec_initrd_end_offset) = arch->initrd_end;
+	*(unsigned long *)(virt + kexec_free_mem_offset) = PAGE0->mem_free;
+
+	flush_cache_all();
+	flush_tlb_all();
+	local_irq_disable();
+
+	reloc(image->head & PAGE_MASK, image->start, phys);
+}
+
+int machine_kexec_prepare(struct kimage *image)
+{
+	kexec_image_info(image);
+	return 0;
+}
diff --git a/arch/parisc/kernel/relocate_kernel.S b/arch/parisc/kernel/relocate_kernel.S
new file mode 100644
index 000000000000..2561e52b8d9b
--- /dev/null
+++ b/arch/parisc/kernel/relocate_kernel.S
@@ -0,0 +1,149 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <linux/linkage.h>
+#include <linux/kexec.h>
+
+#include <asm/assembly.h>
+#include <asm/asm-offsets.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <asm/psw.h>
+
+.level PA_ASM_LEVEL
+
+.macro	kexec_param name
+.align 8
+ENTRY(kexec\()_\name)
+#ifdef CONFIG_64BIT
+	.dword 0
+#else
+	.word 0
+#endif
+
+ENTRY(kexec\()_\name\()_offset)
+	.word kexec\()_\name - relocate_new_kernel
+.endm
+
+.text
+
+/* args:
+ * r26 - kimage->head
+ * r25 - start address of kernel
+ * r24 - physical address of relocate code
+ */
+
+ENTRY_CFI(relocate_new_kernel)
+0:	copy	%arg1, %rp
+	/* disable I and Q bit, so we are allowed to execute RFI */
+	rsm PSW_SM_I, %r0
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	rsm PSW_SM_Q, %r0
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	/*
+	 * After return-from-interrupt, we want to run without Code/Data
+	 * translation enabled just like on a normal boot.
+	 */
+
+	/* calculate new physical execution address */
+	ldo	1f-0b(%arg2), %r1
+	mtctl	%r0, %cr17 /* IIASQ */
+	mtctl	%r0, %cr17 /* IIASQ */
+	mtctl	%r1, %cr18 /* IIAOQ */
+	ldo	4(%r1),%r1
+	mtctl	%r1, %cr18 /* IIAOQ */
+#ifdef CONFIG_64BIT
+	depdi,z	1, PSW_W_BIT, 1, %r1
+	mtctl	%r1, %cr22 /* IPSW */
+#else
+	mtctl	%r0, %cr22 /* IPSW */
+#endif
+	/* lets go... */
+	rfi
+1:	nop
+	nop
+
+.Lloop:
+	LDREG,ma	REG_SZ(%arg0), %r3
+	/* If crash kernel, no copy needed */
+	cmpib,COND(=),n 0,%r3,boot
+
+	bb,<,n		%r3, 31 - IND_DONE_BIT, boot
+	bb,>=,n		%r3, 31 - IND_INDIRECTION_BIT, .Lnotind
+	/* indirection, load and restart */
+	movb		%r3, %arg0, .Lloop
+	depi		0, 31, PAGE_SHIFT, %arg0
+
+.Lnotind:
+	bb,>=,n		%r3, 31 - IND_DESTINATION_BIT, .Lnotdest
+	b		.Lloop
+	copy		%r3, %r20
+
+.Lnotdest:
+	bb,>=		%r3, 31 - IND_SOURCE_BIT, .Lloop
+	depi		0, 31, PAGE_SHIFT, %r3
+	copy		%r3, %r21
+
+	/* copy page */
+	copy		%r0, %r18
+	zdepi		1, 31 - PAGE_SHIFT, 1, %r18
+	add		%r20, %r18, %r17
+
+	depi		0, 31, PAGE_SHIFT, %r20
+.Lcopy:
+	copy		%r20, %r12
+	LDREG,ma	REG_SZ(%r21), %r8
+	LDREG,ma	REG_SZ(%r21), %r9
+	LDREG,ma	REG_SZ(%r21), %r10
+	LDREG,ma	REG_SZ(%r21), %r11
+	STREG,ma	%r8, REG_SZ(%r20)
+	STREG,ma	%r9, REG_SZ(%r20)
+	STREG,ma	%r10, REG_SZ(%r20)
+	STREG,ma	%r11, REG_SZ(%r20)
+
+#ifndef CONFIG_64BIT
+	LDREG,ma	REG_SZ(%r21), %r8
+	LDREG,ma	REG_SZ(%r21), %r9
+	LDREG,ma	REG_SZ(%r21), %r10
+	LDREG,ma	REG_SZ(%r21), %r11
+	STREG,ma	%r8, REG_SZ(%r20)
+	STREG,ma	%r9, REG_SZ(%r20)
+	STREG,ma	%r10, REG_SZ(%r20)
+	STREG,ma	%r11, REG_SZ(%r20)
+#endif
+
+	fdc		%r0(%r12)
+	cmpb,COND(<<)	%r20,%r17,.Lcopy
+	fic		(%sr4, %r12)
+	b,n		.Lloop
+
+boot:
+	mtctl	%r0, %cr15
+
+	LDREG	kexec_free_mem-0b(%arg2), %arg0
+	LDREG	kexec_cmdline-0b(%arg2), %arg1
+	LDREG	kexec_initrd_end-0b(%arg2), %arg3
+	LDREG	kexec_initrd_start-0b(%arg2), %arg2
+	bv,n %r0(%rp)
+
+ENDPROC_CFI(relocate_new_kernel);
+
+ENTRY(relocate_new_kernel_size)
+       .word relocate_new_kernel_size - relocate_new_kernel
+
+kexec_param cmdline
+kexec_param initrd_start
+kexec_param initrd_end
+kexec_param free_mem
diff --git a/include/uapi/linux/kexec.h b/include/uapi/linux/kexec.h
index 6d112868272d..05669c87a0af 100644
--- a/include/uapi/linux/kexec.h
+++ b/include/uapi/linux/kexec.h
@@ -31,6 +31,7 @@
 #define KEXEC_ARCH_DEFAULT ( 0 << 16)
 #define KEXEC_ARCH_386     ( 3 << 16)
 #define KEXEC_ARCH_68K     ( 4 << 16)
+#define KEXEC_ARCH_PARISC  (15 << 16)
 #define KEXEC_ARCH_X86_64  (62 << 16)
 #define KEXEC_ARCH_PPC     (20 << 16)
 #define KEXEC_ARCH_PPC64   (21 << 16)
-- 
2.23.0.rc1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 3/4] parisc: wire up kexec_file_load syscall
  2019-09-08  9:33 [PATCH 0/4] kexec support for PARISC Sven Schnelle
  2019-09-08  9:33 ` [PATCH 1/4] parisc: add __pdc_cpu_rendezvous() Sven Schnelle
  2019-09-08  9:33 ` [PATCH 2/4] parisc: add kexec syscall support Sven Schnelle
@ 2019-09-08  9:33 ` Sven Schnelle
  2019-09-08  9:33 ` [PATCH 4/4] parisc: add support for kexec_file_load() syscall Sven Schnelle
  2019-09-08 13:45 ` [PATCH 0/4] kexec support for PARISC Helge Deller
  4 siblings, 0 replies; 6+ messages in thread
From: Sven Schnelle @ 2019-09-08  9:33 UTC (permalink / raw)
  To: Helge Deller; +Cc: linux-parisc, Sven Schnelle

Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
 arch/parisc/kernel/syscalls/syscall.tbl | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl
index 670d1371aca1..285ff516150c 100644
--- a/arch/parisc/kernel/syscalls/syscall.tbl
+++ b/arch/parisc/kernel/syscalls/syscall.tbl
@@ -399,7 +399,8 @@
 352	common	pkey_alloc		sys_pkey_alloc
 353	common	pkey_free		sys_pkey_free
 354	common	rseq			sys_rseq
-# 355 through 402 are unassigned to sync up with generic numbers
+355	common	kexec_file_load		sys_kexec_file_load		sys_kexec_file_load
+# up to 402 is unassigned and reserved for arch specific syscalls
 403	32	clock_gettime64			sys_clock_gettime		sys_clock_gettime
 404	32	clock_settime64			sys_clock_settime		sys_clock_settime
 405	32	clock_adjtime64			sys_clock_adjtime		sys_clock_adjtime
-- 
2.23.0.rc1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 4/4] parisc: add support for kexec_file_load() syscall
  2019-09-08  9:33 [PATCH 0/4] kexec support for PARISC Sven Schnelle
                   ` (2 preceding siblings ...)
  2019-09-08  9:33 ` [PATCH 3/4] parisc: wire up kexec_file_load syscall Sven Schnelle
@ 2019-09-08  9:33 ` Sven Schnelle
  2019-09-08 13:45 ` [PATCH 0/4] kexec support for PARISC Helge Deller
  4 siblings, 0 replies; 6+ messages in thread
From: Sven Schnelle @ 2019-09-08  9:33 UTC (permalink / raw)
  To: Helge Deller; +Cc: linux-parisc, Sven Schnelle

Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
 arch/parisc/Kconfig             | 10 ++++
 arch/parisc/kernel/Makefile     |  1 +
 arch/parisc/kernel/kexec.c      |  7 +++
 arch/parisc/kernel/kexec_file.c | 86 +++++++++++++++++++++++++++++++++
 4 files changed, 104 insertions(+)
 create mode 100644 arch/parisc/kernel/kexec_file.c

diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 548c767f4358..2e757c785239 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -359,6 +359,16 @@ config KEXEC
 	  shutdown, so do not be surprised if this code does not
 	  initially work for you.
 
+config KEXEC_FILE
+	bool "kexec file based system call"
+	select KEXEC_CORE
+	select KEXEC_ELF
+	help
+	  This enables the kexec_file_load() System call. This is
+	  file based and takes file descriptors as system call argument
+	  for kernel and initramfs as opposed to list of segments as
+	  accepted by previous system call.
+
 endmenu
 
 
diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile
index 487cf88866a8..2663c8f8be11 100644
--- a/arch/parisc/kernel/Makefile
+++ b/arch/parisc/kernel/Makefile
@@ -38,3 +38,4 @@ obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
 obj-$(CONFIG_KGDB)			+= kgdb.o
 obj-$(CONFIG_KPROBES)			+= kprobes.o
 obj-$(CONFIG_KEXEC)			+= kexec.o relocate_kernel.o
+obj-$(CONFIG_KEXEC_FILE)		+= kexec_file.o
diff --git a/arch/parisc/kernel/kexec.c b/arch/parisc/kernel/kexec.c
index deeb0466d359..3d0716ded552 100644
--- a/arch/parisc/kernel/kexec.c
+++ b/arch/parisc/kernel/kexec.c
@@ -37,6 +37,13 @@ static void kexec_image_info(const struct kimage *kimage)
 
 	for (i = 0; i < kimage->nr_segments; i++)
 		kexec_show_segment_info(kimage, i);
+
+#ifdef CONFIG_KEXEC_FILE
+	if (kimage->file_mode) {
+		pr_debug("cmdline: %.*s\n", (int)kimage->cmdline_buf_len,
+			 kimage->cmdline_buf);
+	}
+#endif
 }
 
 void machine_kexec_cleanup(struct kimage *kimage)
diff --git a/arch/parisc/kernel/kexec_file.c b/arch/parisc/kernel/kexec_file.c
new file mode 100644
index 000000000000..f87c26e5e735
--- /dev/null
+++ b/arch/parisc/kernel/kexec_file.c
@@ -0,0 +1,86 @@
+/*
+ * Load ELF vmlinux file for the kexec_file_load syscall.
+ *
+ * Copyright (c) 2019 Sven Schnelle <svens@stackframe.org>
+ *
+ */
+#include <linux/elf.h>
+#include <linux/kexec.h>
+#include <linux/libfdt.h>
+#include <linux/module.h>
+#include <linux/of_fdt.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+static void *elf_load(struct kimage *image, char *kernel_buf,
+			unsigned long kernel_len, char *initrd,
+			unsigned long initrd_len, char *cmdline,
+			unsigned long cmdline_len)
+{
+	int ret, i;
+	unsigned long kernel_load_addr;
+	struct elfhdr ehdr;
+	struct kexec_elf_info elf_info;
+	struct kexec_buf kbuf = { .image = image, .buf_min = 0,
+				  .buf_max = -1UL, };
+
+	ret = kexec_build_elf_info(kernel_buf, kernel_len, &ehdr, &elf_info);
+	if (ret)
+		goto out;
+
+	ret = kexec_elf_load(image, &ehdr, &elf_info, &kbuf, &kernel_load_addr);
+	if (ret)
+		goto out;
+
+	image->start = __pa(elf_info.ehdr->e_entry);
+
+	for(i = 0; i < image->nr_segments; i++)
+		image->segment[i].mem = __pa(image->segment[i].mem);
+
+	pr_debug("Loaded the kernel at 0x%lx, entry at 0x%lx\n",
+		 kernel_load_addr, image->start);
+
+	if (initrd != NULL) {
+		kbuf.buffer = initrd;
+		kbuf.bufsz = kbuf.memsz = initrd_len;
+		kbuf.buf_align = PAGE_SIZE;
+		kbuf.top_down = false;
+		kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
+		ret = kexec_add_buffer(&kbuf);
+		if (ret)
+			goto out;
+
+		pr_debug("Loaded initrd at 0x%lx\n", kbuf.mem);
+		image->arch.initrd_start = kbuf.mem;
+		image->arch.initrd_end = kbuf.mem + initrd_len;
+	}
+
+	if (cmdline != NULL) {
+		kbuf.buffer = cmdline;
+		kbuf.bufsz = kbuf.memsz = ALIGN(cmdline_len, 8);
+		kbuf.buf_align = PAGE_SIZE;
+		kbuf.top_down = false;
+		kbuf.buf_min = PAGE0->mem_free + PAGE_SIZE;
+		kbuf.buf_max = kernel_load_addr;
+		kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
+		ret = kexec_add_buffer(&kbuf);
+		if (ret)
+			goto out;
+
+		pr_debug("Loaded cmdline at 0x%lx\n", kbuf.mem);
+		image->arch.cmdline = kbuf.mem;
+	}
+out:
+	return NULL;
+}
+
+const struct kexec_file_ops kexec_elf_ops = {
+	.probe = kexec_elf_probe,
+	.load = elf_load,
+};
+
+const struct kexec_file_ops * const kexec_file_loaders[] = {
+	&kexec_elf_ops,
+	NULL
+};
+
-- 
2.23.0.rc1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/4] kexec support for PARISC
  2019-09-08  9:33 [PATCH 0/4] kexec support for PARISC Sven Schnelle
                   ` (3 preceding siblings ...)
  2019-09-08  9:33 ` [PATCH 4/4] parisc: add support for kexec_file_load() syscall Sven Schnelle
@ 2019-09-08 13:45 ` Helge Deller
  4 siblings, 0 replies; 6+ messages in thread
From: Helge Deller @ 2019-09-08 13:45 UTC (permalink / raw)
  To: Sven Schnelle; +Cc: linux-parisc

On 08.09.19 11:33, Sven Schnelle wrote:
> this series adds support for the kexec syscalls to the PARISC architecture.
> Note that kexec() on PA8800/PA8900 doesn't work yet as i haven't figured
> out how to restart the CPUs on these systems.
>
> For testing you can use my patched kexec-tools:
>
> https://git.stackframe.org/cgit/kexec-tools/log/
>
> I will submit these patches as soon as kexec is merged into the linux
> kernel.


Thanks!
Patch series applied to the parisc for-next tree:
https://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux.git/log/?h=for-next

Helge

>
> Thanks,
> Sven
>
> Sven Schnelle (4):
>   parisc: add __pdc_cpu_rendezvous()
>   parisc: add kexec syscall support
>   parisc: wire up kexec_file_load syscall
>   parisc: add support for kexec_file_load() syscall
>
>  arch/parisc/Kconfig                     |  23 ++++
>  arch/parisc/include/asm/fixmap.h        |   1 +
>  arch/parisc/include/asm/kexec.h         |  37 ++++++
>  arch/parisc/include/asm/pdc.h           |   1 +
>  arch/parisc/kernel/Makefile             |   2 +
>  arch/parisc/kernel/firmware.c           |  13 +++
>  arch/parisc/kernel/kexec.c              | 109 +++++++++++++++++
>  arch/parisc/kernel/kexec_file.c         |  86 ++++++++++++++
>  arch/parisc/kernel/relocate_kernel.S    | 149 ++++++++++++++++++++++++
>  arch/parisc/kernel/smp.c                |   1 +
>  arch/parisc/kernel/syscalls/syscall.tbl |   3 +-
>  include/uapi/linux/kexec.h              |   1 +
>  12 files changed, 425 insertions(+), 1 deletion(-)
>  create mode 100644 arch/parisc/include/asm/kexec.h
>  create mode 100644 arch/parisc/kernel/kexec.c
>  create mode 100644 arch/parisc/kernel/kexec_file.c
>  create mode 100644 arch/parisc/kernel/relocate_kernel.S
>


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, back to index

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-08  9:33 [PATCH 0/4] kexec support for PARISC Sven Schnelle
2019-09-08  9:33 ` [PATCH 1/4] parisc: add __pdc_cpu_rendezvous() Sven Schnelle
2019-09-08  9:33 ` [PATCH 2/4] parisc: add kexec syscall support Sven Schnelle
2019-09-08  9:33 ` [PATCH 3/4] parisc: wire up kexec_file_load syscall Sven Schnelle
2019-09-08  9:33 ` [PATCH 4/4] parisc: add support for kexec_file_load() syscall Sven Schnelle
2019-09-08 13:45 ` [PATCH 0/4] kexec support for PARISC Helge Deller

Linux-parisc archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-parisc/0 linux-parisc/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-parisc linux-parisc/ https://lore.kernel.org/linux-parisc \
		linux-parisc@vger.kernel.org linux-parisc@archiver.kernel.org
	public-inbox-index linux-parisc


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-parisc


AGPL code for this site: git clone https://public-inbox.org/ public-inbox