aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/purgatory/entry64.S
diff options
context:
space:
mode:
authorVivek Goyal <vgoyal@redhat.com>2014-08-08 17:26:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-08 18:57:32 -0400
commit8fc5b4d4121c95482b2583a07863c6b0aba2d9e1 (patch)
tree16ef44c15e9802c1aed83d8eead0569822268794 /arch/x86/purgatory/entry64.S
parentdaeba0641a707626f3674db71016f333edf64395 (diff)
purgatory: core purgatory functionality
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. [sfr@canb.auug.org.au: run host built programs from objtree] Signed-off-by: Vivek Goyal <vgoyal@redhat.com> Cc: Borislav Petkov <bp@suse.de> Cc: Michael Kerrisk <mtk.manpages@gmail.com> Cc: Yinghai Lu <yinghai@kernel.org> Cc: Eric Biederman <ebiederm@xmission.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Matthew Garrett <mjg59@srcf.ucam.org> Cc: Greg Kroah-Hartman <greg@kroah.com> Cc: Dave Young <dyoung@redhat.com> Cc: WANG Chao <chaowang@redhat.com> Cc: Baoquan He <bhe@redhat.com> Cc: Andy Lutomirski <luto@amacapital.net> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/x86/purgatory/entry64.S')
-rw-r--r--arch/x86/purgatory/entry64.S101
1 files changed, 101 insertions, 0 deletions
diff --git a/arch/x86/purgatory/entry64.S b/arch/x86/purgatory/entry64.S
new file mode 100644
index 000000000000..be3249d7ed2d
--- /dev/null
+++ b/arch/x86/purgatory/entry64.S
@@ -0,0 +1,101 @@
1/*
2 * Copyright (C) 2003,2004 Eric Biederman (ebiederm@xmission.com)
3 * Copyright (C) 2014 Red Hat Inc.
4
5 * Author(s): Vivek Goyal <vgoyal@redhat.com>
6 *
7 * This code has been taken from kexec-tools.
8 *
9 * This source code is licensed under the GNU General Public License,
10 * Version 2. See the file COPYING for more details.
11 */
12
13 .text
14 .balign 16
15 .code64
16 .globl entry64, entry64_regs
17
18
19entry64:
20 /* Setup a gdt that should be preserved */
21 lgdt gdt(%rip)
22
23 /* load the data segments */
24 movl $0x18, %eax /* data segment */
25 movl %eax, %ds
26 movl %eax, %es
27 movl %eax, %ss
28 movl %eax, %fs
29 movl %eax, %gs
30
31 /* Setup new stack */
32 leaq stack_init(%rip), %rsp
33 pushq $0x10 /* CS */
34 leaq new_cs_exit(%rip), %rax
35 pushq %rax
36 lretq
37new_cs_exit:
38
39 /* Load the registers */
40 movq rax(%rip), %rax
41 movq rbx(%rip), %rbx
42 movq rcx(%rip), %rcx
43 movq rdx(%rip), %rdx
44 movq rsi(%rip), %rsi
45 movq rdi(%rip), %rdi
46 movq rsp(%rip), %rsp
47 movq rbp(%rip), %rbp
48 movq r8(%rip), %r8
49 movq r9(%rip), %r9
50 movq r10(%rip), %r10
51 movq r11(%rip), %r11
52 movq r12(%rip), %r12
53 movq r13(%rip), %r13
54 movq r14(%rip), %r14
55 movq r15(%rip), %r15
56
57 /* Jump to the new code... */
58 jmpq *rip(%rip)
59
60 .section ".rodata"
61 .balign 4
62entry64_regs:
63rax: .quad 0x0
64rbx: .quad 0x0
65rcx: .quad 0x0
66rdx: .quad 0x0
67rsi: .quad 0x0
68rdi: .quad 0x0
69rsp: .quad 0x0
70rbp: .quad 0x0
71r8: .quad 0x0
72r9: .quad 0x0
73r10: .quad 0x0
74r11: .quad 0x0
75r12: .quad 0x0
76r13: .quad 0x0
77r14: .quad 0x0
78r15: .quad 0x0
79rip: .quad 0x0
80 .size entry64_regs, . - entry64_regs
81
82 /* GDT */
83 .section ".rodata"
84 .balign 16
85gdt:
86 /* 0x00 unusable segment
87 * 0x08 unused
88 * so use them as gdt ptr
89 */
90 .word gdt_end - gdt - 1
91 .quad gdt
92 .word 0, 0, 0
93
94 /* 0x10 4GB flat code segment */
95 .word 0xFFFF, 0x0000, 0x9A00, 0x00AF
96
97 /* 0x18 4GB flat data segment */
98 .word 0xFFFF, 0x0000, 0x9200, 0x00CF
99gdt_end:
100stack: .quad 0, 0
101stack_init: