diff options
| author | Andi Kleen <ak@suse.de> | 2008-02-04 10:48:09 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-02-04 10:48:09 -0500 |
| commit | f07333fd149eb6826da26a89c3aff90324f270b0 (patch) | |
| tree | 139557a0a7469e52dc8407c72dd70a011dee3884 | |
| parent | b5360222273cb3e57a119c18eef42f59da4da87b (diff) | |
x86: implement gbpages support in change_page_attr()
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
| -rw-r--r-- | arch/x86/mm/pageattr.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 143fbafc948a..42ca3d8effad 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
| @@ -281,7 +281,12 @@ static int try_preserve_large_page(pte_t *kpte, unsigned long address, | |||
| 281 | psize = PMD_PAGE_SIZE; | 281 | psize = PMD_PAGE_SIZE; |
| 282 | pmask = PMD_PAGE_MASK; | 282 | pmask = PMD_PAGE_MASK; |
| 283 | break; | 283 | break; |
| 284 | #ifdef CONFIG_X86_64 | ||
| 284 | case PG_LEVEL_1G: | 285 | case PG_LEVEL_1G: |
| 286 | psize = PMD_PAGE_SIZE; | ||
| 287 | pmask = PMD_PAGE_MASK; | ||
| 288 | break; | ||
| 289 | #endif | ||
| 285 | default: | 290 | default: |
| 286 | res = -EINVAL; | 291 | res = -EINVAL; |
| 287 | goto out_unlock; | 292 | goto out_unlock; |
| @@ -343,7 +348,7 @@ static int split_large_page(pte_t *kpte, unsigned long address) | |||
| 343 | { | 348 | { |
| 344 | pgprot_t ref_prot; | 349 | pgprot_t ref_prot; |
| 345 | gfp_t gfp_flags = GFP_KERNEL; | 350 | gfp_t gfp_flags = GFP_KERNEL; |
| 346 | unsigned long flags, addr, pfn; | 351 | unsigned long flags, addr, pfn, pfninc = 1; |
| 347 | pte_t *pbase, *tmp; | 352 | pte_t *pbase, *tmp; |
| 348 | struct page *base; | 353 | struct page *base; |
| 349 | unsigned int i, level; | 354 | unsigned int i, level; |
| @@ -372,11 +377,19 @@ static int split_large_page(pte_t *kpte, unsigned long address) | |||
| 372 | #endif | 377 | #endif |
| 373 | ref_prot = pte_pgprot(pte_clrhuge(*kpte)); | 378 | ref_prot = pte_pgprot(pte_clrhuge(*kpte)); |
| 374 | 379 | ||
| 380 | #ifdef CONFIG_X86_64 | ||
| 381 | if (level == PG_LEVEL_1G) { | ||
| 382 | pfninc = PMD_PAGE_SIZE >> PAGE_SHIFT; | ||
| 383 | pgprot_val(ref_prot) |= _PAGE_PSE; | ||
| 384 | addr &= PUD_PAGE_MASK; | ||
| 385 | } | ||
| 386 | #endif | ||
| 387 | |||
| 375 | /* | 388 | /* |
| 376 | * Get the target pfn from the original entry: | 389 | * Get the target pfn from the original entry: |
| 377 | */ | 390 | */ |
| 378 | pfn = pte_pfn(*kpte); | 391 | pfn = pte_pfn(*kpte); |
| 379 | for (i = 0; i < PTRS_PER_PTE; i++, pfn++) | 392 | for (i = 0; i < PTRS_PER_PTE; i++, pfn += pfninc) |
| 380 | set_pte(&pbase[i], pfn_pte(pfn, ref_prot)); | 393 | set_pte(&pbase[i], pfn_pte(pfn, ref_prot)); |
| 381 | 394 | ||
| 382 | /* | 395 | /* |
