|
4 | 4 | use vmm_sys_util::syscall::SyscallReturnCode;
|
5 | 5 |
|
6 | 6 | use crate::arch::x86_64::generated::arch_prctl;
|
| 7 | +use crate::logger::info; |
7 | 8 |
|
8 | 9 | const INTEL_AMX_MASK: u64 = 1u64 << arch_prctl::ARCH_XCOMP_TILEDATA;
|
9 | 10 |
|
@@ -72,28 +73,55 @@ fn get_supported_xfeatures() -> Result<Option<u64>, std::io::Error> {
|
72 | 73 | {
|
73 | 74 | Ok(()) => Ok(Some(supported_xfeatures)),
|
74 | 75 | // 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). |
76 | 77 | // 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 | + } |
78 | 82 | Err(err) => Err(err),
|
79 | 83 | }
|
80 | 84 | }
|
81 | 85 |
|
82 | 86 | /// Request permission for a dynamic XSTATE feature.
|
83 | 87 | ///
|
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. |
86 | 93 | fn request_xfeature_permission(xfeature: u32) -> Result<(), std::io::Error> {
|
87 | 94 | // SAFETY: Safe because the third input (`addr`) is a valid `c_ulong` value.
|
88 | 95 | // https://man7.org/linux/man-pages/man2/arch_prctl.2.html
|
89 |
| - SyscallReturnCode(unsafe { |
| 96 | + match SyscallReturnCode(unsafe { |
90 | 97 | libc::syscall(
|
91 | 98 | libc::SYS_arch_prctl,
|
92 | 99 | arch_prctl::ARCH_REQ_XCOMP_GUEST_PERM as libc::c_ulong,
|
93 | 100 | xfeature as libc::c_ulong,
|
94 | 101 | )
|
95 | 102 | })
|
96 | 103 | .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 | + } |
97 | 125 | }
|
98 | 126 |
|
99 | 127 | #[cfg(test)]
|
|
0 commit comments