mirror of
https://github.com/xemu-project/xemu.git
synced 2025-02-07 20:57:50 +00:00
KVM: x86: Add debug register saving and restoring
Make use of the new KVM_GET/SET_DEBUGREGS to save/restore the x86 debug registers. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
This commit is contained in:
parent
a303f9e37b
commit
ff44f1a373
11
kvm-all.c
11
kvm-all.c
@ -64,6 +64,7 @@ struct KVMState
|
||||
int migration_log;
|
||||
int vcpu_events;
|
||||
int robust_singlestep;
|
||||
int debugregs;
|
||||
#ifdef KVM_CAP_SET_GUEST_DEBUG
|
||||
struct kvm_sw_breakpoint_head kvm_sw_breakpoints;
|
||||
#endif
|
||||
@ -664,6 +665,11 @@ int kvm_init(int smp_cpus)
|
||||
kvm_check_extension(s, KVM_CAP_X86_ROBUST_SINGLESTEP);
|
||||
#endif
|
||||
|
||||
s->debugregs = 0;
|
||||
#ifdef KVM_CAP_DEBUGREGS
|
||||
s->debugregs = kvm_check_extension(s, KVM_CAP_DEBUGREGS);
|
||||
#endif
|
||||
|
||||
ret = kvm_arch_init(s, smp_cpus);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
@ -939,6 +945,11 @@ int kvm_has_robust_singlestep(void)
|
||||
return kvm_state->robust_singlestep;
|
||||
}
|
||||
|
||||
int kvm_has_debugregs(void)
|
||||
{
|
||||
return kvm_state->debugregs;
|
||||
}
|
||||
|
||||
void kvm_setup_guest_memory(void *start, size_t size)
|
||||
{
|
||||
if (!kvm_has_sync_mmu()) {
|
||||
|
1
kvm.h
1
kvm.h
@ -40,6 +40,7 @@ int kvm_init(int smp_cpus);
|
||||
int kvm_has_sync_mmu(void);
|
||||
int kvm_has_vcpu_events(void);
|
||||
int kvm_has_robust_singlestep(void);
|
||||
int kvm_has_debugregs(void);
|
||||
|
||||
#ifdef NEED_CPU_H
|
||||
int kvm_init_vcpu(CPUState *env);
|
||||
|
@ -874,6 +874,53 @@ static int kvm_guest_debug_workarounds(CPUState *env)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int kvm_put_debugregs(CPUState *env)
|
||||
{
|
||||
#ifdef KVM_CAP_DEBUGREGS
|
||||
struct kvm_debugregs dbgregs;
|
||||
int i;
|
||||
|
||||
if (!kvm_has_debugregs()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
dbgregs.db[i] = env->dr[i];
|
||||
}
|
||||
dbgregs.dr6 = env->dr[6];
|
||||
dbgregs.dr7 = env->dr[7];
|
||||
dbgregs.flags = 0;
|
||||
|
||||
return kvm_vcpu_ioctl(env, KVM_SET_DEBUGREGS, &dbgregs);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int kvm_get_debugregs(CPUState *env)
|
||||
{
|
||||
#ifdef KVM_CAP_DEBUGREGS
|
||||
struct kvm_debugregs dbgregs;
|
||||
int i, ret;
|
||||
|
||||
if (!kvm_has_debugregs()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = kvm_vcpu_ioctl(env, KVM_GET_DEBUGREGS, &dbgregs);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
env->dr[i] = dbgregs.db[i];
|
||||
}
|
||||
env->dr[4] = env->dr[6] = dbgregs.dr6;
|
||||
env->dr[5] = env->dr[7] = dbgregs.dr7;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvm_arch_put_registers(CPUState *env, int level)
|
||||
{
|
||||
int ret;
|
||||
@ -909,6 +956,10 @@ int kvm_arch_put_registers(CPUState *env, int level)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = kvm_put_debugregs(env);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -940,6 +991,10 @@ int kvm_arch_get_registers(CPUState *env)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = kvm_get_debugregs(env);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user