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: Gerald Schaefer <gerald.schaefer@de.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
378b1e7a80
commit
5b1ba9e30c
|
@ -8,25 +8,38 @@
|
|||
#include <asm/cacheflush.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,
|
||||
pte_t (*set) (pte_t))
|
||||
{
|
||||
pte_t *ptep, pte;
|
||||
pmd_t *pmdp;
|
||||
pud_t *pudp;
|
||||
pgd_t *pgdp;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numpages; i++) {
|
||||
pgdp = pgd_offset(&init_mm, addr);
|
||||
pudp = pud_offset(pgdp, addr);
|
||||
pmdp = pmd_offset(pudp, addr);
|
||||
if (pmd_large(*pmdp)) {
|
||||
WARN_ON_ONCE(1);
|
||||
continue;
|
||||
}
|
||||
ptep = pte_offset_kernel(pmdp, addr);
|
||||
|
||||
ptep = walk_page_table(addr);
|
||||
if (WARN_ON_ONCE(!ptep))
|
||||
break;
|
||||
pte = *ptep;
|
||||
pte = set(pte);
|
||||
__ptep_ipte(addr, ptep);
|
||||
|
|
Loading…
Reference in New Issue