]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
kvm/svm: PKU not currently supported
authorJohn Allen <john.allen@amd.com>
Thu, 19 Dec 2019 20:17:59 +0000 (14:17 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 11 Feb 2020 12:35:40 +0000 (04:35 -0800)
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
arch/x86/kvm/cpuid.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx/capabilities.h
arch/x86/kvm/vmx/vmx.c

index 4fc61483919aae8acb84d47b4c316b33c5d13618..17b93f54ee432deb5094a6a91dc888f7edbd7e9f 100644 (file)
@@ -1128,6 +1128,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);
index b1d5a8c94a57b5a5b0178b0c6c5a44570db4a11e..6fa946f983c921afc08c3c4ea18dd6a67d0ab8de 100644 (file)
@@ -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_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(struct kvm_cpuid_entry2 *entry, int index)
 
        /* 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(struct kvm_cpuid_entry2 *entry, int index)
                /* 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);
index c5673bda4b66df5e7672abc78e5bf520b3c3361c..8d1be7c61f109407026117797e64d096db438374 100644 (file)
@@ -5986,6 +5986,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), \
@@ -7278,6 +7283,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
        .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,
 
index 7aa69716d5160421c388154d83db11e15a494606..283bdb7071af604453e081f30baec3bcdd938dac 100644 (file)
@@ -145,6 +145,11 @@ static inline bool vmx_umip_emulated(void)
                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 &
index f09a213fd5cbb966c4eed183633be0b1b132c19e..731651da9af556d55ddb073f97b9635764d6b049 100644 (file)
@@ -7865,6 +7865,7 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = {
        .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,