All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vivek Goyal <vgoyal@redhat.com>
To: linux-kernel@vger.kernel.org, kexec@lists.infradead.org
Cc: ebiederm@xmission.com, hpa@zytor.com, mjg59@srcf.ucam.org,
	greg@kroah.com, bp@alien8.de, jkosina@suse.cz, dyoung@redhat.com,
	chaowang@redhat.com, bhe@redhat.com, akpm@linux-foundation.org,
	Vivek Goyal <vgoyal@redhat.com>
Subject: [PATCH 09/13] purgatory: Core purgatory functionality
Date: Tue,  3 Jun 2014 09:06:58 -0400	[thread overview]
Message-ID: <1401800822-27425-10-git-send-email-vgoyal@redhat.com> (raw)
In-Reply-To: <1401800822-27425-1-git-send-email-vgoyal@redhat.com>

Create a stand alone relocatable object purgatory which runs between two
kernels. This name, concept and some code has been taken from kexec-tools.
Idea is that this code runs after a crash and it runs in minimal environment.
So keep it separate from rest of the kernel and in long term we will have
to practically do no maintenance of this code.

This code also has the logic to do verify sha256 hashes of various
segments which have been loaded into memory. So first we verify that
the kernel we are jumping to is fine and has not been corrupted and
make progress only if checsums are verified.

This code also takes care of copying some memory contents to backup region.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
---
 arch/x86/Kbuild                   |   1 +
 arch/x86/Makefile                 |   6 +++
 arch/x86/purgatory/Makefile       |  35 +++++++++++++
 arch/x86/purgatory/entry64.S      | 101 ++++++++++++++++++++++++++++++++++++++
 arch/x86/purgatory/purgatory.c    |  71 +++++++++++++++++++++++++++
 arch/x86/purgatory/setup-x86_32.S |  17 +++++++
 arch/x86/purgatory/setup-x86_64.S |  58 ++++++++++++++++++++++
 arch/x86/purgatory/stack.S        |  19 +++++++
 arch/x86/purgatory/string.c       |  13 +++++
 9 files changed, 321 insertions(+)
 create mode 100644 arch/x86/purgatory/Makefile
 create mode 100644 arch/x86/purgatory/entry64.S
 create mode 100644 arch/x86/purgatory/purgatory.c
 create mode 100644 arch/x86/purgatory/setup-x86_32.S
 create mode 100644 arch/x86/purgatory/setup-x86_64.S
 create mode 100644 arch/x86/purgatory/stack.S
 create mode 100644 arch/x86/purgatory/string.c

diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild
index e5287d8..faaeee7 100644
--- a/arch/x86/Kbuild
+++ b/arch/x86/Kbuild
@@ -16,3 +16,4 @@ obj-$(CONFIG_IA32_EMULATION) += ia32/
 
 obj-y += platform/
 obj-y += net/
+obj-$(CONFIG_KEXEC) += purgatory/
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 33f71b0..0b25c6c 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -186,6 +186,11 @@ archscripts: scripts_basic
 archheaders:
 	$(Q)$(MAKE) $(build)=arch/x86/syscalls all
 
+archprepare:
+ifeq ($(CONFIG_KEXEC),y)
+	$(Q)$(MAKE) $(build)=arch/x86/purgatory arch/x86/purgatory/kexec-purgatory.c
+endif
+
 ###
 # Kernel objects
 
@@ -249,6 +254,7 @@ archclean:
 	$(Q)rm -rf $(objtree)/arch/x86_64
 	$(Q)$(MAKE) $(clean)=$(boot)
 	$(Q)$(MAKE) $(clean)=arch/x86/tools
+	$(Q)$(MAKE) $(clean)=arch/x86/purgatory
 
 PHONY += kvmconfig
 kvmconfig:
diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile
new file mode 100644
index 0000000..8dbf8f5
--- /dev/null
+++ b/arch/x86/purgatory/Makefile
@@ -0,0 +1,35 @@
+ifeq ($(CONFIG_X86_64),y)
+	purgatory-y := purgatory.o entry64.o stack.o setup-x86_64.o sha256.o string.o
+else
+	purgatory-y := purgatory.o stack.o sha256.o setup-x86_32.o
+endif
+
+targets += $(purgatory-y)
+PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y))
+
+LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined -nostdlib -z nodefaultlib
+targets += purgatory.ro
+
+# Default KBUILD_CFLAGS can have -pg option set when FTRACE is enabled. That
+# in turn leaves some undefined symbols like __fentry__ in purgatory and not
+# sure how to relocate those. Like kexec-tools, custom flags.
+
+ifeq ($(CONFIG_X86_64),y)
+KBUILD_CFLAGS	:= -fno-strict-aliasing -Wall -Wstrict-prototypes -fno-zero-initialized-in-bss -mcmodel=large -Os -fno-builtin -ffreestanding -c -MD
+else
+KBUILD_CFLAGS	:= -fno-strict-aliasing -Wall -Wstrict-prototypes -fno-zero-initialized-in-bss -Os -fno-builtin -ffreestanding -c -MD -m32
+endif
+
+$(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
+		$(call if_changed,ld)
+
+targets += kexec-purgatory.c
+
+quiet_cmd_bin2c = BIN2C   $@
+      cmd_bin2c = cat $(obj)/purgatory.ro | $(srctree)/scripts/basic/bin2c kexec_purgatory > $(obj)/kexec-purgatory.c
+
+$(obj)/kexec-purgatory.c: $(obj)/purgatory.ro FORCE
+	$(call if_changed,bin2c)
+
+
+obj-$(CONFIG_KEXEC)	+= kexec-purgatory.o
diff --git a/arch/x86/purgatory/entry64.S b/arch/x86/purgatory/entry64.S
new file mode 100644
index 0000000..219b50b
--- /dev/null
+++ b/arch/x86/purgatory/entry64.S
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2003,2004  Eric Biederman (ebiederm@xmission.com)
+ * Copyright (C) 2014  Red Hat Inc.
+
+ * Author(s): Vivek Goyal <vgoyal@redhat.com>
+ *
+ * This code has been taken from kexec-tools.
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+	.text
+	.balign 16
+	.code64
+	.globl entry64, entry64_regs
+
+
+entry64:
+	/* Setup a gdt that should be preserved */
+	lgdt gdt(%rip)
+
+	/* load the data segments */
+	movl    $0x18, %eax     /* data segment */
+	movl    %eax, %ds
+	movl    %eax, %es
+	movl    %eax, %ss
+	movl    %eax, %fs
+	movl    %eax, %gs
+
+	/* Setup new stack */
+	leaq    stack_init(%rip), %rsp
+	pushq   $0x10 /* CS */
+	leaq    new_cs_exit(%rip), %rax
+	pushq   %rax
+	lretq
+new_cs_exit:
+
+	/* Load the registers */
+	movq	rax(%rip), %rax
+	movq	rbx(%rip), %rbx
+	movq	rcx(%rip), %rcx
+	movq	rdx(%rip), %rdx
+	movq	rsi(%rip), %rsi
+	movq	rdi(%rip), %rdi
+	movq    rsp(%rip), %rsp
+	movq	rbp(%rip), %rbp
+	movq	r8(%rip), %r8
+	movq	r9(%rip), %r9
+	movq	r10(%rip), %r10
+	movq	r11(%rip), %r11
+	movq	r12(%rip), %r12
+	movq	r13(%rip), %r13
+	movq	r14(%rip), %r14
+	movq	r15(%rip), %r15
+
+	/* Jump to the new code... */
+	jmpq	*rip(%rip)
+
+	.section ".rodata"
+	.balign 4
+entry64_regs:
+rax:	.quad 0x00000000
+rbx:	.quad 0x00000000
+rcx:	.quad 0x00000000
+rdx:	.quad 0x00000000
+rsi:	.quad 0x00000000
+rdi:	.quad 0x00000000
+rsp:	.quad 0x00000000
+rbp:	.quad 0x00000000
+r8:	.quad 0x00000000
+r9:	.quad 0x00000000
+r10:	.quad 0x00000000
+r11:	.quad 0x00000000
+r12:	.quad 0x00000000
+r13:	.quad 0x00000000
+r14:	.quad 0x00000000
+r15:	.quad 0x00000000
+rip:	.quad 0x00000000
+	.size entry64_regs, . - entry64_regs
+
+	/* GDT */
+	.section ".rodata"
+	.balign 16
+gdt:
+	/* 0x00 unusable segment
+	 * 0x08 unused
+	 * so use them as gdt ptr
+	 */
+	.word gdt_end - gdt - 1
+	.quad gdt
+	.word 0, 0, 0
+
+	/* 0x10 4GB flat code segment */
+	.word 0xFFFF, 0x0000, 0x9A00, 0x00AF
+
+	/* 0x18 4GB flat data segment */
+	.word 0xFFFF, 0x0000, 0x9200, 0x00CF
+gdt_end:
+stack:	.quad   0, 0
+stack_init:
diff --git a/arch/x86/purgatory/purgatory.c b/arch/x86/purgatory/purgatory.c
new file mode 100644
index 0000000..3a808db
--- /dev/null
+++ b/arch/x86/purgatory/purgatory.c
@@ -0,0 +1,71 @@
+/*
+ * purgatory: Runs between two kernels
+ *
+ * Copyright (C) 2014 Red Hat Inc.
+ *
+ * Author:
+ *       Vivek Goyal <vgoyal@redhat.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include "sha256.h"
+#include "../boot/string.h"
+
+struct sha_region {
+	unsigned long start;
+	unsigned long len;
+};
+
+unsigned long backup_dest = 0;
+unsigned long backup_src = 0;
+unsigned long backup_sz = 0;
+
+u8 sha256_digest[SHA256_DIGEST_SIZE] = { 0 };
+
+struct sha_region sha_regions[16] = {};
+
+/*
+ * On x86, second kernel requries first 640K of memory to boot. Copy
+ * first 640K to a backup region in reserved memory range so that second
+ * kernel can use first 640K.
+ */
+static int copy_backup_region(void)
+{
+	if (backup_dest)
+		memcpy((void *)backup_dest, (void *)backup_src, backup_sz);
+
+	return 0;
+}
+
+int verify_sha256_digest(void)
+{
+	struct sha_region *ptr, *end;
+	u8 digest[SHA256_DIGEST_SIZE];
+	struct sha256_state sctx;
+
+	sha256_init(&sctx);
+	end = &sha_regions[sizeof(sha_regions)/sizeof(sha_regions[0])];
+	for (ptr = sha_regions; ptr < end; ptr++)
+		sha256_update(&sctx, (uint8_t *)(ptr->start), ptr->len);
+
+	sha256_final(&sctx, digest);
+
+	if (memcmp(digest, sha256_digest, sizeof(digest)) != 0)
+		return 1;
+
+	return 0;
+}
+
+void purgatory(void)
+{
+	int ret;
+
+	ret = verify_sha256_digest();
+	if (ret) {
+		/* loop forever */
+		for (;;);
+	}
+	copy_backup_region();
+}
diff --git a/arch/x86/purgatory/setup-x86_32.S b/arch/x86/purgatory/setup-x86_32.S
new file mode 100644
index 0000000..cfcff31
--- /dev/null
+++ b/arch/x86/purgatory/setup-x86_32.S
@@ -0,0 +1,17 @@
+/*
+ * purgatory:  setup code
+ *
+ * Copyright (C) 2014 Red Hat Inc.
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+	.text
+	.globl purgatory_start
+	.balign 16
+purgatory_start:
+	.code32
+
+	/* This is just a stub. Write code when 32bit support comes along */
+	call purgatory
diff --git a/arch/x86/purgatory/setup-x86_64.S b/arch/x86/purgatory/setup-x86_64.S
new file mode 100644
index 0000000..fe3c91b
--- /dev/null
+++ b/arch/x86/purgatory/setup-x86_64.S
@@ -0,0 +1,58 @@
+/*
+ * purgatory:  setup code
+ *
+ * Copyright (C) 2003,2004  Eric Biederman (ebiederm@xmission.com)
+ * Copyright (C) 2014 Red Hat Inc.
+ *
+ * This code has been taken from kexec-tools.
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+	.text
+	.globl purgatory_start
+	.balign 16
+purgatory_start:
+	.code64
+
+	/* Load a gdt so I know what the segment registers are */
+	lgdt	gdt(%rip)
+
+	/* load the data segments */
+	movl	$0x18, %eax	/* data segment */
+	movl	%eax, %ds
+	movl	%eax, %es
+	movl	%eax, %ss
+	movl	%eax, %fs
+	movl	%eax, %gs
+
+	/* Setup a stack */
+	leaq	lstack_end(%rip), %rsp
+
+	/* Call the C code */
+	call purgatory
+	jmp	entry64
+
+	.section ".rodata"
+	.balign 16
+gdt:	/* 0x00 unusable segment
+	 * 0x08 unused
+	 * so use them as the gdt ptr
+	 */
+	.word	gdt_end - gdt - 1
+	.quad	gdt
+	.word	0, 0, 0
+
+	/* 0x10 4GB flat code segment */
+	.word	0xFFFF, 0x0000, 0x9A00, 0x00AF
+
+	/* 0x18 4GB flat data segment */
+	.word	0xFFFF, 0x0000, 0x9200, 0x00CF
+gdt_end:
+
+	.bss
+	.balign 4096
+lstack:
+	.skip 4096
+lstack_end:
diff --git a/arch/x86/purgatory/stack.S b/arch/x86/purgatory/stack.S
new file mode 100644
index 0000000..3cefba1
--- /dev/null
+++ b/arch/x86/purgatory/stack.S
@@ -0,0 +1,19 @@
+/*
+ * purgatory:  stack
+ *
+ * Copyright (C) 2014 Red Hat Inc.
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+	/* A stack for the loaded kernel.
+	 * Seperate and in the data section so it can be prepopulated.
+	 */
+	.data
+	.balign 4096
+	.globl stack, stack_end
+
+stack:
+	.skip 4096
+stack_end:
diff --git a/arch/x86/purgatory/string.c b/arch/x86/purgatory/string.c
new file mode 100644
index 0000000..d886b1f
--- /dev/null
+++ b/arch/x86/purgatory/string.c
@@ -0,0 +1,13 @@
+/*
+ * Simple string functions.
+ *
+ * Copyright (C) 2014 Red Hat Inc.
+ *
+ * Author:
+ *       Vivek Goyal <vgoyal@redhat.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include "../boot/string.c"
-- 
1.9.0


WARNING: multiple messages have this Message-ID (diff)
From: Vivek Goyal <vgoyal@redhat.com>
To: linux-kernel@vger.kernel.org, kexec@lists.infradead.org
Cc: mjg59@srcf.ucam.org, bhe@redhat.com, jkosina@suse.cz,
	hpa@zytor.com, Vivek Goyal <vgoyal@redhat.com>,
	bp@alien8.de, ebiederm@xmission.com, greg@kroah.com,
	akpm@linux-foundation.org, dyoung@redhat.com,
	chaowang@redhat.com
Subject: [PATCH 09/13] purgatory: Core purgatory functionality
Date: Tue,  3 Jun 2014 09:06:58 -0400	[thread overview]
Message-ID: <1401800822-27425-10-git-send-email-vgoyal@redhat.com> (raw)
In-Reply-To: <1401800822-27425-1-git-send-email-vgoyal@redhat.com>

Create a stand alone relocatable object purgatory which runs between two
kernels. This name, concept and some code has been taken from kexec-tools.
Idea is that this code runs after a crash and it runs in minimal environment.
So keep it separate from rest of the kernel and in long term we will have
to practically do no maintenance of this code.

This code also has the logic to do verify sha256 hashes of various
segments which have been loaded into memory. So first we verify that
the kernel we are jumping to is fine and has not been corrupted and
make progress only if checsums are verified.

This code also takes care of copying some memory contents to backup region.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
---
 arch/x86/Kbuild                   |   1 +
 arch/x86/Makefile                 |   6 +++
 arch/x86/purgatory/Makefile       |  35 +++++++++++++
 arch/x86/purgatory/entry64.S      | 101 ++++++++++++++++++++++++++++++++++++++
 arch/x86/purgatory/purgatory.c    |  71 +++++++++++++++++++++++++++
 arch/x86/purgatory/setup-x86_32.S |  17 +++++++
 arch/x86/purgatory/setup-x86_64.S |  58 ++++++++++++++++++++++
 arch/x86/purgatory/stack.S        |  19 +++++++
 arch/x86/purgatory/string.c       |  13 +++++
 9 files changed, 321 insertions(+)
 create mode 100644 arch/x86/purgatory/Makefile
 create mode 100644 arch/x86/purgatory/entry64.S
 create mode 100644 arch/x86/purgatory/purgatory.c
 create mode 100644 arch/x86/purgatory/setup-x86_32.S
 create mode 100644 arch/x86/purgatory/setup-x86_64.S
 create mode 100644 arch/x86/purgatory/stack.S
 create mode 100644 arch/x86/purgatory/string.c

diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild
index e5287d8..faaeee7 100644
--- a/arch/x86/Kbuild
+++ b/arch/x86/Kbuild
@@ -16,3 +16,4 @@ obj-$(CONFIG_IA32_EMULATION) += ia32/
 
 obj-y += platform/
 obj-y += net/
+obj-$(CONFIG_KEXEC) += purgatory/
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 33f71b0..0b25c6c 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -186,6 +186,11 @@ archscripts: scripts_basic
 archheaders:
 	$(Q)$(MAKE) $(build)=arch/x86/syscalls all
 
+archprepare:
+ifeq ($(CONFIG_KEXEC),y)
+	$(Q)$(MAKE) $(build)=arch/x86/purgatory arch/x86/purgatory/kexec-purgatory.c
+endif
+
 ###
 # Kernel objects
 
@@ -249,6 +254,7 @@ archclean:
 	$(Q)rm -rf $(objtree)/arch/x86_64
 	$(Q)$(MAKE) $(clean)=$(boot)
 	$(Q)$(MAKE) $(clean)=arch/x86/tools
+	$(Q)$(MAKE) $(clean)=arch/x86/purgatory
 
 PHONY += kvmconfig
 kvmconfig:
diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile
new file mode 100644
index 0000000..8dbf8f5
--- /dev/null
+++ b/arch/x86/purgatory/Makefile
@@ -0,0 +1,35 @@
+ifeq ($(CONFIG_X86_64),y)
+	purgatory-y := purgatory.o entry64.o stack.o setup-x86_64.o sha256.o string.o
+else
+	purgatory-y := purgatory.o stack.o sha256.o setup-x86_32.o
+endif
+
+targets += $(purgatory-y)
+PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y))
+
+LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined -nostdlib -z nodefaultlib
+targets += purgatory.ro
+
+# Default KBUILD_CFLAGS can have -pg option set when FTRACE is enabled. That
+# in turn leaves some undefined symbols like __fentry__ in purgatory and not
+# sure how to relocate those. Like kexec-tools, custom flags.
+
+ifeq ($(CONFIG_X86_64),y)
+KBUILD_CFLAGS	:= -fno-strict-aliasing -Wall -Wstrict-prototypes -fno-zero-initialized-in-bss -mcmodel=large -Os -fno-builtin -ffreestanding -c -MD
+else
+KBUILD_CFLAGS	:= -fno-strict-aliasing -Wall -Wstrict-prototypes -fno-zero-initialized-in-bss -Os -fno-builtin -ffreestanding -c -MD -m32
+endif
+
+$(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
+		$(call if_changed,ld)
+
+targets += kexec-purgatory.c
+
+quiet_cmd_bin2c = BIN2C   $@
+      cmd_bin2c = cat $(obj)/purgatory.ro | $(srctree)/scripts/basic/bin2c kexec_purgatory > $(obj)/kexec-purgatory.c
+
+$(obj)/kexec-purgatory.c: $(obj)/purgatory.ro FORCE
+	$(call if_changed,bin2c)
+
+
+obj-$(CONFIG_KEXEC)	+= kexec-purgatory.o
diff --git a/arch/x86/purgatory/entry64.S b/arch/x86/purgatory/entry64.S
new file mode 100644
index 0000000..219b50b
--- /dev/null
+++ b/arch/x86/purgatory/entry64.S
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2003,2004  Eric Biederman (ebiederm@xmission.com)
+ * Copyright (C) 2014  Red Hat Inc.
+
+ * Author(s): Vivek Goyal <vgoyal@redhat.com>
+ *
+ * This code has been taken from kexec-tools.
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+	.text
+	.balign 16
+	.code64
+	.globl entry64, entry64_regs
+
+
+entry64:
+	/* Setup a gdt that should be preserved */
+	lgdt gdt(%rip)
+
+	/* load the data segments */
+	movl    $0x18, %eax     /* data segment */
+	movl    %eax, %ds
+	movl    %eax, %es
+	movl    %eax, %ss
+	movl    %eax, %fs
+	movl    %eax, %gs
+
+	/* Setup new stack */
+	leaq    stack_init(%rip), %rsp
+	pushq   $0x10 /* CS */
+	leaq    new_cs_exit(%rip), %rax
+	pushq   %rax
+	lretq
+new_cs_exit:
+
+	/* Load the registers */
+	movq	rax(%rip), %rax
+	movq	rbx(%rip), %rbx
+	movq	rcx(%rip), %rcx
+	movq	rdx(%rip), %rdx
+	movq	rsi(%rip), %rsi
+	movq	rdi(%rip), %rdi
+	movq    rsp(%rip), %rsp
+	movq	rbp(%rip), %rbp
+	movq	r8(%rip), %r8
+	movq	r9(%rip), %r9
+	movq	r10(%rip), %r10
+	movq	r11(%rip), %r11
+	movq	r12(%rip), %r12
+	movq	r13(%rip), %r13
+	movq	r14(%rip), %r14
+	movq	r15(%rip), %r15
+
+	/* Jump to the new code... */
+	jmpq	*rip(%rip)
+
+	.section ".rodata"
+	.balign 4
+entry64_regs:
+rax:	.quad 0x00000000
+rbx:	.quad 0x00000000
+rcx:	.quad 0x00000000
+rdx:	.quad 0x00000000
+rsi:	.quad 0x00000000
+rdi:	.quad 0x00000000
+rsp:	.quad 0x00000000
+rbp:	.quad 0x00000000
+r8:	.quad 0x00000000
+r9:	.quad 0x00000000
+r10:	.quad 0x00000000
+r11:	.quad 0x00000000
+r12:	.quad 0x00000000
+r13:	.quad 0x00000000
+r14:	.quad 0x00000000
+r15:	.quad 0x00000000
+rip:	.quad 0x00000000
+	.size entry64_regs, . - entry64_regs
+
+	/* GDT */
+	.section ".rodata"
+	.balign 16
+gdt:
+	/* 0x00 unusable segment
+	 * 0x08 unused
+	 * so use them as gdt ptr
+	 */
+	.word gdt_end - gdt - 1
+	.quad gdt
+	.word 0, 0, 0
+
+	/* 0x10 4GB flat code segment */
+	.word 0xFFFF, 0x0000, 0x9A00, 0x00AF
+
+	/* 0x18 4GB flat data segment */
+	.word 0xFFFF, 0x0000, 0x9200, 0x00CF
+gdt_end:
+stack:	.quad   0, 0
+stack_init:
diff --git a/arch/x86/purgatory/purgatory.c b/arch/x86/purgatory/purgatory.c
new file mode 100644
index 0000000..3a808db
--- /dev/null
+++ b/arch/x86/purgatory/purgatory.c
@@ -0,0 +1,71 @@
+/*
+ * purgatory: Runs between two kernels
+ *
+ * Copyright (C) 2014 Red Hat Inc.
+ *
+ * Author:
+ *       Vivek Goyal <vgoyal@redhat.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include "sha256.h"
+#include "../boot/string.h"
+
+struct sha_region {
+	unsigned long start;
+	unsigned long len;
+};
+
+unsigned long backup_dest = 0;
+unsigned long backup_src = 0;
+unsigned long backup_sz = 0;
+
+u8 sha256_digest[SHA256_DIGEST_SIZE] = { 0 };
+
+struct sha_region sha_regions[16] = {};
+
+/*
+ * On x86, second kernel requries first 640K of memory to boot. Copy
+ * first 640K to a backup region in reserved memory range so that second
+ * kernel can use first 640K.
+ */
+static int copy_backup_region(void)
+{
+	if (backup_dest)
+		memcpy((void *)backup_dest, (void *)backup_src, backup_sz);
+
+	return 0;
+}
+
+int verify_sha256_digest(void)
+{
+	struct sha_region *ptr, *end;
+	u8 digest[SHA256_DIGEST_SIZE];
+	struct sha256_state sctx;
+
+	sha256_init(&sctx);
+	end = &sha_regions[sizeof(sha_regions)/sizeof(sha_regions[0])];
+	for (ptr = sha_regions; ptr < end; ptr++)
+		sha256_update(&sctx, (uint8_t *)(ptr->start), ptr->len);
+
+	sha256_final(&sctx, digest);
+
+	if (memcmp(digest, sha256_digest, sizeof(digest)) != 0)
+		return 1;
+
+	return 0;
+}
+
+void purgatory(void)
+{
+	int ret;
+
+	ret = verify_sha256_digest();
+	if (ret) {
+		/* loop forever */
+		for (;;);
+	}
+	copy_backup_region();
+}
diff --git a/arch/x86/purgatory/setup-x86_32.S b/arch/x86/purgatory/setup-x86_32.S
new file mode 100644
index 0000000..cfcff31
--- /dev/null
+++ b/arch/x86/purgatory/setup-x86_32.S
@@ -0,0 +1,17 @@
+/*
+ * purgatory:  setup code
+ *
+ * Copyright (C) 2014 Red Hat Inc.
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+	.text
+	.globl purgatory_start
+	.balign 16
+purgatory_start:
+	.code32
+
+	/* This is just a stub. Write code when 32bit support comes along */
+	call purgatory
diff --git a/arch/x86/purgatory/setup-x86_64.S b/arch/x86/purgatory/setup-x86_64.S
new file mode 100644
index 0000000..fe3c91b
--- /dev/null
+++ b/arch/x86/purgatory/setup-x86_64.S
@@ -0,0 +1,58 @@
+/*
+ * purgatory:  setup code
+ *
+ * Copyright (C) 2003,2004  Eric Biederman (ebiederm@xmission.com)
+ * Copyright (C) 2014 Red Hat Inc.
+ *
+ * This code has been taken from kexec-tools.
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+	.text
+	.globl purgatory_start
+	.balign 16
+purgatory_start:
+	.code64
+
+	/* Load a gdt so I know what the segment registers are */
+	lgdt	gdt(%rip)
+
+	/* load the data segments */
+	movl	$0x18, %eax	/* data segment */
+	movl	%eax, %ds
+	movl	%eax, %es
+	movl	%eax, %ss
+	movl	%eax, %fs
+	movl	%eax, %gs
+
+	/* Setup a stack */
+	leaq	lstack_end(%rip), %rsp
+
+	/* Call the C code */
+	call purgatory
+	jmp	entry64
+
+	.section ".rodata"
+	.balign 16
+gdt:	/* 0x00 unusable segment
+	 * 0x08 unused
+	 * so use them as the gdt ptr
+	 */
+	.word	gdt_end - gdt - 1
+	.quad	gdt
+	.word	0, 0, 0
+
+	/* 0x10 4GB flat code segment */
+	.word	0xFFFF, 0x0000, 0x9A00, 0x00AF
+
+	/* 0x18 4GB flat data segment */
+	.word	0xFFFF, 0x0000, 0x9200, 0x00CF
+gdt_end:
+
+	.bss
+	.balign 4096
+lstack:
+	.skip 4096
+lstack_end:
diff --git a/arch/x86/purgatory/stack.S b/arch/x86/purgatory/stack.S
new file mode 100644
index 0000000..3cefba1
--- /dev/null
+++ b/arch/x86/purgatory/stack.S
@@ -0,0 +1,19 @@
+/*
+ * purgatory:  stack
+ *
+ * Copyright (C) 2014 Red Hat Inc.
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+	/* A stack for the loaded kernel.
+	 * Seperate and in the data section so it can be prepopulated.
+	 */
+	.data
+	.balign 4096
+	.globl stack, stack_end
+
+stack:
+	.skip 4096
+stack_end:
diff --git a/arch/x86/purgatory/string.c b/arch/x86/purgatory/string.c
new file mode 100644
index 0000000..d886b1f
--- /dev/null
+++ b/arch/x86/purgatory/string.c
@@ -0,0 +1,13 @@
+/*
+ * Simple string functions.
+ *
+ * Copyright (C) 2014 Red Hat Inc.
+ *
+ * Author:
+ *       Vivek Goyal <vgoyal@redhat.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include "../boot/string.c"
-- 
1.9.0


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

  parent reply	other threads:[~2014-06-03 13:08 UTC|newest]

Thread overview: 214+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-03 13:06 [RFC PATCH 00/13][V3] kexec: A new system call to allow in kernel loading Vivek Goyal
2014-06-03 13:06 ` Vivek Goyal
2014-06-03 13:06 ` [PATCH 01/13] bin2c: Move bin2c in scripts/basic Vivek Goyal
2014-06-03 13:06   ` Vivek Goyal
2014-06-03 16:01   ` Borislav Petkov
2014-06-03 16:01     ` Borislav Petkov
2014-06-03 17:13     ` Vivek Goyal
2014-06-03 17:13       ` Vivek Goyal
2014-06-03 13:06 ` [PATCH 02/13] kernel: Build bin2c based on config option CONFIG_BUILD_BIN2C Vivek Goyal
2014-06-03 13:06   ` Vivek Goyal
2014-06-04  9:13   ` Borislav Petkov
2014-06-04  9:13     ` Borislav Petkov
2014-06-03 13:06 ` [PATCH 03/13] kexec: Move segment verification code in a separate function Vivek Goyal
2014-06-03 13:06   ` Vivek Goyal
2014-06-04  9:32   ` Borislav Petkov
2014-06-04  9:32     ` Borislav Petkov
2014-06-04 18:47     ` Vivek Goyal
2014-06-04 18:47       ` Vivek Goyal
2014-06-04 20:30       ` Borislav Petkov
2014-06-04 20:30         ` Borislav Petkov
2014-06-05 14:05         ` Vivek Goyal
2014-06-05 14:05           ` Vivek Goyal
2014-06-05 14:07           ` Borislav Petkov
2014-06-05 14:07             ` Borislav Petkov
2014-06-03 13:06 ` [PATCH 04/13] resource: Provide new functions to walk through resources Vivek Goyal
2014-06-03 13:06   ` Vivek Goyal
2014-06-04 10:24   ` Borislav Petkov
2014-06-04 10:24     ` Borislav Petkov
2014-06-05 13:58     ` Vivek Goyal
2014-06-05 13:58       ` Vivek Goyal
2014-06-03 13:06 ` [PATCH 05/13] kexec: Make kexec_segment user buffer pointer a union Vivek Goyal
2014-06-03 13:06   ` Vivek Goyal
2014-06-04 10:34   ` Borislav Petkov
2014-06-04 10:34     ` Borislav Petkov
2014-06-03 13:06 ` [PATCH 06/13] kexec: New syscall kexec_file_load() declaration Vivek Goyal
2014-06-03 13:06   ` Vivek Goyal
2014-06-04 15:18   ` Borislav Petkov
2014-06-04 15:18     ` Borislav Petkov
2014-06-05  9:56   ` WANG Chao
2014-06-05  9:56     ` WANG Chao
2014-06-05 15:16     ` Vivek Goyal
2014-06-05 15:16       ` Vivek Goyal
2014-06-05 15:22       ` Vivek Goyal
2014-06-05 15:22         ` Vivek Goyal
2014-06-06  6:34         ` WANG Chao
2014-06-06  6:34           ` WANG Chao
2014-06-03 13:06 ` [PATCH 07/13] kexec: Implementation of new syscall kexec_file_load Vivek Goyal
2014-06-03 13:06   ` Vivek Goyal
2014-06-05 11:15   ` Borislav Petkov
2014-06-05 11:15     ` Borislav Petkov
2014-06-05 20:17     ` Vivek Goyal
2014-06-05 20:17       ` Vivek Goyal
2014-06-06  2:11       ` Borislav Petkov
2014-06-06  2:11         ` Borislav Petkov
2014-06-06 18:02         ` Vivek Goyal
2014-06-06 18:02           ` Vivek Goyal
2014-06-11 14:13           ` Borislav Petkov
2014-06-11 14:13             ` Borislav Petkov
2014-06-11 17:04             ` Vivek Goyal
2014-06-11 17:04               ` Vivek Goyal
2014-06-06  6:56   ` WANG Chao
2014-06-06  6:56     ` WANG Chao
2014-06-06 18:19     ` Vivek Goyal
2014-06-06 18:19       ` Vivek Goyal
2014-06-09  2:11       ` Dave Young
2014-06-09  2:11         ` Dave Young
2014-06-09  5:35         ` WANG Chao
2014-06-09  5:35           ` WANG Chao
2014-06-09 15:41           ` Vivek Goyal
2014-06-09 15:41             ` Vivek Goyal
2014-06-13  7:50             ` Borislav Petkov
2014-06-13  7:50               ` Borislav Petkov
2014-06-13  8:00               ` WANG Chao
2014-06-13  8:00                 ` WANG Chao
2014-06-13  8:10                 ` Borislav Petkov
2014-06-13  8:10                   ` Borislav Petkov
2014-06-13  8:24                   ` WANG Chao
2014-06-13  8:24                     ` WANG Chao
2014-06-13  8:30                     ` Borislav Petkov
2014-06-13  8:30                       ` Borislav Petkov
2014-06-13 12:49                 ` Vivek Goyal
2014-06-13 12:49                   ` Vivek Goyal
2014-06-13 12:46               ` Vivek Goyal
2014-06-13 12:46                 ` Vivek Goyal
2014-06-13 15:36                 ` Borislav Petkov
2014-06-13 15:36                   ` Borislav Petkov
2014-06-16 17:38                   ` Vivek Goyal
2014-06-16 17:38                     ` Vivek Goyal
2014-06-16 20:05                     ` Borislav Petkov
2014-06-16 20:05                       ` Borislav Petkov
2014-06-16 20:53                       ` Vivek Goyal
2014-06-16 20:53                         ` Vivek Goyal
2014-06-16 21:09                         ` Borislav Petkov
2014-06-16 21:09                           ` Borislav Petkov
2014-06-16 21:25                           ` H. Peter Anvin
2014-06-16 21:25                             ` H. Peter Anvin
2014-06-16 21:43                             ` Vivek Goyal
2014-06-16 21:43                               ` Vivek Goyal
2014-06-16 22:10                               ` Borislav Petkov
2014-06-16 22:10                                 ` Borislav Petkov
2014-06-16 22:49                               ` H. Peter Anvin
2014-06-16 22:49                                 ` H. Peter Anvin
2014-06-09 15:30         ` Vivek Goyal
2014-06-09 15:30           ` Vivek Goyal
2014-06-03 13:06 ` [PATCH 08/13] purgatory/sha256: Provide implementation of sha256 in purgaotory context Vivek Goyal
2014-06-03 13:06   ` Vivek Goyal
2014-06-03 13:06 ` Vivek Goyal [this message]
2014-06-03 13:06   ` [PATCH 09/13] purgatory: Core purgatory functionality Vivek Goyal
2014-06-05 20:05   ` Borislav Petkov
2014-06-05 20:05     ` Borislav Petkov
2014-06-06 19:51     ` Vivek Goyal
2014-06-06 19:51       ` Vivek Goyal
2014-06-13 10:17       ` Borislav Petkov
2014-06-13 10:17         ` Borislav Petkov
2014-06-16 17:25         ` Vivek Goyal
2014-06-16 17:25           ` Vivek Goyal
2014-06-16 20:10           ` Borislav Petkov
2014-06-16 20:10             ` Borislav Petkov
2014-06-03 13:06 ` [PATCH 10/13] kexec: Load and Relocate purgatory at kernel load time Vivek Goyal
2014-06-03 13:06   ` Vivek Goyal
2014-06-10 16:31   ` Borislav Petkov
2014-06-10 16:31     ` Borislav Petkov
2014-06-11 19:24     ` Vivek Goyal
2014-06-11 19:24       ` Vivek Goyal
2014-06-13 16:14       ` Borislav Petkov
2014-06-13 16:14         ` Borislav Petkov
2014-06-03 13:07 ` [PATCH 11/13] kexec-bzImage: Support for loading bzImage using 64bit entry Vivek Goyal
2014-06-03 13:07   ` Vivek Goyal
2014-06-15 16:35   ` Borislav Petkov
2014-06-15 16:35     ` Borislav Petkov
2014-06-15 16:56     ` H. Peter Anvin
2014-06-15 16:56       ` H. Peter Anvin
2014-06-16 20:06     ` Vivek Goyal
2014-06-16 20:06       ` Vivek Goyal
2014-06-16 20:57       ` Borislav Petkov
2014-06-16 20:57         ` Borislav Petkov
2014-06-16 21:15         ` Vivek Goyal
2014-06-16 21:15           ` Vivek Goyal
2014-06-16 21:27           ` Borislav Petkov
2014-06-16 21:27             ` Borislav Petkov
2014-06-16 21:45             ` Vivek Goyal
2014-06-16 21:45               ` Vivek Goyal
2014-06-24 17:31     ` Vivek Goyal
2014-06-24 17:31       ` Vivek Goyal
2014-06-24 18:23       ` Borislav Petkov
2014-06-24 18:23         ` Borislav Petkov
2014-06-03 13:07 ` [PATCH 12/13] kexec: Support for Kexec on panic using new system call Vivek Goyal
2014-06-03 13:07   ` Vivek Goyal
2014-06-17 21:43   ` Borislav Petkov
2014-06-17 21:43     ` Borislav Petkov
2014-06-18 14:20     ` Vivek Goyal
2014-06-18 14:20       ` Vivek Goyal
2014-06-03 13:07 ` [PATCH 13/13] kexec: Support kexec/kdump on EFI systems Vivek Goyal
2014-06-03 13:07   ` Vivek Goyal
2014-06-18 15:43   ` Borislav Petkov
2014-06-18 15:43     ` Borislav Petkov
2014-06-18 16:06   ` Borislav Petkov
2014-06-18 16:06     ` Borislav Petkov
2014-06-18 16:06     ` Borislav Petkov
2014-06-18 17:39     ` Vivek Goyal
2014-06-18 17:39       ` Vivek Goyal
2014-06-18 17:39       ` Vivek Goyal
2014-06-03 13:12 ` [RFC PATCH 00/13][V3] kexec: A new system call to allow in kernel loading Vivek Goyal
2014-06-03 13:12   ` Vivek Goyal
2014-06-04  9:22   ` WANG Chao
2014-06-04  9:22     ` WANG Chao
2014-06-04 17:50     ` Vivek Goyal
2014-06-04 17:50       ` Vivek Goyal
2014-06-04 19:39       ` Michael Kerrisk
2014-06-04 19:39         ` Michael Kerrisk
2014-06-04 19:39         ` Michael Kerrisk
2014-06-05 14:04         ` Vivek Goyal
2014-06-05 14:04           ` Vivek Goyal
2014-06-05 14:04           ` Vivek Goyal
2014-06-06  5:45           ` Michael Kerrisk (man-pages)
2014-06-06  5:45             ` Michael Kerrisk (man-pages)
2014-06-06  5:45             ` Michael Kerrisk (man-pages)
2014-06-06 18:04             ` Vivek Goyal
2014-06-06 18:04               ` Vivek Goyal
2014-06-06 18:04               ` Vivek Goyal
2014-06-05  8:31   ` Dave Young
2014-06-05  8:31     ` Dave Young
2014-06-05 15:01     ` Vivek Goyal
2014-06-05 15:01       ` Vivek Goyal
2014-06-06  7:37       ` Dave Young
2014-06-06  7:37         ` Dave Young
2014-06-06 20:04         ` Vivek Goyal
2014-06-06 20:04           ` Vivek Goyal
2014-06-09  1:57           ` Dave Young
2014-06-09  1:57             ` Dave Young
2014-06-06 20:37         ` H. Peter Anvin
2014-06-06 20:37           ` H. Peter Anvin
2014-06-06 20:58           ` Matt Fleming
2014-06-06 20:58             ` Matt Fleming
2014-06-06 21:00             ` H. Peter Anvin
2014-06-06 21:00               ` H. Peter Anvin
2014-06-06 21:02               ` Matt Fleming
2014-06-06 21:02                 ` Matt Fleming
2014-06-12  5:42 ` Dave Young
2014-06-12  5:42   ` Dave Young
2014-06-12 12:36   ` Vivek Goyal
2014-06-12 12:36     ` Vivek Goyal
2014-06-17 14:24   ` Vivek Goyal
2014-06-17 14:24     ` Vivek Goyal
2014-06-18  1:45     ` Dave Young
2014-06-18  1:45       ` Dave Young
2014-06-18  1:52       ` Dave Young
2014-06-18  1:52         ` Dave Young
2014-06-18 12:40         ` Vivek Goyal
2014-06-18 12:40           ` Vivek Goyal
2014-06-16 21:13 ` Borislav Petkov
2014-06-16 21:13   ` Borislav Petkov
2014-06-17 13:24   ` Vivek Goyal
2014-06-17 13:24     ` Vivek Goyal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1401800822-27425-10-git-send-email-vgoyal@redhat.com \
    --to=vgoyal@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=bhe@redhat.com \
    --cc=bp@alien8.de \
    --cc=chaowang@redhat.com \
    --cc=dyoung@redhat.com \
    --cc=ebiederm@xmission.com \
    --cc=greg@kroah.com \
    --cc=hpa@zytor.com \
    --cc=jkosina@suse.cz \
    --cc=kexec@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mjg59@srcf.ucam.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.