diff options
-rw-r--r-- | arch/ia64/include/asm/kvm.h | 7 | ||||
-rw-r--r-- | arch/ia64/kvm/kvm-ia64.c | 4 | ||||
-rw-r--r-- | arch/powerpc/include/asm/kvm.h | 7 | ||||
-rw-r--r-- | arch/powerpc/kvm/powerpc.c | 4 | ||||
-rw-r--r-- | arch/s390/include/asm/kvm.h | 7 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 4 | ||||
-rw-r--r-- | arch/x86/include/asm/kvm.h | 18 | ||||
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 9 | ||||
-rw-r--r-- | arch/x86/kvm/svm.c | 50 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 93 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 14 | ||||
-rw-r--r-- | include/linux/kvm.h | 51 | ||||
-rw-r--r-- | include/linux/kvm_host.h | 6 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 6 |
14 files changed, 179 insertions, 101 deletions
diff --git a/arch/ia64/include/asm/kvm.h b/arch/ia64/include/asm/kvm.h index bfa86b6af7cd..be3fdb891214 100644 --- a/arch/ia64/include/asm/kvm.h +++ b/arch/ia64/include/asm/kvm.h | |||
@@ -214,4 +214,11 @@ struct kvm_sregs { | |||
214 | struct kvm_fpu { | 214 | struct kvm_fpu { |
215 | }; | 215 | }; |
216 | 216 | ||
217 | struct kvm_debug_exit_arch { | ||
218 | }; | ||
219 | |||
220 | /* for KVM_SET_GUEST_DEBUG */ | ||
221 | struct kvm_guest_debug_arch { | ||
222 | }; | ||
223 | |||
217 | #endif | 224 | #endif |
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 28f982045f29..de47467a0e61 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
@@ -1303,8 +1303,8 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) | |||
1303 | return -EINVAL; | 1303 | return -EINVAL; |
1304 | } | 1304 | } |
1305 | 1305 | ||
1306 | int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, | 1306 | int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, |
1307 | struct kvm_debug_guest *dbg) | 1307 | struct kvm_guest_debug *dbg) |
1308 | { | 1308 | { |
1309 | return -EINVAL; | 1309 | return -EINVAL; |
1310 | } | 1310 | } |
diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h index f993e4198d5c..755f1b1948c5 100644 --- a/arch/powerpc/include/asm/kvm.h +++ b/arch/powerpc/include/asm/kvm.h | |||
@@ -52,4 +52,11 @@ struct kvm_fpu { | |||
52 | __u64 fpr[32]; | 52 | __u64 fpr[32]; |
53 | }; | 53 | }; |
54 | 54 | ||
55 | struct kvm_debug_exit_arch { | ||
56 | }; | ||
57 | |||
58 | /* for KVM_SET_GUEST_DEBUG */ | ||
59 | struct kvm_guest_debug_arch { | ||
60 | }; | ||
61 | |||
55 | #endif /* __LINUX_KVM_POWERPC_H */ | 62 | #endif /* __LINUX_KVM_POWERPC_H */ |
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 5f81256287f5..7c2ad4017d6a 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -240,8 +240,8 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | |||
240 | kvmppc_core_vcpu_put(vcpu); | 240 | kvmppc_core_vcpu_put(vcpu); |
241 | } | 241 | } |
242 | 242 | ||
243 | int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, | 243 | int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, |
244 | struct kvm_debug_guest *dbg) | 244 | struct kvm_guest_debug *dbg) |
245 | { | 245 | { |
246 | int i; | 246 | int i; |
247 | 247 | ||
diff --git a/arch/s390/include/asm/kvm.h b/arch/s390/include/asm/kvm.h index e1f54654e3ae..0b2f829f6d50 100644 --- a/arch/s390/include/asm/kvm.h +++ b/arch/s390/include/asm/kvm.h | |||
@@ -42,4 +42,11 @@ struct kvm_fpu { | |||
42 | __u64 fprs[16]; | 42 | __u64 fprs[16]; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | struct kvm_debug_exit_arch { | ||
46 | }; | ||
47 | |||
48 | /* for KVM_SET_GUEST_DEBUG */ | ||
49 | struct kvm_guest_debug_arch { | ||
50 | }; | ||
51 | |||
45 | #endif | 52 | #endif |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 0d33893e1e89..cbfe91e10120 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -422,8 +422,8 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, | |||
422 | return -EINVAL; /* not implemented yet */ | 422 | return -EINVAL; /* not implemented yet */ |
423 | } | 423 | } |
424 | 424 | ||
425 | int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, | 425 | int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, |
426 | struct kvm_debug_guest *dbg) | 426 | struct kvm_guest_debug *dbg) |
427 | { | 427 | { |
428 | return -EINVAL; /* not implemented yet */ | 428 | return -EINVAL; /* not implemented yet */ |
429 | } | 429 | } |
diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h index 886c9402ec45..32eb96c7ca27 100644 --- a/arch/x86/include/asm/kvm.h +++ b/arch/x86/include/asm/kvm.h | |||
@@ -212,6 +212,24 @@ struct kvm_pit_channel_state { | |||
212 | __s64 count_load_time; | 212 | __s64 count_load_time; |
213 | }; | 213 | }; |
214 | 214 | ||
215 | struct kvm_debug_exit_arch { | ||
216 | __u32 exception; | ||
217 | __u32 pad; | ||
218 | __u64 pc; | ||
219 | __u64 dr6; | ||
220 | __u64 dr7; | ||
221 | }; | ||
222 | |||
223 | #define KVM_GUESTDBG_USE_SW_BP 0x00010000 | ||
224 | #define KVM_GUESTDBG_USE_HW_BP 0x00020000 | ||
225 | #define KVM_GUESTDBG_INJECT_DB 0x00040000 | ||
226 | #define KVM_GUESTDBG_INJECT_BP 0x00080000 | ||
227 | |||
228 | /* for KVM_SET_GUEST_DEBUG */ | ||
229 | struct kvm_guest_debug_arch { | ||
230 | __u64 debugreg[8]; | ||
231 | }; | ||
232 | |||
215 | struct kvm_pit_state { | 233 | struct kvm_pit_state { |
216 | struct kvm_pit_channel_state channels[3]; | 234 | struct kvm_pit_channel_state channels[3]; |
217 | }; | 235 | }; |
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 53779309514a..c430cd580ee2 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -135,12 +135,6 @@ enum { | |||
135 | 135 | ||
136 | #define KVM_NR_MEM_OBJS 40 | 136 | #define KVM_NR_MEM_OBJS 40 |
137 | 137 | ||
138 | struct kvm_guest_debug { | ||
139 | int enabled; | ||
140 | unsigned long bp[4]; | ||
141 | int singlestep; | ||
142 | }; | ||
143 | |||
144 | /* | 138 | /* |
145 | * We don't want allocation failures within the mmu code, so we preallocate | 139 | * We don't want allocation failures within the mmu code, so we preallocate |
146 | * enough memory for a single page fault in a cache. | 140 | * enough memory for a single page fault in a cache. |
@@ -448,8 +442,7 @@ struct kvm_x86_ops { | |||
448 | void (*vcpu_put)(struct kvm_vcpu *vcpu); | 442 | void (*vcpu_put)(struct kvm_vcpu *vcpu); |
449 | 443 | ||
450 | int (*set_guest_debug)(struct kvm_vcpu *vcpu, | 444 | int (*set_guest_debug)(struct kvm_vcpu *vcpu, |
451 | struct kvm_debug_guest *dbg); | 445 | struct kvm_guest_debug *dbg); |
452 | void (*guest_debug_pre)(struct kvm_vcpu *vcpu); | ||
453 | int (*get_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata); | 446 | int (*get_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata); |
454 | int (*set_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 data); | 447 | int (*set_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 data); |
455 | u64 (*get_segment_base)(struct kvm_vcpu *vcpu, int seg); | 448 | u64 (*get_segment_base)(struct kvm_vcpu *vcpu, int seg); |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 0fbbde54ecae..88d9062f4545 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -968,9 +968,32 @@ static void svm_set_segment(struct kvm_vcpu *vcpu, | |||
968 | 968 | ||
969 | } | 969 | } |
970 | 970 | ||
971 | static int svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg) | 971 | static int svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg) |
972 | { | 972 | { |
973 | return -EOPNOTSUPP; | 973 | int old_debug = vcpu->guest_debug; |
974 | struct vcpu_svm *svm = to_svm(vcpu); | ||
975 | |||
976 | vcpu->guest_debug = dbg->control; | ||
977 | |||
978 | svm->vmcb->control.intercept_exceptions &= | ||
979 | ~((1 << DB_VECTOR) | (1 << BP_VECTOR)); | ||
980 | if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) { | ||
981 | if (vcpu->guest_debug & | ||
982 | (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) | ||
983 | svm->vmcb->control.intercept_exceptions |= | ||
984 | 1 << DB_VECTOR; | ||
985 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) | ||
986 | svm->vmcb->control.intercept_exceptions |= | ||
987 | 1 << BP_VECTOR; | ||
988 | } else | ||
989 | vcpu->guest_debug = 0; | ||
990 | |||
991 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) | ||
992 | svm->vmcb->save.rflags |= X86_EFLAGS_TF | X86_EFLAGS_RF; | ||
993 | else if (old_debug & KVM_GUESTDBG_SINGLESTEP) | ||
994 | svm->vmcb->save.rflags &= ~(X86_EFLAGS_TF | X86_EFLAGS_RF); | ||
995 | |||
996 | return 0; | ||
974 | } | 997 | } |
975 | 998 | ||
976 | static int svm_get_irq(struct kvm_vcpu *vcpu) | 999 | static int svm_get_irq(struct kvm_vcpu *vcpu) |
@@ -1094,6 +1117,27 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | |||
1094 | return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code); | 1117 | return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code); |
1095 | } | 1118 | } |
1096 | 1119 | ||
1120 | static int db_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | ||
1121 | { | ||
1122 | if (!(svm->vcpu.guest_debug & | ||
1123 | (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) { | ||
1124 | kvm_queue_exception(&svm->vcpu, DB_VECTOR); | ||
1125 | return 1; | ||
1126 | } | ||
1127 | kvm_run->exit_reason = KVM_EXIT_DEBUG; | ||
1128 | kvm_run->debug.arch.pc = svm->vmcb->save.cs.base + svm->vmcb->save.rip; | ||
1129 | kvm_run->debug.arch.exception = DB_VECTOR; | ||
1130 | return 0; | ||
1131 | } | ||
1132 | |||
1133 | static int bp_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | ||
1134 | { | ||
1135 | kvm_run->exit_reason = KVM_EXIT_DEBUG; | ||
1136 | kvm_run->debug.arch.pc = svm->vmcb->save.cs.base + svm->vmcb->save.rip; | ||
1137 | kvm_run->debug.arch.exception = BP_VECTOR; | ||
1138 | return 0; | ||
1139 | } | ||
1140 | |||
1097 | static int ud_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | 1141 | static int ud_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) |
1098 | { | 1142 | { |
1099 | int er; | 1143 | int er; |
@@ -2050,6 +2094,8 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm, | |||
2050 | [SVM_EXIT_WRITE_DR3] = emulate_on_interception, | 2094 | [SVM_EXIT_WRITE_DR3] = emulate_on_interception, |
2051 | [SVM_EXIT_WRITE_DR5] = emulate_on_interception, | 2095 | [SVM_EXIT_WRITE_DR5] = emulate_on_interception, |
2052 | [SVM_EXIT_WRITE_DR7] = emulate_on_interception, | 2096 | [SVM_EXIT_WRITE_DR7] = emulate_on_interception, |
2097 | [SVM_EXIT_EXCP_BASE + DB_VECTOR] = db_interception, | ||
2098 | [SVM_EXIT_EXCP_BASE + BP_VECTOR] = bp_interception, | ||
2053 | [SVM_EXIT_EXCP_BASE + UD_VECTOR] = ud_interception, | 2099 | [SVM_EXIT_EXCP_BASE + UD_VECTOR] = ud_interception, |
2054 | [SVM_EXIT_EXCP_BASE + PF_VECTOR] = pf_interception, | 2100 | [SVM_EXIT_EXCP_BASE + PF_VECTOR] = pf_interception, |
2055 | [SVM_EXIT_EXCP_BASE + NM_VECTOR] = nm_interception, | 2101 | [SVM_EXIT_EXCP_BASE + NM_VECTOR] = nm_interception, |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 1d974c1eaa7d..f55690ddb3ac 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -480,8 +480,13 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu) | |||
480 | eb = (1u << PF_VECTOR) | (1u << UD_VECTOR); | 480 | eb = (1u << PF_VECTOR) | (1u << UD_VECTOR); |
481 | if (!vcpu->fpu_active) | 481 | if (!vcpu->fpu_active) |
482 | eb |= 1u << NM_VECTOR; | 482 | eb |= 1u << NM_VECTOR; |
483 | if (vcpu->guest_debug.enabled) | 483 | if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) { |
484 | eb |= 1u << DB_VECTOR; | 484 | if (vcpu->guest_debug & |
485 | (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) | ||
486 | eb |= 1u << DB_VECTOR; | ||
487 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) | ||
488 | eb |= 1u << BP_VECTOR; | ||
489 | } | ||
485 | if (vcpu->arch.rmode.active) | 490 | if (vcpu->arch.rmode.active) |
486 | eb = ~0; | 491 | eb = ~0; |
487 | if (vm_need_ept()) | 492 | if (vm_need_ept()) |
@@ -1003,40 +1008,23 @@ static void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg) | |||
1003 | } | 1008 | } |
1004 | } | 1009 | } |
1005 | 1010 | ||
1006 | static int set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg) | 1011 | static int set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg) |
1007 | { | 1012 | { |
1008 | unsigned long dr7 = 0x400; | 1013 | int old_debug = vcpu->guest_debug; |
1009 | int old_singlestep; | 1014 | unsigned long flags; |
1010 | |||
1011 | old_singlestep = vcpu->guest_debug.singlestep; | ||
1012 | |||
1013 | vcpu->guest_debug.enabled = dbg->enabled; | ||
1014 | if (vcpu->guest_debug.enabled) { | ||
1015 | int i; | ||
1016 | |||
1017 | dr7 |= 0x200; /* exact */ | ||
1018 | for (i = 0; i < 4; ++i) { | ||
1019 | if (!dbg->breakpoints[i].enabled) | ||
1020 | continue; | ||
1021 | vcpu->guest_debug.bp[i] = dbg->breakpoints[i].address; | ||
1022 | dr7 |= 2 << (i*2); /* global enable */ | ||
1023 | dr7 |= 0 << (i*4+16); /* execution breakpoint */ | ||
1024 | } | ||
1025 | |||
1026 | vcpu->guest_debug.singlestep = dbg->singlestep; | ||
1027 | } else | ||
1028 | vcpu->guest_debug.singlestep = 0; | ||
1029 | 1015 | ||
1030 | if (old_singlestep && !vcpu->guest_debug.singlestep) { | 1016 | vcpu->guest_debug = dbg->control; |
1031 | unsigned long flags; | 1017 | if (!(vcpu->guest_debug & KVM_GUESTDBG_ENABLE)) |
1018 | vcpu->guest_debug = 0; | ||
1032 | 1019 | ||
1033 | flags = vmcs_readl(GUEST_RFLAGS); | 1020 | flags = vmcs_readl(GUEST_RFLAGS); |
1021 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) | ||
1022 | flags |= X86_EFLAGS_TF | X86_EFLAGS_RF; | ||
1023 | else if (old_debug & KVM_GUESTDBG_SINGLESTEP) | ||
1034 | flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_RF); | 1024 | flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_RF); |
1035 | vmcs_writel(GUEST_RFLAGS, flags); | 1025 | vmcs_writel(GUEST_RFLAGS, flags); |
1036 | } | ||
1037 | 1026 | ||
1038 | update_exception_bitmap(vcpu); | 1027 | update_exception_bitmap(vcpu); |
1039 | vmcs_writel(GUEST_DR7, dr7); | ||
1040 | 1028 | ||
1041 | return 0; | 1029 | return 0; |
1042 | } | 1030 | } |
@@ -2540,24 +2528,6 @@ static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr) | |||
2540 | return 0; | 2528 | return 0; |
2541 | } | 2529 | } |
2542 | 2530 | ||
2543 | static void kvm_guest_debug_pre(struct kvm_vcpu *vcpu) | ||
2544 | { | ||
2545 | struct kvm_guest_debug *dbg = &vcpu->guest_debug; | ||
2546 | |||
2547 | set_debugreg(dbg->bp[0], 0); | ||
2548 | set_debugreg(dbg->bp[1], 1); | ||
2549 | set_debugreg(dbg->bp[2], 2); | ||
2550 | set_debugreg(dbg->bp[3], 3); | ||
2551 | |||
2552 | if (dbg->singlestep) { | ||
2553 | unsigned long flags; | ||
2554 | |||
2555 | flags = vmcs_readl(GUEST_RFLAGS); | ||
2556 | flags |= X86_EFLAGS_TF | X86_EFLAGS_RF; | ||
2557 | vmcs_writel(GUEST_RFLAGS, flags); | ||
2558 | } | ||
2559 | } | ||
2560 | |||
2561 | static int handle_rmode_exception(struct kvm_vcpu *vcpu, | 2531 | static int handle_rmode_exception(struct kvm_vcpu *vcpu, |
2562 | int vec, u32 err_code) | 2532 | int vec, u32 err_code) |
2563 | { | 2533 | { |
@@ -2574,9 +2544,17 @@ static int handle_rmode_exception(struct kvm_vcpu *vcpu, | |||
2574 | * the required debugging infrastructure rework. | 2544 | * the required debugging infrastructure rework. |
2575 | */ | 2545 | */ |
2576 | switch (vec) { | 2546 | switch (vec) { |
2577 | case DE_VECTOR: | ||
2578 | case DB_VECTOR: | 2547 | case DB_VECTOR: |
2548 | if (vcpu->guest_debug & | ||
2549 | (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) | ||
2550 | return 0; | ||
2551 | kvm_queue_exception(vcpu, vec); | ||
2552 | return 1; | ||
2579 | case BP_VECTOR: | 2553 | case BP_VECTOR: |
2554 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) | ||
2555 | return 0; | ||
2556 | /* fall through */ | ||
2557 | case DE_VECTOR: | ||
2580 | case OF_VECTOR: | 2558 | case OF_VECTOR: |
2581 | case BR_VECTOR: | 2559 | case BR_VECTOR: |
2582 | case UD_VECTOR: | 2560 | case UD_VECTOR: |
@@ -2593,7 +2571,7 @@ static int handle_rmode_exception(struct kvm_vcpu *vcpu, | |||
2593 | static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | 2571 | static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) |
2594 | { | 2572 | { |
2595 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 2573 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
2596 | u32 intr_info, error_code; | 2574 | u32 intr_info, ex_no, error_code; |
2597 | unsigned long cr2, rip; | 2575 | unsigned long cr2, rip; |
2598 | u32 vect_info; | 2576 | u32 vect_info; |
2599 | enum emulation_result er; | 2577 | enum emulation_result er; |
@@ -2653,14 +2631,16 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
2653 | return 1; | 2631 | return 1; |
2654 | } | 2632 | } |
2655 | 2633 | ||
2656 | if ((intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK)) == | 2634 | ex_no = intr_info & INTR_INFO_VECTOR_MASK; |
2657 | (INTR_TYPE_HARD_EXCEPTION | 1)) { | 2635 | if (ex_no == DB_VECTOR || ex_no == BP_VECTOR) { |
2658 | kvm_run->exit_reason = KVM_EXIT_DEBUG; | 2636 | kvm_run->exit_reason = KVM_EXIT_DEBUG; |
2659 | return 0; | 2637 | kvm_run->debug.arch.pc = vmcs_readl(GUEST_CS_BASE) + rip; |
2638 | kvm_run->debug.arch.exception = ex_no; | ||
2639 | } else { | ||
2640 | kvm_run->exit_reason = KVM_EXIT_EXCEPTION; | ||
2641 | kvm_run->ex.exception = ex_no; | ||
2642 | kvm_run->ex.error_code = error_code; | ||
2660 | } | 2643 | } |
2661 | kvm_run->exit_reason = KVM_EXIT_EXCEPTION; | ||
2662 | kvm_run->ex.exception = intr_info & INTR_INFO_VECTOR_MASK; | ||
2663 | kvm_run->ex.error_code = error_code; | ||
2664 | return 0; | 2644 | return 0; |
2665 | } | 2645 | } |
2666 | 2646 | ||
@@ -3600,7 +3580,6 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
3600 | .vcpu_put = vmx_vcpu_put, | 3580 | .vcpu_put = vmx_vcpu_put, |
3601 | 3581 | ||
3602 | .set_guest_debug = set_guest_debug, | 3582 | .set_guest_debug = set_guest_debug, |
3603 | .guest_debug_pre = kvm_guest_debug_pre, | ||
3604 | .get_msr = vmx_get_msr, | 3583 | .get_msr = vmx_get_msr, |
3605 | .set_msr = vmx_set_msr, | 3584 | .set_msr = vmx_set_msr, |
3606 | .get_segment_base = vmx_get_segment_base, | 3585 | .get_segment_base = vmx_get_segment_base, |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index b5e9932e0f62..e990d164b56d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -3005,9 +3005,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
3005 | goto out; | 3005 | goto out; |
3006 | } | 3006 | } |
3007 | 3007 | ||
3008 | if (vcpu->guest_debug.enabled) | ||
3009 | kvm_x86_ops->guest_debug_pre(vcpu); | ||
3010 | |||
3011 | vcpu->guest_mode = 1; | 3008 | vcpu->guest_mode = 1; |
3012 | /* | 3009 | /* |
3013 | * Make sure that guest_mode assignment won't happen after | 3010 | * Make sure that guest_mode assignment won't happen after |
@@ -3218,7 +3215,7 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
3218 | /* | 3215 | /* |
3219 | * Don't leak debug flags in case they were set for guest debugging | 3216 | * Don't leak debug flags in case they were set for guest debugging |
3220 | */ | 3217 | */ |
3221 | if (vcpu->guest_debug.enabled && vcpu->guest_debug.singlestep) | 3218 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) |
3222 | regs->rflags &= ~(X86_EFLAGS_TF | X86_EFLAGS_RF); | 3219 | regs->rflags &= ~(X86_EFLAGS_TF | X86_EFLAGS_RF); |
3223 | 3220 | ||
3224 | vcpu_put(vcpu); | 3221 | vcpu_put(vcpu); |
@@ -3837,8 +3834,8 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, | |||
3837 | return 0; | 3834 | return 0; |
3838 | } | 3835 | } |
3839 | 3836 | ||
3840 | int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, | 3837 | int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, |
3841 | struct kvm_debug_guest *dbg) | 3838 | struct kvm_guest_debug *dbg) |
3842 | { | 3839 | { |
3843 | int r; | 3840 | int r; |
3844 | 3841 | ||
@@ -3846,6 +3843,11 @@ int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, | |||
3846 | 3843 | ||
3847 | r = kvm_x86_ops->set_guest_debug(vcpu, dbg); | 3844 | r = kvm_x86_ops->set_guest_debug(vcpu, dbg); |
3848 | 3845 | ||
3846 | if (dbg->control & KVM_GUESTDBG_INJECT_DB) | ||
3847 | kvm_queue_exception(vcpu, DB_VECTOR); | ||
3848 | else if (dbg->control & KVM_GUESTDBG_INJECT_BP) | ||
3849 | kvm_queue_exception(vcpu, BP_VECTOR); | ||
3850 | |||
3849 | vcpu_put(vcpu); | 3851 | vcpu_put(vcpu); |
3850 | 3852 | ||
3851 | return r; | 3853 | return r; |
diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 0424326f1679..429a2ce202f9 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h | |||
@@ -126,6 +126,7 @@ struct kvm_run { | |||
126 | __u64 data_offset; /* relative to kvm_run start */ | 126 | __u64 data_offset; /* relative to kvm_run start */ |
127 | } io; | 127 | } io; |
128 | struct { | 128 | struct { |
129 | struct kvm_debug_exit_arch arch; | ||
129 | } debug; | 130 | } debug; |
130 | /* KVM_EXIT_MMIO */ | 131 | /* KVM_EXIT_MMIO */ |
131 | struct { | 132 | struct { |
@@ -217,21 +218,6 @@ struct kvm_interrupt { | |||
217 | __u32 irq; | 218 | __u32 irq; |
218 | }; | 219 | }; |
219 | 220 | ||
220 | struct kvm_breakpoint { | ||
221 | __u32 enabled; | ||
222 | __u32 padding; | ||
223 | __u64 address; | ||
224 | }; | ||
225 | |||
226 | /* for KVM_DEBUG_GUEST */ | ||
227 | struct kvm_debug_guest { | ||
228 | /* int */ | ||
229 | __u32 enabled; | ||
230 | __u32 pad; | ||
231 | struct kvm_breakpoint breakpoints[4]; | ||
232 | __u32 singlestep; | ||
233 | }; | ||
234 | |||
235 | /* for KVM_GET_DIRTY_LOG */ | 221 | /* for KVM_GET_DIRTY_LOG */ |
236 | struct kvm_dirty_log { | 222 | struct kvm_dirty_log { |
237 | __u32 slot; | 223 | __u32 slot; |
@@ -292,6 +278,17 @@ struct kvm_s390_interrupt { | |||
292 | __u64 parm64; | 278 | __u64 parm64; |
293 | }; | 279 | }; |
294 | 280 | ||
281 | /* for KVM_SET_GUEST_DEBUG */ | ||
282 | |||
283 | #define KVM_GUESTDBG_ENABLE 0x00000001 | ||
284 | #define KVM_GUESTDBG_SINGLESTEP 0x00000002 | ||
285 | |||
286 | struct kvm_guest_debug { | ||
287 | __u32 control; | ||
288 | __u32 pad; | ||
289 | struct kvm_guest_debug_arch arch; | ||
290 | }; | ||
291 | |||
295 | #define KVM_TRC_SHIFT 16 | 292 | #define KVM_TRC_SHIFT 16 |
296 | /* | 293 | /* |
297 | * kvm trace categories | 294 | * kvm trace categories |
@@ -396,6 +393,7 @@ struct kvm_trace_rec { | |||
396 | #ifdef __KVM_HAVE_USER_NMI | 393 | #ifdef __KVM_HAVE_USER_NMI |
397 | #define KVM_CAP_USER_NMI 22 | 394 | #define KVM_CAP_USER_NMI 22 |
398 | #endif | 395 | #endif |
396 | #define KVM_CAP_SET_GUEST_DEBUG 23 | ||
399 | 397 | ||
400 | /* | 398 | /* |
401 | * ioctls for VM fds | 399 | * ioctls for VM fds |
@@ -440,7 +438,8 @@ struct kvm_trace_rec { | |||
440 | #define KVM_SET_SREGS _IOW(KVMIO, 0x84, struct kvm_sregs) | 438 | #define KVM_SET_SREGS _IOW(KVMIO, 0x84, struct kvm_sregs) |
441 | #define KVM_TRANSLATE _IOWR(KVMIO, 0x85, struct kvm_translation) | 439 | #define KVM_TRANSLATE _IOWR(KVMIO, 0x85, struct kvm_translation) |
442 | #define KVM_INTERRUPT _IOW(KVMIO, 0x86, struct kvm_interrupt) | 440 | #define KVM_INTERRUPT _IOW(KVMIO, 0x86, struct kvm_interrupt) |
443 | #define KVM_DEBUG_GUEST _IOW(KVMIO, 0x87, struct kvm_debug_guest) | 441 | /* KVM_DEBUG_GUEST is no longer supported, use KVM_SET_GUEST_DEBUG instead */ |
442 | #define KVM_DEBUG_GUEST __KVM_DEPRECATED_DEBUG_GUEST | ||
444 | #define KVM_GET_MSRS _IOWR(KVMIO, 0x88, struct kvm_msrs) | 443 | #define KVM_GET_MSRS _IOWR(KVMIO, 0x88, struct kvm_msrs) |
445 | #define KVM_SET_MSRS _IOW(KVMIO, 0x89, struct kvm_msrs) | 444 | #define KVM_SET_MSRS _IOW(KVMIO, 0x89, struct kvm_msrs) |
446 | #define KVM_SET_CPUID _IOW(KVMIO, 0x8a, struct kvm_cpuid) | 445 | #define KVM_SET_CPUID _IOW(KVMIO, 0x8a, struct kvm_cpuid) |
@@ -469,6 +468,26 @@ struct kvm_trace_rec { | |||
469 | #define KVM_SET_MP_STATE _IOW(KVMIO, 0x99, struct kvm_mp_state) | 468 | #define KVM_SET_MP_STATE _IOW(KVMIO, 0x99, struct kvm_mp_state) |
470 | /* Available with KVM_CAP_NMI */ | 469 | /* Available with KVM_CAP_NMI */ |
471 | #define KVM_NMI _IO(KVMIO, 0x9a) | 470 | #define KVM_NMI _IO(KVMIO, 0x9a) |
471 | /* Available with KVM_CAP_SET_GUEST_DEBUG */ | ||
472 | #define KVM_SET_GUEST_DEBUG _IOW(KVMIO, 0x9b, struct kvm_guest_debug) | ||
473 | |||
474 | /* | ||
475 | * Deprecated interfaces | ||
476 | */ | ||
477 | struct kvm_breakpoint { | ||
478 | __u32 enabled; | ||
479 | __u32 padding; | ||
480 | __u64 address; | ||
481 | }; | ||
482 | |||
483 | struct kvm_debug_guest { | ||
484 | __u32 enabled; | ||
485 | __u32 pad; | ||
486 | struct kvm_breakpoint breakpoints[4]; | ||
487 | __u32 singlestep; | ||
488 | }; | ||
489 | |||
490 | #define __KVM_DEPRECATED_DEBUG_GUEST _IOW(KVMIO, 0x87, struct kvm_debug_guest) | ||
472 | 491 | ||
473 | #define KVM_TRC_INJ_VIRQ (KVM_TRC_HANDLER + 0x02) | 492 | #define KVM_TRC_INJ_VIRQ (KVM_TRC_HANDLER + 0x02) |
474 | #define KVM_TRC_REDELIVER_EVT (KVM_TRC_HANDLER + 0x03) | 493 | #define KVM_TRC_REDELIVER_EVT (KVM_TRC_HANDLER + 0x03) |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index bf6f703642fc..e92212f970db 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
@@ -73,7 +73,7 @@ struct kvm_vcpu { | |||
73 | struct kvm_run *run; | 73 | struct kvm_run *run; |
74 | int guest_mode; | 74 | int guest_mode; |
75 | unsigned long requests; | 75 | unsigned long requests; |
76 | struct kvm_guest_debug guest_debug; | 76 | unsigned long guest_debug; |
77 | int fpu_active; | 77 | int fpu_active; |
78 | int guest_fpu_loaded; | 78 | int guest_fpu_loaded; |
79 | wait_queue_head_t wq; | 79 | wait_queue_head_t wq; |
@@ -255,8 +255,8 @@ int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, | |||
255 | struct kvm_mp_state *mp_state); | 255 | struct kvm_mp_state *mp_state); |
256 | int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, | 256 | int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, |
257 | struct kvm_mp_state *mp_state); | 257 | struct kvm_mp_state *mp_state); |
258 | int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, | 258 | int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, |
259 | struct kvm_debug_guest *dbg); | 259 | struct kvm_guest_debug *dbg); |
260 | int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run); | 260 | int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run); |
261 | 261 | ||
262 | int kvm_arch_init(void *opaque); | 262 | int kvm_arch_init(void *opaque); |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 29a667ce35b0..f83ef9c7e89b 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -1755,13 +1755,13 @@ out_free2: | |||
1755 | r = 0; | 1755 | r = 0; |
1756 | break; | 1756 | break; |
1757 | } | 1757 | } |
1758 | case KVM_DEBUG_GUEST: { | 1758 | case KVM_SET_GUEST_DEBUG: { |
1759 | struct kvm_debug_guest dbg; | 1759 | struct kvm_guest_debug dbg; |
1760 | 1760 | ||
1761 | r = -EFAULT; | 1761 | r = -EFAULT; |
1762 | if (copy_from_user(&dbg, argp, sizeof dbg)) | 1762 | if (copy_from_user(&dbg, argp, sizeof dbg)) |
1763 | goto out; | 1763 | goto out; |
1764 | r = kvm_arch_vcpu_ioctl_debug_guest(vcpu, &dbg); | 1764 | r = kvm_arch_vcpu_ioctl_set_guest_debug(vcpu, &dbg); |
1765 | if (r) | 1765 | if (r) |
1766 | goto out; | 1766 | goto out; |
1767 | r = 0; | 1767 | r = 0; |