lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Fri, 21 Jun 2024 21:12:02 +0800
From: "Hou Wenlong" <houwenlong.hwl@...group.com>
To: linux-kernel@...r.kernel.org
Cc: "Lai Jiangshan" <jiangshan.ljs@...group.com>,
  "Hou Wenlong" <houwenlong.hwl@...group.com>,
  "Xin Li" <xin@...or.com>,
  "H. Peter Anvin" <hpa@...or.com>,
  "Andy Lutomirski" <luto@...nel.org>,
  "Thomas Gleixner" <tglx@...utronix.de>,
  "Ingo Molnar" <mingo@...hat.com>,
  "Borislav Petkov" <bp@...en8.de>,
  "Dave Hansen" <dave.hansen@...ux.intel.com>,
   <x86@...nel.org>,
  "Peter Zijlstra" <peterz@...radead.org>,
  "Jacob Pan" <jacob.jun.pan@...ux.intel.com>,
  "Rick Edgecombe" <rick.p.edgecombe@...el.com>,
  "Paolo Bonzini" <pbonzini@...hat.com>
Subject: [PATCH 2/2] x86/fred: Add a page fault entry stub for FRED

The page fault handler is installed into the IDT before FRED setup is
done. During this gap, the handler would retrieve the wrong CR2 from the
stack if FRED is present and a #PF is triggered. Similar to the debug
entry, a page fault entry stub for FRED should be added.

Fixes: 14619d912b65 ("x86/fred: FRED entry/exit and dispatch code")
Signed-off-by: Hou Wenlong <houwenlong.hwl@...group.com>
---
 arch/x86/entry/entry_fred.c     |  2 +-
 arch/x86/include/asm/idtentry.h | 12 ++++++++++++
 arch/x86/mm/fault.c             | 19 +++++++++++++++----
 3 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/arch/x86/entry/entry_fred.c b/arch/x86/entry/entry_fred.c
index f004a4dc74c2..73ea483fec87 100644
--- a/arch/x86/entry/entry_fred.c
+++ b/arch/x86/entry/entry_fred.c
@@ -181,7 +181,7 @@ static noinstr void fred_hwexc(struct pt_regs *regs, unsigned long error_code)
 {
 	/* Optimize for #PF. That's the only exception which matters performance wise */
 	if (likely(regs->fred_ss.vector == X86_TRAP_PF))
-		return exc_page_fault(regs, error_code);
+		return fred_exc_page_fault(regs, error_code);
 
 	switch (regs->fred_ss.vector) {
 	case X86_TRAP_DE: return exc_divide_error(regs);
diff --git a/arch/x86/include/asm/idtentry.h b/arch/x86/include/asm/idtentry.h
index daee9f7765bc..a0fd9cfa08d6 100644
--- a/arch/x86/include/asm/idtentry.h
+++ b/arch/x86/include/asm/idtentry.h
@@ -86,6 +86,7 @@ static __always_inline void __##func(struct pt_regs *regs)
 #define DECLARE_IDTENTRY_ERRORCODE(vector, func)			\
 	asmlinkage void asm_##func(void);				\
 	asmlinkage void xen_asm_##func(void);				\
+	void fred_##func(struct pt_regs *regs, unsigned long error_code);\
 	__visible void func(struct pt_regs *regs, unsigned long error_code)
 
 /**
@@ -180,6 +181,17 @@ noinstr void fred_##func(struct pt_regs *regs)
 #define DEFINE_IDTENTRY_RAW_ERRORCODE(func)				\
 __visible noinstr void func(struct pt_regs *regs, unsigned long error_code)
 
+/**
+ * DEFINE_FRED_RAW_ERRORCODE - Emit code for raw FRED entry points
+ * @func:	Function name of the entry point
+ *
+ * @func is called from the FRED event dispatcher with interrupts disabled.
+ *
+ * See @DEFINE_IDTENTRY_RAW_ERRORCODE for further details.
+ */
+#define DEFINE_FREDENTRY_RAW_ERRORCODE(func)			\
+__visible noinstr void fred_##func(struct pt_regs *regs, unsigned long error_code)
+
 /**
  * DECLARE_IDTENTRY_IRQ - Declare functions for device interrupt IDT entry
  *			  points (common/spurious)
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index e6c469b323cc..712dcf491daa 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -1490,12 +1490,10 @@ handle_page_fault(struct pt_regs *regs, unsigned long error_code,
 	}
 }
 
-DEFINE_IDTENTRY_RAW_ERRORCODE(exc_page_fault)
+static noinstr void __exc_page_fault(struct pt_regs *regs, unsigned long error_code,
+				     unsigned long address)
 {
 	irqentry_state_t state;
-	unsigned long address;
-
-	address = cpu_feature_enabled(X86_FEATURE_FRED) ? fred_event_data(regs) : read_cr2();
 
 	prefetchw(&current->mm->mmap_lock);
 
@@ -1541,3 +1539,16 @@ DEFINE_IDTENTRY_RAW_ERRORCODE(exc_page_fault)
 
 	irqentry_exit(regs, state);
 }
+
+DEFINE_IDTENTRY_RAW_ERRORCODE(exc_page_fault)
+{
+	__exc_page_fault(regs, error_code, read_cr2());
+}
+
+#ifdef CONFIG_X86_FRED
+DEFINE_FREDENTRY_RAW_ERRORCODE(exc_page_fault)
+{
+	/* FRED #PF stores CR2 on the stack. */
+	__exc_page_fault(regs, error_code, fred_event_data(regs));
+}
+#endif
-- 
2.31.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ