linux-parisc.vger.kernel.org archive mirror
 help / color / mirror / 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; 7+ 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] 7+ 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; 7+ 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 related	[flat|nested] 7+ 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; 7+ 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 related	[flat|nested] 7+ 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; 7+ 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 related	[flat|nested] 7+ 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; 7+ 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 related	[flat|nested] 7+ 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
  2019-09-17 14:39   ` Helge Deller
  4 siblings, 1 reply; 7+ 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] 7+ messages in thread

* Re: [PATCH 0/4] kexec support for PARISC
  2019-09-08 13:45 ` [PATCH 0/4] kexec support for PARISC Helge Deller
@ 2019-09-17 14:39   ` Helge Deller
  0 siblings, 0 replies; 7+ messages in thread
From: Helge Deller @ 2019-09-17 14:39 UTC (permalink / raw)
  To: Sven Schnelle; +Cc: linux-parisc

Hi Sven,

On 08.09.19 15:45, Helge Deller wrote:
> On 08.09.19 11:33, Sven Schnelle wrote:
>> this series adds support for the kexec syscalls to the PARISC architecture.
>> ....
>> 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.

All kexec patches have been merged upstream and will be part
of kernel v5.4.
So, you may now push your patches to userspace kexec-tools
upstream too.

Thanks!
Helge

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

end of thread, other threads:[~2019-09-17 14:39 UTC | newest]

Thread overview: 7+ 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
2019-09-17 14:39   ` Helge Deller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).