diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2010-02-24 12:59:12 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-04-25 06:53:04 -0400 |
commit | 887f500ca1a721cac237ba56374b9c0f578251ec (patch) | |
tree | 26d5411d7d4ae0144d32f0da8921f888e8b495e0 /arch/x86/kvm/svm.c | |
parent | 0e5cbe368b366f02cf3fe707aea2c0efac1bf70e (diff) |
KVM: SVM: Check for nested intercepts on NMI injection
This patch implements the NMI intercept checking for nested
svm.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/svm.c')
-rw-r--r-- | arch/x86/kvm/svm.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index ef40b90219f6..9f1143105e00 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -1486,6 +1486,21 @@ static inline bool nested_svm_intr(struct vcpu_svm *svm) | |||
1486 | return true; | 1486 | return true; |
1487 | } | 1487 | } |
1488 | 1488 | ||
1489 | /* This function returns true if it is save to enable the nmi window */ | ||
1490 | static inline bool nested_svm_nmi(struct vcpu_svm *svm) | ||
1491 | { | ||
1492 | if (!is_nested(svm)) | ||
1493 | return true; | ||
1494 | |||
1495 | if (!(svm->nested.intercept & (1ULL << INTERCEPT_NMI))) | ||
1496 | return true; | ||
1497 | |||
1498 | svm->vmcb->control.exit_code = SVM_EXIT_NMI; | ||
1499 | svm->nested.exit_required = true; | ||
1500 | |||
1501 | return false; | ||
1502 | } | ||
1503 | |||
1489 | static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, struct page **_page) | 1504 | static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, struct page **_page) |
1490 | { | 1505 | { |
1491 | struct page *page; | 1506 | struct page *page; |
@@ -2687,9 +2702,11 @@ static void enable_nmi_window(struct kvm_vcpu *vcpu) | |||
2687 | * Something prevents NMI from been injected. Single step over possible | 2702 | * Something prevents NMI from been injected. Single step over possible |
2688 | * problem (IRET or exception injection or interrupt shadow) | 2703 | * problem (IRET or exception injection or interrupt shadow) |
2689 | */ | 2704 | */ |
2690 | svm->nmi_singlestep = true; | 2705 | if (gif_set(svm) && nested_svm_nmi(svm)) { |
2691 | svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF); | 2706 | svm->nmi_singlestep = true; |
2692 | update_db_intercept(vcpu); | 2707 | svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF); |
2708 | update_db_intercept(vcpu); | ||
2709 | } | ||
2693 | } | 2710 | } |
2694 | 2711 | ||
2695 | static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr) | 2712 | static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr) |