diff options
author | Jing Liu <jing2.liu@intel.com> | 2022-01-05 13:35:15 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2022-01-07 19:33:04 +0100 |
commit | 445ecdf79be0c71ca248f7611aeefceaea3ec59f (patch) | |
tree | de6de4d866343a9cddb7e1f0715e359f587eb211 /arch/x86/kvm/cpuid.c | |
parent | kvm: x86: Fix xstate_required_size() to follow XSTATE alignment rule (diff) | |
download | linux-445ecdf79be0c71ca248f7611aeefceaea3ec59f.tar.xz linux-445ecdf79be0c71ca248f7611aeefceaea3ec59f.zip |
kvm: x86: Exclude unpermitted xfeatures at KVM_GET_SUPPORTED_CPUID
KVM_GET_SUPPORTED_CPUID should not include any dynamic xstates in
CPUID[0xD] if they have not been requested with prctl. Otherwise
a process which directly passes KVM_GET_SUPPORTED_CPUID to
KVM_SET_CPUID2 would now fail even if it doesn't intend to use a
dynamically enabled feature. Userspace must know that prctl is
required and allocate >4K xstate buffer before setting any dynamic
bit.
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Jing Liu <jing2.liu@intel.com>
Signed-off-by: Yang Zhong <yang.zhong@intel.com>
Message-Id: <20220105123532.12586-5-yang.zhong@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm/cpuid.c')
-rw-r--r-- | arch/x86/kvm/cpuid.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index f3e6fda6b858..eb52dde5deec 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -815,11 +815,13 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) goto out; } break; - case 0xd: - entry->eax &= supported_xcr0; + case 0xd: { + u64 guest_perm = xstate_get_guest_group_perm(); + + entry->eax &= supported_xcr0 & guest_perm; entry->ebx = xstate_required_size(supported_xcr0, false); entry->ecx = entry->ebx; - entry->edx &= supported_xcr0 >> 32; + entry->edx &= (supported_xcr0 & guest_perm) >> 32; if (!supported_xcr0) break; @@ -866,6 +868,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) entry->edx = 0; } break; + } case 0x12: /* Intel SGX */ if (!kvm_cpu_cap_has(X86_FEATURE_SGX)) { |