[PATCH] efi: pstore: Support late setup with TEE-backed efivars ops

Val Packett posted 1 patch 2 weeks, 6 days ago
drivers/firmware/efi/efi-pstore.c | 32 +++++++++++++++++++++++++++----
1 file changed, 28 insertions(+), 4 deletions(-)
[PATCH] efi: pstore: Support late setup with TEE-backed efivars ops
Posted by Val Packett 2 weeks, 6 days ago
On some platforms, EFI variable services only become available when an
appropriate TEE driver is initialized such as qseecom, gsmi or stmm.

This would work fine when efi_pstore was built as a module and loaded
late by userspace, but with CONFIG_EFI_VARS_PSTORE=y this driver would
quit due to non-writable efivars before the necessary driver had any
chance to load.

Listen to efivar_ops_nh notifications and retry the initialization when
writable EFI variable ops become available.

Signed-off-by: Val Packett <val@packett.cool>
---
 drivers/firmware/efi/efi-pstore.c | 32 +++++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c
index a253b6144945..ad5192d5892e 100644
--- a/drivers/firmware/efi/efi-pstore.c
+++ b/drivers/firmware/efi/efi-pstore.c
@@ -253,14 +253,11 @@ static struct pstore_info efi_pstore_info = {
 	.erase		= efi_pstore_erase,
 };
 
-static int efivars_pstore_init(void)
+static int efivars_pstore_setup(void)
 {
 	if (!efivar_supports_writes())
 		return 0;
 
-	if (pstore_disable)
-		return 0;
-
 	/*
 	 * Notice that 1024 is the minimum here to prevent issues with
 	 * decompression algorithms that were spotted during tests;
@@ -285,8 +282,35 @@ static int efivars_pstore_init(void)
 	return 0;
 }
 
+static int efivars_pstore_ops_notifier(struct notifier_block *nb,
+				 unsigned long event, void *data)
+{
+	if (event == EFIVAR_OPS_RDWR && !efi_pstore_info.bufsize)
+		efivars_pstore_setup();
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block efivars_pstore_ops_notifier_block = {
+	.notifier_call = efivars_pstore_ops_notifier,
+};
+
+static int efivars_pstore_init(void)
+{
+	if (pstore_disable)
+		return 0;
+
+	blocking_notifier_chain_register(&efivar_ops_nh,
+					&efivars_pstore_ops_notifier_block);
+
+	return efivars_pstore_setup();
+}
+
 static void efivars_pstore_exit(void)
 {
+	blocking_notifier_chain_unregister(&efivar_ops_nh,
+					&efivars_pstore_ops_notifier_block);
+
 	if (!efi_pstore_info.bufsize)
 		return;
 
-- 
2.51.0
Re: [PATCH] efi: pstore: Support late setup with TEE-backed efivars ops
Posted by kernel test robot 1 week, 6 days ago

Hello,

kernel test robot noticed "WARNING:at_kernel/locking/rwsem.c:#__down_write_trylock" on:

commit: 6f473fefec79a8ba24013a5676a93934ee5ac922 ("[PATCH] efi: pstore: Support late setup with TEE-backed efivars ops")
url: https://github.com/intel-lab-lkp/linux/commits/Val-Packett/efi-pstore-Support-late-setup-with-TEE-backed-efivars-ops/20251203-123406
base: https://git.kernel.org/cgit/linux/kernel/git/kees/linux.git for-next/pstore
patch link: https://lore.kernel.org/all/20251203042850.14210-1-val@packett.cool/
patch subject: [PATCH] efi: pstore: Support late setup with TEE-backed efivars ops

in testcase: boot

config: i386-randconfig-015-20251207
compiler: clang-20
test machine: qemu-system-i386 -enable-kvm -cpu SandyBridge -smp 2 -m 4G

(please refer to attached dmesg/kmsg for entire log/backtrace)


+---------------------------------------------------------+------------+------------+
|                                                         | b692553573 | 6f473fefec |
+---------------------------------------------------------+------------+------------+
| WARNING:at_kernel/locking/rwsem.c:#__down_write_trylock | 0          | 18         |
| EIP:__down_write_trylock                                | 0          | 18         |
| WARNING:at_kernel/locking/rwsem.c:#up_write             | 0          | 18         |
| EIP:up_write                                            | 0          | 18         |
+---------------------------------------------------------+------------+------------+


If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang@intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202512101632.a94de49b-lkp@intel.com


[    7.731121][    T1] ------------[ cut here ]------------
[    7.731800][    T1] DEBUG_RWSEMS_WARN_ON(sem->magic != sem): count = 0x0, magic = 0x0, owner = 0x0, curr 0xc0288000, list not empty
[    7.733282][    T1] WARNING: CPU: 0 PID: 1 at kernel/locking/rwsem.c:1339 __down_write_trylock (kernel/locking/rwsem.c:1339)
[    7.734420][    T1] Modules linked in:
[    7.734903][    T1] CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.18.0-rc2-00002-g6f473fefec79 #1 PREEMPT(none)
[    7.736185][    T1] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[    7.737529][    T1] EIP: __down_write_trylock (kernel/locking/rwsem.c:1339)
[    7.738173][    T1] Code: c1 92 28 c2 bf 39 3e 26 c2 0f 44 fa 57 50 ff 71 04 56 ff 31 68 dc f4 35 c2 68 fe 5b 35 c2 89 cf e8 81 d1 e8 ff 89 f9 83 c4 1c <0f> 0b 39 ce 0f 85 4b ff ff ff e9 4f ff ff ff 0f 0b eb 8b 90 90 90
All code
========
   0:	c1 92 28 c2 bf 39 3e 	rcll   $0x3e,0x39bfc228(%rdx)
   7:	26 c2 0f 44          	es ret $0x440f
   b:	fa                   	cli
   c:	57                   	push   %rdi
   d:	50                   	push   %rax
   e:	ff 71 04             	push   0x4(%rcx)
  11:	56                   	push   %rsi
  12:	ff 31                	push   (%rcx)
  14:	68 dc f4 35 c2       	push   $0xffffffffc235f4dc
  19:	68 fe 5b 35 c2       	push   $0xffffffffc2355bfe
  1e:	89 cf                	mov    %ecx,%edi
  20:	e8 81 d1 e8 ff       	call   0xffffffffffe8d1a6
  25:	89 f9                	mov    %edi,%ecx
  27:	83 c4 1c             	add    $0x1c,%esp
  2a:*	0f 0b                	ud2		<-- trapping instruction
  2c:	39 ce                	cmp    %ecx,%esi
  2e:	0f 85 4b ff ff ff    	jne    0xffffffffffffff7f
  34:	e9 4f ff ff ff       	jmp    0xffffffffffffff88
  39:	0f 0b                	ud2
  3b:	eb 8b                	jmp    0xffffffffffffffc8
  3d:	90                   	nop
  3e:	90                   	nop
  3f:	90                   	nop

Code starting with the faulting instruction
===========================================
   0:	0f 0b                	ud2
   2:	39 ce                	cmp    %ecx,%esi
   4:	0f 85 4b ff ff ff    	jne    0xffffffffffffff55
   a:	e9 4f ff ff ff       	jmp    0xffffffffffffff5e
   f:	0f 0b                	ud2
  11:	eb 8b                	jmp    0xffffffffffffff9e
  13:	90                   	nop
  14:	90                   	nop
  15:	90                   	nop
[    7.740468][    T1] EAX: 58e1ae7d EBX: c33977c0 ECX: c33977c0 EDX: 00000000
[    7.741422][    T1] ESI: 00000000 EDI: c33977c0 EBP: c0293bf0 ESP: c0293be8
[    7.742277][    T1] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 EFLAGS: 00010296
[    7.743199][    T1] CR0: 80050033 CR2: ffd38000 CR3: 02b87000 CR4: 000406d0
[    7.744043][    T1] Call Trace:
[    7.744429][    T1]  ? blocking_notifier_chain_register (kernel/notifier.c:264)
[    7.745251][    T1]  down_write (kernel/locking/rwsem.c:1591)
[    7.745755][    T1]  blocking_notifier_chain_register (kernel/notifier.c:264)
[    7.746473][    T1]  efivars_pstore_init (drivers/firmware/efi/efi-pstore.c:258 drivers/firmware/efi/efi-pstore.c:306)
[    7.747059][    T1]  do_one_initcall (init/main.c:1283)
[    7.747623][    T1]  ? last_attempt_status_show (drivers/firmware/efi/efi-pstore.c:299)
[    7.748291][    T1]  ? local_clock (arch/x86/include/asm/preempt.h:95 kernel/sched/clock.c:319)
[    7.748949][    T1]  ? kvm_sched_clock_read (arch/x86/kernel/kvmclock.c:91)
[    7.749590][    T1]  ? kvm_sched_clock_read (arch/x86/kernel/kvmclock.c:91)
[    7.750218][    T1]  ? sched_clock_noinstr (arch/x86/kernel/tsc.c:271)
[    7.750828][    T1]  ? local_clock_noinstr (kernel/sched/clock.c:272 kernel/sched/clock.c:309)
[    7.751477][    T1]  ? local_clock (arch/x86/include/asm/preempt.h:95 kernel/sched/clock.c:319)
[    7.752042][    T1]  ? ktime_get (include/linux/seqlock.h:226)
[    7.752565][    T1]  ? kvm_clock_get_cycles (arch/x86/include/asm/preempt.h:95 arch/x86/kernel/kvmclock.c:80 arch/x86/kernel/kvmclock.c:86)
[    7.753268][    T1]  ? ktime_get (kernel/time/timekeeping.c:295 kernel/time/timekeeping.c:404 kernel/time/timekeeping.c:826)
[    7.753775][    T1]  ? local_clock_noinstr (kernel/sched/clock.c:272 kernel/sched/clock.c:309)
[    7.754393][    T1]  ? clockevents_program_event (kernel/time/clockevents.c:336)
[    7.755098][    T1]  ? tick_program_event (kernel/time/tick-oneshot.c:44)
[    7.755720][    T1]  ? hrtimer_interrupt (kernel/time/hrtimer.c:1916)
[    7.756331][    T1]  ? irqentry_exit (kernel/entry/common.c:?)
[    7.756993][    T1]  ? sysvec_apic_timer_interrupt (arch/x86/kernel/apic/apic.c:1052)
[    7.757704][    T1]  ? trace_hardirqs_on (kernel/trace/trace_preemptirq.c:80)
[    7.758306][    T1]  ? irqentry_exit (kernel/entry/common.c:?)
[    7.758860][    T1]  ? sysvec_call_function_single (arch/x86/kernel/apic/apic.c:1052)
[    7.759562][    T1]  ? sysvec_apic_timer_interrupt (arch/x86/kernel/apic/apic.c:1052)
[    7.760261][    T1]  ? handle_exception (arch/x86/entry/entry_32.S:1048)
[    7.760967][    T1]  ? __get_immptr (arch/x86/lib/insn.c:632)
[    7.761517][    T1]  ? parameq (kernel/params.c:81 kernel/params.c:91 kernel/params.c:99)
[    7.762011][    T1]  ? __get_immptr (arch/x86/lib/insn.c:632)
[    7.762540][    T1]  ? next_arg (lib/cmdline.c:273)
[    7.763050][    T1]  ? parameq (kernel/params.c:90 kernel/params.c:99)
[    7.763551][    T1]  ? parse_args (kernel/params.c:153)
[    7.764127][    T1]  do_initcall_level (init/main.c:1344)
[    7.764819][    T1]  do_initcalls (init/main.c:1358)
[    7.765347][    T1]  ? kernel_init (init/main.c:1485)
[    7.765895][    T1]  do_basic_setup (init/main.c:1381)
[    7.766432][    T1]  kernel_init_freeable (init/main.c:1597)
[    7.767049][    T1]  ? rest_init (init/main.c:1475)
[    7.767587][    T1]  ? rest_init (init/main.c:1475)
[    7.768125][    T1]  kernel_init (init/main.c:1485)
[    7.768686][    T1]  ret_from_fork (arch/x86/kernel/process.c:164)
[    7.769276][    T1]  ? __switch_to_asm (arch/x86/entry/entry_32.S:704)
[    7.769852][    T1]  ? __switch_to_asm (arch/x86/entry/entry_32.S:704)
[    7.770427][    T1]  ? __switch_to_asm (arch/x86/entry/entry_32.S:704)
[    7.771001][    T1]  ? rest_init (init/main.c:1475)
[    7.771535][    T1]  ret_from_fork_asm (arch/x86/entry/entry_32.S:737)
[    7.771957][    T1]  entry_INT80_32 (arch/x86/entry/entry_32.S:945)
[    7.772338][    T1] irq event stamp: 108765
[    7.772712][    T1] hardirqs last  enabled at (108773): __console_unlock (arch/x86/include/asm/irqflags.h:19 arch/x86/include/asm/irqflags.h:109 arch/x86/include/asm/irqflags.h:151 kernel/printk/printk.c:345 kernel/printk/printk.c:2858)
[    7.773432][    T1] hardirqs last disabled at (108782): __console_unlock (kernel/printk/printk.c:343)
[    7.774123][    T1] softirqs last  enabled at (108714): __do_softirq (kernel/softirq.c:657)
[    7.774782][    T1] softirqs last disabled at (108699): __do_softirq (kernel/softirq.c:657)
[    7.775441][    T1] ---[ end trace 0000000000000000 ]---


The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20251210/202512101632.a94de49b-lkp@intel.com



-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH] efi: pstore: Support late setup with TEE-backed efivars ops
Posted by Ard Biesheuvel 1 week, 6 days ago
On Wed, 10 Dec 2025 at 17:41, kernel test robot <oliver.sang@intel.com> wrote:
>
>
>
> Hello,
>
> kernel test robot noticed "WARNING:at_kernel/locking/rwsem.c:#__down_write_trylock" on:
>
> commit: 6f473fefec79a8ba24013a5676a93934ee5ac922 ("[PATCH] efi: pstore: Support late setup with TEE-backed efivars ops")
> url: https://github.com/intel-lab-lkp/linux/commits/Val-Packett/efi-pstore-Support-late-setup-with-TEE-backed-efivars-ops/20251203-123406
> base: https://git.kernel.org/cgit/linux/kernel/git/kees/linux.git for-next/pstore
> patch link: https://lore.kernel.org/all/20251203042850.14210-1-val@packett.cool/
> patch subject: [PATCH] efi: pstore: Support late setup with TEE-backed efivars ops
>
> in testcase: boot
>
> config: i386-randconfig-015-20251207
> compiler: clang-20
> test machine: qemu-system-i386 -enable-kvm -cpu SandyBridge -smp 2 -m 4G
>
> (please refer to attached dmesg/kmsg for entire log/backtrace)
>
>
> +---------------------------------------------------------+------------+------------+
> |                                                         | b692553573 | 6f473fefec |
> +---------------------------------------------------------+------------+------------+
> | WARNING:at_kernel/locking/rwsem.c:#__down_write_trylock | 0          | 18         |
> | EIP:__down_write_trylock                                | 0          | 18         |
> | WARNING:at_kernel/locking/rwsem.c:#up_write             | 0          | 18         |
> | EIP:up_write                                            | 0          | 18         |
> +---------------------------------------------------------+------------+------------+
>

This seems to be a non-EFI boot, in which case the notifier chain is
never initialized.

Kees, can you drop this from your branch so we can get it fixed? I
also had some review feedback that hasn't been taken into account yet.



>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <oliver.sang@intel.com>
> | Closes: https://lore.kernel.org/oe-lkp/202512101632.a94de49b-lkp@intel.com
>
>
> [    7.731121][    T1] ------------[ cut here ]------------
> [    7.731800][    T1] DEBUG_RWSEMS_WARN_ON(sem->magic != sem): count = 0x0, magic = 0x0, owner = 0x0, curr 0xc0288000, list not empty
> [    7.733282][    T1] WARNING: CPU: 0 PID: 1 at kernel/locking/rwsem.c:1339 __down_write_trylock (kernel/locking/rwsem.c:1339)
> [    7.734420][    T1] Modules linked in:
> [    7.734903][    T1] CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.18.0-rc2-00002-g6f473fefec79 #1 PREEMPT(none)
> [    7.736185][    T1] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
> [    7.737529][    T1] EIP: __down_write_trylock (kernel/locking/rwsem.c:1339)
> [    7.738173][    T1] Code: c1 92 28 c2 bf 39 3e 26 c2 0f 44 fa 57 50 ff 71 04 56 ff 31 68 dc f4 35 c2 68 fe 5b 35 c2 89 cf e8 81 d1 e8 ff 89 f9 83 c4 1c <0f> 0b 39 ce 0f 85 4b ff ff ff e9 4f ff ff ff 0f 0b eb 8b 90 90 90
> All code
> ========
>    0:   c1 92 28 c2 bf 39 3e    rcll   $0x3e,0x39bfc228(%rdx)
>    7:   26 c2 0f 44             es ret $0x440f
>    b:   fa                      cli
>    c:   57                      push   %rdi
>    d:   50                      push   %rax
>    e:   ff 71 04                push   0x4(%rcx)
>   11:   56                      push   %rsi
>   12:   ff 31                   push   (%rcx)
>   14:   68 dc f4 35 c2          push   $0xffffffffc235f4dc
>   19:   68 fe 5b 35 c2          push   $0xffffffffc2355bfe
>   1e:   89 cf                   mov    %ecx,%edi
>   20:   e8 81 d1 e8 ff          call   0xffffffffffe8d1a6
>   25:   89 f9                   mov    %edi,%ecx
>   27:   83 c4 1c                add    $0x1c,%esp
>   2a:*  0f 0b                   ud2             <-- trapping instruction
>   2c:   39 ce                   cmp    %ecx,%esi
>   2e:   0f 85 4b ff ff ff       jne    0xffffffffffffff7f
>   34:   e9 4f ff ff ff          jmp    0xffffffffffffff88
>   39:   0f 0b                   ud2
>   3b:   eb 8b                   jmp    0xffffffffffffffc8
>   3d:   90                      nop
>   3e:   90                      nop
>   3f:   90                      nop
>
> Code starting with the faulting instruction
> ===========================================
>    0:   0f 0b                   ud2
>    2:   39 ce                   cmp    %ecx,%esi
>    4:   0f 85 4b ff ff ff       jne    0xffffffffffffff55
>    a:   e9 4f ff ff ff          jmp    0xffffffffffffff5e
>    f:   0f 0b                   ud2
>   11:   eb 8b                   jmp    0xffffffffffffff9e
>   13:   90                      nop
>   14:   90                      nop
>   15:   90                      nop
> [    7.740468][    T1] EAX: 58e1ae7d EBX: c33977c0 ECX: c33977c0 EDX: 00000000
> [    7.741422][    T1] ESI: 00000000 EDI: c33977c0 EBP: c0293bf0 ESP: c0293be8
> [    7.742277][    T1] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 EFLAGS: 00010296
> [    7.743199][    T1] CR0: 80050033 CR2: ffd38000 CR3: 02b87000 CR4: 000406d0
> [    7.744043][    T1] Call Trace:
> [    7.744429][    T1]  ? blocking_notifier_chain_register (kernel/notifier.c:264)
> [    7.745251][    T1]  down_write (kernel/locking/rwsem.c:1591)
> [    7.745755][    T1]  blocking_notifier_chain_register (kernel/notifier.c:264)
> [    7.746473][    T1]  efivars_pstore_init (drivers/firmware/efi/efi-pstore.c:258 drivers/firmware/efi/efi-pstore.c:306)
> [    7.747059][    T1]  do_one_initcall (init/main.c:1283)
> [    7.747623][    T1]  ? last_attempt_status_show (drivers/firmware/efi/efi-pstore.c:299)
> [    7.748291][    T1]  ? local_clock (arch/x86/include/asm/preempt.h:95 kernel/sched/clock.c:319)
> [    7.748949][    T1]  ? kvm_sched_clock_read (arch/x86/kernel/kvmclock.c:91)
> [    7.749590][    T1]  ? kvm_sched_clock_read (arch/x86/kernel/kvmclock.c:91)
> [    7.750218][    T1]  ? sched_clock_noinstr (arch/x86/kernel/tsc.c:271)
> [    7.750828][    T1]  ? local_clock_noinstr (kernel/sched/clock.c:272 kernel/sched/clock.c:309)
> [    7.751477][    T1]  ? local_clock (arch/x86/include/asm/preempt.h:95 kernel/sched/clock.c:319)
> [    7.752042][    T1]  ? ktime_get (include/linux/seqlock.h:226)
> [    7.752565][    T1]  ? kvm_clock_get_cycles (arch/x86/include/asm/preempt.h:95 arch/x86/kernel/kvmclock.c:80 arch/x86/kernel/kvmclock.c:86)
> [    7.753268][    T1]  ? ktime_get (kernel/time/timekeeping.c:295 kernel/time/timekeeping.c:404 kernel/time/timekeeping.c:826)
> [    7.753775][    T1]  ? local_clock_noinstr (kernel/sched/clock.c:272 kernel/sched/clock.c:309)
> [    7.754393][    T1]  ? clockevents_program_event (kernel/time/clockevents.c:336)
> [    7.755098][    T1]  ? tick_program_event (kernel/time/tick-oneshot.c:44)
> [    7.755720][    T1]  ? hrtimer_interrupt (kernel/time/hrtimer.c:1916)
> [    7.756331][    T1]  ? irqentry_exit (kernel/entry/common.c:?)
> [    7.756993][    T1]  ? sysvec_apic_timer_interrupt (arch/x86/kernel/apic/apic.c:1052)
> [    7.757704][    T1]  ? trace_hardirqs_on (kernel/trace/trace_preemptirq.c:80)
> [    7.758306][    T1]  ? irqentry_exit (kernel/entry/common.c:?)
> [    7.758860][    T1]  ? sysvec_call_function_single (arch/x86/kernel/apic/apic.c:1052)
> [    7.759562][    T1]  ? sysvec_apic_timer_interrupt (arch/x86/kernel/apic/apic.c:1052)
> [    7.760261][    T1]  ? handle_exception (arch/x86/entry/entry_32.S:1048)
> [    7.760967][    T1]  ? __get_immptr (arch/x86/lib/insn.c:632)
> [    7.761517][    T1]  ? parameq (kernel/params.c:81 kernel/params.c:91 kernel/params.c:99)
> [    7.762011][    T1]  ? __get_immptr (arch/x86/lib/insn.c:632)
> [    7.762540][    T1]  ? next_arg (lib/cmdline.c:273)
> [    7.763050][    T1]  ? parameq (kernel/params.c:90 kernel/params.c:99)
> [    7.763551][    T1]  ? parse_args (kernel/params.c:153)
> [    7.764127][    T1]  do_initcall_level (init/main.c:1344)
> [    7.764819][    T1]  do_initcalls (init/main.c:1358)
> [    7.765347][    T1]  ? kernel_init (init/main.c:1485)
> [    7.765895][    T1]  do_basic_setup (init/main.c:1381)
> [    7.766432][    T1]  kernel_init_freeable (init/main.c:1597)
> [    7.767049][    T1]  ? rest_init (init/main.c:1475)
> [    7.767587][    T1]  ? rest_init (init/main.c:1475)
> [    7.768125][    T1]  kernel_init (init/main.c:1485)
> [    7.768686][    T1]  ret_from_fork (arch/x86/kernel/process.c:164)
> [    7.769276][    T1]  ? __switch_to_asm (arch/x86/entry/entry_32.S:704)
> [    7.769852][    T1]  ? __switch_to_asm (arch/x86/entry/entry_32.S:704)
> [    7.770427][    T1]  ? __switch_to_asm (arch/x86/entry/entry_32.S:704)
> [    7.771001][    T1]  ? rest_init (init/main.c:1475)
> [    7.771535][    T1]  ret_from_fork_asm (arch/x86/entry/entry_32.S:737)
> [    7.771957][    T1]  entry_INT80_32 (arch/x86/entry/entry_32.S:945)
> [    7.772338][    T1] irq event stamp: 108765
> [    7.772712][    T1] hardirqs last  enabled at (108773): __console_unlock (arch/x86/include/asm/irqflags.h:19 arch/x86/include/asm/irqflags.h:109 arch/x86/include/asm/irqflags.h:151 kernel/printk/printk.c:345 kernel/printk/printk.c:2858)
> [    7.773432][    T1] hardirqs last disabled at (108782): __console_unlock (kernel/printk/printk.c:343)
> [    7.774123][    T1] softirqs last  enabled at (108714): __do_softirq (kernel/softirq.c:657)
> [    7.774782][    T1] softirqs last disabled at (108699): __do_softirq (kernel/softirq.c:657)
> [    7.775441][    T1] ---[ end trace 0000000000000000 ]---
>
>
> The kernel config and materials to reproduce are available at:
> https://download.01.org/0day-ci/archive/20251210/202512101632.a94de49b-lkp@intel.com
>
>
>
> --
> 0-DAY CI Kernel Test Service
> https://github.com/intel/lkp-tests/wiki
>
Re: [PATCH] efi: pstore: Support late setup with TEE-backed efivars ops
Posted by Kees Cook 1 week, 5 days ago
On Wed, Dec 10, 2025 at 06:13:17PM +0900, Ard Biesheuvel wrote:
> On Wed, 10 Dec 2025 at 17:41, kernel test robot <oliver.sang@intel.com> wrote:
> >
> >
> >
> > Hello,
> >
> > kernel test robot noticed "WARNING:at_kernel/locking/rwsem.c:#__down_write_trylock" on:
> >
> > commit: 6f473fefec79a8ba24013a5676a93934ee5ac922 ("[PATCH] efi: pstore: Support late setup with TEE-backed efivars ops")
> > url: https://github.com/intel-lab-lkp/linux/commits/Val-Packett/efi-pstore-Support-late-setup-with-TEE-backed-efivars-ops/20251203-123406
> > base: https://git.kernel.org/cgit/linux/kernel/git/kees/linux.git for-next/pstore
> > patch link: https://lore.kernel.org/all/20251203042850.14210-1-val@packett.cool/
> > patch subject: [PATCH] efi: pstore: Support late setup with TEE-backed efivars ops
> >
> > in testcase: boot
> >
> > config: i386-randconfig-015-20251207
> > compiler: clang-20
> > test machine: qemu-system-i386 -enable-kvm -cpu SandyBridge -smp 2 -m 4G
> >
> > (please refer to attached dmesg/kmsg for entire log/backtrace)
> >
> >
> > +---------------------------------------------------------+------------+------------+
> > |                                                         | b692553573 | 6f473fefec |
> > +---------------------------------------------------------+------------+------------+
> > | WARNING:at_kernel/locking/rwsem.c:#__down_write_trylock | 0          | 18         |
> > | EIP:__down_write_trylock                                | 0          | 18         |
> > | WARNING:at_kernel/locking/rwsem.c:#up_write             | 0          | 18         |
> > | EIP:up_write                                            | 0          | 18         |
> > +---------------------------------------------------------+------------+------------+
> >
> 
> This seems to be a non-EFI boot, in which case the notifier chain is
> never initialized.
> 
> Kees, can you drop this from your branch so we can get it fixed? I
> also had some review feedback that hasn't been taken into account yet.

I didn't take it -- this appears to be patch-based 0day randconfig. (I'd
rather it went via EFI anyway, too.)

-Kees

-- 
Kees Cook
Re: [PATCH] efi: pstore: Support late setup with TEE-backed efivars ops
Posted by Kees Cook 2 weeks, 4 days ago
On Wed, Dec 03, 2025 at 01:28:29AM -0300, Val Packett wrote:
> On some platforms, EFI variable services only become available when an
> appropriate TEE driver is initialized such as qseecom, gsmi or stmm.
> 
> This would work fine when efi_pstore was built as a module and loaded
> late by userspace, but with CONFIG_EFI_VARS_PSTORE=y this driver would
> quit due to non-writable efivars before the necessary driver had any
> chance to load.
> 
> Listen to efivar_ops_nh notifications and retry the initialization when
> writable EFI variable ops become available.
> 
> Signed-off-by: Val Packett <val@packett.cool>

This seems fine to me, though I defer to Ard, who knows the EFI bits way
better than I do. :)

Acked-by: Kees Cook <kees@kernel.org>

-- 
Kees Cook
Re: [PATCH] efi: pstore: Support late setup with TEE-backed efivars ops
Posted by Ilias Apalodimas 2 weeks, 5 days ago
Hi Val,

On Wed, 3 Dec 2025 at 06:29, Val Packett <val@packett.cool> wrote:
>
> On some platforms, EFI variable services only become available when an
> appropriate TEE driver is initialized such as qseecom, gsmi or stmm.
>
> This would work fine when efi_pstore was built as a module and loaded
> late by userspace, but with CONFIG_EFI_VARS_PSTORE=y this driver would
> quit due to non-writable efivars before the necessary driver had any
> chance to load.

The problem, at least for OP-TEE/StMM, is that writing the variables
to an RPMB depends on a userspace application If CONFIG_RPMB is not
selected. We have no guarantees that the app will still be alive.
I don't know how gsmi or qseecom deal with writing variables. We can
probably allow it for StMM if CONFIG_RPMB is enabled, but we'll have
the right trigger to do so.

>
> Listen to efivar_ops_nh notifications and retry the initialization when
> writable EFI variable ops become available.
>
> Signed-off-by: Val Packett <val@packett.cool>

Thanks
/Ilias
> ---
>  drivers/firmware/efi/efi-pstore.c | 32 +++++++++++++++++++++++++++----
>  1 file changed, 28 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c
> index a253b6144945..ad5192d5892e 100644
> --- a/drivers/firmware/efi/efi-pstore.c
> +++ b/drivers/firmware/efi/efi-pstore.c
> @@ -253,14 +253,11 @@ static struct pstore_info efi_pstore_info = {
>         .erase          = efi_pstore_erase,
>  };
>
> -static int efivars_pstore_init(void)
> +static int efivars_pstore_setup(void)
>  {
>         if (!efivar_supports_writes())
>                 return 0;
>
> -       if (pstore_disable)
> -               return 0;
> -
>         /*
>          * Notice that 1024 is the minimum here to prevent issues with
>          * decompression algorithms that were spotted during tests;
> @@ -285,8 +282,35 @@ static int efivars_pstore_init(void)
>         return 0;
>  }
>
> +static int efivars_pstore_ops_notifier(struct notifier_block *nb,
> +                                unsigned long event, void *data)
> +{
> +       if (event == EFIVAR_OPS_RDWR && !efi_pstore_info.bufsize)
> +               efivars_pstore_setup();
> +
> +       return NOTIFY_OK;
> +}
> +
> +static struct notifier_block efivars_pstore_ops_notifier_block = {
> +       .notifier_call = efivars_pstore_ops_notifier,
> +};
> +
> +static int efivars_pstore_init(void)
> +{
> +       if (pstore_disable)
> +               return 0;
> +
> +       blocking_notifier_chain_register(&efivar_ops_nh,
> +                                       &efivars_pstore_ops_notifier_block);
> +
> +       return efivars_pstore_setup();
> +}
> +
>  static void efivars_pstore_exit(void)
>  {
> +       blocking_notifier_chain_unregister(&efivar_ops_nh,
> +                                       &efivars_pstore_ops_notifier_block);
> +
>         if (!efi_pstore_info.bufsize)
>                 return;
>
> --
> 2.51.0
>
>
Re: [PATCH] efi: pstore: Support late setup with TEE-backed efivars ops
Posted by Val Packett 2 weeks, 4 days ago
On 12/4/25 6:49 AM, Ilias Apalodimas wrote:
> Hi Val,
>
> On Wed, 3 Dec 2025 at 06:29, Val Packett <val@packett.cool> wrote:
>> On some platforms, EFI variable services only become available when an
>> appropriate TEE driver is initialized such as qseecom, gsmi or stmm.
>>
>> This would work fine when efi_pstore was built as a module and loaded
>> late by userspace, but with CONFIG_EFI_VARS_PSTORE=y this driver would
>> quit due to non-writable efivars before the necessary driver had any
>> chance to load.
> The problem, at least for OP-TEE/StMM, is that writing the variables
> to an RPMB depends on a userspace application If CONFIG_RPMB is not
> selected. We have no guarantees that the app will still be alive.
> I don't know how gsmi or qseecom deal with writing variables. We can
> probably allow it for StMM if CONFIG_RPMB is enabled, but we'll have
> the right trigger to do so.

qseecom/uefisecapp does not have any userspace requirements and works 
fine with efi_pstore.

I don't think complicating efi_pstore with extra logic about which ops 
are fine would be worth it..

Either way, it currently *already* tries to use whatever ops that have 
been registered if it's loaded late as a module by systemd! The only 
thing this patch changes is the CONFIG_EFI_VARS_PSTORE=y case.


Thanks,
~val
Re: [PATCH] efi: pstore: Support late setup with TEE-backed efivars ops
Posted by Ard Biesheuvel 2 weeks, 3 days ago
On Thu, 4 Dec 2025 at 21:57, Val Packett <val@packett.cool> wrote:
>
>
> On 12/4/25 6:49 AM, Ilias Apalodimas wrote:
> > Hi Val,
> >
> > On Wed, 3 Dec 2025 at 06:29, Val Packett <val@packett.cool> wrote:
> >> On some platforms, EFI variable services only become available when an
> >> appropriate TEE driver is initialized such as qseecom, gsmi or stmm.
> >>
> >> This would work fine when efi_pstore was built as a module and loaded
> >> late by userspace, but with CONFIG_EFI_VARS_PSTORE=y this driver would
> >> quit due to non-writable efivars before the necessary driver had any
> >> chance to load.
> > The problem, at least for OP-TEE/StMM, is that writing the variables
> > to an RPMB depends on a userspace application If CONFIG_RPMB is not
> > selected. We have no guarantees that the app will still be alive.
> > I don't know how gsmi or qseecom deal with writing variables. We can
> > probably allow it for StMM if CONFIG_RPMB is enabled, but we'll have
> > the right trigger to do so.
>
> qseecom/uefisecapp does not have any userspace requirements and works
> fine with efi_pstore.
>
> I don't think complicating efi_pstore with extra logic about which ops
> are fine would be worth it..
>
> Either way, it currently *already* tries to use whatever ops that have
> been registered if it's loaded late as a module by systemd! The only
> thing this patch changes is the CONFIG_EFI_VARS_PSTORE=y case.
>

OP-TEE/StMM's implementation of tee_set_variable_nonblocking() just
returns EFI_UNSUPPORTED, and so in practice, EFI pstore doesn't work
at all there. I think this is fine, although it would be better to be
upfront about this, and not expose the pstore FS at all in this case.
And once we can provide an implementation (based on CONFIG_RPMB), it
would be good to wire that up correctly as well.

> +static int efivars_pstore_init(void)
> +{
> +       if (pstore_disable)
> +               return 0;
> +
> +       blocking_notifier_chain_register(&efivar_ops_nh,
> +                                       &efivars_pstore_ops_notifier_block);
> +
> +       return efivars_pstore_setup();
> +}
> +

Better to do the registration last, so there is no way
efivars_pstore_setup() might ever race with itself.
Re: [PATCH] efi: pstore: Support late setup with TEE-backed efivars ops
Posted by Ilias Apalodimas 2 weeks, 3 days ago
On Fri, 5 Dec 2025 at 12:27, Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Thu, 4 Dec 2025 at 21:57, Val Packett <val@packett.cool> wrote:
> >
> >
> > On 12/4/25 6:49 AM, Ilias Apalodimas wrote:
> > > Hi Val,
> > >
> > > On Wed, 3 Dec 2025 at 06:29, Val Packett <val@packett.cool> wrote:
> > >> On some platforms, EFI variable services only become available when an
> > >> appropriate TEE driver is initialized such as qseecom, gsmi or stmm.
> > >>
> > >> This would work fine when efi_pstore was built as a module and loaded
> > >> late by userspace, but with CONFIG_EFI_VARS_PSTORE=y this driver would
> > >> quit due to non-writable efivars before the necessary driver had any
> > >> chance to load.
> > > The problem, at least for OP-TEE/StMM, is that writing the variables
> > > to an RPMB depends on a userspace application If CONFIG_RPMB is not
> > > selected. We have no guarantees that the app will still be alive.
> > > I don't know how gsmi or qseecom deal with writing variables. We can
> > > probably allow it for StMM if CONFIG_RPMB is enabled, but we'll have
> > > the right trigger to do so.
> >
> > qseecom/uefisecapp does not have any userspace requirements and works
> > fine with efi_pstore.
> >
> > I don't think complicating efi_pstore with extra logic about which ops
> > are fine would be worth it..
> >
> > Either way, it currently *already* tries to use whatever ops that have
> > been registered if it's loaded late as a module by systemd! The only
> > thing this patch changes is the CONFIG_EFI_VARS_PSTORE=y case.
> >
>
> OP-TEE/StMM's implementation of tee_set_variable_nonblocking() just
> returns EFI_UNSUPPORTED,

Yes that's a limitation imposed by Arm MM iirc.

> and so in practice, EFI pstore doesn't work at all there.

Exactly. It's been a while, but I vaguely remember that in v1 we had
pstore explicitly disabled from the Kconfig. But distros tend to use
it, so we ended up doing it like this, so they can enable the feature.

> I think this is fine, although it would be better to be
> upfront about this, and not expose the pstore FS at all in this case.
> And once we can provide an implementation (based on CONFIG_RPMB), it
> would be good to wire that up correctly as well.

I'll see if i can find hardware and time to test it. In theory we
should be find if the writes are wired up via the kernel and not
userspace.
If they are we can just define tee_set_variable_nonblocking() to a
working function if that Kconfig is selected.


Cheers
/Ilias
>
> > +static int efivars_pstore_init(void)
> > +{
> > +       if (pstore_disable)
> > +               return 0;
> > +
> > +       blocking_notifier_chain_register(&efivar_ops_nh,
> > +                                       &efivars_pstore_ops_notifier_block);
> > +
> > +       return efivars_pstore_setup();
> > +}
> > +
>
> Better to do the registration last, so there is no way
> efivars_pstore_setup() might ever race with itself.