summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-06-03Merge tag 'cgroup-for-7.1-rc6-fixes' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup Pull cgroup fixes from Tejun Heo: "One cpuset fix and a maintenance update, both low-risk: - Fix cpuset partition CPU accounting under sibling CPU exclusion that could produce wrong CPU assignments and trigger scheduling-domain warnings. Includes selftests. - Update an email address in MAINTAINERS" * tag 'cgroup-for-7.1-rc6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup: cgroup/cpuset: Change Ridong's email cgroup/cpuset: Add test cases for sibling CPU exclusion on partition update cgroup/cpuset: Use effective_xcpus in partcmd_update add/del mask calculation
2026-06-03x86/virt/seamldr: Shut down the current TDX moduleChao Gao
The first step of TDX module updates is shutting down the current TDX module. This step also packs state information that needs to be preserved across updates, called "handoff data". This handoff data is consumed by the updated module and stored internally in the SEAM range and hidden from the kernel. Since the handoff data layout may change between modules, the handoff data is versioned. Each module has a native handoff version and provides backward support for several older versions. The complete handoff versioning protocol is complex as it supports both module upgrades and downgrades. See details in "Intel Trust Domain Extensions (Intel TDX) Module Base Architecture Specification", Chapter "Handoff Versioning". Ideally, the kernel needs to retrieve the handoff versions supported by the current module and the new module and select a version supported by both. But since this implementation only supports module upgrades, simply request handoff data from the current module using its highest supported version. That is sufficient for this upgrade-only implementation. Retrieve the module's handoff version from TDX global metadata and add an update step to shut down the module. Module shutdown only needs to run on one CPU. Don't cache the handoff information in tdx_sysinfo. It is used only for module shutdown, and is present only when the TDX module supports updates. Caching it in get_tdx_sys_info() would require extra update-support guards and refreshing the cached value across module updates. [ dhansen: fix up function variables, remove 'cpu'. Return from tdx_module_shutdown() early if handoff call fails. ] Signed-off-by: Chao Gao <chao.gao@intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Tony Lindgren <tony.lindgren@linux.intel.com> Reviewed-by: Xu Yilun <yilun.xu@linux.intel.com> Reviewed-by: Kai Huang <kai.huang@intel.com> Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org> Link: https://patch.msgid.link/20260520133909.409394-17-chao.gao@intel.com
2026-06-03Merge tag 'sched_ext-for-7.1-rc6-fixes' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext Pull sched_ext fixes from Tejun Heo: "Two low-risk fixes: - Drop a spurious warning that can fire during cgroup migration while a sched_ext scheduler is loaded - Fix a drgn-based debug script that broke after scheduler state moved into a per-scheduler struct" * tag 'sched_ext-for-7.1-rc6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext: sched_ext: Don't warn on NULL cgrp_moving_from in scx_cgroup_move_task() tools/sched_ext: Fix scx_show_state per-scheduler state reads
2026-06-03arm64: fpsimd: Remove <asm/fpsimdmacros.h>Mark Rutland
We no longer need any of the remaining macros in <asm/fpsimdmacros.h>. Remove all of it. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Mark Brown <broonie@kernel.org> Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Fuad Tabba <tabba@google.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Will Deacon <will@kernel.org> Signed-off-by: Will Deacon <will@kernel.org>
2026-06-03arm64: fpsimd: Move SME save/restore inlineMark Rutland
Currently the SVE register save/restore sequences are written in out-of-line assembly routines. While this works, it's somewhat painful: * For KVM to use the sequences, portions of the logic will need to be duplicated in KVM hyp code. While the common logic can be shared in assembly macros, this is very likely to lead to unnecessary divergence and be a maintenance burden. * For historical reasons, the assembly macros take some register arguments as numerical indices (e.g. "sme_save_za 0, x2, 12" uses x0, x1, and x12), which is simply confusing. * Address generation and control flow are far clearer in C than in assembly. * The assembly sequences can't be instrumented, and so it's harder than necessary to catch memory safety issues. To handle the above, move the SME register save/restore sequences to inline assembly. Neither GCC nor LLVM instrument memory arguments to inline assembly, so explicit instrumentation is added in the same manner as other assembly routines. This instrumentation is implicitly disabled by Kbuild for nVHE hyp code. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Mark Brown <broonie@kernel.org> Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Fuad Tabba <tabba@google.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Will Deacon <will@kernel.org> Signed-off-by: Will Deacon <will@kernel.org>
2026-06-03arm64: fpsimd: Move sve_flush_live() inlineMark Rutland
Currently sve_flush_live() is written in out-of-line assembly. It would be nice if we could move it inline such that control flow can be written more clearly in C, and to permit the removal of otherwise unused assembly macros. The 'flush_ffr' argument is redundant as sve_flush_live() is always called from non-streaming mode, and all callers pass 'true'. Remove the argument and make it a requirement that the function is called from non-streaming mode. The 'vq_minus_1' argument is unnecessary, as sve_flush_live() can read the live VL directly using the RDVL instruction (wrapped by the sve_get_vl() helper function). Move the function to C, with the simplifications above. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Mark Brown <broonie@kernel.org> Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Fuad Tabba <tabba@google.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Will Deacon <will@kernel.org> Signed-off-by: Will Deacon <will@kernel.org>
2026-06-03arm64: fpsimd: Move SVE save/restore inlineMark Rutland
Currently the SVE register save/restore sequences are written in out-of-line assembly routines. While this works, it's somewhat painful: * As KVM needs to be able to use the sequences in hyp code, separate assembly files are used for the regular kernel and KVM code. While the common logic is shared in assembly macros, this still requires some duplication, and has lead to some trivial divergence. * As the SVE LDR/STR instrucitons have limited addressing modes, the assembly macros use an awkward pattern requiring negative offsets. This could be written more clearly with addresses being generated in C code. * As the FFR does not always exist in streaming mode, some awkward conditional branching has been written in assembly which could be clearer in C (and would permit the compiler to optimize out unnecessary branches in some cases). * For historical reasons, the assembly macros take some register arguments as numerical indices (e.g. "sve_save 0, x1" uses x0 and x1), which is simply confusing. * For historical reasons, the SVE save/restore code and FPSIMD save/restore code have a distinct sequences for FPSR and FPCR. Ideally this logic would be shared. * The assembly sequences can't be instrumented, and so it's harder than necessary to catch memory safety issues. To handle the above, move the SVE register save/restore sequences to inline assembly. Neither GCC nor LLVM instrument memory arguments to inline assembly, so explicit instrumentation is added in the same manner as other assembly routines. This instrumentation is implicitly disabled by Kbuild for nVHE hyp code. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Mark Brown <broonie@kernel.org> Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Fuad Tabba <tabba@google.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Will Deacon <will@kernel.org> Signed-off-by: Will Deacon <will@kernel.org>
2026-06-03arm64: fpsimd: Use opaque type for SME stateMark Rutland
As the SME state size can vary at runtime, we don't have a concrete type for the in-memory SME state, and pass this around using a pointer to void. Using pointer to void means that it's very easy to introduce errors that cannot be caught by the compiler (e.g. as 'void **' can be assigned to 'void *'). Improve this by adding an opaque 'struct arm64_sme_state', and consistently passing a pointer to this. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Mark Brown <broonie@kernel.org> Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Fuad Tabba <tabba@google.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Will Deacon <will@kernel.org> Signed-off-by: Will Deacon <will@kernel.org>
2026-06-03arm64: fpsimd: Use opaque type for SVE stateMark Rutland
As the SVE state size can vary at runtime, we don't have a concrete type for the in-memory SVE state, and pass this around using a pointer to void. The functions which save/restore the SVE state have a very unusual calling convention, expecting a pointer to the FFR *in the middle of* the in-memory SVE state, which is also passed as a pointer to void. Passing a pointer to the FFR also requires that callers find the live VL and perform some arithmetic, which callers implement differently. Using pointer to void means that it's very easy to introduce errors that cannot be caught by the compiler (e.g. as 'void **' can be assigned to 'void *'). In general this is unnecessarily confusing and fragile. Improve this by adding an opaque 'struct arm64_sve_state', and consistently passing a pointer to this, performing the necessary offsetting *within* the save/restore functions. For the moment, the offsetting is performed in a new '_sve_pffr' assembly macro, using the ADDVL and ADDPL instructions. These add a multiple of the live vector length and predicate length respectively. The ADDVL immediate range cannot encode 32, so this is split into two increments of 16. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Mark Brown <broonie@kernel.org> Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Fuad Tabba <tabba@google.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Will Deacon <will@kernel.org> Signed-off-by: Will Deacon <will@kernel.org>
2026-06-03arm64: fpsimd: Move fpsimd save/restore inlineMark Rutland
Currently the FPSIMD register save/restore sequences are written in out-of-line assembly routines. While this works, it's somewhat painful: * As KVM needs to be able to use the sequences in hyp code, separate assembly files are used for the regular kernel and KVM code. While the common logic is shared in assembly macros, this still requires some duplication, and has lead to some trivial divergence. * For historical reasons, the assembly macros take some register arguments as numerical indices (e.g. "fpsimd_save x0, 8" uses x0 and x8), which is simply confusing. * For historical reasons, the SVE save/restore code and FPSIMD save/restore code have distinct sequences for FPSR and FPCR. Ideally this logic would be shared. * The assembly sequences can't be instrumented, and so it's harder than necessary to catch memory safety issues. To handle the above, move the FPSIMD register save/restore sequences to inline assembly, and share the FPSR+FPCR save/restore with SVE. Neither GCC nor LLVM instrument memory arguments to inline assembly, so explicit instrumentation is added in the same manner as other assembly routines. This instrumentation is implicitly disabled by Kbuild for nVHE hyp code. I've used the SVE sequence for restoring FPCR, which uses an unconditional write to FPCR, rather than the conditional write used by the FPSIMD assembly sequence. I believe that in practice, this doesn't matter to a real workload, and given it's possible for the mis-predicted branch to cost more than the necessary micro-architectural synchronization, I strongly suspect any performance impact is within the noise. Looking at the history, the FPSIMD assembly sequence was changed to use a conditional write to FPCR since 2014 in commit: 5959e25729a5 ("arm64: fpsimd: avoid restoring fpcr if the contents haven't change") ... as described in the commit message, this was based on an expectation of implementation style, and was not based on benchmarking. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Mark Brown <broonie@kernel.org> Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Fuad Tabba <tabba@google.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Will Deacon <will@kernel.org> Signed-off-by: Will Deacon <will@kernel.org>
2026-06-03arm64: fpsimd: Split FPSR/FPCR from SVE save/restoreMark Rutland
Regardless of whether the vector registers are saved in FPSIMD or SVE format, we store FPSR and FPCR in user_fpsimd_state::{fpsr,fpcr}. For historical reasons, the functions which save/restore SVE context take a pointer to user_fpsimd_state::fpsr, and use this to access both user_fpsimd_state::fpsr and user_fpsimd_state::fpcr. This is unnecessarily fragile. Move the save/restore of FPSR and FPCR into separate helper functions which take a pointer to user_fpsimd_state. I've used read_sysreg_s() and write_sysreg_s() as contemporary versions of LLVM will refuse to directly assemble accesses to FPCR or FPSR unless the "fp" arch extension is enabled. For the moment, fpsimd_save_state() and fpsimd_load_state() are left as-is with their own logic to save/restore FPSR and FPCR. This will be unified in subsequent patches. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Mark Brown <broonie@kernel.org> Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Fuad Tabba <tabba@google.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Will Deacon <will@kernel.org> Signed-off-by: Will Deacon <will@kernel.org>
2026-06-03arm64: sysreg: Add FPCR and FPSRMark Rutland
Add sysreg definitions for FPCR and FPSR. Some versions of LLVM will refuse to assemble accesses to FPCR and FPSR unless the "fp" arch extension is enabled, which we don't currently do for read_sysreg() and write_sysreg(). In general, handling feature dependencies would complicate read_sysreg() and write_sysreg(), and it's simpler to use read_sysreg_s() and write_sysreg_s() instead, requiring sysreg definitions. The values used can be found in ARM ARM issue M.b: https://developer.arm.com/documentation/ddi0487/mb/ ... in sections: * C5.2.8 ("FPCR, Floating-point Control Register") * C5.2.10 ("FPSR, Floating-point Status Register") Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Mark Brown <broonie@kernel.org> Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Fuad Tabba <tabba@google.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Will Deacon <will@kernel.org> Signed-off-by: Will Deacon <will@kernel.org>
2026-06-03arm64: fpsimd: Move sve_get_vl() and sme_get_vl() inlineMark Rutland
The sve_get_vl() and sme_get_vl() functions are wrappers for the RDVL and RDSVL instructions respectively. There's no need for those to be out-of-line. Replace the out-of-line assembly functions with equivalent inline functions. The _sve_rdvl assembly macro is unused, and so it is removed. The _sme_rdsvl assembly macro is still used elsewhere, and so is kept for now. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Mark Brown <broonie@kernel.org> Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Fuad Tabba <tabba@google.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Will Deacon <will@kernel.org> Signed-off-by: Will Deacon <will@kernel.org>
2026-06-03arm64: fpsimd: Use assembler for baseline SME instructionsMark Rutland
We currently support assemblers which do not support SME instructions, and have macros to manually encode SME instructions. This was necessary historically as SME support was developed before assembler support was widely available, but things have changed: * All currently supported versions of LLVM support baseline SME instructions. Building the kernel requires LLVM 15+, while LLVM 13+ supports SME. * GNU binutils has supported baseline SME instructions since 2.38, which was released on 09 February 2022. Toolchains using this or later are widely available. For example Debian 12 (released on 10 June 2023) provides binutils 2.40. Toolchains provided kernel.org provide binutils 2.38+ since the GCC 12.1.0 release (released between 06 May 2022 and 17 August 2022). * For various reasons, SME support was marked as BROKEN, and re-enabled in v6.16 (released on 27 July 2025). The earliest support LTS kernel with SME support is v6.18.y, v6.18 was tagged on 30 November 2025, and contemporary toolchains (GCC 15.2 and binutils 2.45) supported baseline SME instructions. * Any distribution which intends to support SME will presumably have a toolchain that supports baseline SME instructions such that userspace can be built. Considering the above, there's no practical benefit to allowing SME to be built when the toolchain doesn't support baseline SME instructions. Make CONFIG_ARM64_SME depend on assembler support for SME, and remove the manual encoding of SME instructions. The various _sme_<insn> macros are kept for now, and will be cleaned up in subsequent patches. A couple of SME2 instructions require a more recent toolchain, and are left as-is for now. I've looked through releases of binutils and LLVM to find when support was added, and noted this in a comment. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Mark Brown <broonie@kernel.org> Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Fuad Tabba <tabba@google.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Will Deacon <will@kernel.org> Signed-off-by: Will Deacon <will@kernel.org>
2026-06-03arm64: fpsimd: Use assembler for SVE instructionsMark Rutland
Historically we supported assemblers which could not assemble SVE instructions. We dropped support for such assemblers in commit: 118c40b7b503 ("kbuild: require gcc-8 and binutils-2.30") Since that commit, all supported assemblers (binutils and LLVM) are capable of assembling SVE instructions, and there's no need for us to manually encode SVE instructions. Rely on the assembler to encode SVE instructions, and remove the manual encoding. The various _sve_<insn> macros are kept for now, and will be cleaned up in subsequent patches. There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Mark Brown <broonie@kernel.org> Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Fuad Tabba <tabba@google.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Will Deacon <will@kernel.org> Signed-off-by: Will Deacon <will@kernel.org>
2026-06-03arm64: fpsimd: Remove sve_set_vq() and sme_set_vq()Mark Rutland
The sve_set_vq() and sme_set_vq() assembly functions (and the sve_load_vq and sme_load_vq macros they use) are open-coded forms of sysreg_clear_set*(). There's no need for these to be implemented out-of-line in assembly, and the 'vq_minus_1' argument is unusual and confusing. Use sysreg_clear_set_s() directly, where the necessary 'vq - 1' encoding is more obviously part of encoding the register value. For now, sve_flush_live() is left with the unusual vq_minus_1 argument. This will be addressed in subsequent patches. There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Mark Brown <broonie@kernel.org> Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Fuad Tabba <tabba@google.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Will Deacon <will@kernel.org> Signed-off-by: Will Deacon <will@kernel.org>
2026-06-03arm64: fpsimd: Fold sve_init_regs() into do_sve_acc()Mark Rutland
For historical reasons, do_sve_acc() is structurally different from do_sme_acc(), and the logic to convert the task from FPSIMD to SVE is out-of-line in sve_init_regs(). We only use sve_init_regs() within do_sve_acc(), so it's not necessary for this to be a separate function. Fold sve_init_regs() into do_sve_acc(), and simplify the associated comments. This makes do_sve_acc() structurally similar to do_sme_acc(), making it easier to see similarities and differences. There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Mark Brown <broonie@kernel.org> Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Fuad Tabba <tabba@google.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Will Deacon <will@kernel.org> Signed-off-by: Will Deacon <will@kernel.org>
2026-06-03KVM: arm64: pkvm: Remove struct cpu_sve_stateMark Rutland
There's no need for struct cpu_sve_state. Code would be simpler and more robust without it, and removing it will simplify further cleanups (e.g. adding an opaque type for the sve register state). Protected KVM stores most of the host's system register state in kvm_host_data::host_ctxt, which is an instance of struct kvm_cpu_context. As kvm_cpu_context::sys_regs[] has a slot for ZCR_EL1, we can store the host's ZCR_EL1 there. While kvm_cpu_context::sys_regs doesn't have slots for FPSR and FPCR, these are usually expected to be stored in struct user_fpsimd_state. For historical reasons, __sve_save_state and __sve_restore_state() expect a pointer to fpsr *within* struct user_fpsimd_state, assuming the fpcr will immediately follow, as per the order within struct user_fpsimd_state. We currently match this ordering in struct cpu_sve_state, but it would be simpler and more robust to use struct user_fpsimd_state directly. After moving ZCR_EL1, FPSR, and FPCR out of struct cpu_sve_state, all that's left is sve_regs, which can be represented as a pointer without need for a container struct. This is kept as a pointer to u8 (matching the array type), as this permits the compiler to catch unbalanced referencing/dereferencing, which is not possible for pointers to void. Apply the above changes, and remove cpu_sve_state. I've dropped the comment regarding buffer alignment as AFAICT this was never necessary. The LDR/STR (vector) instructions only require this alignment when SCTLR_ELx.A==1, which is not the case for the kernel or hyp code. Nothing else depends on the alignment. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Fuad Tabba <tabba@google.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Mark Brown <broonie@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Will Deacon <will@kernel.org> Signed-off-by: Will Deacon <will@kernel.org>
2026-06-03KVM: arm64: pkvm: Save host FPMR in host cpu contextMark Rutland
Protected KVM stores most of the host's system register state in kvm_host_data::host_ctxt, which is an instance of struct kvm_cpu_context. As kvm_cpu_context::sys_regs[] has a slot for FPMR, we can store the host's FPMR there. Do so, and remove kvm_host_data::fpmr. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Fuad Tabba <tabba@google.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Mark Brown <broonie@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Will Deacon <will@kernel.org> Signed-off-by: Will Deacon <will@kernel.org>
2026-06-03KVM: arm64: Don't override FFR save/restore argumentMark Rutland
The __sve_save_state() and __sve_restore_state() functions take a parameter describing whether to save/restore the FFR, but both functions silently override this with '1'. This has always been benign (and callers have all passed 'true' since the parameter was introduced), but clearly this is not intentional. Historically, the functions always saved/restored the FFR, and there was no parameter to control this. In v5.16, the sve_save and sve_load assembly macros used by __sve_save_state() and __sve_restore_state() were changed to make saving/restoring FFR optional. The implementations of __sve_save_state() and __sve_restore_state() were changed to pass '1' to their respective macros, and the prototypes of __sve_save_state() and __sve_restore_state() were unchanged. See commit: 9f5848665788 ("arm64/sve: Make access to FFR optional") In v6.10, the prototypes of __sve_save_state() and __sve_restore_state() were changed to add 'save_ffr' and 'restore_ffr' parameters respectively, but the implementations were not changed to stop passing 1 to their respective macros. All callers were changed to pass 'true' to __sve_save_state() and __sve_restore_state(). See commit: 45f4ea9bcfe9 ("KVM: arm64: Fix prototype for __sve_save_state/__sve_restore_state") This is all benign, but clearly unintentional, and it gets in the way of cleaning up the FPSIMD/SVE/SME code. Remove the unnecessary overriding. The 'save_ffr' and 'restore_ffr' parameters are 32-bit ints, and per the AAPCS64 parameter passing rules, the upper 32 bits of the register holding these arguments might contain arbitrary values. Thus it is necessary to pass 'w2' rather than 'x2' to the sve_load and save_save macros, such that the upper 32 bits are ignored when deciding whether to save/restore the FFR. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Mark Brown <broonie@kernel.org> Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Fuad Tabba <tabba@google.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Will Deacon <will@kernel.org> Signed-off-by: Will Deacon <will@kernel.org>
2026-06-03KVM: arm64: Don't include <asm/fpsimdmacros.h>Mark Rutland
There's no need for hyp/entry.S to include <asm/fpsimdmacros.h>. The fpsimd macros have never been used by code in hyp/entry.S, and were instead used by code in hyp/fpsimd.S. Remove the unnecessary include. There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Mark Brown <broonie@kernel.org> Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Fuad Tabba <tabba@google.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Will Deacon <will@kernel.org> Signed-off-by: Will Deacon <will@kernel.org>
2026-06-03arm64: fpsimd: Fix type mismatch in sme_{save,load}_state()Mark Rutland
The sme_save_state() and sme_load_state() functions take a 32-bit int argument that describes whether to save/restore ZT0. Their assembly implementations consume the entire 64-bit register containing this 32-bit value, and will attempt to save/restore ZT0 if any bit of that 64-bit register is non-zero. Per the AAPCS64 parameter passing rules, the callee is responsible for any necessary widening, and the upper 32-bits are permitted to contain arbitrary values. If the upper 32 bits are non-zero, this could result in an unexpected attempt to save/restore ZT0, and consequently could lead to unexpected traps/undefs/faults. In practice compilers are very unlikely to generate code where the upper 32-bits would be non-zero, but they are permitted to do so. Fix this by only consuming the low 32 bits of the register, and update comments accordingly. Fixes: 95fcec713259 ("arm64/sme: Implement context switching for ZT0") Signed-off-by: Mark Rutland <mark.rutland@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Fuad Tabba <tabba@google.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Mark Brown <broonie@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Will Deacon <will@kernel.org> Cc: stable@vger.kernel.org Signed-off-by: Will Deacon <will@kernel.org>
2026-06-03arm64: fpsimd: Fix type mismatch in sve_{save,load}_state()Mark Rutland
The sve_save_state() and sve_load_state() functions take a 32-bit int argument that describes whether to save/restore the FFR. Their assembly implementations consume the entire 64-bit register containing this 32-bit value, and will attempt to save/restore the FFR if any bit of that 64-bit register is non-zero. Per the AAPCS64 parameter passing rules, the callee is responsible for any necessary widening, and the upper 32-bits are permitted to contain arbitrary values. If the upper 32 bits are non-zero, this could result in an unexpected attempt to save/restore the FFR, and consequently could lead to unexpected traps/undefs/faults. In practice compilers are very unlikely to generate code where the upper 32-bits would be non-zero, but they are permitted to do so. Fix this by only consuming the low 32 bits of the register, and update comments accordingly. The hyp code __sve_save_state() and __sve_restore_state() functions don't have the same latent bug as they override the full 64-bit register containing the argument. Fixes: 9f5848665788 ("arm64/sve: Make access to FFR optional") Signed-off-by: Mark Rutland <mark.rutland@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Fuad Tabba <tabba@google.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Mark Brown <broonie@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Vladimir Murzin <vladimir.murzin@arm.com> Cc: Will Deacon <will@kernel.org> Cc: stable@vger.kernel.org Signed-off-by: Will Deacon <will@kernel.org>
2026-06-03Bluetooth: MGMT: Fix backward compatibility with userspaceLuiz Augusto von Dentz
bluetoothd has a bug with makes it send extra bytes as part of MGMT_OP_ADD_EXT_ADV_DATA which are now being checked to be the exact the expected length, relax this so only when the expected length is greater than the data length to cause an error since that would result in accessing invalid memory, otherwise just ignore the extra bytes. Link: https://lore.kernel.org/linux-bluetooth/20260602204749.210857-1-luiz.dentz@gmail.com/T/#u Fixes: d3f7d17960ed ("Bluetooth: MGMT: validate Add Extended Advertising Data length") Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-06-03Bluetooth: SCO: Fix data-race on sco_pi fields in sco_connectSeungJu Cheon
sco_sock_connect() copies the destination address into sco_pi(sk)->dst under lock_sock(), then releases the lock and calls sco_connect(), which reads dst, src, setting, and codec without holding lock_sock() in hci_get_route() and hci_connect_sco(). These fields may be modified concurrently by connect(), bind(), or setsockopt() on the same socket, resulting in data-races reported by KCSAN. Fix this by snapshotting dst, src, setting, and codec under lock_sock() at the start of sco_connect() before passing them to hci_get_route() and hci_connect_sco(). BUG: KCSAN: data-race in memcmp+0x45/0xb0 race at unknown origin, with read to 0xffff88800e6b0dd0 of 1 bytes by task 315 on cpu 0: memcmp+0x45/0xb0 hci_connect_acl+0x1b7/0x6b0 hci_connect_sco+0x4d/0xb30 sco_sock_connect+0x27b/0xd60 __sys_connect_file+0xbd/0xe0 __sys_connect+0xe0/0x110 __x64_sys_connect+0x40/0x50 x64_sys_call+0xcad/0x1c60 do_syscall_64+0x133/0x590 entry_SYSCALL_64_after_hwframe+0x77/0x7f Fixes: 9a8ec9e8ebb5 ("Bluetooth: SCO: Fix possible circular locking dependency on sco_connect_cfm") Signed-off-by: SeungJu Cheon <suunj1331@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-06-03Bluetooth: ISO: Fix data-race on iso_pi fields in hci_get_route callsSeungJu Cheon
iso_connect_bis(), iso_connect_cis(), iso_listen_bis(), and iso_conn_big_sync() call hci_get_route() using iso_pi(sk)->dst, iso_pi(sk)->src, and iso_pi(sk)->src_type without holding lock_sock(). These fields may be modified concurrently by connect() or setsockopt() on the same socket, resulting in data-races reported by KCSAN. Fix this by snapshotting the required fields under lock_sock() before calling hci_get_route(). BUG: KCSAN: data-race in memcmp+0x45/0xb0 race at unknown origin, with read to 0xffff8880122135cf of 1 bytes by task 333 on cpu 1: memcmp+0x45/0xb0 hci_get_route+0x27e/0x490 iso_connect_cis+0x4c/0xa10 iso_sock_connect+0x60e/0xb30 __sys_connect_file+0xbd/0xe0 __sys_connect+0xe0/0x110 __x64_sys_connect+0x40/0x50 x64_sys_call+0xcad/0x1c60 do_syscall_64+0x133/0x590 entry_SYSCALL_64_after_hwframe+0x77/0x7f Fixes: 241f51931c35 ("Bluetooth: ISO: Avoid circular locking dependency") Signed-off-by: SeungJu Cheon <suunj1331@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-06-03Bluetooth: ISO: Fix a use-after-free of the hci_conn pointerLuiz Augusto von Dentz
In iso_sock_rebind_bc(), the bis pointer is cached, then the socket lock is dropped: bis = iso_pi(sk)->conn->hcon; /* Release the socket before lookups since that requires hci_dev_lock * which shall not be acquired while holding sock_lock for proper * ordering. */ release_sock(sk); hci_dev_lock(bis->hdev); During the unlocked window, could a concurrent close() destroy the connection and free the bis structure, causing hci_dev_lock(bis->hdev) to access memory after it is freed, fix this by using the hdev reference which was safely acquired via iso_conn_get_hdev(). Fixes: d3413703d5f8 ("Bluetooth: ISO: Add support to bind to trigger PAST") Reported-by: Sashiko <sashiko-bot@kernel.org> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-06-03Bluetooth: ISO: Fix not releasing hdev reference on iso_conn_big_syncLuiz Augusto von Dentz
hci_get_route() returns a reference-counted hci_dev pointer via hci_dev_hold(). The function exits normally or with an error without ever releasing it. Fixes: 07a9342b94a9 ("Bluetooth: ISO: Send BIG Create Sync via hci_sync") Reported-by: Sashiko <sashiko-bot@kernel.org> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-06-03Bluetooth: fix memory leak in error path of hci_alloc_dev()Bharath Reddy
Early failures in Bluetooth HCI UART configuration leak SRCU percpu memory. When device initialization fails before hci_register_dev() completes, the HCI_UNREGISTER flag is never set. As a result, when the device reference count reaches zero, bt_host_release() evaluates this flag as false and falls back to a direct kfree(hdev). Because hci_release_dev() is bypassed, the SRCU struct initialized early in hci_alloc_dev() is never cleaned up, resulting in a leak of percpu memory. Fix the leak by explicitly calling cleanup_srcu_struct() in the fallback (unregistered) branch of bt_host_release() before freeing the device. Reported-by: syzbot+535ecc844591e50588a5@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=535ecc844591e50588a5 Tested-by: syzbot+535ecc844591e50588a5@syzkaller.appspotmail.com Fixes: 1d6123102e9f ("Bluetooth: hci_core: Fix use-after-free in vhci_flush()") Signed-off-by: Bharath Reddy <kbreddy.rpbc@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-06-03Bluetooth: bnep: reject short frames before parsingZhang Cen
A BNEP peer can send a short BNEP SDU. bnep_rx_frame() reads the packet type byte immediately and, for control packets, reads the control opcode and setup UUID-size byte before proving that those bytes are present. bnep_rx_control() also dereferences the control opcode without rejecting an empty control payload. Use skb_pull_data() for the fixed fields in bnep_rx_frame() so a NULL return gates each dereference. Split the control handler so the frame path can pass an opcode that has already been pulled, and keep the byte-buffer wrapper for extension control payloads. For BNEP_SETUP_CONN_REQ, name the UUID-size byte before pulling the setup payload. struct bnep_setup_conn_req carries destination and source service UUIDs after that byte, each uuid_size bytes, so the parser now documents that tuple explicitly instead of leaving the pull length as an opaque multiplication. Validation reproduced this kernel report: KASAN slab-out-of-bounds in bnep_rx_frame.isra.0+0x130c/0x1790 The buggy address belongs to the object at ffff88800c0f7908 which belongs to the cache kmalloc-8 of size 8 The buggy address is located 0 bytes to the right of allocated 1-byte region [ffff88800c0f7908, ffff88800c0f7909) Read of size 1 Call trace: dump_stack_lvl+0xb3/0x140 (?:?) print_address_description+0x57/0x3a0 (?:?) bnep_rx_frame+0x130c/0x1790 (net/bluetooth/bnep/core.c:306) print_report+0xb9/0x2b0 (?:?) __virt_addr_valid+0x1ba/0x3a0 (?:?) srso_alias_return_thunk+0x5/0xfbef5 (?:?) kasan_addr_to_slab+0x21/0x60 (?:?) kasan_report+0xe0/0x110 (?:?) process_one_work+0xfce/0x17e0 (kernel/workqueue.c:3200) worker_thread+0x65c/0xe40 (?:?) __kthread_parkme+0x184/0x230 (?:?) kthread+0x35e/0x470 (?:?) _raw_spin_unlock_irq+0x28/0x50 (?:?) ret_from_fork+0x586/0x870 (?:?) __switch_to+0x74f/0xdc0 (?:?) ret_from_fork_asm+0x1a/0x30 (?:?) Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Assisted-by: Codex:gpt-5.5 Signed-off-by: Zhang Cen <rollkingzzc@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-06-03Bluetooth: hci_sync: reject oversized Broadcast Announcement prependYuqi Xu
Existing advertising instances can already hold the maximum extended advertising payload. When hci_adv_bcast_annoucement() prepends the Broadcast Announcement service data to that payload, the combined data may no longer fit in the temporary buffer used to rebuild the advertising data. Reject that case before copying the existing payload and report the failure through the device log. This keeps the existing advertising data intact and avoids overrunning the temporary buffer. Fixes: 5725bc608252 ("Bluetooth: hci_sync: Fix broadcast/PA when using an existing instance") Cc: stable@kernel.org Reported-by: Yuan Tan <yuantan098@gmail.com> Reported-by: Zhengchuan Liang <zcliangcn@gmail.com> Reported-by: Xin Liu <bird@lzu.edu.cn> Assisted-by: Codex:GPT-5.4 Signed-off-by: Yuqi Xu <xuyq21@lenovo.com> Signed-off-by: Ren Wei <n05ec@lzu.edu.cn> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-06-03Bluetooth: L2CAP: reject BR/EDR signaling packets over MTUsigMichael Bommarito
net/bluetooth/l2cap_core.c:l2cap_sig_channel() accepts BR/EDR signaling packets up to the channel MTU and dispatches each command without enforcing the signaling MTU (MTUsig). A Bluetooth BR/EDR peer within radio range can send a fixed-channel CID 0x0001 packet that is larger than MTUsig and contains many L2CAP_ECHO_REQ commands before pairing. In a real-radio stock-kernel run, one 681-byte signaling packet containing 168 zero-length ECHO_REQ commands made the target transmit 168 ECHO_RSP frames over about 220 ms. Impact: a Bluetooth BR/EDR peer within radio range, before pairing, can force 168 ECHO_RSP frames from one 681-byte fixed-channel signaling packet containing packed ECHO_REQ commands. Define Linux's BR/EDR signaling MTU as the spec minimum of 48 bytes and reject any larger signaling packet with one L2CAP_COMMAND_REJECT_RSP carrying L2CAP_REJ_MTU_EXCEEDED before any command is dispatched. The Bluetooth Core spec wording for MTUExceeded says the reject identifier shall match the first request command in the packet, and that packets containing only responses shall be silently discarded. Linux intentionally deviates from that prescription: silently discarding desynchronizes the peer because the remote stack never learns its responses were dropped, and locating the first request command requires walking command headers past MTUsig, i.e. processing bytes from a packet we have already decided is too large to process. We therefore always emit one reject and use the identifier from the first command header, a single fixed-offset byte read. The unrestricted BR/EDR signaling parser and ECHO_REQ response path both trace to the initial git import; no later introducing commit is available for a Fixes tag. Cc: stable@vger.kernel.org Suggested-by: Luiz Augusto von Dentz <luiz.dentz@gmail.com> Link: https://lore.kernel.org/r/20260518002800.1361430-1-michael.bommarito@gmail.com Link: https://lore.kernel.org/r/20260520135034.1060859-1-michael.bommarito@gmail.com Link: https://lore.kernel.org/r/20260521000555.3712030-1-michael.bommarito@gmail.com Assisted-by: Claude:claude-opus-4-7 Assisted-by: Codex:gpt-5-5-xhigh Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-06-03Bluetooth: RFCOMM: validate skb length in MCC handlersSeungJu Cheon
The RFCOMM MCC handlers cast skb->data to protocol-specific structs without validating skb->len first. A malicious remote device can send truncated MCC frames and trigger out-of-bounds reads in these handlers. Fix this by using skb_pull_data() to validate and access the required data before dereferencing it. rfcomm_recv_rpn() requires special handling since ETSI TS 07.10 allows 1-byte RPN requests. Handle this by validating only the DLCI byte first, and validating the full struct only when len > 1. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Suggested-by: Muhammad Bilal <meatuni001@gmail.com> Signed-off-by: SeungJu Cheon <suunj1331@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-06-03Bluetooth: MGMT: validate advertising TLV before type checksZhang Cen
tlv_data_is_valid() reads each advertising data field length from data[i], then inspects data[i + 1] for managed EIR types before checking that the current field still fits inside the supplied buffer. A malformed field whose length byte is the last byte of the buffer can therefore make the parser read one byte past the advertising data. KASAN reported the following when a malformed MGMT_OP_ADD_ADVERTISING request reached that path: BUG: KASAN: vmalloc-out-of-bounds in tlv_data_is_valid() Read of size 1 Call trace: tlv_data_is_valid() add_advertising() hci_mgmt_cmd() hci_sock_sendmsg() Move the existing element-length check before any type-octet inspection so each non-empty element is proven to contain its type byte before the parser looks at data[i + 1]. Fixes: 2bb36870e8cb ("Bluetooth: Unify advertising instance flags check") Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de> Signed-off-by: Zhang Cen <rollkingzzc@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-06-03Bluetooth: RFCOMM: hold listener socket in rfcomm_connect_ind()Zhang Cen
rfcomm_get_sock_by_channel() scans rfcomm_sk_list under the list lock, but returns the selected listener after dropping that lock without taking a reference. rfcomm_connect_ind() then locks the listener, queues a child socket on it, and may notify it after unlocking it. The buggy scenario involves two paths, with each column showing the order within that path: rfcomm_connect_ind(): listener close: 1. Find parent in 1. close() enters rfcomm_get_sock_by_channel() rfcomm_sock_release(). 2. Drop rfcomm_sk_list.lock 2. rfcomm_sock_shutdown() without pinning parent. closes the listener. 3. Call lock_sock(parent) and 3. rfcomm_sock_kill() bt_accept_enqueue(parent, unlinks and puts parent. sk, true). 4. Read parent flags and may 4. parent can be freed. call sk_state_change(). If close wins the race, parent can be freed before rfcomm_connect_ind() reaches lock_sock(), bt_accept_enqueue(), or the deferred-setup callback. Take a reference on the listener before leaving rfcomm_sk_list.lock. After lock_sock() succeeds, recheck that it is still in BT_LISTEN before queueing a child, cache the deferred-setup bit while the parent is locked, and drop the reference after the last parent use. KASAN reported a slab-use-after-free in lock_sock_nested() from rfcomm_connect_ind(), with the freeing stack going through rfcomm_sock_kill() and rfcomm_sock_release(). Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Zhang Cen <rollkingzzc@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-06-03x86/virt/seamldr: Abort updates after a failed stepChao Gao
A TDX module update is a multi-step process, and any step can fail. The current update flow continues to later steps after an error. Continuing after a failure can cause the TDX module to enter an unrecoverable state. But certain failures during the initial module shutdown step should simply return an error to userspace, so the update can be retried cleanly. To preserve that recoverability, one option would be to abort the update only for those failures, since they occur before any TDX module state is changed. But special-casing specific failures in specific steps would complicate the do-while() update loop for no benefit. Simply abort update on any failure, at any step. Track failures for each step, stop the update loop once a failure is observed, and do not advance the state machine to the next step. [ dhansen: style nits ] Signed-off-by: Chao Gao <chao.gao@intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Xu Yilun <yilun.xu@linux.intel.com> Reviewed-by: Tony Lindgren <tony.lindgren@linux.intel.com> Reviewed-by: Kai Huang <kai.huang@intel.com> Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org> Link: https://lore.kernel.org/linux-coco/aQFmOZCdw64z14cJ@google.com/ # [1] Link: https://patch.msgid.link/20260520133909.409394-16-chao.gao@intel.com
2026-06-03x86/virt/seamldr: Introduce skeleton for TDX module updatesChao Gao
tl;dr: Use stop_machine() and a state machine based on the "MULTI_STOP" pattern to implement core TDX module update logic. Long version: TDX module updates require careful synchronization with other TDX operations. The requirements are (#1/#2 reflect current behavior that must be preserved): 1. SEAMCALLs need to be callable from both process and IRQ contexts. 2. SEAMCALLs need to be able to run concurrently across CPUs 3. During updates, only update-related SEAMCALLs are permitted; all other SEAMCALLs shouldn't be called. 4. During updates, all online CPUs must participate in the update work. No single lock primitive satisfies all requirements. For instance, rwlock_t handles #1/#2 but fails #4: CPUs spinning with IRQs disabled cannot be directed to perform update work. Use stop_machine() as it is the only well-understood mechanism that can meet all requirements. And TDX module updates consist of several steps (See Intel Trust Domain Extensions (Intel TDX) Module Base Architecture Specification, Chapter "TD-Preserving TDX module Update"). Ordering requirements between steps mandate lockstep synchronization across all CPUs. multi_cpu_stop() provides a good example of executing a multi-step task in lockstep across CPUs, but it does not synchronize the individual steps inside the callback itself. Implement a similar state machine as the skeleton for TDX module updates. Each state represents one step in the update flow, and the state advances only after all CPUs acknowledge completion of the current step. This acknowledgment mechanism provides the required lockstep execution. The update flow is intentionally simpler than multi_cpu_stop() in two ways: a) use a spinlock to protect the control data instead of atomic_t and explicit memory barriers. b) omit touch_nmi_watchdog() and rcu_momentary_eqs(), which exist there for debugging and are not strictly needed for this update flow Potential alternative to stop_machine() ======================================= An alternative approach is to lock all KVM entry points and kick all vCPUs. Here, KVM entry points refer to KVM VM/vCPU ioctl entry points, implemented in KVM common code (virt/kvm). Adding a locking mechanism there would affect all architectures KVM supports. And to lock only TDX vCPUs, new logic would be needed to identify TDX vCPUs, which the KVM common code currently lacks. This would add significant complexity and maintenance overhead to KVM for this TDX-specific use case, so don't take this approach. [ dhansen: normal changelog/style munging ] Signed-off-by: Chao Gao <chao.gao@intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Xu Yilun <yilun.xu@linux.intel.com> Reviewed-by: Tony Lindgren <tony.lindgren@linux.intel.com> Reviewed-by: Kai Huang <kai.huang@intel.com> Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org> Reviewed-by: Rick Edgecombe <rick.p.edgecombe@intel.com> Link: https://patch.msgid.link/20260520133909.409394-15-chao.gao@intel.com
2026-06-03x86/virt/seamldr: Allocate and populate a module update requestChao Gao
There are two important ABIs here: 'struct tdx_image' - The on-disk and in-memory format for a TDX module update image. 'struct seamldr_params' - The in-memory ABI passed to the TDX module loader. Points to a single 'struct tdx_image' broken up into 4k pages. Userspace supplies the update image in 'struct tdx_image' format. The image consists of a header followed by a sigstruct and the module binary. P-SEAMLDR, however, consumes 'struct seamldr_params' rather than the image directly. Parse the 'struct tdx_image' provided by userspace and populate a matching 'struct seamldr_params'. The 'tdx_image' ABI is versioned. Two public versions exist today: 0x100 and 0x200. This kernel only accepts 0x200. The older 0x100 format is being deprecated and is intentionally not supported here. Future versions of the module might be able to use the same ABIs (user/kernel and kernel/SEAMLDR) but they will not be able to use this kernel code. Reject module images without that specific version. This ensures that the kernel is able to understand the passed-in format. Validate the 'struct tdx_image' header before using it, because the header is consumed solely by the kernel to locate the sigstruct and module within the image. Do not validate the payload itself. The sigstruct and module pages are passed through to P-SEAMLDR, which validates them as part of the update. sigstruct_pages_pa_list currently has only one entry, but it will grow to four pages in the future. Keep it as an array for symmetry with module_pages_pa_list and for extensibility. [ dhansen: normal changelog clarification/munging ] 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-14-chao.gao@intel.com
2026-06-03coco/tdx-host: Implement firmware upload sysfs ABI for TDX module updatesChao Gao
tl;dr: Select fw_upload for doing TDX module updates. The process of selecting among available update images is complicated and nuanced. Punt the selection process out to userspace. One existing userspace implementation today is the script in the Intel TDX Module Binaries repository[1]. Long Version: The kernel supports two primary firmware update mechanisms: 1. request_firmware() - used by microcode, SEV firmware, hundreds of other drivers 2. 'struct fw_upload' - used by CXL, FPGA updates, dozens of others The key difference between is that request_firmware() loads a named file from the filesystem where the filename is kernel-controlled, while fw_upload accepts firmware data directly from userspace. TDX module firmware update selection policy is too complex for the kernel. Leave it to userspace and use fw_upload. Add a skeleton fw_upload implementation to be fleshed out in subsequent patches. Refactor the sysfs visiblity attribute function so it can be used as a more generic flag for the presence of viable runtime update support. Why fw_upload instead of request_firmware()? ============================================ Selecting a TDX module update image is not a simple "load the latest" decision. Userspace needs to choose an image that is compatible with both the platform and the currently running module. Some constraints are hard requirements: a. 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. b. Updates are also constrained by version distance. A 1.5.6 module might permit updates to 1.5.7 but not to 1.5.50. There may also be userspace policy choices: c. Decide the update direction: upgrade or downgrade d. Choose whether to optimize for fewer updates or smaller version steps, for example, 1.2.3=>1.2.5 versus 1.2.3=>1.2.4=>1.2.5. Given that complexity, leave module selection to userspace and use fw_upload. 1. https://github.com/intel/confidential-computing.tdx.tdx-module.binaries/blob/main/version_select_and_load.py [ dhansen: add version script link, add more explanation of code moves, fix some minor whitespace issues ] Signed-off-by: Chao Gao <chao.gao@intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Tony Lindgren <tony.lindgren@linux.intel.com> Reviewed-by: Kai Huang <kai.huang@intel.com> Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org> Link: https://lore.kernel.org/kvm/01fc8946-eb84-46fa-9458-f345dd3f6033@intel.com/ Link: https://patch.msgid.link/20260520133909.409394-13-chao.gao@intel.com
2026-06-03coco/tdx-host: Don't expose P-SEAMLDR information on CPUs with erratumChao Gao
TDX-capable CPUs clobber the current VMCS on P-SEAMLDR calls. Clearing the current VMCS behind KVM's back breaks KVM. Future CPUs will fix this by preserving the current VMCS across P-SEAMLDR calls. A future specification update will describe the VMCS-clearing behavior as an erratum and to state that it does not occur when IA32_VMX_BASIC[60] is set. Add a CPU bug bit and refuse to expose P-SEAMLDR information on affected CPUs. Use a CPU bug bit to stay consistent with X86_BUG_TDX_PW_MCE. As a bonus, the bug bit is visible to userspace, which allows userspace to determine why these sysfs files are not exposed, and it can also be checked by other kernel components in the future if needed. == Alternatives == Two workarounds were considered but both were rejected: 1. Save/restore the current VMCS around P-SEAMLDR calls. This produces ugly assembly code [1] and doesn't play well with #MCE or #NMI if they need to use the current VMCS. 2. Move KVM's VMCS tracking logic to the TDX core code, which would break the boundary between KVM and the TDX core code [2]. [ dhansen: comment and changelog munging. Add seamldr_call() bug check. ] Signed-off-by: Chao Gao <chao.gao@intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Kai Huang <kai.huang@intel.com> Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org> Reviewed-by: Rick Edgecombe <rick.p.edgecombe@intel.com> Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com> Link: https://lore.kernel.org/kvm/fedb3192-e68c-423c-93b2-a4dc2f964148@intel.com/ # [1] Link: https://lore.kernel.org/kvm/aYIXFmT-676oN6j0@google.com/ # [2] Link: https://patch.msgid.link/20260520133909.409394-12-chao.gao@intel.com
2026-06-03coco/tdx-host: Expose P-SEAMLDR information via sysfsChao Gao
TDX module updates require userspace to select the appropriate module to load. Expose necessary information to facilitate this decision. Two values are needed: - P-SEAMLDR version: for compatibility checks between TDX module and P-SEAMLDR - num_remaining_updates: indicates how many updates can be performed Expose them as tdx-host device attributes visible only when updates are supported. Note that the underlying P-SEAMLDR attributes are available regardless of update support; this only restricts their visibility to userspace. Signed-off-by: Chao Gao <chao.gao@intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org> Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com> Link: https://patch.msgid.link/20260520133909.409394-11-chao.gao@intel.com
2026-06-03x86/virt/seamldr: Add a helper to retrieve P-SEAMLDR informationChao Gao
P-SEAMLDR reports its state via SEAMLDR.INFO, including its version and the number of remaining runtime updates. This information is useful for userspace. For example, userspace can use the P-SEAMLDR version to determine whether a candidate TDX module is compatible with the running loader, and can use the remaining update count to determine whether another runtime update is still possible. Add a helper to retrieve P-SEAMLDR information in preparation for exposing P-SEAMLDR version and other necessary information to userspace. Export the new kAPI for use by the "tdx_host" device. Note that there are two distinct P-SEAMLDR APIs with similar names: "SEAMLDR.INFO" is metadata about the loader. It's metadata for the update process. "SEAMLDR.SEAMINFO" is metadata about SEAM mode. It is for the module init process, not for the update process. Use SEAMLDR.INFO here. For details, see "Intel Trust Domain Extensions - SEAM Loader (SEAMLDR) Interface Specification". Signed-off-by: Chao Gao <chao.gao@intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Kai Huang <kai.huang@intel.com> Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com> Reviewed-by: Rick Edgecombe <rick.p.edgecombe@intel.com> Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com> Link: https://patch.msgid.link/20260520133909.409394-10-chao.gao@intel.com
2026-06-03x86/virt/seamldr: Introduce a wrapper for P-SEAMLDR SEAMCALLsChao Gao
The TDX architecture uses the "SEAMCALL" instruction to communicate with SEAM mode software. Right now, the only SEAM mode software that the kernel communicates with is the TDX module. But, there is actually another component that runs in SEAM mode but it is separate from the TDX module: the persistent SEAM loader or "P-SEAMLDR". Right now, the only component that communicates with it is the BIOS which loads the TDX module itself at boot. But, to support updating the TDX module, the kernel now needs to be able to talk to it. P-SEAMLDR SEAMCALLs differ from TDX module SEAMCALLs in areas such as concurrency requirements. Add a P-SEAMLDR wrapper to handle these differences and prepare for implementing concrete functions. Use seamcall_prerr() (not '_ret') because current P-SEAMLDR calls do not use any output registers other than RAX. Note: Despite the similar name, the NP-SEAMLDR ("Non-Persistent") (ACM) invoked exclusively by the BIOS at boot rather than a component running in SEAM mode. The kernel cannot call it at runtime. It exposes no SEAMCALL interface. Signed-off-by: Chao Gao <chao.gao@intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com> Reviewed-by: Kai Huang <kai.huang@intel.com> Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com> Reviewed-by: Rick Edgecombe <rick.p.edgecombe@intel.com> Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com> Link: https://cdrdv2.intel.com/v1/dl/getContent/733582 # [1] Link: https://patch.msgid.link/20260520133909.409394-9-chao.gao@intel.com
2026-06-03coco/tdx-host: Expose TDX module versionChao Gao
For TDX module updates, userspace needs to select compatible update versions based on the current module version. For example, the 1.5.x series runs on Sapphire Rapids but not Granite Rapids, which needs 2.0.x. Updates are also constrained by version distance, so a 1.5.6 module might permit updates to 1.5.7 but not to 1.5.20. Start the process of punting the version selection logic to userspace. Expose the TDX module version in the new faux device. Define TDX_VERSION_FMT macro for the TDX version format since it will be used multiple times. Also convert an existing print statement to use it. == Background == For posterity, here's what other firmware mechanisms do: 1. AMD SEV leverages an existing PCI device for the PSP to expose metadata. TDX uses a faux device as it doesn't have PCI device in its architecture. 2. Microcode uses per-CPU virtual devices to report microcode revisions because CPUs can have different revisions. But, there is only a single TDX module, so exposing the TDX module version through a global TDX faux device is appropriate 3. ARM's CCA implementation isn't in-tree yet, but will likely follow a similar faux device approach, though it's unclear whether they need to expose firmware version information [ dhansen: trim changelog ] Signed-off-by: Chao Gao <chao.gao@intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com> Reviewed-by: Tony Lindgren <tony.lindgren@linux.intel.com> Reviewed-by: Xu Yilun <yilun.xu@linux.intel.com> Reviewed-by: Kai Huang <kai.huang@intel.com> Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com> Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com> Link: https://lore.kernel.org/all/2025073035-bulginess-rematch-b92e@gregkh/ # [1] Link: https://patch.msgid.link/20260520133909.409394-8-chao.gao@intel.com
2026-06-03coco/tdx-host: Introduce a "tdx_host" deviceChao Gao
TDX depends on a platform firmware module that runs on the CPU. Unlike other CoCo architectures, TDX has no hardware "device" running the show, just a blob on the CPU. Create a virtual device to anchor interactions with this platform firmware. This lets later code: - expose metadata: TDX module version, seamldr version, to userspace as device attributes - implement firmware uploader APIs (which are tied to a device) to support TDX module runtime updates Use a faux device because the TDX module is singular within the system and has no platform resources. Using a faux device eliminates the need to create a stub bus. The call to tdx_get_sysinfo() ensures that the TDX module is ready to provide services. Note that AMD has a PCI device for the PSP for SEV and ARM CCA will likely have a faux device [1]. Thanks to Dan and Yilun for all the help on this one. [ dhansen: trim changelog ] Signed-off-by: Chao Gao <chao.gao@intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Reviewed-by: Tony Lindgren <tony.lindgren@linux.intel.com> Reviewed-by: Xu Yilun <yilun.xu@linux.intel.com> Reviewed-by: Kai Huang <kai.huang@intel.com> Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com> Link: https://lore.kernel.org/all/2025073035-bulginess-rematch-b92e@gregkh/ # [1] Link: https://patch.msgid.link/20260520133909.409394-7-chao.gao@intel.com
2026-06-03x86/virt/tdx: Move low level SEAMCALL helpers out of <asm/tdx.h>Kai Huang
TDX host core code implements three seamcall*() helpers to make SEAMCALLs to the TDX module. Currently, they are implemented in <asm/tdx.h> and are exposed to other kernel code which includes <asm/tdx.h>. However, other than the TDX host core, seamcall*() are not expected to be used by other kernel code directly. For instance, for all SEAMCALLs that are used by KVM, the TDX host core exports a wrapper function for each of them. Move seamcall*() and related code out of <asm/tdx.h> and make them only visible to TDX host core. Since TDX host core tdx.c is already very heavy, don't put low level seamcall*() code there but to a new dedicated "seamcall_internal.h". Also, currently tdx.c has seamcall_prerr*() helpers which additionally print error message when calling seamcall*() fails. Move them to "seamcall_internal.h" as well. In such way all low level SEAMCALL helpers are in a dedicated place, which is much more readable. Copy the copyright notice from the original files and consolidate the date ranges to: Copyright (C) 2021-2023 Intel Corporation Signed-off-by: Kai Huang <kai.huang@intel.com> Signed-off-by: Chao Gao <chao.gao@intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Zhenzhong Duan <zhenzhong.duan@intel.com> Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com> Reviewed-by: Tony Lindgren <tony.lindgren@linux.intel.com> Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com> Reviewed-by: Vishal Annapurve <vannapurve@google.com> Acked-by: Dave Hansen <dave.hansen@linux.intel.com> Link: https://patch.msgid.link/20260520133909.409394-6-chao.gao@intel.com
2026-06-03x86/virt/tdx: Move TDX_FEATURES0 bits to asm/tdx.hChao Gao
Future changes will add support for new TDX features exposed as TDX_FEATURES0 bits. The presence of these features will need to be checked outside of arch/x86/virt. The feature query helpers and the TDX_FEATURES0 defines they reference will need to live in the widely accessible asm/tdx.h header. Move the existing TDX_FEATURES0 to asm/tdx.h so that they can all be kept together. Opportunistically switch to BIT_ULL() since TDX_FEATURES0 is 64-bit. No functional change intended. [ dhansen: grammar fixups ] Signed-off-by: Chao Gao <chao.gao@intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Link: https://lore.kernel.org/kvm/20260427152854.101171-17-chao.gao@intel.com/ # [1] Link: https://lore.kernel.org/kvm/20251121005125.417831-16-rick.p.edgecombe@intel.com/ # [2] Link: https://patch.msgid.link/20260520133909.409394-5-chao.gao@intel.com
2026-06-03x86/virt/tdx: Consolidate TDX global initialization statesChao Gao
The kernel uses several global flags to guard one-time TDX initialization flows and prevent them from being repeated. When the TDX module is updated, all of those states must be reset so that the module can be initialized again. Today those states are kept as separate global variables, which makes the reset path awkward and easy to miss when a new state is added. Group the states into a single structure so they can be reset together, for example with memset(), and so a newly added state won't be missed. Drop the __ro_after_init annotation from tdx_module_initialized because the other two states do not have it. And with TDX module update support, all the states need to be writable at runtime. 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-4-chao.gao@intel.com
2026-06-03x86/virt/tdx: Move TDX global initialization states to file scopeChao Gao
TDX module global initialization is executed only once. The first call caches both the result and the "done" state, and later callers reuse the saved result. A lock protects that cached states. Those states and the lock are currently kept as function-local statics because they are used only by try_init_module_global(). TDX module updates need to reset the cached states so TDX global initialization can be run again after an update. That will add another access site in the same file. Move the cached states to file scope so it is accessible outside try_init_module_global(), and move the lock along with the states it protects. No functional change intended. 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-3-chao.gao@intel.com
2026-06-03x86/virt/tdx: Clarify try_init_module_global() result cachingChao Gao
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