Skip to content

Commit 977402c

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 977402c

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
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: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use vmm_sys_util::syscall::SyscallReturnCode;
55

66
use crate::arch::x86_64::generated::arch_prctl;
7+
use crate::logger::info;
78

89
const INTEL_AMX_MASK: u64 = 1u64 << arch_prctl::ARCH_XCOMP_TILEDATA;
910

@@ -72,28 +73,55 @@ fn get_supported_xfeatures() -> Result<Option<u64>, std::io::Error> {
7273
{
7374
Ok(()) => Ok(Some(supported_xfeatures)),
7475
// EINVAL is returned if the dynamic XSTATE feature enabling is not supported (e.g. kernel
75-
// version prior to v5.17).
76+
// version prior to v5.16).
7677
// https://github.com/torvalds/linux/commit/db8268df0983adc2bb1fb48c9e5f7bfbb5f617f3
77-
Err(err) if err.raw_os_error() == Some(libc::EINVAL) => Ok(None),
78+
Err(err) if err.raw_os_error() == Some(libc::EINVAL) => {
79+
info!("Dynamic XSTATE feature enabling is not supported.");
80+
Ok(None)
81+
}
7882
Err(err) => Err(err),
7983
}
8084
}
8185

8286
/// Request permission for a dynamic XSTATE feature.
8387
///
84-
/// This should be called after `get_supported_xfeatures()` that also checks that dynamic XSTATE
85-
/// feature enabling is supported.
88+
/// This should be called after `get_supported_xfeatures()` that retrieves supported dynamic XSTATE
89+
/// features.
90+
///
91+
/// Returns Ok(()) if the permission request succeeded or dynamic XSTATE feature enabling for
92+
/// "guest" is not supported.
8693
fn request_xfeature_permission(xfeature: u32) -> Result<(), std::io::Error> {
8794
// SAFETY: Safe because the third input (`addr`) is a valid `c_ulong` value.
8895
// https://man7.org/linux/man-pages/man2/arch_prctl.2.html
89-
SyscallReturnCode(unsafe {
96+
match SyscallReturnCode(unsafe {
9097
libc::syscall(
9198
libc::SYS_arch_prctl,
9299
arch_prctl::ARCH_REQ_XCOMP_GUEST_PERM as libc::c_ulong,
93100
xfeature as libc::c_ulong,
94101
)
95102
})
96103
.into_empty_result()
104+
{
105+
Ok(()) => Ok(()),
106+
// EINVAL is returned if the dynamic XSTATE feature enabling for "guest" is not supported
107+
// although that for "userspace application" is supported (e.g. kernel versions >= 5.16 and
108+
// < 5.17).
109+
// https://github.com/torvalds/linux/commit/980fe2fddcff21937c93532b4597c8ea450346c1
110+
//
111+
// Note that XFEATURE_MASK_XTILE (= XFEATURE_MASK_XTILE_DATA | XFEATURE_MASK_XTILE_CFG) was
112+
// also added to KVM_SUPPORTED_XCR0 in kernel v5.17. KVM_SUPPORTED_XCR0 is used to
113+
// initialize the guest-supported XCR0. Thus, KVM_GET_SUPPORTED_CPUID doesn't
114+
// return AMX-half-enabled state, where XTILE_CFG is set but XTILE_DATA is unset, on such
115+
// kernels.
116+
// https://github.com/torvalds/linux/commit/86aff7a4799286635efd94dab17b513544703cad
117+
// https://github.com/torvalds/linux/blame/f443e374ae131c168a065ea1748feac6b2e76613/arch/x86/kvm/x86.c#L8850-L8853
118+
// https://github.com/firecracker-microvm/firecracker/pull/5065
119+
Err(err) if err.raw_os_error() == Some(libc::EINVAL) => {
120+
info!("Dynamic XSTATE feature enabling is not supported for guest.");
121+
Ok(())
122+
}
123+
Err(err) => Err(err),
124+
}
97125
}
98126

99127
#[cfg(test)]

0 commit comments

Comments
 (0)