3838#include <asm/cacheflush.h>
3939#include <asm/fixmap.h>
4040
41- static pgd_t save_pgd __initdata ;
41+ static pgd_t * save_pgd __initdata ;
4242static unsigned long efi_flags __initdata ;
4343
4444static void __init early_code_mapping_set_exec (int executable )
@@ -61,12 +61,20 @@ static void __init early_code_mapping_set_exec(int executable)
6161void __init efi_call_phys_prelog (void )
6262{
6363 unsigned long vaddress ;
64+ int pgd ;
65+ int n_pgds ;
6466
6567 early_code_mapping_set_exec (1 );
6668 local_irq_save (efi_flags );
67- vaddress = (unsigned long )__va (0x0UL );
68- save_pgd = * pgd_offset_k (0x0UL );
69- set_pgd (pgd_offset_k (0x0UL ), * pgd_offset_k (vaddress ));
69+
70+ n_pgds = DIV_ROUND_UP ((max_pfn << PAGE_SHIFT ), PGDIR_SIZE );
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+ }
7078 __flush_tlb_all ();
7179}
7280
@@ -75,7 +83,11 @@ void __init efi_call_phys_epilog(void)
7583 /*
7684 * After the lock is released, the original page table is restored.
7785 */
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 );
7991 __flush_tlb_all ();
8092 local_irq_restore (efi_flags );
8193 early_code_mapping_set_exec (0 );
0 commit comments