Skip to content

Commit d2ac4ab

Browse files
committed
fix(vmm): Support kernel >= 5.16 and < 5.17 for xfeature enabling
The Linux kernel introduced some arch_prctl() APIs (ARCH_GET_XCOMP_SUPP, ARCH_GET_XCOMP_PERM and ARCH_REQ_XCOMP_PERM) to support dynamic XSTATE feature enabling for "userspace applications" in 5.16 [1]. To support that for "KVM guest", v5.17 introduced additional arch_prctl() APIs (ARCH_GET_XCOMP_GUEST_PERM and ARCH_REQ_XCOMP_GUEST_PERM) [2]. Note that ARCH_XCOMP_GUEST_SUPP does not exist, so regardless of userspace application or KVM guest, ARCH_GET_XCOMP_SUPP is used to retrieve supported features. As a result, kernel versions >= 5.16 and < 5.17 report supported features via ARCH_GET_XCOMP_SUPP but ARCH_REQ_XCOMP_GUEST_PERM fail with EINVAL. [1]: torvalds/linux@db8268d [2]: torvalds/linux@980fe2f Signed-off-by: Takahiro Itazuri <[email protected]>
1 parent 584f86c commit d2ac4ab

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ and this project adheres to
2727
typo in Swagger definition of `MmdsConfig`, where the property `imds_compat`
2828
was spelled as `imds_comat`. This caused auto-generated clients to create bad
2929
requests.
30+
- [#5447](https://github.com/firecracker-microvm/firecracker/pull/5447): Fixed
31+
Intel AMX enabling for kernels that support dynamic XSTATE features for
32+
userspace applications but not for KVM guests (e.g. kernel versions >= 5.16
33+
and < 5.17).
3034

3135
## [1.13.0]
3236

src/vmm/src/arch/x86_64/xstate.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
use vmm_sys_util::syscall::SyscallReturnCode;
55

6+
use crate::logger::info;
67
use crate::arch::x86_64::generated::arch_prctl;
78

89
const INTEL_AMX_MASK: u64 = 1u64 << arch_prctl::ARCH_XCOMP_TILEDATA;
@@ -33,7 +34,10 @@ pub fn request_dynamic_xstate_features() -> Result<(), XstateError> {
3334
match get_supported_xfeatures().map_err(XstateError::GetSupportedFeatures)? {
3435
Some(supported_xfeatures) => supported_xfeatures,
3536
// Exit early if dynamic XSTATE feature enabling is not supported on the kernel.
36-
None => return Ok(()),
37+
None => {
38+
info!("Dynamic XSTATE feature enabling is not supported.");
39+
return Ok(());
40+
},
3741
};
3842

3943
// Intel AMX's TILEDATA
@@ -86,14 +90,35 @@ fn get_supported_xfeatures() -> Result<Option<u64>, std::io::Error> {
8690
fn request_xfeature_permission(xfeature: u32) -> Result<(), std::io::Error> {
8791
// SAFETY: Safe because the third input (`addr`) is a valid `c_ulong` value.
8892
// https://man7.org/linux/man-pages/man2/arch_prctl.2.html
89-
SyscallReturnCode(unsafe {
93+
match SyscallReturnCode(unsafe {
9094
libc::syscall(
9195
libc::SYS_arch_prctl,
9296
arch_prctl::ARCH_REQ_XCOMP_GUEST_PERM as libc::c_ulong,
9397
xfeature as libc::c_ulong,
9498
)
9599
})
96100
.into_empty_result()
101+
{
102+
Ok(()) => Ok(()),
103+
// EINVAL is returned if the dynamic XSTATE feature enabling for "guest" is not supported
104+
// although that for "userspace application" is supported (e.g. kernel versions >= 5.16 and
105+
// < 5.17).
106+
// https://github.com/torvalds/linux/commit/980fe2fddcff21937c93532b4597c8ea450346c1
107+
//
108+
// Note that XFEATURE_MASK_XTILE (= XFEATURE_MASK_XTILE_DATA | XFEATURE_MASK_XTILE_CFG) was
109+
// also added to KVM_SUPPORTED_XCR0 in kernel v5.17. KVM_SUPPORTED_XCR0 is used to
110+
// initialize the guest-supported XCR0. Thus, KVM_GET_SUPPORTED_CPUID doesn't
111+
// return AMX-half-enabled state, where XTILE_CFG is set but XTILE_DATA is unset, on such
112+
// kernels.
113+
// https://github.com/torvalds/linux/commit/86aff7a4799286635efd94dab17b513544703cad
114+
// https://github.com/torvalds/linux/blame/f443e374ae131c168a065ea1748feac6b2e76613/arch/x86/kvm/x86.c#L8850-L8853
115+
// https://github.com/firecracker-microvm/firecracker/pull/5065
116+
Err(err) if err.raw_os_error() == Some(libc::EINVAL) => {
117+
info!("Dynamic XSTATE feature enabling is not supported for guest.");
118+
Ok(())
119+
},
120+
Err(err) => Err(err),
121+
}
97122
}
98123

99124
#[cfg(test)]

0 commit comments

Comments
 (0)