s390/vmem: do not silently ignore mapping limit
authorAlexander Gordeev <agordeev@linux.ibm.com>
Fri, 1 Sep 2023 06:11:14 +0000 (08:11 +0200)
committerHeiko Carstens <hca@linux.ibm.com>
Tue, 5 Sep 2023 18:12:52 +0000 (20:12 +0200)
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: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
arch/s390/mm/vmem.c

index d734058..6957d2e 100644 (file)
@@ -290,14 +290,9 @@ out:
 
 static void try_free_pmd_table(pud_t *pud, unsigned long start)
 {
-       const unsigned long end = start + PUD_SIZE;
        pmd_t *pmd;
        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);
        for (i = 0; i < PTRS_PER_PMD; i++, pmd++)
                if (!pmd_none(*pmd))
@@ -362,14 +357,9 @@ out:
 
 static void try_free_pud_table(p4d_t *p4d, unsigned long start)
 {
-       const unsigned long end = start + P4D_SIZE;
        pud_t *pud;
        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);
        for (i = 0; i < PTRS_PER_PUD; i++, pud++) {
                if (!pud_none(*pud))
@@ -412,14 +402,9 @@ out:
 
 static void try_free_p4d_table(pgd_t *pgd, unsigned long start)
 {
-       const unsigned long end = start + PGDIR_SIZE;
        p4d_t *p4d;
        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);
        for (i = 0; i < PTRS_PER_P4D; i++, p4d++) {
                if (!p4d_none(*p4d))
@@ -439,6 +424,9 @@ static int modify_pagetable(unsigned long start, unsigned long end, bool add,
 
        if (WARN_ON_ONCE(!PAGE_ALIGNED(start | end)))
                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) {
                next = pgd_addr_end(addr, end);
                pgd = pgd_offset_k(addr);