[RFC,v3,12/12] x86/efi: Disable LASS enforcement when switching to EFI MM

Message ID 20230609183632.48706-13-alexander.shishkin@linux.intel.com
State New
Headers
Series Enable Linear Address Space Separation support |

Commit Message

Alexander Shishkin June 9, 2023, 6:36 p.m. UTC
  From: Sohil Mehta <sohil.mehta@intel.com>

[Code is experimental and not yet ready to be merged upstream]

PeterZ suggested that EFI memory can be mapped in user virtual address
space which would trigger LASS violation upon access. It isn't exactly
clear how and when these user address mapping happen. It may be possible
this is related to EFI mixed mode.
Link:https://lore.kernel.org/lkml/Y73S56t%2FwDIGEPlK@hirez.programming.kicks-ass.net/

stac()/clac() calls in the EFI MM enter and exit functions trigger
objtool warnings due to switch_mm() not being classified as
func_uaccess_safe. Refer Objtool warnings section #9 in the document
tools/objtool/Documentation/objtool.txt. This would need to be resolved
before even considering merging.

Signed-off-by: Sohil Mehta <sohil.mehta@intel.com>
Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
 arch/x86/platform/efi/efi_64.c | 6 ++++++
 1 file changed, 6 insertions(+)
  

Patch

diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index 232acf418cfb..20966efcd87a 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -473,9 +473,14 @@  void __init efi_dump_pagetable(void)
  * while the EFI-mm is borrowed. mmgrab()/mmdrop() is not used because the mm
  * can not change under us.
  * It should be ensured that there are no concurrent calls to this function.
+ *
+ * Disable LASS enforcement temporarily when switching to EFI MM since it could
+ * be mapped into the low 64-bit virtual address space with address bit 63 set
+ * to 0.
  */
 void efi_enter_mm(void)
 {
+	stac();
 	efi_prev_mm = current->active_mm;
 	current->active_mm = &efi_mm;
 	switch_mm(efi_prev_mm, &efi_mm, NULL);
@@ -485,6 +490,7 @@  void efi_leave_mm(void)
 {
 	current->active_mm = efi_prev_mm;
 	switch_mm(&efi_mm, efi_prev_mm, NULL);
+	clac();
 }
 
 static DEFINE_SPINLOCK(efi_runtime_lock);