Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1819ed1f authored by Heiko Carstens's avatar Heiko Carstens Committed by Martin Schwidefsky
Browse files

s390/page table dumper: add support for change-recording override bit

parent 2a7d2b96
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -340,6 +340,8 @@ extern unsigned long MODULES_END;
#define _REGION3_ENTRY_EMPTY	(_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_INV)

#define _REGION3_ENTRY_LARGE	0x400	/* RTTE-format control, large page  */
#define _REGION3_ENTRY_RO	0x200	/* page protection bit		    */
#define _REGION3_ENTRY_CO	0x100	/* change-recording override	    */

/* Bits in the segment table entry */
#define _SEGMENT_ENTRY_ORIGIN	~0x7ffUL/* segment table origin		    */
+20 −5
Original line number Diff line number Diff line
@@ -49,10 +49,13 @@ static void print_prot(struct seq_file *m, unsigned int pr, int level)
		{ "ASCE", "PGD", "PUD", "PMD", "PTE" };

	seq_printf(m, "%s ", level_name[level]);
	if (pr & _PAGE_INVALID)
	if (pr & _PAGE_INVALID) {
		seq_printf(m, "I\n");
	else
		seq_printf(m, "%s\n", pr & _PAGE_RO ? "RO" : "RW");
		return;
	}
	seq_printf(m, "%s", pr & _PAGE_RO ? "RO " : "RW ");
	seq_printf(m, "%s", pr & _PAGE_CO ? "CO " : "   ");
	seq_putc(m, '\n');
}

static void note_page(struct seq_file *m, struct pg_state *st,
@@ -125,6 +128,12 @@ static void walk_pte_level(struct seq_file *m, struct pg_state *st,
	}
}

#ifdef CONFIG_64BIT
#define _PMD_PROT_MASK (_SEGMENT_ENTRY_RO | _SEGMENT_ENTRY_CO)
#else
#define _PMD_PROT_MASK 0
#endif

static void walk_pmd_level(struct seq_file *m, struct pg_state *st,
			   pud_t *pud, unsigned long addr)
{
@@ -137,7 +146,7 @@ static void walk_pmd_level(struct seq_file *m, struct pg_state *st,
		pmd = pmd_offset(pud, addr);
		if (!pmd_none(*pmd)) {
			if (pmd_large(*pmd)) {
				prot = pmd_val(*pmd) & _SEGMENT_ENTRY_RO;
				prot = pmd_val(*pmd) & _PMD_PROT_MASK;
				note_page(m, st, prot, 3);
			} else
				walk_pte_level(m, st, pmd, addr);
@@ -147,6 +156,12 @@ static void walk_pmd_level(struct seq_file *m, struct pg_state *st,
	}
}

#ifdef CONFIG_64BIT
#define _PUD_PROT_MASK (_REGION3_ENTRY_RO | _REGION3_ENTRY_CO)
#else
#define _PUD_PROT_MASK 0
#endif

static void walk_pud_level(struct seq_file *m, struct pg_state *st,
			   pgd_t *pgd, unsigned long addr)
{
@@ -159,7 +174,7 @@ static void walk_pud_level(struct seq_file *m, struct pg_state *st,
		pud = pud_offset(pgd, addr);
		if (!pud_none(*pud))
			if (pud_large(*pud)) {
				prot = pud_val(*pud) & _PAGE_RO;
				prot = pud_val(*pud) & _PUD_PROT_MASK;
				note_page(m, st, prot, 2);
			} else
				walk_pmd_level(m, st, pud, addr);