[PATCH RFC v9 12/51] x86/fault: Report RMP page faults for kernel addresses

Michael Roth posted 51 patches 2 years, 8 months ago
There is a newer version of this series
[PATCH RFC v9 12/51] x86/fault: Report RMP page faults for kernel addresses
Posted by Michael Roth 2 years, 8 months ago
RMP #PFs on kernel addresses are fatal and should never happen in
practice. They indicate a bug in the host kernel somewhere, so dump some
information about any RMP entries related to the faulting address to aid
with debugging.

Signed-off-by: Michael Roth <michael.roth@amd.com>
---
 arch/x86/mm/fault.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 95791071e3cd..d46b9cf832b9 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -33,6 +33,7 @@
 #include <asm/kvm_para.h>		/* kvm_handle_async_pf		*/
 #include <asm/vdso.h>			/* fixup_vdso_exception()	*/
 #include <asm/irq_stack.h>
+#include <asm/sev-host.h>		/* sev_dump_rmpentry()          */
 
 #define CREATE_TRACE_POINTS
 #include <asm/trace/exceptions.h>
@@ -579,6 +580,18 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code, unsigned long ad
 	}
 
 	dump_pagetable(address);
+
+	if (error_code & X86_PF_RMP) {
+		unsigned int level;
+		pgd_t *pgd;
+		pte_t *pte;
+
+		pgd = __va(read_cr3_pa());
+		pgd += pgd_index(address);
+		pte = lookup_address_in_pgd(pgd, address, &level);
+
+		sev_dump_rmpentry(pte_pfn(*pte));
+	}
 }
 
 static noinline void
-- 
2.25.1
Re: [PATCH RFC v9 12/51] x86/fault: Report RMP page faults for kernel addresses
Posted by Dave Hansen 2 years, 8 months ago
On 6/11/23 21:25, Michael Roth wrote:
>  	dump_pagetable(address);
> +
> +	if (error_code & X86_PF_RMP) {
> +		unsigned int level;
> +		pgd_t *pgd;
> +		pte_t *pte;
> +
> +		pgd = __va(read_cr3_pa());
> +		pgd += pgd_index(address);
> +		pte = lookup_address_in_pgd(pgd, address, &level);
> +
> +		sev_dump_rmpentry(pte_pfn(*pte));
> +	}
>  }

It would be nice to trim this hunk down.  Can you make it:

	if (error_code & X86_PF_RMP)
		sev_dump_rmpentry(address);

and hide the rest of the logic in the helper?

Oh, and lookup_address_in_pgd() can return NULL.  It's not great to page
fault in the page fault handler.  Could you fix that up too, please?