| From a47970ed74a535b1accb4bc73643fd5a93993c3e Mon Sep 17 00:00:00 2001 |
| From: John Allen <john.allen@amd.com> |
| Date: Thu, 19 Dec 2019 14:17:59 -0600 |
| Subject: kvm/svm: PKU not currently supported |
| |
| From: John Allen <john.allen@amd.com> |
| |
| commit a47970ed74a535b1accb4bc73643fd5a93993c3e 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: 0556cbdc2fbc ("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> |
| |
| --- |
| arch/x86/include/asm/kvm_host.h | 1 + |
| arch/x86/kvm/cpuid.c | 4 +++- |
| arch/x86/kvm/svm.c | 6 ++++++ |
| arch/x86/kvm/vmx/capabilities.h | 5 +++++ |
| arch/x86/kvm/vmx/vmx.c | 1 + |
| 5 files changed, 16 insertions(+), 1 deletion(-) |
| |
| --- a/arch/x86/include/asm/kvm_host.h |
| +++ b/arch/x86/include/asm/kvm_host.h |
| @@ -1145,6 +1145,7 @@ struct kvm_x86_ops { |
| bool (*xsaves_supported)(void); |
| bool (*umip_emulated)(void); |
| bool (*pt_supported)(void); |
| + bool (*pku_supported)(void); |
| |
| int (*check_nested_events)(struct kvm_vcpu *vcpu, bool external_intr); |
| void (*request_immediate_exit)(struct kvm_vcpu *vcpu); |
| --- a/arch/x86/kvm/cpuid.c |
| +++ b/arch/x86/kvm/cpuid.c |
| @@ -352,6 +352,7 @@ static inline void do_cpuid_7_mask(struc |
| 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_la57; |
| + unsigned f_pku = kvm_x86_ops->pku_supported() ? F(PKU) : 0; |
| |
| /* cpuid 7.0.ebx */ |
| const u32 kvm_cpuid_7_0_ebx_x86_features = |
| @@ -363,7 +364,7 @@ static inline void do_cpuid_7_mask(struc |
| |
| /* cpuid 7.0.ecx*/ |
| 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(VAES) | F(VPCLMULQDQ) | F(AVX512_VNNI) | F(AVX512_BITALG) | |
| F(CLDEMOTE) | F(MOVDIRI) | F(MOVDIR64B) | 0 /*WAITPKG*/; |
| @@ -392,6 +393,7 @@ static inline void do_cpuid_7_mask(struc |
| /* Set LA57 based on hardware capability. */ |
| entry->ecx |= f_la57; |
| entry->ecx |= f_umip; |
| + entry->ecx |= f_pku; |
| /* PKU is not yet implemented for shadow paging. */ |
| if (!tdp_enabled || !boot_cpu_has(X86_FEATURE_OSPKE)) |
| entry->ecx &= ~F(PKU); |
| --- a/arch/x86/kvm/svm.c |
| +++ b/arch/x86/kvm/svm.c |
| @@ -6001,6 +6001,11 @@ static bool svm_has_wbinvd_exit(void) |
| return true; |
| } |
| |
| +static bool svm_pku_supported(void) |
| +{ |
| + return false; |
| +} |
| + |
| #define PRE_EX(exit) { .exit_code = (exit), \ |
| .stage = X86_ICPT_PRE_EXCEPT, } |
| #define POST_EX(exit) { .exit_code = (exit), \ |
| @@ -7341,6 +7346,7 @@ static struct kvm_x86_ops svm_x86_ops __ |
| .xsaves_supported = svm_xsaves_supported, |
| .umip_emulated = svm_umip_emulated, |
| .pt_supported = svm_pt_supported, |
| + .pku_supported = svm_pku_supported, |
| |
| .set_supported_cpuid = svm_set_supported_cpuid, |
| |
| --- a/arch/x86/kvm/vmx/capabilities.h |
| +++ b/arch/x86/kvm/vmx/capabilities.h |
| @@ -145,6 +145,11 @@ static inline bool vmx_umip_emulated(voi |
| 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) |
| { |
| return vmcs_config.cpu_based_2nd_exec_ctrl & |
| --- a/arch/x86/kvm/vmx/vmx.c |
| +++ b/arch/x86/kvm/vmx/vmx.c |
| @@ -7870,6 +7870,7 @@ static struct kvm_x86_ops vmx_x86_ops __ |
| .xsaves_supported = vmx_xsaves_supported, |
| .umip_emulated = vmx_umip_emulated, |
| .pt_supported = vmx_pt_supported, |
| + .pku_supported = vmx_pku_supported, |
| |
| .request_immediate_exit = vmx_request_immediate_exit, |
| |