diff options
author | Avi Kivity <avi@qumranet.com> | 2007-10-09 06:12:19 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2007-10-22 06:03:28 -0400 |
commit | 1b6269db3f83396c2fd2c8d0f3e0f37ac0e6ba05 (patch) | |
tree | a8e99f6f6690e2024b9a08096a61d884b57dc8bc | |
parent | 7f2145ad6f3e7060147a2a4c4db35c641ff61b5c (diff) |
KVM: VMX: Handle NMIs before enabling interrupts and preemption
This makes sure we handle NMI on the current cpu, and that we don't service
maskable interrupts before non-maskable ones.
Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r-- | drivers/kvm/vmx.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index 4f115a8e45ef..bcc1e398a976 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c | |||
@@ -1760,10 +1760,8 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
1760 | set_bit(irq / BITS_PER_LONG, &vcpu->irq_summary); | 1760 | set_bit(irq / BITS_PER_LONG, &vcpu->irq_summary); |
1761 | } | 1761 | } |
1762 | 1762 | ||
1763 | if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) { /* nmi */ | 1763 | if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) /* nmi */ |
1764 | asm ("int $2"); | 1764 | return 1; /* already handled by vmx_vcpu_run() */ |
1765 | return 1; | ||
1766 | } | ||
1767 | 1765 | ||
1768 | if (is_no_device(intr_info)) { | 1766 | if (is_no_device(intr_info)) { |
1769 | vmx_fpu_activate(vcpu); | 1767 | vmx_fpu_activate(vcpu); |
@@ -2196,6 +2194,7 @@ static void vmx_intr_assist(struct kvm_vcpu *vcpu) | |||
2196 | static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | 2194 | static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) |
2197 | { | 2195 | { |
2198 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 2196 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
2197 | u32 intr_info; | ||
2199 | 2198 | ||
2200 | /* | 2199 | /* |
2201 | * Loading guest fpu may have cleared host cr0.ts | 2200 | * Loading guest fpu may have cleared host cr0.ts |
@@ -2322,6 +2321,12 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
2322 | 2321 | ||
2323 | asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS)); | 2322 | asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS)); |
2324 | vmx->launched = 1; | 2323 | vmx->launched = 1; |
2324 | |||
2325 | intr_info = vmcs_read32(VM_EXIT_INTR_INFO); | ||
2326 | |||
2327 | /* We need to handle NMIs before interrupts are enabled */ | ||
2328 | if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) /* nmi */ | ||
2329 | asm("int $2"); | ||
2325 | } | 2330 | } |
2326 | 2331 | ||
2327 | static void vmx_inject_page_fault(struct kvm_vcpu *vcpu, | 2332 | static void vmx_inject_page_fault(struct kvm_vcpu *vcpu, |