[PULL 22/26] target/ppc: powerpc_excp: Stop passing excp_model around

2022-01-03 Thread Cédric Le Goater
From: Fabiano Rosas 

We can just access it directly in powerpc_excp.

Signed-off-by: Fabiano Rosas 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Richard Henderson 
Reviewed-by: David Gibson 
[ clg: Took into account removal of inline ]
Message-Id: <20211229165751.3774248-6-faro...@linux.ibm.com>
Signed-off-by: Cédric Le Goater 
---
 target/ppc/excp_helper.c | 43 
 1 file changed, 21 insertions(+), 22 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 2c20a8060cf9..a779dc936a55 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -365,10 +365,11 @@ static void powerpc_set_excp_state(PowerPCCPU *cpu,
  * Note that this function should be greatly optimized when called
  * with a constant excp, from ppc_hw_interrupt
  */
-static void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
+static void powerpc_excp(PowerPCCPU *cpu, int excp)
 {
 CPUState *cs = CPU(cpu);
 CPUPPCState *env = >env;
+int excp_model = env->excp_model;
 target_ulong msr, new_msr, vector;
 int srr0, srr1, lev = -1;
 
@@ -952,9 +953,8 @@ static void powerpc_excp(PowerPCCPU *cpu, int excp_model, 
int excp)
 void ppc_cpu_do_interrupt(CPUState *cs)
 {
 PowerPCCPU *cpu = POWERPC_CPU(cs);
-CPUPPCState *env = >env;
 
-powerpc_excp(cpu, env->excp_model, cs->exception_index);
+powerpc_excp(cpu, cs->exception_index);
 }
 
 static void ppc_hw_interrupt(CPUPPCState *env)
@@ -965,20 +965,20 @@ static void ppc_hw_interrupt(CPUPPCState *env)
 /* External reset */
 if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_RESET);
+powerpc_excp(cpu, POWERPC_EXCP_RESET);
 return;
 }
 /* Machine check exception */
 if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_MCHECK);
+powerpc_excp(cpu, POWERPC_EXCP_MCHECK);
 return;
 }
 #if 0 /* TODO */
 /* External debug exception */
 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DEBUG);
+powerpc_excp(cpu, POWERPC_EXCP_DEBUG);
 return;
 }
 #endif
@@ -998,7 +998,7 @@ static void ppc_hw_interrupt(CPUPPCState *env)
 if ((async_deliver || msr_hv == 0) && hdice) {
 /* HDEC clears on delivery */
 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_HDECR);
+powerpc_excp(cpu, POWERPC_EXCP_HDECR);
 return;
 }
 }
@@ -1008,7 +1008,7 @@ static void ppc_hw_interrupt(CPUPPCState *env)
 /* LPCR will be clear when not supported so this will work */
 bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE);
 if ((async_deliver || msr_hv == 0) && hvice) {
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_HVIRT);
+powerpc_excp(cpu, POWERPC_EXCP_HVIRT);
 return;
 }
 }
@@ -1020,14 +1020,14 @@ static void ppc_hw_interrupt(CPUPPCState *env)
 /* HEIC blocks delivery to the hypervisor */
 if ((async_deliver && !(heic && msr_hv && !msr_pr)) ||
 (env->has_hv_mode && msr_hv == 0 && !lpes0)) {
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_EXTERNAL);
+powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL);
 return;
 }
 }
 if (msr_ce != 0) {
 /* External critical interrupt */
 if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) {
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_CRITICAL);
+powerpc_excp(cpu, POWERPC_EXCP_CRITICAL);
 return;
 }
 }
@@ -1035,24 +1035,24 @@ static void ppc_hw_interrupt(CPUPPCState *env)
 /* Watchdog timer on embedded PowerPC */
 if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_WDT);
+powerpc_excp(cpu, POWERPC_EXCP_WDT);
 return;
 }
 if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) {
 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL);
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORCI);
+powerpc_excp(cpu, POWERPC_EXCP_DOORCI);
 return;
 }
 /* Fixed interval timer on embedded PowerPC */
 if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
-powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_FIT);
+powerpc_excp(cpu, 

[PULL 18/26] target/ppc: powerpc_excp: Set alternate SRRs directly

2022-01-03 Thread Cédric Le Goater
From: Fabiano Rosas 

There are currently only two interrupts that use alternate SRRs, so
let them write to them directly during the setup code.

No functional change intended.

Signed-off-by: Fabiano Rosas 
Reviewed-by: Richard Henderson 
Reviewed-by: Cédric Le Goater 
Reviewed-by: David Gibson 
Message-Id: <20211229165751.3774248-2-faro...@linux.ibm.com>
Signed-off-by: Cédric Le Goater 
---
 target/ppc/excp_helper.c | 23 ---
 1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index e3380722c5c4..c7efbdc3051b 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -370,7 +370,7 @@ static void powerpc_excp(PowerPCCPU *cpu, int excp_model, 
int excp)
 CPUState *cs = CPU(cpu);
 CPUPPCState *env = >env;
 target_ulong msr, new_msr, vector;
-int srr0, srr1, asrr0, asrr1, lev = -1;
+int srr0, srr1, lev = -1;
 
 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
   " => %s (%d) error=%02x\n", env->nip, 
powerpc_excp_name(excp),
@@ -392,8 +392,6 @@ static void powerpc_excp(PowerPCCPU *cpu, int excp_model, 
int excp)
 /* target registers */
 srr0 = SPR_SRR0;
 srr1 = SPR_SRR1;
-asrr0 = -1;
-asrr1 = -1;
 
 /*
  * check for special resume at 0x100 from doze/nap/sleep/winkle on
@@ -483,8 +481,9 @@ static void powerpc_excp(PowerPCCPU *cpu, int excp_model, 
int excp)
 /* FIXME: choose one or the other based on CPU type */
 srr0 = SPR_BOOKE_MCSRR0;
 srr1 = SPR_BOOKE_MCSRR1;
-asrr0 = SPR_BOOKE_CSRR0;
-asrr1 = SPR_BOOKE_CSRR1;
+
+env->spr[SPR_BOOKE_CSRR0] = env->nip;
+env->spr[SPR_BOOKE_CSRR1] = msr;
 break;
 default:
 break;
@@ -643,8 +642,10 @@ static void powerpc_excp(PowerPCCPU *cpu, int excp_model, 
int excp)
 /* FIXME: choose one or the other based on CPU type */
 srr0 = SPR_BOOKE_DSRR0;
 srr1 = SPR_BOOKE_DSRR1;
-asrr0 = SPR_BOOKE_CSRR0;
-asrr1 = SPR_BOOKE_CSRR1;
+
+env->spr[SPR_BOOKE_CSRR0] = env->nip;
+env->spr[SPR_BOOKE_CSRR1] = msr;
+
 /* DBSR already modified by caller */
 } else {
 cpu_abort(cs, "Debug exception triggered on unsupported model\n");
@@ -911,14 +912,6 @@ static void powerpc_excp(PowerPCCPU *cpu, int excp_model, 
int excp)
 
 vector |= env->excp_prefix;
 
-/* If any alternate SRR register are defined, duplicate saved values */
-if (asrr0 != -1) {
-env->spr[asrr0] = env->nip;
-}
-if (asrr1 != -1) {
-env->spr[asrr1] = msr;
-}
-
 #if defined(TARGET_PPC64)
 if (excp_model == POWERPC_EXCP_BOOKE) {
 if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {
-- 
2.31.1




Re: [PATCH] target/ppc: Check effective address validity

2022-01-03 Thread Cédric Le Goater

On 12/31/21 08:31, Cédric Le Goater wrote:

For Radix translation, the EA range is 64-bits. when EA(2:11) are
nonzero, a segment interrupt should occur.

Signed-off-by: Cédric Le Goater 



Applied in ppc-next.

Thanks,

C.




[PULL 08/26] target/ppc: Remove static inline

2022-01-03 Thread Cédric Le Goater
The compiler should know better how to inline code if necessary.

Suggested-by: Richard Henderson 
Signed-off-by: Cédric Le Goater 
Reviewed-by: Richard Henderson 
Message-Id: <20220103063441.3424853-2-...@kaod.org>
Signed-off-by: Cédric Le Goater 
---
 target/ppc/excp_helper.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index f90e616aacda..8ba93d25aee6 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -36,7 +36,7 @@
 /* Exception processing */
 #if !defined(CONFIG_USER_ONLY)
 
-static inline void dump_syscall(CPUPPCState *env)
+static void dump_syscall(CPUPPCState *env)
 {
 qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64
   " r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64
@@ -48,7 +48,7 @@ static inline void dump_syscall(CPUPPCState *env)
   ppc_dump_gpr(env, 8), env->nip);
 }
 
-static inline void dump_hcall(CPUPPCState *env)
+static void dump_hcall(CPUPPCState *env)
 {
 qemu_log_mask(CPU_LOG_INT, "hypercall r3=%016" PRIx64
   " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64
@@ -161,7 +161,7 @@ static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState 
*env, int excp,
  * | a | h  | 11  | 1   | 1   | h   |
  * ++
  */
-static inline void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp_model, int 
excp,
+static void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp_model, int excp,
   target_ulong msr,
   target_ulong *new_msr,
   target_ulong *vector)
@@ -258,7 +258,7 @@ static inline void ppc_excp_apply_ail(PowerPCCPU *cpu, int 
excp_model, int excp,
 #endif
 }
 
-static inline void powerpc_set_excp_state(PowerPCCPU *cpu,
+static void powerpc_set_excp_state(PowerPCCPU *cpu,
   target_ulong vector, target_ulong 
msr)
 {
 CPUState *cs = CPU(cpu);
@@ -293,7 +293,7 @@ static inline void powerpc_set_excp_state(PowerPCCPU *cpu,
  * Note that this function should be greatly optimized when called
  * with a constant excp, from ppc_hw_interrupt
  */
-static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
+static void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
 {
 CPUState *cs = CPU(cpu);
 CPUPPCState *env = >env;
@@ -1167,7 +1167,7 @@ void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t 
insn)
 #endif /* defined(TARGET_PPC64) */
 #endif /* CONFIG_TCG */
 
-static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
+static void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
 {
 CPUState *cs = env_cpu(env);
 
-- 
2.31.1




[PULL 12/26] ppc/ppc405: Restore TCR and STR write handlers

2022-01-03 Thread Cédric Le Goater
The 405 timers were broken when booke support was added. Assumption
was made that the register numbers were the same but it's not :

SPR_BOOKE_TSR (0x150)
SPR_BOOKE_TCR (0x154)
SPR_40x_TSR   (0x3D8)
SPR_40x_TCR   (0x3DA)

Cc: Christophe Leroy 
Fixes: ddd1055b07fd ("PPC: booke timers")
Reviewed-by: Richard Henderson 
Signed-off-by: Cédric Le Goater 
Message-Id: <20211222064025.1541490-5-...@kaod.org>
Signed-off-by: Cédric Le Goater 
Message-Id: <20220103063441.3424853-6-...@kaod.org>
Signed-off-by: Cédric Le Goater 
---
 target/ppc/cpu.h |  2 ++
 target/ppc/helper.h  |  2 ++
 target/ppc/spr_tcg.h |  2 ++
 hw/ppc/ppc.c | 25 +
 target/ppc/cpu_init.c|  4 ++--
 target/ppc/timebase_helper.c | 10 ++
 target/ppc/translate.c   | 12 
 hw/ppc/trace-events  |  2 ++
 8 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index fc66c3561dab..4808e10ebe8b 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1399,6 +1399,8 @@ target_ulong load_40x_pit(CPUPPCState *env);
 void store_40x_pit(CPUPPCState *env, target_ulong val);
 void store_40x_dbcr0(CPUPPCState *env, uint32_t val);
 void store_40x_sler(CPUPPCState *env, uint32_t val);
+void store_40x_tcr(CPUPPCState *env, target_ulong val);
+void store_40x_tsr(CPUPPCState *env, target_ulong val);
 void store_booke_tcr(CPUPPCState *env, target_ulong val);
 void store_booke_tsr(CPUPPCState *env, target_ulong val);
 void ppc_tlb_invalidate_all(CPUPPCState *env);
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index fb6cac38b4c5..f9c72dcd504d 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -706,6 +706,8 @@ DEF_HELPER_2(store_hid0_601, void, env, tl)
 DEF_HELPER_3(store_403_pbr, void, env, i32, tl)
 DEF_HELPER_FLAGS_1(load_40x_pit, TCG_CALL_NO_RWG, tl, env)
 DEF_HELPER_FLAGS_2(store_40x_pit, TCG_CALL_NO_RWG, void, env, tl)
+DEF_HELPER_FLAGS_2(store_40x_tcr, TCG_CALL_NO_RWG, void, env, tl)
+DEF_HELPER_FLAGS_2(store_40x_tsr, TCG_CALL_NO_RWG, void, env, tl)
 DEF_HELPER_2(store_40x_dbcr0, void, env, tl)
 DEF_HELPER_2(store_40x_sler, void, env, tl)
 DEF_HELPER_FLAGS_2(store_booke_tcr, TCG_CALL_NO_RWG, void, env, tl)
diff --git a/target/ppc/spr_tcg.h b/target/ppc/spr_tcg.h
index f98d97c0ba17..64cf5302cb86 100644
--- a/target/ppc/spr_tcg.h
+++ b/target/ppc/spr_tcg.h
@@ -87,6 +87,8 @@ void spr_read_40x_pit(DisasContext *ctx, int gprn, int sprn);
 void spr_write_40x_pit(DisasContext *ctx, int sprn, int gprn);
 void spr_write_40x_dbcr0(DisasContext *ctx, int sprn, int gprn);
 void spr_write_40x_sler(DisasContext *ctx, int sprn, int gprn);
+void spr_write_40x_tcr(DisasContext *ctx, int sprn, int gprn);
+void spr_write_40x_tsr(DisasContext *ctx, int sprn, int gprn);
 void spr_write_booke_tcr(DisasContext *ctx, int sprn, int gprn);
 void spr_write_booke_tsr(DisasContext *ctx, int sprn, int gprn);
 void spr_read_403_pbr(DisasContext *ctx, int gprn, int sprn);
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 818d75798584..cca99cb86f81 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -1300,6 +1300,31 @@ target_ulong load_40x_pit (CPUPPCState *env)
 return cpu_ppc_load_decr(env);
 }
 
+void store_40x_tsr(CPUPPCState *env, target_ulong val)
+{
+PowerPCCPU *cpu = env_archcpu(env);
+
+trace_ppc40x_store_tcr(val);
+
+env->spr[SPR_40x_TSR] &= ~(val & 0xFC00);
+if (val & 0x8000) {
+ppc_set_irq(cpu, PPC_INTERRUPT_PIT, 0);
+}
+}
+
+void store_40x_tcr(CPUPPCState *env, target_ulong val)
+{
+PowerPCCPU *cpu = env_archcpu(env);
+ppc_tb_t *tb_env;
+
+trace_ppc40x_store_tsr(val);
+
+tb_env = env->tb_env;
+env->spr[SPR_40x_TCR] = val & 0xFFC0;
+start_stop_pit(env, tb_env, 1);
+cpu_4xx_wdt_cb(cpu);
+}
+
 static void ppc_40x_set_tb_clk (void *opaque, uint32_t freq)
 {
 CPUPPCState *env = opaque;
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 06ef15cd9e4e..b5e2fde9ec4d 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -1440,11 +1440,11 @@ static void register_40x_sprs(CPUPPCState *env)
  0x);
 spr_register(env, SPR_40x_TCR, "TCR",
  SPR_NOACCESS, SPR_NOACCESS,
- _read_generic, _write_booke_tcr,
+ _read_generic, _write_40x_tcr,
  0x);
 spr_register(env, SPR_40x_TSR, "TSR",
  SPR_NOACCESS, SPR_NOACCESS,
- _read_generic, _write_booke_tsr,
+ _read_generic, _write_40x_tsr,
  0x);
 }
 
diff --git a/target/ppc/timebase_helper.c b/target/ppc/timebase_helper.c
index 8ff4080eb91e..af378318c19c 100644
--- a/target/ppc/timebase_helper.c
+++ b/target/ppc/timebase_helper.c
@@ -144,6 +144,16 @@ void helper_store_40x_pit(CPUPPCState *env, target_ulong 
val)
 store_40x_pit(env, val);
 }
 
+void 

[PULL 13/26] ppc/ppc405: Rework ppc_40x_timers_init() to use a PowerPCCPU

2022-01-03 Thread Cédric Le Goater
This is a small cleanup to ease reading. It includes the removal of a
check done on the returned value of g_malloc0(), which can not fail.

Reviewed-by: Richard Henderson 
Signed-off-by: Cédric Le Goater 
Message-Id: <20211222064025.1541490-6-...@kaod.org>
Signed-off-by: Cédric Le Goater 
Message-Id: <20220103063441.3424853-7-...@kaod.org>
Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc.c | 42 +++---
 1 file changed, 19 insertions(+), 23 deletions(-)

diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index cca99cb86f81..bb5bee9a3382 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -1124,14 +1124,12 @@ struct ppc40x_timer_t {
 /* Fixed interval timer */
 static void cpu_4xx_fit_cb (void *opaque)
 {
-PowerPCCPU *cpu;
-CPUPPCState *env;
+PowerPCCPU *cpu = opaque;
+CPUPPCState *env = >env;
 ppc_tb_t *tb_env;
 ppc40x_timer_t *ppc40x_timer;
 uint64_t now, next;
 
-env = opaque;
-cpu = env_archcpu(env);
 tb_env = env->tb_env;
 ppc40x_timer = tb_env->opaque;
 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
@@ -1193,13 +1191,11 @@ static void start_stop_pit (CPUPPCState *env, ppc_tb_t 
*tb_env, int is_excp)
 
 static void cpu_4xx_pit_cb (void *opaque)
 {
-PowerPCCPU *cpu;
-CPUPPCState *env;
+PowerPCCPU *cpu = opaque;
+CPUPPCState *env = >env;
 ppc_tb_t *tb_env;
 ppc40x_timer_t *ppc40x_timer;
 
-env = opaque;
-cpu = env_archcpu(env);
 tb_env = env->tb_env;
 ppc40x_timer = tb_env->opaque;
 env->spr[SPR_40x_TSR] |= 1 << 27;
@@ -1216,14 +1212,12 @@ static void cpu_4xx_pit_cb (void *opaque)
 /* Watchdog timer */
 static void cpu_4xx_wdt_cb (void *opaque)
 {
-PowerPCCPU *cpu;
-CPUPPCState *env;
+PowerPCCPU *cpu = opaque;
+CPUPPCState *env = >env;
 ppc_tb_t *tb_env;
 ppc40x_timer_t *ppc40x_timer;
 uint64_t now, next;
 
-env = opaque;
-cpu = env_archcpu(env);
 tb_env = env->tb_env;
 ppc40x_timer = tb_env->opaque;
 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
@@ -1341,24 +1335,26 @@ clk_setup_cb ppc_40x_timers_init (CPUPPCState *env, 
uint32_t freq,
 {
 ppc_tb_t *tb_env;
 ppc40x_timer_t *ppc40x_timer;
+PowerPCCPU *cpu = env_archcpu(env);
+
+trace_ppc40x_timers_init(freq);
 
 tb_env = g_malloc0(sizeof(ppc_tb_t));
+ppc40x_timer = g_malloc0(sizeof(ppc40x_timer_t));
+
 env->tb_env = tb_env;
 tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED;
-ppc40x_timer = g_malloc0(sizeof(ppc40x_timer_t));
 tb_env->tb_freq = freq;
 tb_env->decr_freq = freq;
 tb_env->opaque = ppc40x_timer;
-trace_ppc40x_timers_init(freq);
-if (ppc40x_timer != NULL) {
-/* We use decr timer for PIT */
-tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, _4xx_pit_cb, 
env);
-ppc40x_timer->fit_timer =
-timer_new_ns(QEMU_CLOCK_VIRTUAL, _4xx_fit_cb, env);
-ppc40x_timer->wdt_timer =
-timer_new_ns(QEMU_CLOCK_VIRTUAL, _4xx_wdt_cb, env);
-ppc40x_timer->decr_excp = decr_excp;
-}
+
+/* We use decr timer for PIT */
+tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, _4xx_pit_cb, 
cpu);
+ppc40x_timer->fit_timer =
+timer_new_ns(QEMU_CLOCK_VIRTUAL, _4xx_fit_cb, cpu);
+ppc40x_timer->wdt_timer =
+timer_new_ns(QEMU_CLOCK_VIRTUAL, _4xx_wdt_cb, cpu);
+ppc40x_timer->decr_excp = decr_excp;
 
 return _40x_set_tb_clk;
 }
-- 
2.31.1




[PULL 09/26] target/ppc: Print out literal exception names in logs

2022-01-03 Thread Cédric Le Goater
It facilitates reading the logs when mask CPU_LOG_INT is activated. We
should do the same for error codes.

Cc: Fabiano Rosas 
Signed-off-by: Cédric Le Goater 
Reviewed-by: Fabiano Rosas 
Reviewed-by: David Gibson 
Reviewed-by: Richard Henderson 
Message-Id: <20211222064025.1541490-2-...@kaod.org>
Signed-off-by: Cédric Le Goater 
Message-Id: <20220103063441.3424853-3-...@kaod.org>
Signed-off-by: Cédric Le Goater 
---
 target/ppc/excp_helper.c | 75 +++-
 1 file changed, 74 insertions(+), 1 deletion(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 8ba93d25aee6..e3380722c5c4 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -36,6 +36,78 @@
 /* Exception processing */
 #if !defined(CONFIG_USER_ONLY)
 
+static const char *powerpc_excp_name(int excp)
+{
+switch (excp) {
+case POWERPC_EXCP_CRITICAL: return "CRITICAL";
+case POWERPC_EXCP_MCHECK:   return "MCHECK";
+case POWERPC_EXCP_DSI:  return "DSI";
+case POWERPC_EXCP_ISI:  return "ISI";
+case POWERPC_EXCP_EXTERNAL: return "EXTERNAL";
+case POWERPC_EXCP_ALIGN:return "ALIGN";
+case POWERPC_EXCP_PROGRAM:  return "PROGRAM";
+case POWERPC_EXCP_FPU:  return "FPU";
+case POWERPC_EXCP_SYSCALL:  return "SYSCALL";
+case POWERPC_EXCP_APU:  return "APU";
+case POWERPC_EXCP_DECR: return "DECR";
+case POWERPC_EXCP_FIT:  return "FIT";
+case POWERPC_EXCP_WDT:  return "WDT";
+case POWERPC_EXCP_DTLB: return "DTLB";
+case POWERPC_EXCP_ITLB: return "ITLB";
+case POWERPC_EXCP_DEBUG:return "DEBUG";
+case POWERPC_EXCP_SPEU: return "SPEU";
+case POWERPC_EXCP_EFPDI:return "EFPDI";
+case POWERPC_EXCP_EFPRI:return "EFPRI";
+case POWERPC_EXCP_EPERFM:   return "EPERFM";
+case POWERPC_EXCP_DOORI:return "DOORI";
+case POWERPC_EXCP_DOORCI:   return "DOORCI";
+case POWERPC_EXCP_GDOORI:   return "GDOORI";
+case POWERPC_EXCP_GDOORCI:  return "GDOORCI";
+case POWERPC_EXCP_HYPPRIV:  return "HYPPRIV";
+case POWERPC_EXCP_RESET:return "RESET";
+case POWERPC_EXCP_DSEG: return "DSEG";
+case POWERPC_EXCP_ISEG: return "ISEG";
+case POWERPC_EXCP_HDECR:return "HDECR";
+case POWERPC_EXCP_TRACE:return "TRACE";
+case POWERPC_EXCP_HDSI: return "HDSI";
+case POWERPC_EXCP_HISI: return "HISI";
+case POWERPC_EXCP_HDSEG:return "HDSEG";
+case POWERPC_EXCP_HISEG:return "HISEG";
+case POWERPC_EXCP_VPU:  return "VPU";
+case POWERPC_EXCP_PIT:  return "PIT";
+case POWERPC_EXCP_IO:   return "IO";
+case POWERPC_EXCP_RUNM: return "RUNM";
+case POWERPC_EXCP_EMUL: return "EMUL";
+case POWERPC_EXCP_IFTLB:return "IFTLB";
+case POWERPC_EXCP_DLTLB:return "DLTLB";
+case POWERPC_EXCP_DSTLB:return "DSTLB";
+case POWERPC_EXCP_FPA:  return "FPA";
+case POWERPC_EXCP_DABR: return "DABR";
+case POWERPC_EXCP_IABR: return "IABR";
+case POWERPC_EXCP_SMI:  return "SMI";
+case POWERPC_EXCP_PERFM:return "PERFM";
+case POWERPC_EXCP_THERM:return "THERM";
+case POWERPC_EXCP_VPUA: return "VPUA";
+case POWERPC_EXCP_SOFTP:return "SOFTP";
+case POWERPC_EXCP_MAINT:return "MAINT";
+case POWERPC_EXCP_MEXTBR:   return "MEXTBR";
+case POWERPC_EXCP_NMEXTBR:  return "NMEXTBR";
+case POWERPC_EXCP_ITLBE:return "ITLBE";
+case POWERPC_EXCP_DTLBE:return "DTLBE";
+case POWERPC_EXCP_VSXU: return "VSXU";
+case POWERPC_EXCP_FU:   return "FU";
+case POWERPC_EXCP_HV_EMU:   return "HV_EMU";
+case POWERPC_EXCP_HV_MAINT: return "HV_MAINT";
+case POWERPC_EXCP_HV_FU:return "HV_FU";
+case POWERPC_EXCP_SDOOR:return "SDOOR";
+case POWERPC_EXCP_SDOOR_HV: return "SDOOR_HV";
+case POWERPC_EXCP_HVIRT:return "HVIRT";
+case POWERPC_EXCP_SYSCALL_VECTORED: return "SYSCALL_VECTORED";
+default:
+g_assert_not_reached();
+}
+}
+
 static void dump_syscall(CPUPPCState *env)
 {
 qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64
@@ -301,7 +373,8 @@ static void powerpc_excp(PowerPCCPU *cpu, int excp_model, 
int excp)
 int srr0, srr1, asrr0, asrr1, lev = -1;
 
 qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
-  " => %08x (%02x)\n", env->nip, excp, env->error_code);
+  " => %s (%d) error=%02x\n", env->nip, 
powerpc_excp_name(excp),
+  excp, env->error_code);
 
 /* new srr1 value excluding must-be-zero bits */
 if (excp_model == POWERPC_EXCP_BOOKE) {
-- 
2.31.1




[PULL 25/26] target/ppc: Use env->pnc_cyc_cnt

2022-01-03 Thread Cédric Le Goater
From: Richard Henderson 

Use the cached pmc_cyc_cnt value in pmu_update_cycles
and pmc_update_overflow_timer.  This leaves pmc_get_event
and pmc_is_inactive unused, so remove them.

Signed-off-by: Richard Henderson 
Message-Id: <20220103224746.167831-4-danielhb...@gmail.com>
Signed-off-by: Cédric Le Goater 
---
 target/ppc/power8-pmu.c | 107 
 1 file changed, 9 insertions(+), 98 deletions(-)

diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 27c4c7915bf3..73713ca2a320 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -24,19 +24,6 @@
 
 #define PMC_COUNTER_NEGATIVE_VAL 0x8000UL
 
-static bool pmc_is_inactive(CPUPPCState *env, int sprn)
-{
-if (env->spr[SPR_POWER_MMCR0] & MMCR0_FC) {
-return true;
-}
-
-if (sprn < SPR_POWER_PMC5) {
-return env->spr[SPR_POWER_MMCR0] & MMCR0_FC14;
-}
-
-return env->spr[SPR_POWER_MMCR0] & MMCR0_FC56;
-}
-
 static bool pmc_has_overflow_enabled(CPUPPCState *env, int sprn)
 {
 if (sprn == SPR_POWER_PMC1) {
@@ -46,80 +33,6 @@ static bool pmc_has_overflow_enabled(CPUPPCState *env, int 
sprn)
 return env->spr[SPR_POWER_MMCR0] & MMCR0_PMCjCE;
 }
 
-/*
- * For PMCs 1-4, IBM POWER chips has support for an implementation
- * dependent event, 0x1E, that enables cycle counting. The Linux kernel
- * makes extensive use of 0x1E, so let's also support it.
- *
- * Likewise, event 0x2 is an implementation-dependent event that IBM
- * POWER chips implement (at least since POWER8) that is equivalent to
- * PM_INST_CMPL. Let's support this event on PMCs 1-4 as well.
- */
-static PMUEventType pmc_get_event(CPUPPCState *env, int sprn)
-{
-uint8_t mmcr1_evt_extr[] = { MMCR1_PMC1EVT_EXTR, MMCR1_PMC2EVT_EXTR,
- MMCR1_PMC3EVT_EXTR, MMCR1_PMC4EVT_EXTR };
-PMUEventType evt_type = PMU_EVENT_INVALID;
-uint8_t pmcsel;
-int i;
-
-if (pmc_is_inactive(env, sprn)) {
-return PMU_EVENT_INACTIVE;
-}
-
-if (sprn == SPR_POWER_PMC5) {
-return PMU_EVENT_INSTRUCTIONS;
-}
-
-if (sprn == SPR_POWER_PMC6) {
-return PMU_EVENT_CYCLES;
-}
-
-i = sprn - SPR_POWER_PMC1;
-pmcsel = extract64(env->spr[SPR_POWER_MMCR1], mmcr1_evt_extr[i],
-   MMCR1_EVT_SIZE);
-
-switch (pmcsel) {
-case 0x2:
-evt_type = PMU_EVENT_INSTRUCTIONS;
-break;
-case 0x1E:
-evt_type = PMU_EVENT_CYCLES;
-break;
-case 0xF0:
-/*
- * PMC1SEL = 0xF0 is the architected PowerISA v3.1
- * event that counts cycles using PMC1.
- */
-if (sprn == SPR_POWER_PMC1) {
-evt_type = PMU_EVENT_CYCLES;
-}
-break;
-case 0xFA:
-/*
- * PMC4SEL = 0xFA is the "instructions completed
- * with run latch set" event.
- */
-if (sprn == SPR_POWER_PMC4) {
-evt_type = PMU_EVENT_INSN_RUN_LATCH;
-}
-break;
-case 0xFE:
-/*
- * PMC1SEL = 0xFE is the architected PowerISA v3.1
- * event to sample instructions using PMC1.
- */
-if (sprn == SPR_POWER_PMC1) {
-evt_type = PMU_EVENT_INSTRUCTIONS;
-}
-break;
-default:
-break;
-}
-
-return evt_type;
-}
-
 void pmu_update_summaries(CPUPPCState *env)
 {
 target_ulong mmcr0 = env->spr[SPR_POWER_MMCR0];
@@ -238,18 +151,16 @@ static void pmu_update_cycles(CPUPPCState *env)
 {
 uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 uint64_t time_delta = now - env->pmu_base_time;
-int sprn;
+int sprn, cyc_cnt = env->pmc_cyc_cnt;
 
 for (sprn = SPR_POWER_PMC1; sprn <= SPR_POWER_PMC6; sprn++) {
-if (pmc_get_event(env, sprn) != PMU_EVENT_CYCLES) {
-continue;
+if (cyc_cnt & (1 << (sprn - SPR_POWER_PMC1 + 1))) {
+/*
+ * The pseries and powernv clock runs at 1Ghz, meaning
+ * that 1 nanosec equals 1 cycle.
+ */
+env->spr[sprn] += time_delta;
 }
-
-/*
- * The pseries and powernv clock runs at 1Ghz, meaning
- * that 1 nanosec equals 1 cycle.
- */
-env->spr[sprn] += time_delta;
 }
 
 /* Update base_time for future calculations */
@@ -278,7 +189,7 @@ static void pmc_update_overflow_timer(CPUPPCState *env, int 
sprn)
 return;
 }
 
-if (pmc_get_event(env, sprn) != PMU_EVENT_CYCLES ||
+if (!(env->pmc_cyc_cnt & (1 << (sprn - SPR_POWER_PMC1 + 1))) ||
 !pmc_has_overflow_enabled(env, sprn)) {
 /* Overflow timer is not needed for this counter */
 timer_del(pmc_overflow_timer);
@@ -286,7 +197,7 @@ static void pmc_update_overflow_timer(CPUPPCState *env, int 
sprn)
 }
 
 if (env->spr[sprn] >= PMC_COUNTER_NEGATIVE_VAL) {
-timeout =  0;
+timeout = 0;
 } else {
 timeout = PMC_COUNTER_NEGATIVE_VAL - env->spr[sprn];
 }

[PULL 00/26] ppc queue

2022-01-03 Thread Cédric Le Goater
The following changes since commit b5a3d8bc9146ba22a25116cb748c97341bf99737:

  Merge tag 'pull-misc-20220103' of https://gitlab.com/rth7680/qemu into 
staging (2022-01-03 09:34:41 -0800)

are available in the Git repository at:

  https://github.com/legoater/qemu/ tags/pull-ppc-20220104

for you to fetch changes up to 0625c7760d5451d7436ef0738f763c6bb5141919:

  target/ppc: do not call hreg_compute_hflags() in helper_store_mmcr0() 
(2022-01-04 07:55:35 +0100)


ppc 7.0 queue:

* Cleanup of PowerNV PHBs (Daniel and Cedric)
* Cleanup and fixes for PPC405 machine (Cedric)
* Fix for xscvspdpn (Matheus)
* Rework of powerpc exception handling 1/n (Fabiano)
* Optimisation for PMU (Richard and Daniel)


Cédric Le Goater (14):
  ppc/pnv: Change the maximum of PHB3 devices for Power8NVL
  ppc/pnv: Remove PHB4 reset handler
  ppc/pnv: Remove the PHB4 "device-id" property
  target/ppc: Improve logging in Radix MMU
  target/ppc: Check effective address validity
  target/ppc: Remove static inline
  target/ppc: Print out literal exception names in logs
  ppc/ppc4xx: Convert printfs()
  ppc/ppc405: Activate MMU logs
  ppc/ppc405: Restore TCR and STR write handlers
  ppc/ppc405: Rework ppc_40x_timers_init() to use a PowerPCCPU
  ppc/ppc405: Fix timer initialization
  ppc/ppc405: Introduce a store helper for SPR_40x_PID
  ppc/ppc405: Dump specific registers

Daniel Henrique Barboza (3):
  pnv_phb3.c: do not set 'root-bus' as bus name
  pnv_phb4.c: do not set 'root-bus' as bus name
  target/ppc: do not call hreg_compute_hflags() in helper_store_mmcr0()

Fabiano Rosas (5):
  target/ppc: powerpc_excp: Set alternate SRRs directly
  target/ppc: powerpc_excp: Add excp_vectors bounds check
  target/ppc: powerpc_excp: Set vector earlier
  target/ppc: powerpc_excp: Move system call vectored code together
  target/ppc: powerpc_excp: Stop passing excp_model around

Matheus Ferst (1):
  target/ppc: do not silence snan in xscvspdpn

Richard Henderson (3):
  target/ppc: Cache per-pmc insn and cycle count settings
  target/ppc: Rewrite pmu_increment_insns
  target/ppc: Use env->pnc_cyc_cnt

 include/hw/pci-host/pnv_phb4.h  |   2 -
 target/ppc/cpu.h|   5 +
 target/ppc/helper.h |   2 +
 target/ppc/mmu-radix64.h|   1 +
 target/ppc/power8-pmu.h |  14 +-
 target/ppc/spr_tcg.h|   3 +
 hw/pci-host/pnv_phb3.c  |   3 +-
 hw/pci-host/pnv_phb4.c  |  16 +--
 hw/pci-host/pnv_phb4_pec.c  |   3 -
 hw/ppc/mpc8544_guts.c   |   9 +-
 hw/ppc/pnv.c|   2 +-
 hw/ppc/ppc.c|  67 ++---
 hw/ppc/ppc405_uc.c  |   2 -
 hw/ppc/ppc4xx_devs.c|  39 ++
 hw/ppc/ppc4xx_pci.c |  11 +-
 target/ppc/cpu_init.c   |  34 +++--
 target/ppc/excp_helper.c| 187 -
 target/ppc/fpu_helper.c |   5 +-
 target/ppc/helper_regs.c|   2 +-
 target/ppc/machine.c|   2 +
 target/ppc/mmu-radix64.c|  60 +++-
 target/ppc/mmu_common.c | 164 +++---
 target/ppc/mmu_helper.c |  97 ++---
 target/ppc/power8-pmu.c | 238 ++--
 target/ppc/timebase_helper.c|  10 ++
 target/ppc/translate.c  |  20 +++
 tests/tcg/ppc64le/non_signalling_xscv.c |  37 +
 hw/ppc/trace-events |   7 +
 tests/tcg/ppc64/Makefile.target |   4 +-
 tests/tcg/ppc64le/Makefile.target   |   4 +-
 30 files changed, 604 insertions(+), 446 deletions(-)
 create mode 100644 tests/tcg/ppc64le/non_signalling_xscv.c



[PULL 11/26] ppc/ppc405: Activate MMU logs

2022-01-03 Thread Cédric Le Goater
There is no need to deactivate MMU logging at compile time. Remove all
use of defines. Only keep DUMP_PAGE_TABLES for another series since
page tables could be dumped from the monitor.

Signed-off-by: Cédric Le Goater 
Message-Id: <20211222064025.1541490-4-...@kaod.org>
Signed-off-by: Cédric Le Goater 
Reviewed-by: Richard Henderson 
Message-Id: <20220103063441.3424853-5-...@kaod.org>
Signed-off-by: Cédric Le Goater 
---
 target/ppc/mmu_common.c | 164 +++-
 target/ppc/mmu_helper.c |  97 +++-
 2 files changed, 122 insertions(+), 139 deletions(-)

diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index 4e278365ca55..91270c1f17eb 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -34,29 +34,7 @@
 #include "mmu-book3s-v3.h"
 #include "mmu-radix64.h"
 
-/* #define DEBUG_MMU */
-/* #define DEBUG_BATS */
-/* #define DEBUG_SOFTWARE_TLB */
 /* #define DUMP_PAGE_TABLES */
-/* #define FLUSH_ALL_TLBS */
-
-#ifdef DEBUG_MMU
-#  define LOG_MMU_STATE(cpu) log_cpu_state_mask(CPU_LOG_MMU, (cpu), 0)
-#else
-#  define LOG_MMU_STATE(cpu) do { } while (0)
-#endif
-
-#ifdef DEBUG_SOFTWARE_TLB
-#  define LOG_SWTLB(...) qemu_log_mask(CPU_LOG_MMU, __VA_ARGS__)
-#else
-#  define LOG_SWTLB(...) do { } while (0)
-#endif
-
-#ifdef DEBUG_BATS
-#  define LOG_BATS(...) qemu_log_mask(CPU_LOG_MMU, __VA_ARGS__)
-#else
-#  define LOG_BATS(...) do { } while (0)
-#endif
 
 void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
 {
@@ -231,18 +209,20 @@ static int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t 
*ctx,
 tlb = >tlb.tlb6[nr];
 /* This test "emulates" the PTE index match for hardware TLBs */
 if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) {
-LOG_SWTLB("TLB %d/%d %s [" TARGET_FMT_lx " " TARGET_FMT_lx
-  "] <> " TARGET_FMT_lx "\n", nr, env->nb_tlb,
-  pte_is_valid(tlb->pte0) ? "valid" : "inval",
-  tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE, eaddr);
+qemu_log_mask(CPU_LOG_MMU, "TLB %d/%d %s [" TARGET_FMT_lx
+  " " TARGET_FMT_lx "] <> " TARGET_FMT_lx "\n",
+  nr, env->nb_tlb,
+  pte_is_valid(tlb->pte0) ? "valid" : "inval",
+  tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE, eaddr);
 continue;
 }
-LOG_SWTLB("TLB %d/%d %s " TARGET_FMT_lx " <> " TARGET_FMT_lx " "
-  TARGET_FMT_lx " %c %c\n", nr, env->nb_tlb,
-  pte_is_valid(tlb->pte0) ? "valid" : "inval",
-  tlb->EPN, eaddr, tlb->pte1,
-  access_type == MMU_DATA_STORE ? 'S' : 'L',
-  access_type == MMU_INST_FETCH ? 'I' : 'D');
+qemu_log_mask(CPU_LOG_MMU, "TLB %d/%d %s " TARGET_FMT_lx " <> "
+  TARGET_FMT_lx " " TARGET_FMT_lx " %c %c\n",
+  nr, env->nb_tlb,
+  pte_is_valid(tlb->pte0) ? "valid" : "inval",
+  tlb->EPN, eaddr, tlb->pte1,
+  access_type == MMU_DATA_STORE ? 'S' : 'L',
+  access_type == MMU_INST_FETCH ? 'I' : 'D');
 switch (ppc6xx_tlb_pte_check(ctx, tlb->pte0, tlb->pte1,
  0, access_type)) {
 case -3:
@@ -272,8 +252,9 @@ static int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t 
*ctx,
 }
 if (best != -1) {
 done:
-LOG_SWTLB("found TLB at addr " TARGET_FMT_plx " prot=%01x ret=%d\n",
-  ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret);
+qemu_log_mask(CPU_LOG_MMU, "found TLB at addr " TARGET_FMT_plx
+  " prot=%01x ret=%d\n",
+  ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret);
 /* Update page flags */
 pte_update_flags(ctx, >tlb.tlb6[best].pte1, ret, access_type);
 }
@@ -317,7 +298,7 @@ static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
 int ret = -1;
 bool ifetch = access_type == MMU_INST_FETCH;
 
-LOG_BATS("%s: %cBAT v " TARGET_FMT_lx "\n", __func__,
+ qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT v " TARGET_FMT_lx "\n", __func__,
  ifetch ? 'I' : 'D', virtual);
 if (ifetch) {
 BATlt = env->IBAT[1];
@@ -332,9 +313,9 @@ static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
 BEPIu = *BATu & 0xF000;
 BEPIl = *BATu & 0x0FFE;
 bat_size_prot(env, , , , BATu, BATl);
-LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
- " BATl " TARGET_FMT_lx "\n", __func__,
- ifetch ? 'I' : 'D', i, virtual, *BATu, *BATl);
+ qemu_log_mask(CPU_LOG_MMU, "%s: %cBAT%d v " TARGET_FMT_lx " BATu "
+   TARGET_FMT_lx " BATl " TARGET_FMT_lx "\n", __func__,
+   ifetch ? 'I' : 'D', i, virtual, *BATu, *BATl);
 if ((virtual & 0xF000) == BEPIu &&
 ((virtual & 

[PULL 16/26] ppc/ppc405: Dump specific registers

2022-01-03 Thread Cédric Le Goater
Rework slightly ppc_cpu_dump_state() to replace the various 'if'
statements with a 'switch'.

Reviewed-by: Richard Henderson 
Signed-off-by: Cédric Le Goater 
Message-Id: <20211222064025.1541490-9-...@kaod.org>
Signed-off-by: Cédric Le Goater 
Message-Id: <20220103063441.3424853-10-...@kaod.org>
Signed-off-by: Cédric Le Goater 
---
 target/ppc/cpu_init.c | 27 +--
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 9ef9a1a5ddd5..25970bd79f20 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -8648,16 +8648,17 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, int 
flags)
  env->spr[SPR_SPRG4], env->spr[SPR_SPRG5],
  env->spr[SPR_SPRG6], env->spr[SPR_SPRG7]);
 
+switch (env->excp_model) {
 #if defined(TARGET_PPC64)
-if (env->excp_model == POWERPC_EXCP_POWER7 ||
-env->excp_model == POWERPC_EXCP_POWER8 ||
-env->excp_model == POWERPC_EXCP_POWER9 ||
-env->excp_model == POWERPC_EXCP_POWER10)  {
+case POWERPC_EXCP_POWER7:
+case POWERPC_EXCP_POWER8:
+case POWERPC_EXCP_POWER9:
+case POWERPC_EXCP_POWER10:
 qemu_fprintf(f, "HSRR0 " TARGET_FMT_lx " HSRR1 " TARGET_FMT_lx "\n",
  env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
-}
+break;
 #endif
-if (env->excp_model == POWERPC_EXCP_BOOKE) {
+case POWERPC_EXCP_BOOKE:
 qemu_fprintf(f, "CSRR0 " TARGET_FMT_lx " CSRR1 " TARGET_FMT_lx
  " MCSRR0 " TARGET_FMT_lx " MCSRR1 " TARGET_FMT_lx "\n",
  env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
@@ -8688,6 +8689,20 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
  * IVORs are left out as they are large and do not change often --
  * they can be read with "p $ivor0", "p $ivor1", etc.
  */
+break;
+case POWERPC_EXCP_40x:
+qemu_fprintf(f, "  TCR " TARGET_FMT_lx "   TSR " TARGET_FMT_lx
+ "ESR " TARGET_FMT_lx "   DEAR " TARGET_FMT_lx "\n",
+ env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR],
+ env->spr[SPR_40x_ESR], env->spr[SPR_40x_DEAR]);
+
+qemu_fprintf(f, " EVPR " TARGET_FMT_lx "  SRR2 " TARGET_FMT_lx
+ "   SRR3 " TARGET_FMT_lx  "   PID " TARGET_FMT_lx "\n",
+ env->spr[SPR_40x_EVPR], env->spr[SPR_40x_SRR2],
+ env->spr[SPR_40x_SRR3], env->spr[SPR_40x_PID]);
+break;
+default:
+break;
 }
 
 #if defined(TARGET_PPC64)
-- 
2.31.1




[PULL 06/26] target/ppc: Improve logging in Radix MMU

2022-01-03 Thread Cédric Le Goater
Signed-off-by: Cédric Le Goater 
Reviewed-by: Richard Henderson 
Message-Id: <20211222071002.1568894-1-...@kaod.org>
Signed-off-by: Cédric Le Goater 
---
 target/ppc/mmu-radix64.c | 55 +---
 1 file changed, 52 insertions(+), 3 deletions(-)

diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index 5b0e62e676dc..d10ae001d7c9 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -97,12 +97,22 @@ static void ppc_radix64_raise_segi(PowerPCCPU *cpu, 
MMUAccessType access_type,
 env->error_code = 0;
 }
 
+static inline const char *access_str(MMUAccessType access_type)
+{
+return access_type == MMU_DATA_LOAD ? "reading" :
+(access_type == MMU_DATA_STORE ? "writing" : "execute");
+}
+
 static void ppc_radix64_raise_si(PowerPCCPU *cpu, MMUAccessType access_type,
  vaddr eaddr, uint32_t cause)
 {
 CPUState *cs = CPU(cpu);
 CPUPPCState *env = >env;
 
+qemu_log_mask(CPU_LOG_MMU, "%s for %s @0x%"VADDR_PRIx" cause %08x\n",
+  __func__, access_str(access_type),
+  eaddr, cause);
+
 switch (access_type) {
 case MMU_INST_FETCH:
 /* Instruction Storage Interrupt */
@@ -130,6 +140,11 @@ static void ppc_radix64_raise_hsi(PowerPCCPU *cpu, 
MMUAccessType access_type,
 CPUState *cs = CPU(cpu);
 CPUPPCState *env = >env;
 
+qemu_log_mask(CPU_LOG_MMU, "%s for %s @0x%"VADDR_PRIx" 0x%"
+  HWADDR_PRIx" cause %08x\n",
+  __func__, access_str(access_type),
+  eaddr, g_raddr, cause);
+
 switch (access_type) {
 case MMU_INST_FETCH:
 /* H Instruction Storage Interrupt */
@@ -306,6 +321,15 @@ static int ppc_radix64_partition_scoped_xlate(PowerPCCPU 
*cpu,
 hwaddr pte_addr;
 uint64_t pte;
 
+qemu_log_mask(CPU_LOG_MMU, "%s for %s @0x%"VADDR_PRIx
+  " mmu_idx %u (prot %c%c%c) 0x%"HWADDR_PRIx"\n",
+  __func__, access_str(access_type),
+  eaddr, mmu_idx,
+  *h_prot & PAGE_READ ? 'r' : '-',
+  *h_prot & PAGE_WRITE ? 'w' : '-',
+  *h_prot & PAGE_EXEC ? 'x' : '-',
+  g_raddr);
+
 *h_page_size = PRTBE_R_GET_RTS(pate.dw0);
 /* No valid pte or access denied due to protection */
 if (ppc_radix64_walk_tree(CPU(cpu)->as, g_raddr, pate.dw0 & PRTBE_R_RPDB,
@@ -343,6 +367,11 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU 
*cpu,
 hwaddr h_raddr, pte_addr;
 int ret;
 
+qemu_log_mask(CPU_LOG_MMU, "%s for %s @0x%"VADDR_PRIx
+  " mmu_idx %u pid %"PRIu64"\n",
+  __func__, access_str(access_type),
+  eaddr, mmu_idx, pid);
+
 /* Index Process Table by PID to Find Corresponding Process Table Entry */
 offset = pid * sizeof(struct prtb_entry);
 size = 1ULL << ((pate.dw1 & PATE1_R_PRTS) + 12);
@@ -468,9 +497,10 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU 
*cpu,
  *  | = On| Process Scoped |Scoped |
  *  +-++---+
  */
-bool ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
-   hwaddr *raddr, int *psizep, int *protp, int mmu_idx,
-   bool guest_visible)
+static bool ppc_radix64_xlate_impl(PowerPCCPU *cpu, vaddr eaddr,
+   MMUAccessType access_type, hwaddr *raddr,
+   int *psizep, int *protp, int mmu_idx,
+   bool guest_visible)
 {
 CPUPPCState *env = >env;
 uint64_t lpid, pid;
@@ -588,3 +618,22 @@ bool ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, 
MMUAccessType access_type,
 
 return true;
 }
+
+bool ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
+   hwaddr *raddrp, int *psizep, int *protp, int mmu_idx,
+   bool guest_visible)
+{
+bool ret = ppc_radix64_xlate_impl(cpu, eaddr, access_type, raddrp,
+  psizep, protp, mmu_idx, guest_visible);
+
+qemu_log_mask(CPU_LOG_MMU, "%s for %s @0x%"VADDR_PRIx
+  " mmu_idx %u (prot %c%c%c) -> 0x%"HWADDR_PRIx"\n",
+  __func__, access_str(access_type),
+  eaddr, mmu_idx,
+  *protp & PAGE_READ ? 'r' : '-',
+  *protp & PAGE_WRITE ? 'w' : '-',
+  *protp & PAGE_EXEC ? 'x' : '-',
+  *raddrp);
+
+return ret;
+}
-- 
2.31.1




[PULL 14/26] ppc/ppc405: Fix timer initialization

2022-01-03 Thread Cédric Le Goater
Timers are already initialized in ppc4xx_init(). No need to do it a
second time with a wrong set.

Fixes: d715ea961254 ("PPC: 405: Fix ppc405ep initialization")
Reviewed-by: Richard Henderson 
Signed-off-by: Cédric Le Goater 
Message-Id: <20211222064025.1541490-7-...@kaod.org>
Signed-off-by: Cédric Le Goater 
Message-Id: <20220103063441.3424853-8-...@kaod.org>
Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc405_uc.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index ec97b22bd019..8aacd275a652 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1461,8 +1461,6 @@ PowerPCCPU *ppc405ep_init(MemoryRegion *address_space_mem,
 ppc4xx_pob_init(env);
 /* OBP arbitrer */
 ppc4xx_opba_init(0xef600600);
-/* Initialize timers */
-ppc_booke_timers_init(cpu, sysclk, 0);
 /* Universal interrupt controller */
 uicdev = qdev_new(TYPE_PPC_UIC);
 uicsbd = SYS_BUS_DEVICE(uicdev);
-- 
2.31.1




[PULL 03/26] ppc/pnv: Remove the PHB4 "device-id" property

2022-01-03 Thread Cédric Le Goater
It's unused.

Signed-off-by: Cédric Le Goater 
Reviewed-by: Daniel Henrique Barboza 
Message-Id: <20211222063817.1541058-4-...@kaod.org>
Signed-off-by: Cédric Le Goater 
---
 include/hw/pci-host/pnv_phb4.h | 2 --
 hw/pci-host/pnv_phb4.c | 1 -
 hw/pci-host/pnv_phb4_pec.c | 3 ---
 3 files changed, 6 deletions(-)

diff --git a/include/hw/pci-host/pnv_phb4.h b/include/hw/pci-host/pnv_phb4.h
index 60de3031a622..4a19338db35e 100644
--- a/include/hw/pci-host/pnv_phb4.h
+++ b/include/hw/pci-host/pnv_phb4.h
@@ -84,7 +84,6 @@ struct PnvPHB4 {
 uint32_t phb_id;
 
 uint64_t version;
-uint16_t device_id;
 
 char bus_path[8];
 
@@ -222,7 +221,6 @@ struct PnvPhb4PecClass {
 const char *stk_compat;
 int stk_compat_size;
 uint64_t version;
-uint64_t device_id;
 const uint32_t *num_stacks;
 };
 
diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
index 2074621405ce..371abda5c6e9 100644
--- a/hw/pci-host/pnv_phb4.c
+++ b/hw/pci-host/pnv_phb4.c
@@ -1262,7 +1262,6 @@ static Property pnv_phb4_properties[] = {
 DEFINE_PROP_UINT32("index", PnvPHB4, phb_id, 0),
 DEFINE_PROP_UINT32("chip-id", PnvPHB4, chip_id, 0),
 DEFINE_PROP_UINT64("version", PnvPHB4, version, 0),
-DEFINE_PROP_UINT16("device-id", PnvPHB4, device_id, 0),
 DEFINE_PROP_LINK("stack", PnvPHB4, stack, TYPE_PNV_PHB4_PEC_STACK,
  PnvPhb4PecStack *),
 DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/pci-host/pnv_phb4_pec.c b/hw/pci-host/pnv_phb4_pec.c
index 24a3adcae326..f3e4fa0c8297 100644
--- a/hw/pci-host/pnv_phb4_pec.c
+++ b/hw/pci-host/pnv_phb4_pec.c
@@ -527,7 +527,6 @@ static void pnv_pec_class_init(ObjectClass *klass, void 
*data)
 pecc->stk_compat = stk_compat;
 pecc->stk_compat_size = sizeof(stk_compat);
 pecc->version = PNV_PHB4_VERSION;
-pecc->device_id = PNV_PHB4_DEVICE_ID;
 pecc->num_stacks = pnv_pec_num_stacks;
 }
 
@@ -587,8 +586,6 @@ static void pnv_pec_stk_realize(DeviceState *dev, Error 
**errp)
 _fatal);
 object_property_set_int(OBJECT(>phb), "version", pecc->version,
 _fatal);
-object_property_set_int(OBJECT(>phb), "device-id", pecc->device_id,
-_fatal);
 object_property_set_link(OBJECT(>phb), "stack", OBJECT(stack),
  _abort);
 if (!sysbus_realize(SYS_BUS_DEVICE(>phb), errp)) {
-- 
2.31.1




[PULL 20/26] target/ppc: powerpc_excp: Set vector earlier

2022-01-03 Thread Cédric Le Goater
From: Fabiano Rosas 

None of the interrupt setup code touches 'vector', so we can move it
earlier in the function. This will allow us to later move the System
Call Vectored setup that is on the top level into the
POWERPC_EXCP_SYSCALL_VECTORED code block.

This patch also moves the verification for when 'excp' does not have
an address associated with it. We now bail a little earlier when that
is the case. This should not cause any visible effects.

Signed-off-by: Fabiano Rosas 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Richard Henderson 
Reviewed-by: David Gibson 
Message-Id: <20211229165751.3774248-4-faro...@linux.ibm.com>
Signed-off-by: Cédric Le Goater 
---
 target/ppc/excp_helper.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 9e7c428821e1..35ac450590f5 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -429,6 +429,14 @@ static void powerpc_excp(PowerPCCPU *cpu, int excp_model, 
int excp)
 }
 #endif
 
+vector = env->excp_vectors[excp];
+if (vector == (target_ulong)-1ULL) {
+cpu_abort(cs, "Raised an exception without defined vector %d\n",
+  excp);
+}
+
+vector |= env->excp_prefix;
+
 switch (excp) {
 case POWERPC_EXCP_CRITICAL:/* Critical input */
 switch (excp_model) {
@@ -905,14 +913,6 @@ static void powerpc_excp(PowerPCCPU *cpu, int excp_model, 
int excp)
 }
 #endif
 
-vector = env->excp_vectors[excp];
-if (vector == (target_ulong)-1ULL) {
-cpu_abort(cs, "Raised an exception without defined vector %d\n",
-  excp);
-}
-
-vector |= env->excp_prefix;
-
 #if defined(TARGET_PPC64)
 if (excp_model == POWERPC_EXCP_BOOKE) {
 if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {
-- 
2.31.1




[PULL 07/26] target/ppc: Check effective address validity

2022-01-03 Thread Cédric Le Goater
For Radix translation, the EA range is 64-bits. when EA(2:11) are
nonzero, a segment interrupt should occur.

Signed-off-by: Cédric Le Goater 
Reviewed-by: Frederic Barrat 
Message-Id: <20211231073122.3183583-1-...@kaod.org>
Signed-off-by: Cédric Le Goater 
---
 target/ppc/mmu-radix64.h | 1 +
 target/ppc/mmu-radix64.c | 5 +
 2 files changed, 6 insertions(+)

diff --git a/target/ppc/mmu-radix64.h b/target/ppc/mmu-radix64.h
index b70357cf345c..4c768aa5cc74 100644
--- a/target/ppc/mmu-radix64.h
+++ b/target/ppc/mmu-radix64.h
@@ -5,6 +5,7 @@
 
 /* Radix Quadrants */
 #define R_EADDR_MASK0x3FFF
+#define R_EADDR_VALID_MASK  0xC00F
 #define R_EADDR_QUADRANT0xC000
 #define R_EADDR_QUADRANT0   0x
 #define R_EADDR_QUADRANT1   0x4000
diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index d10ae001d7c9..040c055bff65 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -32,6 +32,11 @@ static bool ppc_radix64_get_fully_qualified_addr(const 
CPUPPCState *env,
  vaddr eaddr,
  uint64_t *lpid, uint64_t *pid)
 {
+/* When EA(2:11) are nonzero, raise a segment interrupt */
+if (eaddr & ~R_EADDR_VALID_MASK) {
+return false;
+}
+
 if (msr_hv) { /* MSR[HV] -> Hypervisor/bare metal */
 switch (eaddr & R_EADDR_QUADRANT) {
 case R_EADDR_QUADRANT0:
-- 
2.31.1




[PULL 01/26] ppc/pnv: Change the maximum of PHB3 devices for Power8NVL

2022-01-03 Thread Cédric Le Goater
The POWER8 processors with a NVLink logic unit have 4 PHB3 devices per
chip.

Signed-off-by: Cédric Le Goater 
Reviewed-by: Daniel Henrique Barboza 
Message-Id: <20211222063817.1541058-2-...@kaod.org>
Signed-off-by: Cédric Le Goater 
---
 hw/ppc/pnv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 29ee0d0f08b4..9de8b8353014 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1314,7 +1314,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass 
*klass, void *data)
 
 k->chip_cfam_id = 0x120d30498000ull;  /* P8 Naples DD1.0 */
 k->cores_mask = POWER8_CORE_MASK;
-k->num_phbs = 3;
+k->num_phbs = 4;
 k->core_pir = pnv_chip_core_pir_p8;
 k->intc_create = pnv_chip_power8_intc_create;
 k->intc_reset = pnv_chip_power8_intc_reset;
-- 
2.31.1




[PULL 04/26] pnv_phb3.c: do not set 'root-bus' as bus name

2022-01-03 Thread Cédric Le Goater
From: Daniel Henrique Barboza 

All pnv-phb3-root-bus buses are being created as 'root-bus'. This
makes it impossible to, for example, add a pnv-phb3-root-port in
a specific root bus, since they all have the same name. By default
the device will be parented by the pnv-phb3 device that precedeced it in
the QEMU command line.

Moreover, this doesn't all for custom bus naming. Libvirt, for instance,
likes to name these buses as 'pcie.N', where 'N' is the index value of
the controller in the domain XML, by using the 'id' command line
attribute. At this moment this is also being ignored - the created root
bus will always be named 'root-bus'.

This patch fixes both scenarios by removing the 'root-bus' name from the
pci_register_root_bus() call. If an "id" is provided, use that.
Otherwise use 'NULL' as bus name. The 'NULL' value will be handled in
qbus_init_internal() and it will defaulted as lowercase bus type + the
global bus_id value.

After this path we can define the bus name by using the 'id' attribute:

qemu-system-ppc64 -m 4G -machine powernv8,accel=tcg \
-device pnv-phb3,chip-id=0,index=1,id=pcie.0

  dev: pnv-phb3, id "pcie.0"
index = 1 (0x1)
chip-id = 0 (0x0)
x-config-reg-migration-enabled = true
bypass-iommu = false
bus: pcie.0
  type pnv-phb3-root-bus

And without an 'id' we will have the following default:

qemu-system-ppc64 -m 4G -machine powernv8,accel=tcg \
-device pnv-phb3,chip-id=0,index=1

  dev: pnv-phb3, id ""
index = 1 (0x1)
chip-id = 0 (0x0)
x-config-reg-migration-enabled = true
bypass-iommu = false
bus: pnv-phb3-root-bus.0
  type pnv-phb3-root-bus

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Cédric Le Goater 
Message-Id: <20211228193806.1198496-3-danielhb...@gmail.com>
Signed-off-by: Cédric Le Goater 
---
 hw/pci-host/pnv_phb3.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/pci-host/pnv_phb3.c b/hw/pci-host/pnv_phb3.c
index c6e7871ecbf1..c78084cce795 100644
--- a/hw/pci-host/pnv_phb3.c
+++ b/hw/pci-host/pnv_phb3.c
@@ -1045,7 +1045,8 @@ static void pnv_phb3_realize(DeviceState *dev, Error 
**errp)
 memory_region_init(>pci_mmio, OBJECT(phb), "pci-mmio",
PCI_MMIO_TOTAL_SIZE);
 
-pci->bus = pci_register_root_bus(dev, "root-bus",
+pci->bus = pci_register_root_bus(dev,
+ dev->id ? dev->id : NULL,
  pnv_phb3_set_irq, pnv_phb3_map_irq, phb,
  >pci_mmio, >pci_io,
  0, 4, TYPE_PNV_PHB3_ROOT_BUS);
-- 
2.31.1




[PULL 10/26] ppc/ppc4xx: Convert printfs()

2022-01-03 Thread Cédric Le Goater
Use a QEMU log primitive for errors and trace events for debug.

Signed-off-by: Cédric Le Goater 
Reviewed-by: David Gibson 
Reviewed-by: Richard Henderson 
Message-Id: <20211222064025.1541490-3-...@kaod.org>
Signed-off-by: Cédric Le Goater 
Message-Id: <20220103063441.3424853-4-...@kaod.org>
Signed-off-by: Cédric Le Goater 
---
 hw/ppc/mpc8544_guts.c |  9 ++---
 hw/ppc/ppc4xx_devs.c  | 39 +++
 hw/ppc/ppc4xx_pci.c   | 11 +++
 hw/ppc/trace-events   |  5 +
 4 files changed, 29 insertions(+), 35 deletions(-)

diff --git a/hw/ppc/mpc8544_guts.c b/hw/ppc/mpc8544_guts.c
index e8d2d51c20c0..a26e83d0484b 100644
--- a/hw/ppc/mpc8544_guts.c
+++ b/hw/ppc/mpc8544_guts.c
@@ -19,6 +19,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu/module.h"
+#include "qemu/log.h"
 #include "sysemu/runstate.h"
 #include "cpu.h"
 #include "hw/sysbus.h"
@@ -82,7 +83,9 @@ static uint64_t mpc8544_guts_read(void *opaque, hwaddr addr,
 value = env->spr[SPR_E500_SVR];
 break;
 default:
-fprintf(stderr, "guts: Unknown register read: %x\n", (int)addr);
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Unknown register 0x%" HWADDR_PRIx "\n",
+  __func__, addr);
 break;
 }
 
@@ -101,8 +104,8 @@ static void mpc8544_guts_write(void *opaque, hwaddr addr,
 }
 break;
 default:
-fprintf(stderr, "guts: Unknown register write: %x = %x\n",
-(int)addr, (unsigned)value);
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Unknown register 0x%" HWADDR_PRIx
+   " = 0x%" PRIx64 "\n", __func__, addr, value);
 break;
 }
 }
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index 980c48944fc7..e7d82ae5016c 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -35,14 +35,7 @@
 #include "exec/address-spaces.h"
 #include "qemu/error-report.h"
 #include "qapi/error.h"
-
-/*#define DEBUG_UIC*/
-
-#ifdef DEBUG_UIC
-#  define LOG_UIC(...) qemu_log_mask(CPU_LOG_INT, ## __VA_ARGS__)
-#else
-#  define LOG_UIC(...) do { } while (0)
-#endif
+#include "trace.h"
 
 static void ppc4xx_reset(void *opaque)
 {
@@ -137,8 +130,9 @@ static uint32_t sdram_bcr (hwaddr ram_base,
 bcr = 0x000C;
 break;
 default:
-printf("%s: invalid RAM size " TARGET_FMT_plx "\n", __func__,
-   ram_size);
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: invalid RAM size 0x%" HWADDR_PRIx "\n", __func__,
+  ram_size);
 return 0x;
 }
 bcr |= ram_base & 0xFF80;
@@ -171,10 +165,8 @@ static void sdram_set_bcr(ppc4xx_sdram_t *sdram, int i,
 {
 if (sdram->bcr[i] & 0x0001) {
 /* Unmap RAM */
-#ifdef DEBUG_SDRAM
-printf("%s: unmap RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
-   __func__, sdram_base(sdram->bcr[i]), sdram_size(sdram->bcr[i]));
-#endif
+trace_ppc4xx_sdram_unmap(sdram_base(sdram->bcr[i]),
+ sdram_size(sdram->bcr[i]));
 memory_region_del_subregion(get_system_memory(),
 >containers[i]);
 memory_region_del_subregion(>containers[i],
@@ -183,10 +175,7 @@ static void sdram_set_bcr(ppc4xx_sdram_t *sdram, int i,
 }
 sdram->bcr[i] = bcr & 0xFFDEE001;
 if (enabled && (bcr & 0x0001)) {
-#ifdef DEBUG_SDRAM
-printf("%s: Map RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
-   __func__, sdram_base(bcr), sdram_size(bcr));
-#endif
+trace_ppc4xx_sdram_unmap(sdram_base(bcr), sdram_size(bcr));
 memory_region_init(>containers[i], NULL, "sdram-containers",
sdram_size(bcr));
 memory_region_add_subregion(>containers[i], 0,
@@ -216,10 +205,8 @@ static void sdram_unmap_bcr (ppc4xx_sdram_t *sdram)
 int i;
 
 for (i = 0; i < sdram->nbanks; i++) {
-#ifdef DEBUG_SDRAM
-printf("%s: Unmap RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
-   __func__, sdram_base(sdram->bcr[i]), sdram_size(sdram->bcr[i]));
-#endif
+trace_ppc4xx_sdram_unmap(sdram_base(sdram->bcr[i]),
+ sdram_size(sdram->bcr[i]));
 memory_region_del_subregion(get_system_memory(),
 >ram_memories[i]);
 }
@@ -316,16 +303,12 @@ static void dcr_write_sdram (void *opaque, int dcrn, 
uint32_t val)
 case 0x20: /* SDRAM_CFG */
 val &= 0xFFE0;
 if (!(sdram->cfg & 0x8000) && (val & 0x8000)) {
-#ifdef DEBUG_SDRAM
-printf("%s: enable SDRAM controller\n", __func__);
-#endif
+trace_ppc4xx_sdram_enable("enable");
 /* validate all RAM mappings */
 sdram_map_bcr(sdram);
 sdram->status &= ~0x8000;
 } else if ((sdram->cfg & 0x8000) && !(val & 0x8000)) {
-#ifdef DEBUG_SDRAM
-

[PULL 02/26] ppc/pnv: Remove PHB4 reset handler

2022-01-03 Thread Cédric Le Goater
The PHB4 reset handler was preparing ground for PHB5 to set
appropriately the device id. We don't need it for the PHB4 since the
device id is already set in the root port complex. PH5 will introduce
its own.

"device-id" property is now useless. It should be removed.

Signed-off-by: Cédric Le Goater 
Reviewed-by: Daniel Henrique Barboza 
Message-Id: <20211222063817.1541058-3-...@kaod.org>
Signed-off-by: Cédric Le Goater 
---
 hw/pci-host/pnv_phb4.c | 13 -
 1 file changed, 13 deletions(-)

diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
index 1fbf7328f5a1..2074621405ce 100644
--- a/hw/pci-host/pnv_phb4.c
+++ b/hw/pci-host/pnv_phb4.c
@@ -1230,18 +1230,6 @@ static void pnv_phb4_realize(DeviceState *dev, Error 
**errp)
 phb->qirqs = qemu_allocate_irqs(xive_source_set_irq, xsrc, xsrc->nr_irqs);
 }
 
-static void pnv_phb4_reset(DeviceState *dev)
-{
-PnvPHB4 *phb = PNV_PHB4(dev);
-PCIDevice *root_dev = PCI_DEVICE(>root);
-
-/*
- * Configure PCI device id at reset using a property.
- */
-pci_config_set_vendor_id(root_dev->config, PCI_VENDOR_ID_IBM);
-pci_config_set_device_id(root_dev->config, phb->device_id);
-}
-
 static const char *pnv_phb4_root_bus_path(PCIHostState *host_bridge,
   PCIBus *rootbus)
 {
@@ -1291,7 +1279,6 @@ static void pnv_phb4_class_init(ObjectClass *klass, void 
*data)
 device_class_set_props(dc, pnv_phb4_properties);
 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
 dc->user_creatable  = false;
-dc->reset   = pnv_phb4_reset;
 
 xfc->notify = pnv_phb4_xive_notify;
 }
-- 
2.31.1




[PULL 23/26] target/ppc: Cache per-pmc insn and cycle count settings

2022-01-03 Thread Cédric Le Goater
From: Richard Henderson 

This is the combination of frozen bit and counter type, on a per
counter basis. So far this is only used by HFLAGS_INSN_CNT, but
will be used more later.

Signed-off-by: Richard Henderson 
[danielhb: fixed PMC4 cyc_cnt shift, insn run latch code,
   MMCR0_FC handling, "PMC[1-6]" comment]
Signed-off-by: Daniel Henrique Barboza 
Message-Id: <20220103224746.167831-2-danielhb...@gmail.com>
Signed-off-by: Cédric Le Goater 
---
 target/ppc/cpu.h |  3 +++
 target/ppc/power8-pmu.h  | 14 +-
 target/ppc/cpu_init.c|  1 +
 target/ppc/helper_regs.c |  2 +-
 target/ppc/machine.c |  2 ++
 target/ppc/power8-pmu.c  | 56 
 6 files changed, 58 insertions(+), 20 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 4808e10ebe8b..f20d4ffa6d32 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1144,6 +1144,9 @@ struct CPUPPCState {
 /* Other registers */
 target_ulong spr[1024]; /* special purpose registers */
 ppc_spr_t spr_cb[1024];
+/* Composite status for PMC[1-6] enabled and counting insns or cycles. */
+uint8_t pmc_ins_cnt;
+uint8_t pmc_cyc_cnt;
 /* Vector status and control register, minus VSCR_SAT */
 uint32_t vscr;
 /* VSX registers (including FP and AVR) */
diff --git a/target/ppc/power8-pmu.h b/target/ppc/power8-pmu.h
index 3ee4b4cda5a9..a8391995618a 100644
--- a/target/ppc/power8-pmu.h
+++ b/target/ppc/power8-pmu.h
@@ -13,14 +13,12 @@
 #ifndef POWER8_PMU
 #define POWER8_PMU
 
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "exec/helper-proto.h"
-#include "qemu/error-report.h"
-#include "qemu/main-loop.h"
-
 void cpu_ppc_pmu_init(CPUPPCState *env);
-bool pmu_insn_cnt_enabled(CPUPPCState *env);
+
+#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
+void pmu_update_summaries(CPUPPCState *env);
+#else
+static inline void pmu_update_summaries(CPUPPCState *env) { }
+#endif
 
 #endif
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 25970bd79f20..cc93bff3fac4 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -8313,6 +8313,7 @@ static void ppc_cpu_reset(DeviceState *dev)
 #endif /* CONFIG_TCG */
 #endif
 
+pmu_update_summaries(env);
 hreg_compute_hflags(env);
 env->reserve_addr = (target_ulong)-1ULL;
 /* Be sure no exception or interrupt is pending */
diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index b8479288426b..8671b7bb691f 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -123,7 +123,7 @@ static uint32_t hreg_compute_hflags_value(CPUPPCState *env)
 }
 
 #if defined(TARGET_PPC64)
-if (pmu_insn_cnt_enabled(env)) {
+if (env->pmc_ins_cnt) {
 hflags |= 1 << HFLAGS_INSN_CNT;
 }
 #endif
diff --git a/target/ppc/machine.c b/target/ppc/machine.c
index 93972df58ea9..756d8de5d8dd 100644
--- a/target/ppc/machine.c
+++ b/target/ppc/machine.c
@@ -8,6 +8,7 @@
 #include "qapi/error.h"
 #include "qemu/main-loop.h"
 #include "kvm_ppc.h"
+#include "power8-pmu.h"
 
 static void post_load_update_msr(CPUPPCState *env)
 {
@@ -19,6 +20,7 @@ static void post_load_update_msr(CPUPPCState *env)
  */
 env->msr ^= env->msr_mask & ~((1ULL << MSR_TGPR) | MSR_HVB);
 ppc_store_msr(env, msr);
+pmu_update_summaries(env);
 }
 
 static int cpu_load_old(QEMUFile *f, void *opaque, int version_id)
diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 08d1902cd5d6..1f4f6119943a 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -11,8 +11,6 @@
  */
 
 #include "qemu/osdep.h"
-
-#include "power8-pmu.h"
 #include "cpu.h"
 #include "helper_regs.h"
 #include "exec/exec-all.h"
@@ -20,6 +18,7 @@
 #include "qemu/error-report.h"
 #include "qemu/main-loop.h"
 #include "hw/ppc/ppc.h"
+#include "power8-pmu.h"
 
 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
 
@@ -121,18 +120,52 @@ static PMUEventType pmc_get_event(CPUPPCState *env, int 
sprn)
 return evt_type;
 }
 
-bool pmu_insn_cnt_enabled(CPUPPCState *env)
+void pmu_update_summaries(CPUPPCState *env)
 {
-int sprn;
+target_ulong mmcr0 = env->spr[SPR_POWER_MMCR0];
+target_ulong mmcr1 = env->spr[SPR_POWER_MMCR1];
+int ins_cnt = 0;
+int cyc_cnt = 0;
 
-for (sprn = SPR_POWER_PMC1; sprn <= SPR_POWER_PMC5; sprn++) {
-if (pmc_get_event(env, sprn) == PMU_EVENT_INSTRUCTIONS ||
-pmc_get_event(env, sprn) == PMU_EVENT_INSN_RUN_LATCH) {
-return true;
+if (mmcr0 & MMCR0_FC) {
+goto hflags_calc;
+}
+
+if (!(mmcr0 & MMCR0_FC14) && mmcr1 != 0) {
+target_ulong sel;
+
+sel = extract64(mmcr1, MMCR1_PMC1EVT_EXTR, MMCR1_EVT_SIZE);
+switch (sel) {
+case 0x02:
+case 0xfe:
+ins_cnt |= 1 << 1;
+break;
+case 0x1e:
+case 0xf0:
+cyc_cnt |= 1 << 1;
+break;
 }
+
+sel = extract64(mmcr1, 

[PULL 05/26] pnv_phb4.c: do not set 'root-bus' as bus name

2022-01-03 Thread Cédric Le Goater
From: Daniel Henrique Barboza 

This change has the same motivation as the one done for pnv-phb3-root-bus
buses previously. Defaulting every bus to 'root-bus' makes it impossible to 
attach
root ports to specific buses and it doesn't allow for custom bus
naming because we're ignoring the 'id' value when registering the root
bus.

After this patch, creating pnv-phb4 devices with 'id' being set will
result in the following qtree:

qemu-system-ppc64 -m 4G -machine powernv9,accel=tcg \
   -device pnv-phb4,chip-id=0,index=0,id=pcie.0 \
   -device pnv-phb4,chip-id=1,index=4,id=pcie.1

bus: main-system-bus
  type System
  dev: pnv-phb4, id "pcie.1"
index = 4 (0x4)
chip-id = 1 (0x1)
version = 704374636546 (0xa40002)
device-id = 1217 (0x4c1)
x-config-reg-migration-enabled = true
bypass-iommu = false
bus: pcie.1
  type pnv-phb4-root-bus
  dev: pnv-phb4, id "pcie.0"
index = 0 (0x0)
chip-id = 0 (0x0)
version = 704374636546 (0xa40002)
device-id = 1217 (0x4c1)
x-config-reg-migration-enabled = true
bypass-iommu = false
bus: pcie.0
  type pnv-phb4-root-bus

And without setting any ids:

qemu-system-ppc64 -m 4G -machine powernv9,accel=tcg \
   -device pnv-phb4,chip-id=0,index=0,id=pcie.0 \
   -device pnv-phb4,chip-id=1,index=4,id=pcie.1

bus: main-system-bus
  type System
  dev: pnv-phb4, id ""
index = 4 (0x4)
chip-id = 1 (0x1)
version = 704374636546 (0xa40002)
device-id = 1217 (0x4c1)
x-config-reg-migration-enabled = true
bypass-iommu = false
bus: pnv-phb4-root-bus.1
  type pnv-phb4-root-bus
  dev: pnv-phb4, id ""
index = 0 (0x0)
chip-id = 0 (0x0)
version = 704374636546 (0xa40002)
device-id = 1217 (0x4c1)
x-config-reg-migration-enabled = true
bypass-iommu = false
bus: pnv-phb4-root-bus.0
  type pnv-phb4-root-bus

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Cédric Le Goater 
Message-Id: <20211228193806.1198496-17-danielhb...@gmail.com>
Signed-off-by: Cédric Le Goater 
---
 hw/pci-host/pnv_phb4.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
index 371abda5c6e9..5ba26e250a1f 100644
--- a/hw/pci-host/pnv_phb4.c
+++ b/hw/pci-host/pnv_phb4.c
@@ -1201,7 +1201,7 @@ static void pnv_phb4_realize(DeviceState *dev, Error 
**errp)
 memory_region_init(>pci_mmio, OBJECT(phb), name,
PCI_MMIO_TOTAL_SIZE);
 
-pci->bus = pci_register_root_bus(dev, "root-bus",
+pci->bus = pci_register_root_bus(dev, dev->id,
  pnv_phb4_set_irq, pnv_phb4_map_irq, phb,
  >pci_mmio, >pci_io,
  0, 4, TYPE_PNV_PHB4_ROOT_BUS);
-- 
2.31.1




Re: [PATCH 3/8] hw/pci: Document pci_dma_map()

2022-01-03 Thread Peter Xu
On Fri, Dec 31, 2021 at 12:48:56PM +0100, Philippe Mathieu-Daudé wrote:
> +/**
> + * pci_dma_map: Map a physical memory region into a device PCI address space.

Shouldn't this be: "Map device PCI address space range into host virtual
address"?

-- 
Peter Xu




[PATCH v2 0/2] Align SiFive PDMA behavior to real hardware

2022-01-03 Thread Jim Shu
HiFive Unmatched PDMA supports high/low 32-bit access of 64-bit
register, but QEMU emulation supports low part access now. Enhance QEMU
emulation to support high 32-bit access. 

Also, permit 4/8-byte valid access in PDMA as we have verified 32/64-bit
accesses of PDMA registers are supported.

Changelog:

v2:
  * Fix high 32-bit write access of 64-bit RO registers
  * Fix commit log

Jim Shu (2):
  hw/dma: sifive_pdma: support high 32-bit access of 64-bit register
  hw/dma: sifive_pdma: permit 4/8-byte access size of PDMA registers

 hw/dma/sifive_pdma.c | 181 +--
 1 file changed, 159 insertions(+), 22 deletions(-)

-- 
2.25.1




[PATCH v2 2/2] hw/dma: sifive_pdma: permit 4/8-byte access size of PDMA registers

2022-01-03 Thread Jim Shu
It's obvious that PDMA supports 64-bit access of 64-bit registers, and
in previous commit, we confirm that PDMA supports 32-bit access of
both 32/64-bit registers. Thus, we configure 32/64-bit memory access
of PDMA registers as valid in general.

Signed-off-by: Jim Shu 
Reviewed-by: Frank Chang 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 
Reviewed-by: Bin Meng 
Tested-by: Bin Meng 
---
 hw/dma/sifive_pdma.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/hw/dma/sifive_pdma.c b/hw/dma/sifive_pdma.c
index f4df16449b..1dd88f3479 100644
--- a/hw/dma/sifive_pdma.c
+++ b/hw/dma/sifive_pdma.c
@@ -444,6 +444,10 @@ static const MemoryRegionOps sifive_pdma_ops = {
 .impl = {
 .min_access_size = 4,
 .max_access_size = 8,
+},
+.valid = {
+.min_access_size = 4,
+.max_access_size = 8,
 }
 };
 
-- 
2.25.1




[PATCH v2 1/2] hw/dma: sifive_pdma: support high 32-bit access of 64-bit register

2022-01-03 Thread Jim Shu
Real PDMA supports high 32-bit read/write memory access of 64-bit
register.

The following result is PDMA tested in U-Boot on Unmatched board:

1. Real PDMA allows high 32-bit read/write to 64-bit register.
=> mw.l 0x300 0x0  <= Disclaim channel 0
=> mw.l 0x300 0x1  <= Claim channel 0
=> mw.l 0x310 0x8000   <= Write low 32-bit NextDest 
(NextDest = 0x28000)
=> mw.l 0x314 0x2  <= Write high 32-bit NextDest
=> md.l 0x310 1<= Dump low 32-bit NextDest
0310: 8000
=> md.l 0x314 1<= Dump high 32-bit NextDest
0314: 0002
=> mw.l 0x318 0x80001000   <= Write low 32-bit NextSrc (NextSrc 
= 0x280001000)
=> mw.l 0x31c 0x2  <= Write high 32-bit NextSrc
=> md.l 0x318 1<= Dump low 32-bit NextSrc
0310: 80001000
=> md.l 0x31c 1<= Dump high 32-bit NextSrc
0314: 0002

2. PDMA transfer from 0x280001000 to 0x28000 is OK.
=> mw.q 0x308 0x4  <= NextBytes = 4
=> mw.l 0x304 0x2200   <= wsize = rsize = 2 (2^2 = 4 bytes)
=> mw.l 0x28000 0x87654321 <= Fill test data to dst
=> mw.l 0x280001000 0x12345678 <= Fill test data to src
=> md.l 0x28000 1; md.l 0x280001000 1  <= Dump src/dst memory contents
28000: 87654321  !Ce.
280001000: 12345678  xV4.
=> md.l 0x300 8<= Dump PDMA status
0300: 0001 2200 0004 ..."
0310: 8000 0002 80001000 0002
=> mw.l 0x300 0x3  <= Set channel 0 run and claim bits
=> md.l 0x300 8<= Dump PDMA status
0300: 4001 2200 0004 ...@..."
0310: 8000 0002 80001000 0002
=> md.l 0x28000 1; md.l 0x280001000 1  <= Dump src/dst memory contents
28000: 12345678   xV4.
280001000: 12345678   xV4.

Signed-off-by: Jim Shu 
Reviewed-by: Frank Chang 
Reviewed-by: Alistair Francis 
Reviewed-by: Bin Meng 
Tested-by: Bin Meng 
---
 hw/dma/sifive_pdma.c | 177 +--
 1 file changed, 155 insertions(+), 22 deletions(-)

diff --git a/hw/dma/sifive_pdma.c b/hw/dma/sifive_pdma.c
index 85fe34f5f3..f4df16449b 100644
--- a/hw/dma/sifive_pdma.c
+++ b/hw/dma/sifive_pdma.c
@@ -177,18 +177,44 @@ static inline void sifive_pdma_update_irq(SiFivePDMAState 
*s, int ch)
 s->chan[ch].state = DMA_CHAN_STATE_IDLE;
 }
 
-static uint64_t sifive_pdma_read(void *opaque, hwaddr offset, unsigned size)
+static uint64_t sifive_pdma_readq(SiFivePDMAState *s, int ch, hwaddr offset)
 {
-SiFivePDMAState *s = opaque;
-int ch = SIFIVE_PDMA_CHAN_NO(offset);
 uint64_t val = 0;
 
-if (ch >= SIFIVE_PDMA_CHANS) {
-qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid channel no %d\n",
-  __func__, ch);
-return 0;
+offset &= 0xfff;
+switch (offset) {
+case DMA_NEXT_BYTES:
+val = s->chan[ch].next_bytes;
+break;
+case DMA_NEXT_DST:
+val = s->chan[ch].next_dst;
+break;
+case DMA_NEXT_SRC:
+val = s->chan[ch].next_src;
+break;
+case DMA_EXEC_BYTES:
+val = s->chan[ch].exec_bytes;
+break;
+case DMA_EXEC_DST:
+val = s->chan[ch].exec_dst;
+break;
+case DMA_EXEC_SRC:
+val = s->chan[ch].exec_src;
+break;
+default:
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Unexpected 64-bit access to 0x%" HWADDR_PRIX "\n",
+  __func__, offset);
+break;
 }
 
+return val;
+}
+
+static uint32_t sifive_pdma_readl(SiFivePDMAState *s, int ch, hwaddr offset)
+{
+uint32_t val = 0;
+
 offset &= 0xfff;
 switch (offset) {
 case DMA_CONTROL:
@@ -198,28 +224,47 @@ static uint64_t sifive_pdma_read(void *opaque, hwaddr 
offset, unsigned size)
 val = s->chan[ch].next_config;
 break;
 case DMA_NEXT_BYTES:
-val = s->chan[ch].next_bytes;
+val = extract64(s->chan[ch].next_bytes, 0, 32);
+break;
+case DMA_NEXT_BYTES + 4:
+val = extract64(s->chan[ch].next_bytes, 32, 32);
 break;
 case DMA_NEXT_DST:
-val = s->chan[ch].next_dst;
+val = extract64(s->chan[ch].next_dst, 0, 32);
+break;
+case DMA_NEXT_DST + 4:
+val = extract64(s->chan[ch].next_dst, 32, 32);
 break;
 case DMA_NEXT_SRC:
-val = s->chan[ch].next_src;
+val = extract64(s->chan[ch].next_src, 0, 32);
+break;
+case DMA_NEXT_SRC + 4:
+val = extract64(s->chan[ch].next_src, 32, 32);
 break;
 case DMA_EXEC_CONFIG:
 val = 

Re: [PATCH 1/2] hw/dma: sifive_pdma: support high 32-bit access of 64-bit register

2022-01-03 Thread Jim Shu
Hi Bin,

Thanks for the review.
I will fix the commit log and the behavior of writing high 32-bit of RO
registers in v2 patch.


Thanks,
Jim Shu

On Tue, Jan 4, 2022 at 10:55 AM Bin Meng  wrote:

> Hi Jim,
>
> On Tue, Dec 28, 2021 at 8:53 AM Jim Shu  wrote:
> >
> > Real PDMA support high 32-bit read/write memory access of 64-bit
>
> %s/support/supports
>
> > register.
> >
> > The following result is PDMA tested in U-Boot on Unmatched board:
> >
> > 1. Real PDMA is allowed high 32-bit read/write to 64-bit register.
>
> %s/is allowed/allows
>
> > => mw.l 0x300 0x0  <= Disclaim channel 0
> > => mw.l 0x300 0x1  <= Claim channel 0
> > => mw.l 0x310 0x8000   <= Write low 32-bit NextDest
> (NextDest = 0x28000)
> > => mw.l 0x314 0x2  <= Write high 32-bit NextDest
> > => md.l 0x310 1<= Dump low 32-bit NextDest
> > 0310: 8000
> > => md.l 0x314 1<= Dump high 32-bit NextDest
> > 0314: 0002
> > => mw.l 0x318 0x80001000   <= Write low 32-bit NextSrc
> (NextSrc = 0x280001000)
> > => mw.l 0x31c 0x2  <= Write high 32-bit NextSrc
> > => md.l 0x318 1<= Dump low 32-bit NextSrc
> > 0310: 80001000
> > => md.l 0x31c 1<= Dump high 32-bit NextSrc
> > 0314: 0002
> >
> > 2. PDMA transfer from 0x280001000 to 0x28000 is OK.
> > => mw.q 0x308 0x4  <= NextBytes = 4
> > => mw.l 0x304 0x2200   <= wsize = rsize = 2 (2^2 = 4
> bytes)
> > => mw.l 0x28000 0x87654321 <= Fill test data to dst
> > => mw.l 0x280001000 0x12345678 <= Fill test data to src
> > => md.l 0x28000 1; md.l 0x280001000 1  <= Dump src/dst memory
> contents
> > 28000: 87654321  !Ce.
> > 280001000: 12345678  xV4.
> > => md.l 0x300 8<= Dump PDMA status
> > 0300: 0001 2200 0004 ..."
> > 0310: 8000 0002 80001000 0002
> > => mw.l 0x300 0x3  <= Set channel 0 run and
> claim bits
> > => md.l 0x300 8<= Dump PDMA status
> > 0300: 4001 2200 0004 ...@..."
> > 0310: 8000 0002 80001000 0002
> > => md.l 0x28000 1; md.l 0x280001000 1  <= Dump src/dst memory
> contents
> > 28000: 12345678   xV4.
> > 280001000: 12345678   xV4.
> >
> > Signed-off-by: Jim Shu 
> > Reviewed-by: Frank Chang 
> > ---
> >  hw/dma/sifive_pdma.c | 174 +--
> >  1 file changed, 152 insertions(+), 22 deletions(-)
> >
> > diff --git a/hw/dma/sifive_pdma.c b/hw/dma/sifive_pdma.c
> > index 85fe34f5f3..b8b198ab4e 100644
> > --- a/hw/dma/sifive_pdma.c
> > +++ b/hw/dma/sifive_pdma.c
> > @@ -177,18 +177,44 @@ static inline void
> sifive_pdma_update_irq(SiFivePDMAState *s, int ch)
> >  s->chan[ch].state = DMA_CHAN_STATE_IDLE;
> >  }
> >
> > -static uint64_t sifive_pdma_read(void *opaque, hwaddr offset, unsigned
> size)
> > +static uint64_t sifive_pdma_readq(SiFivePDMAState *s, int ch, hwaddr
> offset)
> >  {
> > -SiFivePDMAState *s = opaque;
> > -int ch = SIFIVE_PDMA_CHAN_NO(offset);
> >  uint64_t val = 0;
> >
> > -if (ch >= SIFIVE_PDMA_CHANS) {
> > -qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid channel no %d\n",
> > -  __func__, ch);
> > -return 0;
> > +offset &= 0xfff;
> > +switch (offset) {
> > +case DMA_NEXT_BYTES:
> > +val = s->chan[ch].next_bytes;
> > +break;
> > +case DMA_NEXT_DST:
> > +val = s->chan[ch].next_dst;
> > +break;
> > +case DMA_NEXT_SRC:
> > +val = s->chan[ch].next_src;
> > +break;
> > +case DMA_EXEC_BYTES:
> > +val = s->chan[ch].exec_bytes;
> > +break;
> > +case DMA_EXEC_DST:
> > +val = s->chan[ch].exec_dst;
> > +break;
> > +case DMA_EXEC_SRC:
> > +val = s->chan[ch].exec_src;
> > +break;
> > +default:
> > +qemu_log_mask(LOG_GUEST_ERROR,
> > +  "%s: Unexpected 64-bit access to 0x%" HWADDR_PRIX
> "\n",
> > +  __func__, offset);
> > +break;
> >  }
> >
> > +return val;
> > +}
> > +
> > +static uint32_t sifive_pdma_readl(SiFivePDMAState *s, int ch, hwaddr
> offset)
> > +{
> > +uint32_t val = 0;
> > +
> >  offset &= 0xfff;
> >  switch (offset) {
> >  case DMA_CONTROL:
> > @@ -198,28 +224,47 @@ static uint64_t sifive_pdma_read(void *opaque,
> hwaddr offset, unsigned size)
> >  val = s->chan[ch].next_config;
> >  break;
> >  case DMA_NEXT_BYTES:
> > -val = s->chan[ch].next_bytes;
> > +

Re: [PATCH v6 7/7] tests/acpi/bios-table-test: Update expected virt/PPTT file

2022-01-03 Thread wangyanan (Y)



On 2022/1/4 12:27, Ani Sinha wrote:


On Tue, 4 Jan 2022, wangyanan (Y) wrote:


Hi Ani,
Thanks for your review.

On 2022/1/3 20:01, Ani Sinha wrote:

On Mon, 3 Jan 2022, Yanan Wang wrote:


Run ./tests/data/acpi/rebuild-expected-aml.sh from build directory
to update PPTT binary. Also empty bios-tables-test-allowed-diff.h.

The disassembled differences between actual and expected PPTT:

   /*
* Intel ACPI Component Architecture
* AML/ASL+ Disassembler version 20180810 (64-bit version)
* Copyright (c) 2000 - 2018 Intel Corporation
*
- * Disassembly of tests/data/acpi/virt/PPTT, Mon Oct 25 20:24:53 2021
+ * Disassembly of /tmp/aml-BPI5B1, Mon Oct 25 20:24:53 2021
*
* ACPI Data Table [PPTT]
*
* Format: [HexOffset DecimalOffset ByteLength]  FieldName : FieldValue
*/

   [000h    4]Signature : "PPTT"[Processor
Properties Topology Table]
-[004h 0004   4] Table Length : 004C
+[004h 0004   4] Table Length : 0060
   [008h 0008   1] Revision : 02
-[009h 0009   1] Checksum : A8
+[009h 0009   1] Checksum : 48
   [00Ah 0010   6]   Oem ID : "BOCHS "
   [010h 0016   8] Oem Table ID : "BXPC"
   [018h 0024   4] Oem Revision : 0001
   [01Ch 0028   4]  Asl Compiler ID : "BXPC"
   [020h 0032   4]Asl Compiler Revision : 0001

   [024h 0036   1]Subtable Type : 00 [Processor Hierarchy
Node]
   [025h 0037   1]   Length : 14
   [026h 0038   2] Reserved : 
   [028h 0040   4]Flags (decoded below) : 0001
   Physical package : 1
ACPI Processor ID valid : 0
   [02Ch 0044   4]   Parent : 
   [030h 0048   4]ACPI Processor ID : 
   [034h 0052   4]  Private Resource Number : 

   [038h 0056   1]Subtable Type : 00 [Processor Hierarchy
Node]
   [039h 0057   1]   Length : 14
   [03Ah 0058   2] Reserved : 
-[03Ch 0060   4]Flags (decoded below) : 000A
+[03Ch 0060   4]Flags (decoded below) : 
   Physical package : 0
- ACPI Processor ID valid : 1
+ ACPI Processor ID valid : 0

I do not know this very well but does the above two changes (flags and
processor ID) makes sense?

Yes. I think this is exactly what we expected.
Above flags is for the newly inserted cluster node which is between
socket node and core node. Flag "Physical package" is 0 because
it does not represent the boundary of physical package. Flag
"ACPI Processor ID valid" is 0, because we don't need a valid ID
for a container in QEMU (cluster is container of CPU core) just
like socket node.

"000A" originally comes from core node, which now is at
place [*] below.

We can also read the reason why we don't need a valid ID for a
container in 099f2df2e6b "hw/acpi/aml-build: Add PPTT table".

Ok as long as we can explain it, I am good.


   [040h 0064   4]   Parent : 0024
   [044h 0068   4]ACPI Processor ID : 
   [048h 0072   4]  Private Resource Number : 

-Raw Table Data: Length 76 (0x4C)
+[04Ch 0076   1]Subtable Type : 00 [Processor Hierarchy
Node]
+[04Dh 0077   1]   Length : 14
+[04Eh 0078   2] Reserved : 
+[050h 0080   4]Flags (decoded below) : 000A
+Physical package : 0
+ ACPI Processor ID valid : 1
+[054h 0084   4]   Parent : 0038
+[058h 0088   4]ACPI Processor ID : 
+[05Ch 0092   4]  Private Resource Number : 

[*] Information of core node.

Thanks,
Yanan

+
+Raw Table Data: Length 96 (0x60)

-: 50 50 54 54 4C 00 00 00 02 A8 42 4F 43 48 53 20  //
PPTTL.BOCHS
+: 50 50 54 54 60 00 00 00 02 48 42 4F 43 48 53 20  //
PPTT`HBOCHS
   0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43  // BXPC
BXPC
   0020: 01 00 00 00 00 14 00 00 01 00 00 00 00 00 00 00  //

-0030: 00 00 00 00 00 00 00 00 00 14 00 00 0A 00 00 00  //

-0040: 24 00 00 00 00 00 00 00 00 00 00 00  //
$...
+0030: 00 00 00 00 00 00 00 00 00 14 00 00 00 00 00 00  //

+0040: 24 00 00 00 00 00 00 00 00 00 00 00 00 14 00 00  //
$...
+0050: 0A 00 00 00 38 00 00 00 00 00 00 00 00 00 00 00  //
8...

Signed-off-by: Yanan Wang 

Reviewed-by: Ani Sinha 

Thank you.

Yanan

---
   tests/data/acpi/virt/PPTT   | Bin 76 -> 96 bytes
   tests/qtest/bios-tables-test-allowed-diff.h |   1 -
   2 files changed, 1 deletion(-)

diff --git a/tests/data/acpi/virt/PPTT 

Re: [PATCH v6 7/7] tests/acpi/bios-table-test: Update expected virt/PPTT file

2022-01-03 Thread Ani Sinha



On Tue, 4 Jan 2022, wangyanan (Y) wrote:

> Hi Ani,
> Thanks for your review.
>
> On 2022/1/3 20:01, Ani Sinha wrote:
> >
> > On Mon, 3 Jan 2022, Yanan Wang wrote:
> >
> > > Run ./tests/data/acpi/rebuild-expected-aml.sh from build directory
> > > to update PPTT binary. Also empty bios-tables-test-allowed-diff.h.
> > >
> > > The disassembled differences between actual and expected PPTT:
> > >
> > >   /*
> > >* Intel ACPI Component Architecture
> > >* AML/ASL+ Disassembler version 20180810 (64-bit version)
> > >* Copyright (c) 2000 - 2018 Intel Corporation
> > >*
> > > - * Disassembly of tests/data/acpi/virt/PPTT, Mon Oct 25 20:24:53 2021
> > > + * Disassembly of /tmp/aml-BPI5B1, Mon Oct 25 20:24:53 2021
> > >*
> > >* ACPI Data Table [PPTT]
> > >*
> > >* Format: [HexOffset DecimalOffset ByteLength]  FieldName : FieldValue
> > >*/
> > >
> > >   [000h    4]Signature : "PPTT"[Processor
> > > Properties Topology Table]
> > > -[004h 0004   4] Table Length : 004C
> > > +[004h 0004   4] Table Length : 0060
> > >   [008h 0008   1] Revision : 02
> > > -[009h 0009   1] Checksum : A8
> > > +[009h 0009   1] Checksum : 48
> > >   [00Ah 0010   6]   Oem ID : "BOCHS "
> > >   [010h 0016   8] Oem Table ID : "BXPC"
> > >   [018h 0024   4] Oem Revision : 0001
> > >   [01Ch 0028   4]  Asl Compiler ID : "BXPC"
> > >   [020h 0032   4]Asl Compiler Revision : 0001
> > >
> > >   [024h 0036   1]Subtable Type : 00 [Processor Hierarchy
> > > Node]
> > >   [025h 0037   1]   Length : 14
> > >   [026h 0038   2] Reserved : 
> > >   [028h 0040   4]Flags (decoded below) : 0001
> > >   Physical package : 1
> > >ACPI Processor ID valid : 0
> > >   [02Ch 0044   4]   Parent : 
> > >   [030h 0048   4]ACPI Processor ID : 
> > >   [034h 0052   4]  Private Resource Number : 
> > >
> > >   [038h 0056   1]Subtable Type : 00 [Processor Hierarchy
> > > Node]
> > >   [039h 0057   1]   Length : 14
> > >   [03Ah 0058   2] Reserved : 
> > > -[03Ch 0060   4]Flags (decoded below) : 000A
> > > +[03Ch 0060   4]Flags (decoded below) : 
> > >   Physical package : 0
> > > - ACPI Processor ID valid : 1
> > > + ACPI Processor ID valid : 0
> > I do not know this very well but does the above two changes (flags and
> > processor ID) makes sense?
> Yes. I think this is exactly what we expected.
> Above flags is for the newly inserted cluster node which is between
> socket node and core node. Flag "Physical package" is 0 because
> it does not represent the boundary of physical package. Flag
> "ACPI Processor ID valid" is 0, because we don't need a valid ID
> for a container in QEMU (cluster is container of CPU core) just
> like socket node.
>
> "000A" originally comes from core node, which now is at
> place [*] below.
>
> We can also read the reason why we don't need a valid ID for a
> container in 099f2df2e6b "hw/acpi/aml-build: Add PPTT table".

Ok as long as we can explain it, I am good.

> >
> > >   [040h 0064   4]   Parent : 0024
> > >   [044h 0068   4]ACPI Processor ID : 
> > >   [048h 0072   4]  Private Resource Number : 
> > >
> > > -Raw Table Data: Length 76 (0x4C)
> > > +[04Ch 0076   1]Subtable Type : 00 [Processor Hierarchy
> > > Node]
> > > +[04Dh 0077   1]   Length : 14
> > > +[04Eh 0078   2] Reserved : 
> > > +[050h 0080   4]Flags (decoded below) : 000A
> > > +Physical package : 0
> > > + ACPI Processor ID valid : 1
> > > +[054h 0084   4]   Parent : 0038
> > > +[058h 0088   4]ACPI Processor ID : 
> > > +[05Ch 0092   4]  Private Resource Number : 
> [*] Information of core node.
>
> Thanks,
> Yanan
> > > +
> > > +Raw Table Data: Length 96 (0x60)
> > >
> > > -: 50 50 54 54 4C 00 00 00 02 A8 42 4F 43 48 53 20  //
> > > PPTTL.BOCHS
> > > +: 50 50 54 54 60 00 00 00 02 48 42 4F 43 48 53 20  //
> > > PPTT`HBOCHS
> > >   0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43  // BXPC
> > > BXPC
> > >   0020: 01 00 00 00 00 14 00 00 01 00 00 00 00 00 00 00  //
> > > 
> > > -0030: 00 00 00 00 00 00 00 00 00 14 00 00 0A 00 00 00  //
> > > 
> > > -0040: 24 00 00 00 00 00 00 00 00 00 00 00  //
> > > $...
> > > +0030: 00 00 00 00 00 00 00 00 00 14 00 00 00 00 00 

Re: [PATCH v10 2/3] cpu-throttle: implement virtual CPU throttle

2022-01-03 Thread Hyman Huang




在 2022/1/4 10:32, Peter Xu 写道:

On Fri, Dec 31, 2021 at 12:36:40AM +0800, Hyman Huang wrote:

+struct {
+DirtyLimitState *states;
+int max_cpus;
+unsigned long *bmap; /* running thread bitmap */
+unsigned long nr;
+QemuThread thread;
+} *dirtylimit_state;
+
+static bool dirtylimit_quit = true;


Again, I think "quit" is not a good wording to show "whether dirtylimit is in
service".  How about "dirtylimit_global_enabled"?

You can actually use "dirtylimit_state" to show whether it's enabled already
(then drop the global value) since it's a pointer.  It shouldn't need to be
init-once-for-all, but we can alloc the strucuture wAhen dirty limit enabled
globally, and destroy it (and reset it to NULL) when globally disabled.

Then "whether it's enabled" is simply to check "!!dirtylimit_state" under BQL.

Yes, checking pointer is fairly straightforword, but since dirtylimit thread
also access the dirtylimit_state when doing the limit, if we free
dirtylimit_state after last limited vcpu be canceled, dirtylimit thread
would crash when reference null pointer. And this method turn out to
introduce a mutex lock to protect dirtylimit_state, comparing with qatomic
operation, which is better ?


I don't see much difference here on using either atomic or mutex, because it's
not a hot path.

If to use mutex and not overload BQL we can use a dirtylimit_mutex then before
referencing the pointer anywhere we need to fetch it, and release when sleep.

Ok, i'm already try this in the next version :)


The only thing confusing to me about the global variable way is having
quit=true as initial value, and clearing it when start.  I think it'll work,
but just reads weird.

How about having "enabled" and "quit" as a normal threaded app?  Then:

   - When init: enabled=0 quit=0
   - When start: enabled=1 quit=0
   - When stop
 - main thread set enabled=1 quit=1
 - dirtylimit sees quit=1, goes to join()
 - main thread reset enable=quit=0

dirtylimit_in_service() should reference "enabled", and "quit" should be only
used for sync on exit.


Ok, no problem

Thanks,



--
Best regard

Hyman Huang(黄勇)



Re: [PATCH v4 0/7] Unaligned access for user only

2022-01-03 Thread WANG Xuerui

Hi Richard,

On 1/4/22 10:15, Richard Henderson wrote:

Version 3 was way back in August:

https://lore.kernel.org/qemu-devel/20210818191920.390759-1-richard.hender...@linaro.org/

Quite a few of the patches in there have been merged, but not all.

Based-on: <20211227150127.2659293-1-richard.hender...@linaro.org>

There are follow-on patch sets for arm, mips, and sparc, which I
will be refreshing soon.  Xuerui, I believe that tcg/loongarch
should be as simple as one of these five.
Thanks for the heads-up; I'll take care of implementing the loongarch64 
part in this week (or maybe next week in case of $DAY_JOB).



r~


Richard Henderson (7):
   tcg/i386: Support raising sigbus for user-only
   tcg/aarch64: Support raising sigbus for user-only
   tcg/ppc: Support raising sigbus for user-only
   tcg/riscv: Support raising sigbus for user-only
   tcg/s390x: Support raising sigbus for user-only
   tcg/tci: Support raising sigbus for user-only
   tests/tcg/multiarch: Add sigbus.c

  tcg/aarch64/tcg-target.h |   2 -
  tcg/i386/tcg-target.h|   2 -
  tcg/ppc/tcg-target.h |   2 -
  tcg/riscv/tcg-target.h   |   2 -
  tcg/s390x/tcg-target.h   |   2 -
  tcg/tci.c|  20 +--
  tests/tcg/multiarch/sigbus.c |  68 +++
  tcg/aarch64/tcg-target.c.inc |  91 +--
  tcg/i386/tcg-target.c.inc| 103 +--
  tcg/ppc/tcg-target.c.inc |  98 ++---
  tcg/riscv/tcg-target.c.inc   |  63 -
  tcg/s390x/tcg-target.c.inc   |  59 +++-
  12 files changed, 462 insertions(+), 50 deletions(-)
  create mode 100644 tests/tcg/multiarch/sigbus.c





Re: [PATCH 2/2] hw/dma: sifive_pdma: permit 4/8-byte access size of PDMA registers

2022-01-03 Thread Bin Meng
On Tue, Dec 28, 2021 at 8:53 AM Jim Shu  wrote:
>
> It's obvious that PDMA support 64-bit access of 64-bit registers, and

%s/support/supports

> in previous commit, we confirm that PDMA support 32-bit access of both

%s/support/supports

> 32/64-bit registers. Thus, we configure 32/64-bit memory access of
> PDMA registers as valid in general.
>
> Signed-off-by: Jim Shu 
> Reviewed-by: Frank Chang 
> ---
>  hw/dma/sifive_pdma.c | 4 
>  1 file changed, 4 insertions(+)
>
> diff --git a/hw/dma/sifive_pdma.c b/hw/dma/sifive_pdma.c
> index b8b198ab4e..731fcdcf89 100644
> --- a/hw/dma/sifive_pdma.c
> +++ b/hw/dma/sifive_pdma.c
> @@ -441,6 +441,10 @@ static const MemoryRegionOps sifive_pdma_ops = {
>  .impl = {
>  .min_access_size = 4,
>  .max_access_size = 8,
> +},
> +.valid = {
> +.min_access_size = 4,
> +.max_access_size = 8,
>  }
>  };
>

Otherwise,

Reviewed-by: Bin Meng 
Tested-by: Bin Meng 



Re: [PATCH 1/2] hw/dma: sifive_pdma: support high 32-bit access of 64-bit register

2022-01-03 Thread Bin Meng
Hi Jim,

On Tue, Dec 28, 2021 at 8:53 AM Jim Shu  wrote:
>
> Real PDMA support high 32-bit read/write memory access of 64-bit

%s/support/supports

> register.
>
> The following result is PDMA tested in U-Boot on Unmatched board:
>
> 1. Real PDMA is allowed high 32-bit read/write to 64-bit register.

%s/is allowed/allows

> => mw.l 0x300 0x0  <= Disclaim channel 0
> => mw.l 0x300 0x1  <= Claim channel 0
> => mw.l 0x310 0x8000   <= Write low 32-bit NextDest 
> (NextDest = 0x28000)
> => mw.l 0x314 0x2  <= Write high 32-bit NextDest
> => md.l 0x310 1<= Dump low 32-bit NextDest
> 0310: 8000
> => md.l 0x314 1<= Dump high 32-bit NextDest
> 0314: 0002
> => mw.l 0x318 0x80001000   <= Write low 32-bit NextSrc 
> (NextSrc = 0x280001000)
> => mw.l 0x31c 0x2  <= Write high 32-bit NextSrc
> => md.l 0x318 1<= Dump low 32-bit NextSrc
> 0310: 80001000
> => md.l 0x31c 1<= Dump high 32-bit NextSrc
> 0314: 0002
>
> 2. PDMA transfer from 0x280001000 to 0x28000 is OK.
> => mw.q 0x308 0x4  <= NextBytes = 4
> => mw.l 0x304 0x2200   <= wsize = rsize = 2 (2^2 = 4 
> bytes)
> => mw.l 0x28000 0x87654321 <= Fill test data to dst
> => mw.l 0x280001000 0x12345678 <= Fill test data to src
> => md.l 0x28000 1; md.l 0x280001000 1  <= Dump src/dst memory contents
> 28000: 87654321  !Ce.
> 280001000: 12345678  xV4.
> => md.l 0x300 8<= Dump PDMA status
> 0300: 0001 2200 0004 ..."
> 0310: 8000 0002 80001000 0002
> => mw.l 0x300 0x3  <= Set channel 0 run and claim bits
> => md.l 0x300 8<= Dump PDMA status
> 0300: 4001 2200 0004 ...@..."
> 0310: 8000 0002 80001000 0002
> => md.l 0x28000 1; md.l 0x280001000 1  <= Dump src/dst memory contents
> 28000: 12345678   xV4.
> 280001000: 12345678   xV4.
>
> Signed-off-by: Jim Shu 
> Reviewed-by: Frank Chang 
> ---
>  hw/dma/sifive_pdma.c | 174 +--
>  1 file changed, 152 insertions(+), 22 deletions(-)
>
> diff --git a/hw/dma/sifive_pdma.c b/hw/dma/sifive_pdma.c
> index 85fe34f5f3..b8b198ab4e 100644
> --- a/hw/dma/sifive_pdma.c
> +++ b/hw/dma/sifive_pdma.c
> @@ -177,18 +177,44 @@ static inline void 
> sifive_pdma_update_irq(SiFivePDMAState *s, int ch)
>  s->chan[ch].state = DMA_CHAN_STATE_IDLE;
>  }
>
> -static uint64_t sifive_pdma_read(void *opaque, hwaddr offset, unsigned size)
> +static uint64_t sifive_pdma_readq(SiFivePDMAState *s, int ch, hwaddr offset)
>  {
> -SiFivePDMAState *s = opaque;
> -int ch = SIFIVE_PDMA_CHAN_NO(offset);
>  uint64_t val = 0;
>
> -if (ch >= SIFIVE_PDMA_CHANS) {
> -qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid channel no %d\n",
> -  __func__, ch);
> -return 0;
> +offset &= 0xfff;
> +switch (offset) {
> +case DMA_NEXT_BYTES:
> +val = s->chan[ch].next_bytes;
> +break;
> +case DMA_NEXT_DST:
> +val = s->chan[ch].next_dst;
> +break;
> +case DMA_NEXT_SRC:
> +val = s->chan[ch].next_src;
> +break;
> +case DMA_EXEC_BYTES:
> +val = s->chan[ch].exec_bytes;
> +break;
> +case DMA_EXEC_DST:
> +val = s->chan[ch].exec_dst;
> +break;
> +case DMA_EXEC_SRC:
> +val = s->chan[ch].exec_src;
> +break;
> +default:
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "%s: Unexpected 64-bit access to 0x%" HWADDR_PRIX "\n",
> +  __func__, offset);
> +break;
>  }
>
> +return val;
> +}
> +
> +static uint32_t sifive_pdma_readl(SiFivePDMAState *s, int ch, hwaddr offset)
> +{
> +uint32_t val = 0;
> +
>  offset &= 0xfff;
>  switch (offset) {
>  case DMA_CONTROL:
> @@ -198,28 +224,47 @@ static uint64_t sifive_pdma_read(void *opaque, hwaddr 
> offset, unsigned size)
>  val = s->chan[ch].next_config;
>  break;
>  case DMA_NEXT_BYTES:
> -val = s->chan[ch].next_bytes;
> +val = extract64(s->chan[ch].next_bytes, 0, 32);
> +break;
> +case DMA_NEXT_BYTES + 4:
> +val = extract64(s->chan[ch].next_bytes, 32, 32);
>  break;
>  case DMA_NEXT_DST:
> -val = s->chan[ch].next_dst;
> +val = extract64(s->chan[ch].next_dst, 0, 32);
> +break;
> +case DMA_NEXT_DST + 4:
> +val = extract64(s->chan[ch].next_dst, 32, 32);
>  break;
>  case 

[PATCH] sysemu: Cleanup qemu_run_machine_init_done_notifiers()

2022-01-03 Thread Xiaoyao Li
Remove qemu_run_machine_init_done_notifiers() since no implementation
and user.

Signed-off-by: Xiaoyao Li 
---
 include/sysemu/sysemu.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 8fae667172ac..b9421e03ffdd 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -16,7 +16,6 @@ extern bool qemu_uuid_set;
 void qemu_add_exit_notifier(Notifier *notify);
 void qemu_remove_exit_notifier(Notifier *notify);
 
-void qemu_run_machine_init_done_notifiers(void);
 void qemu_add_machine_init_done_notifier(Notifier *notify);
 void qemu_remove_machine_init_done_notifier(Notifier *notify);
 
-- 
2.27.0




[PATCH] trace: Split address space and slot id in trace_kvm_set_user_memory()

2022-01-03 Thread Xiaoyao Li
The upper 16 bits of kvm_userspace_memory_region::slot are
address space id. Parse it separately in trace_kvm_set_user_memory().

Signed-off-by: Xiaoyao Li 
---
 accel/kvm/kvm-all.c| 5 +++--
 accel/kvm/trace-events | 2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 0e66ebb49717..6b9fd943494b 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -379,8 +379,9 @@ static int kvm_set_user_memory_region(KVMMemoryListener 
*kml, KVMSlot *slot, boo
 ret = kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, );
 slot->old_flags = mem.flags;
 err:
-trace_kvm_set_user_memory(mem.slot, mem.flags, mem.guest_phys_addr,
-  mem.memory_size, mem.userspace_addr, ret);
+trace_kvm_set_user_memory(mem.slot >> 16, (uint16_t)mem.slot, mem.flags,
+  mem.guest_phys_addr, mem.memory_size,
+  mem.userspace_addr, ret);
 if (ret < 0) {
 error_report("%s: KVM_SET_USER_MEMORY_REGION failed, slot=%d,"
  " start=0x%" PRIx64 ", size=0x%" PRIx64 ": %s",
diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events
index 399aaeb0ec75..14ebfa1b991c 100644
--- a/accel/kvm/trace-events
+++ b/accel/kvm/trace-events
@@ -15,7 +15,7 @@ kvm_irqchip_update_msi_route(int virq) "Updating MSI route 
virq=%d"
 kvm_irqchip_release_virq(int virq) "virq %d"
 kvm_set_ioeventfd_mmio(int fd, uint64_t addr, uint32_t val, bool assign, 
uint32_t size, bool datamatch) "fd: %d @0x%" PRIx64 " val=0x%x assign: %d size: 
%d match: %d"
 kvm_set_ioeventfd_pio(int fd, uint16_t addr, uint32_t val, bool assign, 
uint32_t size, bool datamatch) "fd: %d @0x%x val=0x%x assign: %d size: %d 
match: %d"
-kvm_set_user_memory(uint32_t slot, uint32_t flags, uint64_t guest_phys_addr, 
uint64_t memory_size, uint64_t userspace_addr, int ret) "Slot#%d flags=0x%x 
gpa=0x%"PRIx64 " size=0x%"PRIx64 " ua=0x%"PRIx64 " ret=%d"
+kvm_set_user_memory(uint16_t as, uint16_t slot, uint32_t flags, uint64_t 
guest_phys_addr, uint64_t memory_size, uint64_t userspace_addr, int ret) 
"AddrSpace#%d Slot#%d flags=0x%x gpa=0x%"PRIx64 " size=0x%"PRIx64 " 
ua=0x%"PRIx64 " ret=%d"
 kvm_clear_dirty_log(uint32_t slot, uint64_t start, uint32_t size) 
"slot#%"PRId32" start 0x%"PRIx64" size 0x%"PRIx32
 kvm_resample_fd_notify(int gsi) "gsi %d"
 kvm_dirty_ring_full(int id) "vcpu %d"
-- 
2.27.0




Re: [PATCH v10 2/3] cpu-throttle: implement virtual CPU throttle

2022-01-03 Thread Peter Xu
On Fri, Dec 31, 2021 at 12:36:40AM +0800, Hyman Huang wrote:
> > > +struct {
> > > +DirtyLimitState *states;
> > > +int max_cpus;
> > > +unsigned long *bmap; /* running thread bitmap */
> > > +unsigned long nr;
> > > +QemuThread thread;
> > > +} *dirtylimit_state;
> > > +
> > > +static bool dirtylimit_quit = true;
> > 
> > Again, I think "quit" is not a good wording to show "whether dirtylimit is 
> > in
> > service".  How about "dirtylimit_global_enabled"?
> > 
> > You can actually use "dirtylimit_state" to show whether it's enabled already
> > (then drop the global value) since it's a pointer.  It shouldn't need to be
> > init-once-for-all, but we can alloc the strucuture wAhen dirty limit enabled
> > globally, and destroy it (and reset it to NULL) when globally disabled.
> > 
> > Then "whether it's enabled" is simply to check "!!dirtylimit_state" under 
> > BQL.
> Yes, checking pointer is fairly straightforword, but since dirtylimit thread
> also access the dirtylimit_state when doing the limit, if we free
> dirtylimit_state after last limited vcpu be canceled, dirtylimit thread
> would crash when reference null pointer. And this method turn out to
> introduce a mutex lock to protect dirtylimit_state, comparing with qatomic
> operation, which is better ?

I don't see much difference here on using either atomic or mutex, because it's
not a hot path.

If to use mutex and not overload BQL we can use a dirtylimit_mutex then before
referencing the pointer anywhere we need to fetch it, and release when sleep.

The only thing confusing to me about the global variable way is having
quit=true as initial value, and clearing it when start.  I think it'll work,
but just reads weird.

How about having "enabled" and "quit" as a normal threaded app?  Then:

  - When init: enabled=0 quit=0
  - When start: enabled=1 quit=0
  - When stop
- main thread set enabled=1 quit=1
- dirtylimit sees quit=1, goes to join()
- main thread reset enable=quit=0

dirtylimit_in_service() should reference "enabled", and "quit" should be only
used for sync on exit.

Thanks,

-- 
Peter Xu




Re: [PATCH v6 7/7] tests/acpi/bios-table-test: Update expected virt/PPTT file

2022-01-03 Thread wangyanan (Y)

Hi Ani,
Thanks for your review.

On 2022/1/3 20:01, Ani Sinha wrote:


On Mon, 3 Jan 2022, Yanan Wang wrote:


Run ./tests/data/acpi/rebuild-expected-aml.sh from build directory
to update PPTT binary. Also empty bios-tables-test-allowed-diff.h.

The disassembled differences between actual and expected PPTT:

  /*
   * Intel ACPI Component Architecture
   * AML/ASL+ Disassembler version 20180810 (64-bit version)
   * Copyright (c) 2000 - 2018 Intel Corporation
   *
- * Disassembly of tests/data/acpi/virt/PPTT, Mon Oct 25 20:24:53 2021
+ * Disassembly of /tmp/aml-BPI5B1, Mon Oct 25 20:24:53 2021
   *
   * ACPI Data Table [PPTT]
   *
   * Format: [HexOffset DecimalOffset ByteLength]  FieldName : FieldValue
   */

  [000h    4]Signature : "PPTT"[Processor 
Properties Topology Table]
-[004h 0004   4] Table Length : 004C
+[004h 0004   4] Table Length : 0060
  [008h 0008   1] Revision : 02
-[009h 0009   1] Checksum : A8
+[009h 0009   1] Checksum : 48
  [00Ah 0010   6]   Oem ID : "BOCHS "
  [010h 0016   8] Oem Table ID : "BXPC"
  [018h 0024   4] Oem Revision : 0001
  [01Ch 0028   4]  Asl Compiler ID : "BXPC"
  [020h 0032   4]Asl Compiler Revision : 0001

  [024h 0036   1]Subtable Type : 00 [Processor Hierarchy Node]
  [025h 0037   1]   Length : 14
  [026h 0038   2] Reserved : 
  [028h 0040   4]Flags (decoded below) : 0001
  Physical package : 1
   ACPI Processor ID valid : 0
  [02Ch 0044   4]   Parent : 
  [030h 0048   4]ACPI Processor ID : 
  [034h 0052   4]  Private Resource Number : 

  [038h 0056   1]Subtable Type : 00 [Processor Hierarchy Node]
  [039h 0057   1]   Length : 14
  [03Ah 0058   2] Reserved : 
-[03Ch 0060   4]Flags (decoded below) : 000A
+[03Ch 0060   4]Flags (decoded below) : 
  Physical package : 0
- ACPI Processor ID valid : 1
+ ACPI Processor ID valid : 0

I do not know this very well but does the above two changes (flags and
processor ID) makes sense?

Yes. I think this is exactly what we expected.
Above flags is for the newly inserted cluster node which is between
socket node and core node. Flag "Physical package" is 0 because
it does not represent the boundary of physical package. Flag
"ACPI Processor ID valid" is 0, because we don't need a valid ID
for a container in QEMU (cluster is container of CPU core) just
like socket node.

"000A" originally comes from core node, which now is at
place [*] below.

We can also read the reason why we don't need a valid ID for a
container in 099f2df2e6b "hw/acpi/aml-build: Add PPTT table".



  [040h 0064   4]   Parent : 0024
  [044h 0068   4]ACPI Processor ID : 
  [048h 0072   4]  Private Resource Number : 

-Raw Table Data: Length 76 (0x4C)
+[04Ch 0076   1]Subtable Type : 00 [Processor Hierarchy Node]
+[04Dh 0077   1]   Length : 14
+[04Eh 0078   2] Reserved : 
+[050h 0080   4]Flags (decoded below) : 000A
+Physical package : 0
+ ACPI Processor ID valid : 1
+[054h 0084   4]   Parent : 0038
+[058h 0088   4]ACPI Processor ID : 
+[05Ch 0092   4]  Private Resource Number : 

[*] Information of core node.

Thanks,
Yanan

+
+Raw Table Data: Length 96 (0x60)

-: 50 50 54 54 4C 00 00 00 02 A8 42 4F 43 48 53 20  // PPTTL.BOCHS
+: 50 50 54 54 60 00 00 00 02 48 42 4F 43 48 53 20  // PPTT`HBOCHS
  0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43  // BXPCBXPC
  0020: 01 00 00 00 00 14 00 00 01 00 00 00 00 00 00 00  // 
-0030: 00 00 00 00 00 00 00 00 00 14 00 00 0A 00 00 00  // 
-0040: 24 00 00 00 00 00 00 00 00 00 00 00  // $...
+0030: 00 00 00 00 00 00 00 00 00 14 00 00 00 00 00 00  // 
+0040: 24 00 00 00 00 00 00 00 00 00 00 00 00 14 00 00  // $...
+0050: 0A 00 00 00 38 00 00 00 00 00 00 00 00 00 00 00  // 8...

Signed-off-by: Yanan Wang 
---
  tests/data/acpi/virt/PPTT   | Bin 76 -> 96 bytes
  tests/qtest/bios-tables-test-allowed-diff.h |   1 -
  2 files changed, 1 deletion(-)

diff --git a/tests/data/acpi/virt/PPTT b/tests/data/acpi/virt/PPTT
index 
7a1258ecf123555b24462c98ccbb76b4ac1d0c2b..f56ea63b369a604877374ad696c396e796ab1c83
 100644
GIT binary patch
delta 53
zcmV-50LuSNU
.





[PATCH v4 6/7] tcg/tci: Support raising sigbus for user-only

2022-01-03 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/tci.c | 20 ++--
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/tcg/tci.c b/tcg/tci.c
index e76087ccac..92a7c81674 100644
--- a/tcg/tci.c
+++ b/tcg/tci.c
@@ -292,11 +292,11 @@ static bool tci_compare64(uint64_t u0, uint64_t u1, 
TCGCond condition)
 static uint64_t tci_qemu_ld(CPUArchState *env, target_ulong taddr,
 MemOpIdx oi, const void *tb_ptr)
 {
-MemOp mop = get_memop(oi) & (MO_BSWAP | MO_SSIZE);
+MemOp mop = get_memop(oi);
 uintptr_t ra = (uintptr_t)tb_ptr;
 
 #ifdef CONFIG_SOFTMMU
-switch (mop) {
+switch (mop & (MO_BSWAP | MO_SSIZE)) {
 case MO_UB:
 return helper_ret_ldub_mmu(env, taddr, oi, ra);
 case MO_SB:
@@ -326,10 +326,14 @@ static uint64_t tci_qemu_ld(CPUArchState *env, 
target_ulong taddr,
 }
 #else
 void *haddr = g2h(env_cpu(env), taddr);
+unsigned a_mask = (1u << get_alignment_bits(mop)) - 1;
 uint64_t ret;
 
 set_helper_retaddr(ra);
-switch (mop) {
+if (taddr & a_mask) {
+helper_unaligned_ld(env, taddr);
+}
+switch (mop & (MO_BSWAP | MO_SSIZE)) {
 case MO_UB:
 ret = ldub_p(haddr);
 break;
@@ -377,11 +381,11 @@ static uint64_t tci_qemu_ld(CPUArchState *env, 
target_ulong taddr,
 static void tci_qemu_st(CPUArchState *env, target_ulong taddr, uint64_t val,
 MemOpIdx oi, const void *tb_ptr)
 {
-MemOp mop = get_memop(oi) & (MO_BSWAP | MO_SSIZE);
+MemOp mop = get_memop(oi);
 uintptr_t ra = (uintptr_t)tb_ptr;
 
 #ifdef CONFIG_SOFTMMU
-switch (mop) {
+switch (mop & (MO_BSWAP | MO_SIZE)) {
 case MO_UB:
 helper_ret_stb_mmu(env, taddr, val, oi, ra);
 break;
@@ -408,9 +412,13 @@ static void tci_qemu_st(CPUArchState *env, target_ulong 
taddr, uint64_t val,
 }
 #else
 void *haddr = g2h(env_cpu(env), taddr);
+unsigned a_mask = (1u << get_alignment_bits(mop)) - 1;
 
 set_helper_retaddr(ra);
-switch (mop) {
+if (taddr & a_mask) {
+helper_unaligned_st(env, taddr);
+}
+switch (mop & (MO_BSWAP | MO_SIZE)) {
 case MO_UB:
 stb_p(haddr, val);
 break;
-- 
2.25.1




[PATCH v4 7/7] tests/tcg/multiarch: Add sigbus.c

2022-01-03 Thread Richard Henderson
A mostly generic test for unaligned access raising SIGBUS.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 tests/tcg/multiarch/sigbus.c | 68 
 1 file changed, 68 insertions(+)
 create mode 100644 tests/tcg/multiarch/sigbus.c

diff --git a/tests/tcg/multiarch/sigbus.c b/tests/tcg/multiarch/sigbus.c
new file mode 100644
index 00..8134c5fd56
--- /dev/null
+++ b/tests/tcg/multiarch/sigbus.c
@@ -0,0 +1,68 @@
+#define _GNU_SOURCE 1
+
+#include 
+#include 
+#include 
+#include 
+
+
+unsigned long long x = 0x8877665544332211ull;
+void * volatile p = (void *) + 1;
+
+void sigbus(int sig, siginfo_t *info, void *uc)
+{
+assert(sig == SIGBUS);
+assert(info->si_signo == SIGBUS);
+#ifdef BUS_ADRALN
+assert(info->si_code == BUS_ADRALN);
+#endif
+assert(info->si_addr == p);
+exit(EXIT_SUCCESS);
+}
+
+int main()
+{
+struct sigaction sa = {
+.sa_sigaction = sigbus,
+.sa_flags = SA_SIGINFO
+};
+int allow_fail = 0;
+int tmp;
+
+tmp = sigaction(SIGBUS, , NULL);
+assert(tmp == 0);
+
+/*
+ * Select an operation that's likely to enforce alignment.
+ * On many guests that support unaligned accesses by default,
+ * this is often an atomic operation.
+ */
+#if defined(__aarch64__)
+asm volatile("ldxr %w0,[%1]" : "=r"(tmp) : "r"(p) : "memory");
+#elif defined(__alpha__)
+asm volatile("ldl_l %0,0(%1)" : "=r"(tmp) : "r"(p) : "memory");
+#elif defined(__arm__)
+asm volatile("ldrex %0,[%1]" : "=r"(tmp) : "r"(p) : "memory");
+#elif defined(__powerpc__)
+asm volatile("lwarx %0,0,%1" : "=r"(tmp) : "r"(p) : "memory");
+#elif defined(__riscv_atomic)
+asm volatile("lr.w %0,(%1)" : "=r"(tmp) : "r"(p) : "memory");
+#else
+/* No insn known to fault unaligned -- try for a straight load. */
+allow_fail = 1;
+tmp = *(volatile int *)p;
+#endif
+
+assert(allow_fail);
+
+/*
+ * We didn't see a signal.
+ * We might as well validate the unaligned load worked.
+ */
+if (BYTE_ORDER == LITTLE_ENDIAN) {
+assert(tmp == 0x55443322);
+} else {
+assert(tmp == 0x77665544);
+}
+return EXIT_SUCCESS;
+}
-- 
2.25.1




[PATCH v4 5/7] tcg/s390x: Support raising sigbus for user-only

2022-01-03 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 tcg/s390x/tcg-target.h |  2 --
 tcg/s390x/tcg-target.c.inc | 59 --
 2 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/tcg/s390x/tcg-target.h b/tcg/s390x/tcg-target.h
index 527ada0f63..69217d995b 100644
--- a/tcg/s390x/tcg-target.h
+++ b/tcg/s390x/tcg-target.h
@@ -178,9 +178,7 @@ static inline void tb_target_set_jmp_target(uintptr_t 
tc_ptr, uintptr_t jmp_rx,
 /* no need to flush icache explicitly */
 }
 
-#ifdef CONFIG_SOFTMMU
 #define TCG_TARGET_NEED_LDST_LABELS
-#endif
 #define TCG_TARGET_NEED_POOL_LABELS
 
 #endif
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
index 57e803e339..d5ec770fb8 100644
--- a/tcg/s390x/tcg-target.c.inc
+++ b/tcg/s390x/tcg-target.c.inc
@@ -29,6 +29,7 @@
 #error "unsupported code generation mode"
 #endif
 
+#include "../tcg-ldst.c.inc"
 #include "../tcg-pool.c.inc"
 #include "elf.h"
 
@@ -136,6 +137,7 @@ typedef enum S390Opcode {
 RI_OIHL = 0xa509,
 RI_OILH = 0xa50a,
 RI_OILL = 0xa50b,
+RI_TMLL = 0xa701,
 
 RIE_CGIJ= 0xec7c,
 RIE_CGRJ= 0xec64,
@@ -1804,8 +1806,6 @@ static void tcg_out_qemu_st_direct(TCGContext *s, MemOp 
opc, TCGReg data,
 }
 
 #if defined(CONFIG_SOFTMMU)
-#include "../tcg-ldst.c.inc"
-
 /* We're expecting to use a 20-bit negative offset on the tlb memory ops.  */
 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 19));
@@ -1942,6 +1942,53 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, 
TCGLabelQemuLdst *lb)
 return true;
 }
 #else
+static void tcg_out_test_alignment(TCGContext *s, bool is_ld,
+   TCGReg addrlo, unsigned a_bits)
+{
+unsigned a_mask = (1 << a_bits) - 1;
+TCGLabelQemuLdst *l = new_ldst_label(s);
+
+l->is_ld = is_ld;
+l->addrlo_reg = addrlo;
+
+/* We are expecting a_bits to max out at 7, much lower than TMLL. */
+tcg_debug_assert(a_bits < 16);
+tcg_out_insn(s, RI, TMLL, addrlo, a_mask);
+
+tcg_out16(s, RI_BRC | (7 << 4)); /* CC in {1,2,3} */
+l->label_ptr[0] = s->code_ptr;
+s->code_ptr += 1;
+
+l->raddr = tcg_splitwx_to_rx(s->code_ptr);
+}
+
+static bool tcg_out_fail_alignment(TCGContext *s, TCGLabelQemuLdst *l)
+{
+if (!patch_reloc(l->label_ptr[0], R_390_PC16DBL,
+ (intptr_t)tcg_splitwx_to_rx(s->code_ptr), 2)) {
+return false;
+}
+
+tcg_out_mov(s, TCG_TYPE_TL, TCG_REG_R3, l->addrlo_reg);
+tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_AREG0);
+
+/* "Tail call" to the helper, with the return address back inline. */
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R14, (uintptr_t)l->raddr);
+tgen_gotoi(s, S390_CC_ALWAYS, (const void *)(l->is_ld ? helper_unaligned_ld
+ : helper_unaligned_st));
+return true;
+}
+
+static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
+{
+return tcg_out_fail_alignment(s, l);
+}
+
+static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
+{
+return tcg_out_fail_alignment(s, l);
+}
+
 static void tcg_prepare_user_ldst(TCGContext *s, TCGReg *addr_reg,
   TCGReg *index_reg, tcg_target_long *disp)
 {
@@ -1980,7 +2027,11 @@ static void tcg_out_qemu_ld(TCGContext* s, TCGReg 
data_reg, TCGReg addr_reg,
 #else
 TCGReg index_reg;
 tcg_target_long disp;
+unsigned a_bits = get_alignment_bits(opc);
 
+if (a_bits) {
+tcg_out_test_alignment(s, true, addr_reg, a_bits);
+}
 tcg_prepare_user_ldst(s, _reg, _reg, );
 tcg_out_qemu_ld_direct(s, opc, data_reg, addr_reg, index_reg, disp);
 #endif
@@ -2007,7 +2058,11 @@ static void tcg_out_qemu_st(TCGContext* s, TCGReg 
data_reg, TCGReg addr_reg,
 #else
 TCGReg index_reg;
 tcg_target_long disp;
+unsigned a_bits = get_alignment_bits(opc);
 
+if (a_bits) {
+tcg_out_test_alignment(s, false, addr_reg, a_bits);
+}
 tcg_prepare_user_ldst(s, _reg, _reg, );
 tcg_out_qemu_st_direct(s, opc, data_reg, addr_reg, index_reg, disp);
 #endif
-- 
2.25.1




[PATCH v4 4/7] tcg/riscv: Support raising sigbus for user-only

2022-01-03 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/riscv/tcg-target.h |  2 --
 tcg/riscv/tcg-target.c.inc | 63 --
 2 files changed, 61 insertions(+), 4 deletions(-)

diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index ef78b99e98..11c9b3e4f4 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -165,9 +165,7 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 
 #define TCG_TARGET_DEFAULT_MO (0)
 
-#ifdef CONFIG_SOFTMMU
 #define TCG_TARGET_NEED_LDST_LABELS
-#endif
 #define TCG_TARGET_NEED_POOL_LABELS
 
 #define TCG_TARGET_HAS_MEMORY_BSWAP 0
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 9b13a46fb4..49e84cbe13 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -27,6 +27,7 @@
  * THE SOFTWARE.
  */
 
+#include "../tcg-ldst.c.inc"
 #include "../tcg-pool.c.inc"
 
 #ifdef CONFIG_DEBUG_TCG
@@ -847,8 +848,6 @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
  */
 
 #if defined(CONFIG_SOFTMMU)
-#include "../tcg-ldst.c.inc"
-
 /* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
  * MemOpIdx oi, uintptr_t ra)
  */
@@ -1053,6 +1052,54 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, 
TCGLabelQemuLdst *l)
 tcg_out_goto(s, l->raddr);
 return true;
 }
+#else
+
+static void tcg_out_test_alignment(TCGContext *s, bool is_ld, TCGReg addr_reg,
+   unsigned a_bits)
+{
+unsigned a_mask = (1 << a_bits) - 1;
+TCGLabelQemuLdst *l = new_ldst_label(s);
+
+l->is_ld = is_ld;
+l->addrlo_reg = addr_reg;
+
+/* We are expecting a_bits to max out at 7, so we can always use andi. */
+tcg_debug_assert(a_bits < 12);
+tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_TMP1, addr_reg, a_mask);
+
+l->label_ptr[0] = s->code_ptr;
+tcg_out_opc_branch(s, OPC_BNE, TCG_REG_TMP1, TCG_REG_ZERO, 0);
+
+l->raddr = tcg_splitwx_to_rx(s->code_ptr);
+}
+
+static bool tcg_out_fail_alignment(TCGContext *s, TCGLabelQemuLdst *l)
+{
+/* resolve label address */
+if (!reloc_sbimm12(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
+return false;
+}
+
+tcg_out_mov(s, TCG_TYPE_TL, TCG_REG_A1, l->addrlo_reg);
+tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0);
+
+/* tail call, with the return address back inline. */
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RA, (uintptr_t)l->raddr);
+tcg_out_call_int(s, (const void *)(l->is_ld ? helper_unaligned_ld
+   : helper_unaligned_st), true);
+return true;
+}
+
+static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
+{
+return tcg_out_fail_alignment(s, l);
+}
+
+static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
+{
+return tcg_out_fail_alignment(s, l);
+}
+
 #endif /* CONFIG_SOFTMMU */
 
 static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg lo, TCGReg hi,
@@ -1108,6 +1155,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg 
*args, bool is_64)
 MemOp opc;
 #if defined(CONFIG_SOFTMMU)
 tcg_insn_unit *label_ptr[1];
+#else
+unsigned a_bits;
 #endif
 TCGReg base = TCG_REG_TMP0;
 
@@ -1130,6 +1179,10 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg 
*args, bool is_64)
 tcg_out_ext32u(s, base, addr_regl);
 addr_regl = base;
 }
+a_bits = get_alignment_bits(opc);
+if (a_bits) {
+tcg_out_test_alignment(s, true, addr_regl, a_bits);
+}
 if (guest_base != 0) {
 tcg_out_opc_reg(s, OPC_ADD, base, TCG_GUEST_BASE_REG, addr_regl);
 }
@@ -1174,6 +1227,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args, bool is_64)
 MemOp opc;
 #if defined(CONFIG_SOFTMMU)
 tcg_insn_unit *label_ptr[1];
+#else
+unsigned a_bits;
 #endif
 TCGReg base = TCG_REG_TMP0;
 
@@ -1196,6 +1251,10 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args, bool is_64)
 tcg_out_ext32u(s, base, addr_regl);
 addr_regl = base;
 }
+a_bits = get_alignment_bits(opc);
+if (a_bits) {
+tcg_out_test_alignment(s, false, addr_regl, a_bits);
+}
 if (guest_base != 0) {
 tcg_out_opc_reg(s, OPC_ADD, base, TCG_GUEST_BASE_REG, addr_regl);
 }
-- 
2.25.1




[PATCH v4 1/7] tcg/i386: Support raising sigbus for user-only

2022-01-03 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 tcg/i386/tcg-target.h |   2 -
 tcg/i386/tcg-target.c.inc | 103 --
 2 files changed, 98 insertions(+), 7 deletions(-)

diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index b00a6da293..3b2c9437a0 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -232,9 +232,7 @@ static inline void tb_target_set_jmp_target(uintptr_t 
tc_ptr, uintptr_t jmp_rx,
 
 #define TCG_TARGET_HAS_MEMORY_BSWAP  have_movbe
 
-#ifdef CONFIG_SOFTMMU
 #define TCG_TARGET_NEED_LDST_LABELS
-#endif
 #define TCG_TARGET_NEED_POOL_LABELS
 
 #endif
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
index 84b109bb84..e073868d8f 100644
--- a/tcg/i386/tcg-target.c.inc
+++ b/tcg/i386/tcg-target.c.inc
@@ -22,6 +22,7 @@
  * THE SOFTWARE.
  */
 
+#include "../tcg-ldst.c.inc"
 #include "../tcg-pool.c.inc"
 
 #ifdef CONFIG_DEBUG_TCG
@@ -421,8 +422,9 @@ static bool tcg_target_const_match(int64_t val, TCGType 
type, int ct)
 #define OPC_VZEROUPPER  (0x77 | P_EXT)
 #define OPC_XCHG_ax_r32(0x90)
 
-#define OPC_GRP3_Ev(0xf7)
-#define OPC_GRP5   (0xff)
+#define OPC_GRP3_Eb (0xf6)
+#define OPC_GRP3_Ev (0xf7)
+#define OPC_GRP5(0xff)
 #define OPC_GRP14   (0x73 | P_EXT | P_DATA16)
 
 /* Group 1 opcode extensions for 0x80-0x83.
@@ -444,6 +446,7 @@ static bool tcg_target_const_match(int64_t val, TCGType 
type, int ct)
 #define SHIFT_SAR 7
 
 /* Group 3 opcode extensions for 0xf6, 0xf7.  To be used with OPC_GRP3.  */
+#define EXT3_TESTi 0
 #define EXT3_NOT   2
 #define EXT3_NEG   3
 #define EXT3_MUL   4
@@ -1606,8 +1609,6 @@ static void tcg_out_nopn(TCGContext *s, int n)
 }
 
 #if defined(CONFIG_SOFTMMU)
-#include "../tcg-ldst.c.inc"
-
 /* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
  * int mmu_idx, uintptr_t ra)
  */
@@ -1916,7 +1917,84 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, 
TCGLabelQemuLdst *l)
 tcg_out_jmp(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
 return true;
 }
-#elif TCG_TARGET_REG_BITS == 32
+#else
+
+static void tcg_out_test_alignment(TCGContext *s, bool is_ld, TCGReg addrlo,
+   TCGReg addrhi, unsigned a_bits)
+{
+unsigned a_mask = (1 << a_bits) - 1;
+TCGLabelQemuLdst *label;
+
+/*
+ * We are expecting a_bits to max out at 7, so we can usually use testb.
+ * For i686, we have to use testl for %esi/%edi.
+ */
+if (a_mask <= 0xff && (TCG_TARGET_REG_BITS == 64 || addrlo < 4)) {
+tcg_out_modrm(s, OPC_GRP3_Eb | P_REXB_RM, EXT3_TESTi, addrlo);
+tcg_out8(s, a_mask);
+} else {
+tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_TESTi, addrlo);
+tcg_out32(s, a_mask);
+}
+
+/* jne slow_path */
+tcg_out_opc(s, OPC_JCC_long + JCC_JNE, 0, 0, 0);
+
+label = new_ldst_label(s);
+label->is_ld = is_ld;
+label->addrlo_reg = addrlo;
+label->addrhi_reg = addrhi;
+label->raddr = tcg_splitwx_to_rx(s->code_ptr + 4);
+label->label_ptr[0] = s->code_ptr;
+
+s->code_ptr += 4;
+}
+
+static bool tcg_out_fail_alignment(TCGContext *s, TCGLabelQemuLdst *l)
+{
+/* resolve label address */
+tcg_patch32(l->label_ptr[0], s->code_ptr - l->label_ptr[0] - 4);
+
+if (TCG_TARGET_REG_BITS == 32) {
+int ofs = 0;
+
+tcg_out_st(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_ESP, ofs);
+ofs += 4;
+
+tcg_out_st(s, TCG_TYPE_I32, l->addrlo_reg, TCG_REG_ESP, ofs);
+ofs += 4;
+if (TARGET_LONG_BITS == 64) {
+tcg_out_st(s, TCG_TYPE_I32, l->addrhi_reg, TCG_REG_ESP, ofs);
+ofs += 4;
+}
+
+tcg_out_pushi(s, (uintptr_t)l->raddr);
+} else {
+tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
+l->addrlo_reg);
+tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
+
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RAX, (uintptr_t)l->raddr);
+tcg_out_push(s, TCG_REG_RAX);
+}
+
+/* "Tail call" to the helper, with the return address back inline. */
+tcg_out_jmp(s, (const void *)(l->is_ld ? helper_unaligned_ld
+  : helper_unaligned_st));
+return true;
+}
+
+static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
+{
+return tcg_out_fail_alignment(s, l);
+}
+
+static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
+{
+return tcg_out_fail_alignment(s, l);
+}
+
+#if TCG_TARGET_REG_BITS == 32
 # define x86_guest_base_seg 0
 # define x86_guest_base_index   -1
 # define x86_guest_base_offset  guest_base
@@ -1950,6 +2028,7 @@ static inline int setup_guest_base_seg(void)
 return 0;
 }
 # endif
+#endif
 #endif /* SOFTMMU */
 
 static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
@@ -2059,6 +2138,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg 

[PATCH v4 3/7] tcg/ppc: Support raising sigbus for user-only

2022-01-03 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 tcg/ppc/tcg-target.h |  2 -
 tcg/ppc/tcg-target.c.inc | 98 
 2 files changed, 90 insertions(+), 10 deletions(-)

diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index 0943192cde..c775c97b61 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -182,9 +182,7 @@ void tb_target_set_jmp_target(uintptr_t, uintptr_t, 
uintptr_t, uintptr_t);
 #define TCG_TARGET_DEFAULT_MO (0)
 #define TCG_TARGET_HAS_MEMORY_BSWAP 1
 
-#ifdef CONFIG_SOFTMMU
 #define TCG_TARGET_NEED_LDST_LABELS
-#endif
 #define TCG_TARGET_NEED_POOL_LABELS
 
 #endif
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
index 3e4ca2be88..8a117e0665 100644
--- a/tcg/ppc/tcg-target.c.inc
+++ b/tcg/ppc/tcg-target.c.inc
@@ -24,6 +24,7 @@
 
 #include "elf.h"
 #include "../tcg-pool.c.inc"
+#include "../tcg-ldst.c.inc"
 
 /*
  * Standardize on the _CALL_FOO symbols used by GCC:
@@ -1881,7 +1882,8 @@ void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t 
jmp_rx,
 }
 }
 
-static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target)
+static void tcg_out_call_int(TCGContext *s, int lk,
+ const tcg_insn_unit *target)
 {
 #ifdef _CALL_AIX
 /* Look through the descriptor.  If the branch is in range, and we
@@ -1892,7 +1894,7 @@ static void tcg_out_call(TCGContext *s, const 
tcg_insn_unit *target)
 
 if (in_range_b(diff) && toc == (uint32_t)toc) {
 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP1, toc);
-tcg_out_b(s, LK, tgt);
+tcg_out_b(s, lk, tgt);
 } else {
 /* Fold the low bits of the constant into the addresses below.  */
 intptr_t arg = (intptr_t)target;
@@ -1907,7 +1909,7 @@ static void tcg_out_call(TCGContext *s, const 
tcg_insn_unit *target)
 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_TMP1, ofs);
 tcg_out32(s, MTSPR | RA(TCG_REG_R0) | CTR);
 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_REG_TMP1, ofs + SZP);
-tcg_out32(s, BCCTR | BO_ALWAYS | LK);
+tcg_out32(s, BCCTR | BO_ALWAYS | lk);
 }
 #elif defined(_CALL_ELF) && _CALL_ELF == 2
 intptr_t diff;
@@ -1921,16 +1923,21 @@ static void tcg_out_call(TCGContext *s, const 
tcg_insn_unit *target)
 
 diff = tcg_pcrel_diff(s, target);
 if (in_range_b(diff)) {
-tcg_out_b(s, LK, target);
+tcg_out_b(s, lk, target);
 } else {
 tcg_out32(s, MTSPR | RS(TCG_REG_R12) | CTR);
-tcg_out32(s, BCCTR | BO_ALWAYS | LK);
+tcg_out32(s, BCCTR | BO_ALWAYS | lk);
 }
 #else
-tcg_out_b(s, LK, target);
+tcg_out_b(s, lk, target);
 #endif
 }
 
+static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target)
+{
+tcg_out_call_int(s, LK, target);
+}
+
 static const uint32_t qemu_ldx_opc[(MO_SSIZE + MO_BSWAP) + 1] = {
 [MO_UB] = LBZX,
 [MO_UW] = LHZX,
@@ -1960,8 +1967,6 @@ static const uint32_t qemu_exts_opc[4] = {
 };
 
 #if defined (CONFIG_SOFTMMU)
-#include "../tcg-ldst.c.inc"
-
 /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
  * int mmu_idx, uintptr_t ra)
  */
@@ -2227,6 +2232,71 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, 
TCGLabelQemuLdst *lb)
 tcg_out_b(s, 0, lb->raddr);
 return true;
 }
+#else
+
+static void tcg_out_test_alignment(TCGContext *s, bool is_ld, TCGReg addrlo,
+   TCGReg addrhi, unsigned a_bits)
+{
+unsigned a_mask = (1 << a_bits) - 1;
+TCGLabelQemuLdst *label = new_ldst_label(s);
+
+label->is_ld = is_ld;
+label->addrlo_reg = addrlo;
+label->addrhi_reg = addrhi;
+
+/* We are expecting a_bits to max out at 7, much lower than ANDI. */
+tcg_debug_assert(a_bits < 16);
+tcg_out32(s, ANDI | SAI(addrlo, TCG_REG_R0, a_mask));
+
+label->label_ptr[0] = s->code_ptr;
+tcg_out32(s, BC | BI(0, CR_EQ) | BO_COND_FALSE | LK);
+
+label->raddr = tcg_splitwx_to_rx(s->code_ptr);
+}
+
+static bool tcg_out_fail_alignment(TCGContext *s, TCGLabelQemuLdst *l)
+{
+if (!reloc_pc14(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
+return false;
+}
+
+if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
+TCGReg arg = TCG_REG_R4;
+#ifdef TCG_TARGET_CALL_ALIGN_ARGS
+arg |= 1;
+#endif
+if (l->addrlo_reg != arg) {
+tcg_out_mov(s, TCG_TYPE_I32, arg, l->addrhi_reg);
+tcg_out_mov(s, TCG_TYPE_I32, arg + 1, l->addrlo_reg);
+} else if (l->addrhi_reg != arg + 1) {
+tcg_out_mov(s, TCG_TYPE_I32, arg + 1, l->addrlo_reg);
+tcg_out_mov(s, TCG_TYPE_I32, arg, l->addrhi_reg);
+} else {
+tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_R0, arg);
+tcg_out_mov(s, TCG_TYPE_I32, arg, arg + 1);
+tcg_out_mov(s, TCG_TYPE_I32, arg + 1, TCG_REG_R0);
+}
+} else {
+tcg_out_mov(s, TCG_TYPE_TL, TCG_REG_R4, l->addrlo_reg);
+}
+

[PATCH v4 0/7] Unaligned access for user only

2022-01-03 Thread Richard Henderson
Version 3 was way back in August:

https://lore.kernel.org/qemu-devel/20210818191920.390759-1-richard.hender...@linaro.org/

Quite a few of the patches in there have been merged, but not all.

Based-on: <20211227150127.2659293-1-richard.hender...@linaro.org>

There are follow-on patch sets for arm, mips, and sparc, which I
will be refreshing soon.  Xuerui, I believe that tcg/loongarch
should be as simple as one of these five.


r~


Richard Henderson (7):
  tcg/i386: Support raising sigbus for user-only
  tcg/aarch64: Support raising sigbus for user-only
  tcg/ppc: Support raising sigbus for user-only
  tcg/riscv: Support raising sigbus for user-only
  tcg/s390x: Support raising sigbus for user-only
  tcg/tci: Support raising sigbus for user-only
  tests/tcg/multiarch: Add sigbus.c

 tcg/aarch64/tcg-target.h |   2 -
 tcg/i386/tcg-target.h|   2 -
 tcg/ppc/tcg-target.h |   2 -
 tcg/riscv/tcg-target.h   |   2 -
 tcg/s390x/tcg-target.h   |   2 -
 tcg/tci.c|  20 +--
 tests/tcg/multiarch/sigbus.c |  68 +++
 tcg/aarch64/tcg-target.c.inc |  91 +--
 tcg/i386/tcg-target.c.inc| 103 +--
 tcg/ppc/tcg-target.c.inc |  98 ++---
 tcg/riscv/tcg-target.c.inc   |  63 -
 tcg/s390x/tcg-target.c.inc   |  59 +++-
 12 files changed, 462 insertions(+), 50 deletions(-)
 create mode 100644 tests/tcg/multiarch/sigbus.c

-- 
2.25.1




[PATCH v4 2/7] tcg/aarch64: Support raising sigbus for user-only

2022-01-03 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.h |  2 -
 tcg/aarch64/tcg-target.c.inc | 91 +---
 2 files changed, 74 insertions(+), 19 deletions(-)

diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index 7a93ac8023..876af589ce 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -151,9 +151,7 @@ typedef enum {
 
 void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
 
-#ifdef CONFIG_SOFTMMU
 #define TCG_TARGET_NEED_LDST_LABELS
-#endif
 #define TCG_TARGET_NEED_POOL_LABELS
 
 #endif /* AARCH64_TCG_TARGET_H */
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
index 5edca8d44d..1f205f90b2 100644
--- a/tcg/aarch64/tcg-target.c.inc
+++ b/tcg/aarch64/tcg-target.c.inc
@@ -10,6 +10,7 @@
  * See the COPYING file in the top-level directory for details.
  */
 
+#include "../tcg-ldst.c.inc"
 #include "../tcg-pool.c.inc"
 #include "qemu/bitops.h"
 
@@ -443,6 +444,7 @@ typedef enum {
 I3404_ANDI  = 0x1200,
 I3404_ORRI  = 0x3200,
 I3404_EORI  = 0x5200,
+I3404_ANDSI = 0x7200,
 
 /* Move wide immediate instructions.  */
 I3405_MOVN  = 0x1280,
@@ -1328,8 +1330,9 @@ static void tcg_out_goto_long(TCGContext *s, const 
tcg_insn_unit *target)
 if (offset == sextract64(offset, 0, 26)) {
 tcg_out_insn(s, 3206, B, offset);
 } else {
-tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, (intptr_t)target);
-tcg_out_insn(s, 3207, BR, TCG_REG_TMP);
+/* Choose X9 as a call-clobbered non-LR temporary. */
+tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_X9, (intptr_t)target);
+tcg_out_insn(s, 3207, BR, TCG_REG_X9);
 }
 }
 
@@ -1541,9 +1544,14 @@ static void tcg_out_cltz(TCGContext *s, TCGType ext, 
TCGReg d,
 }
 }
 
-#ifdef CONFIG_SOFTMMU
-#include "../tcg-ldst.c.inc"
+static void tcg_out_adr(TCGContext *s, TCGReg rd, const void *target)
+{
+ptrdiff_t offset = tcg_pcrel_diff(s, target);
+tcg_debug_assert(offset == sextract64(offset, 0, 21));
+tcg_out_insn(s, 3406, ADR, rd, offset);
+}
 
+#ifdef CONFIG_SOFTMMU
 /* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
  * MemOpIdx oi, uintptr_t ra)
  */
@@ -1577,13 +1585,6 @@ static void * const qemu_st_helpers[MO_SIZE + 1] = {
 #endif
 };
 
-static inline void tcg_out_adr(TCGContext *s, TCGReg rd, const void *target)
-{
-ptrdiff_t offset = tcg_pcrel_diff(s, target);
-tcg_debug_assert(offset == sextract64(offset, 0, 21));
-tcg_out_insn(s, 3406, ADR, rd, offset);
-}
-
 static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
 {
 MemOpIdx oi = lb->oi;
@@ -1714,15 +1715,58 @@ static void tcg_out_tlb_read(TCGContext *s, TCGReg 
addr_reg, MemOp opc,
 tcg_out_insn(s, 3202, B_C, TCG_COND_NE, 0);
 }
 
+#else
+static void tcg_out_test_alignment(TCGContext *s, bool is_ld, TCGReg addr_reg,
+   unsigned a_bits)
+{
+unsigned a_mask = (1 << a_bits) - 1;
+TCGLabelQemuLdst *label = new_ldst_label(s);
+
+label->is_ld = is_ld;
+label->addrlo_reg = addr_reg;
+
+/* tst addr, #mask */
+tcg_out_logicali(s, I3404_ANDSI, 0, TCG_REG_XZR, addr_reg, a_mask);
+
+label->label_ptr[0] = s->code_ptr;
+
+/* b.ne slow_path */
+tcg_out_insn(s, 3202, B_C, TCG_COND_NE, 0);
+
+label->raddr = tcg_splitwx_to_rx(s->code_ptr);
+}
+
+static bool tcg_out_fail_alignment(TCGContext *s, TCGLabelQemuLdst *l)
+{
+if (!reloc_pc19(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
+return false;
+}
+
+tcg_out_mov(s, TCG_TYPE_TL, TCG_REG_X1, l->addrlo_reg);
+tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_X0, TCG_AREG0);
+
+/* "Tail call" to the helper, with the return address back inline. */
+tcg_out_adr(s, TCG_REG_LR, l->raddr);
+tcg_out_goto_long(s, (const void *)(l->is_ld ? helper_unaligned_ld
+: helper_unaligned_st));
+return true;
+}
+
+static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
+{
+return tcg_out_fail_alignment(s, l);
+}
+
+static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
+{
+return tcg_out_fail_alignment(s, l);
+}
 #endif /* CONFIG_SOFTMMU */
 
 static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp memop, TCGType ext,
TCGReg data_r, TCGReg addr_r,
TCGType otype, TCGReg off_r)
 {
-/* Byte swapping is left to middle-end expansion. */
-tcg_debug_assert((memop & MO_BSWAP) == 0);
-
 switch (memop & MO_SSIZE) {
 case MO_UB:
 tcg_out_ldst_r(s, I3312_LDRB, data_r, addr_r, otype, off_r);
@@ -1756,9 +1800,6 @@ static void tcg_out_qemu_st_direct(TCGContext *s, MemOp 
memop,
TCGReg data_r, TCGReg addr_r,
TCGType otype, TCGReg off_r)
 {
-

Re: [PATCH v6 6/7] hw/arm/virt-acpi-build: Support cluster level in PPTT generation

2022-01-03 Thread wangyanan (Y)



On 2022/1/3 19:32, Andrew Jones wrote:

On Mon, Jan 03, 2022 at 04:46:35PM +0800, Yanan Wang wrote:

Support cluster level in generation of ACPI Processor Properties
Topology Table (PPTT) for ARM virt machines.

Signed-off-by: Yanan Wang 
---
  hw/arm/virt-acpi-build.c | 15 +++
  1 file changed, 15 insertions(+)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 3ce7680393..5f91969688 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -840,6 +840,21 @@ build_pptt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
  0, socket, NULL, 0);
  }
  
+length = g_queue_get_length(list);

+for (i = 0; i < length; i++) {
+int cluster;
+
+father_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
+for (cluster = 0; cluster < ms->smp.clusters; cluster++) {
+g_queue_push_tail(list,
+GUINT_TO_POINTER(table_data->len - pptt_start));
+build_processor_hierarchy_node(
+table_data,
+(0 << 0), /* not a physical package */
+father_offset, cluster, NULL, 0);
+}
+}
+
  length = g_queue_get_length(list);
  for (i = 0; i < length; i++) {
  int core;
--
2.27.0


Looks good except please do s/father_offset/parent_offset/ as I mentioned
in an earlier patch.

Will do.


Reviewed-by: Andrew Jones 


Thanks,
Yanan




Re: [PATCH v6 3/7] hw/acpi/aml-build: Improve scalability of PPTT generation

2022-01-03 Thread wangyanan (Y)

Hi Drew,
Thanks for your review.
On 2022/1/3 19:24, Andrew Jones wrote:

On Mon, Jan 03, 2022 at 04:46:32PM +0800, Yanan Wang wrote:

Currently we generate a PPTT table of n-level processor hierarchy
with n-level loops in build_pptt(). It works fine as now there are
only three CPU topology parameters. But the code may become less
scalable with the processor hierarchy levels increasing.

This patch only improves the scalability of build_pptt by reducing
the loops, and intends to make no functional change.

Signed-off-by: Yanan Wang 
---
  hw/acpi/aml-build.c | 50 +
  1 file changed, 32 insertions(+), 18 deletions(-)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index b3b3310df3..be3851be36 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -2001,7 +2001,10 @@ static void build_processor_hierarchy_node(GArray *tbl, 
uint32_t flags,
  void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
  const char *oem_id, const char *oem_table_id)
  {
-int pptt_start = table_data->len;
+GQueue *list = g_queue_new();
+guint pptt_start = table_data->len;
+guint father_offset;

"parent_offset" would be more conventional.

Apparently... I will rename it.

+guint length, i;
  int uid = 0;
  int socket;
  AcpiTable table = { .sig = "PPTT", .rev = 2,
@@ -2010,9 +2013,8 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, 
MachineState *ms,
  acpi_table_begin(, table_data);
  
  for (socket = 0; socket < ms->smp.sockets; socket++) {

-uint32_t socket_offset = table_data->len - pptt_start;
-int core;
-
+g_queue_push_tail(list,
+GUINT_TO_POINTER(table_data->len - pptt_start));
  build_processor_hierarchy_node(
  table_data,
  /*
@@ -2021,35 +2023,47 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, 
MachineState *ms,
   */
  (1 << 0),
  0, socket, NULL, 0);
+}
  
-for (core = 0; core < ms->smp.cores; core++) {

-uint32_t core_offset = table_data->len - pptt_start;
-int thread;
+length = g_queue_get_length(list);
+for (i = 0; i < length; i++) {
+int core;
  
+father_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));

+for (core = 0; core < ms->smp.cores; core++) {
  if (ms->smp.threads > 1) {
+g_queue_push_tail(list,
+GUINT_TO_POINTER(table_data->len - pptt_start));
  build_processor_hierarchy_node(
  table_data,
  (0 << 0), /* not a physical package */
-socket_offset, core, NULL, 0);
-
-for (thread = 0; thread < ms->smp.threads; thread++) {
-build_processor_hierarchy_node(
-table_data,
-(1 << 1) | /* ACPI Processor ID valid */
-(1 << 2) | /* Processor is a Thread */
-(1 << 3),  /* Node is a Leaf */
-core_offset, uid++, NULL, 0);
-}
+father_offset, core, NULL, 0);
  } else {
  build_processor_hierarchy_node(
  table_data,
  (1 << 1) | /* ACPI Processor ID valid */
  (1 << 3),  /* Node is a Leaf */
-socket_offset, uid++, NULL, 0);
+father_offset, uid++, NULL, 0);
  }
  }
  }
  
+length = g_queue_get_length(list);

+for (i = 0; i < length; i++) {
+int thread;
+
+father_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
+for (thread = 0; thread < ms->smp.threads; thread++) {
+build_processor_hierarchy_node(
+table_data,
+(1 << 1) | /* ACPI Processor ID valid */
+(1 << 2) | /* Processor is a Thread */
+(1 << 3),  /* Node is a Leaf */
+father_offset, uid++, NULL, 0);
+}
+}
+
+g_queue_free(list);
  acpi_table_end(linker, );
  }

This patch actually increases the number of loops, since we need to visit
higher hierarchical nodes twice (once to enqueue and once to dequeue).

Yes, we actually need to access the higher hierarchical node's offset twice.
But that may not be a problem since numbers of topology parameters are
not so huge that we need to consider the performance.

We
do reduce code indentation and it looks like we could more easily skip
hierarchy levels we don't want, though.

Yes, just as you said. The commit message doesn't describe the motivation
well. This patch aims to reduce the increasing code indentation because of
increasing nested loops, and consequently it's a bit easier to extend with
new topology level.

While my impulse is to say we
should just keep this simple and add another nested loop for 

Re: [PATCH v6 4/7] hw/arm/virt-acpi-build: Make an ARM specific PPTT generator

2022-01-03 Thread wangyanan (Y)

Hi Drew,

On 2022/1/3 19:30, Andrew Jones wrote:

On Mon, Jan 03, 2022 at 04:46:33PM +0800, Yanan Wang wrote:

We have a generic build_pptt() in hw/acpi/aml-build.c but it's
currently only used in ARM acpi initialization. Now we are going
to support the new CPU cluster parameter which is currently only
supported by ARM, it won't be a very good idea to add it to the
generic build_pptt() as it will make the code complex and hard
to maintain especially when we also support CPU cache topology
hierarchy in build_pptt() too. Note that the cache topology
design also varies between different CPU targets.

It's a shame to remove generic ACPI table. I'm not sure what
will be best when addressing the cache topology, but for the
clusters it seems like we should be able to easily skip them
when has_clusters is false.
Hm yes. Currently for clusters alone, a check of 
ms->smp_props.clusters_supported

would be enough. So I guess it's preferred that we should keep the
generic PPTT, right?

So an ARM specific PPTT generator becomes necessary now. Given
that the generic one is currently only used by ARM, let's just
move build_pptt() from aml-build.c to virt-acpi-build.c with
minor update.

Please state what the minor update is? I see the oem parameter
change, but I want to be sure that's the one you're referring
to.

Yes, I changed the function parameter "ms" to "vms". That's the
whole update.

Thanks,
Yanan

Signed-off-by: Yanan Wang 
---
  hw/acpi/aml-build.c | 80 ++---
  hw/arm/virt-acpi-build.c| 77 ++-
  include/hw/acpi/aml-build.h |  5 ++-
  3 files changed, 81 insertions(+), 81 deletions(-)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index be3851be36..040fbc9b4b 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1968,10 +1968,9 @@ void build_slit(GArray *table_data, BIOSLinker *linker, 
MachineState *ms,
   * ACPI spec, Revision 6.3
   * 5.2.29.1 Processor hierarchy node structure (Type 0)
   */
-static void build_processor_hierarchy_node(GArray *tbl, uint32_t flags,
-   uint32_t parent, uint32_t id,
-   uint32_t *priv_rsrc,
-   uint32_t priv_num)
+void build_processor_hierarchy_node(GArray *tbl, uint32_t flags,
+uint32_t parent, uint32_t id,
+uint32_t *priv_rsrc, uint32_t priv_num)
  {
  int i;
  
@@ -1994,79 +1993,6 @@ static void build_processor_hierarchy_node(GArray *tbl, uint32_t flags,

  }
  }
  
-/*

- * ACPI spec, Revision 6.3
- * 5.2.29 Processor Properties Topology Table (PPTT)
- */
-void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
-const char *oem_id, const char *oem_table_id)
-{
-GQueue *list = g_queue_new();
-guint pptt_start = table_data->len;
-guint father_offset;
-guint length, i;
-int uid = 0;
-int socket;
-AcpiTable table = { .sig = "PPTT", .rev = 2,
-.oem_id = oem_id, .oem_table_id = oem_table_id };
-
-acpi_table_begin(, table_data);
-
-for (socket = 0; socket < ms->smp.sockets; socket++) {
-g_queue_push_tail(list,
-GUINT_TO_POINTER(table_data->len - pptt_start));
-build_processor_hierarchy_node(
-table_data,
-/*
- * Physical package - represents the boundary
- * of a physical package
- */
-(1 << 0),
-0, socket, NULL, 0);
-}
-
-length = g_queue_get_length(list);
-for (i = 0; i < length; i++) {
-int core;
-
-father_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
-for (core = 0; core < ms->smp.cores; core++) {
-if (ms->smp.threads > 1) {
-g_queue_push_tail(list,
-GUINT_TO_POINTER(table_data->len - pptt_start));
-build_processor_hierarchy_node(
-table_data,
-(0 << 0), /* not a physical package */
-father_offset, core, NULL, 0);
-} else {
-build_processor_hierarchy_node(
-table_data,
-(1 << 1) | /* ACPI Processor ID valid */
-(1 << 3),  /* Node is a Leaf */
-father_offset, uid++, NULL, 0);
-}
-}
-}
-
-length = g_queue_get_length(list);
-for (i = 0; i < length; i++) {
-int thread;
-
-father_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
-for (thread = 0; thread < ms->smp.threads; thread++) {
-build_processor_hierarchy_node(
-table_data,
-(1 << 1) | /* ACPI Processor ID valid */
-(1 << 2) | /* Processor is a Thread */
-(1 << 3),  /* Node is a Leaf */
-father_offset, uid++, NULL, 0);
- 

Re: [PATCH v3 kvm/queue 14/16] KVM: Handle page fault for private memory

2022-01-03 Thread Yan Zhao
On Thu, Dec 23, 2021 at 08:30:09PM +0800, Chao Peng wrote:
> When a page fault from the secondary page table while the guest is
> running happens in a memslot with KVM_MEM_PRIVATE, we need go
> different paths for private access and shared access.
> 
>   - For private access, KVM checks if the page is already allocated in
> the memory backend, if yes KVM establishes the mapping, otherwise
> exits to userspace to convert a shared page to private one.
>
will this conversion be atomical or not?
For example, after punching a hole in a private memory slot, will KVM
see two notifications: one for invalidation of the whole private memory
slot, and one for fallocate of the rest ranges besides the hole?
Or, KVM only sees one invalidation notification for the hole?
Could you please show QEMU code about this conversion?


>   - For shared access, KVM also checks if the page is already allocated
> in the memory backend, if yes then exit to userspace to convert a
> private page to shared one, otherwise it's treated as a traditional
> hva-based shared memory, KVM lets existing code to obtain a pfn with
> get_user_pages() and establish the mapping.
> 
> The above code assume private memory is persistent and pre-allocated in
> the memory backend so KVM can use this information as an indicator for
> a page is private or shared. The above check is then performed by
> calling kvm_memfd_get_pfn() which currently is implemented as a
> pagecache search but in theory that can be implemented differently
> (i.e. when the page is even not mapped into host pagecache there should
> be some different implementation).
> 
> Signed-off-by: Yu Zhang 
> Signed-off-by: Chao Peng 
> ---
>  arch/x86/kvm/mmu/mmu.c | 73 --
>  arch/x86/kvm/mmu/paging_tmpl.h | 11 +++--
>  2 files changed, 77 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
> index 2856eb662a21..fbcdf62f8281 100644
> --- a/arch/x86/kvm/mmu/mmu.c
> +++ b/arch/x86/kvm/mmu/mmu.c
> @@ -2920,6 +2920,9 @@ int kvm_mmu_max_mapping_level(struct kvm *kvm,
>   if (max_level == PG_LEVEL_4K)
>   return PG_LEVEL_4K;
>  
> + if (kvm_slot_is_private(slot))
> + return max_level;
> +
>   host_level = host_pfn_mapping_level(kvm, gfn, pfn, slot);
>   return min(host_level, max_level);
>  }
> @@ -3950,7 +3953,59 @@ static bool kvm_arch_setup_async_pf(struct kvm_vcpu 
> *vcpu, gpa_t cr2_or_gpa,
> kvm_vcpu_gfn_to_hva(vcpu, gfn), );
>  }
>  
> -static bool kvm_faultin_pfn(struct kvm_vcpu *vcpu, struct kvm_page_fault 
> *fault, int *r)
> +static bool kvm_vcpu_is_private_gfn(struct kvm_vcpu *vcpu, gfn_t gfn)
> +{
> + /*
> +  * At this time private gfn has not been supported yet. Other patch
> +  * that enables it should change this.
> +  */
> + return false;
> +}
> +
> +static bool kvm_faultin_pfn_private(struct kvm_vcpu *vcpu,
> + struct kvm_page_fault *fault,
> + bool *is_private_pfn, int *r)
> +{
> + int order;
> + int mem_convert_type;
> + struct kvm_memory_slot *slot = fault->slot;
> + long pfn = kvm_memfd_get_pfn(slot, fault->gfn, );
For private memory slots, it's possible to have pfns backed by
backends other than memfd, e.g. devicefd. So is it possible to let those
private memslots keep private and use traditional hva-based way?
Reasons below:
1. only memfd is supported in this patch set.
2. qemu/host read/write to those private memslots backing up by devicefd may
not cause machine check.

Thanks
Yan


> +
> + if (kvm_vcpu_is_private_gfn(vcpu, fault->addr >> PAGE_SHIFT)) {
> + if (pfn < 0)
> + mem_convert_type = KVM_EXIT_MEM_MAP_PRIVATE;
> + else {
> + fault->pfn = pfn;
> + if (slot->flags & KVM_MEM_READONLY)
> + fault->map_writable = false;
> + else
> + fault->map_writable = true;
> +
> + if (order == 0)
> + fault->max_level = PG_LEVEL_4K;
> + *is_private_pfn = true;
> + *r = RET_PF_FIXED;
> + return true;
> + }
> + } else {
> + if (pfn < 0)
> + return false;
> +
> + kvm_memfd_put_pfn(pfn);
> + mem_convert_type = KVM_EXIT_MEM_MAP_SHARED;
> + }
> +
> + vcpu->run->exit_reason = KVM_EXIT_MEMORY_ERROR;
> + vcpu->run->mem.type = mem_convert_type;
> + vcpu->run->mem.u.map.gpa = fault->gfn << PAGE_SHIFT;
> + vcpu->run->mem.u.map.size = PAGE_SIZE;
> + fault->pfn = -1;
> + *r = -1;
> + return true;
> +}
> +
> +static bool kvm_faultin_pfn(struct kvm_vcpu *vcpu, struct kvm_page_fault 
> *fault,
> + bool *is_private_pfn, int *r)
>  {
>

RE: [PATCH 0/2] kvm/msi: do explicit commit when adding msi routes

2022-01-03 Thread longpeng2--- via
Hi guys,

Ping...

> -Original Message-
> From: Longpeng (Mike, Cloud Infrastructure Service Product Dept.)
> Sent: Saturday, December 11, 2021 10:27 PM
> To: pbonz...@redhat.com; alex.william...@redhat.com; m...@redhat.com;
> mtosa...@redhat.com
> Cc: k...@vger.kernel.org; qemu-devel@nongnu.org; Gonglei (Arei)
> ; Longpeng (Mike, Cloud Infrastructure Service
> Product Dept.) 
> Subject: [PATCH 0/2] kvm/msi: do explicit commit when adding msi routes
> 
> From: Longpeng 
> 
> This patchset moves the call to kvm_irqchip_commit_routes() out of
> kvm_irqchip_add_msi_route(). An optimization of vfio migration [1]
> depends on this changes.
> 
> [1] https://lists.gnu.org/archive/html/qemu-devel/2021-11/msg00968.html
> 
> Longpeng (Mike) (2):
>   kvm-irqchip: introduce new API to support route change
>   kvm/msi: do explicit commit when adding msi routes
> 
>  accel/kvm/kvm-all.c|  7 ---
>  accel/stubs/kvm-stub.c |  2 +-
>  hw/misc/ivshmem.c  |  5 -
>  hw/vfio/pci.c  |  5 -
>  hw/virtio/virtio-pci.c |  4 +++-
>  include/sysemu/kvm.h   | 23 +--
>  target/i386/kvm/kvm.c  |  4 +++-
>  7 files changed, 40 insertions(+), 10 deletions(-)
> 
> --
> 2.23.0




[PATCH v3 4/4] target/ppc: do not call hreg_compute_hflags() in helper_store_mmcr0()

2022-01-03 Thread Daniel Henrique Barboza
MMCR0 writes will change only MMCR0 bits which are used to calculate
HFLAGS_PMCC0, HFLAGS_PMCC1 and HFLAGS_INSN_CNT hflags. No other machine
register will be changed during this operation. This means that
hreg_compute_hflags() is overkill for what we need to do.

pmu_update_summaries() is already updating HFLAGS_INSN_CNT without
calling hreg_compure_hflags(). Let's do the same for the other 2 MMCR0
hflags.

Reviewed-by: Richard Henderson 
Signed-off-by: Daniel Henrique Barboza 
---
 target/ppc/power8-pmu.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 73713ca2a3..236e8e66e9 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -224,12 +224,17 @@ static void pmu_update_overflow_timers(CPUPPCState *env)
 
 void helper_store_mmcr0(CPUPPCState *env, target_ulong value)
 {
+bool hflags_pmcc0 = (value & MMCR0_PMCC0) != 0;
+bool hflags_pmcc1 = (value & MMCR0_PMCC1) != 0;
+
 pmu_update_cycles(env);
 
 env->spr[SPR_POWER_MMCR0] = value;
 
 /* MMCR0 writes can change HFLAGS_PMCC[01] and HFLAGS_INSN_CNT */
-hreg_compute_hflags(env);
+env->hflags = deposit32(env->hflags, HFLAGS_PMCC0, 1, hflags_pmcc0);
+env->hflags = deposit32(env->hflags, HFLAGS_PMCC1, 1, hflags_pmcc1);
+
 pmu_update_summaries(env);
 
 /* Update cycle overflow timers with the current MMCR0 state */
-- 
2.33.1




Re: [PATCH 1/6] target/riscv: add cfg properties for zfinx, zdinx and zhinx{min}

2022-01-03 Thread Alistair Francis
On Fri, Dec 24, 2021 at 1:51 PM liweiwei  wrote:
>
> Co-authored-by: ardxwe 
> Signed-off-by: liweiwei 
> Signed-off-by: wangjunqiang 
> ---
>  roms/SLOF|  2 +-
>  target/riscv/cpu.c   | 12 
>  target/riscv/cpu.h   |  4 
>  target/riscv/translate.c |  8 
>  4 files changed, 25 insertions(+), 1 deletion(-)
>
> diff --git a/roms/SLOF b/roms/SLOF
> index a6906b024c..dd0dcaa1c1 16
> --- a/roms/SLOF
> +++ b/roms/SLOF
> @@ -1 +1 @@
> -Subproject commit a6906b024c6cca5a86496f51eb4bfee3a0c36148
> +Subproject commit dd0dcaa1c1085c159ddab709c7f274b3917be8bd

It looks like you accidentally changed a submodule.

Alistair



[PATCH v3 1/4] target/ppc: Cache per-pmc insn and cycle count settings

2022-01-03 Thread Daniel Henrique Barboza
From: Richard Henderson 

This is the combination of frozen bit and counter type, on a per
counter basis. So far this is only used by HFLAGS_INSN_CNT, but
will be used more later.

Signed-off-by: Richard Henderson 
[danielhb: fixed PMC4 cyc_cnt shift, insn run latch code,
   MMCR0_FC handling, "PMC[1-6]" comment]
Signed-off-by: Daniel Henrique Barboza 
---
 target/ppc/cpu.h |  3 +++
 target/ppc/cpu_init.c|  1 +
 target/ppc/helper_regs.c |  2 +-
 target/ppc/machine.c |  2 ++
 target/ppc/power8-pmu.c  | 56 
 target/ppc/power8-pmu.h  | 14 +-
 6 files changed, 58 insertions(+), 20 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index fc66c3561d..fd187fe3dd 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1144,6 +1144,9 @@ struct CPUPPCState {
 /* Other registers */
 target_ulong spr[1024]; /* special purpose registers */
 ppc_spr_t spr_cb[1024];
+/* Composite status for PMC[1-6] enabled and counting insns or cycles. */
+uint8_t pmc_ins_cnt;
+uint8_t pmc_cyc_cnt;
 /* Vector status and control register, minus VSCR_SAT */
 uint32_t vscr;
 /* VSX registers (including FP and AVR) */
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 06ef15cd9e..63f9babfee 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -8313,6 +8313,7 @@ static void ppc_cpu_reset(DeviceState *dev)
 #endif /* CONFIG_TCG */
 #endif
 
+pmu_update_summaries(env);
 hreg_compute_hflags(env);
 env->reserve_addr = (target_ulong)-1ULL;
 /* Be sure no exception or interrupt is pending */
diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index b847928842..8671b7bb69 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -123,7 +123,7 @@ static uint32_t hreg_compute_hflags_value(CPUPPCState *env)
 }
 
 #if defined(TARGET_PPC64)
-if (pmu_insn_cnt_enabled(env)) {
+if (env->pmc_ins_cnt) {
 hflags |= 1 << HFLAGS_INSN_CNT;
 }
 #endif
diff --git a/target/ppc/machine.c b/target/ppc/machine.c
index 93972df58e..756d8de5d8 100644
--- a/target/ppc/machine.c
+++ b/target/ppc/machine.c
@@ -8,6 +8,7 @@
 #include "qapi/error.h"
 #include "qemu/main-loop.h"
 #include "kvm_ppc.h"
+#include "power8-pmu.h"
 
 static void post_load_update_msr(CPUPPCState *env)
 {
@@ -19,6 +20,7 @@ static void post_load_update_msr(CPUPPCState *env)
  */
 env->msr ^= env->msr_mask & ~((1ULL << MSR_TGPR) | MSR_HVB);
 ppc_store_msr(env, msr);
+pmu_update_summaries(env);
 }
 
 static int cpu_load_old(QEMUFile *f, void *opaque, int version_id)
diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 08d1902cd5..1f4f611994 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -11,8 +11,6 @@
  */
 
 #include "qemu/osdep.h"
-
-#include "power8-pmu.h"
 #include "cpu.h"
 #include "helper_regs.h"
 #include "exec/exec-all.h"
@@ -20,6 +18,7 @@
 #include "qemu/error-report.h"
 #include "qemu/main-loop.h"
 #include "hw/ppc/ppc.h"
+#include "power8-pmu.h"
 
 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
 
@@ -121,18 +120,52 @@ static PMUEventType pmc_get_event(CPUPPCState *env, int 
sprn)
 return evt_type;
 }
 
-bool pmu_insn_cnt_enabled(CPUPPCState *env)
+void pmu_update_summaries(CPUPPCState *env)
 {
-int sprn;
+target_ulong mmcr0 = env->spr[SPR_POWER_MMCR0];
+target_ulong mmcr1 = env->spr[SPR_POWER_MMCR1];
+int ins_cnt = 0;
+int cyc_cnt = 0;
 
-for (sprn = SPR_POWER_PMC1; sprn <= SPR_POWER_PMC5; sprn++) {
-if (pmc_get_event(env, sprn) == PMU_EVENT_INSTRUCTIONS ||
-pmc_get_event(env, sprn) == PMU_EVENT_INSN_RUN_LATCH) {
-return true;
+if (mmcr0 & MMCR0_FC) {
+goto hflags_calc;
+}
+
+if (!(mmcr0 & MMCR0_FC14) && mmcr1 != 0) {
+target_ulong sel;
+
+sel = extract64(mmcr1, MMCR1_PMC1EVT_EXTR, MMCR1_EVT_SIZE);
+switch (sel) {
+case 0x02:
+case 0xfe:
+ins_cnt |= 1 << 1;
+break;
+case 0x1e:
+case 0xf0:
+cyc_cnt |= 1 << 1;
+break;
 }
+
+sel = extract64(mmcr1, MMCR1_PMC2EVT_EXTR, MMCR1_EVT_SIZE);
+ins_cnt |= (sel == 0x02) << 2;
+cyc_cnt |= (sel == 0x1e) << 2;
+
+sel = extract64(mmcr1, MMCR1_PMC3EVT_EXTR, MMCR1_EVT_SIZE);
+ins_cnt |= (sel == 0x02) << 3;
+cyc_cnt |= (sel == 0x1e) << 3;
+
+sel = extract64(mmcr1, MMCR1_PMC4EVT_EXTR, MMCR1_EVT_SIZE);
+ins_cnt |= ((sel == 0xfa) || (sel == 0x2)) << 4;
+cyc_cnt |= (sel == 0x1e) << 4;
 }
 
-return false;
+ins_cnt |= !(mmcr0 & MMCR0_FC56) << 5;
+cyc_cnt |= !(mmcr0 & MMCR0_FC56) << 6;
+
+ hflags_calc:
+env->pmc_ins_cnt = ins_cnt;
+env->pmc_cyc_cnt = cyc_cnt;
+env->hflags = deposit32(env->hflags, HFLAGS_INSN_CNT, 1, ins_cnt != 0);
 }
 
 static bool pmu_increment_insns(CPUPPCState *env, uint32_t num_insns)
@@ 

[PATCH v3 2/4] target/ppc: Rewrite pmu_increment_insns

2022-01-03 Thread Daniel Henrique Barboza
From: Richard Henderson 

Use the cached pmc_ins_cnt value.  Unroll the loop over the
different PMC counters.  Treat the PMC4 run-latch specially.

Signed-off-by: Richard Henderson 
---
 target/ppc/power8-pmu.c | 78 ++---
 1 file changed, 49 insertions(+), 29 deletions(-)

diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 1f4f611994..27c4c7915b 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -170,45 +170,65 @@ void pmu_update_summaries(CPUPPCState *env)
 
 static bool pmu_increment_insns(CPUPPCState *env, uint32_t num_insns)
 {
+target_ulong mmcr0 = env->spr[SPR_POWER_MMCR0];
+unsigned ins_cnt = env->pmc_ins_cnt;
 bool overflow_triggered = false;
-int sprn;
-
-/* PMC6 never counts instructions */
-for (sprn = SPR_POWER_PMC1; sprn <= SPR_POWER_PMC5; sprn++) {
-PMUEventType evt_type = pmc_get_event(env, sprn);
-bool insn_event = evt_type == PMU_EVENT_INSTRUCTIONS ||
-  evt_type == PMU_EVENT_INSN_RUN_LATCH;
-
-if (pmc_is_inactive(env, sprn) || !insn_event) {
-continue;
+target_ulong tmp;
+
+if (unlikely(ins_cnt & 0x1e)) {
+if (ins_cnt & (1 << 1)) {
+tmp = env->spr[SPR_POWER_PMC1];
+tmp += num_insns;
+if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMC1CE)) {
+tmp = PMC_COUNTER_NEGATIVE_VAL;
+overflow_triggered = true;
+}
+env->spr[SPR_POWER_PMC1] = tmp;
 }
 
-if (evt_type == PMU_EVENT_INSTRUCTIONS) {
-env->spr[sprn] += num_insns;
+if (ins_cnt & (1 << 2)) {
+tmp = env->spr[SPR_POWER_PMC2];
+tmp += num_insns;
+if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) {
+tmp = PMC_COUNTER_NEGATIVE_VAL;
+overflow_triggered = true;
+}
+env->spr[SPR_POWER_PMC2] = tmp;
 }
 
-if (evt_type == PMU_EVENT_INSN_RUN_LATCH &&
-env->spr[SPR_CTRL] & CTRL_RUN) {
-env->spr[sprn] += num_insns;
+if (ins_cnt & (1 << 3)) {
+tmp = env->spr[SPR_POWER_PMC3];
+tmp += num_insns;
+if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) {
+tmp = PMC_COUNTER_NEGATIVE_VAL;
+overflow_triggered = true;
+}
+env->spr[SPR_POWER_PMC3] = tmp;
 }
 
-if (env->spr[sprn] >= PMC_COUNTER_NEGATIVE_VAL &&
-pmc_has_overflow_enabled(env, sprn)) {
+if (ins_cnt & (1 << 4)) {
+target_ulong mmcr1 = env->spr[SPR_POWER_MMCR1];
+int sel = extract64(mmcr1, MMCR1_PMC4EVT_EXTR, MMCR1_EVT_SIZE);
+if (sel == 0x02 || (env->spr[SPR_CTRL] & CTRL_RUN)) {
+tmp = env->spr[SPR_POWER_PMC4];
+tmp += num_insns;
+if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) 
{
+tmp = PMC_COUNTER_NEGATIVE_VAL;
+overflow_triggered = true;
+}
+env->spr[SPR_POWER_PMC4] = tmp;
+}
+}
+}
 
+if (ins_cnt & (1 << 5)) {
+tmp = env->spr[SPR_POWER_PMC5];
+tmp += num_insns;
+if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) {
+tmp = PMC_COUNTER_NEGATIVE_VAL;
 overflow_triggered = true;
-
-/*
- * The real PMU will always trigger a counter overflow with
- * PMC_COUNTER_NEGATIVE_VAL. We don't have an easy way to
- * do that since we're counting block of instructions at
- * the end of each translation block, and we're probably
- * passing this value at this point.
- *
- * Let's write PMC_COUNTER_NEGATIVE_VAL to the overflowed
- * counter to simulate what the real hardware would do.
- */
-env->spr[sprn] = PMC_COUNTER_NEGATIVE_VAL;
 }
+env->spr[SPR_POWER_PMC5] = tmp;
 }
 
 return overflow_triggered;
-- 
2.33.1




[PATCH v3 3/4] target/ppc: Use env->pnc_cyc_cnt

2022-01-03 Thread Daniel Henrique Barboza
From: Richard Henderson 

Use the cached pmc_cyc_cnt value in pmu_update_cycles
and pmc_update_overflow_timer.  This leaves pmc_get_event
and pmc_is_inactive unused, so remove them.

Signed-off-by: Richard Henderson 
---
 target/ppc/power8-pmu.c | 107 
 1 file changed, 9 insertions(+), 98 deletions(-)

diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 27c4c7915b..73713ca2a3 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -24,19 +24,6 @@
 
 #define PMC_COUNTER_NEGATIVE_VAL 0x8000UL
 
-static bool pmc_is_inactive(CPUPPCState *env, int sprn)
-{
-if (env->spr[SPR_POWER_MMCR0] & MMCR0_FC) {
-return true;
-}
-
-if (sprn < SPR_POWER_PMC5) {
-return env->spr[SPR_POWER_MMCR0] & MMCR0_FC14;
-}
-
-return env->spr[SPR_POWER_MMCR0] & MMCR0_FC56;
-}
-
 static bool pmc_has_overflow_enabled(CPUPPCState *env, int sprn)
 {
 if (sprn == SPR_POWER_PMC1) {
@@ -46,80 +33,6 @@ static bool pmc_has_overflow_enabled(CPUPPCState *env, int 
sprn)
 return env->spr[SPR_POWER_MMCR0] & MMCR0_PMCjCE;
 }
 
-/*
- * For PMCs 1-4, IBM POWER chips has support for an implementation
- * dependent event, 0x1E, that enables cycle counting. The Linux kernel
- * makes extensive use of 0x1E, so let's also support it.
- *
- * Likewise, event 0x2 is an implementation-dependent event that IBM
- * POWER chips implement (at least since POWER8) that is equivalent to
- * PM_INST_CMPL. Let's support this event on PMCs 1-4 as well.
- */
-static PMUEventType pmc_get_event(CPUPPCState *env, int sprn)
-{
-uint8_t mmcr1_evt_extr[] = { MMCR1_PMC1EVT_EXTR, MMCR1_PMC2EVT_EXTR,
- MMCR1_PMC3EVT_EXTR, MMCR1_PMC4EVT_EXTR };
-PMUEventType evt_type = PMU_EVENT_INVALID;
-uint8_t pmcsel;
-int i;
-
-if (pmc_is_inactive(env, sprn)) {
-return PMU_EVENT_INACTIVE;
-}
-
-if (sprn == SPR_POWER_PMC5) {
-return PMU_EVENT_INSTRUCTIONS;
-}
-
-if (sprn == SPR_POWER_PMC6) {
-return PMU_EVENT_CYCLES;
-}
-
-i = sprn - SPR_POWER_PMC1;
-pmcsel = extract64(env->spr[SPR_POWER_MMCR1], mmcr1_evt_extr[i],
-   MMCR1_EVT_SIZE);
-
-switch (pmcsel) {
-case 0x2:
-evt_type = PMU_EVENT_INSTRUCTIONS;
-break;
-case 0x1E:
-evt_type = PMU_EVENT_CYCLES;
-break;
-case 0xF0:
-/*
- * PMC1SEL = 0xF0 is the architected PowerISA v3.1
- * event that counts cycles using PMC1.
- */
-if (sprn == SPR_POWER_PMC1) {
-evt_type = PMU_EVENT_CYCLES;
-}
-break;
-case 0xFA:
-/*
- * PMC4SEL = 0xFA is the "instructions completed
- * with run latch set" event.
- */
-if (sprn == SPR_POWER_PMC4) {
-evt_type = PMU_EVENT_INSN_RUN_LATCH;
-}
-break;
-case 0xFE:
-/*
- * PMC1SEL = 0xFE is the architected PowerISA v3.1
- * event to sample instructions using PMC1.
- */
-if (sprn == SPR_POWER_PMC1) {
-evt_type = PMU_EVENT_INSTRUCTIONS;
-}
-break;
-default:
-break;
-}
-
-return evt_type;
-}
-
 void pmu_update_summaries(CPUPPCState *env)
 {
 target_ulong mmcr0 = env->spr[SPR_POWER_MMCR0];
@@ -238,18 +151,16 @@ static void pmu_update_cycles(CPUPPCState *env)
 {
 uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 uint64_t time_delta = now - env->pmu_base_time;
-int sprn;
+int sprn, cyc_cnt = env->pmc_cyc_cnt;
 
 for (sprn = SPR_POWER_PMC1; sprn <= SPR_POWER_PMC6; sprn++) {
-if (pmc_get_event(env, sprn) != PMU_EVENT_CYCLES) {
-continue;
+if (cyc_cnt & (1 << (sprn - SPR_POWER_PMC1 + 1))) {
+/*
+ * The pseries and powernv clock runs at 1Ghz, meaning
+ * that 1 nanosec equals 1 cycle.
+ */
+env->spr[sprn] += time_delta;
 }
-
-/*
- * The pseries and powernv clock runs at 1Ghz, meaning
- * that 1 nanosec equals 1 cycle.
- */
-env->spr[sprn] += time_delta;
 }
 
 /* Update base_time for future calculations */
@@ -278,7 +189,7 @@ static void pmc_update_overflow_timer(CPUPPCState *env, int 
sprn)
 return;
 }
 
-if (pmc_get_event(env, sprn) != PMU_EVENT_CYCLES ||
+if (!(env->pmc_cyc_cnt & (1 << (sprn - SPR_POWER_PMC1 + 1))) ||
 !pmc_has_overflow_enabled(env, sprn)) {
 /* Overflow timer is not needed for this counter */
 timer_del(pmc_overflow_timer);
@@ -286,7 +197,7 @@ static void pmc_update_overflow_timer(CPUPPCState *env, int 
sprn)
 }
 
 if (env->spr[sprn] >= PMC_COUNTER_NEGATIVE_VAL) {
-timeout =  0;
+timeout = 0;
 } else {
 timeout = PMC_COUNTER_NEGATIVE_VAL - env->spr[sprn];
 }
-- 
2.33.1




[PATCH v3 0/4] Reorg ppc64 pmu insn counting

2022-01-03 Thread Daniel Henrique Barboza
Hi,

This new version implements Richard's suggestions made in the
v2 review.

Changes from v2:
- Patch 1:
  * fixed "PMC[1-5]" comment in target/ppc/cpu.h
- Former patch 4: squashed into patch 1
- Patch 4 (former 5):
  * use boolean variables instead of uint32_t
  * added Richard's r-b
- v2 link: https://lists.gnu.org/archive/html/qemu-devel/2022-01/msg00117.html


Daniel Henrique Barboza (1):
  target/ppc: do not call hreg_compute_hflags() in helper_store_mmcr0()

Richard Henderson (3):
  target/ppc: Cache per-pmc insn and cycle count settings
  target/ppc: Rewrite pmu_increment_insns
  target/ppc: Use env->pnc_cyc_cnt

 target/ppc/cpu.h |   3 +
 target/ppc/cpu_init.c|   1 +
 target/ppc/helper_regs.c |   2 +-
 target/ppc/machine.c |   2 +
 target/ppc/power8-pmu.c  | 238 +--
 target/ppc/power8-pmu.h  |  14 +--
 6 files changed, 117 insertions(+), 143 deletions(-)

-- 
2.33.1




Re: [PATCH 2/2] hw/dma: sifive_pdma: permit 4/8-byte access size of PDMA registers

2022-01-03 Thread Alistair Francis
On Tue, Dec 28, 2021 at 10:54 AM Jim Shu  wrote:
>
> It's obvious that PDMA support 64-bit access of 64-bit registers, and
> in previous commit, we confirm that PDMA support 32-bit access of both
> 32/64-bit registers. Thus, we configure 32/64-bit memory access of
> PDMA registers as valid in general.
>
> Signed-off-by: Jim Shu 
> Reviewed-by: Frank Chang 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/dma/sifive_pdma.c | 4 
>  1 file changed, 4 insertions(+)
>
> diff --git a/hw/dma/sifive_pdma.c b/hw/dma/sifive_pdma.c
> index b8b198ab4e..731fcdcf89 100644
> --- a/hw/dma/sifive_pdma.c
> +++ b/hw/dma/sifive_pdma.c
> @@ -441,6 +441,10 @@ static const MemoryRegionOps sifive_pdma_ops = {
>  .impl = {
>  .min_access_size = 4,
>  .max_access_size = 8,
> +},
> +.valid = {
> +.min_access_size = 4,
> +.max_access_size = 8,
>  }
>  };
>
> --
> 2.25.1
>
>



Re: [PATCH 1/2] hw/dma: sifive_pdma: support high 32-bit access of 64-bit register

2022-01-03 Thread Alistair Francis
On Tue, Dec 28, 2021 at 10:54 AM Jim Shu  wrote:
>
> Real PDMA support high 32-bit read/write memory access of 64-bit
> register.
>
> The following result is PDMA tested in U-Boot on Unmatched board:
>
> 1. Real PDMA is allowed high 32-bit read/write to 64-bit register.
> => mw.l 0x300 0x0  <= Disclaim channel 0
> => mw.l 0x300 0x1  <= Claim channel 0
> => mw.l 0x310 0x8000   <= Write low 32-bit NextDest 
> (NextDest = 0x28000)
> => mw.l 0x314 0x2  <= Write high 32-bit NextDest
> => md.l 0x310 1<= Dump low 32-bit NextDest
> 0310: 8000
> => md.l 0x314 1<= Dump high 32-bit NextDest
> 0314: 0002
> => mw.l 0x318 0x80001000   <= Write low 32-bit NextSrc 
> (NextSrc = 0x280001000)
> => mw.l 0x31c 0x2  <= Write high 32-bit NextSrc
> => md.l 0x318 1<= Dump low 32-bit NextSrc
> 0310: 80001000
> => md.l 0x31c 1<= Dump high 32-bit NextSrc
> 0314: 0002
>
> 2. PDMA transfer from 0x280001000 to 0x28000 is OK.
> => mw.q 0x308 0x4  <= NextBytes = 4
> => mw.l 0x304 0x2200   <= wsize = rsize = 2 (2^2 = 4 
> bytes)
> => mw.l 0x28000 0x87654321 <= Fill test data to dst
> => mw.l 0x280001000 0x12345678 <= Fill test data to src
> => md.l 0x28000 1; md.l 0x280001000 1  <= Dump src/dst memory contents
> 28000: 87654321  !Ce.
> 280001000: 12345678  xV4.
> => md.l 0x300 8<= Dump PDMA status
> 0300: 0001 2200 0004 ..."
> 0310: 8000 0002 80001000 0002
> => mw.l 0x300 0x3  <= Set channel 0 run and claim bits
> => md.l 0x300 8<= Dump PDMA status
> 0300: 4001 2200 0004 ...@..."
> 0310: 8000 0002 80001000 0002
> => md.l 0x28000 1; md.l 0x280001000 1  <= Dump src/dst memory contents
> 28000: 12345678   xV4.
> 280001000: 12345678   xV4.
>
> Signed-off-by: Jim Shu 
> Reviewed-by: Frank Chang 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/dma/sifive_pdma.c | 174 +--
>  1 file changed, 152 insertions(+), 22 deletions(-)
>
> diff --git a/hw/dma/sifive_pdma.c b/hw/dma/sifive_pdma.c
> index 85fe34f5f3..b8b198ab4e 100644
> --- a/hw/dma/sifive_pdma.c
> +++ b/hw/dma/sifive_pdma.c
> @@ -177,18 +177,44 @@ static inline void 
> sifive_pdma_update_irq(SiFivePDMAState *s, int ch)
>  s->chan[ch].state = DMA_CHAN_STATE_IDLE;
>  }
>
> -static uint64_t sifive_pdma_read(void *opaque, hwaddr offset, unsigned size)
> +static uint64_t sifive_pdma_readq(SiFivePDMAState *s, int ch, hwaddr offset)
>  {
> -SiFivePDMAState *s = opaque;
> -int ch = SIFIVE_PDMA_CHAN_NO(offset);
>  uint64_t val = 0;
>
> -if (ch >= SIFIVE_PDMA_CHANS) {
> -qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid channel no %d\n",
> -  __func__, ch);
> -return 0;
> +offset &= 0xfff;
> +switch (offset) {
> +case DMA_NEXT_BYTES:
> +val = s->chan[ch].next_bytes;
> +break;
> +case DMA_NEXT_DST:
> +val = s->chan[ch].next_dst;
> +break;
> +case DMA_NEXT_SRC:
> +val = s->chan[ch].next_src;
> +break;
> +case DMA_EXEC_BYTES:
> +val = s->chan[ch].exec_bytes;
> +break;
> +case DMA_EXEC_DST:
> +val = s->chan[ch].exec_dst;
> +break;
> +case DMA_EXEC_SRC:
> +val = s->chan[ch].exec_src;
> +break;
> +default:
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "%s: Unexpected 64-bit access to 0x%" HWADDR_PRIX "\n",
> +  __func__, offset);
> +break;
>  }
>
> +return val;
> +}
> +
> +static uint32_t sifive_pdma_readl(SiFivePDMAState *s, int ch, hwaddr offset)
> +{
> +uint32_t val = 0;
> +
>  offset &= 0xfff;
>  switch (offset) {
>  case DMA_CONTROL:
> @@ -198,28 +224,47 @@ static uint64_t sifive_pdma_read(void *opaque, hwaddr 
> offset, unsigned size)
>  val = s->chan[ch].next_config;
>  break;
>  case DMA_NEXT_BYTES:
> -val = s->chan[ch].next_bytes;
> +val = extract64(s->chan[ch].next_bytes, 0, 32);
> +break;
> +case DMA_NEXT_BYTES + 4:
> +val = extract64(s->chan[ch].next_bytes, 32, 32);
>  break;
>  case DMA_NEXT_DST:
> -val = s->chan[ch].next_dst;
> +val = extract64(s->chan[ch].next_dst, 0, 32);
> +break;
> +case DMA_NEXT_DST + 4:
> +val = extract64(s->chan[ch].next_dst, 32, 32);
>  break;
>  case 

Re: [PATCH v3 1/2] linux-user: add sched_getattr support

2022-01-03 Thread Laurent Vivier

Le 03/01/2022 à 20:31, Tõnis Tiigi a écrit :

On Mon, Jan 3, 2022 at 10:37 AM Laurent Vivier  wrote:


Le 03/01/2022 à 18:07, Tõnis Tiigi a écrit :

Ping Laurent. Any suggestions for the follow-up questions?

On Thu, Dec 23, 2021 at 3:00 PM Tõnis Tiigi  wrote:


On Thu, Dec 23, 2021 at 1:03 PM Laurent Vivier  wrote:


Le 23/12/2021 à 07:47, Tonis Tiigi a écrit :

Please copy here what you explain in PATCH 0 regarding this patch.
(do the same for PATCH 1)


Signed-off-by: Tonis Tiigi 
---
linux-user/syscall.c  | 94 +++
linux-user/syscall_defs.h | 14 ++
2 files changed, 108 insertions(+)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f1cfcc8104..2f5a0fac5a 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -339,6 +339,12 @@ _syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned 
int, len,
#define __NR_sys_sched_setaffinity __NR_sched_setaffinity
_syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
  unsigned long *, user_mask_ptr);
+#define __NR_sys_sched_getattr __NR_sched_getattr
+_syscall4(int, sys_sched_getattr, pid_t, pid, struct target_sched_attr *, attr,
+  unsigned int, size, unsigned int, flags);
+#define __NR_sys_sched_setattr __NR_sched_setattr
+_syscall3(int, sys_sched_setattr, pid_t, pid, struct target_sched_attr *, attr,
+  unsigned int, flags);
#define __NR_sys_getcpu __NR_getcpu
_syscall3(int, sys_getcpu, unsigned *, cpu, unsigned *, node, void *, 
tcache);
_syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
@@ -10593,6 +10599,94 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
}
case TARGET_NR_sched_getscheduler:
return get_errno(sched_getscheduler(arg1));
+case TARGET_NR_sched_getattr:
+{
+struct target_sched_attr *target_scha;
+struct target_sched_attr scha;


In fact, this scha is used with the host syscall, so it must be  sched_attr.



Where do you want me to define the "host variant" of sched_attr and
with what types for the properties? Or do you want additional
typedef(where?) so the name is less confusing? All properties in this
type are fixed length and identical for all architectures.


It's better to use the host variant with the host syscall.

Normally sched_attr comes with kernel headers, so it should be available and 
you should not have to
define it.

We need to define a target property because alignment also matters as the 
alignment for type can
differ from an architecture to another. I agree that in most cases it should 
not be needed but I
think it's cleaner like that.

so for this part, only replace "struct target_sched_attr scha;" by "struct sched_att 
scha;"


sched_attr is defined in linux/sched/types.h . I can't include it
directly as it conflicts with libc headers with "redefinition of
'struct sched_param'". It looks like
https://lkml.org/lkml/2020/5/28/810 attempted to resolve this conflict
but was not merged and seems to be stuck in kernel vs glibc blame
cycle.



So the best to do is to define a struct host_sched_attr (a strict copy of the kernel one) and use it 
with sched_getattr().


See for instance prlimit64 implementation:

163a05a8398b ("linux-user: Implement prlimit64 syscall")

it's a bit old, but it shows the main idea of a host structure for the host side, a target structure 
for the target side (we have introduced the abi type since).










+if (arg2 == 0) {
+return -TARGET_EINVAL;
+}
+if (arg3 > sizeof(scha)) {
+arg3 = sizeof(scha);
+}
+ret = get_errno(sys_sched_getattr(arg1, , arg3, arg4));
+if (!is_error(ret)) {
+target_scha = lock_user(VERIFY_WRITE, arg2, arg3, 0);
+if (!target_scha) {
+return -TARGET_EFAULT;
+}
+target_scha->size = tswap32(scha.size);
+target_scha->sched_policy = tswap32(scha.sched_policy);
+target_scha->sched_flags = tswap64(scha.sched_flags);
+target_scha->sched_nice = tswap32(scha.sched_nice);
+target_scha->sched_priority = tswap32(scha.sched_priority);
+target_scha->sched_runtime = tswap64(scha.sched_runtime);
+target_scha->sched_deadline = tswap64(scha.sched_deadline);
+target_scha->sched_period = tswap64(scha.sched_period);
+if (scha.size > offsetof(struct target_sched_attr, 
sched_util_min)) {
+target_scha->sched_util_min = tswap32(scha.sched_util_min);
+target_scha->sched_util_max = tswap32(scha.sched_util_max);
+}
+unlock_user(target_scha, arg2, arg3);
+}
+return ret;
+}
+case TARGET_NR_sched_setattr:
+{
+struct 

[PATCH 7/9] target/ppc: powerpc_excp: Move ILE setting into a function

2022-01-03 Thread Fabiano Rosas
Move the ILE code into a separate function similarly to what we do for
AIL.

This leaves the excp_model check behind because it will go away when
we split powerpc_excp.

Signed-off-by: Fabiano Rosas 
---
 target/ppc/excp_helper.c | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index e56ddbe5d5..d7e087f2f6 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -290,6 +290,17 @@ static inline void ppc_excp_apply_ail(PowerPCCPU *cpu, int 
excp_model, int excp,
 #endif
 }
 
+static void ppc_excp_toggle_ile(PowerPCCPU *cpu, target_ulong *new_msr)
+{
+#ifdef TARGET_PPC64
+if (ppc_interrupts_little_endian(cpu, !!(*new_msr & MSR_HVB))) {
+*new_msr |= (target_ulong)1 << MSR_LE;
+} else {
+*new_msr &= ~((target_ulong)1 << MSR_LE);
+}
+#endif
+}
+
 static inline void powerpc_set_excp_state(PowerPCCPU *cpu,
   target_ulong vector, target_ulong 
msr)
 {
@@ -756,18 +767,12 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp)
 }
 
 /*
- * Sort out endianness of interrupt, this differs depending on the
- * CPU, the HV mode, etc...
+ * We preserve MSR_LE, but some CPUs can take interrupts in a
+ * different endianness.
  */
-#ifdef TARGET_PPC64
 if (excp_model >= POWERPC_EXCP_970) {
-if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
-new_msr |= (target_ulong)1 << MSR_LE;
-} else {
-new_msr &= ~((target_ulong)1 << MSR_LE);
-}
+ppc_excp_toggle_ile(cpu, _msr);
 }
-#endif
 
 #if defined(TARGET_PPC64)
 if (excp_model == POWERPC_EXCP_BOOKE) {
-- 
2.33.1




[PATCH 9/9] target/ppc: Introduce a wrapper for powerpc_excp

2022-01-03 Thread Fabiano Rosas
Next patches will split powerpc_excp in multiple family specific
handlers. This patch adds a wrapper to make the transition clearer.

Signed-off-by: Fabiano Rosas 
---
 target/ppc/excp_helper.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index a4787c3ae2..15c492a934 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -336,7 +336,7 @@ static inline void powerpc_set_excp_state(PowerPCCPU *cpu,
  * Note that this function should be greatly optimized when called
  * with a constant excp, from ppc_hw_interrupt
  */
-static inline void powerpc_excp(PowerPCCPU *cpu, int excp)
+static inline void powerpc_excp_legacy(PowerPCCPU *cpu, int excp)
 {
 CPUState *cs = CPU(cpu);
 CPUPPCState *env = >env;
@@ -805,6 +805,16 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp)
 powerpc_set_excp_state(cpu, vector, new_msr);
 }
 
+static void powerpc_excp(PowerPCCPU *cpu, int excp)
+{
+CPUPPCState *env = >env;
+
+switch (env->excp_model) {
+default:
+powerpc_excp_legacy(cpu, excp);
+}
+}
+
 void ppc_cpu_do_interrupt(CPUState *cs)
 {
 PowerPCCPU *cpu = POWERPC_CPU(cs);
-- 
2.33.1




[PATCH 3/9] target/ppc: powerpc_excp: Group unimplemented exceptions

2022-01-03 Thread Fabiano Rosas
(I'll alter this to use powerpc_excp_name once it is merged)

Signed-off-by: Fabiano Rosas 
---
 target/ppc/excp_helper.c | 76 
 1 file changed, 7 insertions(+), 69 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 4769abfb0c..160e06e3a3 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -628,23 +628,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp)
 case POWERPC_EXCP_SPEU:   /* SPE/embedded floating-point unavailable/VPU  
*/
 env->spr[SPR_BOOKE_ESR] = ESR_SPV;
 break;
-case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt   */
-/* XXX: TODO */
-cpu_abort(cs, "Embedded floating point data exception "
-  "is not implemented yet !\n");
-env->spr[SPR_BOOKE_ESR] = ESR_SPV;
-break;
-case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt  */
-/* XXX: TODO */
-cpu_abort(cs, "Embedded floating point round exception "
-  "is not implemented yet !\n");
-env->spr[SPR_BOOKE_ESR] = ESR_SPV;
-break;
-case POWERPC_EXCP_EPERFM:/* Embedded performance monitor interrupt   */
-/* XXX: TODO */
-cpu_abort(cs,
-  "Performance counter exception is not implemented yet !\n");
-break;
 case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt  */
 break;
 case POWERPC_EXCP_DOORCI:/* Embedded doorbell critical interrupt */
@@ -709,19 +692,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp)
 case POWERPC_EXCP_PIT:   /* Programmable interval timer interrupt*/
 trace_ppc_excp_print("PIT");
 break;
-case POWERPC_EXCP_IO:/* IO error exception   */
-/* XXX: TODO */
-cpu_abort(cs, "601 IO error exception is not implemented yet !\n");
-break;
-case POWERPC_EXCP_RUNM:  /* Run mode exception   */
-/* XXX: TODO */
-cpu_abort(cs, "601 run mode exception is not implemented yet !\n");
-break;
-case POWERPC_EXCP_EMUL:  /* Emulation trap exception */
-/* XXX: TODO */
-cpu_abort(cs, "602 emulation trap exception "
-  "is not implemented yet !\n");
-break;
 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error  */
 case POWERPC_EXCP_DLTLB: /* Data load TLB miss   */
 case POWERPC_EXCP_DSTLB: /* Data store TLB miss  */
@@ -748,56 +718,24 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp)
 break;
 }
 break;
+case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt   */
+case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt  */
+case POWERPC_EXCP_EPERFM:/* Embedded performance monitor interrupt   */
+case POWERPC_EXCP_IO:/* IO error exception   */
+case POWERPC_EXCP_RUNM:  /* Run mode exception   */
+case POWERPC_EXCP_EMUL:  /* Emulation trap exception */
 case POWERPC_EXCP_FPA:   /* Floating-point assist exception  */
-/* XXX: TODO */
-cpu_abort(cs, "Floating point assist exception "
-  "is not implemented yet !\n");
-break;
 case POWERPC_EXCP_DABR:  /* Data address breakpoint  */
-/* XXX: TODO */
-cpu_abort(cs, "DABR exception is not implemented yet !\n");
-break;
 case POWERPC_EXCP_IABR:  /* Instruction address breakpoint   */
-/* XXX: TODO */
-cpu_abort(cs, "IABR exception is not implemented yet !\n");
-break;
 case POWERPC_EXCP_SMI:   /* System management interrupt  */
-/* XXX: TODO */
-cpu_abort(cs, "SMI exception is not implemented yet !\n");
-break;
 case POWERPC_EXCP_THERM: /* Thermal interrupt*/
-/* XXX: TODO */
-cpu_abort(cs, "Thermal management exception "
-  "is not implemented yet !\n");
-break;
 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt   */
-/* XXX: TODO */
-cpu_abort(cs,
-  "Performance counter exception is not implemented yet !\n");
-break;
 case POWERPC_EXCP_VPUA:  /* Vector assist exception  */
-/* XXX: TODO */
-cpu_abort(cs, "VPU assist exception is not implemented yet !\n");
-break;
 case POWERPC_EXCP_SOFTP: /* Soft patch exception */
-/* XXX: TODO */
-cpu_abort(cs,
-  "970 soft-patch exception is not implemented yet !\n");
-break;
 case POWERPC_EXCP_MAINT: /* Maintenance exception  

[PATCH 1/9] target/ppc: powerpc_excp: Extract software TLB logging into a function

2022-01-03 Thread Fabiano Rosas
Signed-off-by: Fabiano Rosas 
---
 target/ppc/excp_helper.c | 63 +++-
 1 file changed, 36 insertions(+), 27 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index c7e55800af..002a42261b 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -63,6 +63,41 @@ static inline void dump_hcall(CPUPPCState *env)
   env->nip);
 }
 
+static void ppc_excp_debug_sw_tlb(CPUPPCState *env, int excp)
+{
+#if defined(DEBUG_SOFTWARE_TLB)
+const char *es;
+target_ulong *miss, *cmp;
+int en;
+
+if (!qemu_log_enabled()) {
+return;
+}
+
+if (excp == POWERPC_EXCP_IFTLB) {
+es = "I";
+en = 'I';
+miss = >spr[SPR_IMISS];
+cmp = >spr[SPR_ICMP];
+} else {
+if (excp == POWERPC_EXCP_DLTLB) {
+es = "DL";
+} else {
+es = "DS";
+}
+en = 'D';
+miss = >spr[SPR_DMISS];
+cmp = >spr[SPR_DCMP];
+}
+qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
+ TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 "
+ TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
+ env->spr[SPR_HASH1], env->spr[SPR_HASH2],
+ env->error_code);
+#endif
+}
+
+
 static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp,
 target_ulong *msr)
 {
@@ -704,34 +739,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp)
 }
 /* fall through */
 case POWERPC_EXCP_7x5:
-#if defined(DEBUG_SOFTWARE_TLB)
-if (qemu_log_enabled()) {
-const char *es;
-target_ulong *miss, *cmp;
-int en;
+ppc_excp_debug_sw_tlb(env, excp);
 
-if (excp == POWERPC_EXCP_IFTLB) {
-es = "I";
-en = 'I';
-miss = >spr[SPR_IMISS];
-cmp = >spr[SPR_ICMP];
-} else {
-if (excp == POWERPC_EXCP_DLTLB) {
-es = "DL";
-} else {
-es = "DS";
-}
-en = 'D';
-miss = >spr[SPR_DMISS];
-cmp = >spr[SPR_DCMP];
-}
-qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
- TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 "
- TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
- env->spr[SPR_HASH1], env->spr[SPR_HASH2],
- env->error_code);
-}
-#endif
 msr |= env->crf[0] << 28;
 msr |= env->error_code; /* key, D/I, S/L bits */
 /* Set way using a LRU mechanism */
-- 
2.33.1




[PATCH 6/9] target/ppc: powerpc_excp: Preserve MSR_LE bit

2022-01-03 Thread Fabiano Rosas
We currently clear MSR_LE when copying bits from env->msr to
new_msr. However, for CPUs that do not have LPCR_ILE we always set
new_msr[LE] according to env->msr[LE]. And for CPUs that do have ILE
support we need to check LPCR/HID0 anyway, so there's no need to clear
the bit when copying.

Signed-off-by: Fabiano Rosas 
---
 target/ppc/excp_helper.c | 14 +-
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 5d31940426..e56ddbe5d5 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -348,10 +348,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp)
 }
 
 /*
- * new interrupt handler msr preserves existing HV and ME unless
- * explicitly overriden
+ * new interrupt handler msr preserves existing HV, ME and LE
+ * unless explicitly overriden.
  */
-new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB);
+new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB | MSR_LE);
 
 /* target registers */
 srr0 = SPR_SRR0;
@@ -763,13 +763,9 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp)
 if (excp_model >= POWERPC_EXCP_970) {
 if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
 new_msr |= (target_ulong)1 << MSR_LE;
+} else {
+new_msr &= ~((target_ulong)1 << MSR_LE);
 }
-} else if (msr_ile) {
-new_msr |= (target_ulong)1 << MSR_LE;
-}
-#else
-if (msr_ile) {
-new_msr |= (target_ulong)1 << MSR_LE;
 }
 #endif
 
-- 
2.33.1




[PATCH 8/9] target/ppc: powerpc_excp: Move AIL under a Book3s block

2022-01-03 Thread Fabiano Rosas
AIL only applies for Book3s CPUs, so move it along with ILE. This
moves ILE further down in the file because the AIL function can alter
vector so we cannot move it up.

Signed-off-by: Fabiano Rosas 
---
 target/ppc/excp_helper.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index d7e087f2f6..a4787c3ae2 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -766,14 +766,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp)
 }
 }
 
-/*
- * We preserve MSR_LE, but some CPUs can take interrupts in a
- * different endianness.
- */
-if (excp_model >= POWERPC_EXCP_970) {
-ppc_excp_toggle_ile(cpu, _msr);
-}
-
 #if defined(TARGET_PPC64)
 if (excp_model == POWERPC_EXCP_BOOKE) {
 if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {
@@ -799,8 +791,16 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp)
 env->spr[srr1] = msr;
 }
 
-/* This can update new_msr and vector if AIL applies */
-ppc_excp_apply_ail(cpu, excp_model, excp, msr, _msr, );
+if (excp_model >= POWERPC_EXCP_970) {
+/*
+ * We preserve MSR_LE, but some CPUs can take interrupts in a
+ * different endianness.
+ */
+ppc_excp_toggle_ile(cpu, _msr);
+
+/* This can update new_msr and vector if AIL applies */
+ppc_excp_apply_ail(cpu, excp_model, excp, msr, _msr, );
+}
 
 powerpc_set_excp_state(cpu, vector, new_msr);
 }
-- 
2.33.1




[PATCH 2/9] target/ppc: powerpc_excp: Keep 60x soft MMU logs active

2022-01-03 Thread Fabiano Rosas
Remove the compile time definition and make the logging be controlled
by the `-d mmu` option in the cmdline.

Signed-off-by: Fabiano Rosas 
---
 target/ppc/excp_helper.c | 15 ++-
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 002a42261b..4769abfb0c 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -30,8 +30,6 @@
 #include "exec/cpu_ldst.h"
 #endif
 
-/* #define DEBUG_SOFTWARE_TLB */
-
 /*/
 /* Exception processing */
 #if !defined(CONFIG_USER_ONLY)
@@ -65,7 +63,6 @@ static inline void dump_hcall(CPUPPCState *env)
 
 static void ppc_excp_debug_sw_tlb(CPUPPCState *env, int excp)
 {
-#if defined(DEBUG_SOFTWARE_TLB)
 const char *es;
 target_ulong *miss, *cmp;
 int en;
@@ -89,12 +86,12 @@ static void ppc_excp_debug_sw_tlb(CPUPPCState *env, int 
excp)
 miss = >spr[SPR_DMISS];
 cmp = >spr[SPR_DCMP];
 }
-qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
- TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 "
- TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
- env->spr[SPR_HASH1], env->spr[SPR_HASH2],
- env->error_code);
-#endif
+
+qemu_log_mask(CPU_LOG_MMU, "6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
+  TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 "
+  TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
+  env->spr[SPR_HASH1], env->spr[SPR_HASH2],
+  env->error_code);
 }
 
 
-- 
2.33.1




[PATCH 4/9] target/ppc: Add HV support to ppc_interrupts_little_endian

2022-01-03 Thread Fabiano Rosas
The ppc_interrupts_little_endian function could be used for interrupts
delivered in Hypervisor mode, so add support for powernv8 and powernv9
to it.

Also drop the comment because it is inaccurate, all CPUs that can run
little endian can have interrupts in little endian. The point is
whether they can take interrupts in an endianness different from
MSR_LE.

This change has no functional impact.

Signed-off-by: Fabiano Rosas 
---
 target/ppc/arch_dump.c   |  2 +-
 target/ppc/cpu.h | 21 +
 target/ppc/excp_helper.c |  2 +-
 3 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/target/ppc/arch_dump.c b/target/ppc/arch_dump.c
index bb392f6d88..12cde198a3 100644
--- a/target/ppc/arch_dump.c
+++ b/target/ppc/arch_dump.c
@@ -237,7 +237,7 @@ int cpu_get_dump_info(ArchDumpInfo *info,
 info->d_machine = PPC_ELF_MACHINE;
 info->d_class = ELFCLASS;
 
-if (ppc_interrupts_little_endian(cpu)) {
+if (ppc_interrupts_little_endian(cpu, false)) {
 info->d_endian = ELFDATA2LSB;
 } else {
 info->d_endian = ELFDATA2MSB;
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index fc66c3561d..a991da4e74 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -2723,19 +2723,24 @@ static inline bool ppc_has_spr(PowerPCCPU *cpu, int spr)
 return cpu->env.spr_cb[spr].name != NULL;
 }
 
-static inline bool ppc_interrupts_little_endian(PowerPCCPU *cpu)
+static inline bool ppc_interrupts_little_endian(PowerPCCPU *cpu, bool hv)
 {
 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
+CPUPPCState *env = >env;
+bool ile = false;
 
-/*
- * Only models that have an LPCR and know about LPCR_ILE can do little
- * endian.
- */
-if (pcc->lpcr_mask & LPCR_ILE) {
-return !!(cpu->env.spr[SPR_LPCR] & LPCR_ILE);
+if (hv) {
+if (is_isa300(pcc)) {
+ile = !!(env->spr[SPR_HID0] & HID0_POWER9_HILE);
+} else {
+ile = !!(env->spr[SPR_HID0] & HID0_HILE);
+}
+
+} else if (pcc->lpcr_mask & LPCR_ILE) {
+ile = !!(env->spr[SPR_LPCR] & LPCR_ILE);
 }
 
-return false;
+return ile;
 }
 
 void dump_mmu(CPUPPCState *env);
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 160e06e3a3..0dbadc5d07 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -997,7 +997,7 @@ void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, 
target_ulong vector)
  */
 msr = (1ULL << MSR_ME);
 msr |= env->msr & (1ULL << MSR_SF);
-if (ppc_interrupts_little_endian(cpu)) {
+if (ppc_interrupts_little_endian(cpu, false)) {
 msr |= (1ULL << MSR_LE);
 }
 
-- 
2.33.1




[PATCH 5/9] target/ppc: Use ppc_interrupts_little_endian in powerpc_excp

2022-01-03 Thread Fabiano Rosas
The ppc_interrupts_little_endian function is suitable for determining
the endianness of interrupts for all Book3S CPUs.

(I'm keeping the MSR check for the rest of the CPUs, but it will go
away in the next patch.)

Signed-off-by: Fabiano Rosas 
---
 target/ppc/excp_helper.c | 21 ++---
 1 file changed, 2 insertions(+), 19 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 0dbadc5d07..5d31940426 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -760,25 +760,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp)
  * CPU, the HV mode, etc...
  */
 #ifdef TARGET_PPC64
-if (excp_model == POWERPC_EXCP_POWER7) {
-if (!(new_msr & MSR_HVB) && (env->spr[SPR_LPCR] & LPCR_ILE)) {
-new_msr |= (target_ulong)1 << MSR_LE;
-}
-} else if (excp_model == POWERPC_EXCP_POWER8) {
-if (new_msr & MSR_HVB) {
-if (env->spr[SPR_HID0] & HID0_HILE) {
-new_msr |= (target_ulong)1 << MSR_LE;
-}
-} else if (env->spr[SPR_LPCR] & LPCR_ILE) {
-new_msr |= (target_ulong)1 << MSR_LE;
-}
-} else if (excp_model == POWERPC_EXCP_POWER9 ||
-   excp_model == POWERPC_EXCP_POWER10) {
-if (new_msr & MSR_HVB) {
-if (env->spr[SPR_HID0] & HID0_POWER9_HILE) {
-new_msr |= (target_ulong)1 << MSR_LE;
-}
-} else if (env->spr[SPR_LPCR] & LPCR_ILE) {
+if (excp_model >= POWERPC_EXCP_970) {
+if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
 new_msr |= (target_ulong)1 << MSR_LE;
 }
 } else if (msr_ile) {
-- 
2.33.1




[PATCH 0/9] target/ppc: powerpc_excp improvements (2/n)

2022-01-03 Thread Fabiano Rosas
These are the follow up cleanups from the RFC that touch the top level
of powerpc_excp. Applies on top of the 1/n series.

Patches 1-2: extract software TLB debug into a function;

Patch 3: group the "unimplemented" messages;

Patches 4-8: move ILE code into a separate function and put ILE and
 AIL under a BookS conditional;

Patch 9: the powerpc_excp_legacy wrapper. Subsequent patch series will
 be dedicated to splitting one "cpu family" each. I have 40x
 ready and I'm working on 60x.

RFC v1:
https://lists.nongnu.org/archive/html/qemu-ppc/2021-06/msg00026.html

RFC v2:
https://lists.nongnu.org/archive/html/qemu-ppc/2021-12/msg00542.html

Cleanups 1/n:
https://mail.gnu.org/archive/html/qemu-ppc/2021-12/msg00696.html

Fabiano Rosas (9):
  target/ppc: powerpc_excp: Extract software TLB logging into a function
  target/ppc: powerpc_excp: Keep 60x soft MMU logs active
  target/ppc: powerpc_excp: Group unimplemented exceptions
  target/ppc: Add HV support to ppc_interrupts_little_endian
  target/ppc: Use ppc_interrupts_little_endian in powerpc_excp
  target/ppc: powerpc_excp: Preserve MSR_LE bit
  target/ppc: powerpc_excp: Move ILE setting into a function
  target/ppc: powerpc_excp: Move AIL under a Book3s block
  target/ppc: Introduce a wrapper for powerpc_excp

 target/ppc/arch_dump.c   |   2 +-
 target/ppc/cpu.h |  21 ++--
 target/ppc/excp_helper.c | 218 ++-
 3 files changed, 92 insertions(+), 149 deletions(-)

-- 
2.33.1




Re: [PATCH v2 4/5] target/ppc: keep ins_cnt/cyc_cnt cleared if MMCR0_FC is set

2022-01-03 Thread Daniel Henrique Barboza




On 1/3/22 18:38, Richard Henderson wrote:

On 1/3/22 10:53 AM, Daniel Henrique Barboza wrote:

pmu_update_summaries() is not considering the case where the PMU can be
turned off (i.e. stop counting all events) if MMCR0_FC is set,
regardless of the other frozen counter bits state. This use case was
covered in the late pmc_get_event(), via the also gone pmc_is_inactive(),
that would return an invalid event if MMCR0_FC was set.

This use case is exercised by the back_to_back_ebbs_test Linux kernel
selftests [1]. As it is today, after enabling EBB exceptions, the test
will report an additional event-based branch being taken and will fail.
Other tests, such as cycles_test.c, will report additional cycles being
calculated in the counters because we're not freezing the PMU quick
enough.

Fix pmu_update_summaries() by keeping env->ins_cnt and env->cyc_cnt
cleared when MMCR0_FC is set.

[1] tools/testing/selftests/powerpc/pmu/ebb/back_to_back_ebbs_test.c

Signed-off-by: Daniel Henrique Barboza 
---
  target/ppc/power8-pmu.c | 5 +
  1 file changed, 5 insertions(+)

diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 7fc7d91109..73713ca2a3 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -40,6 +40,10 @@ void pmu_update_summaries(CPUPPCState *env)
  int ins_cnt = 0;
  int cyc_cnt = 0;
+    if (mmcr0 & MMCR0_FC) {
+    goto hflags_calc;
+    }
+
  if (!(mmcr0 & MMCR0_FC14) && mmcr1 != 0) {
  target_ulong sel;
@@ -71,6 +75,7 @@ void pmu_update_summaries(CPUPPCState *env)
  ins_cnt |= !(mmcr0 & MMCR0_FC56) << 5;
  cyc_cnt |= !(mmcr0 & MMCR0_FC56) << 6;
+ hflags_calc:


Good catch, but should be folded into patch 1 to avoid bisection breakage.


Fair point. Given that you have a suggestion in patch 5 as well I'll send a v3.


Thanks,


Daniel






r~




Re: [PATCH v2 5/5] target/ppc: do not call hreg_compute_hflags() in helper_store_mmcr0()

2022-01-03 Thread Richard Henderson

On 1/3/22 10:53 AM, Daniel Henrique Barboza wrote:

MMCR0 writes will change only MMCR0 bits which are used to calculate
HFLAGS_PMCC0, HFLAGS_PMCC1 and HFLAGS_INSN_CNT hflags. No other machine
register will be changed during this operation. This means that
hreg_compute_hflags() is overkill for what we need to do.

pmu_update_summaries() is already updating HFLAGS_INSN_CNT without
calling hreg_compure_hflags(). Let's do the same for the other 2 MMCR0
hflags.

Signed-off-by: Daniel Henrique Barboza 
---
  target/ppc/power8-pmu.c | 7 ++-
  1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 73713ca2a3..69342413bd 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -224,12 +224,17 @@ static void pmu_update_overflow_timers(CPUPPCState *env)
  
  void helper_store_mmcr0(CPUPPCState *env, target_ulong value)

  {
+uint32_t hflags_pmcc0 = (value & MMCR0_PMCC0) != 0;
+uint32_t hflags_pmcc1 = (value & MMCR0_PMCC1) != 0;


Could use bool here.  Otherwise,

Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 4/5] target/ppc: keep ins_cnt/cyc_cnt cleared if MMCR0_FC is set

2022-01-03 Thread Richard Henderson

On 1/3/22 10:53 AM, Daniel Henrique Barboza wrote:

pmu_update_summaries() is not considering the case where the PMU can be
turned off (i.e. stop counting all events) if MMCR0_FC is set,
regardless of the other frozen counter bits state. This use case was
covered in the late pmc_get_event(), via the also gone pmc_is_inactive(),
that would return an invalid event if MMCR0_FC was set.

This use case is exercised by the back_to_back_ebbs_test Linux kernel
selftests [1]. As it is today, after enabling EBB exceptions, the test
will report an additional event-based branch being taken and will fail.
Other tests, such as cycles_test.c, will report additional cycles being
calculated in the counters because we're not freezing the PMU quick
enough.

Fix pmu_update_summaries() by keeping env->ins_cnt and env->cyc_cnt
cleared when MMCR0_FC is set.

[1] tools/testing/selftests/powerpc/pmu/ebb/back_to_back_ebbs_test.c

Signed-off-by: Daniel Henrique Barboza 
---
  target/ppc/power8-pmu.c | 5 +
  1 file changed, 5 insertions(+)

diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 7fc7d91109..73713ca2a3 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -40,6 +40,10 @@ void pmu_update_summaries(CPUPPCState *env)
  int ins_cnt = 0;
  int cyc_cnt = 0;
  
+if (mmcr0 & MMCR0_FC) {

+goto hflags_calc;
+}
+
  if (!(mmcr0 & MMCR0_FC14) && mmcr1 != 0) {
  target_ulong sel;
  
@@ -71,6 +75,7 @@ void pmu_update_summaries(CPUPPCState *env)

  ins_cnt |= !(mmcr0 & MMCR0_FC56) << 5;
  cyc_cnt |= !(mmcr0 & MMCR0_FC56) << 6;
  
+ hflags_calc:


Good catch, but should be folded into patch 1 to avoid bisection breakage.


r~



Re: [PATCH 00/17] ppc/pnv: enable pnv-phb4 user devices

2022-01-03 Thread Daniel Henrique Barboza




On 1/3/22 18:20, Cédric Le Goater wrote:

On 1/3/22 19:58, Daniel Henrique Barboza wrote:



On 1/3/22 05:21, Cédric Le Goater wrote:

Hello Daniel,

On 12/28/21 20:37, Daniel Henrique Barboza wrote:

Hi,

This series implements pnv-phb4 user devices for the powernv9 machine.
It also includes a couple of pnv-phb3 and pnv-phb3-root-port fixes that
were also applied for the pnv4 equivalents.

During the enablement I had to rollback from the previously added
support for user creatable pnv-phb4-pec devices. The most important
reason is user experience. PEC devices that doesn't spawn the PHB
devices will be just a placeholder to add PHBs, having no use of their
own as far as the user sees it. From this standpoint it makes more sense
to just create all PECs and attach the PHBs the user wants on them.
Patch 14 also describes technical reasons to rollback this support.

The series is rebased using Cedric's 'powernv-6.2' branch [1]i, which
includes the '[PATCH 0/5] ppc/pnv: Preliminary cleanups before user
created PHBs' patches [2].


It would be easier if you based the patchset on mainline. It's not
a problem to resend patches of another person or/and even rework
them to fit your needs.


Sure, I'll send the v2 based on the mainline + the required patches.


Let me merge a couple first. It should reduce the overhead. I will drop
these :


No problem. I'll re-send the v2 after the merge.



   ppc/pnv: Attach PHB3 root port device when defaults are enabled
   ppc/pnv: Attach PHB4 root port device when defaults are enabled

They are in the way for your changes.



I`ll drop these in my side as well.


Thanks,


Daniel









Thanks,

C.




Re: [PATCH v2 1/5] target/ppc: Cache per-pmc insn and cycle count settings

2022-01-03 Thread Richard Henderson

On 1/3/22 10:53 AM, Daniel Henrique Barboza wrote:

+/* Composite status for PMC[1-5] enabled and counting insns or cycles. */
+uint8_t pmc_ins_cnt;
+uint8_t pmc_cyc_cnt;


I should have updated the comment to 1-6 when I added cyc_cnt.


+sel = extract64(mmcr1, MMCR1_PMC4EVT_EXTR, MMCR1_EVT_SIZE);
+ins_cnt |= ((sel == 0xfa) || (sel == 0x2)) << 4;


Ah, thanks for fixing my typo.


r~



Re: [PATCH 00/17] ppc/pnv: enable pnv-phb4 user devices

2022-01-03 Thread Cédric Le Goater

On 1/3/22 19:58, Daniel Henrique Barboza wrote:



On 1/3/22 05:21, Cédric Le Goater wrote:

Hello Daniel,

On 12/28/21 20:37, Daniel Henrique Barboza wrote:

Hi,

This series implements pnv-phb4 user devices for the powernv9 machine.
It also includes a couple of pnv-phb3 and pnv-phb3-root-port fixes that
were also applied for the pnv4 equivalents.

During the enablement I had to rollback from the previously added
support for user creatable pnv-phb4-pec devices. The most important
reason is user experience. PEC devices that doesn't spawn the PHB
devices will be just a placeholder to add PHBs, having no use of their
own as far as the user sees it. From this standpoint it makes more sense
to just create all PECs and attach the PHBs the user wants on them.
Patch 14 also describes technical reasons to rollback this support.

The series is rebased using Cedric's 'powernv-6.2' branch [1]i, which
includes the '[PATCH 0/5] ppc/pnv: Preliminary cleanups before user
created PHBs' patches [2].


It would be easier if you based the patchset on mainline. It's not
a problem to resend patches of another person or/and even rework
them to fit your needs.


Sure, I'll send the v2 based on the mainline + the required patches.


Let me merge a couple first. It should reduce the overhead. I will drop
these :

  ppc/pnv: Attach PHB3 root port device when defaults are enabled
  ppc/pnv: Attach PHB4 root port device when defaults are enabled

They are in the way for your changes.

Thanks,

C.



Re: [PULL 0/5] Misc patch queue

2022-01-03 Thread Richard Henderson

On 1/3/22 9:33 AM, Richard Henderson wrote:

The following changes since commit 69f153667fce723ee546d2f047d66d0cfa67c3cc:

   Merge tag 'memory-api-20211231' of https://github.com/philmd/qemu into 
staging (2021-12-30 17:02:42 -0800)

are available in the Git repository at:

   https://gitlab.com/rth7680/qemu.git tags/pull-misc-20220103

for you to fetch changes up to 5c23f0c3191907000bab278654570a7d5879822a:

   gitlab: Disable check-python-tox (2022-01-03 08:55:55 -0800)


Fix some meson conversion breakage
Disable check-python-tox
Fix emulation of hppa STBY insn


Richard Henderson (5):
   meson: Unify mips and mips64 in host_arch
   tests/tcg: Use $cpu in configure.sh
   tests/tcg: Unconditionally use 90 second timeout
   target/hppa: Fix atomic_store_3 for STBY
   gitlab: Disable check-python-tox

  configure  |  2 +-
  meson.build|  2 +
  target/hppa/op_helper.c| 27 +++--
  tests/tcg/hppa/stby.c  | 87 ++
  .gitlab-ci.d/static_checks.yml |  2 +
  tests/tcg/Makefile.target  | 12 +++---
  tests/tcg/configure.sh |  2 +-
  tests/tcg/hppa/Makefile.target |  5 +++
  8 files changed, 118 insertions(+), 21 deletions(-)
  create mode 100644 tests/tcg/hppa/stby.c


Applied.

r~




Re: [PATCH] FreeBSD: Upgrade to 12.3 release

2022-01-03 Thread Warner Losh
On Mon, Jan 3, 2022 at 1:57 PM Philippe Mathieu-Daudé 
wrote:

> On 3/1/22 21:45, Brad Smith wrote:
> > FreeBSD: Upgrade to 12.3 release
>
> Maybe some mention like:
>
> '''
> Note, since libasn1 got fixed in 12.3 [*], this commit re-enables GNUTLS.
>
> [*]
> https://gitlab.com/gnutls/libtasn1/-/merge_requests/71
> '''
>

Agreed.


> > Signed-off-by: Brad Smith 
> > Tested-by: Thomas Huth 
> > ---
> >   .gitlab-ci.d/cirrus.yml | 5 +
> >   tests/vm/freebsd| 8 +++-
> >   2 files changed, 4 insertions(+), 9 deletions(-)
> >
> > diff --git a/.gitlab-ci.d/cirrus.yml b/.gitlab-ci.d/cirrus.yml
> > index d273a9e713..18ded37c77 100644
> > --- a/.gitlab-ci.d/cirrus.yml
> > +++ b/.gitlab-ci.d/cirrus.yml
> > @@ -52,14 +52,11 @@ x64-freebsd-12-build:
> >   NAME: freebsd-12
> >   CIRRUS_VM_INSTANCE_TYPE: freebsd_instance
> >   CIRRUS_VM_IMAGE_SELECTOR: image_family
> > -CIRRUS_VM_IMAGE_NAME: freebsd-12-2
> > +CIRRUS_VM_IMAGE_NAME: freebsd-12-3
> >   CIRRUS_VM_CPUS: 8
> >   CIRRUS_VM_RAM: 8G
> >   UPDATE_COMMAND: pkg update
> >   INSTALL_COMMAND: pkg install -y
> > -# TODO: Enable gnutls again once FreeBSD's libtasn1 got fixed
> > -# See: https://gitlab.com/gnutls/libtasn1/-/merge_requests/71
> > -CONFIGURE_ARGS: --disable-gnutls
> >   TEST_TARGETS: check
> >
> >   x64-freebsd-13-build:
> > diff --git a/tests/vm/freebsd b/tests/vm/freebsd
> > index 6e20e84322..805db759d6 100755
> > --- a/tests/vm/freebsd
> > +++ b/tests/vm/freebsd
> > @@ -28,8 +28,8 @@ class FreeBSDVM(basevm.BaseVM):
> >   name = "freebsd"
> >   arch = "x86_64"
> >   https://gitlab.com/gnutls/libtasn1/-/merge_requests/71
> > -link = "
> https://download.freebsd.org/ftp/releases/ISO-IMAGES/12.2/FreeBSD-12.2-RELEASE-amd64-disc1.iso.xz
> "
> > -csum =
> "a4530246cafbf1dd42a9bd3ea441ca9a78a6a0cd070278cbdf63f3a6f803ecae"
> > +link = "
> https://download.freebsd.org/ftp/releases/ISO-IMAGES/12.3/FreeBSD-12.3-RELEASE-amd64-disc1.iso.xz
> "
> > +csum =
> "36dd0de50f1fe5f0a88e181e94657656de26fb64254412f74e80e128e8b938b4"
> >   size = "20G"
> >   pkgs = [
> >   # build tools
> > @@ -65,8 +65,6 @@ class FreeBSDVM(basevm.BaseVM):
> >   "zstd",
> >   ]
> >
> > -# TODO: Enable gnutls again once FreeBSD's libtasn1 got fixed
> > -# See: https://gitlab.com/gnutls/libtasn1/-/merge_requests/71
> >   BUILD_SCRIPT = """
> >   set -e;
> >   rm -rf /home/qemu/qemu-test.*
> > @@ -74,7 +72,7 @@ class FreeBSDVM(basevm.BaseVM):
> >   mkdir src build; cd src;
> >   tar -xf /dev/vtbd1;
> >   cd ../build
> > -../src/configure --python=python3.7 --disable-gnutls
> {configure_opts};
> > +../src/configure --python=python3.7 {configure_opts};
> >   gmake --output-sync -j{jobs} {target} {verbose};
> >   """
> >
>
>
>


Re: [PATCH] FreeBSD: Upgrade to 12.3 release

2022-01-03 Thread Warner Losh
On Mon, Jan 3, 2022 at 1:47 PM Brad Smith  wrote:

> FreeBSD: Upgrade to 12.3 release
>
> Signed-off-by: Brad Smith 
> Tested-by: Thomas Huth 
> ---
>  .gitlab-ci.d/cirrus.yml | 5 +
>  tests/vm/freebsd| 8 +++-
>  2 files changed, 4 insertions(+), 9 deletions(-)
>

Reviewed-by: Warner Losh 


> diff --git a/.gitlab-ci.d/cirrus.yml b/.gitlab-ci.d/cirrus.yml
> index d273a9e713..18ded37c77 100644
> --- a/.gitlab-ci.d/cirrus.yml
> +++ b/.gitlab-ci.d/cirrus.yml
> @@ -52,14 +52,11 @@ x64-freebsd-12-build:
>  NAME: freebsd-12
>  CIRRUS_VM_INSTANCE_TYPE: freebsd_instance
>  CIRRUS_VM_IMAGE_SELECTOR: image_family
> -CIRRUS_VM_IMAGE_NAME: freebsd-12-2
> +CIRRUS_VM_IMAGE_NAME: freebsd-12-3
>  CIRRUS_VM_CPUS: 8
>  CIRRUS_VM_RAM: 8G
>  UPDATE_COMMAND: pkg update
>  INSTALL_COMMAND: pkg install -y
> -# TODO: Enable gnutls again once FreeBSD's libtasn1 got fixed
> -# See: https://gitlab.com/gnutls/libtasn1/-/merge_requests/71
> -CONFIGURE_ARGS: --disable-gnutls
>  TEST_TARGETS: check
>
>  x64-freebsd-13-build:
> diff --git a/tests/vm/freebsd b/tests/vm/freebsd
> index 6e20e84322..805db759d6 100755
> --- a/tests/vm/freebsd
> +++ b/tests/vm/freebsd
> @@ -28,8 +28,8 @@ class FreeBSDVM(basevm.BaseVM):
>  name = "freebsd"
>  arch = "x86_64"
>
> -link = "
> https://download.freebsd.org/ftp/releases/ISO-IMAGES/12.2/FreeBSD-12.2-RELEASE-amd64-disc1.iso.xz
> "
> -csum =
> "a4530246cafbf1dd42a9bd3ea441ca9a78a6a0cd070278cbdf63f3a6f803ecae"
> +link = "
> https://download.freebsd.org/ftp/releases/ISO-IMAGES/12.3/FreeBSD-12.3-RELEASE-amd64-disc1.iso.xz
> "
> +csum =
> "36dd0de50f1fe5f0a88e181e94657656de26fb64254412f74e80e128e8b938b4"
>  size = "20G"
>  pkgs = [
>  # build tools
> @@ -65,8 +65,6 @@ class FreeBSDVM(basevm.BaseVM):
>  "zstd",
>  ]
>
> -# TODO: Enable gnutls again once FreeBSD's libtasn1 got fixed
> -# See: https://gitlab.com/gnutls/libtasn1/-/merge_requests/71
>  BUILD_SCRIPT = """
>  set -e;
>  rm -rf /home/qemu/qemu-test.*
> @@ -74,7 +72,7 @@ class FreeBSDVM(basevm.BaseVM):
>  mkdir src build; cd src;
>  tar -xf /dev/vtbd1;
>  cd ../build
> -../src/configure --python=python3.7 --disable-gnutls
> {configure_opts};
> +../src/configure --python=python3.7 {configure_opts};
>  gmake --output-sync -j{jobs} {target} {verbose};
>  """
>
> --
> 2.34.1
>
>
>


Re: [PATCH] FreeBSD: Upgrade to 12.3 release

2022-01-03 Thread Philippe Mathieu-Daudé

On 3/1/22 21:45, Brad Smith wrote:

FreeBSD: Upgrade to 12.3 release


Maybe some mention like:

'''
Note, since libasn1 got fixed in 12.3 [*], this commit re-enables GNUTLS.

[*]
https://gitlab.com/gnutls/libtasn1/-/merge_requests/71
'''


Signed-off-by: Brad Smith 
Tested-by: Thomas Huth 
---
  .gitlab-ci.d/cirrus.yml | 5 +
  tests/vm/freebsd| 8 +++-
  2 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/.gitlab-ci.d/cirrus.yml b/.gitlab-ci.d/cirrus.yml
index d273a9e713..18ded37c77 100644
--- a/.gitlab-ci.d/cirrus.yml
+++ b/.gitlab-ci.d/cirrus.yml
@@ -52,14 +52,11 @@ x64-freebsd-12-build:
  NAME: freebsd-12
  CIRRUS_VM_INSTANCE_TYPE: freebsd_instance
  CIRRUS_VM_IMAGE_SELECTOR: image_family
-CIRRUS_VM_IMAGE_NAME: freebsd-12-2
+CIRRUS_VM_IMAGE_NAME: freebsd-12-3
  CIRRUS_VM_CPUS: 8
  CIRRUS_VM_RAM: 8G
  UPDATE_COMMAND: pkg update
  INSTALL_COMMAND: pkg install -y
-# TODO: Enable gnutls again once FreeBSD's libtasn1 got fixed
-# See: https://gitlab.com/gnutls/libtasn1/-/merge_requests/71
-CONFIGURE_ARGS: --disable-gnutls
  TEST_TARGETS: check
  
  x64-freebsd-13-build:

diff --git a/tests/vm/freebsd b/tests/vm/freebsd
index 6e20e84322..805db759d6 100755
--- a/tests/vm/freebsd
+++ b/tests/vm/freebsd
@@ -28,8 +28,8 @@ class FreeBSDVM(basevm.BaseVM):
  name = "freebsd"
  arch = "x86_64"
  https://gitlab.com/gnutls/libtasn1/-/merge_requests/71
-link = 
"https://download.freebsd.org/ftp/releases/ISO-IMAGES/12.2/FreeBSD-12.2-RELEASE-amd64-disc1.iso.xz;
-csum = "a4530246cafbf1dd42a9bd3ea441ca9a78a6a0cd070278cbdf63f3a6f803ecae"
+link = 
"https://download.freebsd.org/ftp/releases/ISO-IMAGES/12.3/FreeBSD-12.3-RELEASE-amd64-disc1.iso.xz;
+csum = "36dd0de50f1fe5f0a88e181e94657656de26fb64254412f74e80e128e8b938b4"
  size = "20G"
  pkgs = [
  # build tools
@@ -65,8 +65,6 @@ class FreeBSDVM(basevm.BaseVM):
  "zstd",
  ]
  
-# TODO: Enable gnutls again once FreeBSD's libtasn1 got fixed

-# See: https://gitlab.com/gnutls/libtasn1/-/merge_requests/71
  BUILD_SCRIPT = """
  set -e;
  rm -rf /home/qemu/qemu-test.*
@@ -74,7 +72,7 @@ class FreeBSDVM(basevm.BaseVM):
  mkdir src build; cd src;
  tar -xf /dev/vtbd1;
  cd ../build
-../src/configure --python=python3.7 --disable-gnutls {configure_opts};
+../src/configure --python=python3.7 {configure_opts};
  gmake --output-sync -j{jobs} {target} {verbose};
  """
  





Re: [PULL v2 20/36] docs/sphinx: add sphinx modules to include D-Bus documentation

2022-01-03 Thread Thomas Huth

On 21/12/2021 07.58, marcandre.lur...@redhat.com wrote:

From: Marc-André Lureau 

Add a new dbus-doc directive to import D-Bus interfaces documentation
from the introspection XML. The comments annotations follow the
gtkdoc/kerneldoc style, and should be formatted with reST.

Note: I realize after the fact that I was implementing those modules
with sphinx 4, and that we have much lower requirements. Instead of
lowering the features and code (removing type annotations etc), let's
have a warning in the documentation when the D-Bus modules can't be
used, and point to the source XML file in that case.

Signed-off-by: Marc-André Lureau 
Acked-by: Gerd Hoffmann 
---
  docs/conf.py   |   8 +
  docs/sphinx/dbusdoc.py | 166 +++
  docs/sphinx/dbusdomain.py  | 406 +
  docs/sphinx/dbusparser.py  | 373 ++
  docs/sphinx/fakedbusdoc.py |  25 +++
  5 files changed, 978 insertions(+)
  create mode 100644 docs/sphinx/dbusdoc.py
  create mode 100644 docs/sphinx/dbusdomain.py
  create mode 100644 docs/sphinx/dbusparser.py
  create mode 100644 docs/sphinx/fakedbusdoc.py

diff --git a/docs/conf.py b/docs/conf.py
index 763e7d243448..e79015975e6a 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -73,6 +73,12 @@
  # ones.
  extensions = ['kerneldoc', 'qmp_lexer', 'hxtool', 'depfile', 'qapidoc']
  
+if sphinx.version_info[:3] > (4, 0, 0):

+tags.add('sphinx4')
+extensions += ['dbusdoc']
+else:
+extensions += ['fakedbusdoc']
+
  # Add any paths that contain templates here, relative to this directory.
  templates_path = [os.path.join(qemu_docdir, '_templates')]
  
@@ -311,3 +317,5 @@

  kerneldoc_srctree = os.path.join(qemu_docdir, '..')
  hxtool_srctree = os.path.join(qemu_docdir, '..')
  qapidoc_srctree = os.path.join(qemu_docdir, '..')
+dbusdoc_srctree = os.path.join(qemu_docdir, '..')
+dbus_index_common_prefix = ["org.qemu."]


This does not work with my version of Sphinx (v 1.7.6):

Program sphinx-build-3 found: YES (/usr/bin/sphinx-build-3)
../../home/thuth/devel/qemu/docs/meson.build:30: WARNING: 
/usr/bin/sphinx-build-3:

Extension error:
Could not import extension fakedbusdoc (exception: cannot import name 
'SphinxDirective')


Any ideas how to fix it?

 Thomas





[PATCH] FreeBSD: Upgrade to 12.3 release

2022-01-03 Thread Brad Smith
FreeBSD: Upgrade to 12.3 release

Signed-off-by: Brad Smith 
Tested-by: Thomas Huth 
---
 .gitlab-ci.d/cirrus.yml | 5 +
 tests/vm/freebsd| 8 +++-
 2 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/.gitlab-ci.d/cirrus.yml b/.gitlab-ci.d/cirrus.yml
index d273a9e713..18ded37c77 100644
--- a/.gitlab-ci.d/cirrus.yml
+++ b/.gitlab-ci.d/cirrus.yml
@@ -52,14 +52,11 @@ x64-freebsd-12-build:
 NAME: freebsd-12
 CIRRUS_VM_INSTANCE_TYPE: freebsd_instance
 CIRRUS_VM_IMAGE_SELECTOR: image_family
-CIRRUS_VM_IMAGE_NAME: freebsd-12-2
+CIRRUS_VM_IMAGE_NAME: freebsd-12-3
 CIRRUS_VM_CPUS: 8
 CIRRUS_VM_RAM: 8G
 UPDATE_COMMAND: pkg update
 INSTALL_COMMAND: pkg install -y
-# TODO: Enable gnutls again once FreeBSD's libtasn1 got fixed
-# See: https://gitlab.com/gnutls/libtasn1/-/merge_requests/71
-CONFIGURE_ARGS: --disable-gnutls
 TEST_TARGETS: check
 
 x64-freebsd-13-build:
diff --git a/tests/vm/freebsd b/tests/vm/freebsd
index 6e20e84322..805db759d6 100755
--- a/tests/vm/freebsd
+++ b/tests/vm/freebsd
@@ -28,8 +28,8 @@ class FreeBSDVM(basevm.BaseVM):
 name = "freebsd"
 arch = "x86_64"
 
-link = 
"https://download.freebsd.org/ftp/releases/ISO-IMAGES/12.2/FreeBSD-12.2-RELEASE-amd64-disc1.iso.xz;
-csum = "a4530246cafbf1dd42a9bd3ea441ca9a78a6a0cd070278cbdf63f3a6f803ecae"
+link = 
"https://download.freebsd.org/ftp/releases/ISO-IMAGES/12.3/FreeBSD-12.3-RELEASE-amd64-disc1.iso.xz;
+csum = "36dd0de50f1fe5f0a88e181e94657656de26fb64254412f74e80e128e8b938b4"
 size = "20G"
 pkgs = [
 # build tools
@@ -65,8 +65,6 @@ class FreeBSDVM(basevm.BaseVM):
 "zstd",
 ]
 
-# TODO: Enable gnutls again once FreeBSD's libtasn1 got fixed
-# See: https://gitlab.com/gnutls/libtasn1/-/merge_requests/71
 BUILD_SCRIPT = """
 set -e;
 rm -rf /home/qemu/qemu-test.*
@@ -74,7 +72,7 @@ class FreeBSDVM(basevm.BaseVM):
 mkdir src build; cd src;
 tar -xf /dev/vtbd1;
 cd ../build
-../src/configure --python=python3.7 --disable-gnutls {configure_opts};
+../src/configure --python=python3.7 {configure_opts};
 gmake --output-sync -j{jobs} {target} {verbose};
 """
 
-- 
2.34.1




Something broke "make html" and "make man"

2022-01-03 Thread Thomas Huth



 Hi!

"make html" and "make man" do not work anymore:

$ make help | grep -B1 html
Documentation targets:
  html man  - Build documentation in specified format
$ make html
  GIT ui/keycodemapdb meson tests/fp/berkeley-testfloat-3 
tests/fp/berkeley-softfloat-3 dtc capstone slirp

make: *** No rule to make target 'html'.  Stop.
$ make man
  GIT ui/keycodemapdb meson tests/fp/berkeley-testfloat-3 
tests/fp/berkeley-softfloat-3 dtc capstone slirp

make: *** No rule to make target 'man'.  Stop.

Anybody any ideas how to fix it?

 Thomas




Re: [PATCH 3/4] hw/arm: add i2c muxes to kudo-bmc

2022-01-03 Thread Philippe Mathieu-Daudé

On 2/1/22 22:58, Patrick Venture wrote:

Signed-off-by: Patrick Venture 
Reviewed-by: Hao Wu 
---
  hw/arm/npcm7xx_boards.c | 9 +
  1 file changed, 9 insertions(+)


Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH v3 1/2] linux-user: add sched_getattr support

2022-01-03 Thread Tõnis Tiigi
On Mon, Jan 3, 2022 at 10:37 AM Laurent Vivier  wrote:
>
> Le 03/01/2022 à 18:07, Tõnis Tiigi a écrit :
> > Ping Laurent. Any suggestions for the follow-up questions?
> >
> > On Thu, Dec 23, 2021 at 3:00 PM Tõnis Tiigi  wrote:
> >>
> >> On Thu, Dec 23, 2021 at 1:03 PM Laurent Vivier  wrote:
> >>>
> >>> Le 23/12/2021 à 07:47, Tonis Tiigi a écrit :
> >>>
> >>> Please copy here what you explain in PATCH 0 regarding this patch.
> >>> (do the same for PATCH 1)
> >>>
>  Signed-off-by: Tonis Tiigi 
>  ---
> linux-user/syscall.c  | 94 +++
> linux-user/syscall_defs.h | 14 ++
> 2 files changed, 108 insertions(+)
> 
>  diff --git a/linux-user/syscall.c b/linux-user/syscall.c
>  index f1cfcc8104..2f5a0fac5a 100644
>  --- a/linux-user/syscall.c
>  +++ b/linux-user/syscall.c
>  @@ -339,6 +339,12 @@ _syscall3(int, sys_sched_getaffinity, pid_t, pid, 
>  unsigned int, len,
> #define __NR_sys_sched_setaffinity __NR_sched_setaffinity
> _syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
>   unsigned long *, user_mask_ptr);
>  +#define __NR_sys_sched_getattr __NR_sched_getattr
>  +_syscall4(int, sys_sched_getattr, pid_t, pid, struct target_sched_attr 
>  *, attr,
>  +  unsigned int, size, unsigned int, flags);
>  +#define __NR_sys_sched_setattr __NR_sched_setattr
>  +_syscall3(int, sys_sched_setattr, pid_t, pid, struct target_sched_attr 
>  *, attr,
>  +  unsigned int, flags);
> #define __NR_sys_getcpu __NR_getcpu
> _syscall3(int, sys_getcpu, unsigned *, cpu, unsigned *, node, void *, 
>  tcache);
> _syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
>  @@ -10593,6 +10599,94 @@ static abi_long do_syscall1(void *cpu_env, int 
>  num, abi_long arg1,
> }
> case TARGET_NR_sched_getscheduler:
> return get_errno(sched_getscheduler(arg1));
>  +case TARGET_NR_sched_getattr:
>  +{
>  +struct target_sched_attr *target_scha;
>  +struct target_sched_attr scha;
> >>>
> >>> In fact, this scha is used with the host syscall, so it must be  
> >>> sched_attr.
> >>
> >>
> >> Where do you want me to define the "host variant" of sched_attr and
> >> with what types for the properties? Or do you want additional
> >> typedef(where?) so the name is less confusing? All properties in this
> >> type are fixed length and identical for all architectures.
>
> It's better to use the host variant with the host syscall.
>
> Normally sched_attr comes with kernel headers, so it should be available and 
> you should not have to
> define it.
>
> We need to define a target property because alignment also matters as the 
> alignment for type can
> differ from an architecture to another. I agree that in most cases it should 
> not be needed but I
> think it's cleaner like that.
>
> so for this part, only replace "struct target_sched_attr scha;" by "struct 
> sched_att scha;"

sched_attr is defined in linux/sched/types.h . I can't include it
directly as it conflicts with libc headers with "redefinition of
'struct sched_param'". It looks like
https://lkml.org/lkml/2020/5/28/810 attempted to resolve this conflict
but was not merged and seems to be stuck in kernel vs glibc blame
cycle.

>
> >>
> >>>
> >>>
>  +if (arg2 == 0) {
>  +return -TARGET_EINVAL;
>  +}
>  +if (arg3 > sizeof(scha)) {
>  +arg3 = sizeof(scha);
>  +}
>  +ret = get_errno(sys_sched_getattr(arg1, , arg3, arg4));
>  +if (!is_error(ret)) {
>  +target_scha = lock_user(VERIFY_WRITE, arg2, arg3, 0);
>  +if (!target_scha) {
>  +return -TARGET_EFAULT;
>  +}
>  +target_scha->size = tswap32(scha.size);
>  +target_scha->sched_policy = tswap32(scha.sched_policy);
>  +target_scha->sched_flags = tswap64(scha.sched_flags);
>  +target_scha->sched_nice = tswap32(scha.sched_nice);
>  +target_scha->sched_priority = 
>  tswap32(scha.sched_priority);
>  +target_scha->sched_runtime = 
>  tswap64(scha.sched_runtime);
>  +target_scha->sched_deadline = 
>  tswap64(scha.sched_deadline);
>  +target_scha->sched_period = tswap64(scha.sched_period);
>  +if (scha.size > offsetof(struct target_sched_attr, 
>  sched_util_min)) {
>  +target_scha->sched_util_min = 
>  tswap32(scha.sched_util_min);
>  +target_scha->sched_util_max = 
>  tswap32(scha.sched_util_max);
>  +}
>  +

Re: [PATCH 03/17] pnv_phb3.h: change TYPE_PNV_PHB3_ROOT_BUS name

2022-01-03 Thread Daniel Henrique Barboza




On 1/3/22 05:28, Cédric Le Goater wrote:

On 12/28/21 20:37, Daniel Henrique Barboza wrote:

The TYPE_PNV_PHB3_ROOT_BUS name is used as the default bus name when
the dev has no 'id'. However, pnv-phb3-root-bus is a bit too long to be
used as a bus name.

Most common QEMU buses and PCI controllers are named based on their bus
type (e.g. pSeries spapr-pci-host-bridge is called 'pci'). The most
common name for a PCIE bus controller in QEMU is 'pcie'. Naming it
'pcie' would break the documented use of the pnv-phb3 device, since
'pcie.0' would now refer to the root bus instead of the first root port.

There's nothing particularly wrong with the 'root-bus' name used before,
aside from the fact that 'root-bus' is being used for pnv-phb3 and
pnv-phb4 created buses, which is not quite correct since these buses
aren't implemented the same way in QEMU - you can't plug a
pnv-phb4-root-port into a pnv-phb3 root bus, for example.

This patch renames it as 'phb3-root', which is a compromise between the
existing and the previously used name. Creating 3 phbs without ID will
result in an "info qtree" output similar to this:

bus: main-system-bus
   type System
   dev: pnv-phb3, id ""
 index = 2 (0x2)
 chip-id = 0 (0x0)
 x-config-reg-migration-enabled = true
 bypass-iommu = false
 bus: phb3-root.2
   type phb3-root
   dev: pnv-phb3, id ""
 index = 1 (0x1)
 chip-id = 0 (0x0)
 x-config-reg-migration-enabled = true
 bypass-iommu = false
 bus: phb3-root.1
   type phb3-root
   dev: pnv-phb3, id ""
 index = 0 (0x0)
 chip-id = 0 (0x0)
 x-config-reg-migration-enabled = true
 bypass-iommu = false
 bus: phb3-root.0
   type phb3-root

Signed-off-by: Daniel Henrique Barboza 
---
  include/hw/pci-host/pnv_phb3.h | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/hw/pci-host/pnv_phb3.h b/include/hw/pci-host/pnv_phb3.h
index 2e423c3890..658ee40e13 100644
--- a/include/hw/pci-host/pnv_phb3.h
+++ b/include/hw/pci-host/pnv_phb3.h
@@ -105,7 +105,7 @@ struct PnvPBCQState {
  /*
   * PHB3 PCIe Root port
   */
-#define TYPE_PNV_PHB3_ROOT_BUS "pnv-phb3-root-bus"
+#define TYPE_PNV_PHB3_ROOT_BUS "phb3-root"


hmm, what about "pnv-phb3-root" ? I like the 'pnv' prefix to identify
the machine.


Works for me. I'll make the change in v2.

Thanks,


Daniel




Thanks,

C.




  #define TYPE_PNV_PHB3_ROOT_PORT "pnv-phb3-root-port"







Re: [PATCH 00/17] ppc/pnv: enable pnv-phb4 user devices

2022-01-03 Thread Daniel Henrique Barboza




On 1/3/22 05:21, Cédric Le Goater wrote:

Hello Daniel,

On 12/28/21 20:37, Daniel Henrique Barboza wrote:

Hi,

This series implements pnv-phb4 user devices for the powernv9 machine.
It also includes a couple of pnv-phb3 and pnv-phb3-root-port fixes that
were also applied for the pnv4 equivalents.

During the enablement I had to rollback from the previously added
support for user creatable pnv-phb4-pec devices. The most important
reason is user experience. PEC devices that doesn't spawn the PHB
devices will be just a placeholder to add PHBs, having no use of their
own as far as the user sees it. From this standpoint it makes more sense
to just create all PECs and attach the PHBs the user wants on them.
Patch 14 also describes technical reasons to rollback this support.

The series is rebased using Cedric's 'powernv-6.2' branch [1]i, which
includes the '[PATCH 0/5] ppc/pnv: Preliminary cleanups before user
created PHBs' patches [2].


It would be easier if you based the patchset on mainline. It's not
a problem to resend patches of another person or/and even rework
them to fit your needs.



Sure, I'll send the v2 based on the mainline + the required patches.


Thanks,


Daniel



Thanks,

C.




[PATCH v2 5/5] target/ppc: do not call hreg_compute_hflags() in helper_store_mmcr0()

2022-01-03 Thread Daniel Henrique Barboza
MMCR0 writes will change only MMCR0 bits which are used to calculate
HFLAGS_PMCC0, HFLAGS_PMCC1 and HFLAGS_INSN_CNT hflags. No other machine
register will be changed during this operation. This means that
hreg_compute_hflags() is overkill for what we need to do.

pmu_update_summaries() is already updating HFLAGS_INSN_CNT without
calling hreg_compure_hflags(). Let's do the same for the other 2 MMCR0
hflags.

Signed-off-by: Daniel Henrique Barboza 
---
 target/ppc/power8-pmu.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 73713ca2a3..69342413bd 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -224,12 +224,17 @@ static void pmu_update_overflow_timers(CPUPPCState *env)
 
 void helper_store_mmcr0(CPUPPCState *env, target_ulong value)
 {
+uint32_t hflags_pmcc0 = (value & MMCR0_PMCC0) != 0;
+uint32_t hflags_pmcc1 = (value & MMCR0_PMCC1) != 0;
+
 pmu_update_cycles(env);
 
 env->spr[SPR_POWER_MMCR0] = value;
 
 /* MMCR0 writes can change HFLAGS_PMCC[01] and HFLAGS_INSN_CNT */
-hreg_compute_hflags(env);
+env->hflags = deposit32(env->hflags, HFLAGS_PMCC0, 1, hflags_pmcc0);
+env->hflags = deposit32(env->hflags, HFLAGS_PMCC1, 1, hflags_pmcc1);
+
 pmu_update_summaries(env);
 
 /* Update cycle overflow timers with the current MMCR0 state */
-- 
2.33.1




[PATCH v2 4/5] target/ppc: keep ins_cnt/cyc_cnt cleared if MMCR0_FC is set

2022-01-03 Thread Daniel Henrique Barboza
pmu_update_summaries() is not considering the case where the PMU can be
turned off (i.e. stop counting all events) if MMCR0_FC is set,
regardless of the other frozen counter bits state. This use case was
covered in the late pmc_get_event(), via the also gone pmc_is_inactive(),
that would return an invalid event if MMCR0_FC was set.

This use case is exercised by the back_to_back_ebbs_test Linux kernel
selftests [1]. As it is today, after enabling EBB exceptions, the test
will report an additional event-based branch being taken and will fail.
Other tests, such as cycles_test.c, will report additional cycles being
calculated in the counters because we're not freezing the PMU quick
enough.

Fix pmu_update_summaries() by keeping env->ins_cnt and env->cyc_cnt
cleared when MMCR0_FC is set.

[1] tools/testing/selftests/powerpc/pmu/ebb/back_to_back_ebbs_test.c

Signed-off-by: Daniel Henrique Barboza 
---
 target/ppc/power8-pmu.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 7fc7d91109..73713ca2a3 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -40,6 +40,10 @@ void pmu_update_summaries(CPUPPCState *env)
 int ins_cnt = 0;
 int cyc_cnt = 0;
 
+if (mmcr0 & MMCR0_FC) {
+goto hflags_calc;
+}
+
 if (!(mmcr0 & MMCR0_FC14) && mmcr1 != 0) {
 target_ulong sel;
 
@@ -71,6 +75,7 @@ void pmu_update_summaries(CPUPPCState *env)
 ins_cnt |= !(mmcr0 & MMCR0_FC56) << 5;
 cyc_cnt |= !(mmcr0 & MMCR0_FC56) << 6;
 
+ hflags_calc:
 env->pmc_ins_cnt = ins_cnt;
 env->pmc_cyc_cnt = cyc_cnt;
 env->hflags = deposit32(env->hflags, HFLAGS_INSN_CNT, 1, ins_cnt != 0);
-- 
2.33.1




[PATCH v2 1/5] target/ppc: Cache per-pmc insn and cycle count settings

2022-01-03 Thread Daniel Henrique Barboza
From: Richard Henderson 

This is the combination of frozen bit and counter type, on a per
counter basis. So far this is only used by HFLAGS_INSN_CNT, but
will be used more later.

Signed-off-by: Richard Henderson 
[danielhb: fixed PMC4 cyc_cnt shift and insn run latch code]
Signed-off-by: Daniel Henrique Barboza 
---
 target/ppc/cpu.h |  3 +++
 target/ppc/cpu_init.c|  1 +
 target/ppc/helper_regs.c |  2 +-
 target/ppc/machine.c |  2 ++
 target/ppc/power8-pmu.c  | 53 +++-
 target/ppc/power8-pmu.h  | 14 +--
 6 files changed, 54 insertions(+), 21 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index fc66c3561d..a297a52168 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1144,6 +1144,9 @@ struct CPUPPCState {
 /* Other registers */
 target_ulong spr[1024]; /* special purpose registers */
 ppc_spr_t spr_cb[1024];
+/* Composite status for PMC[1-5] enabled and counting insns or cycles. */
+uint8_t pmc_ins_cnt;
+uint8_t pmc_cyc_cnt;
 /* Vector status and control register, minus VSCR_SAT */
 uint32_t vscr;
 /* VSX registers (including FP and AVR) */
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 06ef15cd9e..63f9babfee 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -8313,6 +8313,7 @@ static void ppc_cpu_reset(DeviceState *dev)
 #endif /* CONFIG_TCG */
 #endif
 
+pmu_update_summaries(env);
 hreg_compute_hflags(env);
 env->reserve_addr = (target_ulong)-1ULL;
 /* Be sure no exception or interrupt is pending */
diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index b847928842..8671b7bb69 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -123,7 +123,7 @@ static uint32_t hreg_compute_hflags_value(CPUPPCState *env)
 }
 
 #if defined(TARGET_PPC64)
-if (pmu_insn_cnt_enabled(env)) {
+if (env->pmc_ins_cnt) {
 hflags |= 1 << HFLAGS_INSN_CNT;
 }
 #endif
diff --git a/target/ppc/machine.c b/target/ppc/machine.c
index 93972df58e..756d8de5d8 100644
--- a/target/ppc/machine.c
+++ b/target/ppc/machine.c
@@ -8,6 +8,7 @@
 #include "qapi/error.h"
 #include "qemu/main-loop.h"
 #include "kvm_ppc.h"
+#include "power8-pmu.h"
 
 static void post_load_update_msr(CPUPPCState *env)
 {
@@ -19,6 +20,7 @@ static void post_load_update_msr(CPUPPCState *env)
  */
 env->msr ^= env->msr_mask & ~((1ULL << MSR_TGPR) | MSR_HVB);
 ppc_store_msr(env, msr);
+pmu_update_summaries(env);
 }
 
 static int cpu_load_old(QEMUFile *f, void *opaque, int version_id)
diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 08d1902cd5..4fce6e8de8 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -11,8 +11,6 @@
  */
 
 #include "qemu/osdep.h"
-
-#include "power8-pmu.h"
 #include "cpu.h"
 #include "helper_regs.h"
 #include "exec/exec-all.h"
@@ -20,6 +18,7 @@
 #include "qemu/error-report.h"
 #include "qemu/main-loop.h"
 #include "hw/ppc/ppc.h"
+#include "power8-pmu.h"
 
 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
 
@@ -121,18 +120,47 @@ static PMUEventType pmc_get_event(CPUPPCState *env, int 
sprn)
 return evt_type;
 }
 
-bool pmu_insn_cnt_enabled(CPUPPCState *env)
+void pmu_update_summaries(CPUPPCState *env)
 {
-int sprn;
-
-for (sprn = SPR_POWER_PMC1; sprn <= SPR_POWER_PMC5; sprn++) {
-if (pmc_get_event(env, sprn) == PMU_EVENT_INSTRUCTIONS ||
-pmc_get_event(env, sprn) == PMU_EVENT_INSN_RUN_LATCH) {
-return true;
+target_ulong mmcr0 = env->spr[SPR_POWER_MMCR0];
+target_ulong mmcr1 = env->spr[SPR_POWER_MMCR1];
+int ins_cnt = 0;
+int cyc_cnt = 0;
+
+if (!(mmcr0 & MMCR0_FC14) && mmcr1 != 0) {
+target_ulong sel;
+
+sel = extract64(mmcr1, MMCR1_PMC1EVT_EXTR, MMCR1_EVT_SIZE);
+switch (sel) {
+case 0x02:
+case 0xfe:
+ins_cnt |= 1 << 1;
+break;
+case 0x1e:
+case 0xf0:
+cyc_cnt |= 1 << 1;
+break;
 }
+
+sel = extract64(mmcr1, MMCR1_PMC2EVT_EXTR, MMCR1_EVT_SIZE);
+ins_cnt |= (sel == 0x02) << 2;
+cyc_cnt |= (sel == 0x1e) << 2;
+
+sel = extract64(mmcr1, MMCR1_PMC3EVT_EXTR, MMCR1_EVT_SIZE);
+ins_cnt |= (sel == 0x02) << 3;
+cyc_cnt |= (sel == 0x1e) << 3;
+
+sel = extract64(mmcr1, MMCR1_PMC4EVT_EXTR, MMCR1_EVT_SIZE);
+ins_cnt |= ((sel == 0xfa) || (sel == 0x2)) << 4;
+cyc_cnt |= (sel == 0x1e) << 4;
 }
 
-return false;
+ins_cnt |= !(mmcr0 & MMCR0_FC56) << 5;
+cyc_cnt |= !(mmcr0 & MMCR0_FC56) << 6;
+
+env->pmc_ins_cnt = ins_cnt;
+env->pmc_cyc_cnt = cyc_cnt;
+env->hflags = deposit32(env->hflags, HFLAGS_INSN_CNT, 1, ins_cnt != 0);
 }
 
 static bool pmu_increment_insns(CPUPPCState *env, uint32_t num_insns)
@@ -264,8 +292,9 @@ void helper_store_mmcr0(CPUPPCState *env, target_ulong 
value)
 
 env->spr[SPR_POWER_MMCR0] = value;
 
-  

[PATCH v2 3/5] target/ppc: Use env->pnc_cyc_cnt

2022-01-03 Thread Daniel Henrique Barboza
From: Richard Henderson 

Use the cached pmc_cyc_cnt value in pmu_update_cycles
and pmc_update_overflow_timer.  This leaves pmc_get_event
and pmc_is_inactive unused, so remove them.

Signed-off-by: Richard Henderson 
---
 target/ppc/power8-pmu.c | 107 
 1 file changed, 9 insertions(+), 98 deletions(-)

diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 8f01934c15..7fc7d91109 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -24,19 +24,6 @@
 
 #define PMC_COUNTER_NEGATIVE_VAL 0x8000UL
 
-static bool pmc_is_inactive(CPUPPCState *env, int sprn)
-{
-if (env->spr[SPR_POWER_MMCR0] & MMCR0_FC) {
-return true;
-}
-
-if (sprn < SPR_POWER_PMC5) {
-return env->spr[SPR_POWER_MMCR0] & MMCR0_FC14;
-}
-
-return env->spr[SPR_POWER_MMCR0] & MMCR0_FC56;
-}
-
 static bool pmc_has_overflow_enabled(CPUPPCState *env, int sprn)
 {
 if (sprn == SPR_POWER_PMC1) {
@@ -46,80 +33,6 @@ static bool pmc_has_overflow_enabled(CPUPPCState *env, int 
sprn)
 return env->spr[SPR_POWER_MMCR0] & MMCR0_PMCjCE;
 }
 
-/*
- * For PMCs 1-4, IBM POWER chips has support for an implementation
- * dependent event, 0x1E, that enables cycle counting. The Linux kernel
- * makes extensive use of 0x1E, so let's also support it.
- *
- * Likewise, event 0x2 is an implementation-dependent event that IBM
- * POWER chips implement (at least since POWER8) that is equivalent to
- * PM_INST_CMPL. Let's support this event on PMCs 1-4 as well.
- */
-static PMUEventType pmc_get_event(CPUPPCState *env, int sprn)
-{
-uint8_t mmcr1_evt_extr[] = { MMCR1_PMC1EVT_EXTR, MMCR1_PMC2EVT_EXTR,
- MMCR1_PMC3EVT_EXTR, MMCR1_PMC4EVT_EXTR };
-PMUEventType evt_type = PMU_EVENT_INVALID;
-uint8_t pmcsel;
-int i;
-
-if (pmc_is_inactive(env, sprn)) {
-return PMU_EVENT_INACTIVE;
-}
-
-if (sprn == SPR_POWER_PMC5) {
-return PMU_EVENT_INSTRUCTIONS;
-}
-
-if (sprn == SPR_POWER_PMC6) {
-return PMU_EVENT_CYCLES;
-}
-
-i = sprn - SPR_POWER_PMC1;
-pmcsel = extract64(env->spr[SPR_POWER_MMCR1], mmcr1_evt_extr[i],
-   MMCR1_EVT_SIZE);
-
-switch (pmcsel) {
-case 0x2:
-evt_type = PMU_EVENT_INSTRUCTIONS;
-break;
-case 0x1E:
-evt_type = PMU_EVENT_CYCLES;
-break;
-case 0xF0:
-/*
- * PMC1SEL = 0xF0 is the architected PowerISA v3.1
- * event that counts cycles using PMC1.
- */
-if (sprn == SPR_POWER_PMC1) {
-evt_type = PMU_EVENT_CYCLES;
-}
-break;
-case 0xFA:
-/*
- * PMC4SEL = 0xFA is the "instructions completed
- * with run latch set" event.
- */
-if (sprn == SPR_POWER_PMC4) {
-evt_type = PMU_EVENT_INSN_RUN_LATCH;
-}
-break;
-case 0xFE:
-/*
- * PMC1SEL = 0xFE is the architected PowerISA v3.1
- * event to sample instructions using PMC1.
- */
-if (sprn == SPR_POWER_PMC1) {
-evt_type = PMU_EVENT_INSTRUCTIONS;
-}
-break;
-default:
-break;
-}
-
-return evt_type;
-}
-
 void pmu_update_summaries(CPUPPCState *env)
 {
 target_ulong mmcr0 = env->spr[SPR_POWER_MMCR0];
@@ -233,18 +146,16 @@ static void pmu_update_cycles(CPUPPCState *env)
 {
 uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 uint64_t time_delta = now - env->pmu_base_time;
-int sprn;
+int sprn, cyc_cnt = env->pmc_cyc_cnt;
 
 for (sprn = SPR_POWER_PMC1; sprn <= SPR_POWER_PMC6; sprn++) {
-if (pmc_get_event(env, sprn) != PMU_EVENT_CYCLES) {
-continue;
+if (cyc_cnt & (1 << (sprn - SPR_POWER_PMC1 + 1))) {
+/*
+ * The pseries and powernv clock runs at 1Ghz, meaning
+ * that 1 nanosec equals 1 cycle.
+ */
+env->spr[sprn] += time_delta;
 }
-
-/*
- * The pseries and powernv clock runs at 1Ghz, meaning
- * that 1 nanosec equals 1 cycle.
- */
-env->spr[sprn] += time_delta;
 }
 
 /* Update base_time for future calculations */
@@ -273,7 +184,7 @@ static void pmc_update_overflow_timer(CPUPPCState *env, int 
sprn)
 return;
 }
 
-if (pmc_get_event(env, sprn) != PMU_EVENT_CYCLES ||
+if (!(env->pmc_cyc_cnt & (1 << (sprn - SPR_POWER_PMC1 + 1))) ||
 !pmc_has_overflow_enabled(env, sprn)) {
 /* Overflow timer is not needed for this counter */
 timer_del(pmc_overflow_timer);
@@ -281,7 +192,7 @@ static void pmc_update_overflow_timer(CPUPPCState *env, int 
sprn)
 }
 
 if (env->spr[sprn] >= PMC_COUNTER_NEGATIVE_VAL) {
-timeout =  0;
+timeout = 0;
 } else {
 timeout = PMC_COUNTER_NEGATIVE_VAL - env->spr[sprn];
 }
-- 
2.33.1




[PATCH v2 2/5] target/ppc: Rewrite pmu_increment_insns

2022-01-03 Thread Daniel Henrique Barboza
From: Richard Henderson 

Use the cached pmc_ins_cnt value.  Unroll the loop over the
different PMC counters.  Treat the PMC4 run-latch specially.

Signed-off-by: Richard Henderson 
---
 target/ppc/power8-pmu.c | 78 ++---
 1 file changed, 49 insertions(+), 29 deletions(-)

diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 4fce6e8de8..8f01934c15 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -165,45 +165,65 @@ void pmu_update_summaries(CPUPPCState *env)
 
 static bool pmu_increment_insns(CPUPPCState *env, uint32_t num_insns)
 {
+target_ulong mmcr0 = env->spr[SPR_POWER_MMCR0];
+unsigned ins_cnt = env->pmc_ins_cnt;
 bool overflow_triggered = false;
-int sprn;
-
-/* PMC6 never counts instructions */
-for (sprn = SPR_POWER_PMC1; sprn <= SPR_POWER_PMC5; sprn++) {
-PMUEventType evt_type = pmc_get_event(env, sprn);
-bool insn_event = evt_type == PMU_EVENT_INSTRUCTIONS ||
-  evt_type == PMU_EVENT_INSN_RUN_LATCH;
-
-if (pmc_is_inactive(env, sprn) || !insn_event) {
-continue;
+target_ulong tmp;
+
+if (unlikely(ins_cnt & 0x1e)) {
+if (ins_cnt & (1 << 1)) {
+tmp = env->spr[SPR_POWER_PMC1];
+tmp += num_insns;
+if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMC1CE)) {
+tmp = PMC_COUNTER_NEGATIVE_VAL;
+overflow_triggered = true;
+}
+env->spr[SPR_POWER_PMC1] = tmp;
 }
 
-if (evt_type == PMU_EVENT_INSTRUCTIONS) {
-env->spr[sprn] += num_insns;
+if (ins_cnt & (1 << 2)) {
+tmp = env->spr[SPR_POWER_PMC2];
+tmp += num_insns;
+if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) {
+tmp = PMC_COUNTER_NEGATIVE_VAL;
+overflow_triggered = true;
+}
+env->spr[SPR_POWER_PMC2] = tmp;
 }
 
-if (evt_type == PMU_EVENT_INSN_RUN_LATCH &&
-env->spr[SPR_CTRL] & CTRL_RUN) {
-env->spr[sprn] += num_insns;
+if (ins_cnt & (1 << 3)) {
+tmp = env->spr[SPR_POWER_PMC3];
+tmp += num_insns;
+if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) {
+tmp = PMC_COUNTER_NEGATIVE_VAL;
+overflow_triggered = true;
+}
+env->spr[SPR_POWER_PMC3] = tmp;
 }
 
-if (env->spr[sprn] >= PMC_COUNTER_NEGATIVE_VAL &&
-pmc_has_overflow_enabled(env, sprn)) {
+if (ins_cnt & (1 << 4)) {
+target_ulong mmcr1 = env->spr[SPR_POWER_MMCR1];
+int sel = extract64(mmcr1, MMCR1_PMC4EVT_EXTR, MMCR1_EVT_SIZE);
+if (sel == 0x02 || (env->spr[SPR_CTRL] & CTRL_RUN)) {
+tmp = env->spr[SPR_POWER_PMC4];
+tmp += num_insns;
+if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) 
{
+tmp = PMC_COUNTER_NEGATIVE_VAL;
+overflow_triggered = true;
+}
+env->spr[SPR_POWER_PMC4] = tmp;
+}
+}
+}
 
+if (ins_cnt & (1 << 5)) {
+tmp = env->spr[SPR_POWER_PMC5];
+tmp += num_insns;
+if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) {
+tmp = PMC_COUNTER_NEGATIVE_VAL;
 overflow_triggered = true;
-
-/*
- * The real PMU will always trigger a counter overflow with
- * PMC_COUNTER_NEGATIVE_VAL. We don't have an easy way to
- * do that since we're counting block of instructions at
- * the end of each translation block, and we're probably
- * passing this value at this point.
- *
- * Let's write PMC_COUNTER_NEGATIVE_VAL to the overflowed
- * counter to simulate what the real hardware would do.
- */
-env->spr[sprn] = PMC_COUNTER_NEGATIVE_VAL;
 }
+env->spr[SPR_POWER_PMC5] = tmp;
 }
 
 return overflow_triggered;
-- 
2.33.1




[PATCH v2 0/5] Reorg ppc64 pmu insn counting

2022-01-03 Thread Daniel Henrique Barboza
Hi,

This is the v2 of Richard's work sent in [1]. The initial implementation
presented some issues with the event-based branch kernel tests that I
fixed in this new version. This code is now passing all EBB PPC64
tests, it makes Avocado happy and it's all contained in the C helper.

Last patch is an improvement that became natural to do after seeing
how Richard updates env->hflags in pmu_update_summaries().

Avocado test performance:

 (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv8: 
PASS (32.63 s)
 (1/1) tests/avocado/boot_linux_console.py:BootLinuxConsole.test_ppc_powernv9: 
PASS (34.16 s)

Changes from v1:
- patch 1:
  * fixed a couple of minor that was causing test failures
- patch 2 and 3: unchanged
- patch 4 (new):
  * clear HFLAGS_INSN_CNT if MMCR0_FC is set
- patch 5 (new):
  * avoid calling hreg_compute_hflags()
- v1 link: https://lists.gnu.org/archive/html/qemu-devel/2021-12/msg04013.html

[1] https://lists.gnu.org/archive/html/qemu-devel/2021-12/msg04013.html


Daniel Henrique Barboza (2):
  target/ppc: keep ins_cnt/cyc_cnt cleared if MMCR0_FC is set
  target/ppc: do not call hreg_compute_hflags() in helper_store_mmcr0()

Richard Henderson (3):
  target/ppc: Cache per-pmc insn and cycle count settings
  target/ppc: Rewrite pmu_increment_insns
  target/ppc: Use env->pnc_cyc_cnt

 target/ppc/cpu.h |   3 +
 target/ppc/cpu_init.c|   1 +
 target/ppc/helper_regs.c |   2 +-
 target/ppc/machine.c |   2 +
 target/ppc/power8-pmu.c  | 238 +--
 target/ppc/power8-pmu.h  |  14 +--
 6 files changed, 117 insertions(+), 143 deletions(-)

-- 
2.33.1




Re: [PATCH v3 1/2] linux-user: add sched_getattr support

2022-01-03 Thread Laurent Vivier

Le 03/01/2022 à 18:07, Tõnis Tiigi a écrit :

Ping Laurent. Any suggestions for the follow-up questions?

On Thu, Dec 23, 2021 at 3:00 PM Tõnis Tiigi  wrote:


On Thu, Dec 23, 2021 at 1:03 PM Laurent Vivier  wrote:


Le 23/12/2021 à 07:47, Tonis Tiigi a écrit :

Please copy here what you explain in PATCH 0 regarding this patch.
(do the same for PATCH 1)


Signed-off-by: Tonis Tiigi 
---
   linux-user/syscall.c  | 94 +++
   linux-user/syscall_defs.h | 14 ++
   2 files changed, 108 insertions(+)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f1cfcc8104..2f5a0fac5a 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -339,6 +339,12 @@ _syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned 
int, len,
   #define __NR_sys_sched_setaffinity __NR_sched_setaffinity
   _syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
 unsigned long *, user_mask_ptr);
+#define __NR_sys_sched_getattr __NR_sched_getattr
+_syscall4(int, sys_sched_getattr, pid_t, pid, struct target_sched_attr *, attr,
+  unsigned int, size, unsigned int, flags);
+#define __NR_sys_sched_setattr __NR_sched_setattr
+_syscall3(int, sys_sched_setattr, pid_t, pid, struct target_sched_attr *, attr,
+  unsigned int, flags);
   #define __NR_sys_getcpu __NR_getcpu
   _syscall3(int, sys_getcpu, unsigned *, cpu, unsigned *, node, void *, 
tcache);
   _syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
@@ -10593,6 +10599,94 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
   }
   case TARGET_NR_sched_getscheduler:
   return get_errno(sched_getscheduler(arg1));
+case TARGET_NR_sched_getattr:
+{
+struct target_sched_attr *target_scha;
+struct target_sched_attr scha;


In fact, this scha is used with the host syscall, so it must be  sched_attr.



Where do you want me to define the "host variant" of sched_attr and
with what types for the properties? Or do you want additional
typedef(where?) so the name is less confusing? All properties in this
type are fixed length and identical for all architectures.


It's better to use the host variant with the host syscall.

Normally sched_attr comes with kernel headers, so it should be available and you should not have to 
define it.


We need to define a target property because alignment also matters as the alignment for type can 
differ from an architecture to another. I agree that in most cases it should not be needed but I 
think it's cleaner like that.


so for this part, only replace "struct target_sched_attr scha;" by "struct sched_att 
scha;"







+if (arg2 == 0) {
+return -TARGET_EINVAL;
+}
+if (arg3 > sizeof(scha)) {
+arg3 = sizeof(scha);
+}
+ret = get_errno(sys_sched_getattr(arg1, , arg3, arg4));
+if (!is_error(ret)) {
+target_scha = lock_user(VERIFY_WRITE, arg2, arg3, 0);
+if (!target_scha) {
+return -TARGET_EFAULT;
+}
+target_scha->size = tswap32(scha.size);
+target_scha->sched_policy = tswap32(scha.sched_policy);
+target_scha->sched_flags = tswap64(scha.sched_flags);
+target_scha->sched_nice = tswap32(scha.sched_nice);
+target_scha->sched_priority = tswap32(scha.sched_priority);
+target_scha->sched_runtime = tswap64(scha.sched_runtime);
+target_scha->sched_deadline = tswap64(scha.sched_deadline);
+target_scha->sched_period = tswap64(scha.sched_period);
+if (scha.size > offsetof(struct target_sched_attr, 
sched_util_min)) {
+target_scha->sched_util_min = tswap32(scha.sched_util_min);
+target_scha->sched_util_max = tswap32(scha.sched_util_max);
+}
+unlock_user(target_scha, arg2, arg3);
+}
+return ret;
+}
+case TARGET_NR_sched_setattr:
+{
+struct target_sched_attr *target_scha;
+struct target_sched_attr scha;


scha is sched_attr as it is used with the host syscall.



+if (arg2 == 0) {
+return -TARGET_EINVAL;
+}
+uint32_t size;


QEMU coding style doesn't allow to mix declarations and statements.


+if (get_user_u32(size, arg2)) {
+return -TARGET_EFAULT;
+}
+if (!size) {
+size = offsetof(struct target_sched_attr, sched_util_min);
+}
+if (size < offsetof(struct target_sched_attr, sched_util_min)) {
+if (put_user_u32(sizeof(struct target_sched_attr), arg2)) {
+return -TARGET_EFAULT;
+}
+return -TARGET_E2BIG;
+}
+
+if (size > 

Re: [PATCH 1/2] linux-user/ppc: deliver SIGTRAP on POWERPC_EXCP_TRAP

2022-01-03 Thread Richard Henderson

On 1/3/22 10:12 AM, Matheus K. Ferst wrote:

On 03/01/2022 14:50, Richard Henderson wrote:

On 1/3/22 8:56 AM, matheus.fe...@eldorado.org.br wrote:

From: Matheus Ferst 

Handle POWERPC_EXCP_TRAP in cpu_loop to deliver SIGTRAP on tw[i]/td[i].
The si_code comes from do_program_check in the kernel source file
arch/powerpc/kernel/traps.c

Signed-off-by: Matheus Ferst 
---
  linux-user/ppc/cpu_loop.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/linux-user/ppc/cpu_loop.c b/linux-user/ppc/cpu_loop.c
index 30c82f2354..8fbaa772dc 100644
--- a/linux-user/ppc/cpu_loop.c
+++ b/linux-user/ppc/cpu_loop.c
@@ -242,7 +242,9 @@ void cpu_loop(CPUPPCState *env)
  }
  break;
  case POWERPC_EXCP_TRAP:
-    cpu_abort(cs, "Tried to call a TRAP\n");
+    info.si_signo = TARGET_SIGTRAP;
+    info.si_errno = 0;
+    info.si_code = TARGET_TRAP_BRKPT;


You're missing the address, which should be nip.

https://github.com/torvalds/linux/blob/master/arch/powerpc/kernel/traps.c#L1503


After this switch-case, there is a

info._sifields._sigfault._addr = env->nip;

Is there anything else to be set?


Nope, sorry I missed that.

r~



Re: [PATCH v2 0/5] Re-write PPC64 PMU instruction count using TCG Ops

2022-01-03 Thread Daniel Henrique Barboza




On 1/3/22 03:46, Cédric Le Goater wrote:

On 12/23/21 21:18, Daniel Henrique Barboza wrote:

Hi,

In this version the tedious repetition was taken away from the
code by using a helper that increments the PMCs based on specified
conditions.

As far as Avocado test goes, the performance is the same as the previous
version. All PMU-EBB kernel selftests are also passing. Basically we have
the same benefits from v1 but 150+ lines shorter.

changes from v1:
- former patches 2-6: removed
- new patch 2:
   * added inc_spr_if_cond() helper
- new patch 3:
   * add insn count for PMCs 1-4
- patch 4 (former 7):
   * use a loop to reduce code repetition when checking for counter
overflows
- v1 link: https://lists.gnu.org/archive/html/qemu-devel/2021-12/msg03871.html


I understand that you are going to rebase on top of Richard's patchset.
and so this series is now obsolete ?


Yes it is. I'll post a new version of Richard's patchset shortly.


Daniel



Thanks,

C.





Re: [PATCH 1/2] linux-user/ppc: deliver SIGTRAP on POWERPC_EXCP_TRAP

2022-01-03 Thread Matheus K. Ferst

On 03/01/2022 14:50, Richard Henderson wrote:

On 1/3/22 8:56 AM, matheus.fe...@eldorado.org.br wrote:

From: Matheus Ferst 

Handle POWERPC_EXCP_TRAP in cpu_loop to deliver SIGTRAP on tw[i]/td[i].
The si_code comes from do_program_check in the kernel source file
arch/powerpc/kernel/traps.c

Signed-off-by: Matheus Ferst 
---
  linux-user/ppc/cpu_loop.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/linux-user/ppc/cpu_loop.c b/linux-user/ppc/cpu_loop.c
index 30c82f2354..8fbaa772dc 100644
--- a/linux-user/ppc/cpu_loop.c
+++ b/linux-user/ppc/cpu_loop.c
@@ -242,7 +242,9 @@ void cpu_loop(CPUPPCState *env)
  }
  break;
  case POWERPC_EXCP_TRAP:
-    cpu_abort(cs, "Tried to call a TRAP\n");
+    info.si_signo = TARGET_SIGTRAP;
+    info.si_errno = 0;
+    info.si_code = TARGET_TRAP_BRKPT;


You're missing the address, which should be nip.

https://github.com/torvalds/linux/blob/master/arch/powerpc/kernel/traps.c#L1503 



After this switch-case, there is a

info._sifields._sigfault._addr = env->nip;

Is there anything else to be set?



Please use force_sig_fault.  (I have a pending patch set to convert all 
other instances;

hopefully that can be merged soon...)



I'll send v2 with a Based-on

Thanks,
Matheus K. Ferst
Instituto de Pesquisas ELDORADO 
Analista de Software
Aviso Legal - Disclaimer 



Re: [PATCH 0/3] Reorg ppc64 pmu insn counting

2022-01-03 Thread Daniel Henrique Barboza




On 1/3/22 12:07, Alex Bennée wrote:


Daniel Henrique Barboza  writes:


On 12/23/21 00:01, Richard Henderson wrote:

In contrast to Daniel's version, the code stays in power8-pmu.c,
but is better organized to not take so much overhead.
Before:
  32.97%  qemu-system-ppc  qemu-system-ppc64   [.] pmc_get_event
  20.22%  qemu-system-ppc  qemu-system-ppc64   [.] helper_insns_inc
   4.52%  qemu-system-ppc  qemu-system-ppc64   [.] hreg_compute_hflags_value
   3.30%  qemu-system-ppc  qemu-system-ppc64   [.] helper_lookup_tb_ptr
   2.68%  qemu-system-ppc  qemu-system-ppc64   [.] tcg_gen_code
   2.28%  qemu-system-ppc  qemu-system-ppc64   [.] cpu_exec
   1.84%  qemu-system-ppc  qemu-system-ppc64   [.] pmu_insn_cnt_enabled
After:
   8.42%  qemu-system-ppc  qemu-system-ppc64   [.]
hreg_compute_hflags_value
   6.65%  qemu-system-ppc  qemu-system-ppc64   [.] cpu_exec
   6.63%  qemu-system-ppc  qemu-system-ppc64   [.] helper_insns_inc



Thanks for looking this up. I had no idea the original C code was that slow.





With that in mind I decided to post a new version of my TCG rework, with less 
repetition and
a bit more concise, to have an alternative that can be used upstream to fix the 
Avocado tests.
Meanwhile I'll see if I can get your reorg working with all EBB tests we need. 
All things
equal - similar performance, all EBB tests passing - I'd rather stay with your 
C code than my
TCG rework since yours doesn't rely on TCG Ops knowledge to maintain
it.


Reading this series did make me wonder if we need a more generic service
from the TCG for helping with "internal" instrumentation needed for
things like decent PMU emulation. We haven't gone as much for it in ARM
yet but it would be nice to. It would be even nicer if such a facility
could be used by stuff like icount as well so we don't end up doing the
same thing twice.


Back in May 2021 when I first starting working on this code I tried to base 
myself in the
ARM PMU code. In fact, the cycle and insn calculation done in the very first 
version of
this work was based on what ARM does in target/arm/helper.c, cycles_get_count() 
and
instructions_get_count(). The cycle calculation got simplified because our 
PPC64 CPU
has a 1Ghz clock so it's easier to just consider 1ns = 1 cycle.

For instruction count, aside from my 2-3 weeks of spectacular failures trying 
to count
instructions inside translate.c, I also looked into how TCG plugins work and 
tried to do
something similar to what plugin_gen_tb_end() does at the end of the 
translator_loop()
in accel/tcg/translator.c. For some reason I wasn't able to replicate the same 
behavior
that I would have if I used the TCG plugin framework in the 'canonical' way.

I ended up doing something similar to what instructions_get_count() from ARM 
does, which
relies on icount. Richard then aided me in figuring out that I could count 
instructions
directly by tapping into the end of each TB.

So, for a generic service of sorts I believe it would be nice to re-use the TCG 
plugins
API in the internal instrumentation (I tried it once, failed, not sure if I 
messed up
or it's not possible ATM). That would be a good start to try to get all this 
logic in a
generic code for internal translate code to use.



Thanks,


Daniel








Thanks,


Daniel


[1] 
https://github.com/torvalds/linux/tree/master/tools/testing/selftests/powerpc/pmu/ebb
[2] https://lists.gnu.org/archive/html/qemu-devel/2021-12/msg00073.html


r~
Richard Henderson (3):
target/ppc: Cache per-pmc insn and cycle count settings
target/ppc: Rewrite pmu_increment_insns
target/ppc: Use env->pnc_cyc_cnt
   target/ppc/cpu.h |   3 +
   target/ppc/power8-pmu.h  |  14 +--
   target/ppc/cpu_init.c|   1 +
   target/ppc/helper_regs.c |   2 +-
   target/ppc/machine.c |   2 +
   target/ppc/power8-pmu.c  | 230 ---
   6 files changed, 108 insertions(+), 144 deletions(-)








Re: [PATCH] hw/arm/virt: KVM: Enable PAuth when supported by the host

2022-01-03 Thread Marc Zyngier
Hi Andrew,

On Mon, 03 Jan 2022 13:46:01 +,
Andrew Jones  wrote:
> 
> Hi Marc,
> 
> On Tue, Dec 28, 2021 at 06:23:47PM +, Marc Zyngier wrote:
> > Add basic support for Pointer Authentication when running a KVM
> > guest and that the host supports it, loosely based on the SVE
> > support.
> > 
> > Although the feature is enabled by default when the host advertises
> > it, it is possible to disable it by setting the 'pauth=off' CPU
> > property.
> > 
> > Tested on an Apple M1 running 5.16-rc6.
> > 
> > Cc: Eric Auger 
> > Cc: Andrew Jones 
> > Cc: Richard Henderson 
> > Cc: Peter Maydell 
> > Signed-off-by: Marc Zyngier 
> > ---
> >  docs/system/arm/cpu-features.rst |  5 +
> >  target/arm/cpu.c |  1 +
> >  target/arm/cpu.h |  1 +
> >  target/arm/cpu64.c   | 36 
> >  target/arm/kvm.c | 13 
> >  target/arm/kvm64.c   | 10 +
> >  target/arm/kvm_arm.h |  7 +++
> >  7 files changed, 73 insertions(+)
> > 
> > diff --git a/docs/system/arm/cpu-features.rst 
> > b/docs/system/arm/cpu-features.rst
> > index 584eb17097..c9e39546a5 100644
> > --- a/docs/system/arm/cpu-features.rst
> > +++ b/docs/system/arm/cpu-features.rst
> > @@ -211,6 +211,11 @@ the list of KVM VCPU features and their descriptions.
> > influence the guest scheduler behavior and/or be
> > exposed to the guest userspace.
> >  
> > +  pauthEnable or disable ``FEAT_Pauth``, pointer
> > +   authentication.  By default, the feature is 
> > enabled
> > +   with ``-cpu host`` if supported by both the host
> > +   kernel and the hardware.
> > +
> 
> Thanks for considering a documentation update. In this case, though, I
> think we should delete the "TCG VCPU Features" pauth paragraph, rather
> than add a new "KVM VCPU Features" pauth paragraph. We don't need to
> document each CPU feature. We just document complex ones, like sve*,
> KVM specific ones (kvm-*), and TCG specific ones (now only pauth-impdef).

Sure, works for me. Do we need to keep a trace of the available
options? I'm not sure how a user is supposed to find out about those
(I always end-up grepping through the code base, and something tells
me I'm doing it wrong...). The QMP stuff flies way over my head.

> >  TCG VCPU Features
> >  =
> >  
> > diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> > index a211804fd3..68b09cbc6a 100644
> > --- a/target/arm/cpu.c
> > +++ b/target/arm/cpu.c
> > @@ -2091,6 +2091,7 @@ static void arm_host_initfn(Object *obj)
> >  kvm_arm_set_cpu_features_from_host(cpu);
> >  if (arm_feature(>env, ARM_FEATURE_AARCH64)) {
> >  aarch64_add_sve_properties(obj);
> > +aarch64_add_pauth_properties(obj);
> >  }
> >  #else
> >  hvf_arm_set_cpu_features_from_host(cpu);
> > diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> > index e33f37b70a..c6a4d50e82 100644
> > --- a/target/arm/cpu.h
> > +++ b/target/arm/cpu.h
> > @@ -1076,6 +1076,7 @@ void aarch64_sve_narrow_vq(CPUARMState *env, unsigned 
> > vq);
> >  void aarch64_sve_change_el(CPUARMState *env, int old_el,
> > int new_el, bool el0_a64);
> >  void aarch64_add_sve_properties(Object *obj);
> > +void aarch64_add_pauth_properties(Object *obj);
> >  
> >  /*
> >   * SVE registers are encoded in KVM's memory in an endianness-invariant 
> > format.
> > diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> > index 15245a60a8..305c0e19fe 100644
> > --- a/target/arm/cpu64.c
> > +++ b/target/arm/cpu64.c
> > @@ -625,6 +625,42 @@ void aarch64_add_sve_properties(Object *obj)
> >  #endif
> >  }
> >  
> > +static bool cpu_arm_get_pauth(Object *obj, Error **errp)
> > +{
> > +ARMCPU *cpu = ARM_CPU(obj);
> > +return cpu_isar_feature(aa64_pauth, cpu);
> > +}
> > +
> > +static void cpu_arm_set_pauth(Object *obj, bool value, Error **errp)
> > +{
> > +ARMCPU *cpu = ARM_CPU(obj);
> > +uint64_t t;
> > +
> > +if (value) {
> > +if (!kvm_arm_pauth_supported()) {
> > +error_setg(errp, "'pauth' feature not supported by KVM on this 
> > host");
> > +}
> > +
> > +return;
> > +}
> > +
> > +/*
> > + * If the host supports PAuth, we only end-up here if the user has
> > + * disabled the support, and value is false.
> > + */
> > +t = cpu->isar.id_aa64isar1;
> > +t = FIELD_DP64(t, ID_AA64ISAR1, APA, value);
> > +t = FIELD_DP64(t, ID_AA64ISAR1, GPA, value);
> > +t = FIELD_DP64(t, ID_AA64ISAR1, API, value);
> > +t = FIELD_DP64(t, ID_AA64ISAR1, GPI, value);
> > +cpu->isar.id_aa64isar1 = t;
> > +}
> > +
> > +void aarch64_add_pauth_properties(Object *obj)
> > +{
> > +object_property_add_bool(obj, "pauth", cpu_arm_get_pauth, 
> > cpu_arm_set_pauth);
> > +}
> 
> I think we should try to merge as 

[PATCH v2] hw/arm/virt: KVM: Enable PAuth when supported by the host

2022-01-03 Thread Marc Zyngier
Add basic support for Pointer Authentication when running a KVM
guest and that the host supports it, loosely based on the SVE
support.

Although the feature is enabled by default when the host advertises
it, it is possible to disable it by setting the 'pauth=off' CPU
property. The 'pauth' comment is removed from cpu-features.rst,
as it is now common to both TCG and KVM.

Tested on an Apple M1 running 5.16-rc6.

Cc: Eric Auger 
Cc: Andrew Jones 
Cc: Richard Henderson 
Cc: Peter Maydell 
Signed-off-by: Marc Zyngier 
---
* From v1:
  - Drop 'pauth' documentation
  - Make the TCG path common to both TCG and KVM
  - Some tidying up

 docs/system/arm/cpu-features.rst |  4 
 target/arm/cpu.c | 14 --
 target/arm/cpu.h |  1 +
 target/arm/cpu64.c   | 33 
 target/arm/kvm64.c   | 21 
 5 files changed, 55 insertions(+), 18 deletions(-)

diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
index 584eb17097..3e626c4b68 100644
--- a/docs/system/arm/cpu-features.rst
+++ b/docs/system/arm/cpu-features.rst
@@ -217,10 +217,6 @@ TCG VCPU Features
 TCG VCPU features are CPU features that are specific to TCG.
 Below is the list of TCG VCPU features and their descriptions.
 
-  pauthEnable or disable ``FEAT_Pauth``, pointer
-   authentication.  By default, the feature is
-   enabled with ``-cpu max``.
-
   pauth-impdef When ``FEAT_Pauth`` is enabled, either the
*impdef* (Implementation Defined) algorithm
is enabled or the *architected* QARMA algorithm
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index a211804fd3..d96cc4ef18 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1380,18 +1380,11 @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error 
**errp)
 return;
 }
 
-/*
- * KVM does not support modifications to this feature.
- * We have not registered the cpu properties when KVM
- * is in use, so the user will not be able to set them.
- */
-if (!kvm_enabled()) {
-arm_cpu_pauth_finalize(cpu, _err);
-if (local_err != NULL) {
+   arm_cpu_pauth_finalize(cpu, _err);
+   if (local_err != NULL) {
 error_propagate(errp, local_err);
 return;
-}
-}
+   }
 }
 
 if (kvm_enabled()) {
@@ -2091,6 +2084,7 @@ static void arm_host_initfn(Object *obj)
 kvm_arm_set_cpu_features_from_host(cpu);
 if (arm_feature(>env, ARM_FEATURE_AARCH64)) {
 aarch64_add_sve_properties(obj);
+aarch64_add_pauth_properties(obj);
 }
 #else
 hvf_arm_set_cpu_features_from_host(cpu);
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index e33f37b70a..c6a4d50e82 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1076,6 +1076,7 @@ void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq);
 void aarch64_sve_change_el(CPUARMState *env, int old_el,
int new_el, bool el0_a64);
 void aarch64_add_sve_properties(Object *obj);
+void aarch64_add_pauth_properties(Object *obj);
 
 /*
  * SVE registers are encoded in KVM's memory in an endianness-invariant format.
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 15245a60a8..d5c0bce1c4 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -630,6 +630,17 @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
 int arch_val = 0, impdef_val = 0;
 uint64_t t;
 
+if (kvm_enabled()) {
+if (cpu->prop_pauth) {
+if (!cpu_isar_feature(aa64_pauth, cpu)) {
+error_setg(errp, "'pauth' feature not supported by KVM on this 
host");
+}
+
+return;
+}
+/* Fall through to disable PAuth */
+}
+
 /* TODO: Handle HaveEnhancedPAC, HaveEnhancedPAC2, HaveFPAC. */
 if (cpu->prop_pauth) {
 if (cpu->prop_pauth_impdef) {
@@ -655,6 +666,23 @@ static Property arm_cpu_pauth_property =
 static Property arm_cpu_pauth_impdef_property =
 DEFINE_PROP_BOOL("pauth-impdef", ARMCPU, prop_pauth_impdef, false);
 
+void aarch64_add_pauth_properties(Object *obj)
+{
+ARMCPU *cpu = ARM_CPU(obj);
+
+/* Default to PAUTH on, with the architected algorithm on TCG. */
+qdev_property_add_static(DEVICE(obj), _cpu_pauth_property);
+if (kvm_enabled()) {
+/*
+ * Mirror PAuth support from the probed sysregs back into the
+ * property for KVM. Is it just a bit backward? Yes it is!
+ */
+cpu->prop_pauth = cpu_isar_feature(aa64_pauth, cpu);
+} else {
+qdev_property_add_static(DEVICE(obj), _cpu_pauth_impdef_property);
+}
+}
+
 /* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
  * otherwise, a CPU with as many features enabled as our emulation supports.
  * 

Re: [PATCH 2/2] tests/tcg/ppc64le: change signal_save_restore_xer to use SIGTRAP

2022-01-03 Thread Richard Henderson

On 1/3/22 8:56 AM, matheus.fe...@eldorado.org.br wrote:

From: Matheus Ferst

Now that linux-user delivers the signal on tw, we can change
signal_save_restore_xer to use SIGTRAP instead of SIGILL.

Suggested-by: Richard Henderson
Signed-off-by: Matheus Ferst
---
  tests/tcg/ppc64le/signal_save_restore_xer.c | 8 
  1 file changed, 4 insertions(+), 4 deletions(-)


Reviewed-by: Richard Henderson 

r~



  1   2   >