aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/svm.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kvm/svm.c')
-rw-r--r--arch/x86/kvm/svm.c32
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
7101static 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
7101static struct kvm_x86_ops svm_x86_ops __ro_after_init = { 7131static 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
7236static int __init svm_init(void) 7268static int __init svm_init(void)