diff options
Diffstat (limited to 'arch/x86/platform')
-rw-r--r-- | arch/x86/platform/efi/efi_64.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 95fd505dfeb6..2b2003860615 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <asm/cacheflush.h> | 38 | #include <asm/cacheflush.h> |
39 | #include <asm/fixmap.h> | 39 | #include <asm/fixmap.h> |
40 | 40 | ||
41 | static pgd_t save_pgd __initdata; | 41 | static pgd_t *save_pgd __initdata; |
42 | static unsigned long efi_flags __initdata; | 42 | static unsigned long efi_flags __initdata; |
43 | 43 | ||
44 | static void __init early_code_mapping_set_exec(int executable) | 44 | static void __init early_code_mapping_set_exec(int executable) |
@@ -61,12 +61,20 @@ static void __init early_code_mapping_set_exec(int executable) | |||
61 | void __init efi_call_phys_prelog(void) | 61 | void __init efi_call_phys_prelog(void) |
62 | { | 62 | { |
63 | unsigned long vaddress; | 63 | unsigned long vaddress; |
64 | int pgd; | ||
65 | int n_pgds; | ||
64 | 66 | ||
65 | early_code_mapping_set_exec(1); | 67 | early_code_mapping_set_exec(1); |
66 | local_irq_save(efi_flags); | 68 | local_irq_save(efi_flags); |
67 | vaddress = (unsigned long)__va(0x0UL); | 69 | |
68 | save_pgd = *pgd_offset_k(0x0UL); | 70 | n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT), PGDIR_SIZE); |
69 | set_pgd(pgd_offset_k(0x0UL), *pgd_offset_k(vaddress)); | 71 | save_pgd = kmalloc(n_pgds * sizeof(pgd_t), GFP_KERNEL); |
72 | |||
73 | for (pgd = 0; pgd < n_pgds; pgd++) { | ||
74 | save_pgd[pgd] = *pgd_offset_k(pgd * PGDIR_SIZE); | ||
75 | vaddress = (unsigned long)__va(pgd * PGDIR_SIZE); | ||
76 | set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), *pgd_offset_k(vaddress)); | ||
77 | } | ||
70 | __flush_tlb_all(); | 78 | __flush_tlb_all(); |
71 | } | 79 | } |
72 | 80 | ||
@@ -75,7 +83,11 @@ void __init efi_call_phys_epilog(void) | |||
75 | /* | 83 | /* |
76 | * After the lock is released, the original page table is restored. | 84 | * After the lock is released, the original page table is restored. |
77 | */ | 85 | */ |
78 | set_pgd(pgd_offset_k(0x0UL), save_pgd); | 86 | int pgd; |
87 | int n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE); | ||
88 | for (pgd = 0; pgd < n_pgds; pgd++) | ||
89 | set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), save_pgd[pgd]); | ||
90 | kfree(save_pgd); | ||
79 | __flush_tlb_all(); | 91 | __flush_tlb_all(); |
80 | local_irq_restore(efi_flags); | 92 | local_irq_restore(efi_flags); |
81 | early_code_mapping_set_exec(0); | 93 | early_code_mapping_set_exec(0); |