aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/vmx.c41
-rw-r--r--include/asm-x86/kvm_host.h4
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)
735static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, 735static 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
746static bool vmx_exception_injected(struct kvm_vcpu *vcpu) 764static 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)