]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - arch/x86_64/kernel/relocate_kernel.S
[PATCH] kexec: x86_64 kexec implementation
[mirror_ubuntu-bionic-kernel.git] / arch / x86_64 / kernel / relocate_kernel.S
CommitLineData
5234f5eb
EB
1/*
2 * relocate_kernel.S - put the kernel image in place to boot
3 * Copyright (C) 2002-2005 Eric Biederman <ebiederm@xmission.com>
4 *
5 * This source code is licensed under the GNU General Public License,
6 * Version 2. See the file COPYING for more details.
7 */
8
9#include <linux/linkage.h>
10
11 /*
12 * Must be relocatable PIC code callable as a C function, that once
13 * it starts can not use the previous processes stack.
14 */
15 .globl relocate_new_kernel
16 .code64
17relocate_new_kernel:
18 /* %rdi page_list
19 * %rsi reboot_code_buffer
20 * %rdx start address
21 * %rcx page_table
22 * %r8 arg5
23 * %r9 arg6
24 */
25
26 /* zero out flags, and disable interrupts */
27 pushq $0
28 popfq
29
30 /* set a new stack at the bottom of our page... */
31 lea 4096(%rsi), %rsp
32
33 /* store the parameters back on the stack */
34 pushq %rdx /* store the start address */
35
36 /* Set cr0 to a known state:
37 * 31 1 == Paging enabled
38 * 18 0 == Alignment check disabled
39 * 16 0 == Write protect disabled
40 * 3 0 == No task switch
41 * 2 0 == Don't do FP software emulation.
42 * 0 1 == Proctected mode enabled
43 */
44 movq %cr0, %rax
45 andq $~((1<<18)|(1<<16)|(1<<3)|(1<<2)), %rax
46 orl $((1<<31)|(1<<0)), %eax
47 movq %rax, %cr0
48
49 /* Set cr4 to a known state:
50 * 10 0 == xmm exceptions disabled
51 * 9 0 == xmm registers instructions disabled
52 * 8 0 == performance monitoring counter disabled
53 * 7 0 == page global disabled
54 * 6 0 == machine check exceptions disabled
55 * 5 1 == physical address extension enabled
56 * 4 0 == page size extensions disabled
57 * 3 0 == Debug extensions disabled
58 * 2 0 == Time stamp disable (disabled)
59 * 1 0 == Protected mode virtual interrupts disabled
60 * 0 0 == VME disabled
61 */
62
63 movq $((1<<5)), %rax
64 movq %rax, %cr4
65
66 jmp 1f
671:
68
69 /* Switch to the identity mapped page tables,
70 * and flush the TLB.
71 */
72 movq %rcx, %cr3
73
74 /* Do the copies */
75 movq %rdi, %rcx /* Put the page_list in %rcx */
76 xorq %rdi, %rdi
77 xorq %rsi, %rsi
78 jmp 1f
79
800: /* top, read another word for the indirection page */
81
82 movq (%rbx), %rcx
83 addq $8, %rbx
841:
85 testq $0x1, %rcx /* is it a destination page? */
86 jz 2f
87 movq %rcx, %rdi
88 andq $0xfffffffffffff000, %rdi
89 jmp 0b
902:
91 testq $0x2, %rcx /* is it an indirection page? */
92 jz 2f
93 movq %rcx, %rbx
94 andq $0xfffffffffffff000, %rbx
95 jmp 0b
962:
97 testq $0x4, %rcx /* is it the done indicator? */
98 jz 2f
99 jmp 3f
1002:
101 testq $0x8, %rcx /* is it the source indicator? */
102 jz 0b /* Ignore it otherwise */
103 movq %rcx, %rsi /* For ever source page do a copy */
104 andq $0xfffffffffffff000, %rsi
105
106 movq $512, %rcx
107 rep ; movsq
108 jmp 0b
1093:
110
111 /* To be certain of avoiding problems with self-modifying code
112 * I need to execute a serializing instruction here.
113 * So I flush the TLB by reloading %cr3 here, it's handy,
114 * and not processor dependent.
115 */
116 movq %cr3, %rax
117 movq %rax, %cr3
118
119 /* set all of the registers to known values */
120 /* leave %rsp alone */
121
122 xorq %rax, %rax
123 xorq %rbx, %rbx
124 xorq %rcx, %rcx
125 xorq %rdx, %rdx
126 xorq %rsi, %rsi
127 xorq %rdi, %rdi
128 xorq %rbp, %rbp
129 xorq %r8, %r8
130 xorq %r9, %r9
131 xorq %r10, %r9
132 xorq %r11, %r11
133 xorq %r12, %r12
134 xorq %r13, %r13
135 xorq %r14, %r14
136 xorq %r15, %r15
137
138 ret
139relocate_new_kernel_end:
140
141 .globl relocate_new_kernel_size
142relocate_new_kernel_size:
143 .quad relocate_new_kernel_end - relocate_new_kernel