提交 5b1ba9e3 编写于 作者: H Heiko Carstens 提交者: Martin Schwidefsky

s390/mm,pageattr: add more page table walk sanity checks

The current page table walk code in pageattr.c only checks for large pages
while walking the kernel page table, but happily assumes that everything
else is just fine.
Add more checks so we never access invalid memory regions.
Reviewed-by: NGerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: NHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: NMartin Schwidefsky <schwidefsky@de.ibm.com>
上级 378b1e7a
...@@ -8,25 +8,38 @@ ...@@ -8,25 +8,38 @@
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
static pte_t *walk_page_table(unsigned long addr)
{
pgd_t *pgdp;
pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
pgdp = pgd_offset_k(addr);
if (pgd_none(*pgdp))
return NULL;
pudp = pud_offset(pgdp, addr);
if (pud_none(*pudp))
return NULL;
pmdp = pmd_offset(pudp, addr);
if (pmd_none(*pmdp) || pmd_large(*pmdp))
return NULL;
ptep = pte_offset_kernel(pmdp, addr);
if (pte_none(*ptep))
return NULL;
return ptep;
}
static void change_page_attr(unsigned long addr, int numpages, static void change_page_attr(unsigned long addr, int numpages,
pte_t (*set) (pte_t)) pte_t (*set) (pte_t))
{ {
pte_t *ptep, pte; pte_t *ptep, pte;
pmd_t *pmdp;
pud_t *pudp;
pgd_t *pgdp;
int i; int i;
for (i = 0; i < numpages; i++) { for (i = 0; i < numpages; i++) {
pgdp = pgd_offset(&init_mm, addr); ptep = walk_page_table(addr);
pudp = pud_offset(pgdp, addr); if (WARN_ON_ONCE(!ptep))
pmdp = pmd_offset(pudp, addr); break;
if (pmd_large(*pmdp)) {
WARN_ON_ONCE(1);
continue;
}
ptep = pte_offset_kernel(pmdp, addr);
pte = *ptep; pte = *ptep;
pte = set(pte); pte = set(pte);
__ptep_ipte(addr, ptep); __ptep_ipte(addr, ptep);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册