diff options
Diffstat (limited to 'arch/x86/kvm/svm.c')
-rw-r--r-- | arch/x86/kvm/svm.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index b5b128a0a051..426039285fd1 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -7098,6 +7098,36 @@ static int nested_enable_evmcs(struct kvm_vcpu *vcpu, | |||
7098 | return -ENODEV; | 7098 | return -ENODEV; |
7099 | } | 7099 | } |
7100 | 7100 | ||
7101 | static bool svm_need_emulation_on_page_fault(struct kvm_vcpu *vcpu) | ||
7102 | { | ||
7103 | bool is_user, smap; | ||
7104 | |||
7105 | is_user = svm_get_cpl(vcpu) == 3; | ||
7106 | smap = !kvm_read_cr4_bits(vcpu, X86_CR4_SMAP); | ||
7107 | |||
7108 | /* | ||
7109 | * Detect and workaround Errata 1096 Fam_17h_00_0Fh | ||
7110 | * | ||
7111 | * In non SEV guest, hypervisor will be able to read the guest | ||
7112 | * memory to decode the instruction pointer when insn_len is zero | ||
7113 | * so we return true to indicate that decoding is possible. | ||
7114 | * | ||
7115 | * But in the SEV guest, the guest memory is encrypted with the | ||
7116 | * guest specific key and hypervisor will not be able to decode the | ||
7117 | * instruction pointer so we will not able to workaround it. Lets | ||
7118 | * print the error and request to kill the guest. | ||
7119 | */ | ||
7120 | if (is_user && smap) { | ||
7121 | if (!sev_guest(vcpu->kvm)) | ||
7122 | return true; | ||
7123 | |||
7124 | pr_err_ratelimited("KVM: Guest triggered AMD Erratum 1096\n"); | ||
7125 | kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu); | ||
7126 | } | ||
7127 | |||
7128 | return false; | ||
7129 | } | ||
7130 | |||
7101 | static struct kvm_x86_ops svm_x86_ops __ro_after_init = { | 7131 | static struct kvm_x86_ops svm_x86_ops __ro_after_init = { |
7102 | .cpu_has_kvm_support = has_svm, | 7132 | .cpu_has_kvm_support = has_svm, |
7103 | .disabled_by_bios = is_disabled, | 7133 | .disabled_by_bios = is_disabled, |
@@ -7231,6 +7261,8 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = { | |||
7231 | 7261 | ||
7232 | .nested_enable_evmcs = nested_enable_evmcs, | 7262 | .nested_enable_evmcs = nested_enable_evmcs, |
7233 | .nested_get_evmcs_version = nested_get_evmcs_version, | 7263 | .nested_get_evmcs_version = nested_get_evmcs_version, |
7264 | |||
7265 | .need_emulation_on_page_fault = svm_need_emulation_on_page_fault, | ||
7234 | }; | 7266 | }; |
7235 | 7267 | ||
7236 | static int __init svm_init(void) | 7268 | static int __init svm_init(void) |