提交 05dd2cd3 编写于 作者: M Matt Fleming 提交者: Paul Mundt

sh: Restore previous behaviour on kernel fault

The last commit changed the behaviour on kernel faults when we were
doing something other than syncing the page tables. vmalloc_sync_one()
needs to return NULL if the page tables are up to date, because the
reason for the fault was not a missing/inconsitent page table entry. By
returning NULL if the page tables are sync'd we signal to the calling
function that further work must be done to resolve this fault.

Also, remove the superfluous __va() around the first argument to
vmalloc_sync_one(). The value of pgd_k is already a virtual address and
using it wth __va() causes a NULL dereference.
Signed-off-by: NMatt Fleming <matt@console-pimps.org>
Signed-off-by: NPaul Mundt <lethal@linux-sh.org>
上级 3e28ad7b
...@@ -60,8 +60,15 @@ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address) ...@@ -60,8 +60,15 @@ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
if (!pmd_present(*pmd)) if (!pmd_present(*pmd))
set_pmd(pmd, *pmd_k); set_pmd(pmd, *pmd_k);
else else {
/*
* The page tables are fully synchronised so there must
* be another reason for the fault. Return NULL here to
* signal that we have not taken care of the fault.
*/
BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k)); BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
return NULL;
}
return pmd_k; return pmd_k;
} }
...@@ -87,7 +94,7 @@ static noinline int vmalloc_fault(unsigned long address) ...@@ -87,7 +94,7 @@ static noinline int vmalloc_fault(unsigned long address)
* an interrupt in the middle of a task switch.. * an interrupt in the middle of a task switch..
*/ */
pgd_k = get_TTB(); pgd_k = get_TTB();
pmd_k = vmalloc_sync_one(__va((unsigned long)pgd_k), address); pmd_k = vmalloc_sync_one(pgd_k, address);
if (!pmd_k) if (!pmd_k)
return -1; return -1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册