diff mbox series

[RFC,v3,2/7] target/ppc: Add ppc_get_trace_int_handler_addr

Message ID 20190118140758.829-3-farosas@linux.ibm.com
State New
Headers show
Series target/ppc: single step for KVM HV | expand

Commit Message

Fabiano Rosas Jan. 18, 2019, 2:07 p.m. UTC
The upcoming single step functionality (KVM HV) needs to write to the
Trace Interrupt handler's address for its mechanism to work. The
address is calculated by applying an offset according to the value of
the Alternate Interrupt Location (AIL) bits in the LPCR register.

Signed-off-by: Fabiano Rosas <farosas@linux.ibm.com>
---
 target/ppc/cpu.h         |  1 +
 target/ppc/excp_helper.c | 12 ++++++++++++
 2 files changed, 13 insertions(+)

Comments

Alexey Kardashevskiy Jan. 25, 2019, 1:22 a.m. UTC | #1
On 19/01/2019 01:07, Fabiano Rosas wrote:
> The upcoming single step functionality (KVM HV) needs to write to the
> Trace Interrupt handler's address for its mechanism to work. The
> address is calculated by applying an offset according to the value of
> the Alternate Interrupt Location (AIL) bits in the LPCR register.
> 
> Signed-off-by: Fabiano Rosas <farosas@linux.ibm.com>
> ---
>  target/ppc/cpu.h         |  1 +
>  target/ppc/excp_helper.c | 12 ++++++++++++
>  2 files changed, 13 insertions(+)
> 
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index 486abaf99b..2185ef5e67 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -1256,6 +1256,7 @@ struct PPCVirtualHypervisorClass {
>      OBJECT_GET_CLASS(PPCVirtualHypervisorClass, (obj), \
>                       TYPE_PPC_VIRTUAL_HYPERVISOR)
>  
> +target_ulong ppc_get_trace_int_handler_addr(CPUState *cs);
>  void ppc_cpu_do_interrupt(CPUState *cpu);
>  bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
>  void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 337a3ef8bb..5d13d05c3b 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -746,6 +746,18 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>      check_tlb_flush(env, false);
>  }
>  
> +target_ulong ppc_get_trace_int_handler_addr(CPUState *cs)
> +{
> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
> +    CPUPPCState *env = &cpu->env;
> +    int ail;
> +
> +    ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
> +    return env->excp_vectors[POWERPC_EXCP_TRACE] |
> +        ppc_excp_vector_offset(cs, ail);
> +}
> +
> +


Extra empty line.

The entire patch seems to belong to 7/7, it does not make sense on its
own as the helper is not called by anyone and all the files which it is
changing belong to target/ppc/.


>  void ppc_cpu_do_interrupt(CPUState *cs)
>  {
>      PowerPCCPU *cpu = POWERPC_CPU(cs);
>
Alexey Kardashevskiy Feb. 1, 2019, 4:08 a.m. UTC | #2
On 19/01/2019 01:07, Fabiano Rosas wrote:
> The upcoming single step functionality (KVM HV) needs to write to the
> Trace Interrupt handler's address for its mechanism to work. The
> address is calculated by applying an offset according to the value of
> the Alternate Interrupt Location (AIL) bits in the LPCR register.
> 
> Signed-off-by: Fabiano Rosas <farosas@linux.ibm.com>
> ---
>  target/ppc/cpu.h         |  1 +
>  target/ppc/excp_helper.c | 12 ++++++++++++
>  2 files changed, 13 insertions(+)
> 
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index 486abaf99b..2185ef5e67 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -1256,6 +1256,7 @@ struct PPCVirtualHypervisorClass {
>      OBJECT_GET_CLASS(PPCVirtualHypervisorClass, (obj), \
>                       TYPE_PPC_VIRTUAL_HYPERVISOR)
>  
> +target_ulong ppc_get_trace_int_handler_addr(CPUState *cs);
>  void ppc_cpu_do_interrupt(CPUState *cpu);
>  bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
>  void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 337a3ef8bb..5d13d05c3b 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -746,6 +746,18 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>      check_tlb_flush(env, false);
>  }
>  
> +target_ulong ppc_get_trace_int_handler_addr(CPUState *cs)
> +{
> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
> +    CPUPPCState *env = &cpu->env;
> +    int ail;
> +
> +    ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
> +    return env->excp_vectors[POWERPC_EXCP_TRACE] |
> +        ppc_excp_vector_offset(cs, ail);


This fails with:
cpu_abort(cs, "Invalid AIL combination %d\n", ail)

as @ail calculates as 0 when I am just about to start a guest and try to
set breakpoint at the initial $nip (set here:
https://git.qemu.org/?p=qemu.git;a=blob;f=hw/ppc/spapr_cpu_core.c;h=993759db47fa33b11a984c3043049297b06c0420;hb=38441756b70eec5807b5f60dad11a93a91199866#l90
)

This is long before h_set_mode is called.


> +}
> +
> +
>  void ppc_cpu_do_interrupt(CPUState *cs)
>  {
>      PowerPCCPU *cpu = POWERPC_CPU(cs);
>
diff mbox series

Patch

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 486abaf99b..2185ef5e67 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1256,6 +1256,7 @@  struct PPCVirtualHypervisorClass {
     OBJECT_GET_CLASS(PPCVirtualHypervisorClass, (obj), \
                      TYPE_PPC_VIRTUAL_HYPERVISOR)
 
+target_ulong ppc_get_trace_int_handler_addr(CPUState *cs);
 void ppc_cpu_do_interrupt(CPUState *cpu);
 bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 337a3ef8bb..5d13d05c3b 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -746,6 +746,18 @@  static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     check_tlb_flush(env, false);
 }
 
+target_ulong ppc_get_trace_int_handler_addr(CPUState *cs)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+    int ail;
+
+    ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
+    return env->excp_vectors[POWERPC_EXCP_TRACE] |
+        ppc_excp_vector_offset(cs, ail);
+}
+
+
 void ppc_cpu_do_interrupt(CPUState *cs)
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);