Message ID | 20230531012313.19891-3-npiggin@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | target/ppc: initial SMT support in TCG | expand |
On 5/31/23 03:23, Nicholas Piggin wrote: > SMT TCG emulation needs to be able to iterate over siblings in a core, > and needs to serialise core access to shared SPRs and state. > > Signed-off-by: Nicholas Piggin <npiggin@gmail.com> > --- > target/ppc/cpu.h | 9 +++++++++ > target/ppc/cpu_init.c | 5 +++++ > target/ppc/translate.c | 20 ++++++++++++++++++++ > 3 files changed, 34 insertions(+) > > diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h > index 1f23b81e90..b594408a8d 100644 > --- a/target/ppc/cpu.h > +++ b/target/ppc/cpu.h > @@ -672,6 +672,8 @@ enum { > POWERPC_FLAG_TM = 0x00100000, > /* Has SCV (ISA 3.00) */ > POWERPC_FLAG_SCV = 0x00200000, > + /* Has >1 thread per core */ > + POWERPC_FLAG_SMT = 0x00400000, > }; > > /* > @@ -1266,6 +1268,13 @@ struct CPUArchState { > uint64_t pmu_base_time; > }; > > +#define _CORE_ID(cs) \ > + (POWERPC_CPU(cs)->env.spr_cb[SPR_PIR].default_value & ~(cs->nr_threads - 1)) > + > +#define THREAD_SIBLING_FOREACH(cs, cs_sibling) \ > + CPU_FOREACH(cs_sibling) \ > + if (_CORE_ID(cs) == _CORE_ID(cs_sibling)) > + May be introduce these helpers when needed (and if needed). > #define SET_FIT_PERIOD(a_, b_, c_, d_) \ > do { \ > env->fit_period[0] = (a_); \ > diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c > index aa364f36f6..5035f6dada 100644 > --- a/target/ppc/cpu_init.c > +++ b/target/ppc/cpu_init.c > @@ -6754,6 +6754,7 @@ static void ppc_cpu_realize(DeviceState *dev, Error **errp) > { > CPUState *cs = CPU(dev); > PowerPCCPU *cpu = POWERPC_CPU(dev); > + CPUPPCState *env = &cpu->env; > PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); > Error *local_err = NULL; > > @@ -6785,6 +6786,10 @@ static void ppc_cpu_realize(DeviceState *dev, Error **errp) > > pcc->parent_realize(dev, errp); > > + if (env_cpu(env)->nr_threads > 1) { > + env->flags |= POWERPC_FLAG_SMT; > + } > + > return; > > unrealize: > diff --git a/target/ppc/translate.c b/target/ppc/translate.c > index b6bab4c234..72270c2163 100644 > --- a/target/ppc/translate.c > +++ b/target/ppc/translate.c > @@ -227,6 +227,26 @@ struct opc_handler_t { > void (*handler)(DisasContext *ctx); > }; > > +static inline bool gen_serialize(DisasContext *ctx) > +{ > + if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { > + /* Restart with exclusive lock. */ > + gen_helper_exit_atomic(cpu_env); > + ctx->base.is_jmp = DISAS_NORETURN; > + return false; > + } > + return true; > +} > + > +static inline bool gen_serialize_core(DisasContext *ctx) > +{ > + if (ctx->flags & POWERPC_FLAG_SMT) { > + return gen_serialize(ctx); > + } > + > + return true; > +} > + > /* SPR load/store helpers */ > static inline void gen_load_spr(TCGv t, int reg) > {
On Wed May 31, 2023 at 5:25 PM AEST, Cédric Le Goater wrote: > On 5/31/23 03:23, Nicholas Piggin wrote: > > SMT TCG emulation needs to be able to iterate over siblings in a core, > > and needs to serialise core access to shared SPRs and state. > > > > Signed-off-by: Nicholas Piggin <npiggin@gmail.com> > > --- > > target/ppc/cpu.h | 9 +++++++++ > > target/ppc/cpu_init.c | 5 +++++ > > target/ppc/translate.c | 20 ++++++++++++++++++++ > > 3 files changed, 34 insertions(+) > > > > diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h > > index 1f23b81e90..b594408a8d 100644 > > --- a/target/ppc/cpu.h > > +++ b/target/ppc/cpu.h > > @@ -672,6 +672,8 @@ enum { > > POWERPC_FLAG_TM = 0x00100000, > > /* Has SCV (ISA 3.00) */ > > POWERPC_FLAG_SCV = 0x00200000, > > + /* Has >1 thread per core */ > > + POWERPC_FLAG_SMT = 0x00400000, > > }; > > > > /* > > @@ -1266,6 +1268,13 @@ struct CPUArchState { > > uint64_t pmu_base_time; > > }; > > > > +#define _CORE_ID(cs) \ > > + (POWERPC_CPU(cs)->env.spr_cb[SPR_PIR].default_value & ~(cs->nr_threads - 1)) > > + > > +#define THREAD_SIBLING_FOREACH(cs, cs_sibling) \ > > + CPU_FOREACH(cs_sibling) \ > > + if (_CORE_ID(cs) == _CORE_ID(cs_sibling)) > > + > > > May be introduce these helpers when needed (and if needed). Yeah that's a good idea, I tried to structure it so you could see the main components first, but for a real patch it might indeed be better add them as needed. Thanks, Nick
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 1f23b81e90..b594408a8d 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -672,6 +672,8 @@ enum { POWERPC_FLAG_TM = 0x00100000, /* Has SCV (ISA 3.00) */ POWERPC_FLAG_SCV = 0x00200000, + /* Has >1 thread per core */ + POWERPC_FLAG_SMT = 0x00400000, }; /* @@ -1266,6 +1268,13 @@ struct CPUArchState { uint64_t pmu_base_time; }; +#define _CORE_ID(cs) \ + (POWERPC_CPU(cs)->env.spr_cb[SPR_PIR].default_value & ~(cs->nr_threads - 1)) + +#define THREAD_SIBLING_FOREACH(cs, cs_sibling) \ + CPU_FOREACH(cs_sibling) \ + if (_CORE_ID(cs) == _CORE_ID(cs_sibling)) + #define SET_FIT_PERIOD(a_, b_, c_, d_) \ do { \ env->fit_period[0] = (a_); \ diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index aa364f36f6..5035f6dada 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -6754,6 +6754,7 @@ static void ppc_cpu_realize(DeviceState *dev, Error **errp) { CPUState *cs = CPU(dev); PowerPCCPU *cpu = POWERPC_CPU(dev); + CPUPPCState *env = &cpu->env; PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); Error *local_err = NULL; @@ -6785,6 +6786,10 @@ static void ppc_cpu_realize(DeviceState *dev, Error **errp) pcc->parent_realize(dev, errp); + if (env_cpu(env)->nr_threads > 1) { + env->flags |= POWERPC_FLAG_SMT; + } + return; unrealize: diff --git a/target/ppc/translate.c b/target/ppc/translate.c index b6bab4c234..72270c2163 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -227,6 +227,26 @@ struct opc_handler_t { void (*handler)(DisasContext *ctx); }; +static inline bool gen_serialize(DisasContext *ctx) +{ + if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { + /* Restart with exclusive lock. */ + gen_helper_exit_atomic(cpu_env); + ctx->base.is_jmp = DISAS_NORETURN; + return false; + } + return true; +} + +static inline bool gen_serialize_core(DisasContext *ctx) +{ + if (ctx->flags & POWERPC_FLAG_SMT) { + return gen_serialize(ctx); + } + + return true; +} + /* SPR load/store helpers */ static inline void gen_load_spr(TCGv t, int reg) {
SMT TCG emulation needs to be able to iterate over siblings in a core, and needs to serialise core access to shared SPRs and state. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> --- target/ppc/cpu.h | 9 +++++++++ target/ppc/cpu_init.c | 5 +++++ target/ppc/translate.c | 20 ++++++++++++++++++++ 3 files changed, 34 insertions(+)