Skip to contentSkip to conversation

arm64/efi: Avoid voluntary preemption with efi_mm installed

PATCH Applied Will Deacon 2 participants 3 messages Aug 11 – Aug 12

Subsystems (2)
lore
Share & tools
lore

Will Deacon

author maintainer
#0 lore raw

PATCH 1/1 arm64/efi: Avoid voluntary preemption with efi_mm installed

Gus reports a bad kernel memory access when using software PAN (CONFIG_ARM64_SW_TTBR0_PAN=y) on a machine with support for EFI runtime services:

  Unable to handle kernel access to user memory outside uaccess routines
    at virtual address 00000000f322ff30
  Mem abort info:
    ESR = 0x0000000096000004
    FSC = 0x04: level 0 translation fault
  Internal error: Oops: 0000000096000004 [#1]  SMP
  Workqueue: efi_rts_wq efi_call_rts
  pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
  pc : efi_call_rts+0xd8/0x288
  Call trace:
   efi_call_rts+0xd8/0x288 (P)
   process_one_work+0x178/0x4f8
   worker_thread+0x194/0x328

This is because the fpsimd context management code called from __efi_fpsimd_begin() can preempt voluntarily, returning later to the EFI code with an incorrect value for TTBR0_EL1 thanks to the deferred mm switching used by the software PAN implementation.

Since EFI runtime services cannot preempt voluntarily and because the fpsimd switching code does not rely on the TTBR0_EL1 mappings, simply reorder the fpsimd switch so that it occurs before we change the page-table.

Cc Ard Biesheuvel <[email protected]>
Fixes a5baf582f4c0 ("arm64/efi: Call EFI runtime services without disabling preemption")
---
 arch/arm64/kernel/efi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/kernel/efi.c +2 -2
index 30cd7f804398..0ec90fd1754e 100644
@@ -184,6 +184,8 @@ void arch_efi_call_virt_setup(void)
 		efi_virtmap_load();
 	}
 
+	__efi_fpsimd_begin();
+
 	/*
 	 * Enable access to the valid TTBR0_EL1 and invoke the errata
 	 * workaround directly since there is no return from exception when
@@ -191,8 +193,6 @@ void arch_efi_call_virt_setup(void)
 	 */
 	uaccess_ttbr0_enable();
 	post_ttbr_update_workaround();
-
-	__efi_fpsimd_begin();
 }
 
 void arch_efi_call_virt_teardown(void)
Signature · 1 line
2.55.0.679.g6767b8d81c-goog
maintainer Reviewed-by on v1 1/1
#1 lore raw
Quoted 28 lines · Will Deacon

Gus reports a bad kernel memory access when using software PAN (CONFIG_ARM64_SW_TTBR0_PAN=y) on a machine with support for EFI runtime services:

  Unable to handle kernel access to user memory outside uaccess routines
    at virtual address 00000000f322ff30
  Mem abort info:
    ESR = 0x0000000096000004
    FSC = 0x04: level 0 translation fault
  Internal error: Oops: 0000000096000004 [#1]  SMP
  Workqueue: efi_rts_wq efi_call_rts
  pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
  pc : efi_call_rts+0xd8/0x288
  Call trace:
   efi_call_rts+0xd8/0x288 (P)
   process_one_work+0x178/0x4f8
   worker_thread+0x194/0x328

This is because the fpsimd context management code called from __efi_fpsimd_begin() can preempt voluntarily, returning later to the EFI code with an incorrect value for TTBR0_EL1 thanks to the deferred mm switching used by the software PAN implementation.

Since EFI runtime services cannot preempt voluntarily and because the fpsimd switching code does not rely on the TTBR0_EL1 mappings, simply reorder the fpsimd switch so that it occurs before we change the page-table.

Quoted 8 lines
Cc Ard Biesheuvel <[email protected]>
Fixes a5baf582f4c0 ("arm64/efi: Call EFI runtime services without

disabling preemption")
Link:
https://lore.kernel.org/all/[email protected]/

author maintainer Applied
#2 lore raw
In reply to Will Deacon
Quoted 18 lines · Will Deacon

Gus reports a bad kernel memory access when using software PAN (CONFIG_ARM64_SW_TTBR0_PAN=y) on a machine with support for EFI runtime services:

  Unable to handle kernel access to user memory outside uaccess routines
    at virtual address 00000000f322ff30
  Mem abort info:
    ESR = 0x0000000096000004
    FSC = 0x04: level 0 translation fault
  Internal error: Oops: 0000000096000004 [#1]  SMP
  Workqueue: efi_rts_wq efi_call_rts
  pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
  pc : efi_call_rts+0xd8/0x288
  Call trace:
   efi_call_rts+0xd8/0x288 (P)
   process_one_work+0x178/0x4f8
   worker_thread+0x194/0x328
Quoted 1 line

[...]

Applied to arm64 (for-next/mm), thanks!

[1/1] arm64/efi: Avoid voluntary preemption with efi_mm installed

      https://git.kernel.org/arm64/c/e98a9d014637

Cheers,

Signature · 5 lines
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev