diff options
-rw-r--r-- | arch/x86/kvm/vmx.c | 41 | ||||
-rw-r--r-- | include/asm-x86/kvm_host.h | 4 |
2 files changed, 43 insertions, 2 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 5c9dac567a74..2879880076d0 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -735,12 +735,30 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu) | |||
735 | static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, | 735 | static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, |
736 | bool has_error_code, u32 error_code) | 736 | bool has_error_code, u32 error_code) |
737 | { | 737 | { |
738 | struct vcpu_vmx *vmx = to_vmx(vcpu); | ||
739 | |||
740 | if (has_error_code) | ||
741 | vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code); | ||
742 | |||
743 | if (vcpu->arch.rmode.active) { | ||
744 | vmx->rmode.irq.pending = true; | ||
745 | vmx->rmode.irq.vector = nr; | ||
746 | vmx->rmode.irq.rip = kvm_rip_read(vcpu); | ||
747 | if (nr == BP_VECTOR) | ||
748 | vmx->rmode.irq.rip++; | ||
749 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, | ||
750 | nr | INTR_TYPE_SOFT_INTR | ||
751 | | (has_error_code ? INTR_INFO_DELIVER_CODE_MASK : 0) | ||
752 | | INTR_INFO_VALID_MASK); | ||
753 | vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); | ||
754 | kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1); | ||
755 | return; | ||
756 | } | ||
757 | |||
738 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, | 758 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, |
739 | nr | INTR_TYPE_EXCEPTION | 759 | nr | INTR_TYPE_EXCEPTION |
740 | | (has_error_code ? INTR_INFO_DELIVER_CODE_MASK : 0) | 760 | | (has_error_code ? INTR_INFO_DELIVER_CODE_MASK : 0) |
741 | | INTR_INFO_VALID_MASK); | 761 | | INTR_INFO_VALID_MASK); |
742 | if (has_error_code) | ||
743 | vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code); | ||
744 | } | 762 | } |
745 | 763 | ||
746 | static bool vmx_exception_injected(struct kvm_vcpu *vcpu) | 764 | static bool vmx_exception_injected(struct kvm_vcpu *vcpu) |
@@ -2231,6 +2249,25 @@ static int handle_rmode_exception(struct kvm_vcpu *vcpu, | |||
2231 | if (((vec == GP_VECTOR) || (vec == SS_VECTOR)) && err_code == 0) | 2249 | if (((vec == GP_VECTOR) || (vec == SS_VECTOR)) && err_code == 0) |
2232 | if (emulate_instruction(vcpu, NULL, 0, 0, 0) == EMULATE_DONE) | 2250 | if (emulate_instruction(vcpu, NULL, 0, 0, 0) == EMULATE_DONE) |
2233 | return 1; | 2251 | return 1; |
2252 | /* | ||
2253 | * Forward all other exceptions that are valid in real mode. | ||
2254 | * FIXME: Breaks guest debugging in real mode, needs to be fixed with | ||
2255 | * the required debugging infrastructure rework. | ||
2256 | */ | ||
2257 | switch (vec) { | ||
2258 | case DE_VECTOR: | ||
2259 | case DB_VECTOR: | ||
2260 | case BP_VECTOR: | ||
2261 | case OF_VECTOR: | ||
2262 | case BR_VECTOR: | ||
2263 | case UD_VECTOR: | ||
2264 | case DF_VECTOR: | ||
2265 | case SS_VECTOR: | ||
2266 | case GP_VECTOR: | ||
2267 | case MF_VECTOR: | ||
2268 | kvm_queue_exception(vcpu, vec); | ||
2269 | return 1; | ||
2270 | } | ||
2234 | return 0; | 2271 | return 0; |
2235 | } | 2272 | } |
2236 | 2273 | ||
diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index da3c1979b734..83afa10c77f5 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h | |||
@@ -58,6 +58,9 @@ | |||
58 | 58 | ||
59 | #define DE_VECTOR 0 | 59 | #define DE_VECTOR 0 |
60 | #define DB_VECTOR 1 | 60 | #define DB_VECTOR 1 |
61 | #define BP_VECTOR 3 | ||
62 | #define OF_VECTOR 4 | ||
63 | #define BR_VECTOR 5 | ||
61 | #define UD_VECTOR 6 | 64 | #define UD_VECTOR 6 |
62 | #define NM_VECTOR 7 | 65 | #define NM_VECTOR 7 |
63 | #define DF_VECTOR 8 | 66 | #define DF_VECTOR 8 |
@@ -66,6 +69,7 @@ | |||
66 | #define SS_VECTOR 12 | 69 | #define SS_VECTOR 12 |
67 | #define GP_VECTOR 13 | 70 | #define GP_VECTOR 13 |
68 | #define PF_VECTOR 14 | 71 | #define PF_VECTOR 14 |
72 | #define MF_VECTOR 16 | ||
69 | #define MC_VECTOR 18 | 73 | #define MC_VECTOR 18 |
70 | 74 | ||
71 | #define SELECTOR_TI_MASK (1 << 2) | 75 | #define SELECTOR_TI_MASK (1 << 2) |