|
@@ -287,6 +287,9 @@ static noinline int vmalloc_fault(unsigned long address)
|
|
|
if (!pmd_k)
|
|
|
return -1;
|
|
|
|
|
|
+ if (pmd_huge(*pmd_k))
|
|
|
+ return 0;
|
|
|
+
|
|
|
pte_k = pte_offset_kernel(pmd_k, address);
|
|
|
if (!pte_present(*pte_k))
|
|
|
return -1;
|
|
@@ -360,8 +363,6 @@ void vmalloc_sync_all(void)
|
|
|
* 64-bit:
|
|
|
*
|
|
|
* Handle a fault on the vmalloc area
|
|
|
- *
|
|
|
- * This assumes no large pages in there.
|
|
|
*/
|
|
|
static noinline int vmalloc_fault(unsigned long address)
|
|
|
{
|
|
@@ -403,17 +404,23 @@ static noinline int vmalloc_fault(unsigned long address)
|
|
|
if (pud_none(*pud_ref))
|
|
|
return -1;
|
|
|
|
|
|
- if (pud_none(*pud) || pud_page_vaddr(*pud) != pud_page_vaddr(*pud_ref))
|
|
|
+ if (pud_none(*pud) || pud_pfn(*pud) != pud_pfn(*pud_ref))
|
|
|
BUG();
|
|
|
|
|
|
+ if (pud_huge(*pud))
|
|
|
+ return 0;
|
|
|
+
|
|
|
pmd = pmd_offset(pud, address);
|
|
|
pmd_ref = pmd_offset(pud_ref, address);
|
|
|
if (pmd_none(*pmd_ref))
|
|
|
return -1;
|
|
|
|
|
|
- if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref))
|
|
|
+ if (pmd_none(*pmd) || pmd_pfn(*pmd) != pmd_pfn(*pmd_ref))
|
|
|
BUG();
|
|
|
|
|
|
+ if (pmd_huge(*pmd))
|
|
|
+ return 0;
|
|
|
+
|
|
|
pte_ref = pte_offset_kernel(pmd_ref, address);
|
|
|
if (!pte_present(*pte_ref))
|
|
|
return -1;
|