aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/purgatory/trampoline.S12
-rw-r--r--arch/x86/include/asm/purgatory.h20
-rw-r--r--arch/x86/kernel/machine_kexec_64.c9
-rw-r--r--arch/x86/purgatory/purgatory.c35
-rw-r--r--arch/x86/purgatory/purgatory.h8
-rw-r--r--arch/x86/purgatory/setup-x86_64.S2
-rw-r--r--arch/x86/purgatory/sha256.h1
-rw-r--r--include/linux/purgatory.h23
-rw-r--r--kernel/kexec_file.c8
-rw-r--r--kernel/kexec_internal.h6
10 files changed, 78 insertions, 46 deletions
diff --git a/arch/powerpc/purgatory/trampoline.S b/arch/powerpc/purgatory/trampoline.S
index f9760ccf4032..3696ea6c4826 100644
--- a/arch/powerpc/purgatory/trampoline.S
+++ b/arch/powerpc/purgatory/trampoline.S
@@ -116,13 +116,13 @@ dt_offset:
116 116
117 .data 117 .data
118 .balign 8 118 .balign 8
119.globl sha256_digest 119.globl purgatory_sha256_digest
120sha256_digest: 120purgatory_sha256_digest:
121 .skip 32 121 .skip 32
122 .size sha256_digest, . - sha256_digest 122 .size purgatory_sha256_digest, . - purgatory_sha256_digest
123 123
124 .balign 8 124 .balign 8
125.globl sha_regions 125.globl purgatory_sha_regions
126sha_regions: 126purgatory_sha_regions:
127 .skip 8 * 2 * 16 127 .skip 8 * 2 * 16
128 .size sha_regions, . - sha_regions 128 .size purgatory_sha_regions, . - purgatory_sha_regions
diff --git a/arch/x86/include/asm/purgatory.h b/arch/x86/include/asm/purgatory.h
new file mode 100644
index 000000000000..d7da2729903d
--- /dev/null
+++ b/arch/x86/include/asm/purgatory.h
@@ -0,0 +1,20 @@
1#ifndef _ASM_X86_PURGATORY_H
2#define _ASM_X86_PURGATORY_H
3
4#ifndef __ASSEMBLY__
5#include <linux/purgatory.h>
6
7extern void purgatory(void);
8/*
9 * These forward declarations serve two purposes:
10 *
11 * 1) Make sparse happy when checking arch/purgatory
12 * 2) Document that these are required to be global so the symbol
13 * lookup in kexec works
14 */
15extern unsigned long purgatory_backup_dest;
16extern unsigned long purgatory_backup_src;
17extern unsigned long purgatory_backup_sz;
18#endif /* __ASSEMBLY__ */
19
20#endif /* _ASM_PURGATORY_H */
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index 307b1f4543de..857cdbd02867 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -194,19 +194,22 @@ static int arch_update_purgatory(struct kimage *image)
194 194
195 /* Setup copying of backup region */ 195 /* Setup copying of backup region */
196 if (image->type == KEXEC_TYPE_CRASH) { 196 if (image->type == KEXEC_TYPE_CRASH) {
197 ret = kexec_purgatory_get_set_symbol(image, "backup_dest", 197 ret = kexec_purgatory_get_set_symbol(image,
198 "purgatory_backup_dest",
198 &image->arch.backup_load_addr, 199 &image->arch.backup_load_addr,
199 sizeof(image->arch.backup_load_addr), 0); 200 sizeof(image->arch.backup_load_addr), 0);
200 if (ret) 201 if (ret)
201 return ret; 202 return ret;
202 203
203 ret = kexec_purgatory_get_set_symbol(image, "backup_src", 204 ret = kexec_purgatory_get_set_symbol(image,
205 "purgatory_backup_src",
204 &image->arch.backup_src_start, 206 &image->arch.backup_src_start,
205 sizeof(image->arch.backup_src_start), 0); 207 sizeof(image->arch.backup_src_start), 0);
206 if (ret) 208 if (ret)
207 return ret; 209 return ret;
208 210
209 ret = kexec_purgatory_get_set_symbol(image, "backup_sz", 211 ret = kexec_purgatory_get_set_symbol(image,
212 "purgatory_backup_sz",
210 &image->arch.backup_src_sz, 213 &image->arch.backup_src_sz,
211 sizeof(image->arch.backup_src_sz), 0); 214 sizeof(image->arch.backup_src_sz), 0);
212 if (ret) 215 if (ret)
diff --git a/arch/x86/purgatory/purgatory.c b/arch/x86/purgatory/purgatory.c
index b6d5c8946e66..470edad96bb9 100644
--- a/arch/x86/purgatory/purgatory.c
+++ b/arch/x86/purgatory/purgatory.c
@@ -10,22 +10,19 @@
10 * Version 2. See the file COPYING for more details. 10 * Version 2. See the file COPYING for more details.
11 */ 11 */
12 12
13#include <linux/bug.h>
14#include <asm/purgatory.h>
15
13#include "sha256.h" 16#include "sha256.h"
14#include "purgatory.h"
15#include "../boot/string.h" 17#include "../boot/string.h"
16 18
17struct sha_region { 19unsigned long purgatory_backup_dest __section(.kexec-purgatory);
18 unsigned long start; 20unsigned long purgatory_backup_src __section(.kexec-purgatory);
19 unsigned long len; 21unsigned long purgatory_backup_sz __section(.kexec-purgatory);
20};
21
22static unsigned long backup_dest;
23static unsigned long backup_src;
24static unsigned long backup_sz;
25 22
26static u8 sha256_digest[SHA256_DIGEST_SIZE] = { 0 }; 23u8 purgatory_sha256_digest[SHA256_DIGEST_SIZE] __section(.kexec-purgatory);
27 24
28struct sha_region sha_regions[16] = {}; 25struct kexec_sha_region purgatory_sha_regions[KEXEC_SEGMENT_MAX] __section(.kexec-purgatory);
29 26
30/* 27/*
31 * On x86, second kernel requries first 640K of memory to boot. Copy 28 * On x86, second kernel requries first 640K of memory to boot. Copy
@@ -34,26 +31,28 @@ struct sha_region sha_regions[16] = {};
34 */ 31 */
35static int copy_backup_region(void) 32static int copy_backup_region(void)
36{ 33{
37 if (backup_dest) 34 if (purgatory_backup_dest) {
38 memcpy((void *)backup_dest, (void *)backup_src, backup_sz); 35 memcpy((void *)purgatory_backup_dest,
39 36 (void *)purgatory_backup_src, purgatory_backup_sz);
37 }
40 return 0; 38 return 0;
41} 39}
42 40
43static int verify_sha256_digest(void) 41static int verify_sha256_digest(void)
44{ 42{
45 struct sha_region *ptr, *end; 43 struct kexec_sha_region *ptr, *end;
46 u8 digest[SHA256_DIGEST_SIZE]; 44 u8 digest[SHA256_DIGEST_SIZE];
47 struct sha256_state sctx; 45 struct sha256_state sctx;
48 46
49 sha256_init(&sctx); 47 sha256_init(&sctx);
50 end = &sha_regions[sizeof(sha_regions)/sizeof(sha_regions[0])]; 48 end = purgatory_sha_regions + ARRAY_SIZE(purgatory_sha_regions);
51 for (ptr = sha_regions; ptr < end; ptr++) 49
50 for (ptr = purgatory_sha_regions; ptr < end; ptr++)
52 sha256_update(&sctx, (uint8_t *)(ptr->start), ptr->len); 51 sha256_update(&sctx, (uint8_t *)(ptr->start), ptr->len);
53 52
54 sha256_final(&sctx, digest); 53 sha256_final(&sctx, digest);
55 54
56 if (memcmp(digest, sha256_digest, sizeof(digest))) 55 if (memcmp(digest, purgatory_sha256_digest, sizeof(digest)))
57 return 1; 56 return 1;
58 57
59 return 0; 58 return 0;
diff --git a/arch/x86/purgatory/purgatory.h b/arch/x86/purgatory/purgatory.h
deleted file mode 100644
index e2e365a6c192..000000000000
--- a/arch/x86/purgatory/purgatory.h
+++ /dev/null
@@ -1,8 +0,0 @@
1#ifndef PURGATORY_H
2#define PURGATORY_H
3
4#ifndef __ASSEMBLY__
5extern void purgatory(void);
6#endif /* __ASSEMBLY__ */
7
8#endif /* PURGATORY_H */
diff --git a/arch/x86/purgatory/setup-x86_64.S b/arch/x86/purgatory/setup-x86_64.S
index f90e9dfa90bb..dfae9b9e60b5 100644
--- a/arch/x86/purgatory/setup-x86_64.S
+++ b/arch/x86/purgatory/setup-x86_64.S
@@ -9,7 +9,7 @@
9 * This source code is licensed under the GNU General Public License, 9 * This source code is licensed under the GNU General Public License,
10 * Version 2. See the file COPYING for more details. 10 * Version 2. See the file COPYING for more details.
11 */ 11 */
12#include "purgatory.h" 12#include <asm/purgatory.h>
13 13
14 .text 14 .text
15 .globl purgatory_start 15 .globl purgatory_start
diff --git a/arch/x86/purgatory/sha256.h b/arch/x86/purgatory/sha256.h
index bd15a4127735..2867d9825a57 100644
--- a/arch/x86/purgatory/sha256.h
+++ b/arch/x86/purgatory/sha256.h
@@ -10,7 +10,6 @@
10#ifndef SHA256_H 10#ifndef SHA256_H
11#define SHA256_H 11#define SHA256_H
12 12
13
14#include <linux/types.h> 13#include <linux/types.h>
15#include <crypto/sha.h> 14#include <crypto/sha.h>
16 15
diff --git a/include/linux/purgatory.h b/include/linux/purgatory.h
new file mode 100644
index 000000000000..d60d4e278609
--- /dev/null
+++ b/include/linux/purgatory.h
@@ -0,0 +1,23 @@
1#ifndef _LINUX_PURGATORY_H
2#define _LINUX_PURGATORY_H
3
4#include <linux/types.h>
5#include <crypto/sha.h>
6#include <uapi/linux/kexec.h>
7
8struct kexec_sha_region {
9 unsigned long start;
10 unsigned long len;
11};
12
13/*
14 * These forward declarations serve two purposes:
15 *
16 * 1) Make sparse happy when checking arch/purgatory
17 * 2) Document that these are required to be global so the symbol
18 * lookup in kexec works
19 */
20extern struct kexec_sha_region purgatory_sha_regions[KEXEC_SEGMENT_MAX];
21extern u8 purgatory_sha256_digest[SHA256_DIGEST_SIZE];
22
23#endif
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index b56a558e406d..b118735fea9d 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -614,13 +614,13 @@ static int kexec_calculate_store_digests(struct kimage *image)
614 ret = crypto_shash_final(desc, digest); 614 ret = crypto_shash_final(desc, digest);
615 if (ret) 615 if (ret)
616 goto out_free_digest; 616 goto out_free_digest;
617 ret = kexec_purgatory_get_set_symbol(image, "sha_regions", 617 ret = kexec_purgatory_get_set_symbol(image, "purgatory_sha_regions",
618 sha_regions, sha_region_sz, 0); 618 sha_regions, sha_region_sz, 0);
619 if (ret) 619 if (ret)
620 goto out_free_digest; 620 goto out_free_digest;
621 621
622 ret = kexec_purgatory_get_set_symbol(image, "sha256_digest", 622 ret = kexec_purgatory_get_set_symbol(image, "purgatory_sha256_digest",
623 digest, SHA256_DIGEST_SIZE, 0); 623 digest, SHA256_DIGEST_SIZE, 0);
624 if (ret) 624 if (ret)
625 goto out_free_digest; 625 goto out_free_digest;
626 } 626 }
diff --git a/kernel/kexec_internal.h b/kernel/kexec_internal.h
index 4cef7e4706b0..799a8a452187 100644
--- a/kernel/kexec_internal.h
+++ b/kernel/kexec_internal.h
@@ -15,11 +15,7 @@ int kimage_is_destination_range(struct kimage *image,
15extern struct mutex kexec_mutex; 15extern struct mutex kexec_mutex;
16 16
17#ifdef CONFIG_KEXEC_FILE 17#ifdef CONFIG_KEXEC_FILE
18struct kexec_sha_region { 18#include <linux/purgatory.h>
19 unsigned long start;
20 unsigned long len;
21};
22
23void kimage_file_post_load_cleanup(struct kimage *image); 19void kimage_file_post_load_cleanup(struct kimage *image);
24#else /* CONFIG_KEXEC_FILE */ 20#else /* CONFIG_KEXEC_FILE */
25static inline void kimage_file_post_load_cleanup(struct kimage *image) { } 21static inline void kimage_file_post_load_cleanup(struct kimage *image) { }