Commit 06fc3b0d authored by Alexander Gordeev's avatar Alexander Gordeev Committed by Heiko Carstens

s390/vmem: do not silently ignore mapping limit

The only interface that allows drivers establishing
liner mappings is vmem_add_mapping(). It does check
a requested range against allowed limits and a call
to modify_pagetable() with an invalid mapping range
is impossible.

Hence, an attempt to map an address range outside of
the identity mapping or vmemmap array could only be
kernel bug.
Reviewed-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent f59ec04d
...@@ -290,14 +290,9 @@ static int __ref modify_pmd_table(pud_t *pud, unsigned long addr, ...@@ -290,14 +290,9 @@ static int __ref modify_pmd_table(pud_t *pud, unsigned long addr,
static void try_free_pmd_table(pud_t *pud, unsigned long start) static void try_free_pmd_table(pud_t *pud, unsigned long start)
{ {
const unsigned long end = start + PUD_SIZE;
pmd_t *pmd; pmd_t *pmd;
int i; int i;
/* Don't mess with any tables not fully in 1:1 mapping & vmemmap area */
if (end > VMALLOC_START)
return;
pmd = pmd_offset(pud, start); pmd = pmd_offset(pud, start);
for (i = 0; i < PTRS_PER_PMD; i++, pmd++) for (i = 0; i < PTRS_PER_PMD; i++, pmd++)
if (!pmd_none(*pmd)) if (!pmd_none(*pmd))
...@@ -362,14 +357,9 @@ static int modify_pud_table(p4d_t *p4d, unsigned long addr, unsigned long end, ...@@ -362,14 +357,9 @@ static int modify_pud_table(p4d_t *p4d, unsigned long addr, unsigned long end,
static void try_free_pud_table(p4d_t *p4d, unsigned long start) static void try_free_pud_table(p4d_t *p4d, unsigned long start)
{ {
const unsigned long end = start + P4D_SIZE;
pud_t *pud; pud_t *pud;
int i; int i;
/* Don't mess with any tables not fully in 1:1 mapping & vmemmap area */
if (end > VMALLOC_START)
return;
pud = pud_offset(p4d, start); pud = pud_offset(p4d, start);
for (i = 0; i < PTRS_PER_PUD; i++, pud++) { for (i = 0; i < PTRS_PER_PUD; i++, pud++) {
if (!pud_none(*pud)) if (!pud_none(*pud))
...@@ -412,14 +402,9 @@ static int modify_p4d_table(pgd_t *pgd, unsigned long addr, unsigned long end, ...@@ -412,14 +402,9 @@ static int modify_p4d_table(pgd_t *pgd, unsigned long addr, unsigned long end,
static void try_free_p4d_table(pgd_t *pgd, unsigned long start) static void try_free_p4d_table(pgd_t *pgd, unsigned long start)
{ {
const unsigned long end = start + PGDIR_SIZE;
p4d_t *p4d; p4d_t *p4d;
int i; int i;
/* Don't mess with any tables not fully in 1:1 mapping & vmemmap area */
if (end > VMALLOC_START)
return;
p4d = p4d_offset(pgd, start); p4d = p4d_offset(pgd, start);
for (i = 0; i < PTRS_PER_P4D; i++, p4d++) { for (i = 0; i < PTRS_PER_P4D; i++, p4d++) {
if (!p4d_none(*p4d)) if (!p4d_none(*p4d))
...@@ -439,6 +424,9 @@ static int modify_pagetable(unsigned long start, unsigned long end, bool add, ...@@ -439,6 +424,9 @@ static int modify_pagetable(unsigned long start, unsigned long end, bool add,
if (WARN_ON_ONCE(!PAGE_ALIGNED(start | end))) if (WARN_ON_ONCE(!PAGE_ALIGNED(start | end)))
return -EINVAL; return -EINVAL;
/* Don't mess with any tables not fully in 1:1 mapping & vmemmap area */
if (WARN_ON_ONCE(end > VMALLOC_START))
return -EINVAL;
for (addr = start; addr < end; addr = next) { for (addr = start; addr < end; addr = next) {
next = pgd_addr_end(addr, end); next = pgd_addr_end(addr, end);
pgd = pgd_offset_k(addr); pgd = pgd_offset_k(addr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment