linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] x86, ptdump: a EFI related fix + enhancements
@ 2014-09-20 21:22 Mathias Krause
  2014-09-20 21:22 ` [PATCH 1/3] x86, ptdump: Add section for EFI runtime services Mathias Krause
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Mathias Krause @ 2014-09-20 21:22 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H. Peter Anvin
  Cc: linux-kernel, x86, Mathias Krause

This series slightly simplifies (patch 2) and then enhances (patch 3)
the page table dump code to respect the page table attributes of the
whole page table walk when determining the effective access rights. It
also fixes the regression that the EFI runtime service mappings are no
longer visible when CONFIG_X86_ESPFIX64 is set (patch 1).

Please apply!


Mathias Krause (3):
  x86, ptdump: Add section for EFI runtime services
  x86, ptdump: Simplify page flag evaluation code
  x86, ptdump: Take parent page flags into account

 arch/x86/include/asm/pgtable_64_types.h |    2 +
 arch/x86/mm/dump_pagetables.c           |  175 +++++++++++------------
 arch/x86/platform/efi/efi_64.c          |    3 +-
 3 files changed, 90 insertions(+), 90 deletions(-)

-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] x86, ptdump: Add section for EFI runtime services
  2014-09-20 21:22 [PATCH 0/3] x86, ptdump: a EFI related fix + enhancements Mathias Krause
@ 2014-09-20 21:22 ` Mathias Krause
  2014-09-20 21:22 ` [PATCH 2/3] x86, ptdump: Simplify page flag evaluation code Mathias Krause
  2014-09-20 21:22 ` [PATCH 3/3] x86, ptdump: Take parent page flags into account Mathias Krause
  2 siblings, 0 replies; 5+ messages in thread
From: Mathias Krause @ 2014-09-20 21:22 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H. Peter Anvin
  Cc: linux-kernel, x86, Mathias Krause, Matt Fleming

In commit 3891a04aafd6 ("x86-64, espfix: Don't leak bits 31:16 of %esp
returning..") the "ESPFix Area" was added to the page table dump special
sections. That area, though, has a limited amount of entries printed.

The EFI runtime services are, unfortunately, located in-between the
espfix area and the high kernel memory mapping. Due to the enforced
limitation for the espfix area, the EFI mappings won't be printed in the
page table dump.

To make the ESP runtime service mappings visible again, provide them a
dedicated entry.

Signed-off-by: Mathias Krause <minipli@googlemail.com>
Cc: Matt Fleming <matt.fleming@intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86/include/asm/pgtable_64_types.h |    2 ++
 arch/x86/mm/dump_pagetables.c           |    3 +++
 arch/x86/platform/efi/efi_64.c          |    3 +--
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h
index 7166e25ecb57..602b6028c5b6 100644
--- a/arch/x86/include/asm/pgtable_64_types.h
+++ b/arch/x86/include/asm/pgtable_64_types.h
@@ -63,6 +63,8 @@ typedef struct { pteval_t pte; } pte_t;
 #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
 #define ESPFIX_PGD_ENTRY _AC(-2, UL)
 #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
+#define EFI_VA_START	 ( -4 * (_AC(1, UL) << 30))
+#define EFI_VA_END	 (-68 * (_AC(1, UL) << 30))
 
 #define EARLY_DYNAMIC_PAGE_TABLES	64
 
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index 95a427e57887..1a8053d1012e 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -76,6 +76,9 @@ static struct addr_marker address_markers[] = {
 # ifdef CONFIG_X86_ESPFIX64
 	{ ESPFIX_BASE_ADDR,	"ESPfix Area", 16 },
 # endif
+# ifdef CONFIG_EFI
+	{ EFI_VA_END,		"EFI Runtime Services" },
+# endif
 	{ __START_KERNEL_map,   "High Kernel Mapping" },
 	{ MODULES_VADDR,        "Modules" },
 	{ MODULES_END,          "End Modules" },
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index 290d397e1dd9..899c7f17ad85 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -48,8 +48,7 @@ static unsigned long efi_flags __initdata;
  * We allocate runtime services regions bottom-up, starting from -4G, i.e.
  * 0xffff_ffff_0000_0000 and limit EFI VA mapping space to 64G.
  */
-static u64 efi_va	= -4 * (1UL << 30);
-#define EFI_VA_END	(-68 * (1UL << 30))
+static u64 efi_va = EFI_VA_START;
 
 /*
  * Scratch space used for switching the pagetable in the EFI stub
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] x86, ptdump: Simplify page flag evaluation code
  2014-09-20 21:22 [PATCH 0/3] x86, ptdump: a EFI related fix + enhancements Mathias Krause
  2014-09-20 21:22 ` [PATCH 1/3] x86, ptdump: Add section for EFI runtime services Mathias Krause
@ 2014-09-20 21:22 ` Mathias Krause
  2014-09-21  7:05   ` Ingo Molnar
  2014-09-20 21:22 ` [PATCH 3/3] x86, ptdump: Take parent page flags into account Mathias Krause
  2 siblings, 1 reply; 5+ messages in thread
From: Mathias Krause @ 2014-09-20 21:22 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H. Peter Anvin
  Cc: linux-kernel, x86, Mathias Krause, Arjan van de Ven

The code evaluating the page flags is rather scattered. Simplify it by
folding the 'if .. else ..' part into the actual print call. Make use
of appropriate format strings to get the desired string width.

Also change the pt_dump_seq_printf() and pt_dump_cont_printf() macros to
use the common 'do ... while(0)' pattern instead of a compound statement
expression. We don't need no expression, just the statement.

Last, but not least, fix the checkpatch warnings for the lines touched.

Signed-off-by: Mathias Krause <minipli@googlemail.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
---
 arch/x86/mm/dump_pagetables.c |  106 ++++++++++++---------------------
 1 file changed, 39 insertions(+), 67 deletions(-)

diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index 1a8053d1012e..f7af11c7e83f 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -100,23 +100,23 @@ static struct addr_marker address_markers[] = {
 #define PUD_LEVEL_MULT (PTRS_PER_PMD * PMD_LEVEL_MULT)
 #define PGD_LEVEL_MULT (PTRS_PER_PUD * PUD_LEVEL_MULT)
 
-#define pt_dump_seq_printf(m, to_dmesg, fmt, args...)		\
-({								\
-	if (to_dmesg)					\
-		printk(KERN_INFO fmt, ##args);			\
-	else							\
-		if (m)						\
-			seq_printf(m, fmt, ##args);		\
-})
-
-#define pt_dump_cont_printf(m, to_dmesg, fmt, args...)		\
-({								\
-	if (to_dmesg)					\
-		printk(KERN_CONT fmt, ##args);			\
-	else							\
-		if (m)						\
-			seq_printf(m, fmt, ##args);		\
-})
+#define ptd_print(m, to_dmesg, fmt, args...)			\
+	do {							\
+		if (to_dmesg)					\
+			pr_info(fmt, ##args);			\
+		else						\
+			if (m)					\
+				seq_printf(m, fmt, ##args);	\
+	} while (0)
+
+#define ptd_cont(m, to_dmesg, fmt, args...)			\
+	do {							\
+		if (to_dmesg)					\
+			pr_cont(fmt, ##args);			\
+		else						\
+			if (m)					\
+				seq_printf(m, fmt, ##args);	\
+	} while (0)
 
 /*
  * Print a readable form of a pgprot_t to the seq_file
@@ -129,47 +129,23 @@ static void printk_prot(struct seq_file *m, pgprot_t prot, int level, bool dmsg)
 
 	if (!pgprot_val(prot)) {
 		/* Not present */
-		pt_dump_cont_printf(m, dmsg, "                          ");
+		ptd_cont(m, dmsg, "%-26s", "");
 	} else {
-		if (pr & _PAGE_USER)
-			pt_dump_cont_printf(m, dmsg, "USR ");
-		else
-			pt_dump_cont_printf(m, dmsg, "    ");
-		if (pr & _PAGE_RW)
-			pt_dump_cont_printf(m, dmsg, "RW ");
-		else
-			pt_dump_cont_printf(m, dmsg, "ro ");
-		if (pr & _PAGE_PWT)
-			pt_dump_cont_printf(m, dmsg, "PWT ");
-		else
-			pt_dump_cont_printf(m, dmsg, "    ");
-		if (pr & _PAGE_PCD)
-			pt_dump_cont_printf(m, dmsg, "PCD ");
-		else
-			pt_dump_cont_printf(m, dmsg, "    ");
+		ptd_cont(m, dmsg, "%-4s", pr & _PAGE_USER ? "USR" : "");
+		ptd_cont(m, dmsg, "%-3s", pr & _PAGE_RW ? "RW" : "ro");
+		ptd_cont(m, dmsg, "%-4s", pr & _PAGE_PWT ? "PWT" : "");
+		ptd_cont(m, dmsg, "%-4s", pr & _PAGE_PCD ? "PCD" : "");
 
 		/* Bit 9 has a different meaning on level 3 vs 4 */
-		if (level <= 3) {
-			if (pr & _PAGE_PSE)
-				pt_dump_cont_printf(m, dmsg, "PSE ");
-			else
-				pt_dump_cont_printf(m, dmsg, "    ");
-		} else {
-			if (pr & _PAGE_PAT)
-				pt_dump_cont_printf(m, dmsg, "pat ");
-			else
-				pt_dump_cont_printf(m, dmsg, "    ");
-		}
-		if (pr & _PAGE_GLOBAL)
-			pt_dump_cont_printf(m, dmsg, "GLB ");
+		if (level <= 3)
+			ptd_cont(m, dmsg, "%-4s", pr & _PAGE_PSE ? "PSE" : "");
 		else
-			pt_dump_cont_printf(m, dmsg, "    ");
-		if (pr & _PAGE_NX)
-			pt_dump_cont_printf(m, dmsg, "NX ");
-		else
-			pt_dump_cont_printf(m, dmsg, "x  ");
+			ptd_cont(m, dmsg, "%-4s", pr & _PAGE_PAT ? "pat" : "");
+
+		ptd_cont(m, dmsg, "%-4s", pr & _PAGE_GLOBAL ? "GLB" : "");
+		ptd_cont(m, dmsg, "%-3s", pr & _PAGE_NX ? "NX" : "x");
 	}
-	pt_dump_cont_printf(m, dmsg, "%s\n", level_name[level]);
+	ptd_cont(m, dmsg, "%s\n", level_name[level]);
 }
 
 /*
@@ -209,8 +185,7 @@ static void note_page(struct seq_file *m, struct pg_state *st,
 		st->level = level;
 		st->marker = address_markers;
 		st->lines = 0;
-		pt_dump_seq_printf(m, st->to_dmesg, "---[ %s ]---\n",
-				   st->marker->name);
+		ptd_print(m, st->to_dmesg, "---[ %s ]---\n", st->marker->name);
 	} else if (prot != cur || level != st->level ||
 		   st->current_address >= st->marker[1].start_address) {
 		const char *unit = units;
@@ -222,18 +197,16 @@ static void note_page(struct seq_file *m, struct pg_state *st,
 		 */
 		if (!st->marker->max_lines ||
 		    st->lines < st->marker->max_lines) {
-			pt_dump_seq_printf(m, st->to_dmesg,
-					   "0x%0*lx-0x%0*lx   ",
-					   width, st->start_address,
-					   width, st->current_address);
+			ptd_print(m, st->to_dmesg, "0x%0*lx-0x%0*lx   ",
+				  width, st->start_address,
+				  width, st->current_address);
 
 			delta = st->current_address - st->start_address;
 			while (!(delta & 1023) && unit[1]) {
 				delta >>= 10;
 				unit++;
 			}
-			pt_dump_cont_printf(m, st->to_dmesg, "%9lu%c ",
-					    delta, *unit);
+			ptd_cont(m, st->to_dmesg, "%9lu%c ", delta, *unit);
 			printk_prot(m, st->current_prot, st->level,
 				    st->to_dmesg);
 		}
@@ -249,15 +222,14 @@ static void note_page(struct seq_file *m, struct pg_state *st,
 			    st->lines > st->marker->max_lines) {
 				unsigned long nskip =
 					st->lines - st->marker->max_lines;
-				pt_dump_seq_printf(m, st->to_dmesg,
-						   "... %lu entr%s skipped ... \n",
-						   nskip,
-						   nskip == 1 ? "y" : "ies");
+				ptd_print(m, st->to_dmesg,
+					  "... %lu entr%s skipped ...\n",
+					  nskip, nskip == 1 ? "y" : "ies");
 			}
 			st->marker++;
 			st->lines = 0;
-			pt_dump_seq_printf(m, st->to_dmesg, "---[ %s ]---\n",
-					   st->marker->name);
+			ptd_print(m, st->to_dmesg, "---[ %s ]---\n",
+				  st->marker->name);
 		}
 
 		st->start_address = st->current_address;
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] x86, ptdump: Take parent page flags into account
  2014-09-20 21:22 [PATCH 0/3] x86, ptdump: a EFI related fix + enhancements Mathias Krause
  2014-09-20 21:22 ` [PATCH 1/3] x86, ptdump: Add section for EFI runtime services Mathias Krause
  2014-09-20 21:22 ` [PATCH 2/3] x86, ptdump: Simplify page flag evaluation code Mathias Krause
@ 2014-09-20 21:22 ` Mathias Krause
  2 siblings, 0 replies; 5+ messages in thread
From: Mathias Krause @ 2014-09-20 21:22 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H. Peter Anvin
  Cc: linux-kernel, x86, Mathias Krause, Arjan van de Ven

We currently ignore the flags of parent entries when evaluating the
flags of a given page table entry in printk_prot(). This might lead to
wrong results when a particular flag in a parent entry differs from the
one of the current page table entry. So, we might show memory regions as
writable even if not all parent entries have the _PAGE_RW bit set. The
same is true for the _PAGE_USER and _PAGE_NX flags. There values in
upper levels of the hierarchy influence the effective access rights but
are ignored in printk_prot().

To handle those cases, track the effective flags for _PAGE_USER,
_PAGE_RW and _PAGE_NX throughout the page table walk and take them into
account when printing a page table entry's flags.

Signed-off-by: Mathias Krause <minipli@googlemail.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
---
The kernel currently does not do such a thing as having a parent page
table entry having stricter flags set than the final page table entry
itself. But we might start doing so in the future. Even if not, better
be correct and safe here, then sorry for printing wrong results. This is
a debugging tool that should aid the developer, not lie to him.

This patch, in fact, helped me to debug some EFI runtime service mapping
related problems where the _PAGE_NX bit was set in the PGD entry but
ignored when shown via /sys/kernel/debug/kernel_page_tables.
---
 arch/x86/mm/dump_pagetables.c |   72 ++++++++++++++++++++++-----------
 1 file changed, 48 insertions(+), 24 deletions(-)

diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index f7af11c7e83f..e9aa46f7ddef 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -118,11 +118,26 @@ static struct addr_marker address_markers[] = {
 				seq_printf(m, fmt, ##args);	\
 	} while (0)
 
+static pgprot_t effective_prot(pgprot_t parent_prot, pgprot_t new_prot)
+{
+	pgprotval_t pv_parent = pgprot_val(parent_prot) & PTE_FLAGS_MASK;
+	pgprotval_t pv_new = pgprot_val(new_prot) & PTE_FLAGS_MASK;
+	pgprotval_t pv_effective = 0;
+
+	pv_effective |= (pv_parent & pv_new) & _PAGE_USER;
+	pv_effective |= (pv_parent & pv_new) & _PAGE_RW;
+	pv_effective |= (pv_parent | pv_new) & _PAGE_NX;
+
+	return __pgprot(pv_effective);
+}
+
 /*
  * Print a readable form of a pgprot_t to the seq_file
  */
-static void printk_prot(struct seq_file *m, pgprot_t prot, int level, bool dmsg)
+static void printk_prot(struct seq_file *m, pgprot_t eff_prot, pgprot_t prot,
+			int level, bool dmsg)
 {
+	pgprotval_t pr_eff = pgprot_val(effective_prot(eff_prot, prot));
 	pgprotval_t pr = pgprot_val(prot);
 	static const char * const level_name[] =
 		{ "cr3", "pgd", "pud", "pmd", "pte" };
@@ -131,8 +146,8 @@ static void printk_prot(struct seq_file *m, pgprot_t prot, int level, bool dmsg)
 		/* Not present */
 		ptd_cont(m, dmsg, "%-26s", "");
 	} else {
-		ptd_cont(m, dmsg, "%-4s", pr & _PAGE_USER ? "USR" : "");
-		ptd_cont(m, dmsg, "%-3s", pr & _PAGE_RW ? "RW" : "ro");
+		ptd_cont(m, dmsg, "%-4s", pr_eff & _PAGE_USER ? "USR" : "");
+		ptd_cont(m, dmsg, "%-3s", pr_eff & _PAGE_RW ? "RW" : "ro");
 		ptd_cont(m, dmsg, "%-4s", pr & _PAGE_PWT ? "PWT" : "");
 		ptd_cont(m, dmsg, "%-4s", pr & _PAGE_PCD ? "PCD" : "");
 
@@ -143,7 +158,7 @@ static void printk_prot(struct seq_file *m, pgprot_t prot, int level, bool dmsg)
 			ptd_cont(m, dmsg, "%-4s", pr & _PAGE_PAT ? "pat" : "");
 
 		ptd_cont(m, dmsg, "%-4s", pr & _PAGE_GLOBAL ? "GLB" : "");
-		ptd_cont(m, dmsg, "%-3s", pr & _PAGE_NX ? "NX" : "x");
+		ptd_cont(m, dmsg, "%-3s", pr_eff & _PAGE_NX ? "NX" : "x");
 	}
 	ptd_cont(m, dmsg, "%s\n", level_name[level]);
 }
@@ -166,7 +181,7 @@ static unsigned long normalize_addr(unsigned long u)
  * print what we collected so far.
  */
 static void note_page(struct seq_file *m, struct pg_state *st,
-		      pgprot_t new_prot, int level)
+		      pgprot_t eff_prot, pgprot_t new_prot, int level)
 {
 	pgprotval_t prot, cur;
 	static const char units[] = "BKMGTPE";
@@ -207,7 +222,7 @@ static void note_page(struct seq_file *m, struct pg_state *st,
 				unit++;
 			}
 			ptd_cont(m, st->to_dmesg, "%9lu%c ", delta, *unit);
-			printk_prot(m, st->current_prot, st->level,
+			printk_prot(m, eff_prot, st->current_prot, st->level,
 				    st->to_dmesg);
 		}
 		st->lines++;
@@ -239,7 +254,7 @@ static void note_page(struct seq_file *m, struct pg_state *st,
 }
 
 static void walk_pte_level(struct seq_file *m, struct pg_state *st, pmd_t addr,
-							unsigned long P)
+			   pgprot_t eff_prot, unsigned long P)
 {
 	int i;
 	pte_t *start;
@@ -249,7 +264,7 @@ static void walk_pte_level(struct seq_file *m, struct pg_state *st, pmd_t addr,
 		pgprot_t prot = pte_pgprot(*start);
 
 		st->current_address = normalize_addr(P + i * PTE_LEVEL_MULT);
-		note_page(m, st, prot, 4);
+		note_page(m, st, eff_prot, prot, 4);
 		start++;
 	}
 }
@@ -257,7 +272,7 @@ static void walk_pte_level(struct seq_file *m, struct pg_state *st, pmd_t addr,
 #if PTRS_PER_PMD > 1
 
 static void walk_pmd_level(struct seq_file *m, struct pg_state *st, pud_t addr,
-							unsigned long P)
+			   pgprot_t eff_prot, unsigned long P)
 {
 	int i;
 	pmd_t *start;
@@ -266,21 +281,23 @@ static void walk_pmd_level(struct seq_file *m, struct pg_state *st, pud_t addr,
 	for (i = 0; i < PTRS_PER_PMD; i++) {
 		st->current_address = normalize_addr(P + i * PMD_LEVEL_MULT);
 		if (!pmd_none(*start)) {
-			pgprotval_t prot = pmd_val(*start) & PTE_FLAGS_MASK;
+			pgprotval_t prot_val = pmd_val(*start) & PTE_FLAGS_MASK;
+			pgprot_t prot = __pgprot(prot_val);
 
 			if (pmd_large(*start) || !pmd_present(*start))
-				note_page(m, st, __pgprot(prot), 3);
+				note_page(m, st, eff_prot, prot, 3);
 			else
 				walk_pte_level(m, st, *start,
+					       effective_prot(eff_prot, prot),
 					       P + i * PMD_LEVEL_MULT);
 		} else
-			note_page(m, st, __pgprot(0), 3);
+			note_page(m, st, eff_prot, __pgprot(0), 3);
 		start++;
 	}
 }
 
 #else
-#define walk_pmd_level(m,s,a,p) walk_pte_level(m,s,__pmd(pud_val(a)),p)
+#define walk_pmd_level(m,s,a,e,p) walk_pte_level(m,s,__pmd(pud_val(a)),e,p)
 #define pud_large(a) pmd_large(__pmd(pud_val(a)))
 #define pud_none(a)  pmd_none(__pmd(pud_val(a)))
 #endif
@@ -288,7 +305,7 @@ static void walk_pmd_level(struct seq_file *m, struct pg_state *st, pud_t addr,
 #if PTRS_PER_PUD > 1
 
 static void walk_pud_level(struct seq_file *m, struct pg_state *st, pgd_t addr,
-							unsigned long P)
+			   pgprot_t eff_prot, unsigned long P)
 {
 	int i;
 	pud_t *start;
@@ -298,22 +315,24 @@ static void walk_pud_level(struct seq_file *m, struct pg_state *st, pgd_t addr,
 	for (i = 0; i < PTRS_PER_PUD; i++) {
 		st->current_address = normalize_addr(P + i * PUD_LEVEL_MULT);
 		if (!pud_none(*start)) {
-			pgprotval_t prot = pud_val(*start) & PTE_FLAGS_MASK;
+			pgprotval_t prot_val = pud_val(*start) & PTE_FLAGS_MASK;
+			pgprot_t prot = __pgprot(prot_val);
 
 			if (pud_large(*start) || !pud_present(*start))
-				note_page(m, st, __pgprot(prot), 2);
+				note_page(m, st, eff_prot, prot, 2);
 			else
 				walk_pmd_level(m, st, *start,
+					       effective_prot(eff_prot, prot),
 					       P + i * PUD_LEVEL_MULT);
 		} else
-			note_page(m, st, __pgprot(0), 2);
+			note_page(m, st, eff_prot, __pgprot(0), 2);
 
 		start++;
 	}
 }
 
 #else
-#define walk_pud_level(m,s,a,p) walk_pmd_level(m,s,__pud(pgd_val(a)),p)
+#define walk_pud_level(m,s,a,e,p) walk_pmd_level(m,s,__pud(pgd_val(a)),e,p)
 #define pgd_large(a) pud_large(__pud(pgd_val(a)))
 #define pgd_none(a)  pud_none(__pud(pgd_val(a)))
 #endif
@@ -327,6 +346,7 @@ void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 #endif
 	int i;
 	struct pg_state st = {};
+	pgprot_t eff_prot = __pgprot(0);
 
 	if (pgd) {
 		start = pgd;
@@ -336,22 +356,26 @@ void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 	for (i = 0; i < PTRS_PER_PGD; i++) {
 		st.current_address = normalize_addr(i * PGD_LEVEL_MULT);
 		if (!pgd_none(*start)) {
-			pgprotval_t prot = pgd_val(*start) & PTE_FLAGS_MASK;
+			pgprotval_t prot_val = pgd_val(*start) & PTE_FLAGS_MASK;
+			pgprot_t prot = __pgprot(prot_val);
 
+			eff_prot = effective_prot(prot, prot);
 			if (pgd_large(*start) || !pgd_present(*start))
-				note_page(m, &st, __pgprot(prot), 1);
+				note_page(m, &st, eff_prot, prot, 1);
 			else
-				walk_pud_level(m, &st, *start,
+				walk_pud_level(m, &st, *start, eff_prot,
 					       i * PGD_LEVEL_MULT);
-		} else
-			note_page(m, &st, __pgprot(0), 1);
+		} else {
+			eff_prot = __pgprot(0);
+			note_page(m, &st, eff_prot, __pgprot(0), 1);
+		}
 
 		start++;
 	}
 
 	/* Flush out the last page */
 	st.current_address = normalize_addr(PTRS_PER_PGD*PGD_LEVEL_MULT);
-	note_page(m, &st, __pgprot(0), 0);
+	note_page(m, &st, eff_prot, __pgprot(0), 0);
 }
 
 static int ptdump_show(struct seq_file *m, void *v)
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/3] x86, ptdump: Simplify page flag evaluation code
  2014-09-20 21:22 ` [PATCH 2/3] x86, ptdump: Simplify page flag evaluation code Mathias Krause
@ 2014-09-21  7:05   ` Ingo Molnar
  0 siblings, 0 replies; 5+ messages in thread
From: Ingo Molnar @ 2014-09-21  7:05 UTC (permalink / raw)
  To: Mathias Krause
  Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, linux-kernel, x86,
	Arjan van de Ven


* Mathias Krause <minipli@googlemail.com> wrote:

> -#define pt_dump_seq_printf(m, to_dmesg, fmt, args...)		\
> +#define ptd_print(m, to_dmesg, fmt, args...)			\

Please don't abbreviate to non-obvious shortcuts ('ptd'), keep 
using the pt_dump_ prefix which was just fine.

(If checkpatch complains about lines slightly above 80cols then 
ignore checkpatch, don't uglify the code.)

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-09-21  7:05 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-20 21:22 [PATCH 0/3] x86, ptdump: a EFI related fix + enhancements Mathias Krause
2014-09-20 21:22 ` [PATCH 1/3] x86, ptdump: Add section for EFI runtime services Mathias Krause
2014-09-20 21:22 ` [PATCH 2/3] x86, ptdump: Simplify page flag evaluation code Mathias Krause
2014-09-21  7:05   ` Ingo Molnar
2014-09-20 21:22 ` [PATCH 3/3] x86, ptdump: Take parent page flags into account Mathias Krause

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).