[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2] spapr: compute interrupt vector address from
From: |
Greg Kurz |
Subject: |
Re: [Qemu-devel] [PATCH v2] spapr: compute interrupt vector address from LPCR |
Date: |
Wed, 30 Mar 2016 19:01:31 +0200 |
On Wed, 30 Mar 2016 17:38:34 +0200
Cédric Le Goater <address@hidden> wrote:
> This address is changed by the linux kernel using the H_SET_MODE hcall
> and needs to be restored when migrating a spapr VM running in
> TCG. This can be done using the AIL bits from the LPCR register.
>
> The patch introduces a helper routine cpu_ppc_get_excp_prefix() which
> returns the effective address offset of the interrupt handler
> depending on the LPCR_AIL bits. The same helper can be used in the
> H_SET_MODE hcall, which lets us remove the H_SET_MODE_ADDR_TRANS_*
> defines.
>
<clarification>
... because these H_SET_MODE_ADDR_TRANS_* defines, which refer to the values
0, 1, 2 and 3 for the mflag argument to the H_SET_MODE hypercall as described
in section 14.5.4.3.8 of PAPR, are actually values for bits 39:40 (AIL) of the
LPCR register, as described in section 2.2 of PowerISA.
</clarification>
> Signed-off-by: Cédric Le Goater <address@hidden>
> ---
>
Reviewed-by: Greg Kurz <address@hidden>
> Changes since v1:
>
> - moved helper routine under target-ppc/
> - moved the restore of excp_prefix under cpu_post_load()
>
> hw/ppc/spapr_hcall.c | 13 ++-----------
> include/hw/ppc/spapr.h | 5 -----
> target-ppc/cpu.h | 9 +++++++++
> target-ppc/machine.c | 20 +++++++++++++++++++-
> target-ppc/translate_init.c | 14 ++++++++++++++
> 5 files changed, 44 insertions(+), 17 deletions(-)
>
> Index: qemu-dgibson-for-2.6.git/hw/ppc/spapr_hcall.c
> ===================================================================
> --- qemu-dgibson-for-2.6.git.orig/hw/ppc/spapr_hcall.c
> +++ qemu-dgibson-for-2.6.git/hw/ppc/spapr_hcall.c
> @@ -835,17 +835,8 @@ static target_ulong h_set_mode_resource_
> return H_P4;
> }
>
> - switch (mflags) {
> - case H_SET_MODE_ADDR_TRANS_NONE:
> - prefix = 0;
> - break;
> - case H_SET_MODE_ADDR_TRANS_0001_8000:
> - prefix = 0x18000;
> - break;
> - case H_SET_MODE_ADDR_TRANS_C000_0000_0000_4000:
> - prefix = 0xC000000000004000ULL;
> - break;
> - default:
> + prefix = cpu_ppc_get_excp_prefix(mflags);
> + if (prefix == (target_ulong) -1ULL) {
> return H_UNSUPPORTED_FLAG;
> }
>
> Index: qemu-dgibson-for-2.6.git/target-ppc/machine.c
> ===================================================================
> --- qemu-dgibson-for-2.6.git.orig/target-ppc/machine.c
> +++ qemu-dgibson-for-2.6.git/target-ppc/machine.c
> @@ -156,12 +156,26 @@ static void cpu_pre_save(void *opaque)
> }
> }
>
> +
> +static int cpu_post_load_excp_prefix(CPUPPCState *env)
> +{
> + int ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
> + target_ulong prefix = cpu_ppc_get_excp_prefix(ail);
> +
> + if (prefix == (target_ulong) -1ULL) {
> + return -EINVAL;
> + }
> + env->excp_prefix = prefix;
> + return 0;
> +}
> +
> static int cpu_post_load(void *opaque, int version_id)
> {
> PowerPCCPU *cpu = opaque;
> CPUPPCState *env = &cpu->env;
> int i;
> target_ulong msr;
> + int ret = 0;
>
> /*
> * We always ignore the source PVR. The user or management
> @@ -201,7 +215,11 @@ static int cpu_post_load(void *opaque, i
>
> hreg_compute_mem_idx(env);
>
> - return 0;
> + if (env->spr[SPR_LPCR] & LPCR_AIL) {
> + ret = cpu_post_load_excp_prefix(env);
> + }
> +
> + return ret;
> }
>
> static bool fpu_needed(void *opaque)
> Index: qemu-dgibson-for-2.6.git/target-ppc/translate_init.c
> ===================================================================
> --- qemu-dgibson-for-2.6.git.orig/target-ppc/translate_init.c
> +++ qemu-dgibson-for-2.6.git/target-ppc/translate_init.c
> @@ -8522,6 +8522,20 @@ void cpu_ppc_set_papr(PowerPCCPU *cpu)
> }
> }
>
> +target_ulong cpu_ppc_get_excp_prefix(target_ulong ail)
> +{
> + switch (ail) {
> + case AIL_NONE:
> + return 0;
> + case AIL_0001_8000:
> + return 0x18000;
> + case AIL_C000_0000_0000_4000:
> + return 0xC000000000004000ULL;
> + default:
> + return (target_ulong) -1ULL;
> + }
> +}
> +
> #endif /* !defined(CONFIG_USER_ONLY) */
>
> #endif /* defined (TARGET_PPC64) */
> Index: qemu-dgibson-for-2.6.git/target-ppc/cpu.h
> ===================================================================
> --- qemu-dgibson-for-2.6.git.orig/target-ppc/cpu.h
> +++ qemu-dgibson-for-2.6.git/target-ppc/cpu.h
> @@ -1269,6 +1269,7 @@ void store_booke_tsr (CPUPPCState *env,
> void ppc_tlb_invalidate_all (CPUPPCState *env);
> void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr);
> void cpu_ppc_set_papr(PowerPCCPU *cpu);
> +target_ulong cpu_ppc_get_excp_prefix(target_ulong ail);
> #endif
> #endif
>
> @@ -2277,6 +2278,14 @@ enum {
> HMER_XSCOM_STATUS_LSH = (63 - 23),
> };
>
> +/* Alternate Interrupt Location (AIL) */
> +enum {
> + AIL_NONE = 0,
> + AIL_RESERVED = 1,
> + AIL_0001_8000 = 2,
> + AIL_C000_0000_0000_4000 = 3,
> +};
> +
>
> /*****************************************************************************/
>
> static inline target_ulong cpu_read_xer(CPUPPCState *env)
> Index: qemu-dgibson-for-2.6.git/include/hw/ppc/spapr.h
> ===================================================================
> --- qemu-dgibson-for-2.6.git.orig/include/hw/ppc/spapr.h
> +++ qemu-dgibson-for-2.6.git/include/hw/ppc/spapr.h
> @@ -204,11 +204,6 @@ struct sPAPRMachineState {
> #define H_SET_MODE_ENDIAN_BIG 0
> #define H_SET_MODE_ENDIAN_LITTLE 1
>
> -/* Flags for H_SET_MODE_RESOURCE_ADDR_TRANS_MODE */
> -#define H_SET_MODE_ADDR_TRANS_NONE 0
> -#define H_SET_MODE_ADDR_TRANS_0001_8000 2
> -#define H_SET_MODE_ADDR_TRANS_C000_0000_0000_4000 3
> -
> /* VASI States */
> #define H_VASI_INVALID 0
> #define H_VASI_ENABLED 1
>
>