summaryrefslogtreecommitdiff
path: root/arch/x86/platform/efi/efi_64.c
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2013-02-04 22:56:41 -0800
committerOlof Johansson <olof@lixom.net>2013-02-04 22:56:41 -0800
commit469da62096e23adc755c1268b00b5fc7a214151b (patch)
treefefd055fdae584e38d551f44d1339eb22cee4ed9 /arch/x86/platform/efi/efi_64.c
parent4227961650884a06757f80877d5dce0bddc723d4 (diff)
parent88b62b915b0b7e25870eb0604ed9a92ba4bfc9f7 (diff)
downloadolio-linux-3.10-469da62096e23adc755c1268b00b5fc7a214151b.tar.xz
olio-linux-3.10-469da62096e23adc755c1268b00b5fc7a214151b.zip
Merge tag 'v3.8-rc6' into next/soc
Linux 3.8-rc6
Diffstat (limited to 'arch/x86/platform/efi/efi_64.c')
-rw-r--r--arch/x86/platform/efi/efi_64.c22
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 95fd505dfeb..2b200386061 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -38,7 +38,7 @@
#include <asm/cacheflush.h>
#include <asm/fixmap.h>
-static pgd_t save_pgd __initdata;
+static pgd_t *save_pgd __initdata;
static unsigned long efi_flags __initdata;
static void __init early_code_mapping_set_exec(int executable)
@@ -61,12 +61,20 @@ static void __init early_code_mapping_set_exec(int executable)
void __init efi_call_phys_prelog(void)
{
unsigned long vaddress;
+ int pgd;
+ int n_pgds;
early_code_mapping_set_exec(1);
local_irq_save(efi_flags);
- vaddress = (unsigned long)__va(0x0UL);
- save_pgd = *pgd_offset_k(0x0UL);
- set_pgd(pgd_offset_k(0x0UL), *pgd_offset_k(vaddress));
+
+ n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT), PGDIR_SIZE);
+ save_pgd = kmalloc(n_pgds * sizeof(pgd_t), GFP_KERNEL);
+
+ for (pgd = 0; pgd < n_pgds; pgd++) {
+ save_pgd[pgd] = *pgd_offset_k(pgd * PGDIR_SIZE);
+ vaddress = (unsigned long)__va(pgd * PGDIR_SIZE);
+ set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), *pgd_offset_k(vaddress));
+ }
__flush_tlb_all();
}
@@ -75,7 +83,11 @@ void __init efi_call_phys_epilog(void)
/*
* After the lock is released, the original page table is restored.
*/
- set_pgd(pgd_offset_k(0x0UL), save_pgd);
+ int pgd;
+ int n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE);
+ for (pgd = 0; pgd < n_pgds; pgd++)
+ set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), save_pgd[pgd]);
+ kfree(save_pgd);
__flush_tlb_all();
local_irq_restore(efi_flags);
early_code_mapping_set_exec(0);