Unverified Commit de22d210 authored by Atish Patra's avatar Atish Patra Committed by Palmer Dabbelt
Browse files

RISC-V: Add page table dump support for uefi



Extend the current page table dump support in RISC-V to include efi
pages as well.

Here is the output of efi runtime page table mappings.

---[ UEFI runtime start ]---
0x0000000020002000-0x0000000020003000 0x00000000be732000 4K PTE D A . . . W R V
0x0000000020018000-0x0000000020019000 0x00000000be738000 4K PTE D A . . . W R V
0x000000002002c000-0x000000002002d000 0x00000000be73c000 4K PTE D A . . . W R V
0x0000000020031000-0x0000000020032000 0x00000000bff61000 4K PTE D A . . X W R V
---[ UEFI runtime end ]---

Signed-off-by: default avatarAtish Patra <atish.patra@wdc.com>
Reviewed-by: default avatarAnup Patel <anup@brainfault.org>
Signed-off-by: default avatarPalmer Dabbelt <palmerdabbelt@google.com>
parent b91540d5
Loading
Loading
Loading
Loading
+42 −6
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
 * Copyright (C) 2019 SiFive
 */

#include <linux/efi.h>
#include <linux/init.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
@@ -49,6 +50,14 @@ struct addr_marker {
	const char *name;
};

/* Private information for debugfs */
struct ptd_mm_info {
	struct mm_struct		*mm;
	const struct addr_marker	*markers;
	unsigned long base_addr;
	unsigned long end;
};

static struct addr_marker address_markers[] = {
#ifdef CONFIG_KASAN
	{KASAN_SHADOW_START,	"Kasan shadow start"},
@@ -68,6 +77,28 @@ static struct addr_marker address_markers[] = {
	{-1, NULL},
};

static struct ptd_mm_info kernel_ptd_info = {
	.mm		= &init_mm,
	.markers	= address_markers,
	.base_addr	= KERN_VIRT_START,
	.end		= ULONG_MAX,
};

#ifdef CONFIG_EFI
static struct addr_marker efi_addr_markers[] = {
		{ 0,		"UEFI runtime start" },
		{ SZ_1G,	"UEFI runtime end" },
		{ -1,		NULL }
};

static struct ptd_mm_info efi_ptd_info = {
	.mm		= &efi_mm,
	.markers	= efi_addr_markers,
	.base_addr	= 0,
	.end		= SZ_2G,
};
#endif

/* Page Table Entry */
struct prot_bits {
	u64 mask;
@@ -245,22 +276,22 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr,
	}
}

static void ptdump_walk(struct seq_file *s)
static void ptdump_walk(struct seq_file *s, struct ptd_mm_info *pinfo)
{
	struct pg_state st = {
		.seq = s,
		.marker = address_markers,
		.marker = pinfo->markers,
		.level = -1,
		.ptdump = {
			.note_page = note_page,
			.range = (struct ptdump_range[]) {
				{KERN_VIRT_START, ULONG_MAX},
				{pinfo->base_addr, pinfo->end},
				{0, 0}
			}
		}
	};

	ptdump_walk_pgd(&st.ptdump, &init_mm, NULL);
	ptdump_walk_pgd(&st.ptdump, pinfo->mm, NULL);
}

void ptdump_check_wx(void)
@@ -293,7 +324,7 @@ void ptdump_check_wx(void)

static int ptdump_show(struct seq_file *m, void *v)
{
	ptdump_walk(m);
	ptdump_walk(m, m->private);

	return 0;
}
@@ -308,8 +339,13 @@ static int ptdump_init(void)
		for (j = 0; j < ARRAY_SIZE(pte_bits); j++)
			pg_level[i].mask |= pte_bits[j].mask;

	debugfs_create_file("kernel_page_tables", 0400, NULL, NULL,
	debugfs_create_file("kernel_page_tables", 0400, NULL, &kernel_ptd_info,
			    &ptdump_fops);
#ifdef CONFIG_EFI
	if (efi_enabled(EFI_RUNTIME_SERVICES))
		debugfs_create_file("efi_page_tables", 0400, NULL, &efi_ptd_info,
				    &ptdump_fops);
#endif

	return 0;
}