Revision b0b1d690 target-i386/kvm.c
b/target-i386/kvm.c | ||
---|---|---|
852 | 852 |
return 0; |
853 | 853 |
} |
854 | 854 |
|
855 |
static int kvm_guest_debug_workarounds(CPUState *env) |
|
856 |
{ |
|
857 |
int ret = 0; |
|
858 |
#ifdef KVM_CAP_SET_GUEST_DEBUG |
|
859 |
unsigned long reinject_trap = 0; |
|
860 |
|
|
861 |
if (!kvm_has_vcpu_events()) { |
|
862 |
if (env->exception_injected == 1) { |
|
863 |
reinject_trap = KVM_GUESTDBG_INJECT_DB; |
|
864 |
} else if (env->exception_injected == 3) { |
|
865 |
reinject_trap = KVM_GUESTDBG_INJECT_BP; |
|
866 |
} |
|
867 |
env->exception_injected = -1; |
|
868 |
} |
|
869 |
|
|
870 |
/* |
|
871 |
* Kernels before KVM_CAP_X86_ROBUST_SINGLESTEP overwrote flags.TF |
|
872 |
* injected via SET_GUEST_DEBUG while updating GP regs. Work around this |
|
873 |
* by updating the debug state once again if single-stepping is on. |
|
874 |
* Another reason to call kvm_update_guest_debug here is a pending debug |
|
875 |
* trap raise by the guest. On kernels without SET_VCPU_EVENTS we have to |
|
876 |
* reinject them via SET_GUEST_DEBUG. |
|
877 |
*/ |
|
878 |
if (reinject_trap || |
|
879 |
(!kvm_has_robust_singlestep() && env->singlestep_enabled)) { |
|
880 |
ret = kvm_update_guest_debug(env, reinject_trap); |
|
881 |
} |
|
882 |
#endif /* KVM_CAP_SET_GUEST_DEBUG */ |
|
883 |
return ret; |
|
884 |
} |
|
885 |
|
|
855 | 886 |
int kvm_arch_put_registers(CPUState *env) |
856 | 887 |
{ |
857 | 888 |
int ret; |
... | ... | |
880 | 911 |
if (ret < 0) |
881 | 912 |
return ret; |
882 | 913 |
|
914 |
/* must be last */ |
|
915 |
ret = kvm_guest_debug_workarounds(env); |
|
916 |
if (ret < 0) |
|
917 |
return ret; |
|
918 |
|
|
883 | 919 |
return 0; |
884 | 920 |
} |
885 | 921 |
|
... | ... | |
1123 | 1159 |
} else if (kvm_find_sw_breakpoint(cpu_single_env, arch_info->pc)) |
1124 | 1160 |
handle = 1; |
1125 | 1161 |
|
1126 |
if (!handle) |
|
1127 |
kvm_update_guest_debug(cpu_single_env, |
|
1128 |
(arch_info->exception == 1) ? |
|
1129 |
KVM_GUESTDBG_INJECT_DB : KVM_GUESTDBG_INJECT_BP); |
|
1162 |
if (!handle) { |
|
1163 |
cpu_synchronize_state(cpu_single_env); |
|
1164 |
assert(cpu_single_env->exception_injected == -1); |
|
1165 |
|
|
1166 |
cpu_single_env->exception_injected = arch_info->exception; |
|
1167 |
cpu_single_env->has_error_code = 0; |
|
1168 |
} |
|
1130 | 1169 |
|
1131 | 1170 |
return handle; |
1132 | 1171 |
} |
Also available in: Unified diff