s390/mm,fault: use get_kernel_nofault() to dereference in dump_pagetable()
authorHeiko Carstens <hca@linux.ibm.com>
Thu, 12 Oct 2023 07:40:44 +0000 (09:40 +0200)
committerVasily Gorbik <gor@linux.ibm.com>
Mon, 23 Oct 2023 16:21:22 +0000 (18:21 +0200)
The page table dumper uses get_kernel_nofault() to test if dereferencing
page table entries is possible. Use the result, which is the required page
table entry, instead of throwing it away and dereferencing a second time
without any safe guard.

Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
arch/s390/mm/fault.c

index bcaac0f939df9045834ff7da6c006d2ffab02a6b..c37e28fbfbef3879a2af64d3f79b45a0dd74aeed 100644 (file)
@@ -112,59 +112,52 @@ static __always_inline bool fault_is_write(struct pt_regs *regs)
        return false;
 }
 
-static int bad_address(void *p)
-{
-       unsigned long dummy;
-
-       return get_kernel_nofault(dummy, (unsigned long *)p);
-}
-
 static void dump_pagetable(unsigned long asce, unsigned long address)
 {
-       unsigned long *table = __va(asce & _ASCE_ORIGIN);
+       unsigned long entry, *table = __va(asce & _ASCE_ORIGIN);
 
        pr_alert("AS:%016lx ", asce);
        switch (asce & _ASCE_TYPE_MASK) {
        case _ASCE_TYPE_REGION1:
                table += (address & _REGION1_INDEX) >> _REGION1_SHIFT;
-               if (bad_address(table))
+               if (get_kernel_nofault(entry, table))
                        goto bad;
-               pr_cont("R1:%016lx ", *table);
-               if (*table & _REGION_ENTRY_INVALID)
+               pr_cont("R1:%016lx ", entry);
+               if (entry & _REGION_ENTRY_INVALID)
                        goto out;
-               table = __va(*table & _REGION_ENTRY_ORIGIN);
+               table = __va(entry & _REGION_ENTRY_ORIGIN);
                fallthrough;
        case _ASCE_TYPE_REGION2:
                table += (address & _REGION2_INDEX) >> _REGION2_SHIFT;
-               if (bad_address(table))
+               if (get_kernel_nofault(entry, table))
                        goto bad;
-               pr_cont("R2:%016lx ", *table);
-               if (*table & _REGION_ENTRY_INVALID)
+               pr_cont("R2:%016lx ", entry);
+               if (entry & _REGION_ENTRY_INVALID)
                        goto out;
-               table = __va(*table & _REGION_ENTRY_ORIGIN);
+               table = __va(entry & _REGION_ENTRY_ORIGIN);
                fallthrough;
        case _ASCE_TYPE_REGION3:
                table += (address & _REGION3_INDEX) >> _REGION3_SHIFT;
-               if (bad_address(table))
+               if (get_kernel_nofault(entry, table))
                        goto bad;
-               pr_cont("R3:%016lx ", *table);
-               if (*table & (_REGION_ENTRY_INVALID | _REGION3_ENTRY_LARGE))
+               pr_cont("R3:%016lx ", entry);
+               if (entry & (_REGION_ENTRY_INVALID | _REGION3_ENTRY_LARGE))
                        goto out;
-               table = __va(*table & _REGION_ENTRY_ORIGIN);
+               table = __va(entry & _REGION_ENTRY_ORIGIN);
                fallthrough;
        case _ASCE_TYPE_SEGMENT:
                table += (address & _SEGMENT_INDEX) >> _SEGMENT_SHIFT;
-               if (bad_address(table))
+               if (get_kernel_nofault(entry, table))
                        goto bad;
-               pr_cont("S:%016lx ", *table);
-               if (*table & (_SEGMENT_ENTRY_INVALID | _SEGMENT_ENTRY_LARGE))
+               pr_cont("S:%016lx ", entry);
+               if (entry & (_SEGMENT_ENTRY_INVALID | _SEGMENT_ENTRY_LARGE))
                        goto out;
-               table = __va(*table & _SEGMENT_ENTRY_ORIGIN);
+               table = __va(entry & _SEGMENT_ENTRY_ORIGIN);
        }
        table += (address & _PAGE_INDEX) >> _PAGE_SHIFT;
-       if (bad_address(table))
+       if (get_kernel_nofault(entry, table))
                goto bad;
-       pr_cont("P:%016lx ", *table);
+       pr_cont("P:%016lx ", entry);
 out:
        pr_cont("\n");
        return;