kvm/svm: PKU not currently supported
commita47970ed74
upstream. Current SVM implementation does not have support for handling PKU. Guests running on a host with future AMD cpus that support the feature will read garbage from the PKRU register and will hit segmentation faults on boot as memory is getting marked as protected that should not be. Ensure that cpuid from SVM does not advertise the feature. Signed-off-by: John Allen <john.allen@amd.com> Cc: stable@vger.kernel.org Fixes:0556cbdc2f
("x86/pkeys: Don't check if PKRU is zero before writing it") Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
9213699efd
commit
d0671151c2
|
@ -1128,6 +1128,7 @@ struct kvm_x86_ops {
|
||||||
bool (*xsaves_supported)(void);
|
bool (*xsaves_supported)(void);
|
||||||
bool (*umip_emulated)(void);
|
bool (*umip_emulated)(void);
|
||||||
bool (*pt_supported)(void);
|
bool (*pt_supported)(void);
|
||||||
|
bool (*pku_supported)(void);
|
||||||
|
|
||||||
int (*check_nested_events)(struct kvm_vcpu *vcpu, bool external_intr);
|
int (*check_nested_events)(struct kvm_vcpu *vcpu, bool external_intr);
|
||||||
void (*request_immediate_exit)(struct kvm_vcpu *vcpu);
|
void (*request_immediate_exit)(struct kvm_vcpu *vcpu);
|
||||||
|
|
|
@ -352,6 +352,7 @@ static inline void do_cpuid_7_mask(struct kvm_cpuid_entry2 *entry, int index)
|
||||||
unsigned f_umip = kvm_x86_ops->umip_emulated() ? F(UMIP) : 0;
|
unsigned f_umip = kvm_x86_ops->umip_emulated() ? F(UMIP) : 0;
|
||||||
unsigned f_intel_pt = kvm_x86_ops->pt_supported() ? F(INTEL_PT) : 0;
|
unsigned f_intel_pt = kvm_x86_ops->pt_supported() ? F(INTEL_PT) : 0;
|
||||||
unsigned f_la57;
|
unsigned f_la57;
|
||||||
|
unsigned f_pku = kvm_x86_ops->pku_supported() ? F(PKU) : 0;
|
||||||
|
|
||||||
/* cpuid 7.0.ebx */
|
/* cpuid 7.0.ebx */
|
||||||
const u32 kvm_cpuid_7_0_ebx_x86_features =
|
const u32 kvm_cpuid_7_0_ebx_x86_features =
|
||||||
|
@ -363,7 +364,7 @@ static inline void do_cpuid_7_mask(struct kvm_cpuid_entry2 *entry, int index)
|
||||||
|
|
||||||
/* cpuid 7.0.ecx*/
|
/* cpuid 7.0.ecx*/
|
||||||
const u32 kvm_cpuid_7_0_ecx_x86_features =
|
const u32 kvm_cpuid_7_0_ecx_x86_features =
|
||||||
F(AVX512VBMI) | F(LA57) | F(PKU) | 0 /*OSPKE*/ | F(RDPID) |
|
F(AVX512VBMI) | F(LA57) | 0 /*PKU*/ | 0 /*OSPKE*/ | F(RDPID) |
|
||||||
F(AVX512_VPOPCNTDQ) | F(UMIP) | F(AVX512_VBMI2) | F(GFNI) |
|
F(AVX512_VPOPCNTDQ) | F(UMIP) | F(AVX512_VBMI2) | F(GFNI) |
|
||||||
F(VAES) | F(VPCLMULQDQ) | F(AVX512_VNNI) | F(AVX512_BITALG) |
|
F(VAES) | F(VPCLMULQDQ) | F(AVX512_VNNI) | F(AVX512_BITALG) |
|
||||||
F(CLDEMOTE) | F(MOVDIRI) | F(MOVDIR64B) | 0 /*WAITPKG*/;
|
F(CLDEMOTE) | F(MOVDIRI) | F(MOVDIR64B) | 0 /*WAITPKG*/;
|
||||||
|
@ -392,6 +393,7 @@ static inline void do_cpuid_7_mask(struct kvm_cpuid_entry2 *entry, int index)
|
||||||
/* Set LA57 based on hardware capability. */
|
/* Set LA57 based on hardware capability. */
|
||||||
entry->ecx |= f_la57;
|
entry->ecx |= f_la57;
|
||||||
entry->ecx |= f_umip;
|
entry->ecx |= f_umip;
|
||||||
|
entry->ecx |= f_pku;
|
||||||
/* PKU is not yet implemented for shadow paging. */
|
/* PKU is not yet implemented for shadow paging. */
|
||||||
if (!tdp_enabled || !boot_cpu_has(X86_FEATURE_OSPKE))
|
if (!tdp_enabled || !boot_cpu_has(X86_FEATURE_OSPKE))
|
||||||
entry->ecx &= ~F(PKU);
|
entry->ecx &= ~F(PKU);
|
||||||
|
|
|
@ -5986,6 +5986,11 @@ static bool svm_has_wbinvd_exit(void)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool svm_pku_supported(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#define PRE_EX(exit) { .exit_code = (exit), \
|
#define PRE_EX(exit) { .exit_code = (exit), \
|
||||||
.stage = X86_ICPT_PRE_EXCEPT, }
|
.stage = X86_ICPT_PRE_EXCEPT, }
|
||||||
#define POST_EX(exit) { .exit_code = (exit), \
|
#define POST_EX(exit) { .exit_code = (exit), \
|
||||||
|
@ -7278,6 +7283,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
|
||||||
.xsaves_supported = svm_xsaves_supported,
|
.xsaves_supported = svm_xsaves_supported,
|
||||||
.umip_emulated = svm_umip_emulated,
|
.umip_emulated = svm_umip_emulated,
|
||||||
.pt_supported = svm_pt_supported,
|
.pt_supported = svm_pt_supported,
|
||||||
|
.pku_supported = svm_pku_supported,
|
||||||
|
|
||||||
.set_supported_cpuid = svm_set_supported_cpuid,
|
.set_supported_cpuid = svm_set_supported_cpuid,
|
||||||
|
|
||||||
|
|
|
@ -145,6 +145,11 @@ static inline bool vmx_umip_emulated(void)
|
||||||
SECONDARY_EXEC_DESC;
|
SECONDARY_EXEC_DESC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool vmx_pku_supported(void)
|
||||||
|
{
|
||||||
|
return boot_cpu_has(X86_FEATURE_PKU);
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool cpu_has_vmx_rdtscp(void)
|
static inline bool cpu_has_vmx_rdtscp(void)
|
||||||
{
|
{
|
||||||
return vmcs_config.cpu_based_2nd_exec_ctrl &
|
return vmcs_config.cpu_based_2nd_exec_ctrl &
|
||||||
|
|
|
@ -7865,6 +7865,7 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = {
|
||||||
.xsaves_supported = vmx_xsaves_supported,
|
.xsaves_supported = vmx_xsaves_supported,
|
||||||
.umip_emulated = vmx_umip_emulated,
|
.umip_emulated = vmx_umip_emulated,
|
||||||
.pt_supported = vmx_pt_supported,
|
.pt_supported = vmx_pt_supported,
|
||||||
|
.pku_supported = vmx_pku_supported,
|
||||||
|
|
||||||
.request_immediate_exit = vmx_request_immediate_exit,
|
.request_immediate_exit = vmx_request_immediate_exit,
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue