diff options
Diffstat (limited to 'arch/ia64/mm/init.c')
| -rw-r--r-- | arch/ia64/mm/init.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 547785e3cba2..4eb2f52b87a1 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c | |||
| @@ -305,8 +305,9 @@ setup_gate (void) | |||
| 305 | struct page *page; | 305 | struct page *page; |
| 306 | 306 | ||
| 307 | /* | 307 | /* |
| 308 | * Map the gate page twice: once read-only to export the ELF headers etc. and once | 308 | * Map the gate page twice: once read-only to export the ELF |
| 309 | * execute-only page to enable privilege-promotion via "epc": | 309 | * headers etc. and once execute-only page to enable |
| 310 | * privilege-promotion via "epc": | ||
| 310 | */ | 311 | */ |
| 311 | page = virt_to_page(ia64_imva(__start_gate_section)); | 312 | page = virt_to_page(ia64_imva(__start_gate_section)); |
| 312 | put_kernel_page(page, GATE_ADDR, PAGE_READONLY); | 313 | put_kernel_page(page, GATE_ADDR, PAGE_READONLY); |
| @@ -315,6 +316,20 @@ setup_gate (void) | |||
| 315 | put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE); | 316 | put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE); |
| 316 | #else | 317 | #else |
| 317 | put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE); | 318 | put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE); |
| 319 | /* Fill in the holes (if any) with read-only zero pages: */ | ||
| 320 | { | ||
| 321 | unsigned long addr; | ||
| 322 | |||
| 323 | for (addr = GATE_ADDR + PAGE_SIZE; | ||
| 324 | addr < GATE_ADDR + PERCPU_PAGE_SIZE; | ||
| 325 | addr += PAGE_SIZE) | ||
| 326 | { | ||
| 327 | put_kernel_page(ZERO_PAGE(0), addr, | ||
| 328 | PAGE_READONLY); | ||
| 329 | put_kernel_page(ZERO_PAGE(0), addr + PERCPU_PAGE_SIZE, | ||
| 330 | PAGE_READONLY); | ||
| 331 | } | ||
| 332 | } | ||
| 318 | #endif | 333 | #endif |
| 319 | ia64_patch_gate(); | 334 | ia64_patch_gate(); |
| 320 | } | 335 | } |
