]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
x86/virt/tdx: Clarify try_init_module_global() result caching
authorChao Gao <chao.gao@intel.com>
Wed, 20 May 2026 22:28:46 +0000 (15:28 -0700)
committerDave Hansen <dave.hansen@linux.intel.com>
Wed, 3 Jun 2026 15:14:39 +0000 (08:14 -0700)
TDX module global initialization is executed only once. The first call
caches both the return code and the "done" state in static function
variables.  Later callers read the variables. A lock protects the
saved state and serializes callers.

These variables will soon be moved to a global structure. Prepare for
that by treating the variables as a unit. Assign them together and
limit accesses to while the lock is held.

[ dhansen: mostly rewrite changelog ]

Signed-off-by: Chao Gao <chao.gao@intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Link: https://patch.msgid.link/20260520133909.409394-2-chao.gao@intel.com
arch/x86/virt/vmx/tdx/tdx.c

index c0c6281b08a5e19d88d821373a40d3785028512f..ad56f142dd0bcc425046eb9d7078fef04df408da 100644 (file)
@@ -115,28 +115,34 @@ static int try_init_module_global(void)
        static DEFINE_RAW_SPINLOCK(sysinit_lock);
        static bool sysinit_done;
        static int sysinit_ret;
+       int ret;
 
        raw_spin_lock(&sysinit_lock);
 
-       if (sysinit_done)
+       /* Return the "cached" return code. */
+       if (sysinit_done) {
+               ret = sysinit_ret;
                goto out;
+       }
 
        /* RCX is module attributes and all bits are reserved */
        args.rcx = 0;
-       sysinit_ret = seamcall_prerr(TDH_SYS_INIT, &args);
+       ret = seamcall_prerr(TDH_SYS_INIT, &args);
 
        /*
         * The first SEAMCALL also detects the TDX module, thus
         * it can fail due to the TDX module is not loaded.
         * Dump message to let the user know.
         */
-       if (sysinit_ret == -ENODEV)
+       if (ret == -ENODEV)
                pr_err("module not loaded\n");
 
+       /* Save the return code for later callers. */
        sysinit_done = true;
+       sysinit_ret = ret;
 out:
        raw_spin_unlock(&sysinit_lock);
-       return sysinit_ret;
+       return ret;
 }
 
 /**