|
3 | 3 |
|
4 | 4 | use vmm_sys_util::syscall::SyscallReturnCode;
|
5 | 5 |
|
| 6 | +use crate::logger::info; |
6 | 7 | use crate::arch::x86_64::generated::arch_prctl;
|
7 | 8 |
|
8 | 9 | const INTEL_AMX_MASK: u64 = 1u64 << arch_prctl::ARCH_XCOMP_TILEDATA;
|
@@ -33,7 +34,10 @@ pub fn request_dynamic_xstate_features() -> Result<(), XstateError> {
|
33 | 34 | match get_supported_xfeatures().map_err(XstateError::GetSupportedFeatures)? {
|
34 | 35 | Some(supported_xfeatures) => supported_xfeatures,
|
35 | 36 | // 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 | + }, |
37 | 41 | };
|
38 | 42 |
|
39 | 43 | // Intel AMX's TILEDATA
|
@@ -86,14 +90,35 @@ fn get_supported_xfeatures() -> Result<Option<u64>, std::io::Error> {
|
86 | 90 | fn request_xfeature_permission(xfeature: u32) -> Result<(), std::io::Error> {
|
87 | 91 | // SAFETY: Safe because the third input (`addr`) is a valid `c_ulong` value.
|
88 | 92 | // https://man7.org/linux/man-pages/man2/arch_prctl.2.html
|
89 |
| - SyscallReturnCode(unsafe { |
| 93 | + match SyscallReturnCode(unsafe { |
90 | 94 | libc::syscall(
|
91 | 95 | libc::SYS_arch_prctl,
|
92 | 96 | arch_prctl::ARCH_REQ_XCOMP_GUEST_PERM as libc::c_ulong,
|
93 | 97 | xfeature as libc::c_ulong,
|
94 | 98 | )
|
95 | 99 | })
|
96 | 100 | .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 | + } |
97 | 122 | }
|
98 | 123 |
|
99 | 124 | #[cfg(test)]
|
|
0 commit comments