diff options
-rw-r--r-- | arch/x86/include/asm/init.h | 4 | ||||
-rw-r--r-- | arch/x86/mm/ident_map.c | 19 | ||||
-rw-r--r-- | arch/x86/power/hibernate_64.c | 2 |
3 files changed, 14 insertions, 11 deletions
diff --git a/arch/x86/include/asm/init.h b/arch/x86/include/asm/init.h index 223042086f4e..737da62bfeb0 100644 --- a/arch/x86/include/asm/init.h +++ b/arch/x86/include/asm/init.h | |||
@@ -5,10 +5,10 @@ struct x86_mapping_info { | |||
5 | void *(*alloc_pgt_page)(void *); /* allocate buf for page table */ | 5 | void *(*alloc_pgt_page)(void *); /* allocate buf for page table */ |
6 | void *context; /* context for alloc_pgt_page */ | 6 | void *context; /* context for alloc_pgt_page */ |
7 | unsigned long pmd_flag; /* page flag for PMD entry */ | 7 | unsigned long pmd_flag; /* page flag for PMD entry */ |
8 | bool kernel_mapping; /* kernel mapping or ident mapping */ | 8 | unsigned long offset; /* ident mapping offset */ |
9 | }; | 9 | }; |
10 | 10 | ||
11 | int kernel_ident_mapping_init(struct x86_mapping_info *info, pgd_t *pgd_page, | 11 | int kernel_ident_mapping_init(struct x86_mapping_info *info, pgd_t *pgd_page, |
12 | unsigned long addr, unsigned long end); | 12 | unsigned long pstart, unsigned long pend); |
13 | 13 | ||
14 | #endif /* _ASM_X86_INIT_H */ | 14 | #endif /* _ASM_X86_INIT_H */ |
diff --git a/arch/x86/mm/ident_map.c b/arch/x86/mm/ident_map.c index ec21796ac5fd..4473cb4f8b90 100644 --- a/arch/x86/mm/ident_map.c +++ b/arch/x86/mm/ident_map.c | |||
@@ -3,15 +3,17 @@ | |||
3 | * included by both the compressed kernel and the regular kernel. | 3 | * included by both the compressed kernel and the regular kernel. |
4 | */ | 4 | */ |
5 | 5 | ||
6 | static void ident_pmd_init(unsigned long pmd_flag, pmd_t *pmd_page, | 6 | static void ident_pmd_init(struct x86_mapping_info *info, pmd_t *pmd_page, |
7 | unsigned long addr, unsigned long end) | 7 | unsigned long addr, unsigned long end) |
8 | { | 8 | { |
9 | addr &= PMD_MASK; | 9 | addr &= PMD_MASK; |
10 | for (; addr < end; addr += PMD_SIZE) { | 10 | for (; addr < end; addr += PMD_SIZE) { |
11 | pmd_t *pmd = pmd_page + pmd_index(addr); | 11 | pmd_t *pmd = pmd_page + pmd_index(addr); |
12 | 12 | ||
13 | if (!pmd_present(*pmd)) | 13 | if (pmd_present(*pmd)) |
14 | set_pmd(pmd, __pmd(addr | pmd_flag)); | 14 | continue; |
15 | |||
16 | set_pmd(pmd, __pmd((addr - info->offset) | info->pmd_flag)); | ||
15 | } | 17 | } |
16 | } | 18 | } |
17 | 19 | ||
@@ -30,13 +32,13 @@ static int ident_pud_init(struct x86_mapping_info *info, pud_t *pud_page, | |||
30 | 32 | ||
31 | if (pud_present(*pud)) { | 33 | if (pud_present(*pud)) { |
32 | pmd = pmd_offset(pud, 0); | 34 | pmd = pmd_offset(pud, 0); |
33 | ident_pmd_init(info->pmd_flag, pmd, addr, next); | 35 | ident_pmd_init(info, pmd, addr, next); |
34 | continue; | 36 | continue; |
35 | } | 37 | } |
36 | pmd = (pmd_t *)info->alloc_pgt_page(info->context); | 38 | pmd = (pmd_t *)info->alloc_pgt_page(info->context); |
37 | if (!pmd) | 39 | if (!pmd) |
38 | return -ENOMEM; | 40 | return -ENOMEM; |
39 | ident_pmd_init(info->pmd_flag, pmd, addr, next); | 41 | ident_pmd_init(info, pmd, addr, next); |
40 | set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE)); | 42 | set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE)); |
41 | } | 43 | } |
42 | 44 | ||
@@ -44,14 +46,15 @@ static int ident_pud_init(struct x86_mapping_info *info, pud_t *pud_page, | |||
44 | } | 46 | } |
45 | 47 | ||
46 | int kernel_ident_mapping_init(struct x86_mapping_info *info, pgd_t *pgd_page, | 48 | int kernel_ident_mapping_init(struct x86_mapping_info *info, pgd_t *pgd_page, |
47 | unsigned long addr, unsigned long end) | 49 | unsigned long pstart, unsigned long pend) |
48 | { | 50 | { |
51 | unsigned long addr = pstart + info->offset; | ||
52 | unsigned long end = pend + info->offset; | ||
49 | unsigned long next; | 53 | unsigned long next; |
50 | int result; | 54 | int result; |
51 | int off = info->kernel_mapping ? pgd_index(__PAGE_OFFSET) : 0; | ||
52 | 55 | ||
53 | for (; addr < end; addr = next) { | 56 | for (; addr < end; addr = next) { |
54 | pgd_t *pgd = pgd_page + pgd_index(addr) + off; | 57 | pgd_t *pgd = pgd_page + pgd_index(addr); |
55 | pud_t *pud; | 58 | pud_t *pud; |
56 | 59 | ||
57 | next = (addr & PGDIR_MASK) + PGDIR_SIZE; | 60 | next = (addr & PGDIR_MASK) + PGDIR_SIZE; |
diff --git a/arch/x86/power/hibernate_64.c b/arch/x86/power/hibernate_64.c index f0b5f2d402af..a3e3ccc87138 100644 --- a/arch/x86/power/hibernate_64.c +++ b/arch/x86/power/hibernate_64.c | |||
@@ -87,7 +87,7 @@ static int set_up_temporary_mappings(void) | |||
87 | struct x86_mapping_info info = { | 87 | struct x86_mapping_info info = { |
88 | .alloc_pgt_page = alloc_pgt_page, | 88 | .alloc_pgt_page = alloc_pgt_page, |
89 | .pmd_flag = __PAGE_KERNEL_LARGE_EXEC, | 89 | .pmd_flag = __PAGE_KERNEL_LARGE_EXEC, |
90 | .kernel_mapping = true, | 90 | .offset = __PAGE_OFFSET, |
91 | }; | 91 | }; |
92 | unsigned long mstart, mend; | 92 | unsigned long mstart, mend; |
93 | pgd_t *pgd; | 93 | pgd_t *pgd; |