diff options
| -rw-r--r-- | arch/x86/mm/fault.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index eef44d9a3f77..e830c71a1323 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
| @@ -287,6 +287,9 @@ static noinline int vmalloc_fault(unsigned long address) | |||
| 287 | if (!pmd_k) | 287 | if (!pmd_k) |
| 288 | return -1; | 288 | return -1; |
| 289 | 289 | ||
| 290 | if (pmd_huge(*pmd_k)) | ||
| 291 | return 0; | ||
| 292 | |||
| 290 | pte_k = pte_offset_kernel(pmd_k, address); | 293 | pte_k = pte_offset_kernel(pmd_k, address); |
| 291 | if (!pte_present(*pte_k)) | 294 | if (!pte_present(*pte_k)) |
| 292 | return -1; | 295 | return -1; |
| @@ -360,8 +363,6 @@ void vmalloc_sync_all(void) | |||
| 360 | * 64-bit: | 363 | * 64-bit: |
| 361 | * | 364 | * |
| 362 | * Handle a fault on the vmalloc area | 365 | * Handle a fault on the vmalloc area |
| 363 | * | ||
| 364 | * This assumes no large pages in there. | ||
| 365 | */ | 366 | */ |
| 366 | static noinline int vmalloc_fault(unsigned long address) | 367 | static noinline int vmalloc_fault(unsigned long address) |
| 367 | { | 368 | { |
| @@ -403,17 +404,23 @@ static noinline int vmalloc_fault(unsigned long address) | |||
| 403 | if (pud_none(*pud_ref)) | 404 | if (pud_none(*pud_ref)) |
| 404 | return -1; | 405 | return -1; |
| 405 | 406 | ||
| 406 | if (pud_none(*pud) || pud_page_vaddr(*pud) != pud_page_vaddr(*pud_ref)) | 407 | if (pud_none(*pud) || pud_pfn(*pud) != pud_pfn(*pud_ref)) |
| 407 | BUG(); | 408 | BUG(); |
| 408 | 409 | ||
| 410 | if (pud_huge(*pud)) | ||
| 411 | return 0; | ||
| 412 | |||
| 409 | pmd = pmd_offset(pud, address); | 413 | pmd = pmd_offset(pud, address); |
| 410 | pmd_ref = pmd_offset(pud_ref, address); | 414 | pmd_ref = pmd_offset(pud_ref, address); |
| 411 | if (pmd_none(*pmd_ref)) | 415 | if (pmd_none(*pmd_ref)) |
| 412 | return -1; | 416 | return -1; |
| 413 | 417 | ||
| 414 | if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref)) | 418 | if (pmd_none(*pmd) || pmd_pfn(*pmd) != pmd_pfn(*pmd_ref)) |
| 415 | BUG(); | 419 | BUG(); |
| 416 | 420 | ||
| 421 | if (pmd_huge(*pmd)) | ||
| 422 | return 0; | ||
| 423 | |||
| 417 | pte_ref = pte_offset_kernel(pmd_ref, address); | 424 | pte_ref = pte_offset_kernel(pmd_ref, address); |
| 418 | if (!pte_present(*pte_ref)) | 425 | if (!pte_present(*pte_ref)) |
| 419 | return -1; | 426 | return -1; |
