Skip to content

Commit 49aa2c8

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 208c2e4 commit 49aa2c8

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,23 @@ fn get_supported_xfeatures() -> Result<Option<u64>, std::io::Error> {
8686
fn request_xfeature_permission(xfeature: u32) -> Result<(), std::io::Error> {
8787
// SAFETY: Safe because the third input (`addr`) is a valid `c_ulong` value.
8888
// https://man7.org/linux/man-pages/man2/arch_prctl.2.html
89-
SyscallReturnCode(unsafe {
89+
match SyscallReturnCode(unsafe {
9090
libc::syscall(
9191
libc::SYS_arch_prctl,
9292
arch_prctl::ARCH_REQ_XCOMP_GUEST_PERM as libc::c_ulong,
9393
xfeature as libc::c_ulong,
9494
)
9595
})
9696
.into_empty_result()
97+
{
98+
Ok(()) => Ok(()),
99+
// EINVAL is returned if the dynamic XSTATE feature enabling for "guest" is not supported
100+
// although that for "userspace application" is supported (e.g. kernel versions >= 5.16 and
101+
// < 5.17).
102+
// https://github.com/torvalds/linux/commit/980fe2fddcff21937c93532b4597c8ea450346c1
103+
Err(err) if err.raw_os_error() == Some(libc::EINVAL) => Ok(()),
104+
Err(err) => Err(err),
105+
}
97106
}
98107

99108
#[cfg(test)]

0 commit comments

Comments
 (0)