target/ppc: Refactor kvm_handle_debug

There are four scenarios being handled in this function:

- single stepping
- hardware breakpoints
- software breakpoints
- fallback (no debug supported)

A future patch will add code to handle specific single step and
software breakpoints cases so let's split each scenario into its own
function now to avoid hurting readability.

Signed-off-by: Fabiano Rosas <farosas@linux.ibm.com>
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Message-Id: <20190228225759.21328-5-farosas@linux.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
Fabiano Rosas 2019-02-28 19:57:58 -03:00 committed by David Gibson
parent 2cbd158131
commit 468e3a1a94
1 changed files with 51 additions and 37 deletions

View File

@ -1624,21 +1624,36 @@ static int kvm_handle_hw_breakpoint(CPUState *cs,
return handle;
}
static int kvm_handle_singlestep(void)
{
return 1;
}
static int kvm_handle_sw_breakpoint(void)
{
return 1;
}
static int kvm_handle_debug(PowerPCCPU *cpu, struct kvm_run *run)
{
CPUState *cs = CPU(cpu);
CPUPPCState *env = &cpu->env;
struct kvm_debug_exit_arch *arch_info = &run->debug.arch;
int handle = 0;
if (cs->singlestep_enabled) {
handle = 1;
} else if (arch_info->status) {
handle = kvm_handle_hw_breakpoint(cs, arch_info);
} else if (kvm_find_sw_breakpoint(cs, arch_info->address)) {
handle = 1;
} else {
/* QEMU is not able to handle debug exception, so inject
return kvm_handle_singlestep();
}
if (arch_info->status) {
return kvm_handle_hw_breakpoint(cs, arch_info);
}
if (kvm_find_sw_breakpoint(cs, arch_info->address)) {
return kvm_handle_sw_breakpoint();
}
/*
* QEMU is not able to handle debug exception, so inject
* program exception to guest;
* Yes program exception NOT debug exception !!
* When QEMU is using debug resources then debug exception must
@ -1658,18 +1673,17 @@ static int kvm_handle_debug(PowerPCCPU *cpu, struct kvm_run *run)
* privileged / illegal instruction and that's why we are
* injecting a program interrupt.
*/
cpu_synchronize_state(cs);
/* env->nip is PC, so increment this by 4 to use
/*
* env->nip is PC, so increment this by 4 to use
* ppc_cpu_do_interrupt(), which set srr0 = env->nip - 4.
*/
env->nip += 4;
cs->exception_index = POWERPC_EXCP_PROGRAM;
env->error_code = POWERPC_EXCP_INVAL;
ppc_cpu_do_interrupt(cs);
}
return handle;
return 0;
}
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)