From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58577) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WVhm9-00033W-5M for qemu-devel@nongnu.org; Thu, 03 Apr 2014 09:33:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WVhm2-00005I-PI for qemu-devel@nongnu.org; Thu, 03 Apr 2014 09:33:49 -0400 Message-ID: <533D6334.2080208@suse.de> Date: Thu, 03 Apr 2014 15:33:40 +0200 From: Alexander Graf MIME-Version: 1.0 References: <1396530891-6352-1-git-send-email-aik@ozlabs.ru> <1396530891-6352-4-git-send-email-aik@ozlabs.ru> In-Reply-To: <1396530891-6352-4-git-send-email-aik@ozlabs.ru> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH 3/4] KVM: PPC: Support POWER8 registers List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alexey Kardashevskiy , qemu-devel@nongnu.org Cc: Tom Musta , qemu-ppc@nongnu.org On 03.04.14 15:14, Alexey Kardashevskiy wrote: > This enabled KVM and migration support for a number of POWER8 registers: > * Program Prioirty Register (PPR) Typo > * Sampled Instruction Address Register (SIAR) > * Sampled Data Address Register (SDAR) > * Vector Registers Save Register (VRSAVE) > > This enables save/restore of transactional state if MSR_TS is set > in the MSR. > > This adds new POWER8 registers support required for migration. > > Signed-off-by: Alexey Kardashevskiy Tom, please have a look through this as well :). > --- > target-ppc/cpu.h | 18 ++++++++++++++++++ > target-ppc/kvm.c | 38 ++++++++++++++++++++++++++++++++++++++ > target-ppc/machine.c | 34 ++++++++++++++++++++++++++++++++++ > target-ppc/translate_init.c | 24 ++++++++++++++++-------- > 4 files changed, 106 insertions(+), 8 deletions(-) > > diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h > index 2719c08..2b476b4 100644 > --- a/target-ppc/cpu.h > +++ b/target-ppc/cpu.h > @@ -426,6 +426,8 @@ struct ppc_slb_t { > #define MSR_TAG 62 /* Tag-active mode (POWERx ?) */ > #define MSR_ISF 61 /* Sixty-four-bit interrupt mode on 630 */ > #define MSR_SHV 60 /* hypervisor state hflags */ > +#define MSR_TS 33 /* Transactional state, 2 bits (Book3s) */ 2 bits means you want to add another define or at least a comment at bit 34. I find it rather counterintuitive to declare bit 33 MSR_TS as 2-bit wide too - you'd expect (3 << MSR_TS) gives you the right mask, but then it'd have to be 34, no? > +#define MSR_TM 32 /* Transactional Memory Available (Book3s) */ > #define MSR_CM 31 /* Computation mode for BookE hflags */ > #define MSR_ICM 30 /* Interrupt computation mode for BookE */ > #define MSR_THV 29 /* hypervisor state for 32 bits PowerPC hflags */ > @@ -1081,6 +1083,20 @@ struct CPUPPCState { > */ > uint8_t fit_period[4]; > uint8_t wdt_period[4]; > + > + /* Transactional memory state migration */ No migration, we're laying the foundation for TM emulation. > + target_ulong tm_gpr[32]; > + ppc_avr_t tm_vsr[64]; > + uint64_t tm_cr; > + uint64_t tm_lr; > + uint64_t tm_ctr; > + uint64_t tm_fpscr; > + uint64_t tm_amr; > + uint64_t tm_ppr; > + uint64_t tm_vrsave; > + uint32_t tm_vscr; > + uint64_t tm_dscr; > + uint64_t tm_tar; > }; > > #define SET_FIT_PERIOD(a_, b_, c_, d_) \ > @@ -1479,6 +1495,8 @@ static inline int cpu_mmu_index (CPUPPCState *env) > #define SPR_MPC_MD_EPN (0x30B) > #define SPR_PERFC (0x30C) > #define SPR_MPC_MD_TWB (0x30C) > +#define SPR_BOOK3S_SIAR (0x30C) > +#define SPR_BOOK3S_SDAR (0x30D) > #define SPR_PERFD (0x30D) > #define SPR_MPC_MD_TWC (0x30D) > #define SPR_PERFE (0x30E) > diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c > index 9974b10..ead69fa 100644 > --- a/target-ppc/kvm.c > +++ b/target-ppc/kvm.c > @@ -866,6 +866,25 @@ int kvm_arch_put_registers(CPUState *cs, int level) > } > > #ifdef TARGET_PPC64 > + if ((cpu->env.msr >> MSR_TS) & 3) { Ah, it works because you're shifting the other direction. That works. How about we just introduce an msr_ts() helper similar to the other lower case helpers to make this obvious? > + for (i = 0; i < sizeof(env->tm_gpr)/sizeof(env->tm_gpr[0]); i++) { ARRAY_SIZE? Alex > + kvm_set_one_reg(cs, KVM_REG_PPC_TM_GPR(i), &env->tm_gpr[i]); > + } > + for (i = 0; i < sizeof(env->tm_vsr)/sizeof(env->tm_vsr[0]); i++) { > + kvm_set_one_reg(cs, KVM_REG_PPC_TM_VSR(i), &env->tm_vsr[i]); > + } > + kvm_set_one_reg(cs, KVM_REG_PPC_TM_CR, &env->tm_cr); > + kvm_set_one_reg(cs, KVM_REG_PPC_TM_LR, &env->tm_lr); > + kvm_set_one_reg(cs, KVM_REG_PPC_TM_CTR, &env->tm_ctr); > + kvm_set_one_reg(cs, KVM_REG_PPC_TM_FPSCR, &env->tm_fpscr); > + kvm_set_one_reg(cs, KVM_REG_PPC_TM_AMR, &env->tm_amr); > + kvm_set_one_reg(cs, KVM_REG_PPC_TM_PPR, &env->tm_ppr); > + kvm_set_one_reg(cs, KVM_REG_PPC_TM_VRSAVE, &env->tm_vrsave); > + kvm_set_one_reg(cs, KVM_REG_PPC_TM_VSCR, &env->tm_vscr); > + kvm_set_one_reg(cs, KVM_REG_PPC_TM_DSCR, &env->tm_dscr); > + kvm_set_one_reg(cs, KVM_REG_PPC_TM_TAR, &env->tm_tar); > + } > + > if (cap_papr) { > if (kvm_put_vpa(cs) < 0) { > DPRINTF("Warning: Unable to set VPA information to KVM\n"); > @@ -1090,6 +1109,25 @@ int kvm_arch_get_registers(CPUState *cs) > } > > #ifdef TARGET_PPC64 > + if ((cpu->env.msr >> MSR_TS) & 3) { > + for (i = 0; i < sizeof(env->tm_gpr)/sizeof(env->tm_gpr[0]); i++) { > + kvm_get_one_reg(cs, KVM_REG_PPC_TM_GPR(i), &env->tm_gpr[i]); > + } > + for (i = 0; i < sizeof(env->tm_vsr)/sizeof(env->tm_vsr[0]); i++) { > + kvm_get_one_reg(cs, KVM_REG_PPC_TM_VSR(i), &env->tm_vsr[i]); > + } > + kvm_get_one_reg(cs, KVM_REG_PPC_TM_CR, &env->tm_cr); > + kvm_get_one_reg(cs, KVM_REG_PPC_TM_LR, &env->tm_lr); > + kvm_get_one_reg(cs, KVM_REG_PPC_TM_CTR, &env->tm_ctr); > + kvm_get_one_reg(cs, KVM_REG_PPC_TM_FPSCR, &env->tm_fpscr); > + kvm_get_one_reg(cs, KVM_REG_PPC_TM_AMR, &env->tm_amr); > + kvm_get_one_reg(cs, KVM_REG_PPC_TM_PPR, &env->tm_ppr); > + kvm_get_one_reg(cs, KVM_REG_PPC_TM_VRSAVE, &env->tm_vrsave); > + kvm_get_one_reg(cs, KVM_REG_PPC_TM_VSCR, &env->tm_vscr); > + kvm_get_one_reg(cs, KVM_REG_PPC_TM_DSCR, &env->tm_dscr); > + kvm_get_one_reg(cs, KVM_REG_PPC_TM_TAR, &env->tm_tar); > + } > + > if (cap_papr) { > if (kvm_get_vpa(cs) < 0) { > DPRINTF("Warning: Unable to get VPA information from KVM\n"); > diff --git a/target-ppc/machine.c b/target-ppc/machine.c > index 063b379..691071d 100644 > --- a/target-ppc/machine.c > +++ b/target-ppc/machine.c > @@ -247,6 +247,37 @@ static const VMStateDescription vmstate_vsx = { > }, > }; > > +#ifdef TARGET_PPC64 > +/* Transactional memory state */ > +static bool tm_needed(void *opaque) > +{ > + PowerPCCPU *cpu = opaque; > + return (cpu->env.msr >> MSR_TS) & 3; > +} > + > +static const VMStateDescription vmstate_tm = { > + .name = "cpu/tm", > + .version_id = 1, > + .minimum_version_id = 1, > + .minimum_version_id_old = 1, > + .fields = (VMStateField []) { > + VMSTATE_UINTTL_ARRAY(env.tm_gpr, PowerPCCPU, 32), > + VMSTATE_AVR_ARRAY(env.tm_vsr, PowerPCCPU, 64), > + VMSTATE_UINT64(env.tm_cr, PowerPCCPU), > + VMSTATE_UINT64(env.tm_lr, PowerPCCPU), > + VMSTATE_UINT64(env.tm_ctr, PowerPCCPU), > + VMSTATE_UINT64(env.tm_fpscr, PowerPCCPU), > + VMSTATE_UINT64(env.tm_amr, PowerPCCPU), > + VMSTATE_UINT64(env.tm_ppr, PowerPCCPU), > + VMSTATE_UINT64(env.tm_vrsave, PowerPCCPU), > + VMSTATE_UINT32(env.tm_vscr, PowerPCCPU), > + VMSTATE_UINT64(env.tm_dscr, PowerPCCPU), > + VMSTATE_UINT64(env.tm_tar, PowerPCCPU), > + VMSTATE_END_OF_LIST() > + }, > +}; > +#endif > + > static bool sr_needed(void *opaque) > { > #ifdef TARGET_PPC64 > @@ -518,6 +549,9 @@ const VMStateDescription vmstate_ppc_cpu = { > .needed = sr_needed, > } , { > #ifdef TARGET_PPC64 > + .vmsd = &vmstate_tm, > + .needed = tm_needed, > + } , { > .vmsd = &vmstate_slb, > .needed = slb_needed, > } , { > diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c > index 1627bb0..4b20c29 100644 > --- a/target-ppc/translate_init.c > +++ b/target-ppc/translate_init.c > @@ -7025,14 +7025,22 @@ static void init_proc_POWER7 (CPUPPCState *env) > SPR_NOACCESS, SPR_NOACCESS, > &spr_read_generic, SPR_NOACCESS, > 0x80800000); > - spr_register(env, SPR_VRSAVE, "SPR_VRSAVE", > - &spr_read_generic, &spr_write_generic, > - &spr_read_generic, &spr_write_generic, > - 0x00000000); > - spr_register(env, SPR_PPR, "PPR", > - &spr_read_generic, &spr_write_generic, > - &spr_read_generic, &spr_write_generic, > - 0x00000000); > + spr_register_kvm(env, SPR_VRSAVE, "VRSAVE", > + &spr_read_generic, &spr_write_generic, > + &spr_read_generic, &spr_write_generic, > + KVM_REG_PPC_VRSAVE, 0x00000000); > + spr_register_kvm(env, SPR_PPR, "PPR", > + &spr_read_generic, &spr_write_generic, > + &spr_read_generic, &spr_write_generic, > + KVM_REG_PPC_PPR, 0x00000000); > + spr_register_kvm(env, SPR_BOOK3S_SIAR, "SIAR", > + &spr_read_generic, &spr_write_generic, > + &spr_read_generic, &spr_write_generic, > + KVM_REG_PPC_SIAR, 0x00000000); > + spr_register_kvm(env, SPR_BOOK3S_SDAR, "SDAR", > + &spr_read_generic, &spr_write_generic, > + &spr_read_generic, &spr_write_generic, > + KVM_REG_PPC_SDAR, 0x00000000); > /* Logical partitionning */ > spr_register_kvm(env, SPR_LPCR, "LPCR", > SPR_NOACCESS, SPR_NOACCESS,