From nobody Mon Jun 8 06:36:55 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 675BF34A799; Fri, 5 Jun 2026 21:25:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780694709; cv=none; b=KLRZ8MqlTm4uDZ/LzxSfITqVDDY28/Hh2KvU8D3kAf3EdNpHHBB7tjMlnaX+v9XDAcZnT6dJRR/kEk4NK3cZ+iCZzMRRiKKS+J1hbaNS3/q7XWFqy+6KyVQdoMcALP/ZVosjB9ZUilyVPQ65iIRSLIvnxRug7LMNgIRQJLLwE0w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780694709; c=relaxed/simple; bh=B7+D8sRV1XVnwTrH2dj/uTnM61Ak5BL0CrgVaU3Jo8U=; h=Date:From:To:Subject:Cc:MIME-Version:Message-ID:Content-Type; b=G9tqfxerQhf6fjzcNzHDP5Jzbdpp07aX8NfP+WApwOyg8fgosX/sfKni1m76YLHQJNTF5ywcptPuIet85vJxHdUo1ep+iFpokDm6yO/UhXDUw5naE0iVCBNSGmKiR+eaWSdygR8EQYfSb+5OeNcnU/fY8TiNvbvMgqrPH6hBenE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=SR2yVPIf; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Bs9cN30u; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="SR2yVPIf"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Bs9cN30u" Date: Fri, 05 Jun 2026 21:25:04 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1780694706; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=qtUhMBhz2w/CMVqD4zlrAllJsDBq9c/C/qjEjMOyZ3Y=; b=SR2yVPIfyqozYe9YUnM8I37SgSV/ity8Xc1dZYT0JClk/MfIrthD3TV6vAW0XTg+F13h8Y hV8OUV9F7+TycEpx1TKmA5lhBLXnk8A4Ztbg2e8lQ13Ua5wwHee2oV/1J0NK1mFjZzdL/D ct/Y1eE6a2JkBT10KiocrrzOVRMvLlxrfM/S1kPLfE6dpXBmdkLK/UbkyDIQ/ewaGUoGii BohQgUiP+KhA8vSEHQtdBmKQ5FdLumbmdxRzvzgxyrhrXhGy49S3wHs6ZkMJ5uLyBSO3gk 5rkqIJ1bkO7xIqmOtB86Xl97X4gWqLWFhIw3yXuw2HPr44WSXZIX1vi5sALbaA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1780694706; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=qtUhMBhz2w/CMVqD4zlrAllJsDBq9c/C/qjEjMOyZ3Y=; b=Bs9cN30ufS2zt7kfdfGKOcZBI5v4+oQL+7E0ohq0l4hP+Qsa5zd74Ll/jB0alrl2OtzFrI yAV1OO/CRvwVqjCg== From: "tip-bot2 for Chao Gao" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: x86/tdx] x86/virt/tdx: Document TDX module update Cc: Chao Gao , Rick Edgecombe , Dave Hansen , x86@kernel.org, linux-kernel@vger.kernel.org Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <178069470449.710.5215196676470813783.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Precedence: bulk Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The following commit has been merged into the x86/tdx branch of tip: Commit-ID: 2b9ad7a6154e0938b9458691536296dd0224942d Gitweb: https://git.kernel.org/tip/2b9ad7a6154e0938b9458691536296dd0= 224942d Author: Chao Gao AuthorDate: Fri, 22 May 2026 14:41:25 -07:00 Committer: Dave Hansen CommitterDate: Fri, 05 Jun 2026 14:18:37 -07:00 x86/virt/tdx: Document TDX module update Recent changes introduced TDX module update support. This is a thorny feature to use correctly. It is intended for informed admins only who are expected to either be doing things very carefully, or using it via userspace programs that handle the pitfalls for them. Document the basics of how to use the feature and what is expected of the user in order for it to go correctly. Both to help the intended users of the feature and as a "here be dragons" note for the more casual TDX users. [ dhansen: tweak docs a bit, clarify update constraints ] Signed-off-by: Chao Gao [dropped "Implementation details" section, update log] Signed-off-by: Rick Edgecombe Signed-off-by: Dave Hansen --- Documentation/arch/x86/tdx.rst | 127 ++++++++++++++++++++++++++++++++- 1 file changed, 127 insertions(+) diff --git a/Documentation/arch/x86/tdx.rst b/Documentation/arch/x86/tdx.rst index 1a3b5ba..3303499 100644 --- a/Documentation/arch/x86/tdx.rst +++ b/Documentation/arch/x86/tdx.rst @@ -73,6 +73,133 @@ initialize:: =20 [..] virt/tdx: TDX-Module initialization failed ... =20 +TDX module Runtime Update +------------------------- + +Similar to microcode, the BIOS generally has a copy of the TDX module +in flash. It loads this module image in to RAM at boot. However, just +like microcode, the BIOS-loaded TDX module might be out of date either +because the BIOS is old or the system has been up a long time. The +kernel can replace the BIOS version in RAM and load a different TDX +module. Kernel-loaded TDX modules do not affect the BIOS flash and do +not survive reboots. + +The TDX module is normally the only piece of software running in SEAM +mode with which the kernel interacts. But there is a second piece of +software which is used to load or update the TDX module: a persistent +SEAM loader (P-SEAMLDR). It runs in SEAM mode separately from the TDX +module. The kernel communicates with the P-SEAMLDR to perform TDX +module runtime updates. + +How to update the TDX module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Updating the TDX module is a complex process. Much of the logic and +policy is left to userspace. End users should use existing update +infrastructure provided by their distro. The Intel TDX Module Binaries +repository has a reference implementation of this logic: + + https://github.com/intel/confidential-computing.tdx.tdx-module.binaries= /blob/main/version_select_and_load.py + +This section will now lay out roughly what is needed to implement a +userspace-driven TDX module update. Detailed documentation on the +tdx_host ABIs is available here:: + + Documentation/ABI/testing/sysfs-devices-faux-tdx-host + +and is not duplicated in this document. + +1. Check whether runtime update is supported at all + + Verify that the TDX module firmware upload interface is available:: + + /sys/class/firmware/tdx_module + + Note that this is the generic kernel firmware update ABI. It is + separate from the "tdx_host" device ABI itself. + +2. Check whether additional updates are possible. Verify that:: + + /sys/devices/faux/tdx_host/num_remaining_updates + + has a value greater than 0. If it is 0, the TDX update log might be + full. Reboot to reset this to a nonzero value. + +3. Choose a compatible TDX module image + + Choosing a compatible TDX module image is not trivial. There are both + hard compatibility requirements and policy choices to make. + + Hard compatibility requirements: + + - The update must be compatible with the kernel. + + The update must not change any TDX ABIs in any non-backward-compatible + way. It can introduce new features but must not require that the kern= el + use new ABIs for existing features. It must ensure that the rest of t= he + system is not affected in any way. Software on the system must never + notice any behavioral changes. Attestation results should be identical + except for version changes. + + - The update must be compatible with the CPU. + + The set of supported CPU FMS values (family, model, stepping) is + encoded in the module image itself. In practice, module version series + are platform-specific. For example, the 1.5.x series runs on Sapphire + Rapids but not Granite Rapids, which needs 2.0.x. + + - The update must be compatible with the P-SEAMLDR. + + This information is provided in a metadata file, typically + mapping_file.json, released with the module image. Each module image + specifies the minimum required P-SEAMLDR version, and the update is + compatible only if the running P-SEAMLDR meets that requirement. + + The current version of the P-SEAMLDR can be read here:: + + /sys/devices/faux/tdx_host/seamldr_version + + - The update must be compatible with the running TDX module. + + Like P-SEAMLDR, each module image also specifies a minimum required + TDX module version. The running module must satisfy that requirement. + + The update software can read the current TDX module version here:: + + /sys/devices/faux/tdx_host/version + + Policy choices: + + - The update software chooses how to optimize its update. For instance, + it can optimize for fewer updates or for smaller version steps, + for example, 1.2.3 =3D> 1.2.5 versus 1.2.3 =3D> 1.2.4 =3D> 1.2.5. + +4. Perform the update + + Run:: + + echo 1 > /sys/class/firmware/tdx_module/loading + cat > /sys/class/firmware/tdx_module/data + echo 0 > /sys/class/firmware/tdx_module/loading + + The files /sys/class/firmware/tdx_module/status and + /sys/class/firmware/tdx_module/error report update progress and error + information. + + After the update completes, the new module version is visible in + /sys/devices/faux/tdx_host/version. + +Impact on running TDs +~~~~~~~~~~~~~~~~~~~~~ + +TDX module runtime updates must have virtually no visible impact on running +TDs. Any TD visible impact is a TDX module bug. + +The main exception is the TEE_TCB_SVN_2 field in TD quotes, which +reflects the TCB of the currently running TDX module and therefore +changes after an update. By contrast, TEE_TCB_SVN reflects the TCB at TD +launch time and is not affected. + TDX Interaction to Other Kernel Components ------------------------------------------ =20