Commit 445ecdf7 authored by Jing Liu's avatar Jing Liu Committed by Paolo Bonzini

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: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarJing Liu <jing2.liu@intel.com>
Signed-off-by: default avatarYang Zhong <yang.zhong@intel.com>
Message-Id: <20220105123532.12586-5-yang.zhong@intel.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent cc04b6a2
...@@ -1687,6 +1687,10 @@ userspace capabilities, and with user requirements (for example, the ...@@ -1687,6 +1687,10 @@ userspace capabilities, and with user requirements (for example, the
user may wish to constrain cpuid to emulate older hardware, or for user may wish to constrain cpuid to emulate older hardware, or for
feature consistency across a cluster). feature consistency across a cluster).
Dynamically-enabled feature bits need to be requested with
``arch_prctl()`` before calling this ioctl. Feature bits that have not
been requested are excluded from the result.
Note that certain capabilities, such as KVM_CAP_X86_DISABLE_EXITS, may Note that certain capabilities, such as KVM_CAP_X86_DISABLE_EXITS, may
expose cpuid features (e.g. MONITOR) which are not supported by kvm in expose cpuid features (e.g. MONITOR) which are not supported by kvm in
its default configuration. If userspace enables such capabilities, it its default configuration. If userspace enables such capabilities, it
......
...@@ -815,11 +815,13 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) ...@@ -815,11 +815,13 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
goto out; goto out;
} }
break; break;
case 0xd: case 0xd: {
entry->eax &= supported_xcr0; u64 guest_perm = xstate_get_guest_group_perm();
entry->eax &= supported_xcr0 & guest_perm;
entry->ebx = xstate_required_size(supported_xcr0, false); entry->ebx = xstate_required_size(supported_xcr0, false);
entry->ecx = entry->ebx; entry->ecx = entry->ebx;
entry->edx &= supported_xcr0 >> 32; entry->edx &= (supported_xcr0 & guest_perm) >> 32;
if (!supported_xcr0) if (!supported_xcr0)
break; break;
...@@ -866,6 +868,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) ...@@ -866,6 +868,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
entry->edx = 0; entry->edx = 0;
} }
break; break;
}
case 0x12: case 0x12:
/* Intel SGX */ /* Intel SGX */
if (!kvm_cpu_cap_has(X86_FEATURE_SGX)) { if (!kvm_cpu_cap_has(X86_FEATURE_SGX)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment