aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@siemens.com>2008-12-15 07:52:10 -0500
committerAvi Kivity <avi@redhat.com>2009-03-24 05:02:49 -0400
commitd0bfb940ecabf0b44fb1fd80d8d60594e569e5ec (patch)
treeb5927d44937a54ec23d2a28d59db06a0262c0412
parent8ab2d2e231062814bd89bba2d6d92563190aa2bb (diff)
KVM: New guest debug interface
This rips out the support for KVM_DEBUG_GUEST and introduces a new IOCTL instead: KVM_SET_GUEST_DEBUG. The IOCTL payload consists of a generic part, controlling the "main switch" and the single-step feature. The arch specific part adds an x86 interface for intercepting both types of debug exceptions separately and re-injecting them when the host was not interested. Moveover, the foundation for guest debugging via debug registers is layed. To signal breakpoint events properly back to userland, an arch-specific data block is now returned along KVM_EXIT_DEBUG. For x86, the arch block contains the PC, the debug exception, and relevant debug registers to tell debug events properly apart. The availability of this new interface is signaled by KVM_CAP_SET_GUEST_DEBUG. Empty stubs for not yet supported archs are provided. Note that both SVM and VTX are supported, but only the latter was tested yet. Based on the experience with all those VTX corner case, I would be fairly surprised if SVM will work out of the box. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--arch/ia64/include/asm/kvm.h7
-rw-r--r--arch/ia64/kvm/kvm-ia64.c4
-rw-r--r--arch/powerpc/include/asm/kvm.h7
-rw-r--r--arch/powerpc/kvm/powerpc.c4
-rw-r--r--arch/s390/include/asm/kvm.h7
-rw-r--r--arch/s390/kvm/kvm-s390.c4
-rw-r--r--arch/x86/include/asm/kvm.h18
-rw-r--r--arch/x86/include/asm/kvm_host.h9
-rw-r--r--arch/x86/kvm/svm.c50
-rw-r--r--arch/x86/kvm/vmx.c93
-rw-r--r--arch/x86/kvm/x86.c14
-rw-r--r--include/linux/kvm.h51
-rw-r--r--include/linux/kvm_host.h6
-rw-r--r--virt/kvm/kvm_main.c6
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 {
214struct kvm_fpu { 214struct kvm_fpu {
215}; 215};
216 216
217struct kvm_debug_exit_arch {
218};
219
220/* for KVM_SET_GUEST_DEBUG */
221struct 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
1306int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, 1306int 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
55struct kvm_debug_exit_arch {
56};
57
58/* for KVM_SET_GUEST_DEBUG */
59struct 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
243int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, 243int 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
45struct kvm_debug_exit_arch {
46};
47
48/* for KVM_SET_GUEST_DEBUG */
49struct 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
425int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, 425int 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
215struct 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 */
229struct kvm_guest_debug_arch {
230 __u64 debugreg[8];
231};
232
215struct kvm_pit_state { 233struct 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
138struct 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
971static int svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg) 971static 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
976static int svm_get_irq(struct kvm_vcpu *vcpu) 999static 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
1120static 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
1133static 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
1097static int ud_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) 1141static 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
1006static int set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg) 1011static 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
2543static 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
2561static int handle_rmode_exception(struct kvm_vcpu *vcpu, 2531static 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,
2593static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 2571static 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
3840int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, 3837int 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
220struct kvm_breakpoint {
221 __u32 enabled;
222 __u32 padding;
223 __u64 address;
224};
225
226/* for KVM_DEBUG_GUEST */
227struct 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 */
236struct kvm_dirty_log { 222struct 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
286struct 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 */
477struct kvm_breakpoint {
478 __u32 enabled;
479 __u32 padding;
480 __u64 address;
481};
482
483struct 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);
256int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, 256int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
257 struct kvm_mp_state *mp_state); 257 struct kvm_mp_state *mp_state);
258int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, 258int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
259 struct kvm_debug_guest *dbg); 259 struct kvm_guest_debug *dbg);
260int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run); 260int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run);
261 261
262int kvm_arch_init(void *opaque); 262int 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;