]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
riscv: Improve PTDUMP to show RSW with non-zero value
authorYu Chien Peter Lin <peterlin@andestech.com>
Thu, 21 Sep 2023 02:50:20 +0000 (10:50 +0800)
committerPalmer Dabbelt <palmer@rivosinc.com>
Sun, 5 Nov 2023 17:41:53 +0000 (09:41 -0800)
RSW field can be used to encode 2 bits of software
defined information. Currently, PTDUMP only prints
"RSW" when its value is 1 or 3.

To fix this issue and improve the debugging experience
with PTDUMP, we redefine _PAGE_SPECIAL to its original
value and use _PAGE_SOFT as the RSW mask, allow it to
print the RSW with any non-zero value.

This patch also removes the val from the struct prot_bits
as it is no longer needed.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Tested-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Link: https://lore.kernel.org/r/20230921025022.3989723-2-peterlin@andestech.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
arch/riscv/include/asm/pgtable-bits.h
arch/riscv/mm/ptdump.c

index f896708e833127d12e4cb9851b0890a8d7c5d922..179bd4afece46a6b96c33088a14480cb6c18c429 100644 (file)
@@ -16,9 +16,9 @@
 #define _PAGE_GLOBAL    (1 << 5)    /* Global */
 #define _PAGE_ACCESSED  (1 << 6)    /* Set by hardware on any access */
 #define _PAGE_DIRTY     (1 << 7)    /* Set by hardware on any write */
-#define _PAGE_SOFT      (1 << 8)    /* Reserved for software */
+#define _PAGE_SOFT      (3 << 8)    /* Reserved for software */
 
-#define _PAGE_SPECIAL   _PAGE_SOFT
+#define _PAGE_SPECIAL   (1 << 8)    /* RSW: 0x1 */
 #define _PAGE_TABLE     _PAGE_PRESENT
 
 /*
index 20a9f991a6d7461be7d177723cc3b27284865cd6..57a0926c66276ca1297dae7cf48bc3b1fcab223a 100644 (file)
@@ -129,7 +129,6 @@ static struct ptd_mm_info efi_ptd_info = {
 /* Page Table Entry */
 struct prot_bits {
        u64 mask;
-       u64 val;
        const char *set;
        const char *clear;
 };
@@ -137,47 +136,38 @@ struct prot_bits {
 static const struct prot_bits pte_bits[] = {
        {
                .mask = _PAGE_SOFT,
-               .val = _PAGE_SOFT,
-               .set = "RSW",
-               .clear = "   ",
+               .set = "RSW(%d)",
+               .clear = "  ..  ",
        }, {
                .mask = _PAGE_DIRTY,
-               .val = _PAGE_DIRTY,
                .set = "D",
                .clear = ".",
        }, {
                .mask = _PAGE_ACCESSED,
-               .val = _PAGE_ACCESSED,
                .set = "A",
                .clear = ".",
        }, {
                .mask = _PAGE_GLOBAL,
-               .val = _PAGE_GLOBAL,
                .set = "G",
                .clear = ".",
        }, {
                .mask = _PAGE_USER,
-               .val = _PAGE_USER,
                .set = "U",
                .clear = ".",
        }, {
                .mask = _PAGE_EXEC,
-               .val = _PAGE_EXEC,
                .set = "X",
                .clear = ".",
        }, {
                .mask = _PAGE_WRITE,
-               .val = _PAGE_WRITE,
                .set = "W",
                .clear = ".",
        }, {
                .mask = _PAGE_READ,
-               .val = _PAGE_READ,
                .set = "R",
                .clear = ".",
        }, {
                .mask = _PAGE_PRESENT,
-               .val = _PAGE_PRESENT,
                .set = "V",
                .clear = ".",
        }
@@ -208,15 +198,20 @@ static void dump_prot(struct pg_state *st)
        unsigned int i;
 
        for (i = 0; i < ARRAY_SIZE(pte_bits); i++) {
-               const char *s;
-
-               if ((st->current_prot & pte_bits[i].mask) == pte_bits[i].val)
-                       s = pte_bits[i].set;
-               else
-                       s = pte_bits[i].clear;
+               char s[7];
+               unsigned long val;
+
+               val = st->current_prot & pte_bits[i].mask;
+               if (val) {
+                       if (pte_bits[i].mask == _PAGE_SOFT)
+                               sprintf(s, pte_bits[i].set, val >> 8);
+                       else
+                               sprintf(s, "%s", pte_bits[i].set);
+               } else {
+                       sprintf(s, "%s", pte_bits[i].clear);
+               }
 
-               if (s)
-                       pt_dump_seq_printf(st->seq, " %s", s);
+               pt_dump_seq_printf(st->seq, " %s", s);
        }
 }