13
13
#include <linux/numa.h>
14
14
#include <linux/ftrace.h>
15
15
#include <linux/suspend.h>
16
+ #include <linux/gfp.h>
16
17
17
18
#include <asm/pgtable.h>
18
19
#include <asm/pgalloc.h>
25
26
#include <asm/system.h>
26
27
#include <asm/cacheflush.h>
27
28
28
- #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
29
- static u32 kexec_pgd [1024 ] PAGE_ALIGNED ;
30
- #ifdef CONFIG_X86_PAE
31
- static u32 kexec_pmd0 [1024 ] PAGE_ALIGNED ;
32
- static u32 kexec_pmd1 [1024 ] PAGE_ALIGNED ;
33
- #endif
34
- static u32 kexec_pte0 [1024 ] PAGE_ALIGNED ;
35
- static u32 kexec_pte1 [1024 ] PAGE_ALIGNED ;
36
-
37
29
static void set_idt (void * newidt , __u16 limit )
38
30
{
39
31
struct desc_ptr curidt ;
@@ -76,6 +68,37 @@ static void load_segments(void)
76
68
#undef __STR
77
69
}
78
70
71
+ static void machine_kexec_free_page_tables (struct kimage * image )
72
+ {
73
+ free_page ((unsigned long )image -> arch .pgd );
74
+ #ifdef CONFIG_X86_PAE
75
+ free_page ((unsigned long )image -> arch .pmd0 );
76
+ free_page ((unsigned long )image -> arch .pmd1 );
77
+ #endif
78
+ free_page ((unsigned long )image -> arch .pte0 );
79
+ free_page ((unsigned long )image -> arch .pte1 );
80
+ }
81
+
82
+ static int machine_kexec_alloc_page_tables (struct kimage * image )
83
+ {
84
+ image -> arch .pgd = (pgd_t * )get_zeroed_page (GFP_KERNEL );
85
+ #ifdef CONFIG_X86_PAE
86
+ image -> arch .pmd0 = (pmd_t * )get_zeroed_page (GFP_KERNEL );
87
+ image -> arch .pmd1 = (pmd_t * )get_zeroed_page (GFP_KERNEL );
88
+ #endif
89
+ image -> arch .pte0 = (pte_t * )get_zeroed_page (GFP_KERNEL );
90
+ image -> arch .pte1 = (pte_t * )get_zeroed_page (GFP_KERNEL );
91
+ if (!image -> arch .pgd ||
92
+ #ifdef CONFIG_X86_PAE
93
+ !image -> arch .pmd0 || !image -> arch .pmd1 ||
94
+ #endif
95
+ !image -> arch .pte0 || !image -> arch .pte1 ) {
96
+ machine_kexec_free_page_tables (image );
97
+ return - ENOMEM ;
98
+ }
99
+ return 0 ;
100
+ }
101
+
79
102
/*
80
103
* A architecture hook called to validate the
81
104
* proposed image and prepare the control pages
@@ -87,13 +110,14 @@ static void load_segments(void)
87
110
* reboot code buffer to allow us to avoid allocations
88
111
* later.
89
112
*
90
- * Make control page executable.
113
+ * - Make control page executable.
114
+ * - Allocate page tables
91
115
*/
92
116
int machine_kexec_prepare (struct kimage * image )
93
117
{
94
118
if (nx_enabled )
95
119
set_pages_x (image -> control_code_page , 1 );
96
- return 0 ;
120
+ return machine_kexec_alloc_page_tables ( image ) ;
97
121
}
98
122
99
123
/*
@@ -104,6 +128,7 @@ void machine_kexec_cleanup(struct kimage *image)
104
128
{
105
129
if (nx_enabled )
106
130
set_pages_nx (image -> control_code_page , 1 );
131
+ machine_kexec_free_page_tables (image );
107
132
}
108
133
109
134
/*
@@ -150,18 +175,18 @@ void machine_kexec(struct kimage *image)
150
175
relocate_kernel_ptr = control_page ;
151
176
page_list [PA_CONTROL_PAGE ] = __pa (control_page );
152
177
page_list [VA_CONTROL_PAGE ] = (unsigned long )control_page ;
153
- page_list [PA_PGD ] = __pa (kexec_pgd );
154
- page_list [VA_PGD ] = (unsigned long )kexec_pgd ;
178
+ page_list [PA_PGD ] = __pa (image -> arch . pgd );
179
+ page_list [VA_PGD ] = (unsigned long )image -> arch . pgd ;
155
180
#ifdef CONFIG_X86_PAE
156
- page_list [PA_PMD_0 ] = __pa (kexec_pmd0 );
157
- page_list [VA_PMD_0 ] = (unsigned long )kexec_pmd0 ;
158
- page_list [PA_PMD_1 ] = __pa (kexec_pmd1 );
159
- page_list [VA_PMD_1 ] = (unsigned long )kexec_pmd1 ;
181
+ page_list [PA_PMD_0 ] = __pa (image -> arch . pmd0 );
182
+ page_list [VA_PMD_0 ] = (unsigned long )image -> arch . pmd0 ;
183
+ page_list [PA_PMD_1 ] = __pa (image -> arch . pmd1 );
184
+ page_list [VA_PMD_1 ] = (unsigned long )image -> arch . pmd1 ;
160
185
#endif
161
- page_list [PA_PTE_0 ] = __pa (kexec_pte0 );
162
- page_list [VA_PTE_0 ] = (unsigned long )kexec_pte0 ;
163
- page_list [PA_PTE_1 ] = __pa (kexec_pte1 );
164
- page_list [VA_PTE_1 ] = (unsigned long )kexec_pte1 ;
186
+ page_list [PA_PTE_0 ] = __pa (image -> arch . pte0 );
187
+ page_list [VA_PTE_0 ] = (unsigned long )image -> arch . pte0 ;
188
+ page_list [PA_PTE_1 ] = __pa (image -> arch . pte1 );
189
+ page_list [VA_PTE_1 ] = (unsigned long )image -> arch . pte1 ;
165
190
166
191
if (image -> type == KEXEC_TYPE_DEFAULT )
167
192
page_list [PA_SWAP_PAGE ] = (page_to_pfn (image -> swap_page )
0 commit comments