[Qemu-devel] [PULL 20/49] hw/ppc: Drop useless CONFIG_KVM ifdefery

2019-07-01 Thread David Gibson
From: Greg Kurz 

kvmppc_set_interrupt() has a stub that does nothing when CONFIG_KVM is
not defined.

Signed-off-by: Greg Kurz 
Message-Id: <156051055182.224162.15842560287892241124.st...@bahia.lan>
Signed-off-by: David Gibson 
---
 hw/ppc/ppc.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 9d91e8481b..288196dfa6 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -80,9 +80,7 @@ void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level)
 }
 
 if (old_pending != env->pending_interrupts) {
-#ifdef CONFIG_KVM
 kvmppc_set_interrupt(cpu, n_IRQ, level);
-#endif
 }
 
 
-- 
2.21.0




[Qemu-devel] [PULL 35/49] target/ppc: introduce GEN_VSX_HELPER_X1 macro to fpu_helper.c

2019-07-01 Thread David Gibson
From: Mark Cave-Ayland 

Rather than perform the VSR register decoding within the helper itself,
introduce a new GEN_VSX_HELPER_X1 macro which performs the decode based
upon xB at translation time.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Richard Henderson 
Message-Id: <20190616123751.781-10-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: David Gibson 
---
 target/ppc/fpu_helper.c |  6 ++
 target/ppc/helper.h |  8 
 target/ppc/translate/vsx-impl.inc.c | 24 
 3 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 902d63b139..5fb43b619e 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -2236,9 +2236,8 @@ VSX_TDIV(xvtdivsp, 4, float32, VsrW(i), -126, 127, 23)
  *   nbits - number of fraction bits
  */
 #define VSX_TSQRT(op, nels, tp, fld, emin, nbits)   \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, uint32_t opcode, ppc_vsr_t *xb)  \
 {   \
-ppc_vsr_t *xb = &env->vsr[xB(opcode)];  \
 int i;  \
 int fe_flag = 0;\
 int fg_flag = 0;\
@@ -3258,9 +3257,8 @@ VSX_TEST_DC(xvtstdcsp, 4, xB(opcode), float32, VsrW(i), 
VsrW(i), UINT32_MAX, 0)
 VSX_TEST_DC(xststdcdp, 1, xB(opcode), float64, VsrD(0), VsrD(0), 0, 1)
 VSX_TEST_DC(xststdcqp, 1, (rB(opcode) + 32), float128, f128, VsrD(0), 0, 1)
 
-void helper_xststdcsp(CPUPPCState *env, uint32_t opcode)
+void helper_xststdcsp(CPUPPCState *env, uint32_t opcode, ppc_vsr_t *xb)
 {
-ppc_vsr_t *xb = &env->vsr[xB(opcode)];
 uint32_t dcmx, sign, exp;
 uint32_t cc, match = 0, not_sp = 0;
 
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 0ab1ef2aee..a8886c56ad 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -376,7 +376,7 @@ DEF_HELPER_3(xsredp, void, env, vsr, vsr)
 DEF_HELPER_3(xssqrtdp, void, env, vsr, vsr)
 DEF_HELPER_3(xsrsqrtedp, void, env, vsr, vsr)
 DEF_HELPER_4(xstdivdp, void, env, i32, vsr, vsr)
-DEF_HELPER_2(xstsqrtdp, void, env, i32)
+DEF_HELPER_3(xstsqrtdp, void, env, i32, vsr)
 DEF_HELPER_4(xsmaddadp, void, env, vsr, vsr, vsr)
 DEF_HELPER_4(xsmaddmdp, void, env, vsr, vsr, vsr)
 DEF_HELPER_4(xsmsubadp, void, env, vsr, vsr, vsr)
@@ -423,7 +423,7 @@ DEF_HELPER_3(xscvuxdsp, void, env, vsr, vsr)
 DEF_HELPER_3(xscvsxdsp, void, env, vsr, vsr)
 DEF_HELPER_2(xscvudqp, void, env, i32)
 DEF_HELPER_3(xscvuxddp, void, env, vsr, vsr)
-DEF_HELPER_2(xststdcsp, void, env, i32)
+DEF_HELPER_3(xststdcsp, void, env, i32, vsr)
 DEF_HELPER_2(xststdcdp, void, env, i32)
 DEF_HELPER_2(xststdcqp, void, env, i32)
 DEF_HELPER_3(xsrdpi, void, env, vsr, vsr)
@@ -461,7 +461,7 @@ DEF_HELPER_3(xvredp, void, env, vsr, vsr)
 DEF_HELPER_3(xvsqrtdp, void, env, vsr, vsr)
 DEF_HELPER_3(xvrsqrtedp, void, env, vsr, vsr)
 DEF_HELPER_4(xvtdivdp, void, env, i32, vsr, vsr)
-DEF_HELPER_2(xvtsqrtdp, void, env, i32)
+DEF_HELPER_3(xvtsqrtdp, void, env, i32, vsr)
 DEF_HELPER_4(xvmaddadp, void, env, vsr, vsr, vsr)
 DEF_HELPER_4(xvmaddmdp, void, env, vsr, vsr, vsr)
 DEF_HELPER_4(xvmsubadp, void, env, vsr, vsr, vsr)
@@ -499,7 +499,7 @@ DEF_HELPER_3(xvresp, void, env, vsr, vsr)
 DEF_HELPER_3(xvsqrtsp, void, env, vsr, vsr)
 DEF_HELPER_3(xvrsqrtesp, void, env, vsr, vsr)
 DEF_HELPER_4(xvtdivsp, void, env, i32, vsr, vsr)
-DEF_HELPER_2(xvtsqrtsp, void, env, i32)
+DEF_HELPER_3(xvtsqrtsp, void, env, i32, vsr)
 DEF_HELPER_4(xvmaddasp, void, env, vsr, vsr, vsr)
 DEF_HELPER_4(xvmaddmsp, void, env, vsr, vsr, vsr)
 DEF_HELPER_4(xvmsubasp, void, env, vsr, vsr, vsr)
diff --git a/target/ppc/translate/vsx-impl.inc.c 
b/target/ppc/translate/vsx-impl.inc.c
index 9b4603ac33..8af093d256 100644
--- a/target/ppc/translate/vsx-impl.inc.c
+++ b/target/ppc/translate/vsx-impl.inc.c
@@ -1079,6 +1079,22 @@ static void gen_##name(DisasContext *ctx)
 \
 tcg_temp_free_ptr(xb);\
 }
 
+#define GEN_VSX_HELPER_X1(name, op1, op2, inval, type)\
+static void gen_##name(DisasContext *ctx) \
+{ \
+TCGv_i32 opc; \
+TCGv_ptr xb;  \
+if (unlikely(!ctx->vsx_enabled)) {\
+gen_exception(ctx, POWERPC_EXCP_VSXU);\
+return;   \
+} \
+opc = tcg_const

[Qemu-devel] [PULL 37/49] target/ppc: introduce GEN_VSX_HELPER_R2 macro to fpu_helper.c

2019-07-01 Thread David Gibson
From: Mark Cave-Ayland 

Rather than perform the VSR register decoding within the helper itself,
introduce a new GEN_VSX_HELPER_R2 macro which performs the decode based
upon rD and rB at translation time.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Richard Henderson 
Message-Id: <20190616123751.781-12-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: David Gibson 
---
 target/ppc/fpu_helper.c | 30 +--
 target/ppc/helper.h | 20 +++
 target/ppc/translate/vsx-impl.inc.c | 38 +
 3 files changed, 50 insertions(+), 38 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 44970ebec9..cb593517ae 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -2808,10 +2808,9 @@ VSX_CVT_FP_TO_FP(xvcvspdp, 2, float32, float64, VsrW(2 * 
i), VsrD(i), 0)
  *   sfprf - set FPRF
  */
 #define VSX_CVT_FP_TO_FP_VECTOR(op, nels, stp, ttp, sfld, tfld, sfprf)\
-void helper_##op(CPUPPCState *env, uint32_t opcode)   \
+void helper_##op(CPUPPCState *env, uint32_t opcode,   \
+ ppc_vsr_t *xt, ppc_vsr_t *xb)\
 {   \
-ppc_vsr_t *xt = &env->vsr[rD(opcode) + 32]; \
-ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32]; \
 ppc_vsr_t t = *xt;  \
 int i;  \
 \
@@ -2975,10 +2974,9 @@ VSX_CVT_FP_TO_INT(xvcvspuxws, 4, float32, uint32, 
VsrW(i), VsrW(i), 0U)
  *   rnan  - resulting NaN
  */
 #define VSX_CVT_FP_TO_INT_VECTOR(op, stp, ttp, sfld, tfld, rnan) \
-void helper_##op(CPUPPCState *env, uint32_t opcode)  \
+void helper_##op(CPUPPCState *env, uint32_t opcode,  \
+ ppc_vsr_t *xt, ppc_vsr_t *xb)   \
 {\
-ppc_vsr_t *xt = &env->vsr[rD(opcode) + 32];  \
-ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32];  \
 ppc_vsr_t t = { };   \
  \
 t.tfld = stp##_to_##ttp##_round_to_zero(xb->sfld, &env->fp_status);  \
@@ -3052,10 +3050,9 @@ VSX_CVT_INT_TO_FP(xvcvuxwsp, 4, uint32, float32, 
VsrW(i), VsrW(i), 0, 0)
  *   tfld  - target vsr_t field
  */
 #define VSX_CVT_INT_TO_FP_VECTOR(op, stp, ttp, sfld, tfld)  \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, uint32_t opcode, \
+ ppc_vsr_t *xt, ppc_vsr_t *xb)  \
 {   \
-ppc_vsr_t *xt = &env->vsr[rD(opcode) + 32]; \
-ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32]; \
 ppc_vsr_t t = *xt;  \
 \
 t.tfld = stp##_to_##ttp(xb->sfld, &env->fp_status); \
@@ -3278,10 +3275,9 @@ void helper_xststdcsp(CPUPPCState *env, uint32_t opcode, 
ppc_vsr_t *xb)
 env->crf[BF(opcode)] = cc;
 }
 
-void helper_xsrqpi(CPUPPCState *env, uint32_t opcode)
+void helper_xsrqpi(CPUPPCState *env, uint32_t opcode,
+   ppc_vsr_t *xt, ppc_vsr_t *xb)
 {
-ppc_vsr_t *xt = &env->vsr[rD(opcode) + 32];
-ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32];
 ppc_vsr_t t = { };
 uint8_t r = Rrm(opcode);
 uint8_t ex = Rc(opcode);
@@ -3336,10 +3332,9 @@ void helper_xsrqpi(CPUPPCState *env, uint32_t opcode)
 *xt = t;
 }
 
-void helper_xsrqpxp(CPUPPCState *env, uint32_t opcode)
+void helper_xsrqpxp(CPUPPCState *env, uint32_t opcode,
+ppc_vsr_t *xt, ppc_vsr_t *xb)
 {
-ppc_vsr_t *xt = &env->vsr[rD(opcode) + 32];
-ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32];
 ppc_vsr_t t = { };
 uint8_t r = Rrm(opcode);
 uint8_t rmc = RMC(opcode);
@@ -3391,10 +3386,9 @@ void helper_xsrqpxp(CPUPPCState *env, uint32_t opcode)
 do_float_check_status(env, GETPC());
 }
 
-void helper_xssqrtqp(CPUPPCState *env, uint32_t opcode)
+void helper_xssqrtqp(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xt, ppc_vsr_t *xb)
 {
-ppc_vsr_t *xt = &env->vsr[rD(opcode) + 32];
-ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32];
 ppc_vsr_t t = { };
 float_status tstat;
 
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 9134da9cbb..2e0646f5eb 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -402,16 +40

[Qemu-devel] [PULL 48/49] ppc/xive: Fix TM_PULL_POOL_CTX special operation

2019-07-01 Thread David Gibson
From: Cédric Le Goater 

When a CPU is reseted, the hypervisor (Linux or OPAL) invalidates the
POOL interrupt context of a CPU with this special command. It returns
the POOL CAM line value and resets the VP bit.

Fixes: 4836b45510aa ("ppc/xive: activate HV support")
Signed-off-by: Cédric Le Goater 
Message-Id: <20190630204601.30574-5-...@kaod.org>
Signed-off-by: David Gibson 
---
 hw/intc/xive.c | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 534f56f86b..cf77bdb7d3 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -132,6 +132,11 @@ static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t 
ring, uint8_t cppr)
 xive_tctx_notify(tctx, ring);
 }
 
+static inline uint32_t xive_tctx_word2(uint8_t *ring)
+{
+return *((uint32_t *) &ring[TM_WORD2]);
+}
+
 /*
  * XIVE Thread Interrupt Management Area (TIMA)
  */
@@ -150,11 +155,12 @@ static uint64_t xive_tm_ack_hv_reg(XiveTCTX *tctx, hwaddr 
offset, unsigned size)
 static uint64_t xive_tm_pull_pool_ctx(XiveTCTX *tctx, hwaddr offset,
   unsigned size)
 {
-uint64_t ret;
+uint32_t qw2w2_prev = xive_tctx_word2(&tctx->regs[TM_QW2_HV_POOL]);
+uint32_t qw2w2;
 
-ret = tctx->regs[TM_QW2_HV_POOL + TM_WORD2] & TM_QW2W2_POOL_CAM;
-tctx->regs[TM_QW2_HV_POOL + TM_WORD2] &= ~TM_QW2W2_POOL_CAM;
-return ret;
+qw2w2 = xive_set_field32(TM_QW2W2_VP, qw2w2_prev, 0);
+memcpy(&tctx->regs[TM_QW2_HV_POOL + TM_WORD2], &qw2w2, 4);
+return qw2w2;
 }
 
 static void xive_tm_vt_push(XiveTCTX *tctx, hwaddr offset,
@@ -484,11 +490,6 @@ const MemoryRegionOps xive_tm_ops = {
 },
 };
 
-static inline uint32_t xive_tctx_word2(uint8_t *ring)
-{
-return *((uint32_t *) &ring[TM_WORD2]);
-}
-
 static char *xive_tctx_ring_print(uint8_t *ring)
 {
 uint32_t w2 = xive_tctx_word2(ring);
-- 
2.21.0




[Qemu-devel] [PULL 45/49] ppc/xive: Force the Physical CAM line value to group mode

2019-07-01 Thread David Gibson
From: Cédric Le Goater 

When an interrupt needs to be delivered, the XIVE interrupt controller
presenter scans the CAM lines of the thread interrupt contexts of the
HW threads of the chip to find a matching vCPU. The interrupt context
is composed of 4 different sets of registers: Physical, HV, OS and
User.

The encoding of the Physical CAM line depends on the mode in which the
interrupt controller is operating: CAM mode or block group mode.
Block group mode being the default configuration today on POWER9 and
the only one available on the next POWER10 generation, enforce this
encoding in the Physical CAM line :

chip << 19 | 000 0 0001 thread (7Bit)

It fits the overall encoding of the NVT ids and simplifies the matching
algorithm in the presenter.

Fixes: d514c48d41fb ("ppc/xive: hardwire the Physical CAM line of the thread 
context")
Signed-off-by: Cédric Le Goater 
Message-Id: <20190630204601.30574-2-...@kaod.org>
Signed-off-by: David Gibson 
---
 hw/intc/xive.c | 21 +
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 6250c0414d..3b1f9520ae 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1229,27 +1229,16 @@ XiveTCTX *xive_router_get_tctx(XiveRouter *xrtr, 
CPUState *cs)
 }
 
 /*
- * By default on P9, the HW CAM line (23bits) is hardwired to :
+ * Encode the HW CAM line in the block group mode format :
  *
- *   0x000||0b1||4Bit chip number||7Bit Thread number.
- *
- * When the block grouping is enabled, the CAM line is changed to :
- *
- *   4Bit chip number||0x001||7Bit Thread number.
+ *   chip << 19 | 000 0 0001 thread (7Bit)
  */
-static uint32_t hw_cam_line(uint8_t chip_id, uint8_t tid)
-{
-return 1 << 11 | (chip_id & 0xf) << 7 | (tid & 0x7f);
-}
-
-static bool xive_presenter_tctx_match_hw(XiveTCTX *tctx,
- uint8_t nvt_blk, uint32_t nvt_idx)
+static uint32_t xive_tctx_hw_cam_line(XiveTCTX *tctx)
 {
 CPUPPCState *env = &POWERPC_CPU(tctx->cs)->env;
 uint32_t pir = env->spr_cb[SPR_PIR].default_value;
 
-return hw_cam_line((pir >> 8) & 0xf, pir & 0x7f) ==
-hw_cam_line(nvt_blk, nvt_idx);
+return xive_nvt_cam_line((pir >> 8) & 0xf, 1 << 7 | (pir & 0x7f));
 }
 
 /*
@@ -1285,7 +1274,7 @@ static int xive_presenter_tctx_match(XiveTCTX *tctx, 
uint8_t format,
 
 /* PHYS ring */
 if ((be32_to_cpu(qw3w2) & TM_QW3W2_VT) &&
-xive_presenter_tctx_match_hw(tctx, nvt_blk, nvt_idx)) {
+cam == xive_tctx_hw_cam_line(tctx)) {
 return TM_QW3_HV_PHYS;
 }
 
-- 
2.21.0




[Qemu-devel] [PULL 12/49] target/ppc: remove getVSR()/putVSR() from fpu_helper.c

2019-07-01 Thread David Gibson
From: Mark Cave-Ayland 

Since commit 8a14d31b00 "target/ppc: switch fpr/vsrl registers so all VSX
registers are in host endian order" functions getVSR() and putVSR() which used
to convert the VSR registers into host endian order are no longer required.

Signed-off-by: Mark Cave-Ayland 
Message-Id: <20190616123751.781-2-mark.cave-ayl...@ilande.co.uk>
Reviewed-by: Richard Henderson 
Signed-off-by: David Gibson 
---
 target/ppc/fpu_helper.c | 762 +++-
 1 file changed, 366 insertions(+), 396 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index ffbd19afa1..8da805d175 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -1803,35 +1803,35 @@ uint32_t helper_efdcmpeq(CPUPPCState *env, uint64_t 
op1, uint64_t op2)
 #define VSX_ADD_SUB(name, op, nels, tp, fld, sfprf, r2sp)\
 void helper_##name(CPUPPCState *env, uint32_t opcode)\
 {\
-ppc_vsr_t xt, xa, xb;\
+ppc_vsr_t *xt = &env->vsr[xT(opcode)];   \
+ppc_vsr_t *xa = &env->vsr[xA(opcode)];   \
+ppc_vsr_t *xb = &env->vsr[xB(opcode)];   \
+ppc_vsr_t t = *xt;   \
 int i;   \
  \
-getVSR(xA(opcode), &xa, env);\
-getVSR(xB(opcode), &xb, env);\
-getVSR(xT(opcode), &xt, env);\
 helper_reset_fpstatus(env);  \
  \
 for (i = 0; i < nels; i++) { \
 float_status tstat = env->fp_status; \
 set_float_exception_flags(0, &tstat);\
-xt.fld = tp##_##op(xa.fld, xb.fld, &tstat);  \
+t.fld = tp##_##op(xa->fld, xb->fld, &tstat); \
 env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
  \
 if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {\
 float_invalid_op_addsub(env, sfprf, GETPC(), \
-tp##_classify(xa.fld) |  \
-tp##_classify(xb.fld));  \
+tp##_classify(xa->fld) | \
+tp##_classify(xb->fld)); \
 }\
  \
 if (r2sp) {  \
-xt.fld = helper_frsp(env, xt.fld);   \
+t.fld = helper_frsp(env, t.fld); \
 }\
  \
 if (sfprf) { \
-helper_compute_fprf_float64(env, xt.fld);\
+helper_compute_fprf_float64(env, t.fld); \
 }\
 }\
-putVSR(xT(opcode), &xt, env);\
+*xt = t; \
 do_float_check_status(env, GETPC()); \
 }
 
@@ -1846,12 +1846,12 @@ VSX_ADD_SUB(xvsubsp, sub, 4, float32, VsrW(i), 0, 0)
 
 void helper_xsaddqp(CPUPPCState *env, uint32_t opcode)
 {
-ppc_vsr_t xt, xa, xb;
+ppc_vsr_t *xt = &env->vsr[rD(opcode) + 32];
+ppc_vsr_t *xa = &env->vsr[rA(opcode) + 32];
+ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32];
+ppc_vsr_t t = *xt;
 float_status tstat;
 
-getVSR(rA(opcode) + 32, &xa, env);
-getVSR(rB(opcode) + 32, &xb, env);
-getVSR(rD(opcode) + 32, &xt, env);
 helper_reset_fpstatus(env);
 
 tstat = env->fp_status;
@@ -1860,18 +1860,18 @@ void helper_xsaddqp(CPUPPCState *env, uint32_t opcode)
 }
 
 set_float_exception_flags(0, &tstat);
-xt.f128 = float128_add(xa.f128, xb.f128, &tstat);
+t.f128 = float128

[Qemu-devel] [PULL 41/49] target/ppc: improve VSX_FMADD with new GEN_VSX_HELPER_VSX_MADD macro

2019-07-01 Thread David Gibson
From: Mark Cave-Ayland 

Introduce a new GEN_VSX_HELPER_VSX_MADD macro for the generator function which
enables the source and destination registers to be decoded at translation time.

This enables the determination of a or m form to be made at translation time so
that a single helper function can now be used for both variants.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Richard Henderson 
Message-Id: <20190616123751.781-16-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: David Gibson 
---
 target/ppc/fpu_helper.c | 68 
 target/ppc/helper.h | 48 ++---
 target/ppc/translate/vsx-impl.inc.c | 81 +
 target/ppc/translate/vsx-ops.inc.c  | 70 +
 4 files changed, 122 insertions(+), 145 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index f0a897cb9a..f437c88aad 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -2280,24 +2280,15 @@ VSX_TSQRT(xvtsqrtsp, 4, float32, VsrW(i), -126, 23)
  *   fld   - vsr_t field (VsrD(*) or VsrW(*))
  *   maddflgs - flags for the float*muladd routine that control the
  *   various forms (madd, msub, nmadd, nmsub)
- *   afrm  - A form (1=A, 0=M)
  *   sfprf - set FPRF
  */
-#define VSX_MADD(op, nels, tp, fld, maddflgs, afrm, sfprf, r2sp)  \
+#define VSX_MADD(op, nels, tp, fld, maddflgs, sfprf, r2sp)\
 void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
- ppc_vsr_t *xa, ppc_vsr_t *xb)\
+ ppc_vsr_t *xa, ppc_vsr_t *b, ppc_vsr_t *c)   \
 { \
-ppc_vsr_t t = *xt, *b, *c;\
+ppc_vsr_t t = *xt;\
 int i;\
   \
-if (afrm) { /* AxB + T */ \
-b = xb;   \
-c = xt;   \
-} else { /* AxT + B */\
-b = xt;   \
-c = xb;   \
-} \
-  \
 helper_reset_fpstatus(env);   \
   \
 for (i = 0; i < nels; i++) {  \
@@ -2336,41 +2327,24 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt,   
  \
 do_float_check_status(env, GETPC());  \
 }
 
-VSX_MADD(xsmaddadp, 1, float64, VsrD(0), MADD_FLGS, 1, 1, 0)
-VSX_MADD(xsmaddmdp, 1, float64, VsrD(0), MADD_FLGS, 0, 1, 0)
-VSX_MADD(xsmsubadp, 1, float64, VsrD(0), MSUB_FLGS, 1, 1, 0)
-VSX_MADD(xsmsubmdp, 1, float64, VsrD(0), MSUB_FLGS, 0, 1, 0)
-VSX_MADD(xsnmaddadp, 1, float64, VsrD(0), NMADD_FLGS, 1, 1, 0)
-VSX_MADD(xsnmaddmdp, 1, float64, VsrD(0), NMADD_FLGS, 0, 1, 0)
-VSX_MADD(xsnmsubadp, 1, float64, VsrD(0), NMSUB_FLGS, 1, 1, 0)
-VSX_MADD(xsnmsubmdp, 1, float64, VsrD(0), NMSUB_FLGS, 0, 1, 0)
-
-VSX_MADD(xsmaddasp, 1, float64, VsrD(0), MADD_FLGS, 1, 1, 1)
-VSX_MADD(xsmaddmsp, 1, float64, VsrD(0), MADD_FLGS, 0, 1, 1)
-VSX_MADD(xsmsubasp, 1, float64, VsrD(0), MSUB_FLGS, 1, 1, 1)
-VSX_MADD(xsmsubmsp, 1, float64, VsrD(0), MSUB_FLGS, 0, 1, 1)
-VSX_MADD(xsnmaddasp, 1, float64, VsrD(0), NMADD_FLGS, 1, 1, 1)
-VSX_MADD(xsnmaddmsp, 1, float64, VsrD(0), NMADD_FLGS, 0, 1, 1)
-VSX_MADD(xsnmsubasp, 1, float64, VsrD(0), NMSUB_FLGS, 1, 1, 1)
-VSX_MADD(xsnmsubmsp, 1, float64, VsrD(0), NMSUB_FLGS, 0, 1, 1)
-
-VSX_MADD(xvmaddadp, 2, float64, VsrD(i), MADD_FLGS, 1, 0, 0)
-VSX_MADD(xvmaddmdp, 2, float64, VsrD(i), MADD_FLGS, 0, 0, 0)
-VSX_MADD(xvmsubadp, 2, float64, VsrD(i), MSUB_FLGS, 1, 0, 0)
-VSX_MADD(xvmsubmdp, 2, float64, VsrD(i), MSUB_FLGS, 0, 0, 0)
-VSX_MADD(xvnmaddadp, 2, float64, VsrD(i), NMADD_FLGS, 1, 0, 0)
-VSX_MADD(xvnmaddmdp, 2, float64, VsrD(i), NMADD_FLGS, 0, 0, 0)
-VSX_MADD(xvnmsubadp, 2, float64, VsrD(i), NMSUB_FLGS, 1, 0, 0)
-VSX_MADD(xvnmsubmdp, 2, float64, VsrD(i), NMSUB_FLGS, 0, 0, 0)
-
-VSX_MADD(xvmaddasp, 4, float32, VsrW(i), MADD_FLGS, 1, 0, 0)
-VSX_MADD(xvmaddmsp, 4, float32, VsrW(i), MADD_FLGS, 0, 0, 0)
-VSX_MADD(xvmsubasp, 4, float32, VsrW(i), MSUB_FLGS, 1, 0, 0)
-VSX_MADD(xvmsubmsp, 4, float32, VsrW(i), MSUB_FLGS, 0, 0, 0)
-VSX_MADD(xvnmaddasp, 4, float32, VsrW(i), NMADD_FLGS, 1, 

[Qemu-devel] [PULL 40/49] target/ppc: decode target register in VSX_EXTRACT_INSERT at translation time

2019-07-01 Thread David Gibson
From: Mark Cave-Ayland 

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Richard Henderson 
Message-Id: <20190616123751.781-15-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: David Gibson 
---
 target/ppc/helper.h |  4 ++--
 target/ppc/int_helper.c | 12 
 target/ppc/translate/vsx-impl.inc.c | 10 +-
 3 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 7ed9e2..3d5150a524 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -534,8 +534,8 @@ DEF_HELPER_3(xvrspip, void, env, vsr, vsr)
 DEF_HELPER_3(xvrspiz, void, env, vsr, vsr)
 DEF_HELPER_4(xxperm, void, env, vsr, vsr, vsr)
 DEF_HELPER_4(xxpermr, void, env, vsr, vsr, vsr)
-DEF_HELPER_4(xxextractuw, void, env, tl, tl, i32)
-DEF_HELPER_4(xxinsertw, void, env, tl, tl, i32)
+DEF_HELPER_4(xxextractuw, void, env, vsr, vsr, i32)
+DEF_HELPER_4(xxinsertw, void, env, vsr, vsr, i32)
 DEF_HELPER_3(xvxsigsp, void, env, vsr, vsr)
 
 DEF_HELPER_2(efscfsi, i32, env, i32)
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index 3b8939edcc..5c07ef3e4d 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -1899,11 +1899,9 @@ VEXTRACT(uw, u32)
 VEXTRACT(d, u64)
 #undef VEXTRACT
 
-void helper_xxextractuw(CPUPPCState *env, target_ulong xtn,
-target_ulong xbn, uint32_t index)
+void helper_xxextractuw(CPUPPCState *env, ppc_vsr_t *xt,
+ppc_vsr_t *xb, uint32_t index)
 {
-ppc_vsr_t *xt = &env->vsr[xtn];
-ppc_vsr_t *xb = &env->vsr[xbn];
 ppc_vsr_t t = { };
 size_t es = sizeof(uint32_t);
 uint32_t ext_index;
@@ -1917,11 +1915,9 @@ void helper_xxextractuw(CPUPPCState *env, target_ulong 
xtn,
 *xt = t;
 }
 
-void helper_xxinsertw(CPUPPCState *env, target_ulong xtn,
-  target_ulong xbn, uint32_t index)
+void helper_xxinsertw(CPUPPCState *env, ppc_vsr_t *xt,
+  ppc_vsr_t *xb, uint32_t index)
 {
-ppc_vsr_t *xt = &env->vsr[xtn];
-ppc_vsr_t *xb = &env->vsr[xbn];
 ppc_vsr_t t = *xt;
 size_t es = sizeof(uint32_t);
 int ins_index, i = 0;
diff --git a/target/ppc/translate/vsx-impl.inc.c 
b/target/ppc/translate/vsx-impl.inc.c
index e853ee1386..7a4b7cb8f9 100644
--- a/target/ppc/translate/vsx-impl.inc.c
+++ b/target/ppc/translate/vsx-impl.inc.c
@@ -1632,7 +1632,7 @@ static void gen_xxsldwi(DisasContext *ctx)
 #define VSX_EXTRACT_INSERT(name)\
 static void gen_##name(DisasContext *ctx)   \
 {   \
-TCGv xt, xb;\
+TCGv_ptr xt, xb;\
 TCGv_i32 t0;\
 TCGv_i64 t1;\
 uint8_t uimm = UIMM4(ctx->opcode);  \
@@ -1641,8 +1641,8 @@ static void gen_##name(DisasContext *ctx) 
  \
 gen_exception(ctx, POWERPC_EXCP_VSXU);  \
 return; \
 }   \
-xt = tcg_const_tl(xT(ctx->opcode)); \
-xb = tcg_const_tl(xB(ctx->opcode)); \
+xt = gen_vsr_ptr(xT(ctx->opcode));  \
+xb = gen_vsr_ptr(xB(ctx->opcode));  \
 t0 = tcg_temp_new_i32();\
 t1 = tcg_temp_new_i64();\
 /*  \
@@ -1657,8 +1657,8 @@ static void gen_##name(DisasContext *ctx) 
  \
 }   \
 tcg_gen_movi_i32(t0, uimm); \
 gen_helper_##name(cpu_env, xt, xb, t0); \
-tcg_temp_free(xb);  \
-tcg_temp_free(xt);  \
+tcg_temp_free_ptr(xb);  \
+tcg_temp_free_ptr(xt);  \
 tcg_temp_free_i32(t0);  \
 tcg_temp_free_i64(t1);  \
 }
-- 
2.21.0




[Qemu-devel] [PULL 44/49] spapr/xive: simplify spapr_irq_init_device() to remove the emulated init

2019-07-01 Thread David Gibson
From: Cédric Le Goater 

The init_emu() handles are now empty. Remove them and rename
spapr_irq_init_device() to spapr_irq_init_kvm().

Signed-off-by: Cédric Le Goater 
Message-Id: <20190614165920.12670-3-...@kaod.org>
Reviewed-by: Greg Kurz 
Signed-off-by: David Gibson 
---
 hw/ppc/spapr_irq.c | 20 +++-
 include/hw/ppc/spapr_irq.h |  1 -
 2 files changed, 3 insertions(+), 18 deletions(-)

diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 02bc5e8c3d..ff3df0bbd8 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -62,7 +62,7 @@ void spapr_irq_msi_reset(SpaprMachineState *spapr)
 bitmap_clear(spapr->irq_map, 0, spapr->irq_map_nr);
 }
 
-static void spapr_irq_init_device(SpaprMachineState *spapr,
+static void spapr_irq_init_kvm(SpaprMachineState *spapr,
   SpaprIrq *irq, Error **errp)
 {
 MachineState *machine = MACHINE(spapr);
@@ -88,8 +88,6 @@ static void spapr_irq_init_device(SpaprMachineState *spapr,
 error_prepend(&local_err, "kernel_irqchip allowed but unavailable: ");
 warn_report_err(local_err);
 }
-
-irq->init_emu(spapr, errp);
 }
 
 /*
@@ -224,7 +222,7 @@ static void spapr_irq_reset_xics(SpaprMachineState *spapr, 
Error **errp)
 {
 Error *local_err = NULL;
 
-spapr_irq_init_device(spapr, &spapr_irq_xics, &local_err);
+spapr_irq_init_kvm(spapr, &spapr_irq_xics, &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
 return;
@@ -236,10 +234,6 @@ static const char 
*spapr_irq_get_nodename_xics(SpaprMachineState *spapr)
 return XICS_NODENAME;
 }
 
-static void spapr_irq_init_emu_xics(SpaprMachineState *spapr, Error **errp)
-{
-}
-
 static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
 {
 if (kvm_enabled()) {
@@ -267,7 +261,6 @@ SpaprIrq spapr_irq_xics = {
 .reset   = spapr_irq_reset_xics,
 .set_irq = spapr_irq_set_irq_xics,
 .get_nodename = spapr_irq_get_nodename_xics,
-.init_emu= spapr_irq_init_emu_xics,
 .init_kvm= spapr_irq_init_kvm_xics,
 };
 
@@ -385,7 +378,7 @@ static void spapr_irq_reset_xive(SpaprMachineState *spapr, 
Error **errp)
 spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx);
 }
 
-spapr_irq_init_device(spapr, &spapr_irq_xive, &local_err);
+spapr_irq_init_kvm(spapr, &spapr_irq_xive, &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
 return;
@@ -411,10 +404,6 @@ static const char 
*spapr_irq_get_nodename_xive(SpaprMachineState *spapr)
 return spapr->xive->nodename;
 }
 
-static void spapr_irq_init_emu_xive(SpaprMachineState *spapr, Error **errp)
-{
-}
-
 static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
 {
 if (kvm_enabled()) {
@@ -446,7 +435,6 @@ SpaprIrq spapr_irq_xive = {
 .reset   = spapr_irq_reset_xive,
 .set_irq = spapr_irq_set_irq_xive,
 .get_nodename = spapr_irq_get_nodename_xive,
-.init_emu= spapr_irq_init_emu_xive,
 .init_kvm= spapr_irq_init_kvm_xive,
 };
 
@@ -624,7 +612,6 @@ SpaprIrq spapr_irq_dual = {
 .reset   = spapr_irq_reset_dual,
 .set_irq = spapr_irq_set_irq_dual,
 .get_nodename = spapr_irq_get_nodename_dual,
-.init_emu= NULL, /* should not be used */
 .init_kvm= NULL, /* should not be used */
 };
 
@@ -840,6 +827,5 @@ SpaprIrq spapr_irq_xics_legacy = {
 .reset   = spapr_irq_reset_xics,
 .set_irq = spapr_irq_set_irq_xics,
 .get_nodename = spapr_irq_get_nodename_xics,
-.init_emu= spapr_irq_init_emu_xics,
 .init_kvm= spapr_irq_init_kvm_xics,
 };
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index 14cab73c9c..f965a58f89 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -48,7 +48,6 @@ typedef struct SpaprIrq {
 void (*reset)(SpaprMachineState *spapr, Error **errp);
 void (*set_irq)(void *opaque, int srcno, int val);
 const char *(*get_nodename)(SpaprMachineState *spapr);
-void (*init_emu)(SpaprMachineState *spapr, Error **errp);
 void (*init_kvm)(SpaprMachineState *spapr, Error **errp);
 } SpaprIrq;
 
-- 
2.21.0




[Qemu-devel] [PULL 29/49] target/ppc: remove getVSR()/putVSR() from int_helper.c

2019-07-01 Thread David Gibson
From: Mark Cave-Ayland 

Since commit 8a14d31b00 "target/ppc: switch fpr/vsrl registers so all VSX
registers are in host endian order" functions getVSR() and putVSR() which used
to convert the VSR registers into host endian order are no longer required.

Now that there are now no more users of getVSR()/putVSR() these functions can
be completely removed.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Richard Henderson 
Message-Id: <20190616123751.781-4-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: David Gibson 
---
 target/ppc/int_helper.c | 22 ++
 target/ppc/internal.h   | 12 
 2 files changed, 10 insertions(+), 24 deletions(-)

diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index 8ce89f2ad9..3b8939edcc 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -1902,38 +1902,36 @@ VEXTRACT(d, u64)
 void helper_xxextractuw(CPUPPCState *env, target_ulong xtn,
 target_ulong xbn, uint32_t index)
 {
-ppc_vsr_t xt, xb;
+ppc_vsr_t *xt = &env->vsr[xtn];
+ppc_vsr_t *xb = &env->vsr[xbn];
+ppc_vsr_t t = { };
 size_t es = sizeof(uint32_t);
 uint32_t ext_index;
 int i;
 
-getVSR(xbn, &xb, env);
-memset(&xt, 0, sizeof(xt));
-
 ext_index = index;
 for (i = 0; i < es; i++, ext_index++) {
-xt.VsrB(8 - es + i) = xb.VsrB(ext_index % 16);
+t.VsrB(8 - es + i) = xb->VsrB(ext_index % 16);
 }
 
-putVSR(xtn, &xt, env);
+*xt = t;
 }
 
 void helper_xxinsertw(CPUPPCState *env, target_ulong xtn,
   target_ulong xbn, uint32_t index)
 {
-ppc_vsr_t xt, xb;
+ppc_vsr_t *xt = &env->vsr[xtn];
+ppc_vsr_t *xb = &env->vsr[xbn];
+ppc_vsr_t t = *xt;
 size_t es = sizeof(uint32_t);
 int ins_index, i = 0;
 
-getVSR(xbn, &xb, env);
-getVSR(xtn, &xt, env);
-
 ins_index = index;
 for (i = 0; i < es && ins_index < 16; i++, ins_index++) {
-xt.VsrB(ins_index) = xb.VsrB(8 - es + i);
+t.VsrB(ins_index) = xb->VsrB(8 - es + i);
 }
 
-putVSR(xtn, &xt, env);
+*xt = t;
 }
 
 #define VEXT_SIGNED(name, element, cast)\
diff --git a/target/ppc/internal.h b/target/ppc/internal.h
index fb6f64ed1e..d3d327e548 100644
--- a/target/ppc/internal.h
+++ b/target/ppc/internal.h
@@ -204,18 +204,6 @@ EXTRACT_HELPER(IMM8, 11, 8);
 EXTRACT_HELPER(DCMX, 16, 7);
 EXTRACT_HELPER_SPLIT_3(DCMX_XV, 5, 16, 0, 1, 2, 5, 1, 6, 6);
 
-static inline void getVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env)
-{
-vsr->VsrD(0) = env->vsr[n].VsrD(0);
-vsr->VsrD(1) = env->vsr[n].VsrD(1);
-}
-
-static inline void putVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env)
-{
-env->vsr[n].VsrD(0) = vsr->VsrD(0);
-env->vsr[n].VsrD(1) = vsr->VsrD(1);
-}
-
 void helper_compute_fprf_float16(CPUPPCState *env, float16 arg);
 void helper_compute_fprf_float32(CPUPPCState *env, float32 arg);
 void helper_compute_fprf_float128(CPUPPCState *env, float128 arg);
-- 
2.21.0




[Qemu-devel] [PULL 21/49] xics/spapr: Drop unused function declaration

2019-07-01 Thread David Gibson
From: Greg Kurz 

Commit 9fb6eb7ca50c added the declaration of xics_spapr_connect(), which
has no implementation and no users.

This is a leftover from a previous iteration of this patch. Drop it.

Signed-off-by: Greg Kurz 
Message-Id: <156077919546.433243.8748677531446035746.st...@bahia.lan>
Reviewed-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 include/hw/ppc/xics_spapr.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
index d968f2499c..3304481262 100644
--- a/include/hw/ppc/xics_spapr.h
+++ b/include/hw/ppc/xics_spapr.h
@@ -37,6 +37,5 @@ int xics_kvm_init(SpaprMachineState *spapr, Error **errp);
 void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp);
 bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr);
 void xics_spapr_init(SpaprMachineState *spapr);
-void xics_spapr_connect(SpaprMachineState *spapr);
 
 #endif /* XICS_SPAPR_H */
-- 
2.21.0




[Qemu-devel] [PULL 36/49] target/ppc: introduce GEN_VSX_HELPER_R3 macro to fpu_helper.c

2019-07-01 Thread David Gibson
From: Mark Cave-Ayland 

Rather than perform the VSR register decoding within the helper itself,
introduce a new GEN_VSX_HELPER_R3 macro which performs the decode based
upon rD, rA and rB at translation time.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Richard Henderson 
Message-Id: <20190616123751.781-11-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: David Gibson 
---
 target/ppc/fpu_helper.c | 36 ++---
 target/ppc/helper.h | 16 ++---
 target/ppc/translate/vsx-impl.inc.c | 36 ++---
 3 files changed, 48 insertions(+), 40 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 5fb43b619e..44970ebec9 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -1842,11 +1842,9 @@ VSX_ADD_SUB(xssubsp, sub, 1, float64, VsrD(0), 1, 1)
 VSX_ADD_SUB(xvsubdp, sub, 2, float64, VsrD(i), 0, 0)
 VSX_ADD_SUB(xvsubsp, sub, 4, float32, VsrW(i), 0, 0)
 
-void helper_xsaddqp(CPUPPCState *env, uint32_t opcode)
+void helper_xsaddqp(CPUPPCState *env, uint32_t opcode,
+ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)
 {
-ppc_vsr_t *xt = &env->vsr[rD(opcode) + 32];
-ppc_vsr_t *xa = &env->vsr[rA(opcode) + 32];
-ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32];
 ppc_vsr_t t = *xt;
 float_status tstat;
 
@@ -1920,11 +1918,9 @@ VSX_MUL(xsmulsp, 1, float64, VsrD(0), 1, 1)
 VSX_MUL(xvmuldp, 2, float64, VsrD(i), 0, 0)
 VSX_MUL(xvmulsp, 4, float32, VsrW(i), 0, 0)
 
-void helper_xsmulqp(CPUPPCState *env, uint32_t opcode)
+void helper_xsmulqp(CPUPPCState *env, uint32_t opcode,
+ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)
 {
-ppc_vsr_t *xt = &env->vsr[rD(opcode) + 32];
-ppc_vsr_t *xa = &env->vsr[rA(opcode) + 32];
-ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32];
 ppc_vsr_t t = *xt;
 float_status tstat;
 
@@ -1999,11 +1995,9 @@ VSX_DIV(xsdivsp, 1, float64, VsrD(0), 1, 1)
 VSX_DIV(xvdivdp, 2, float64, VsrD(i), 0, 0)
 VSX_DIV(xvdivsp, 4, float32, VsrW(i), 0, 0)
 
-void helper_xsdivqp(CPUPPCState *env, uint32_t opcode)
+void helper_xsdivqp(CPUPPCState *env, uint32_t opcode,
+ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)
 {
-ppc_vsr_t *xt = &env->vsr[rD(opcode) + 32];
-ppc_vsr_t *xa = &env->vsr[rA(opcode) + 32];
-ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32];
 ppc_vsr_t t = *xt;
 float_status tstat;
 
@@ -2620,11 +2614,9 @@ VSX_MAX_MIN(xvmindp, minnum, 2, float64, VsrD(i))
 VSX_MAX_MIN(xvminsp, minnum, 4, float32, VsrW(i))
 
 #define VSX_MAX_MINC(name, max)   \
-void helper_##name(CPUPPCState *env, uint32_t opcode) \
+void helper_##name(CPUPPCState *env, uint32_t opcode, \
+   ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)   \
 { \
-ppc_vsr_t *xt = &env->vsr[rD(opcode) + 32];   \
-ppc_vsr_t *xa = &env->vsr[rA(opcode) + 32];   \
-ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32];   \
 ppc_vsr_t t = *xt;\
 bool vxsnan_flag = false, vex_flag = false;   \
   \
@@ -2657,11 +2649,9 @@ VSX_MAX_MINC(xsmaxcdp, 1);
 VSX_MAX_MINC(xsmincdp, 0);
 
 #define VSX_MAX_MINJ(name, max)   \
-void helper_##name(CPUPPCState *env, uint32_t opcode) \
+void helper_##name(CPUPPCState *env, uint32_t opcode, \
+   ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)   \
 { \
-ppc_vsr_t *xt = &env->vsr[rD(opcode) + 32];   \
-ppc_vsr_t *xa = &env->vsr[rA(opcode) + 32];   \
-ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32];   \
 ppc_vsr_t t = *xt;\
 bool vxsnan_flag = false, vex_flag = false;   \
   \
@@ -3436,11 +3426,9 @@ void helper_xssqrtqp(CPUPPCState *env, uint32_t opcode)
 do_float_check_status(env, GETPC());
 }
 
-void helper_xssubqp(CPUPPCState *env, uint32_t opcode)
+void helper_xssubqp(CPUPPCState *env, uint32_t opcode,
+ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)
 {
-ppc_vsr_t *xt = &env->vsr[rD(opcode) + 32];
-ppc_vsr_t *xa = &env->vsr[rA(opcode) + 32];
-ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32];
 ppc_vsr_t t = *xt;
 float_status tstat;
 
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index a8886c56ad..9134da

[Qemu-devel] [PULL 34/49] target/ppc: introduce GEN_VSX_HELPER_X2_AB macro to fpu_helper.c

2019-07-01 Thread David Gibson
From: Mark Cave-Ayland 

Rather than perform the VSR register decoding within the helper itself,
introduce a new GEN_VSX_HELPER_X2_AB macro which performs the decode based
upon xA and xB at translation time.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Richard Henderson 
Message-Id: <20190616123751.781-9-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: David Gibson 
---
 target/ppc/fpu_helper.c | 15 ++-
 target/ppc/helper.h | 12 ++--
 target/ppc/translate/vsx-impl.inc.c | 30 +++--
 3 files changed, 36 insertions(+), 21 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 44dff1b459..902d63b139 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -2179,10 +2179,9 @@ VSX_RSQRTE(xvrsqrtesp, 4, float32, VsrW(i), 0, 0)
  *   nbits - number of fraction bits
  */
 #define VSX_TDIV(op, nels, tp, fld, emin, emax, nbits)  \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, uint32_t opcode, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb)  \
 {   \
-ppc_vsr_t *xa = &env->vsr[xA(opcode)];  \
-ppc_vsr_t *xb = &env->vsr[xB(opcode)];  \
 int i;  \
 int fe_flag = 0;\
 int fg_flag = 0;\
@@ -2431,10 +2430,9 @@ VSX_SCALAR_CMP_DP(xscmpgedp, le, 1, 1)
 VSX_SCALAR_CMP_DP(xscmpgtdp, lt, 1, 1)
 VSX_SCALAR_CMP_DP(xscmpnedp, eq, 0, 0)
 
-void helper_xscmpexpdp(CPUPPCState *env, uint32_t opcode)
+void helper_xscmpexpdp(CPUPPCState *env, uint32_t opcode,
+   ppc_vsr_t *xa, ppc_vsr_t *xb)
 {
-ppc_vsr_t *xa = &env->vsr[xA(opcode)];
-ppc_vsr_t *xb = &env->vsr[xB(opcode)];
 int64_t exp_a, exp_b;
 uint32_t cc;
 
@@ -2492,10 +2490,9 @@ void helper_xscmpexpqp(CPUPPCState *env, uint32_t opcode)
 }
 
 #define VSX_SCALAR_CMP(op, ordered)  \
-void helper_##op(CPUPPCState *env, uint32_t opcode)  \
+void helper_##op(CPUPPCState *env, uint32_t opcode,  \
+ ppc_vsr_t *xa, ppc_vsr_t *xb)   \
 {\
-ppc_vsr_t *xa = &env->vsr[xA(opcode)];   \
-ppc_vsr_t *xb = &env->vsr[xB(opcode)];   \
 uint32_t cc = 0; \
 bool vxsnan_flag = false, vxvc_flag = false; \
  \
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index f56476ec41..0ab1ef2aee 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -375,7 +375,7 @@ DEF_HELPER_2(xsdivqp, void, env, i32)
 DEF_HELPER_3(xsredp, void, env, vsr, vsr)
 DEF_HELPER_3(xssqrtdp, void, env, vsr, vsr)
 DEF_HELPER_3(xsrsqrtedp, void, env, vsr, vsr)
-DEF_HELPER_2(xstdivdp, void, env, i32)
+DEF_HELPER_4(xstdivdp, void, env, i32, vsr, vsr)
 DEF_HELPER_2(xstsqrtdp, void, env, i32)
 DEF_HELPER_4(xsmaddadp, void, env, vsr, vsr, vsr)
 DEF_HELPER_4(xsmaddmdp, void, env, vsr, vsr, vsr)
@@ -389,10 +389,10 @@ DEF_HELPER_4(xscmpeqdp, void, env, vsr, vsr, vsr)
 DEF_HELPER_4(xscmpgtdp, void, env, vsr, vsr, vsr)
 DEF_HELPER_4(xscmpgedp, void, env, vsr, vsr, vsr)
 DEF_HELPER_4(xscmpnedp, void, env, vsr, vsr, vsr)
-DEF_HELPER_2(xscmpexpdp, void, env, i32)
+DEF_HELPER_4(xscmpexpdp, void, env, i32, vsr, vsr)
 DEF_HELPER_2(xscmpexpqp, void, env, i32)
-DEF_HELPER_2(xscmpodp, void, env, i32)
-DEF_HELPER_2(xscmpudp, void, env, i32)
+DEF_HELPER_4(xscmpodp, void, env, i32, vsr, vsr)
+DEF_HELPER_4(xscmpudp, void, env, i32, vsr, vsr)
 DEF_HELPER_2(xscmpoqp, void, env, i32)
 DEF_HELPER_2(xscmpuqp, void, env, i32)
 DEF_HELPER_4(xsmaxdp, void, env, vsr, vsr, vsr)
@@ -460,7 +460,7 @@ DEF_HELPER_4(xvdivdp, void, env, vsr, vsr, vsr)
 DEF_HELPER_3(xvredp, void, env, vsr, vsr)
 DEF_HELPER_3(xvsqrtdp, void, env, vsr, vsr)
 DEF_HELPER_3(xvrsqrtedp, void, env, vsr, vsr)
-DEF_HELPER_2(xvtdivdp, void, env, i32)
+DEF_HELPER_4(xvtdivdp, void, env, i32, vsr, vsr)
 DEF_HELPER_2(xvtsqrtdp, void, env, i32)
 DEF_HELPER_4(xvmaddadp, void, env, vsr, vsr, vsr)
 DEF_HELPER_4(xvmaddmdp, void, env, vsr, vsr, vsr)
@@ -498,7 +498,7 @@ DEF_HELPER_4(xvdivsp, void, env, vsr, vsr, vsr)
 DEF_HELPER_3(xvresp, void, env, vsr, vsr)
 DEF_HELPER_3(xvsqrtsp, void, env, vsr, vsr)
 DEF_HELPER_3(xvrsqrtesp, void, env, vsr, vsr)
-DEF_HELPER_2(xvtdivsp, void, env, i32)
+DEF_HELPER_4(xvtdivsp, void, env, i32, vsr, vsr)
 DEF_HELPER_2(xvtsqrtsp, void, env, i32)
 DEF_HELPER_4(xvmaddasp, void, env, vsr, vsr, vsr)
 DEF

[Qemu-devel] [PULL 25/49] xics/kvm: Add error propagation to ic*_set_kvm_state() functions

2019-07-01 Thread David Gibson
From: Greg Kurz 

This allows errors happening there to be propagated up to spapr_irq,
just like XIVE already does.

Signed-off-by: Greg Kurz 
Message-Id: <156077921763.433243.4614327010172954196.st...@bahia.lan>
Reviewed-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 hw/intc/xics.c| 39 ++-
 hw/intc/xics_kvm.c| 37 ++---
 include/hw/ppc/xics.h |  6 +++---
 3 files changed, 59 insertions(+), 23 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 978d7f0886..faa976e2f8 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -267,7 +267,14 @@ static int icp_post_load(void *opaque, int version_id)
 ICPState *icp = opaque;
 
 if (kvm_irqchip_in_kernel()) {
-return icp_set_kvm_state(icp);
+Error *local_err = NULL;
+int ret;
+
+ret = icp_set_kvm_state(icp, &local_err);
+if (ret < 0) {
+error_report_err(local_err);
+return ret;
+}
 }
 
 return 0;
@@ -300,7 +307,12 @@ static void icp_reset_handler(void *dev)
 qemu_set_irq(icp->output, 0);
 
 if (kvm_irqchip_in_kernel()) {
-icp_set_kvm_state(ICP(dev));
+Error *local_err = NULL;
+
+icp_set_kvm_state(ICP(dev), &local_err);
+if (local_err) {
+error_report_err(local_err);
+}
 }
 }
 
@@ -564,7 +576,12 @@ static void ics_simple_reset(DeviceState *dev)
 icsc->parent_reset(dev);
 
 if (kvm_irqchip_in_kernel()) {
-ics_set_kvm_state(ICS_BASE(dev));
+Error *local_err = NULL;
+
+ics_set_kvm_state(ICS_BASE(dev), &local_err);
+if (local_err) {
+error_report_err(local_err);
+}
 }
 }
 
@@ -680,7 +697,14 @@ static int ics_base_post_load(void *opaque, int version_id)
 ICSState *ics = opaque;
 
 if (kvm_irqchip_in_kernel()) {
-return ics_set_kvm_state(ics);
+Error *local_err = NULL;
+int ret;
+
+ret = ics_set_kvm_state(ics, &local_err);
+if (ret < 0) {
+error_report_err(local_err);
+return ret;
+}
 }
 
 return 0;
@@ -766,8 +790,13 @@ void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)
 lsi ? XICS_FLAGS_IRQ_LSI : XICS_FLAGS_IRQ_MSI;
 
 if (kvm_irqchip_in_kernel()) {
+Error *local_err = NULL;
+
 ics_reset_irq(ics->irqs + srcno);
-ics_set_kvm_state_one(ics, srcno);
+ics_set_kvm_state_one(ics, srcno, &local_err);
+if (local_err) {
+error_report_err(local_err);
+}
 }
 }
 
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index c9e25fb051..4bfbe1a840 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -106,7 +106,7 @@ void icp_synchronize_state(ICPState *icp)
 }
 }
 
-int icp_set_kvm_state(ICPState *icp)
+int icp_set_kvm_state(ICPState *icp, Error **errp)
 {
 uint64_t state;
 int ret;
@@ -126,10 +126,11 @@ int icp_set_kvm_state(ICPState *icp)
 | ((uint64_t)icp->pending_priority << KVM_REG_PPC_ICP_PPRI_SHIFT);
 
 ret = kvm_set_one_reg(icp->cs, KVM_REG_PPC_ICP_STATE, &state);
-if (ret != 0) {
-error_report("Unable to restore KVM interrupt controller state (0x%"
-PRIx64 ") for CPU %ld: %s", state, kvm_arch_vcpu_id(icp->cs),
-strerror(errno));
+if (ret < 0) {
+error_setg_errno(errp, -ret,
+ "Unable to restore KVM interrupt controller state 
(0x%"
+ PRIx64 ") for CPU %ld", state,
+ kvm_arch_vcpu_id(icp->cs));
 return ret;
 }
 
@@ -240,10 +241,9 @@ void ics_synchronize_state(ICSState *ics)
 ics_get_kvm_state(ics);
 }
 
-int ics_set_kvm_state_one(ICSState *ics, int srcno)
+int ics_set_kvm_state_one(ICSState *ics, int srcno, Error **errp)
 {
 uint64_t state;
-Error *local_err = NULL;
 ICSIRQState *irq = &ics->irqs[srcno];
 int ret;
 
@@ -278,16 +278,15 @@ int ics_set_kvm_state_one(ICSState *ics, int srcno)
 }
 
 ret = kvm_device_access(kernel_xics_fd, KVM_DEV_XICS_GRP_SOURCES,
-srcno + ics->offset, &state, true, &local_err);
-if (local_err) {
-error_report_err(local_err);
+srcno + ics->offset, &state, true, errp);
+if (ret < 0) {
 return ret;
 }
 
 return 0;
 }
 
-int ics_set_kvm_state(ICSState *ics)
+int ics_set_kvm_state(ICSState *ics, Error **errp)
 {
 int i;
 
@@ -297,10 +296,12 @@ int ics_set_kvm_state(ICSState *ics)
 }
 
 for (i = 0; i < ics->nr_irqs; i++) {
+Error *local_err = NULL;
 int ret;
 
-ret = ics_set_kvm_state_one(ics, i);
-if (ret) {
+ret = ics_set_kvm_state_one(ics, i, &local_err);
+if (ret < 0) {
+error_propagate(errp, local_err);
 return ret;
 }
 }
@@ -402,12 +403,18 @@ int xics_kvm_connect(SpaprMachineState *spapr, Error 
**

[Qemu-devel] [PULL 38/49] target/ppc: introduce GEN_VSX_HELPER_R2_AB macro to fpu_helper.c

2019-07-01 Thread David Gibson
From: Mark Cave-Ayland 

Rather than perform the VSR register decoding within the helper itself,
introduce a new GEN_VSX_HELPER_R2_AB macro which performs the decode based
upon rA and rB at translation time.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Richard Henderson 
Message-Id: <20190616123751.781-13-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: David Gibson 
---
 target/ppc/fpu_helper.c | 10 --
 target/ppc/helper.h |  6 +++---
 target/ppc/translate/vsx-impl.inc.c | 24 +---
 3 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index cb593517ae..f0a897cb9a 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -2452,10 +2452,9 @@ void helper_xscmpexpdp(CPUPPCState *env, uint32_t opcode,
 do_float_check_status(env, GETPC());
 }
 
-void helper_xscmpexpqp(CPUPPCState *env, uint32_t opcode)
+void helper_xscmpexpqp(CPUPPCState *env, uint32_t opcode,
+   ppc_vsr_t *xa, ppc_vsr_t *xb)
 {
-ppc_vsr_t *xa = &env->vsr[rA(opcode) + 32];
-ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32];
 int64_t exp_a, exp_b;
 uint32_t cc;
 
@@ -2531,10 +2530,9 @@ VSX_SCALAR_CMP(xscmpodp, 1)
 VSX_SCALAR_CMP(xscmpudp, 0)
 
 #define VSX_SCALAR_CMPQ(op, ordered)\
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, uint32_t opcode, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb)  \
 {   \
-ppc_vsr_t *xa = &env->vsr[rA(opcode) + 32]; \
-ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32]; \
 uint32_t cc = 0;\
 bool vxsnan_flag = false, vxvc_flag = false;\
 \
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 2e0646f5eb..a5e12a3933 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -390,11 +390,11 @@ DEF_HELPER_4(xscmpgtdp, void, env, vsr, vsr, vsr)
 DEF_HELPER_4(xscmpgedp, void, env, vsr, vsr, vsr)
 DEF_HELPER_4(xscmpnedp, void, env, vsr, vsr, vsr)
 DEF_HELPER_4(xscmpexpdp, void, env, i32, vsr, vsr)
-DEF_HELPER_2(xscmpexpqp, void, env, i32)
+DEF_HELPER_4(xscmpexpqp, void, env, i32, vsr, vsr)
 DEF_HELPER_4(xscmpodp, void, env, i32, vsr, vsr)
 DEF_HELPER_4(xscmpudp, void, env, i32, vsr, vsr)
-DEF_HELPER_2(xscmpoqp, void, env, i32)
-DEF_HELPER_2(xscmpuqp, void, env, i32)
+DEF_HELPER_4(xscmpoqp, void, env, i32, vsr, vsr)
+DEF_HELPER_4(xscmpuqp, void, env, i32, vsr, vsr)
 DEF_HELPER_4(xsmaxdp, void, env, vsr, vsr, vsr)
 DEF_HELPER_4(xsmindp, void, env, vsr, vsr, vsr)
 DEF_HELPER_5(xsmaxcdp, void, env, i32, vsr, vsr, vsr)
diff --git a/target/ppc/translate/vsx-impl.inc.c 
b/target/ppc/translate/vsx-impl.inc.c
index 05db509a0c..5cf053e7f2 100644
--- a/target/ppc/translate/vsx-impl.inc.c
+++ b/target/ppc/translate/vsx-impl.inc.c
@@ -1133,6 +1133,24 @@ static void gen_##name(DisasContext *ctx)
 \
 tcg_temp_free_ptr(xb);\
 }
 
+#define GEN_VSX_HELPER_R2_AB(name, op1, op2, inval, type) \
+static void gen_##name(DisasContext *ctx) \
+{ \
+TCGv_i32 opc; \
+TCGv_ptr xa, xb;  \
+if (unlikely(!ctx->vsx_enabled)) {\
+gen_exception(ctx, POWERPC_EXCP_VSXU);\
+return;   \
+} \
+opc = tcg_const_i32(ctx->opcode); \
+xa = gen_vsr_ptr(rA(ctx->opcode) + 32);   \
+xb = gen_vsr_ptr(rB(ctx->opcode) + 32);   \
+gen_helper_##name(cpu_env, opc, xa, xb);  \
+tcg_temp_free_i32(opc);   \
+tcg_temp_free_ptr(xa);\
+tcg_temp_free_ptr(xb);\
+}
+
 #define GEN_VSX_HELPER_XT_XB_ENV(name, op1, op2, inval, type) \
 static void gen_##name(DisasContext *ctx) \
 { \
@@ -1176,11 +1194,11 @@ GEN_VSX_HELPER_X3(xscmpgtdp, 0x0C, 0x01, 0, PPC2_ISA300)
 GEN_VSX_HELPER_X3(xscmpgedp, 0x0C, 0x02, 0, PPC2_ISA300)
 GEN_VSX_HELPER_X3(xscmpnedp, 0x0C, 

[Qemu-devel] [PULL 31/49] target/ppc: introduce GEN_VSX_HELPER_X3 macro to fpu_helper.c

2019-07-01 Thread David Gibson
From: Mark Cave-Ayland 

Rather than perform the VSR register decoding within the helper itself,
introduce a new GEN_VSX_HELPER_X3 macro which performs the decode based
upon xT, xA and xB at translation time.

With the previous changes to the VSX_CMP generator and helper macros the
opcode parameter is no longer required in the common case and can be
removed.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Richard Henderson 
Message-Id: <20190616123751.781-6-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: David Gibson 
---
 target/ppc/fpu_helper.c |  42 +++--
 target/ppc/helper.h | 120 
 target/ppc/translate/vsx-impl.inc.c | 137 
 3 files changed, 151 insertions(+), 148 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index b1ce954354..012dfdac3e 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -1801,11 +1801,9 @@ uint32_t helper_efdcmpeq(CPUPPCState *env, uint64_t op1, 
uint64_t op2)
  *   sfprf - set FPRF
  */
 #define VSX_ADD_SUB(name, op, nels, tp, fld, sfprf, r2sp)\
-void helper_##name(CPUPPCState *env, uint32_t opcode)\
+void helper_##name(CPUPPCState *env, ppc_vsr_t *xt,  \
+   ppc_vsr_t *xa, ppc_vsr_t *xb) \
 {\
-ppc_vsr_t *xt = &env->vsr[xT(opcode)];   \
-ppc_vsr_t *xa = &env->vsr[xA(opcode)];   \
-ppc_vsr_t *xb = &env->vsr[xB(opcode)];   \
 ppc_vsr_t t = *xt;   \
 int i;   \
  \
@@ -1884,11 +1882,9 @@ void helper_xsaddqp(CPUPPCState *env, uint32_t opcode)
  *   sfprf - set FPRF
  */
 #define VSX_MUL(op, nels, tp, fld, sfprf, r2sp)  \
-void helper_##op(CPUPPCState *env, uint32_t opcode)  \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt,\
+ ppc_vsr_t *xa, ppc_vsr_t *xb)   \
 {\
-ppc_vsr_t *xt = &env->vsr[xT(opcode)];   \
-ppc_vsr_t *xa = &env->vsr[xA(opcode)];   \
-ppc_vsr_t *xb = &env->vsr[xB(opcode)];   \
 ppc_vsr_t t = *xt;   \
 int i;   \
  \
@@ -1962,11 +1958,9 @@ void helper_xsmulqp(CPUPPCState *env, uint32_t opcode)
  *   sfprf - set FPRF
  */
 #define VSX_DIV(op, nels, tp, fld, sfprf, r2sp)   \
-void helper_##op(CPUPPCState *env, uint32_t opcode)   \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb)\
 { \
-ppc_vsr_t *xt = &env->vsr[xT(opcode)];\
-ppc_vsr_t *xa = &env->vsr[xA(opcode)];\
-ppc_vsr_t *xb = &env->vsr[xB(opcode)];\
 ppc_vsr_t t = *xt;\
 int i;\
   \
@@ -2304,11 +2298,9 @@ VSX_TSQRT(xvtsqrtsp, 4, float32, VsrW(i), -126, 23)
  *   sfprf - set FPRF
  */
 #define VSX_MADD(op, nels, tp, fld, maddflgs, afrm, sfprf, r2sp)  \
-void helper_##op(CPUPPCState *env, uint32_t opcode)   \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb)\
 { \
-ppc_vsr_t *xt = &env->vsr[xT(opcode)];\
-ppc_vsr_t *xa = &env->vsr[xA(opcode)];\
-ppc_vsr_t *xb = &env->vsr[xB(opcode)];\
 ppc_vsr_t t = *xt, *b, *c;\
 int i;\
   \
@@ -2402,11 +2394,9 @@ VSX_MADD(xvnmsubmsp, 4, float32, VsrW(i), NMSUB_FLGS, 0, 
0, 0)

[Qemu-devel] [PULL 24/49] xics/kvm: Always use local_err in xics_kvm_init()

2019-07-01 Thread David Gibson
From: Greg Kurz 

Passing both errp and &local_err to functions is a recipe for messing
things up.

Since we must use &local_err for icp_kvm_realize(), use &local_err
everywhere where rollback must happen and have a single call to
error_propagate() them all. While here, add errno to the error
message.

Signed-off-by: Greg Kurz 
Message-Id: <156077921212.433243.11716701611944816815.st...@bahia.lan>
Reviewed-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 hw/intc/xics_kvm.c | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 377ff88701..c9e25fb051 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -353,32 +353,36 @@ int xics_kvm_connect(SpaprMachineState *spapr, Error 
**errp)
 
 rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_SET_XIVE, "ibm,set-xive");
 if (rc < 0) {
-error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,set-xive");
+error_setg_errno(&local_err, -rc,
+ "kvmppc_define_rtas_kernel_token: ibm,set-xive");
 goto fail;
 }
 
 rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_GET_XIVE, "ibm,get-xive");
 if (rc < 0) {
-error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,get-xive");
+error_setg_errno(&local_err, -rc,
+ "kvmppc_define_rtas_kernel_token: ibm,get-xive");
 goto fail;
 }
 
 rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_INT_ON, "ibm,int-on");
 if (rc < 0) {
-error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,int-on");
+error_setg_errno(&local_err, -rc,
+ "kvmppc_define_rtas_kernel_token: ibm,int-on");
 goto fail;
 }
 
 rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_INT_OFF, "ibm,int-off");
 if (rc < 0) {
-error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,int-off");
+error_setg_errno(&local_err, -rc,
+ "kvmppc_define_rtas_kernel_token: ibm,int-off");
 goto fail;
 }
 
 /* Create the KVM XICS device */
 rc = kvm_create_device(kvm_state, KVM_DEV_TYPE_XICS, false);
 if (rc < 0) {
-error_setg_errno(errp, -rc, "Error on KVM_CREATE_DEVICE for XICS");
+error_setg_errno(&local_err, -rc, "Error on KVM_CREATE_DEVICE for 
XICS");
 goto fail;
 }
 
@@ -393,7 +397,6 @@ int xics_kvm_connect(SpaprMachineState *spapr, Error **errp)
 
 icp_kvm_realize(DEVICE(spapr_cpu_state(cpu)->icp), &local_err);
 if (local_err) {
-error_propagate(errp, local_err);
 goto fail;
 }
 }
@@ -410,6 +413,7 @@ int xics_kvm_connect(SpaprMachineState *spapr, Error **errp)
 return 0;
 
 fail:
+error_propagate(errp, local_err);
 kvmppc_define_rtas_kernel_token(0, "ibm,set-xive");
 kvmppc_define_rtas_kernel_token(0, "ibm,get-xive");
 kvmppc_define_rtas_kernel_token(0, "ibm,int-on");
-- 
2.21.0




[Qemu-devel] [PULL 18/49] hw/ppc/mac_newworld: Drop useless CONFIG_KVM ifdefery

2019-07-01 Thread David Gibson
From: Greg Kurz 

kvm_enabled() expands to (0) when CONFIG_KVM is not defined. The first
CONFIG_KVM guard is thus useless and it is likely that the compiler
will optimize the code out in the case of the second guard. And even
if it doesn't, we have a stub for kvmppc_get_hypercall().

Signed-off-by: Greg Kurz 
Message-Id: <156051054077.224162.9332715375637801197.st...@bahia.lan>
Signed-off-by: David Gibson 
---
 hw/ppc/mac_newworld.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 4d835f32b5..c8d3245524 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -437,13 +437,11 @@ static void ppc_core99_init(MachineState *machine)
 }
 
 /* The NewWorld NVRAM is not located in the MacIO device */
-#ifdef CONFIG_KVM
 if (kvm_enabled() && getpagesize() > 4096) {
 /* We can't combine read-write and read-only in a single page, so
move the NVRAM out of ROM again for KVM */
 nvram_addr = 0xFFE0;
 }
-#endif
 dev = qdev_create(NULL, TYPE_MACIO_NVRAM);
 qdev_prop_set_uint32(dev, "size", 0x2000);
 qdev_prop_set_uint32(dev, "it_shift", 1);
@@ -488,14 +486,12 @@ static void ppc_core99_init(MachineState *machine)
 
 fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled());
 if (kvm_enabled()) {
-#ifdef CONFIG_KVM
 uint8_t *hypercall;
 
 hypercall = g_malloc(16);
 kvmppc_get_hypercall(env, hypercall, 16);
 fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
 fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
-#endif
 }
 fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, tbfreq);
 /* Mac OS X requires a "known good" clock-frequency value; pass it one. */
-- 
2.21.0




[Qemu-devel] [PULL 26/49] xics/kvm: Add proper rollback to xics_kvm_init()

2019-07-01 Thread David Gibson
From: Greg Kurz 

Make xics_kvm_disconnect() able to undo the changes of a partial execution
of xics_kvm_connect() and use it to perform rollback.

Note that kvmppc_define_rtas_kernel_token(0) never fails, no matter the
RTAS call has been defined or not.

Signed-off-by: Greg Kurz 
Message-Id: <156077922319.433243.609897156640506891.st...@bahia.lan>
Reviewed-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 hw/intc/xics_kvm.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 4bfbe1a840..51433b19b0 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -421,10 +421,7 @@ int xics_kvm_connect(SpaprMachineState *spapr, Error 
**errp)
 
 fail:
 error_propagate(errp, local_err);
-kvmppc_define_rtas_kernel_token(0, "ibm,set-xive");
-kvmppc_define_rtas_kernel_token(0, "ibm,get-xive");
-kvmppc_define_rtas_kernel_token(0, "ibm,int-on");
-kvmppc_define_rtas_kernel_token(0, "ibm,int-off");
+xics_kvm_disconnect(spapr, NULL);
 return -1;
 }
 
@@ -448,8 +445,10 @@ void xics_kvm_disconnect(SpaprMachineState *spapr, Error 
**errp)
  * removed from the list of devices of the VM. The VCPU presenters
  * are also detached from the device.
  */
-close(kernel_xics_fd);
-kernel_xics_fd = -1;
+if (kernel_xics_fd != -1) {
+close(kernel_xics_fd);
+kernel_xics_fd = -1;
+}
 
 kvmppc_define_rtas_kernel_token(0, "ibm,set-xive");
 kvmppc_define_rtas_kernel_token(0, "ibm,get-xive");
-- 
2.21.0




[Qemu-devel] [PULL 09/49] xics/spapr: Detect old KVM XICS on POWER9 hosts

2019-07-01 Thread David Gibson
From: Greg Kurz 

Older KVMs on POWER9 don't support destroying/recreating a KVM XICS
device, which is required by 'dual' interrupt controller mode. This
causes QEMU to emit a warning when the guest is rebooted and to fall
back on XICS emulation:

qemu-system-ppc64: warning: kernel_irqchip allowed but unavailable:
 Error on KVM_CREATE_DEVICE for XICS: File exists

If kernel irqchip is required, QEMU will thus exit when the guest is
first rebooted. Failing QEMU this late may be a painful experience
for the user.

Detect that and exit at machine init instead.

Signed-off-by: Greg Kurz 
Message-Id: 
<156044430517.125694.6207865998817342638.st...@bahia.lab.toulouse-stg.fr.ibm.com>
Signed-off-by: David Gibson 
---
 docs/specs/ppc-spapr-xive.rst |  4 ++--
 hw/intc/xics_kvm.c| 30 ++
 hw/ppc/spapr_irq.c| 13 +
 include/hw/ppc/xics_spapr.h   |  1 +
 4 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/docs/specs/ppc-spapr-xive.rst b/docs/specs/ppc-spapr-xive.rst
index 7a64c9d049..6159bc6eed 100644
--- a/docs/specs/ppc-spapr-xive.rst
+++ b/docs/specs/ppc-spapr-xive.rst
@@ -142,8 +142,8 @@ xicsXICS KVM   XICS emul. XICS KVM
 (3) QEMU fails at CAS with ``Guest requested unavailable interrupt
 mode (XICS), either don't set the ic-mode machine property or try
 ic-mode=xics or ic-mode=dual``
-(4) QEMU/KVM incompatibility due to device destruction in reset. This
-needs to be addressed more cleanly with an error.
+(4) QEMU/KVM incompatibility due to device destruction in reset. QEMU fails
+with ``KVM is too old to support ic-mode=dual,kernel-irqchip=on``
 
 
 XIVE Device tree properties
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 5c4208f430..c7f8f5edd2 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -452,3 +452,33 @@ void xics_kvm_disconnect(SpaprMachineState *spapr, Error 
**errp)
 /* Clear the presenter from the VCPUs */
 kvm_disable_icps();
 }
+
+/*
+ * This is a heuristic to detect older KVMs on POWER9 hosts that don't
+ * support destruction of a KVM XICS device while the VM is running.
+ * Required to start a spapr machine with ic-mode=dual,kernel-irqchip=on.
+ */
+bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr)
+{
+int rc;
+
+rc = kvm_create_device(kvm_state, KVM_DEV_TYPE_XICS, false);
+if (rc < 0) {
+/*
+ * The error is ignored on purpose. The KVM XICS setup code
+ * will catch it again anyway. The goal here is to see if
+ * close() actually destroys the device or not.
+ */
+return false;
+}
+
+close(rc);
+
+rc = kvm_create_device(kvm_state, KVM_DEV_TYPE_XICS, false);
+if (rc >= 0) {
+close(rc);
+return false;
+}
+
+return errno == EEXIST;
+}
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index dfb99f35ea..75654fc67a 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -669,6 +669,19 @@ static void spapr_irq_check(SpaprMachineState *spapr, 
Error **errp)
 return;
 }
 }
+
+/*
+ * On a POWER9 host, some older KVM XICS devices cannot be destroyed and
+ * re-created. Detect that early to avoid QEMU to exit later when the
+ * guest reboots.
+ */
+if (kvm_enabled() &&
+spapr->irq == &spapr_irq_dual &&
+machine_kernel_irqchip_required(machine) &&
+xics_kvm_has_broken_disconnect(spapr)) {
+error_setg(errp, "KVM is too old to support 
ic-mode=dual,kernel-irqchip=on");
+return;
+}
 }
 
 /*
diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
index 6c1d9ee559..d968f2499c 100644
--- a/include/hw/ppc/xics_spapr.h
+++ b/include/hw/ppc/xics_spapr.h
@@ -35,6 +35,7 @@ void spapr_dt_xics(SpaprMachineState *spapr, uint32_t 
nr_servers, void *fdt,
uint32_t phandle);
 int xics_kvm_init(SpaprMachineState *spapr, Error **errp);
 void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp);
+bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr);
 void xics_spapr_init(SpaprMachineState *spapr);
 void xics_spapr_connect(SpaprMachineState *spapr);
 
-- 
2.21.0




[Qemu-devel] [PULL 23/49] xics/kvm: Skip rollback when KVM XICS is absent

2019-07-01 Thread David Gibson
From: Greg Kurz 

There is no need to rollback anything at this point, so just return an
error.

Signed-off-by: Greg Kurz 
Message-Id: <156077920657.433243.13541093940589972734.st...@bahia.lan>
Reviewed-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 hw/intc/xics_kvm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 534515143e..377ff88701 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -348,7 +348,7 @@ int xics_kvm_connect(SpaprMachineState *spapr, Error **errp)
 if (!kvm_enabled() || !kvm_check_extension(kvm_state, KVM_CAP_IRQ_XICS)) {
 error_setg(errp,
"KVM and IRQ_XICS capability must be present for in-kernel 
XICS");
-goto fail;
+return -1;
 }
 
 rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_SET_XIVE, "ibm,set-xive");
-- 
2.21.0




[Qemu-devel] [PULL 11/49] xics: Add comment about CPU hotplug

2019-07-01 Thread David Gibson
From: Greg Kurz 

So that no one is tempted to drop that code, which is never called
for cold plugged CPUs.

Signed-off-by: Greg Kurz 
Message-Id: <156078063349.435533.12283208810037409702.st...@bahia.lan>
Reviewed-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 hw/intc/xics.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 29f7d39781..978d7f0886 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -351,6 +351,7 @@ static void icp_realize(DeviceState *dev, Error **errp)
 return;
 }
 
+/* Connect the presenter to the VCPU (required for CPU hotplug) */
 if (kvm_irqchip_in_kernel()) {
 icp_kvm_realize(dev, &err);
 if (err) {
-- 
2.21.0




[Qemu-devel] [PULL 43/49] spapr/xive: rework the mapping the KVM memory regions

2019-07-01 Thread David Gibson
From: Cédric Le Goater 

Today, the interrupt device is fully initialized at reset when the CAS
negotiation process has completed. Depending on the KVM capabilities,
the SpaprXive memory regions (ESB, TIMA) are initialized with a host
MMIO backend or a QEMU emulated backend. This results in a complex
initialization sequence partially done at realize and later at reset,
and some memory region leaks.

To simplify this sequence and to remove of the late initialization of
the emulated device which is required to be done only once, we
introduce new memory regions specific for KVM. These regions are
mapped as overlaps on top of the emulated device to make use of the
host MMIOs. Also provide proper cleanups of these regions when the
XIVE KVM device is destroyed to fix the leaks.

Signed-off-by: Cédric Le Goater 
Message-Id: <20190614165920.12670-2-...@kaod.org>
Reviewed-by: Greg Kurz 
Signed-off-by: David Gibson 
---
 hw/intc/spapr_xive.c| 38 ++---
 hw/intc/spapr_xive_kvm.c| 21 +++-
 hw/ppc/spapr_irq.c  |  1 -
 include/hw/ppc/spapr_xive.h |  2 +-
 include/hw/ppc/xive.h   |  1 +
 5 files changed, 24 insertions(+), 39 deletions(-)

diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 58c2e5d890..3ae311d9ff 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -194,13 +194,6 @@ void spapr_xive_pic_print_info(SpaprXive *xive, Monitor 
*mon)
 }
 }
 
-void spapr_xive_map_mmio(SpaprXive *xive)
-{
-sysbus_mmio_map(SYS_BUS_DEVICE(xive), 0, xive->vc_base);
-sysbus_mmio_map(SYS_BUS_DEVICE(xive), 1, xive->end_base);
-sysbus_mmio_map(SYS_BUS_DEVICE(xive), 2, xive->tm_base);
-}
-
 void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable)
 {
 memory_region_set_enabled(&xive->source.esb_mmio, enable);
@@ -305,6 +298,7 @@ static void spapr_xive_realize(DeviceState *dev, Error 
**errp)
 error_propagate(errp, local_err);
 return;
 }
+sysbus_init_mmio(SYS_BUS_DEVICE(xive), &xsrc->esb_mmio);
 
 /*
  * Initialize the END ESB source
@@ -318,6 +312,7 @@ static void spapr_xive_realize(DeviceState *dev, Error 
**errp)
 error_propagate(errp, local_err);
 return;
 }
+sysbus_init_mmio(SYS_BUS_DEVICE(xive), &end_xsrc->esb_mmio);
 
 /* Set the mapping address of the END ESB pages after the source ESBs */
 xive->end_base = xive->vc_base + (1ull << xsrc->esb_shift) * xsrc->nr_irqs;
@@ -333,31 +328,18 @@ static void spapr_xive_realize(DeviceState *dev, Error 
**errp)
 
 qemu_register_reset(spapr_xive_reset, dev);
 
-/* Define all XIVE MMIO regions on SysBus */
-sysbus_init_mmio(SYS_BUS_DEVICE(xive), &xsrc->esb_mmio);
-sysbus_init_mmio(SYS_BUS_DEVICE(xive), &end_xsrc->esb_mmio);
-sysbus_init_mmio(SYS_BUS_DEVICE(xive), &xive->tm_mmio);
-}
-
-void spapr_xive_init(SpaprXive *xive, Error **errp)
-{
-XiveSource *xsrc = &xive->source;
-
-/*
- * The emulated XIVE device can only be initialized once. If the
- * ESB memory region has been already mapped, it means we have been
- * through there.
- */
-if (memory_region_is_mapped(&xsrc->esb_mmio)) {
-return;
-}
-
 /* TIMA initialization */
 memory_region_init_io(&xive->tm_mmio, OBJECT(xive), &xive_tm_ops, xive,
   "xive.tima", 4ull << TM_SHIFT);
+sysbus_init_mmio(SYS_BUS_DEVICE(xive), &xive->tm_mmio);
 
-/* Map all regions */
-spapr_xive_map_mmio(xive);
+/*
+ * Map all regions. These will be enabled or disabled at reset and
+ * can also be overridden by KVM memory regions if active
+ */
+sysbus_mmio_map(SYS_BUS_DEVICE(xive), 0, xive->vc_base);
+sysbus_mmio_map(SYS_BUS_DEVICE(xive), 1, xive->end_base);
+sysbus_mmio_map(SYS_BUS_DEVICE(xive), 2, xive->tm_base);
 }
 
 static int spapr_xive_get_eas(XiveRouter *xrtr, uint8_t eas_blk,
diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
index b48f135838..5559f8bce5 100644
--- a/hw/intc/spapr_xive_kvm.c
+++ b/hw/intc/spapr_xive_kvm.c
@@ -728,8 +728,10 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp)
 return;
 }
 
-memory_region_init_ram_device_ptr(&xsrc->esb_mmio, OBJECT(xsrc),
+memory_region_init_ram_device_ptr(&xsrc->esb_mmio_kvm, OBJECT(xsrc),
   "xive.esb", esb_len, xsrc->esb_mmap);
+memory_region_add_subregion_overlap(&xsrc->esb_mmio, 0,
+&xsrc->esb_mmio_kvm, 1);
 
 /*
  * 2. END ESB pages (No KVM support yet)
@@ -744,8 +746,10 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp)
 error_propagate(errp, local_err);
 return;
 }
-memory_region_init_ram_device_ptr(&xive->tm_mmio, OBJECT(xive),
+memory_region_init_ram_device_ptr(&xive->tm_mmio_kvm, OBJECT(xive),
   "xive.tima", tima_len, xive->tm_mmap);
+memory_region_add_subregion_overlap(&xive->tm_mmio, 0,

[Qemu-devel] [PULL 42/49] spapr_pci: Unregister listeners before destroying the IOMMU address space

2019-07-01 Thread David Gibson
From: Greg Kurz 

Hot-unplugging a PHB with a VFIO device connected to it crashes QEMU:

-device spapr-pci-host-bridge,index=1,id=phb1 \
-device vfio-pci,host=0034:01:00.3,id=vfio0

(qemu) device_del phb1
[  357.207183] iommu: Removing device 0001:00:00.0 from group 1
[  360.375523] rpadlpar_io: slot PHB 1 removed
qemu-system-ppc64: memory.c:2742:
 do_address_space_destroy: Assertion `QTAILQ_EMPTY(&as->listeners)' failed.

'as' is the IOMMU address space, which indeed has a listener registered
to by vfio_connect_container() when the VFIO device is realized. This
listener is supposed to be unregistered by vfio_disconnect_container()
when the VFIO device is finalized. Unfortunately, the VFIO device hasn't
reached finalize yet at the time the PHB unrealize function is called,
and address_space_destroy() gets called with the VFIO listener still
being registered.

All regions have just been unmapped from the address space. Listeners
aren't needed anymore at this point. Remove them before destroying the
address space.

The VFIO code will try to remove them _again_ at device finalize,
but it is okay since memory_listener_unregister() is idempotent.

Signed-off-by: Greg Kurz 
Message-Id: <156110925375.92514.11649846071216864570.st...@bahia.lan>
Reviewed-by: Alexey Kardashevskiy 
[dwg: Correct spelling error pointed out by aik]
Signed-off-by: David Gibson 
---
 hw/ppc/spapr_pci.c|  6 ++
 include/exec/memory.h | 10 ++
 memory.c  |  7 +++
 3 files changed, 23 insertions(+)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 5591723bb2..9003fe9010 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1788,6 +1788,12 @@ static void spapr_phb_unrealize(DeviceState *dev, Error 
**errp)
 
 memory_region_del_subregion(&sphb->iommu_root, &sphb->msiwindow);
 
+/*
+ * An attached PCI device may have memory listeners, eg. VFIO PCI. We have
+ * unmapped all sections. Remove the listeners now, before destroying the
+ * address space.
+ */
+address_space_remove_listeners(&sphb->iommu_as);
 address_space_destroy(&sphb->iommu_as);
 
 qbus_set_hotplug_handler(BUS(phb->bus), NULL, &error_abort);
diff --git a/include/exec/memory.h b/include/exec/memory.h
index e6140e8a04..2c5cdffa31 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -1757,6 +1757,16 @@ void address_space_init(AddressSpace *as, MemoryRegion 
*root, const char *name);
  */
 void address_space_destroy(AddressSpace *as);
 
+/**
+ * address_space_remove_listeners: unregister all listeners of an address space
+ *
+ * Removes all callbacks previously registered with memory_listener_register()
+ * for @as.
+ *
+ * @as: an initialized #AddressSpace
+ */
+void address_space_remove_listeners(AddressSpace *as);
+
 /**
  * address_space_rw: read from or write to an address space.
  *
diff --git a/memory.c b/memory.c
index 0a089a73ae..480f3d989b 100644
--- a/memory.c
+++ b/memory.c
@@ -2723,6 +2723,13 @@ void memory_listener_unregister(MemoryListener *listener)
 listener->address_space = NULL;
 }
 
+void address_space_remove_listeners(AddressSpace *as)
+{
+while (!QTAILQ_EMPTY(&as->listeners)) {
+memory_listener_unregister(QTAILQ_FIRST(&as->listeners));
+}
+}
+
 void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
 {
 memory_region_ref(root);
-- 
2.21.0




[Qemu-devel] [PULL 28/49] target/ppc/machine: Add kvmppc_pvr_workaround_required() stub

2019-07-01 Thread David Gibson
From: Greg Kurz 

This allows to drop the CONFIG_KVM guard from the code.

Signed-off-by: Greg Kurz 
Message-Id: <156051056289.224162.15553539098911498678.st...@bahia.lan>
Signed-off-by: David Gibson 
---
 target/ppc/kvm_ppc.h | 5 +
 target/ppc/machine.c | 2 --
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
index e642aaaf92..98bd7d5da6 100644
--- a/target/ppc/kvm_ppc.h
+++ b/target/ppc/kvm_ppc.h
@@ -399,6 +399,11 @@ static inline int kvmppc_resize_hpt_commit(PowerPCCPU *cpu,
 return -ENOSYS;
 }
 
+static inline bool kvmppc_pvr_workaround_required(PowerPCCPU *cpu)
+{
+return false;
+}
+
 #endif
 
 #ifndef CONFIG_KVM
diff --git a/target/ppc/machine.c b/target/ppc/machine.c
index 5ad7b40f45..e82f5de9db 100644
--- a/target/ppc/machine.c
+++ b/target/ppc/machine.c
@@ -378,11 +378,9 @@ static int cpu_post_load(void *opaque, int version_id)
  * receive the PVR it expects as a workaround.
  *
  */
-#if defined(CONFIG_KVM)
 if (kvmppc_pvr_workaround_required(cpu)) {
 env->spr[SPR_PVR] = env->spr_cb[SPR_PVR].default_value;
 }
-#endif
 
 env->lr = env->spr[SPR_LR];
 env->ctr = env->spr[SPR_CTR];
-- 
2.21.0




[Qemu-devel] [PULL 07/49] xics/spapr: Prevent RTAS/hypercalls emulation to be used by in-kernel XICS

2019-07-01 Thread David Gibson
From: Greg Kurz 

The XICS-related RTAS calls and hypercalls in QEMU are not supposed to
be called when the KVM in-kernel XICS is in use.

Add some explicit checks to detect that, print an error message and report
an hardware error to the guest.

Signed-off-by: Greg Kurz 
Message-Id: 
<156044429419.125694.507569071972451514.st...@bahia.lab.toulouse-stg.fr.ibm.com>
[dwg: Correction to commit message]
Signed-off-by: David Gibson 
---
 hw/intc/xics_spapr.c | 46 
 1 file changed, 46 insertions(+)

diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 5a1835e8b1..d470ab5f7a 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -41,11 +41,31 @@
  * Guest interfaces
  */
 
+static bool check_in_kernel_xics(const char *func)
+{
+if (kvm_irqchip_in_kernel()) {
+error_report("pseries: %s must never be called for in-kernel XICS",
+ func);
+return true;
+}
+
+return false;
+}
+
+#define CHECK_IN_KERNEL_XICS_HCALL  \
+do {\
+if (check_in_kernel_xics(__func__)) {   \
+return H_HARDWARE;  \
+}   \
+} while (0)
+
 static target_ulong h_cppr(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
 {
 target_ulong cppr = args[0];
 
+CHECK_IN_KERNEL_XICS_HCALL;
+
 icp_set_cppr(spapr_cpu_state(cpu)->icp, cppr);
 return H_SUCCESS;
 }
@@ -56,6 +76,8 @@ static target_ulong h_ipi(PowerPCCPU *cpu, SpaprMachineState 
*spapr,
 target_ulong mfrr = args[1];
 ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), args[0]);
 
+CHECK_IN_KERNEL_XICS_HCALL;
+
 if (!icp) {
 return H_PARAMETER;
 }
@@ -69,6 +91,8 @@ static target_ulong h_xirr(PowerPCCPU *cpu, SpaprMachineState 
*spapr,
 {
 uint32_t xirr = icp_accept(spapr_cpu_state(cpu)->icp);
 
+CHECK_IN_KERNEL_XICS_HCALL;
+
 args[0] = xirr;
 return H_SUCCESS;
 }
@@ -78,6 +102,8 @@ static target_ulong h_xirr_x(PowerPCCPU *cpu, 
SpaprMachineState *spapr,
 {
 uint32_t xirr = icp_accept(spapr_cpu_state(cpu)->icp);
 
+CHECK_IN_KERNEL_XICS_HCALL;
+
 args[0] = xirr;
 args[1] = cpu_get_host_ticks();
 return H_SUCCESS;
@@ -88,6 +114,8 @@ static target_ulong h_eoi(PowerPCCPU *cpu, SpaprMachineState 
*spapr,
 {
 target_ulong xirr = args[0];
 
+CHECK_IN_KERNEL_XICS_HCALL;
+
 icp_eoi(spapr_cpu_state(cpu)->icp, xirr);
 return H_SUCCESS;
 }
@@ -99,6 +127,8 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, 
SpaprMachineState *spapr,
 uint32_t mfrr;
 uint32_t xirr;
 
+CHECK_IN_KERNEL_XICS_HCALL;
+
 if (!icp) {
 return H_PARAMETER;
 }
@@ -111,6 +141,14 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, 
SpaprMachineState *spapr,
 return H_SUCCESS;
 }
 
+#define CHECK_IN_KERNEL_XICS_RTAS(rets) \
+do {\
+if (check_in_kernel_xics(__func__)) {   \
+rtas_st((rets), 0, RTAS_OUT_HW_ERROR);  \
+return; \
+}   \
+} while (0)
+
 static void rtas_set_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
   uint32_t token,
   uint32_t nargs, target_ulong args,
@@ -119,6 +157,8 @@ static void rtas_set_xive(PowerPCCPU *cpu, 
SpaprMachineState *spapr,
 ICSState *ics = spapr->ics;
 uint32_t nr, srcno, server, priority;
 
+CHECK_IN_KERNEL_XICS_RTAS(rets);
+
 if ((nargs != 3) || (nret != 1)) {
 rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
 return;
@@ -152,6 +192,8 @@ static void rtas_get_xive(PowerPCCPU *cpu, 
SpaprMachineState *spapr,
 ICSState *ics = spapr->ics;
 uint32_t nr, srcno;
 
+CHECK_IN_KERNEL_XICS_RTAS(rets);
+
 if ((nargs != 1) || (nret != 3)) {
 rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
 return;
@@ -182,6 +224,8 @@ static void rtas_int_off(PowerPCCPU *cpu, SpaprMachineState 
*spapr,
 ICSState *ics = spapr->ics;
 uint32_t nr, srcno;
 
+CHECK_IN_KERNEL_XICS_RTAS(rets);
+
 if ((nargs != 1) || (nret != 1)) {
 rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
 return;
@@ -213,6 +257,8 @@ static void rtas_int_on(PowerPCCPU *cpu, SpaprMachineState 
*spapr,
 ICSState *ics = spapr->ics;
 uint32_t nr, srcno;
 
+CHECK_IN_KERNEL_XICS_RTAS(rets);
+
 if ((nargs != 1) || (nret != 1)) {
 rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
 return;
-- 
2.21.0




[Qemu-devel] [PULL 14/49] spapr_pci: Fix DRC owner in spapr_dt_pci_bus()

2019-07-01 Thread David Gibson
From: Greg Kurz 

spapr_dt_drc() scans the aliases of all DRConnector objects and filters
the ones that it will use to generate OF properties according to their
owner and type.

Passing bus->parent_dev _works_ if bus belongs to a PCI bridge, but it is
NULL if it is the PHB's root bus. This causes all allocated PCI DRCs to
be associated to all PHBs (visible in their "ibm,drc-types" properties).
As a consequence, hot unplugging a PHB results in PCI devices from the
other PHBs to be unplugged as well, and likely confuses the guest.

Use the same logic as in add_drcs() to ensure the correct owner is passed
to spapr_dt_drc().

Fixes: 14e714900f6b "spapr: Allow hot plug/unplug of PCI bridges and devices 
under PCI bridges"
Signed-off-by: Greg Kurz 
Message-Id: <156084737348.512412.3552825999605902691.st...@bahia.lan>
Signed-off-by: David Gibson 
---
 hw/ppc/spapr_pci.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index fbeb1c90ee..2dca1e57f3 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1343,6 +1343,7 @@ static void spapr_dt_pci_device_cb(PCIBus *bus, PCIDevice 
*pdev,
 static int spapr_dt_pci_bus(SpaprPhbState *sphb, PCIBus *bus,
void *fdt, int offset)
 {
+Object *owner;
 PciWalkFdt cbinfo = {
 .fdt = fdt,
 .offset = offset,
@@ -1363,7 +1364,13 @@ static int spapr_dt_pci_bus(SpaprPhbState *sphb, PCIBus 
*bus,
 return cbinfo.err;
 }
 
-ret = spapr_dt_drc(fdt, offset, OBJECT(bus->parent_dev),
+if (pci_bus_is_root(bus)) {
+owner = OBJECT(sphb);
+} else {
+owner = OBJECT(pci_bridge_get_device(bus));
+}
+
+ret = spapr_dt_drc(fdt, offset, owner,
SPAPR_DR_CONNECTOR_TYPE_PCI);
 if (ret) {
 return ret;
-- 
2.21.0




[Qemu-devel] [PULL 16/49] spapr_pci: Drop useless CONFIG_KVM ifdefery

2019-07-01 Thread David Gibson
From: Greg Kurz 

kvm_enabled() expands to (0) when CONFIG_KVM is not defined.

Signed-off-by: Greg Kurz 
Message-Id: <156051052977.224162.17306829691809502082.st...@bahia.lan>
Signed-off-by: David Gibson 
---
 hw/ppc/spapr_pci.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 2dca1e57f3..5591723bb2 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1951,11 +1951,9 @@ static void spapr_phb_realize(DeviceState *dev, Error 
**errp)
  * For KVM we want to ensure that this memory is a full page so that
  * our memory slot is of page size granularity.
  */
-#ifdef CONFIG_KVM
 if (kvm_enabled()) {
 msi_window_size = getpagesize();
 }
-#endif
 
 memory_region_init_io(&sphb->msiwindow, OBJECT(sphb), &spapr_msi_ops, 
spapr,
   "msi", msi_window_size);
-- 
2.21.0




[Qemu-devel] [PULL 15/49] xics/spapr: Only emulated XICS should use RTAS/hypercalls emulation

2019-07-01 Thread David Gibson
From: Greg Kurz 

Checking that we're not using the in-kernel XICS is ok with the "xics"
interrupt controller mode, but it is definitely not enough with the
other modes since the guest could be using XIVE.

Ensure XIVE is not in use when emulated XICS RTAS/hypercalls are
called.

Signed-off-by: Greg Kurz 
Message-Id: <156077253666.424706.6104557911104491047.st...@bahia.lan>
Reviewed-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 hw/intc/xics_spapr.c | 53 ++--
 1 file changed, 27 insertions(+), 26 deletions(-)

diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 8d605b68a7..7cd3c93d71 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -41,22 +41,23 @@
  * Guest interfaces
  */
 
-static bool check_in_kernel_xics(const char *func)
+static bool check_emulated_xics(SpaprMachineState *spapr, const char *func)
 {
-if (kvm_irqchip_in_kernel()) {
-error_report("pseries: %s must never be called for in-kernel XICS",
+if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT) ||
+kvm_irqchip_in_kernel()) {
+error_report("pseries: %s must only be called for emulated XICS",
  func);
-return true;
+return false;
 }
 
-return false;
+return true;
 }
 
-#define CHECK_IN_KERNEL_XICS_HCALL  \
-do {\
-if (check_in_kernel_xics(__func__)) {   \
-return H_HARDWARE;  \
-}   \
+#define CHECK_EMULATED_XICS_HCALL(spapr)   \
+do {   \
+if (!check_emulated_xics((spapr), __func__)) { \
+return H_HARDWARE; \
+}  \
 } while (0)
 
 static target_ulong h_cppr(PowerPCCPU *cpu, SpaprMachineState *spapr,
@@ -64,7 +65,7 @@ static target_ulong h_cppr(PowerPCCPU *cpu, SpaprMachineState 
*spapr,
 {
 target_ulong cppr = args[0];
 
-CHECK_IN_KERNEL_XICS_HCALL;
+CHECK_EMULATED_XICS_HCALL(spapr);
 
 icp_set_cppr(spapr_cpu_state(cpu)->icp, cppr);
 return H_SUCCESS;
@@ -76,7 +77,7 @@ static target_ulong h_ipi(PowerPCCPU *cpu, SpaprMachineState 
*spapr,
 target_ulong mfrr = args[1];
 ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), args[0]);
 
-CHECK_IN_KERNEL_XICS_HCALL;
+CHECK_EMULATED_XICS_HCALL(spapr);
 
 if (!icp) {
 return H_PARAMETER;
@@ -91,7 +92,7 @@ static target_ulong h_xirr(PowerPCCPU *cpu, SpaprMachineState 
*spapr,
 {
 uint32_t xirr = icp_accept(spapr_cpu_state(cpu)->icp);
 
-CHECK_IN_KERNEL_XICS_HCALL;
+CHECK_EMULATED_XICS_HCALL(spapr);
 
 args[0] = xirr;
 return H_SUCCESS;
@@ -102,7 +103,7 @@ static target_ulong h_xirr_x(PowerPCCPU *cpu, 
SpaprMachineState *spapr,
 {
 uint32_t xirr = icp_accept(spapr_cpu_state(cpu)->icp);
 
-CHECK_IN_KERNEL_XICS_HCALL;
+CHECK_EMULATED_XICS_HCALL(spapr);
 
 args[0] = xirr;
 args[1] = cpu_get_host_ticks();
@@ -114,7 +115,7 @@ static target_ulong h_eoi(PowerPCCPU *cpu, 
SpaprMachineState *spapr,
 {
 target_ulong xirr = args[0];
 
-CHECK_IN_KERNEL_XICS_HCALL;
+CHECK_EMULATED_XICS_HCALL(spapr);
 
 icp_eoi(spapr_cpu_state(cpu)->icp, xirr);
 return H_SUCCESS;
@@ -127,7 +128,7 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, 
SpaprMachineState *spapr,
 uint32_t mfrr;
 uint32_t xirr;
 
-CHECK_IN_KERNEL_XICS_HCALL;
+CHECK_EMULATED_XICS_HCALL(spapr);
 
 if (!icp) {
 return H_PARAMETER;
@@ -141,12 +142,12 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, 
SpaprMachineState *spapr,
 return H_SUCCESS;
 }
 
-#define CHECK_IN_KERNEL_XICS_RTAS(rets) \
-do {\
-if (check_in_kernel_xics(__func__)) {   \
-rtas_st((rets), 0, RTAS_OUT_HW_ERROR);  \
-return; \
-}   \
+#define CHECK_EMULATED_XICS_RTAS(spapr, rets)  \
+do {   \
+if (!check_emulated_xics((spapr), __func__)) { \
+rtas_st((rets), 0, RTAS_OUT_HW_ERROR); \
+return;\
+}  \
 } while (0)
 
 static void rtas_set_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
@@ -157,7 +158,7 @@ static void rtas_set_xive(PowerPCCPU *cpu, 
SpaprMachineState *spapr,
 ICSState *ics = spapr->ics;
 uint32_t nr, srcno, server, priority;
 
-CHECK_IN_KERNEL_XICS_RTAS(rets);
+CHECK_EMULATED_XICS_RTAS(spapr, rets);
 
 if ((nargs != 3) || (nret != 1)) {
 rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
@@ -192,7 +193,7 @@ static void rtas_get_xive(PowerPCCPU *cpu, 
SpaprMachineState *spapr,
 ICSState *ics = spapr->ics;
 uint3

[Qemu-devel] [PULL 22/49] xics/spapr: Rename xics_kvm_init()

2019-07-01 Thread David Gibson
From: Greg Kurz 

Switch to using the connect/disconnect terminology like we already do for
XIVE.

Signed-off-by: Greg Kurz 
Message-Id: <156077920102.433243.6605099291134598170.st...@bahia.lan>
Reviewed-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 hw/intc/xics_kvm.c  | 2 +-
 hw/ppc/spapr_irq.c  | 2 +-
 include/hw/ppc/xics_spapr.h | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index c7f8f5edd2..534515143e 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -331,7 +331,7 @@ void ics_kvm_set_irq(ICSState *ics, int srcno, int val)
 }
 }
 
-int xics_kvm_init(SpaprMachineState *spapr, Error **errp)
+int xics_kvm_connect(SpaprMachineState *spapr, Error **errp)
 {
 int rc;
 CPUState *cs;
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 75654fc67a..b2b01e850d 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -243,7 +243,7 @@ static void spapr_irq_init_emu_xics(SpaprMachineState 
*spapr, Error **errp)
 static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
 {
 if (kvm_enabled()) {
-xics_kvm_init(spapr, errp);
+xics_kvm_connect(spapr, errp);
 }
 }
 
diff --git a/include/hw/ppc/xics_spapr.h b/include/hw/ppc/xics_spapr.h
index 3304481262..5dabc9a138 100644
--- a/include/hw/ppc/xics_spapr.h
+++ b/include/hw/ppc/xics_spapr.h
@@ -33,7 +33,7 @@
 
 void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
uint32_t phandle);
-int xics_kvm_init(SpaprMachineState *spapr, Error **errp);
+int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);
 void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp);
 bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr);
 void xics_spapr_init(SpaprMachineState *spapr);
-- 
2.21.0




[Qemu-devel] [PULL 08/49] xics/spapr: Register RTAS/hypercalls once at machine init

2019-07-01 Thread David Gibson
From: Greg Kurz 

QEMU may crash when running a spapr machine in 'dual' interrupt controller
mode on some older (but not that old, eg. ubuntu 18.04.2) KVMs with partial
XIVE support:

qemu-system-ppc64: hw/ppc/spapr_rtas.c:411: spapr_rtas_register:
 Assertion `!name || !rtas_table[token].name' failed.

XICS is controlled by the guest thanks to a set of RTAS calls. Depending
on whether KVM XICS is used or not, the RTAS calls are handled by KVM or
QEMU. In both cases, QEMU needs to expose the RTAS calls to the guest
through the "rtas" node of the device tree.

The spapr_rtas_register() helper takes care of all of that: it adds the
RTAS call token to the "rtas" node and registers a QEMU callback to be
invoked when the guest issues the RTAS call. In the KVM XICS case, QEMU
registers a dummy callback that just prints an error since it isn't
supposed to be invoked, ever.

Historically, the XICS controller was setup during machine init and
released during final teardown. This changed when the 'dual' interrupt
controller mode was added to the spapr machine: in this case we need
to tear the XICS down and set it up again during machine reset. The
crash happens because we indeed have an incompatibility with older
KVMs that forces QEMU to fallback on emulated XICS, which tries to
re-registers the same RTAS calls.

This could be fixed by adding proper rollback that would unregister
RTAS calls on error. But since the emulated RTAS calls in QEMU can
now detect when they are mistakenly called while KVM XICS is in
use, it seems simpler to register them once and for all at machine
init. This fixes the crash and allows to remove some now useless
lines of code.

Signed-off-by: Greg Kurz 
Message-Id: 
<156044429963.125694.13710679451927268758.st...@bahia.lab.toulouse-stg.fr.ibm.com>
Signed-off-by: David Gibson 
---
 hw/intc/xics_kvm.c  | 19 ---
 hw/intc/xics_spapr.c|  8 
 hw/ppc/spapr_irq.c  |  3 ++-
 include/hw/ppc/spapr.h  |  4 
 include/hw/ppc/xics.h   |  1 -
 include/hw/ppc/xics_spapr.h |  1 +
 6 files changed, 3 insertions(+), 33 deletions(-)

diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 5ba5b77561..5c4208f430 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -331,15 +331,6 @@ void ics_kvm_set_irq(ICSState *ics, int srcno, int val)
 }
 }
 
-static void rtas_dummy(PowerPCCPU *cpu, SpaprMachineState *spapr,
-   uint32_t token,
-   uint32_t nargs, target_ulong args,
-   uint32_t nret, target_ulong rets)
-{
-error_report("pseries: %s must never be called for in-kernel XICS",
- __func__);
-}
-
 int xics_kvm_init(SpaprMachineState *spapr, Error **errp)
 {
 int rc;
@@ -360,11 +351,6 @@ int xics_kvm_init(SpaprMachineState *spapr, Error **errp)
 goto fail;
 }
 
-spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_dummy);
-spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_dummy);
-spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_dummy);
-spapr_rtas_register(RTAS_IBM_INT_ON, "ibm,int-on", rtas_dummy);
-
 rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_SET_XIVE, "ibm,set-xive");
 if (rc < 0) {
 error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,set-xive");
@@ -454,11 +440,6 @@ void xics_kvm_disconnect(SpaprMachineState *spapr, Error 
**errp)
 close(kernel_xics_fd);
 kernel_xics_fd = -1;
 
-spapr_rtas_unregister(RTAS_IBM_SET_XIVE);
-spapr_rtas_unregister(RTAS_IBM_GET_XIVE);
-spapr_rtas_unregister(RTAS_IBM_INT_OFF);
-spapr_rtas_unregister(RTAS_IBM_INT_ON);
-
 kvmppc_define_rtas_kernel_token(0, "ibm,set-xive");
 kvmppc_define_rtas_kernel_token(0, "ibm,get-xive");
 kvmppc_define_rtas_kernel_token(0, "ibm,int-on");
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index d470ab5f7a..8d605b68a7 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -285,14 +285,6 @@ static void rtas_int_on(PowerPCCPU *cpu, SpaprMachineState 
*spapr,
 
 void xics_spapr_init(SpaprMachineState *spapr)
 {
-/* Emulated mode can only be initialized once. */
-if (spapr->ics->init) {
-return;
-}
-
-spapr->ics->init = true;
-
-/* Registration of global state belongs into realize */
 spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_set_xive);
 spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_get_xive);
 spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_int_off);
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 3156daf093..dfb99f35ea 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -114,6 +114,8 @@ static void spapr_irq_init_xics(SpaprMachineState *spapr, 
int nr_irqs,
 }
 
 spapr->ics = ICS_BASE(obj);
+
+xics_spapr_init(spapr);
 }
 
 #define ICS_IRQ_FREE(ics, srcno)   \
@@ -236,7 +238,6 @@ static const char 
*spapr_irq_get_nodename_xics(SpaprMachineState *spapr)
 
 static vo

[Qemu-devel] [PULL 17/49] hw/ppc/mac_oldworld: Drop useless CONFIG_KVM ifdefery

2019-07-01 Thread David Gibson
From: Greg Kurz 

kvm_enabled() expands to (0) when CONFIG_KVM is not defined. It is
likely that the compiler will optimize the code out. And even if
it doesn't, we have a stub for kvmppc_get_hypercall().

Signed-off-by: Greg Kurz 
Message-Id: <156051053529.224162.3489943067148134636.st...@bahia.lan>
Signed-off-by: David Gibson 
---
 hw/ppc/mac_oldworld.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index eddd005a7c..da751addc4 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -345,14 +345,12 @@ static void ppc_heathrow_init(MachineState *machine)
 
 fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled());
 if (kvm_enabled()) {
-#ifdef CONFIG_KVM
 uint8_t *hypercall;
 
 hypercall = g_malloc(16);
 kvmppc_get_hypercall(env, hypercall, 16);
 fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
 fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
-#endif
 }
 fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, tbfreq);
 /* Mac OS X requires a "known good" clock-frequency value; pass it one. */
-- 
2.21.0




[Qemu-devel] [PULL 10/49] target/ppc: fix compile error in kvmppc_define_rtas_kernel_token()

2019-07-01 Thread David Gibson
From: Cédric Le Goater 

gcc9 reports :

In file included from /usr/include/string.h:494,
 from ./include/qemu/osdep.h:101,
 from ./target/ppc/kvm.c:17:
In function ‘strncpy’,
inlined from ‘kvmppc_define_rtas_kernel_token’ at ./target/ppc/kvm.c:2648:5:
/usr/include/bits/string_fortified.h:106:10: error: ‘__builtin_strncpy’ 
specified bound 120 equals destination size [-Werror=stringop-truncation]
  106 |   return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
  |  ^~

Signed-off-by: Cédric Le Goater 
Message-Id: <20190615081252.28602-1-...@kaod.org>
Signed-off-by: David Gibson 
---
 target/ppc/kvm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 4b4989c0af..9014ed029f 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -2650,7 +2650,7 @@ int kvmppc_define_rtas_kernel_token(uint32_t token, const 
char *function)
 return -ENOENT;
 }
 
-strncpy(args.name, function, sizeof(args.name));
+strncpy(args.name, function, sizeof(args.name) - 1);
 
 return kvm_vm_ioctl(kvm_state, KVM_PPC_RTAS_DEFINE_TOKEN, &args);
 }
-- 
2.21.0




[Qemu-devel] [PULL 13/49] target/ppc: remove getVSR()/putVSR() from mem_helper.c

2019-07-01 Thread David Gibson
From: Mark Cave-Ayland 

Since commit 8a14d31b00 "target/ppc: switch fpr/vsrl registers so all VSX
registers are in host endian order" functions getVSR() and putVSR() which used
to convert the VSR registers into host endian order are no longer required.

Signed-off-by: Mark Cave-Ayland 
Message-Id: <20190616123751.781-3-mark.cave-ayl...@ilande.co.uk>
Reviewed-by: Richard Henderson 
Signed-off-by: David Gibson 
---
 target/ppc/mem_helper.c | 23 ---
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/target/ppc/mem_helper.c b/target/ppc/mem_helper.c
index 5b0f9ee50d..87632ccf53 100644
--- a/target/ppc/mem_helper.c
+++ b/target/ppc/mem_helper.c
@@ -417,26 +417,27 @@ STVE(stvewx, cpu_stl_data_ra, bswap32, u32)
 void helper_##name(CPUPPCState *env, target_ulong addr, \
target_ulong xt_num, target_ulong rb)\
 {   \
-int i;  \
-ppc_vsr_t xt;   \
+ppc_vsr_t *xt = &env->vsr[xt_num];  \
+ppc_vsr_t t;\
 uint64_t nb = GET_NB(rb);   \
+int i;  \
 \
-xt.s128 = int128_zero();\
+t.s128 = int128_zero(); \
 if (nb) {   \
 nb = (nb >= 16) ? 16 : nb;  \
 if (msr_le && !lj) {\
 for (i = 16; i > 16 - nb; i--) {\
-xt.VsrB(i - 1) = cpu_ldub_data_ra(env, addr, GETPC());  \
+t.VsrB(i - 1) = cpu_ldub_data_ra(env, addr, GETPC());   \
 addr = addr_add(env, addr, 1);  \
 }   \
 } else {\
 for (i = 0; i < nb; i++) {  \
-xt.VsrB(i) = cpu_ldub_data_ra(env, addr, GETPC());  \
+t.VsrB(i) = cpu_ldub_data_ra(env, addr, GETPC());   \
 addr = addr_add(env, addr, 1);  \
 }   \
 }   \
 }   \
-putVSR(xt_num, &xt, env);   \
+*xt = t;\
 }
 
 VSX_LXVL(lxvl, 0)
@@ -447,23 +448,23 @@ VSX_LXVL(lxvll, 1)
 void helper_##name(CPUPPCState *env, target_ulong addr,   \
target_ulong xt_num, target_ulong rb)  \
 { \
-int i;\
-ppc_vsr_t xt; \
+ppc_vsr_t *xt = &env->vsr[xt_num];\
 target_ulong nb = GET_NB(rb); \
+int i;\
   \
 if (!nb) {\
 return;   \
 } \
-getVSR(xt_num, &xt, env); \
+  \
 nb = (nb >= 16) ? 16 : nb;\
 if (msr_le && !lj) {  \
 for (i = 16; i > 16 - nb; i--) {  \
-cpu_stb_data_ra(env, addr, xt.VsrB(i - 1), GETPC());  \
+cpu_stb_data_ra(env, addr, xt->VsrB(i - 1), GETPC()); \
 addr = addr_add(env, addr, 1);\
 } \
 } else {  \
 for (i = 0; i < nb; i++) {\
-cpu_stb_data_ra(env, addr, xt.VsrB(i), GETPC());  \
+cpu_stb_data_ra(env, addr, xt->VsrB(i), GETPC()); \
 addr = addr_add(env, addr, 1);\
 } \
 } \
-- 

[Qemu-devel] [PULL 02/49] docs: updates on the POWER9 XIVE interrupt controller documentation

2019-07-01 Thread David Gibson
From: Cédric Le Goater 

This includes various small updates and a better description of the
chosen interrupt mode resulting from the combination of the 'ic-mode'
machine option, the 'kernel_irqchip' option, guest support and KVM
support.

Signed-off-by: Cédric Le Goater 
Message-Id: <20190612160425.27670-1-...@kaod.org>
Signed-off-by: David Gibson 
---
 docs/specs/ppc-spapr-xive.rst | 112 --
 docs/specs/ppc-xive.rst   |   9 +--
 2 files changed, 111 insertions(+), 10 deletions(-)

diff --git a/docs/specs/ppc-spapr-xive.rst b/docs/specs/ppc-spapr-xive.rst
index 539ce7ca4e..7a64c9d049 100644
--- a/docs/specs/ppc-spapr-xive.rst
+++ b/docs/specs/ppc-spapr-xive.rst
@@ -34,19 +34,118 @@ CAS Negotiation
 ---
 
 QEMU advertises the supported interrupt modes in the device tree
-property "ibm,arch-vec-5-platform-support" in byte 23 and the OS
-Selection for XIVE is indicated in the "ibm,architecture-vec-5"
+property ``ibm,arch-vec-5-platform-support`` in byte 23 and the OS
+Selection for XIVE is indicated in the ``ibm,architecture-vec-5``
 property byte 23.
 
 The interrupt modes supported by the machine depend on the CPU type
 (POWER9 is required for XIVE) but also on the machine property
 ``ic-mode`` which can be set on the command line. It can take the
-following values: ``xics``, ``xive``, ``dual`` and currently ``xics``
-is the default but it may change in the future.
+following values: ``xics``, ``xive``, and ``dual`` which is the
+default mode. ``dual`` means that both modes XICS **and** XIVE are
+supported and if the guest OS supports XIVE, this mode will be
+selected.
 
 The choosen interrupt mode is activated after a reconfiguration done
 in a machine reset.
 
+KVM negotiation
+---
+
+When the guest starts under KVM, the capabilities of the host kernel
+and QEMU are also negotiated. Depending on the version of the host
+kernel, KVM will advertise the XIVE capability to QEMU or not.
+
+Nevertheless, the available interrupt modes in the machine should not
+depend on the XIVE KVM capability of the host. On older kernels
+without XIVE KVM support, QEMU will use the emulated XIVE device as a
+fallback and on newer kernels (>=5.2), the KVM XIVE device.
+
+As a final refinement, the user can also switch the use of the KVM
+device with the machine option ``kernel_irqchip``.
+
+
+XIVE support in KVM
+~~~
+
+For guest OSes supporting XIVE, the resulting interrupt modes on host
+kernels with XIVE KVM support are the following:
+
+==  =  =  
+ic-modekernel_irqchip
+--  --
+/   allowedoffon
+(default)
+==  =  =  
+dual (default)  XIVE KVM   XIVE emul. XIVE KVM
+xiveXIVE KVM   XIVE emul. XIVE KVM
+xicsXICS KVM   XICS emul. XICS KVM
+==  =  =  
+
+For legacy guest OSes without XIVE support, the resulting interrupt
+modes are the following:
+
+==  =  =  
+ic-modekernel_irqchip
+--  --
+/   allowedoffon
+(default)
+==  =  =  
+dual (default)  XICS KVM   XICS emul. XICS KVM
+xiveQEMU error(3)  QEMU error(3)  QEMU error(3)
+xicsXICS KVM   XICS emul. XICS KVM
+==  =  =  
+
+(3) QEMU fails at CAS with ``Guest requested unavailable interrupt
+mode (XICS), either don't set the ic-mode machine property or try
+ic-mode=xics or ic-mode=dual``
+
+
+No XIVE support in KVM
+~~
+
+For guest OSes supporting XIVE, the resulting interrupt modes on host
+kernels without XIVE KVM support are the following:
+
+==  =  =  
+ic-modekernel_irqchip
+--  --
+/   allowedoffon
+(default)
+==  =  =  
+dual (default)  XIVE emul.(1)  XIVE emul. QEMU error (2)
+xiveXIVE emul.(1)  XIVE emul. QEMU error (2)
+xicsXICS KVM   XICS emul. XICS KVM
+==  =  =  
+
+
+(1) QEMU warns with ``warning: kernel_irqchip requested but unavailable:
+IRQ_XIVE capability must be present for KVM``
+(2) QEMU fails with ``kernel_irqchip requested but unavailable:
+IRQ_XIVE capability must be present for KVM``
+
+
+For legacy guest OSes without XIVE support, the resulting interrupt
+modes are th

[Qemu-devel] [PULL 04/49] ppc/pnv: fix XSCOM MMIO base address for P9 machines with multiple chips

2019-07-01 Thread David Gibson
From: Cédric Le Goater 

The PNV_XSCOM_BASE and PNV_XSCOM_SIZE macros are specific to POWER8
and they are used when the device tree is populated and the MMIO
region created, even for POWER9 chips. This is not too much of a
problem today because we don't have important devices on the second
chip, but we might have oneday (PHBs).

Fix by using the appropriate macros in case of P9.

Signed-off-by: Cédric Le Goater 
Message-Id: <20190612174345.9799-2-...@kaod.org>
Signed-off-by: David Gibson 
---
 hw/ppc/pnv.c   | 24 
 hw/ppc/pnv_xscom.c | 17 -
 include/hw/ppc/pnv.h   |  3 +++
 include/hw/ppc/pnv_xscom.h |  2 +-
 4 files changed, 32 insertions(+), 14 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 9db43916ac..0d98a281f6 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -860,6 +860,14 @@ static void pnv_chip_power8_realize(DeviceState *dev, 
Error **errp)
 Pnv8Psi *psi8 = &chip8->psi;
 Error *local_err = NULL;
 
+/* XSCOM bridge is first */
+pnv_xscom_realize(chip, PNV_XSCOM_SIZE, &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(chip), 0, PNV_XSCOM_BASE(chip));
+
 pcc->parent_realize(dev, &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
@@ -1024,6 +1032,14 @@ static void pnv_chip_power9_realize(DeviceState *dev, 
Error **errp)
 Pnv9Psi *psi9 = &chip9->psi;
 Error *local_err = NULL;
 
+/* XSCOM bridge is first */
+pnv_xscom_realize(chip, PNV9_XSCOM_SIZE, &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(chip), 0, PNV9_XSCOM_BASE(chip));
+
 pcc->parent_realize(dev, &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
@@ -1206,14 +1222,6 @@ static void pnv_chip_realize(DeviceState *dev, Error 
**errp)
 PnvChip *chip = PNV_CHIP(dev);
 Error *error = NULL;
 
-/* XSCOM bridge */
-pnv_xscom_realize(chip, &error);
-if (error) {
-error_propagate(errp, error);
-return;
-}
-sysbus_mmio_map(SYS_BUS_DEVICE(chip), 0, PNV_XSCOM_BASE(chip));
-
 /* Cores */
 pnv_chip_core_realize(chip, &error);
 if (error) {
diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c
index 4e52885c9e..2b81c75f56 100644
--- a/hw/ppc/pnv_xscom.c
+++ b/hw/ppc/pnv_xscom.c
@@ -213,17 +213,17 @@ const MemoryRegionOps pnv_xscom_ops = {
 .endianness = DEVICE_BIG_ENDIAN,
 };
 
-void pnv_xscom_realize(PnvChip *chip, Error **errp)
+void pnv_xscom_realize(PnvChip *chip, uint64_t size, Error **errp)
 {
 SysBusDevice *sbd = SYS_BUS_DEVICE(chip);
 char *name;
 
 name = g_strdup_printf("xscom-%x", chip->chip_id);
 memory_region_init_io(&chip->xscom_mmio, OBJECT(chip), &pnv_xscom_ops,
-  chip, name, PNV_XSCOM_SIZE);
+  chip, name, size);
 sysbus_init_mmio(sbd, &chip->xscom_mmio);
 
-memory_region_init(&chip->xscom, OBJECT(chip), name, PNV_XSCOM_SIZE);
+memory_region_init(&chip->xscom, OBJECT(chip), name, size);
 address_space_init(&chip->xscom_as, &chip->xscom, name);
 g_free(name);
 }
@@ -265,12 +265,19 @@ static const char compat_p9[] = 
"ibm,power9-xscom\0ibm,xscom";
 
 int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset)
 {
-uint64_t reg[] = { cpu_to_be64(PNV_XSCOM_BASE(chip)),
-   cpu_to_be64(PNV_XSCOM_SIZE) };
+uint64_t reg[2];
 int xscom_offset;
 ForeachPopulateArgs args;
 char *name;
 
+if (pnv_chip_is_power9(chip)) {
+reg[0] = cpu_to_be64(PNV9_XSCOM_BASE(chip));
+reg[1] = cpu_to_be64(PNV9_XSCOM_SIZE);
+} else {
+reg[0] = cpu_to_be64(PNV_XSCOM_BASE(chip));
+reg[1] = cpu_to_be64(PNV_XSCOM_SIZE);
+}
+
 name = g_strdup_printf("xscom@%" PRIx64, be64_to_cpu(reg[0]));
 xscom_offset = fdt_add_subnode(fdt, root_offset, name);
 _FDT(xscom_offset);
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index fc4678f757..01ac9e7996 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -256,4 +256,7 @@ void pnv_bmc_powerdown(IPMIBmc *bmc);
 #define PNV9_PSIHB_ESB_SIZE  0x0001ull
 #define PNV9_PSIHB_ESB_BASE(chip)PNV9_CHIP_BASE(chip, 
0x00060302031cull)
 
+#define PNV9_XSCOM_SIZE  0x0004ull
+#define PNV9_XSCOM_BASE(chip)PNV9_CHIP_BASE(chip, 0x00603fcull)
+
 #endif /* PPC_PNV_H */
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index c842d950d2..67641ed278 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -87,7 +87,7 @@ typedef struct PnvXScomInterfaceClass {
 #define PNV9_XSCOM_XIVE_BASE  0x5013000
 #define PNV9_XSCOM_XIVE_SIZE  0x300
 
-extern void pnv_xscom_realize(PnvChip *chip, Error **errp);
+extern void pnv_xscom_realize(PnvChip *chip, uint64_t size, Er

[Qemu-devel] [PULL 06/49] spapr_pci: Fix potential NULL pointer dereference in spapr_dt_pci_bus()

2019-07-01 Thread David Gibson
From: Philippe Mathieu-Daudé 

Commit 14e714900f6 refactored the call to spapr_dt_drc(),
introducing a potential NULL pointer dereference while
accessing bus->parent_dev.
A trivial audit show 'bus' is not null in the two places
the static function spapr_dt_drc() is called.

Since the 'bus' parameter is not NULL in both callers, remove
remove the test on if (bus), and add an assert() to silent
static analyzers.

This fixes:

  /hw/ppc/spapr_pci.c: 1367 in spapr_dt_pci_bus()
  >>> CID 1401933:  Null pointer dereferences  (FORWARD_NULL)
  >>> Dereferencing null pointer "bus".
  1367 ret = spapr_dt_drc(fdt, offset, OBJECT(bus->parent_dev),
  1368SPAPR_DR_CONNECTOR_TYPE_PCI);

Fixes: 14e714900f6
Reported-by: Coverity (CID 1401933)
Suggested-by: Greg Kurz 
Suggested-by: David Gibson 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20190613213406.22053-1-phi...@redhat.com>
Signed-off-by: David Gibson 
---
 hw/ppc/spapr_pci.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 957ae88bbd..fbeb1c90ee 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1356,12 +1356,11 @@ static int spapr_dt_pci_bus(SpaprPhbState *sphb, PCIBus 
*bus,
 _FDT(fdt_setprop_cell(fdt, offset, "#size-cells",
   RESOURCE_CELLS_SIZE));
 
-if (bus) {
-pci_for_each_device_reverse(bus, pci_bus_num(bus),
-spapr_dt_pci_device_cb, &cbinfo);
-if (cbinfo.err) {
-return cbinfo.err;
-}
+assert(bus);
+pci_for_each_device_reverse(bus, pci_bus_num(bus),
+spapr_dt_pci_device_cb, &cbinfo);
+if (cbinfo.err) {
+return cbinfo.err;
 }
 
 ret = spapr_dt_drc(fdt, offset, OBJECT(bus->parent_dev),
-- 
2.21.0




[Qemu-devel] [PULL 00/49] ppc-for-4.1 queue 20190702

2019-07-01 Thread David Gibson
The following changes since commit 7d0e02405fc02a181319b1ab8681d2f72246b7c6:

  Merge remote-tracking branch 
'remotes/vivier2/tags/trivial-patches-pull-request' into staging (2019-07-01 
17:40:32 +0100)

are available in the Git repository at:

  git://github.com/dgibson/qemu.git tags/ppc-for-4.1-20190702

for you to fetch changes up to 1c3d4a8f4b4f24baa9dae31db0599925abc7d2a2:

  spapr/xive: Add proper rollback to kvmppc_xive_connect() (2019-07-02 10:11:44 
+1000)


ppc patch queue 2019-07-2

Here's my next pull request for qemu-4.1.  I'm not sure if this will
squeak in just before the soft freeze, or just after.  I don't think
it really matters - most of this is bugfixes anyway.  There's some
cleanups which aren't stictly bugfixes, but which I think are safe
enough improvements to go in the soft freeze.  There's no true feature
work.

Unfortunately, I wasn't able to complete a few of my standard battery
of pre-pull tests, due to some failures that appear to also be in
master.  I'm hoping that hasn't missed anything important in here.

Highlights are:
  * A number of fixe and cleanups for the XIVE implementation
  * Cleanups to the XICS interrupt controller to fit better with the new
XIVE code
  * Numerous fixes and improvements to TCG handling of ppc vector
instructions
  * Remove a number of unnnecessary #ifdef CONFIG_KVM guards
  * Fix some errors in the PCI hotplug paths
  * Assorted other fixes


Alexey Kardashevskiy (1):
  spapr/rtas: Force big endian compile for rtas

Cédric Le Goater (11):
  docs: updates on the POWER9 XIVE interrupt controller documentation
  ppc/pnv: fix StoreEOI activation
  ppc/pnv: fix XSCOM MMIO base address for P9 machines with multiple chips
  ppc/pnv: remove xscom_base field from PnvChip
  target/ppc: fix compile error in kvmppc_define_rtas_kernel_token()
  spapr/xive: rework the mapping the KVM memory regions
  spapr/xive: simplify spapr_irq_init_device() to remove the emulated init
  ppc/xive: Force the Physical CAM line value to group mode
  ppc/xive: Make the PIPR register readonly
  ppc/pnv: Rework cache watch model of PnvXIVE
  ppc/xive: Fix TM_PULL_POOL_CTX special operation

Greg Kurz (21):
  xics/spapr: Prevent RTAS/hypercalls emulation to be used by in-kernel XICS
  xics/spapr: Register RTAS/hypercalls once at machine init
  xics/spapr: Detect old KVM XICS on POWER9 hosts
  xics: Add comment about CPU hotplug
  spapr_pci: Fix DRC owner in spapr_dt_pci_bus()
  xics/spapr: Only emulated XICS should use RTAS/hypercalls emulation
  spapr_pci: Drop useless CONFIG_KVM ifdefery
  hw/ppc/mac_oldworld: Drop useless CONFIG_KVM ifdefery
  hw/ppc/mac_newworld: Drop useless CONFIG_KVM ifdefery
  hw/ppc/prep: Drop useless CONFIG_KVM ifdefery
  hw/ppc: Drop useless CONFIG_KVM ifdefery
  xics/spapr: Drop unused function declaration
  xics/spapr: Rename xics_kvm_init()
  xics/kvm: Skip rollback when KVM XICS is absent
  xics/kvm: Always use local_err in xics_kvm_init()
  xics/kvm: Add error propagation to ic*_set_kvm_state() functions
  xics/kvm: Add proper rollback to xics_kvm_init()
  ppc: Introduce kvmppc_set_reg_tb_offset() helper
  target/ppc/machine: Add kvmppc_pvr_workaround_required() stub
  spapr_pci: Unregister listeners before destroying the IOMMU address space
  spapr/xive: Add proper rollback to kvmppc_xive_connect()

Mark Cave-Ayland (15):
  target/ppc: remove getVSR()/putVSR() from fpu_helper.c
  target/ppc: remove getVSR()/putVSR() from mem_helper.c
  target/ppc: remove getVSR()/putVSR() from int_helper.c
  target/ppc: introduce separate VSX_CMP macro for xvcmp* instructions
  target/ppc: introduce GEN_VSX_HELPER_X3 macro to fpu_helper.c
  target/ppc: introduce separate generator and helper for xscvqpdp
  target/ppc: introduce GEN_VSX_HELPER_X2 macro to fpu_helper.c
  target/ppc: introduce GEN_VSX_HELPER_X2_AB macro to fpu_helper.c
  target/ppc: introduce GEN_VSX_HELPER_X1 macro to fpu_helper.c
  target/ppc: introduce GEN_VSX_HELPER_R3 macro to fpu_helper.c
  target/ppc: introduce GEN_VSX_HELPER_R2 macro to fpu_helper.c
  target/ppc: introduce GEN_VSX_HELPER_R2_AB macro to fpu_helper.c
  target/ppc: decode target register in VSX_VECTOR_LOAD_STORE_LENGTH at 
translation time
  target/ppc: decode target register in VSX_EXTRACT_INSERT at translation 
time
  target/ppc: improve VSX_FMADD with new GEN_VSX_HELPER_VSX_MADD macro

Philippe Mathieu-Daudé (1):
  spapr_pci: Fix potential NULL pointer dereference in spapr_dt_pci_bus()

 docs/specs/ppc-spapr-xive.rst   | 112 -
 docs/specs/ppc-xive.rst |   9 +-
 hw/intc/pnv_xive.c  | 145 +--
 hw/intc/spapr_xive.c|  38 +-
 hw/intc/spapr_xive_kvm.

[Qemu-devel] [PULL 01/49] spapr/rtas: Force big endian compile for rtas

2019-07-01 Thread David Gibson
From: Alexey Kardashevskiy 

At the moment the rtas's Makefile uses generic QEMU rules which means
that when QEMU is compiled on a little endian system, the spapr-rtas.bin
is compiled as little endian too which is incorrect as it is always
executed in big endian mode.

This enforces -mbig by defining %.o:%.S rule as spapr-rtas.bin is
a standalone guest binary which should not depend on QEMU flags anyway.

Signed-off-by: Alexey Kardashevskiy 
Message-Id: <20190612020723.96802-1-...@ozlabs.ru>
Signed-off-by: David Gibson 
---
 pc-bios/spapr-rtas/Makefile | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/pc-bios/spapr-rtas/Makefile b/pc-bios/spapr-rtas/Makefile
index f26dd428b7..4b9bb12306 100644
--- a/pc-bios/spapr-rtas/Makefile
+++ b/pc-bios/spapr-rtas/Makefile
@@ -14,8 +14,11 @@ $(call set-vpath, $(SRC_PATH)/pc-bios/spapr-rtas)
 
 build-all: spapr-rtas.bin
 
+%.o: %.S
+   $(call quiet-command,$(CCAS) -mbig -c -o $@ $<,"CCAS","$(TARGET_DIR)$@")
+
 %.img: %.o
-   $(call quiet-command,$(CC) -nostdlib -o $@ 
$<,"Building","$(TARGET_DIR)$@")
+   $(call quiet-command,$(CC) -nostdlib -mbig -o $@ 
$<,"Building","$(TARGET_DIR)$@")
 
 %.bin: %.img
$(call quiet-command,$(OBJCOPY) -O binary -j .text $< 
$@,"Building","$(TARGET_DIR)$@")
-- 
2.21.0




[Qemu-devel] [PULL 05/49] ppc/pnv: remove xscom_base field from PnvChip

2019-07-01 Thread David Gibson
From: Cédric Le Goater 

It has now became useless with the previous patch.

Signed-off-by: Cédric Le Goater 
Message-Id: <20190612174345.9799-3-...@kaod.org>
Signed-off-by: David Gibson 
---
 hw/ppc/pnv.c | 10 --
 include/hw/ppc/pnv.h |  5 +
 2 files changed, 1 insertion(+), 14 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 0d98a281f6..b87e01e5b9 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -924,7 +924,6 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, 
void *data)
 k->isa_create = pnv_chip_power8_isa_create;
 k->dt_populate = pnv_chip_power8_dt_populate;
 k->pic_print_info = pnv_chip_power8_pic_print_info;
-k->xscom_base = 0x003fc00ull;
 dc->desc = "PowerNV Chip POWER8E";
 
 device_class_set_parent_realize(dc, pnv_chip_power8_realize,
@@ -944,7 +943,6 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, 
void *data)
 k->isa_create = pnv_chip_power8_isa_create;
 k->dt_populate = pnv_chip_power8_dt_populate;
 k->pic_print_info = pnv_chip_power8_pic_print_info;
-k->xscom_base = 0x003fc00ull;
 dc->desc = "PowerNV Chip POWER8";
 
 device_class_set_parent_realize(dc, pnv_chip_power8_realize,
@@ -964,7 +962,6 @@ static void pnv_chip_power8nvl_class_init(ObjectClass 
*klass, void *data)
 k->isa_create = pnv_chip_power8nvl_isa_create;
 k->dt_populate = pnv_chip_power8_dt_populate;
 k->pic_print_info = pnv_chip_power8_pic_print_info;
-k->xscom_base = 0x003fc00ull;
 dc->desc = "PowerNV Chip POWER8NVL";
 
 device_class_set_parent_realize(dc, pnv_chip_power8_realize,
@@ -1115,7 +1112,6 @@ static void pnv_chip_power9_class_init(ObjectClass 
*klass, void *data)
 k->isa_create = pnv_chip_power9_isa_create;
 k->dt_populate = pnv_chip_power9_dt_populate;
 k->pic_print_info = pnv_chip_power9_pic_print_info;
-k->xscom_base = 0x00603fcull;
 dc->desc = "PowerNV Chip POWER9";
 
 device_class_set_parent_realize(dc, pnv_chip_power9_realize,
@@ -1152,11 +1148,6 @@ static void pnv_chip_core_sanitize(PnvChip *chip, Error 
**errp)
 }
 }
 
-static void pnv_chip_instance_init(Object *obj)
-{
-PNV_CHIP(obj)->xscom_base = PNV_CHIP_GET_CLASS(obj)->xscom_base;
-}
-
 static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
 {
 Error *error = NULL;
@@ -1406,7 +1397,6 @@ static const TypeInfo types[] = {
 .name  = TYPE_PNV_CHIP,
 .parent= TYPE_SYS_BUS_DEVICE,
 .class_init= pnv_chip_class_init,
-.instance_init = pnv_chip_instance_init,
 .instance_size = sizeof(PnvChip),
 .class_size= sizeof(PnvChipClass),
 .abstract  = true,
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 01ac9e7996..fb123edc4e 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -56,7 +56,6 @@ typedef struct PnvChip {
 uint64_t cores_mask;
 void *cores;
 
-hwaddr   xscom_base;
 MemoryRegion xscom_mmio;
 MemoryRegion xscom;
 AddressSpace xscom_as;
@@ -105,8 +104,6 @@ typedef struct PnvChipClass {
 uint64_t chip_cfam_id;
 uint64_t cores_mask;
 
-hwaddr   xscom_base;
-
 DeviceRealize parent_realize;
 
 uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id);
@@ -199,7 +196,7 @@ void pnv_bmc_powerdown(IPMIBmc *bmc);
  */
 #define PNV_XSCOM_SIZE0x8ull
 #define PNV_XSCOM_BASE(chip)\
-(chip->xscom_base + ((uint64_t)(chip)->chip_id) * PNV_XSCOM_SIZE)
+(0x0003fc00ull + ((uint64_t)(chip)->chip_id) * PNV_XSCOM_SIZE)
 
 /*
  * XSCOM 0x20109CA defines the ICP BAR:
-- 
2.21.0




[Qemu-devel] [PULL 03/49] ppc/pnv: fix StoreEOI activation

2019-07-01 Thread David Gibson
From: Cédric Le Goater 

The firmware (skiboot) of the PowerNV machines can configure the XIVE
interrupt controller to activate StoreEOI on the ESB pages of the
interrupts. This feature lets software do an EOI with a store instead
of a load. It is not activated today on P9 for rare race condition
issues but it should be on future processors.

Nevertheless, QEMU has a model for StoreEOI which can be used today by
experimental firmwares. But, the use of object_property_set_int() in
the PnvXive model is incorrect and crashes QEMU. Replace it with a
direct access to the ESB flags of the XiveSource object modeling the
internal sources of the interrupt controller.

Signed-off-by: Cédric Le Goater 
Message-Id: <20190612162357.29566-1-...@kaod.org>
Signed-off-by: David Gibson 
---
 hw/intc/pnv_xive.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c
index a55c2bbc88..9ab77feee9 100644
--- a/hw/intc/pnv_xive.c
+++ b/hw/intc/pnv_xive.c
@@ -781,8 +781,7 @@ static void pnv_xive_ic_reg_write(void *opaque, hwaddr 
offset,
  * support recently though)
  */
 if (val & (VC_SBC_CONF_CPLX_CIST | VC_SBC_CONF_CIST_BOTH)) {
-object_property_set_int(OBJECT(&xive->ipi_source),
-XIVE_SRC_STORE_EOI, "flags", &error_fatal);
+xive->ipi_source.esb_flags |= XIVE_SRC_STORE_EOI;
 }
 break;
 
-- 
2.21.0




Re: [Qemu-devel] [PATCH 06/17] qom: Move HMP command handlers to qom/

2019-07-01 Thread Markus Armbruster
Markus Armbruster  writes:

> There are just two HMP commands related to QOM: qom-list and qom-set.
> Move their handlers from monitor/hmp-cmds.c to new qom/qom-hmp-cmds.c,
> where they are covered by MAINTAINERS section QOM.

Actually three: hmp_info_qom_tree().  I'm squashing the obvious movement
into this patch (appended), updating the commit message to

  Move the HMP command handlers related to QOM handlers from
  monitor/hmp-cmds.c and qdev-monitor.c to new qom/qom-hmp-cmds.c, where
  they are covered by MAINTAINERS section QOM.

Hope that's okay.

> Cc: Paolo Bonzini 
> Cc: "Daniel P. Berrange" 
> Cc: Eduardo Habkost 
> Cc: "Dr. David Alan Gilbert" 
> Signed-off-by: Markus Armbruster 
> ---
>  include/monitor/hmp.h |  2 ++
>  monitor/hmp-cmds.c| 50 +-
>  qom/Makefile.objs |  2 +-
>  qom/qom-hmp-cmds.c| 62 +++
>  4 files changed, 66 insertions(+), 50 deletions(-)
>  create mode 100644 qom/qom-hmp-cmds.c
>
> diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
> index 1d095d5837..f46ccdaa35 100644
> --- a/include/monitor/hmp.h
> +++ b/include/monitor/hmp.h
> @@ -16,6 +16,8 @@
>  
>  #include "qemu/readline.h"
>  
> +void hmp_handle_error(Monitor *mon, Error **errp);
> +
>  void hmp_info_name(Monitor *mon, const QDict *qdict);
>  void hmp_info_version(Monitor *mon, const QDict *qdict);
>  void hmp_info_kvm(Monitor *mon, const QDict *qdict);
> diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
> index d94ab7563e..5641036dc3 100644
> --- a/monitor/hmp-cmds.c
> +++ b/monitor/hmp-cmds.c
> @@ -60,7 +60,7 @@
>  #include 
>  #endif
>  
> -static void hmp_handle_error(Monitor *mon, Error **errp)
> +void hmp_handle_error(Monitor *mon, Error **errp)
>  {
>  assert(errp);
>  if (*errp) {
> @@ -2714,54 +2714,6 @@ void hmp_info_iothreads(Monitor *mon, const QDict 
> *qdict)
>  qapi_free_IOThreadInfoList(info_list);
>  }
>  
> -void hmp_qom_list(Monitor *mon, const QDict *qdict)
> -{
> -const char *path = qdict_get_try_str(qdict, "path");
> -ObjectPropertyInfoList *list;
> -Error *err = NULL;
> -
> -if (path == NULL) {
> -monitor_printf(mon, "/\n");
> -return;
> -}
> -
> -list = qmp_qom_list(path, &err);
> -if (err == NULL) {
> -ObjectPropertyInfoList *start = list;
> -while (list != NULL) {
> -ObjectPropertyInfo *value = list->value;
> -
> -monitor_printf(mon, "%s (%s)\n",
> -   value->name, value->type);
> -list = list->next;
> -}
> -qapi_free_ObjectPropertyInfoList(start);
> -}
> -hmp_handle_error(mon, &err);
> -}
> -
> -void hmp_qom_set(Monitor *mon, const QDict *qdict)
> -{
> -const char *path = qdict_get_str(qdict, "path");
> -const char *property = qdict_get_str(qdict, "property");
> -const char *value = qdict_get_str(qdict, "value");
> -Error *err = NULL;
> -bool ambiguous = false;
> -Object *obj;
> -
> -obj = object_resolve_path(path, &ambiguous);
> -if (obj == NULL) {
> -error_set(&err, ERROR_CLASS_DEVICE_NOT_FOUND,
> -  "Device '%s' not found", path);
> -} else {
> -if (ambiguous) {
> -monitor_printf(mon, "Warning: Path '%s' is ambiguous\n", path);
> -}
> -object_property_parse(obj, value, property, &err);
> -}
> -hmp_handle_error(mon, &err);
> -}
> -
>  void hmp_rocker(Monitor *mon, const QDict *qdict)
>  {
>  const char *name = qdict_get_str(qdict, "name");
> diff --git a/qom/Makefile.objs b/qom/Makefile.objs
> index 5fb43b842c..aae478fc21 100644
> --- a/qom/Makefile.objs
> +++ b/qom/Makefile.objs
> @@ -2,4 +2,4 @@ qom-obj-y = object.o container.o qom-qobject.o
>  qom-obj-y += object_interfaces.o
>  
>  common-obj-y = cpu.o
> -common-obj-$(CONFIG_SOFTMMU) += qom-qmp-cmds.o
> +common-obj-$(CONFIG_SOFTMMU) += qom-hmp-cmds.o qom-qmp-cmds.o
> diff --git a/qom/qom-hmp-cmds.c b/qom/qom-hmp-cmds.c
> new file mode 100644
> index 00..2028a21052
> --- /dev/null
> +++ b/qom/qom-hmp-cmds.c
> @@ -0,0 +1,62 @@
> +/*
> + * HMP commands related to QOM
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or
> + * later.  See the COPYING file in the top-level directory.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "monitor/hmp.h"
> +#include "qapi/qapi-commands-qom.h"
> +#include "qapi/qmp/qdict.h"
> +#include "monitor/monitor.h"
> +#include "qom/object.h"
> +#include "qapi/error.h"
> +
> +void hmp_qom_list(Monitor *mon, const QDict *qdict)
> +{
> +const char *path = qdict_get_try_str(qdict, "path");
> +ObjectPropertyInfoList *list;
> +Error *err = NULL;
> +
> +if (path == NULL) {
> +monitor_printf(mon, "/\n");
> +return;
> +}
> +
> +list = qmp_qom_list(path, &err);
> +if (err == NULL) {
> +ObjectPropertyInfoList *start = list;
> +while (list != NULL) {
> +ObjectPro

Re: [Qemu-devel] [PATCH 1/2] dma/rc4030: Fix off-by-one error in specified memory region size

2019-07-01 Thread Hervé Poussineau

Le 25/06/2019 à 16:27, Aleksandar Markovic a écrit :

From: Aleksandar Markovic 

The size is one byte less than it should be:

address-space: rc4030-dma
   -fffe (prio 0, i/o): rc4030.dma

rc4030 is used in MIPS Jazz board context.

Signed-off-by: Aleksandar Markovic 


Reviewed-by: Hervé Poussineau 


---
  hw/dma/rc4030.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c
index 6ccafec..88ff271 100644
--- a/hw/dma/rc4030.c
+++ b/hw/dma/rc4030.c
@@ -23,6 +23,7 @@
   */
  
  #include "qemu/osdep.h"

+#include "qemu/units.h"
  #include "hw/hw.h"
  #include "hw/mips/mips.h"
  #include "hw/sysbus.h"
@@ -678,7 +679,7 @@ static void rc4030_realize(DeviceState *dev, Error **errp)
  
  memory_region_init_iommu(&s->dma_mr, sizeof(s->dma_mr),

   TYPE_RC4030_IOMMU_MEMORY_REGION,
- o, "rc4030.dma", UINT32_MAX);
+ o, "rc4030.dma", 4 * GiB);
  address_space_init(&s->dma_as, MEMORY_REGION(&s->dma_mr), "rc4030-dma");
  }
  






Re: [Qemu-devel] [PATCH 2/2] dma/rc4030: Minor code style cleanup

2019-07-01 Thread Hervé Poussineau

Le 25/06/2019 à 16:27, Aleksandar Markovic a écrit :

From: Aleksandar Markovic 

Fix some simple checkpatch.pl warnings in rc4030.c.

Signed-off-by: Aleksandar Markovic 


Reviewed-by: Hervé Poussineau 


---
  hw/dma/rc4030.c | 18 +++---
  1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c
index 88ff271..155af9b 100644
--- a/hw/dma/rc4030.c
+++ b/hw/dma/rc4030.c
@@ -58,8 +58,8 @@ typedef struct dma_pagetable_entry {
  
  #define TYPE_RC4030_IOMMU_MEMORY_REGION "rc4030-iommu-memory-region"
  
-typedef struct rc4030State

-{
+typedef struct rc4030State {
+
  SysBusDevice parent;
  
  uint32_t config; /* 0x: RC4030 config register */

@@ -152,8 +152,9 @@ static uint64_t rc4030_read(void *opaque, hwaddr addr, 
unsigned int size)
  case 0x0058:
  val = s->cache_bmask;
  /* HACK */
-if (s->cache_bmask == (uint32_t)-1)
+if (s->cache_bmask == (uint32_t)-1) {
  s->cache_bmask = 0;
+}
  break;
  /* Remote Speed Registers */
  case 0x0070:
@@ -538,8 +539,9 @@ static void rc4030_reset(DeviceState *dev)
  
  s->memory_refresh_rate = 0x18186;

  s->nvram_protect = 7;
-for (i = 0; i < 15; i++)
+for (i = 0; i < 15; i++) {
  s->rem_speed[i] = 7;
+}
  s->imr_jazz = 0x10; /* XXX: required by firmware, but why? */
  s->isr_jazz = 0;
  
@@ -551,7 +553,7 @@ static void rc4030_reset(DeviceState *dev)
  
  static int rc4030_post_load(void *opaque, int version_id)

  {
-rc4030State* s = opaque;
+rc4030State *s = opaque;
  
  set_next_tick(s);

  update_jazz_irq(s);
@@ -591,7 +593,8 @@ static void rc4030_do_dma(void *opaque, int n, uint8_t 
*buf, int len, int is_wri
  hwaddr dma_addr;
  int dev_to_mem;
  
-s->dma_regs[n][DMA_REG_ENABLE] &= ~(DMA_FLAG_TC_INTR | DMA_FLAG_MEM_INTR | DMA_FLAG_ADDR_INTR);

+s->dma_regs[n][DMA_REG_ENABLE] &=
+   ~(DMA_FLAG_TC_INTR | DMA_FLAG_MEM_INTR | DMA_FLAG_ADDR_INTR);
  
  /* Check DMA channel consistency */

  dev_to_mem = (s->dma_regs[n][DMA_REG_ENABLE] & DMA_FLAG_MEM_TO_DEV) ? 0 : 
1;
@@ -603,8 +606,9 @@ static void rc4030_do_dma(void *opaque, int n, uint8_t 
*buf, int len, int is_wri
  }
  
  /* Get start address and len */

-if (len > s->dma_regs[n][DMA_REG_COUNT])
+if (len > s->dma_regs[n][DMA_REG_COUNT]) {
  len = s->dma_regs[n][DMA_REG_COUNT];
+}
  dma_addr = s->dma_regs[n][DMA_REG_ADDRESS];
  
  /* Read/write data at right place */







Re: [Qemu-devel] [Qemu-ppc] [PATCH v10 6/6] ppc: spapr: Handle "ibm, nmi-register" and "ibm, nmi-interlock" RTAS calls

2019-07-01 Thread David Gibson
On Wed, Jun 26, 2019 at 10:43:33AM +0530, Aravinda Prasad wrote:
> 
> 
> On Tuesday 25 June 2019 12:30 PM, Greg Kurz wrote:
> > On Tue, 25 Jun 2019 11:46:06 +0530
> > Aravinda Prasad  wrote:
> > 
> >> On Monday 24 June 2019 07:59 PM, Greg Kurz wrote:
> >>> On Wed, 12 Jun 2019 14:51:38 +0530
> >>> Aravinda Prasad  wrote:
> >>>   
>  This patch adds support in QEMU to handle "ibm,nmi-register"
>  and "ibm,nmi-interlock" RTAS calls and sets the default
>  value of SPAPR_CAP_FWNMI_MCE to SPAPR_CAP_ON for machine
>  type 4.0.
>   
> >>>
> >>> Next machine type is 4.1.  
> >>
> >> ok.
> >>
> >>>   
>  The machine check notification address is saved when the
>  OS issues "ibm,nmi-register" RTAS call.
> 
>  This patch also handles the case when multiple processors
>  experience machine check at or about the same time by
>  handling "ibm,nmi-interlock" call. In such cases, as per
>  PAPR, subsequent processors serialize waiting for the first
>  processor to issue the "ibm,nmi-interlock" call. The second
>  processor that also received a machine check error waits
>  till the first processor is done reading the error log.
>  The first processor issues "ibm,nmi-interlock" call
>  when the error log is consumed.
> 
>  Signed-off-by: Aravinda Prasad 
>  ---
>   hw/ppc/spapr.c |6 -
>   hw/ppc/spapr_rtas.c|   63 
>  
>   include/hw/ppc/spapr.h |5 +++-
>   3 files changed, 72 insertions(+), 2 deletions(-)
> 
>  diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>  index 3d6d139..213d493 100644
>  --- a/hw/ppc/spapr.c
>  +++ b/hw/ppc/spapr.c
>  @@ -2946,6 +2946,9 @@ static void spapr_machine_init(MachineState 
>  *machine)
>   /* Create the error string for live migration blocker */
>   error_setg(&spapr->fwnmi_migration_blocker,
>   "Live migration not supported during machine check 
>  handling");
>  +
>  +/* Register ibm,nmi-register and ibm,nmi-interlock RTAS calls */
>  +spapr_fwnmi_register();  
> >>>
> >>> IIRC this was supposed to depend on SPAPR_CAP_FWNMI_MCE being ON.  
> >>
> >> Yes this is inside SPAPR_CAP_FWNMI_MCE check:
> >>
> >> if (spapr_get_cap(spapr, SPAPR_CAP_FWNMI_MCE) == SPAPR_CAP_ON) {
> >> /*
> >>  * Ensure that the rtas image size is less than RTAS_ERROR_LOG_OFFSET
> >>  * or else the rtas image will be overwritten with the rtas error log
> >>  * when a machine check exception is encountered.
> >>  */
> >> g_assert(spapr->rtas_size < RTAS_ERROR_LOG_OFFSET);
> >>
> >> /* Resize rtas blob to accommodate error log */
> >> spapr->rtas_size = RTAS_ERROR_LOG_MAX;
> >>
> >> /* Create the error string for live migration blocker */
> >> error_setg(&spapr->fwnmi_migration_blocker,
> >> "Live migration not supported during machine check handling");
> >>
> >> /* Register ibm,nmi-register and ibm,nmi-interlock RTAS calls */
> >> spapr_fwnmi_register();
> >> }
> >>
> > 
> > Oops my bad... sorry for the noise.
> > 
> >>
> >>>   
>   }
>   
>   spapr->rtas_blob = g_malloc(spapr->rtas_size);
>  @@ -4408,7 +4411,7 @@ static void spapr_machine_class_init(ObjectClass 
>  *oc, void *data)
>   smc->default_caps.caps[SPAPR_CAP_NESTED_KVM_HV] = SPAPR_CAP_OFF;
>   smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_ON;
>   smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF;
>  -smc->default_caps.caps[SPAPR_CAP_FWNMI_MCE] = SPAPR_CAP_OFF;
>  +smc->default_caps.caps[SPAPR_CAP_FWNMI_MCE] = SPAPR_CAP_ON;
>   spapr_caps_add_properties(smc, &error_abort);
>   smc->irq = &spapr_irq_dual;
>   smc->dr_phb_enabled = true;
>  @@ -4512,6 +4515,7 @@ static void 
>  spapr_machine_3_1_class_options(MachineClass *mc)
>   smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN;
>   smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN;
>   smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_OFF;
>  +smc->default_caps.caps[SPAPR_CAP_FWNMI_MCE] = SPAPR_CAP_OFF;  
> >>>
> >>> This should have been put into spapr_machine_4_0_class_options().  
> >>
> >> ok. I will change it.
> >>
> >>>
> >>> But unless you manage to get this merged before soft-freeze (2019-07-02),
> >>> I'm afraid this will be a 4.2 feature.  
> >>
> >> If there are no other comments, can this be merged to 4.1? I will send a
> >> revised version with the above changes.
> >>
> > 
> > This is David's call.
> 
> David, can you let me know if this can be merged to 4.1 with the above
> minor changes?

Nope, sorry.  I've been away, but also this still needs more polish.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist,

Re: [Qemu-devel] [PATCH v10 3/6] target/ppc: Handle NMI guest exit

2019-07-01 Thread David Gibson
On Wed, Jun 12, 2019 at 02:51:13PM +0530, Aravinda Prasad wrote:
> Memory error such as bit flips that cannot be corrected
> by hardware are passed on to the kernel for handling.
> If the memory address in error belongs to guest then
> the guest kernel is responsible for taking suitable action.
> Patch [1] enhances KVM to exit guest with exit reason
> set to KVM_EXIT_NMI in such cases. This patch handles
> KVM_EXIT_NMI exit.
> 
> [1] https://www.spinics.net/lists/kvm-ppc/msg12637.html
> (e20bbd3d and related commits)
> 
> Signed-off-by: Aravinda Prasad 

Reviewed-by: David Gibson 

> ---
>  hw/ppc/spapr.c  |8 
>  hw/ppc/spapr_events.c   |   23 +++
>  include/hw/ppc/spapr.h  |   10 ++
>  target/ppc/kvm.c|   14 ++
>  target/ppc/kvm_ppc.h|2 ++
>  target/ppc/trace-events |1 +
>  6 files changed, 58 insertions(+)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 2ef86aa..6cc2c3b 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1806,6 +1806,12 @@ static void spapr_machine_reset(void)
>  first_ppc_cpu->env.gpr[5] = 0;
>  
>  spapr->cas_reboot = false;
> +
> +spapr->mc_status = -1;
> +spapr->guest_machine_check_addr = -1;
> +
> +/* Signal all vCPUs waiting on this condition */
> +qemu_cond_broadcast(&spapr->mc_delivery_cond);
>  }
>  
>  static void spapr_create_nvram(SpaprMachineState *spapr)
> @@ -3070,6 +3076,8 @@ static void spapr_machine_init(MachineState *machine)
>  
>  kvmppc_spapr_enable_inkernel_multitce();
>  }
> +
> +qemu_cond_init(&spapr->mc_delivery_cond);
>  }
>  
>  static int spapr_kvm_type(MachineState *machine, const char *vm_type)
> diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
> index ae0f093..a0c66d7 100644
> --- a/hw/ppc/spapr_events.c
> +++ b/hw/ppc/spapr_events.c
> @@ -620,6 +620,29 @@ void 
> spapr_hotplug_req_remove_by_count_indexed(SpaprDrcType drc_type,
>  RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, &drc_id);
>  }
>  
> +void spapr_mce_req_event(PowerPCCPU *cpu)
> +{
> +SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
> +
> +while (spapr->mc_status != -1) {
> +/*
> + * Check whether the same CPU got machine check error
> + * while still handling the mc error (i.e., before
> + * that CPU called "ibm,nmi-interlock")
> + */
> +if (spapr->mc_status == cpu->vcpu_id) {
> +qemu_system_guest_panicked(NULL);
> +return;
> +}
> +qemu_cond_wait_iothread(&spapr->mc_delivery_cond);
> +/* Meanwhile if the system is reset, then just return */
> +if (spapr->guest_machine_check_addr == -1) {
> +return;
> +}
> +}
> +spapr->mc_status = cpu->vcpu_id;
> +}
> +
>  static void check_exception(PowerPCCPU *cpu, SpaprMachineState *spapr,
>  uint32_t token, uint32_t nargs,
>  target_ulong args,
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index f891f8f..f34c79f 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -190,6 +190,15 @@ struct SpaprMachineState {
>   * occurs during the unplug process. */
>  QTAILQ_HEAD(, SpaprDimmState) pending_dimm_unplugs;
>  
> +/* State related to "ibm,nmi-register" and "ibm,nmi-interlock" calls */
> +target_ulong guest_machine_check_addr;
> +/*
> + * mc_status is set to -1 if mc is not in progress, else is set to the 
> CPU
> + * handling the mc.
> + */
> +int mc_status;
> +QemuCond mc_delivery_cond;
> +
>  /*< public >*/
>  char *kvm_type;
>  char *host_model;
> @@ -789,6 +798,7 @@ void spapr_clear_pending_events(SpaprMachineState *spapr);
>  int spapr_max_server_number(SpaprMachineState *spapr);
>  void spapr_store_hpte(PowerPCCPU *cpu, hwaddr ptex,
>uint64_t pte0, uint64_t pte1);
> +void spapr_mce_req_event(PowerPCCPU *cpu);
>  
>  /* DRC callbacks. */
>  void spapr_core_release(DeviceState *dev);
> diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
> index afef4cd..99f33fe 100644
> --- a/target/ppc/kvm.c
> +++ b/target/ppc/kvm.c
> @@ -1763,6 +1763,11 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run 
> *run)
>  ret = 0;
>  break;
>  
> +case KVM_EXIT_NMI:
> +trace_kvm_handle_nmi_exception();
> +ret = kvm_handle_nmi(cpu, run);
> +break;
> +
>  default:
>  fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
>  ret = -1;
> @@ -2863,6 +2868,15 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
>  return data & 0x;
>  }
>  
> +int kvm_handle_nmi(PowerPCCPU *cpu, struct kvm_run *run)
> +{
> +cpu_synchronize_state(CPU(cpu));
> +
> +spapr_mce_req_event(cpu);
> +
> +return 0;
> +}
> +
>  int kvmppc_enable_hwrng(void)
>  {
>  if (!kvm_enabled() || !kvm_check_extension(kvm_state, 
> KVM_C

Re: [Qemu-devel] [PATCH v2 4/9] hw/block/pflash_cfi01: Start state machine as READY to accept commands

2019-07-01 Thread John Snow



On 7/1/19 8:12 PM, Philippe Mathieu-Daudé wrote:
> When the state machine is ready to accept command, the bit 7 of
> the status register (SR) is set to 1.
> The guest polls the status register and check this bit before
> writting command to the internal 'Write State Machine' (WSM).

writing

> 
> Set SR.7 bit to 1 when the device is created.
> 

Right, ok -- it looks like we don't set this on realize otherwise.
(Or if we do, it's not obvious where or how.)

> Reference: Read Array Flowchart
>   "Common Flash Interface (CFI) and Command Sets"
>(Intel Application Note 646)
>Appendix B "Basic Command Set"
> 
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: John Snow 

> ---
>  hw/block/pflash_cfi01.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
> index 33c77f6569..dd1dfd266b 100644
> --- a/hw/block/pflash_cfi01.c
> +++ b/hw/block/pflash_cfi01.c
> @@ -764,7 +764,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Error 
> **errp)
>  }
>  
>  pflash_mode_read_array(pfl);
> -pfl->status = 0;
> +pfl->status = 0x80; /* WSM ready */
>  /* Hardcoded CFI table */
>  /* Standard "QRY" string */
>  pfl->cfi_table[0x10] = 'Q';
> 



Re: [Qemu-devel] [PULL 33/34] roms: Add OpenSBI version 0.3

2019-07-01 Thread Markus Armbruster
Peter Maydell  writes:

> On Mon, 1 Jul 2019 at 18:50, Alistair Francis  
> wrote:
>>
>> On Mon, 2019-07-01 at 17:54 +0100, Peter Maydell wrote:
>> > On Thu, 27 Jun 2019 at 16:24, Palmer Dabbelt 
>> > wrote:
>> > > From: Alistair Francis 
>> > >
>> > > Add OpenSBI version 0.3 as a git submodule and as a prebult binary.
>> > >
>> > > Signed-off-by: Alistair Francis 
>> > > Reviewed-by: Bin Meng 
>> > > Tested-by: Bin Meng 
>> > > Signed-off-by: Palmer Dabbelt 
>> > > ---
>> > >  .gitmodules  |   3 ++
>> > >  Makefile |   5 +-
>> > >  pc-bios/opensbi-riscv32-virt-fw_jump.bin | Bin 0 -> 28848
>> > > bytes
>> > >  pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin | Bin 0 -> 28904
>> > > bytes
>> > >  pc-bios/opensbi-riscv64-virt-fw_jump.bin | Bin 0 -> 28904
>> > > bytes
>> > >  roms/Makefile|  48 ++-
>> > > 
>> > >  roms/opensbi |   1 +
>> > >  7 files changed, 44 insertions(+), 13 deletions(-)
>> > >  create mode 100644 pc-bios/opensbi-riscv32-virt-fw_jump.bin
>> > >  create mode 100644 pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin
>> > >  create mode 100644 pc-bios/opensbi-riscv64-virt-fw_jump.bin
>> > >  create mode 16 roms/opensbi
>> > >
>> > > diff --git a/.gitmodules b/.gitmodules
>> > > index 2857eec76377..7a10e72e09cd 100644
>> > > --- a/.gitmodules
>> > > +++ b/.gitmodules
>> > > @@ -55,3 +55,6 @@
>> > >  [submodule "slirp"]
>> > > path = slirp
>> > > url = https://git.qemu.org/git/libslirp.git
>> > > +[submodule "roms/opensbi"]
>> > > +   path = roms/opensbi
>> > > +   url = https://github.com/riscv/opensbi.git
>> >
>> > It would be nice to state the license for new blobs we're
>> > adding to the source tree... In particular, I find the
>> > readme at https://github.com/riscv/opensbi a bit confusing
>> > because it says it's 2-BSD but also that some parts are Apache-2.0;
>> > the latter is *not* GPL-2.0 compatible. That makes it not completely
>> > obvious to me that we can ship this with QEMU.
>>
>> Ah, I didn't realise there is Apache-2.0 code in there.
>>
>> In this case all of the code we are using (we aren't using the Kendryte
>> code with QEMU) is BSD-2-Clause. Even then though does it matter if it
>> is GPL compatible? This isn't being linked with QEMU it is just being
>> included with QEMU.
>
> Yeah, if we're not building the apache-2.0 parts then I think
> we're OK, and as you say there's the question of whether QEMU's
> GPL affects what we ship as mere bios blobs to run as guest
> code anyway. But it's sufficiently not a "really obviously ok"
> that I'd like a second opinion; cc'd some people who might have
> second opinions.

You need an expert opinion.

My non-expert opinion: we can't distribute anything that's not
compatible with GPLv2, at least as long as LICENSE makes the following
claims:

1) QEMU as a whole is released under the GNU General Public License,
version 2.

2) Parts of QEMU have specific licenses which are compatible with the
GNU General Public License, version 2. Hence each source file contains
its own licensing information.  Source files with no licensing information
are released under the GNU General Public License, version 2 or (at your
option) any later version.

As of July 2013, contributions under version 2 of the GNU General Public
License (and no later version) are only accepted for the following files
or directories: bsd-user/, linux-user/, hw/vfio/, hw/xen/xen_pt*.

3) The Tiny Code Generator (TCG) is released under the BSD license
   (see license headers in files).

Complicating things further just to distribute a firmware blob would be
a mistake.  Our licensing situation is already complex enough for me to
call it a mistake.

[...]



Re: [Qemu-devel] [PATCH v2 3/9] hw/block/pflash_cfi01: Extract pflash_mode_read_array()

2019-07-01 Thread John Snow



On 7/1/19 8:12 PM, Philippe Mathieu-Daudé wrote:
> The same pattern is used when setting the flash in READ_ARRAY mode:
> - Set the state machine command to READ_ARRAY
> - Reset the write_cycle counter
> - Reset the memory region in ROMD
> 
> Refactor the current code by extracting this pattern.
> It is used twice:
> - On a write access (on command failure, error, or explicitly asked)
> - When the device is initialized. Here the ROMD mode is hidden
>   by the memory_region_init_rom_device() call.
> 
> Rename the 'reset_flash' as 'mode_read_array' to make explicit we
> do not reset the device, we simply set its internal state machine
> in the READ_ARRAY mode. We do not reset the status register error
> bits, as a device reset would do.
> 

The rename does make it less confusing; but as of this patch it doesn't
seem obvious why you need this as a function, it's only really used
about "1.5 times" as of yet -- the realize call as you mention doesn't
quite exactly utilize it.

I will assume this comes in handy later, so:

Reviewed-by: John Snow 

> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/block/pflash_cfi01.c | 36 
>  hw/block/trace-events   |  1 +
>  2 files changed, 21 insertions(+), 16 deletions(-)
> 
> diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
> index 743b5d5794..33c77f6569 100644
> --- a/hw/block/pflash_cfi01.c
> +++ b/hw/block/pflash_cfi01.c
> @@ -112,6 +112,14 @@ static const VMStateDescription vmstate_pflash = {
>  }
>  };
>  
> +static void pflash_mode_read_array(PFlashCFI01 *pfl)
> +{
> +trace_pflash_mode_read_array();
> +pfl->cmd = 0xff; /* Read Array */
> +pfl->wcycle = 0;
> +memory_region_rom_device_set_romd(&pfl->mem, true);
> +}
> +
>  /* Perform a CFI query based on the bank width of the flash.
>   * If this code is called we know we have a device_width set for
>   * this flash.
> @@ -470,7 +478,7 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
>  case 0x50: /* Clear status bits */
>  DPRINTF("%s: Clear status bits\n", __func__);
>  pfl->status = 0x0;
> -goto reset_flash;
> +goto mode_read_array;
>  case 0x60: /* Block (un)lock */
>  DPRINTF("%s: Block unlock\n", __func__);
>  break;
> @@ -495,10 +503,10 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr 
> offset,
>  break;
>  case 0xf0: /* Probe for AMD flash */
>  DPRINTF("%s: Probe for AMD flash\n", __func__);
> -goto reset_flash;
> +goto mode_read_array;
>  case 0xff: /* Read array mode */
>  DPRINTF("%s: Read array mode\n", __func__);
> -goto reset_flash;
> +goto mode_read_array;
>  default:
>  goto error_flash;
>  }
> @@ -525,7 +533,7 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
>  pfl->wcycle = 0;
>  pfl->status |= 0x80;
>  } else if (cmd == 0xff) { /* Read Array */
> -goto reset_flash;
> +goto mode_read_array;
>  } else
>  goto error_flash;
>  
> @@ -552,15 +560,15 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr 
> offset,
>  pfl->wcycle = 0;
>  pfl->status |= 0x80;
>  } else if (cmd == 0xff) { /* read array mode */
> -goto reset_flash;
> +goto mode_read_array;
>  } else {
>  DPRINTF("%s: Unknown (un)locking command\n", __func__);
> -goto reset_flash;
> +goto mode_read_array;
>  }
>  break;
>  case 0x98:
>  if (cmd == 0xff) {
> -goto reset_flash;
> +goto mode_read_array;
>  } else {
>  DPRINTF("%s: leaving query mode\n", __func__);
>  }
> @@ -620,7 +628,7 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
>  " the data is already written to storage!\n"
>  "Flash device reset into READ mode.\n",
>  __func__);
> -goto reset_flash;
> +goto mode_read_array;
>  }
>  break;
>  default:
> @@ -630,7 +638,7 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
>  default:
>  /* Should never happen */
>  DPRINTF("%s: invalid write state\n",  __func__);
> -goto reset_flash;
> +goto mode_read_array;
>  }
>  return;
>  
> @@ -639,11 +647,8 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
>"(offset " TARGET_FMT_plx ", wcycle 0x%x cmd 0x%x value 
> 0x%x)"
>"\n", __func__, offset, pfl->wcycle, pfl->cmd, value);
>  
> - reset_flash:
> -trace_pflash_reset();
> -memory_region_rom_device_set_romd(&pfl->mem, true);
> -pfl->wcycle

Re: [Qemu-devel] [PATCH v2 2/9] hw/block/pflash_cfi01: Use the correct READ_ARRAY value

2019-07-01 Thread John Snow



On 7/1/19 8:12 PM, Philippe Mathieu-Daudé wrote:
> In the "Read Array Flowchart" the command has a value of 0xFF.
> 
> In the document [*] the "Read Array Flowchart", the READ_ARRAY
> command has a value of 0xff.
> 
> Use the correct value in the pflash model.
> 
> There is no change of behavior in the guest, because:
> - when the guest were sending 0xFF, the reset_flash label
>   was setting the command value as 0x00
> - 0x00 was used internally for READ_ARRAY
> 
> [*] "Common Flash Interface (CFI) and Command Sets"
> (Intel Application Note 646)
> Appendix B "Basic Command Set"
> 
> Signed-off-by: Philippe Mathieu-Daudé 

I'm assuming you tested a guest and saw it sending 0xFF; and based
entirely on the assumption that you tested this and it is not now worse:

Reviewed-by: John Snow 

> ---
>  hw/block/pflash_cfi01.c | 15 ++-
>  1 file changed, 6 insertions(+), 9 deletions(-)
> 
> diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
> index dcc9885bf0..743b5d5794 100644
> --- a/hw/block/pflash_cfi01.c
> +++ b/hw/block/pflash_cfi01.c
> @@ -280,10 +280,9 @@ static uint32_t pflash_read(PFlashCFI01 *pfl, hwaddr 
> offset,
>  /* This should never happen : reset state & treat it as a read */
>  DPRINTF("%s: unknown command state: %x\n", __func__, pfl->cmd);
>  pfl->wcycle = 0;
> -pfl->cmd = 0;
> +pfl->cmd = 0xff;
>  /* fall through to read code */
> -case 0x00:
> -/* Flash area read */
> +case 0xff: /* Read Array */
>  ret = pflash_data_read(pfl, offset, width, be);
>  break;
>  case 0x10: /* Single byte program */
> @@ -449,8 +448,6 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
>  case 0:
>  /* read mode */
>  switch (cmd) {
> -case 0x00: /* ??? */
> -goto reset_flash;
>  case 0x10: /* Single Byte Program */
>  case 0x40: /* Single Byte Program */
>  DPRINTF("%s: Single Byte Program\n", __func__);
> @@ -527,7 +524,7 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
>  if (cmd == 0xd0) { /* confirm */
>  pfl->wcycle = 0;
>  pfl->status |= 0x80;
> -} else if (cmd == 0xff) { /* read array mode */
> +} else if (cmd == 0xff) { /* Read Array */
>  goto reset_flash;
>  } else
>  goto error_flash;
> @@ -554,7 +551,7 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
>  } else if (cmd == 0x01) {
>  pfl->wcycle = 0;
>  pfl->status |= 0x80;
> -} else if (cmd == 0xff) {
> +} else if (cmd == 0xff) { /* read array mode */
>  goto reset_flash;
>  } else {
>  DPRINTF("%s: Unknown (un)locking command\n", __func__);
> @@ -646,7 +643,7 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
>  trace_pflash_reset();
>  memory_region_rom_device_set_romd(&pfl->mem, true);
>  pfl->wcycle = 0;
> -pfl->cmd = 0;
> +pfl->cmd = 0xff;
>  }
>  
>  
> @@ -762,7 +759,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Error 
> **errp)
>  }
>  
>  pfl->wcycle = 0;
> -pfl->cmd = 0;
> +pfl->cmd = 0xff;
>  pfl->status = 0;
>  /* Hardcoded CFI table */
>  /* Standard "QRY" string */
> 

-- 
—js



[Qemu-devel] [PULL 0/4] Block patches for rc0

2019-07-01 Thread Max Reitz
The following changes since commit 7d0e02405fc02a181319b1ab8681d2f72246b7c6:

  Merge remote-tracking branch 
'remotes/vivier2/tags/trivial-patches-pull-request' into staging (2019-07-01 
17:40:32 +0100)

are available in the Git repository at:

  https://github.com/XanClic/qemu.git tags/pull-block-2019-07-02

for you to fetch changes up to c624b015bf14fe01f1e6452a36e63b3ea1ae4998:

  block/stream: introduce a bottom node (2019-07-02 03:53:05 +0200)


Block patches for 4.1-rc0:
- The stream job no longer relies on a fixed base node
- The rbd block driver can now accomodate growing formats like qcow2


Andrey Shinkevich (3):
  block: include base when checking image chain for block allocation
  block/stream: refactor stream_run: drop goto
  block/stream: introduce a bottom node

Stefano Garzarella (1):
  block/rbd: increase dynamically the image size

 include/block/block.h  |  3 ++-
 block/commit.c |  2 +-
 block/io.c | 21 +++-
 block/mirror.c |  2 +-
 block/qcow2.c  |  3 ++-
 block/rbd.c| 42 ---
 block/replication.c|  2 +-
 block/stream.c | 56 --
 qemu-img.c |  2 +-
 tests/qemu-iotests/245 |  4 +--
 10 files changed, 91 insertions(+), 46 deletions(-)

-- 
2.21.0




Re: [Qemu-devel] [PATCH v10 4/6] target/ppc: Build rtas error log upon an MCE

2019-07-01 Thread David Gibson
On Wed, Jun 12, 2019 at 02:51:21PM +0530, Aravinda Prasad wrote:
> Upon a machine check exception (MCE) in a guest address space,
> KVM causes a guest exit to enable QEMU to build and pass the
> error to the guest in the PAPR defined rtas error log format.
> 
> This patch builds the rtas error log, copies it to the rtas_addr
> and then invokes the guest registered machine check handler. The
> handler in the guest takes suitable action(s) depending on the type
> and criticality of the error. For example, if an error is
> unrecoverable memory corruption in an application inside the
> guest, then the guest kernel sends a SIGBUS to the application.
> For recoverable errors, the guest performs recovery actions and
> logs the error.
> 
> Signed-off-by: Aravinda Prasad 
> ---
>  hw/ppc/spapr.c |   13 +++
>  hw/ppc/spapr_events.c  |  238 
> 
>  hw/ppc/spapr_rtas.c|   26 +
>  include/hw/ppc/spapr.h |6 +
>  target/ppc/kvm.c   |4 +
>  5 files changed, 284 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 6cc2c3b..d61905b 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -2908,6 +2908,19 @@ static void spapr_machine_init(MachineState *machine)
>  error_report("Could not get size of LPAR rtas '%s'", filename);
>  exit(1);
>  }
> +
> +if (spapr_get_cap(spapr, SPAPR_CAP_FWNMI_MCE) == SPAPR_CAP_ON) {
> +/*
> + * Ensure that the rtas image size is less than RTAS_ERROR_LOG_OFFSET
> + * or else the rtas image will be overwritten with the rtas error log
> + * when a machine check exception is encountered.
> + */
> +g_assert(spapr->rtas_size < RTAS_ERROR_LOG_OFFSET);
> +
> +/* Resize rtas blob to accommodate error log */
> +spapr->rtas_size = RTAS_ERROR_LOG_MAX;
> +}
> +
>  spapr->rtas_blob = g_malloc(spapr->rtas_size);
>  if (load_image_size(filename, spapr->rtas_blob, spapr->rtas_size) < 0) {
>  error_report("Could not load LPAR rtas '%s'", filename);
> diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
> index a0c66d7..51c052e 100644
> --- a/hw/ppc/spapr_events.c
> +++ b/hw/ppc/spapr_events.c
> @@ -212,6 +212,106 @@ struct hp_extended_log {
>  struct rtas_event_log_v6_hp hp;
>  } QEMU_PACKED;
>  
> +struct rtas_event_log_v6_mc {
> +#define RTAS_LOG_V6_SECTION_ID_MC   0x4D43 /* MC */
> +struct rtas_event_log_v6_section_header hdr;
> +uint32_t fru_id;
> +uint32_t proc_id;
> +uint8_t error_type;
> +#define RTAS_LOG_V6_MC_TYPE_UE   0
> +#define RTAS_LOG_V6_MC_TYPE_SLB  1
> +#define RTAS_LOG_V6_MC_TYPE_ERAT 2
> +#define RTAS_LOG_V6_MC_TYPE_TLB  4
> +#define RTAS_LOG_V6_MC_TYPE_D_CACHE  5
> +#define RTAS_LOG_V6_MC_TYPE_I_CACHE  7
> +uint8_t sub_err_type;
> +#define RTAS_LOG_V6_MC_UE_INDETERMINATE  0
> +#define RTAS_LOG_V6_MC_UE_IFETCH 1
> +#define RTAS_LOG_V6_MC_UE_PAGE_TABLE_WALK_IFETCH 2
> +#define RTAS_LOG_V6_MC_UE_LOAD_STORE 3
> +#define RTAS_LOG_V6_MC_UE_PAGE_TABLE_WALK_LOAD_STORE 4
> +#define RTAS_LOG_V6_MC_SLB_PARITY0
> +#define RTAS_LOG_V6_MC_SLB_MULTIHIT  1
> +#define RTAS_LOG_V6_MC_SLB_INDETERMINATE 2
> +#define RTAS_LOG_V6_MC_ERAT_PARITY   1
> +#define RTAS_LOG_V6_MC_ERAT_MULTIHIT 2
> +#define RTAS_LOG_V6_MC_ERAT_INDETERMINATE3
> +#define RTAS_LOG_V6_MC_TLB_PARITY1
> +#define RTAS_LOG_V6_MC_TLB_MULTIHIT  2
> +#define RTAS_LOG_V6_MC_TLB_INDETERMINATE 3
> +uint8_t reserved_1[6];
> +uint64_t effective_address;
> +uint64_t logical_address;
> +} QEMU_PACKED;
> +
> +struct mc_extended_log {
> +struct rtas_event_log_v6 v6hdr;
> +struct rtas_event_log_v6_mc mc;
> +} QEMU_PACKED;
> +
> +struct MC_ierror_table {
> +unsigned long srr1_mask;
> +unsigned long srr1_value;
> +bool nip_valid; /* nip is a valid indicator of faulting address */
> +uint8_t error_type;
> +uint8_t error_subtype;
> +unsigned int initiator;
> +unsigned int severity;
> +};
> +
> +static const struct MC_ierror_table mc_ierror_table[] = {
> +{ 0x081c, 0x0004, true,
> +  RTAS_LOG_V6_MC_TYPE_UE, RTAS_LOG_V6_MC_UE_IFETCH,
> +  RTAS_LOG_INITIATOR_CPU, RTAS_LOG_SEVERITY_ERROR_SYNC, },
> +{ 0x081c, 0x0008, true,
> +  RTAS_LOG_V6_MC_TYPE_SLB, RTAS_LOG_V6_MC_SLB_PARITY,
> +  RTAS_LOG_INITIATOR_CPU, RTAS_LOG_SEVERITY_ERROR_SYNC, },
> +{ 0x081c, 0x000c, true,
> +  RTAS_LOG_V6_MC_TYPE_SLB, RTAS_LOG_V6_MC_SLB_MULTIHIT,
> +  RTAS_LOG_INITIATOR_CPU, RTAS_LOG_SEVERITY_ERROR_SYNC, },
> +{ 0x081c, 0

Re: [Qemu-devel] [PATCH v10 2/6] ppc: spapr: Introduce FWNMI capability

2019-07-01 Thread David Gibson
On Wed, Jun 12, 2019 at 02:51:04PM +0530, Aravinda Prasad wrote:
> Introduce the KVM capability KVM_CAP_PPC_FWNMI so that
> the KVM causes guest exit with NMI as exit reason
> when it encounters a machine check exception on the
> address belonging to a guest. Without this capability
> enabled, KVM redirects machine check exceptions to
> guest's 0x200 vector.
> 
> This patch also introduces fwnmi-mce capability to
> deal with the case when a guest with the
> KVM_CAP_PPC_FWNMI capability enabled is attempted
> to migrate to a host that does not support this
> capability.
> 
> Signed-off-by: Aravinda Prasad 
> ---
>  hw/ppc/spapr.c |1 +
>  hw/ppc/spapr_caps.c|   26 ++
>  include/hw/ppc/spapr.h |4 +++-
>  target/ppc/kvm.c   |   19 +++
>  target/ppc/kvm_ppc.h   |   12 
>  5 files changed, 61 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 6dd8aaa..2ef86aa 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -4360,6 +4360,7 @@ static void spapr_machine_class_init(ObjectClass *oc, 
> void *data)
>  smc->default_caps.caps[SPAPR_CAP_NESTED_KVM_HV] = SPAPR_CAP_OFF;
>  smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_ON;
>  smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF;
> +smc->default_caps.caps[SPAPR_CAP_FWNMI_MCE] = SPAPR_CAP_OFF;
>  spapr_caps_add_properties(smc, &error_abort);
>  smc->irq = &spapr_irq_dual;
>  smc->dr_phb_enabled = true;
> diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
> index 31b4661..2e92eb6 100644
> --- a/hw/ppc/spapr_caps.c
> +++ b/hw/ppc/spapr_caps.c
> @@ -479,6 +479,22 @@ static void cap_ccf_assist_apply(SpaprMachineState 
> *spapr, uint8_t val,
>  }
>  }
>  
> +static void cap_fwnmi_mce_apply(SpaprMachineState *spapr, uint8_t val,
> +Error **errp)
> +{
> +if (!val) {
> +return; /* Disabled by default */
> +}
> +
> +if (tcg_enabled()) {
> +error_setg(errp,
> +"No Firmware Assisted Non-Maskable Interrupts support in TCG, try 
> cap-fwnmi-mce=off");

Not allowing this for TCG creates an awkward incompatibility between
KVM and TCG guests.  I can't actually see any reason to ban it for TCG
- with the current code TCG won't ever generate NMIs, but I don't see
that anything will actually break.

In fact, we do have an nmi monitor command, currently wired to the
spapr_nmi() function which resets each cpu, but it probably makes
sense to wire it up to the fwnmi stuff when present.

> +} else if (kvm_enabled() && !kvmppc_has_cap_ppc_fwnmi()) {
> +error_setg(errp,
> +"Firmware Assisted Non-Maskable Interrupts not supported by KVM, try 
> cap-fwnmi-mce=off");
> +}
> +}
> +
>  SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
>  [SPAPR_CAP_HTM] = {
>  .name = "htm",
> @@ -578,6 +594,15 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
>  .type = "bool",
>  .apply = cap_ccf_assist_apply,
>  },
> +[SPAPR_CAP_FWNMI_MCE] = {
> +.name = "fwnmi-mce",
> +.description = "Handle fwnmi machine check exceptions",
> +.index = SPAPR_CAP_FWNMI_MCE,
> +.get = spapr_cap_get_bool,
> +.set = spapr_cap_set_bool,
> +.type = "bool",
> +.apply = cap_fwnmi_mce_apply,
> +},
>  };
>  
>  static SpaprCapabilities default_caps_with_cpu(SpaprMachineState *spapr,
> @@ -717,6 +742,7 @@ SPAPR_CAP_MIG_STATE(hpt_maxpagesize, 
> SPAPR_CAP_HPT_MAXPAGESIZE);
>  SPAPR_CAP_MIG_STATE(nested_kvm_hv, SPAPR_CAP_NESTED_KVM_HV);
>  SPAPR_CAP_MIG_STATE(large_decr, SPAPR_CAP_LARGE_DECREMENTER);
>  SPAPR_CAP_MIG_STATE(ccf_assist, SPAPR_CAP_CCF_ASSIST);
> +SPAPR_CAP_MIG_STATE(fwnmi, SPAPR_CAP_FWNMI_MCE);
>  
>  void spapr_caps_init(SpaprMachineState *spapr)
>  {
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index 4f5becf..f891f8f 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -78,8 +78,10 @@ typedef enum {
>  #define SPAPR_CAP_LARGE_DECREMENTER 0x08
>  /* Count Cache Flush Assist HW Instruction */
>  #define SPAPR_CAP_CCF_ASSIST0x09
> +/* FWNMI machine check handling */
> +#define SPAPR_CAP_FWNMI_MCE 0x0A
>  /* Num Caps */
> -#define SPAPR_CAP_NUM   (SPAPR_CAP_CCF_ASSIST + 1)
> +#define SPAPR_CAP_NUM   (SPAPR_CAP_FWNMI_MCE + 1)
>  
>  /*
>   * Capability Values
> diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
> index 3bf0a46..afef4cd 100644
> --- a/target/ppc/kvm.c
> +++ b/target/ppc/kvm.c
> @@ -84,6 +84,7 @@ static int cap_ppc_safe_indirect_branch;
>  static int cap_ppc_count_cache_flush_assist;
>  static int cap_ppc_nested_kvm_hv;
>  static int cap_large_decr;
> +static int cap_ppc_fwnmi;
>  
>  static uint32_t debug_inst_opcode;
>  
> @@ -152,6 +153,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
>  kvmppc_get_cpu_characteristics(s);
>  cap_ppc_nested_kvm_hv

[Qemu-devel] [PULL 4/4] block/stream: introduce a bottom node

2019-07-01 Thread Max Reitz
From: Andrey Shinkevich 

The bottom node is the intermediate block device that has the base as its
backing image. It is used instead of the base node while a block stream
job is running to avoid dependency on the base that may change due to the
parallel jobs. The change may take place due to a filter node as well that
is inserted between the base and the intermediate bottom node. It occurs
when the base node is the top one for another commit or stream job.
After the introduction of the bottom node, don't freeze its backing child,
that's the base, anymore.

Suggested-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: Andrey Shinkevich 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Alberto Garcia 
Message-id: 1559152576-281803-4-git-send-email-andrey.shinkev...@virtuozzo.com
Reviewed-by: Max Reitz 
Signed-off-by: Max Reitz 
---
 block/stream.c | 43 ++
 tests/qemu-iotests/245 |  4 ++--
 2 files changed, 25 insertions(+), 22 deletions(-)

diff --git a/block/stream.c b/block/stream.c
index 65b13b27e0..cd5e2ba9b0 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -31,7 +31,7 @@ enum {
 
 typedef struct StreamBlockJob {
 BlockJob common;
-BlockDriverState *base;
+BlockDriverState *bottom;
 BlockdevOnError on_error;
 char *backing_file_str;
 bool bs_read_only;
@@ -54,7 +54,7 @@ static void stream_abort(Job *job)
 
 if (s->chain_frozen) {
 BlockJob *bjob = &s->common;
-bdrv_unfreeze_backing_chain(blk_bs(bjob->blk), s->base);
+bdrv_unfreeze_backing_chain(blk_bs(bjob->blk), s->bottom);
 }
 }
 
@@ -63,11 +63,11 @@ static int stream_prepare(Job *job)
 StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
 BlockJob *bjob = &s->common;
 BlockDriverState *bs = blk_bs(bjob->blk);
-BlockDriverState *base = s->base;
+BlockDriverState *base = backing_bs(s->bottom);
 Error *local_err = NULL;
 int ret = 0;
 
-bdrv_unfreeze_backing_chain(bs, base);
+bdrv_unfreeze_backing_chain(bs, s->bottom);
 s->chain_frozen = false;
 
 if (bs->backing) {
@@ -110,7 +110,7 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
 StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
 BlockBackend *blk = s->common.blk;
 BlockDriverState *bs = blk_bs(blk);
-BlockDriverState *base = s->base;
+bool enable_cor = !backing_bs(s->bottom);
 int64_t len;
 int64_t offset = 0;
 uint64_t delay_ns = 0;
@@ -119,7 +119,8 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
 int64_t n = 0; /* bytes */
 void *buf;
 
-if (!bs->backing) {
+if (bs == s->bottom) {
+/* Nothing to stream */
 return 0;
 }
 
@@ -136,7 +137,7 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
  * backing chain since the copy-on-read operation does not take base into
  * account.
  */
-if (!base) {
+if (enable_cor) {
 bdrv_enable_copy_on_read(bs);
 }
 
@@ -159,9 +160,8 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
 } else if (ret >= 0) {
 /* Copy if allocated in the intermediate images.  Limit to the
  * known-unallocated area [offset, offset+n*BDRV_SECTOR_SIZE).  */
-ret = bdrv_is_allocated_above(backing_bs(bs), base, false,
+ret = bdrv_is_allocated_above(backing_bs(bs), s->bottom, true,
   offset, n, &n);
-
 /* Finish early if end of backing file has been reached */
 if (ret == 0 && n == 0) {
 n = len - offset;
@@ -198,7 +198,7 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
 }
 }
 
-if (!base) {
+if (enable_cor) {
 bdrv_disable_copy_on_read(bs);
 }
 
@@ -230,8 +230,10 @@ void stream_start(const char *job_id, BlockDriverState *bs,
 StreamBlockJob *s;
 BlockDriverState *iter;
 bool bs_read_only;
+int basic_flags = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED;
+BlockDriverState *bottom = bdrv_find_overlay(bs, base);
 
-if (bdrv_freeze_backing_chain(bs, base, errp) < 0) {
+if (bdrv_freeze_backing_chain(bs, bottom, errp) < 0) {
 return;
 }
 
@@ -248,10 +250,8 @@ void stream_start(const char *job_id, BlockDriverState *bs,
  * already have our own plans. Also don't allow resize as the image size is
  * queried only at the job start and then cached. */
 s = block_job_create(job_id, &stream_job_driver, NULL, bs,
- BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED |
- BLK_PERM_GRAPH_MOD,
- BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED |
- BLK_PERM_WRITE,
+ basic_flags | BLK_PERM_GRAPH_MOD,
+ basic_flags | BLK_PERM_WRITE,
  speed, creation_flags, NULL, NULL, errp);

[Qemu-devel] [PULL 14/17] COLO-compare: Add remote notification chardev handler frame

2019-07-01 Thread Jason Wang
From: Zhang Chen 

Add chardev handler to send notification to remote(current from Xen) colo-frame.

Signed-off-by: Zhang Chen 
Signed-off-by: Jason Wang 
---
 net/colo-compare.c | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index 10fae2b..fda55d5 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -87,8 +87,10 @@ typedef struct CompareState {
 CharBackend chr_pri_in;
 CharBackend chr_sec_in;
 CharBackend chr_out;
+CharBackend chr_notify_dev;
 SocketReadState pri_rs;
 SocketReadState sec_rs;
+SocketReadState notify_rs;
 bool vnet_hdr;
 
 /*
@@ -745,6 +747,19 @@ static void compare_sec_chr_in(void *opaque, const uint8_t 
*buf, int size)
 }
 }
 
+static void compare_notify_chr(void *opaque, const uint8_t *buf, int size)
+{
+CompareState *s = COLO_COMPARE(opaque);
+int ret;
+
+ret = net_fill_rstate(&s->notify_rs, buf, size);
+if (ret == -1) {
+qemu_chr_fe_set_handlers(&s->chr_notify_dev, NULL, NULL, NULL, NULL,
+ NULL, NULL, true);
+error_report("colo-compare notify_dev error");
+}
+}
+
 /*
  * Check old packet regularly so it can watch for any packets
  * that the secondary hasn't produced equivalents of.
@@ -832,6 +847,11 @@ static void colo_compare_iothread(CompareState *s)
 qemu_chr_fe_set_handlers(&s->chr_sec_in, compare_chr_can_read,
  compare_sec_chr_in, NULL, NULL,
  s, s->worker_context, true);
+if (s->notify_dev) {
+qemu_chr_fe_set_handlers(&s->chr_notify_dev, compare_chr_can_read,
+ compare_notify_chr, NULL, NULL,
+ s, s->worker_context, true);
+}
 
 colo_compare_timer_init(s);
 s->event_bh = qemu_bh_new(colo_compare_handle_event, s);
@@ -943,6 +963,10 @@ static void compare_sec_rs_finalize(SocketReadState 
*sec_rs)
 }
 }
 
+static void compare_notify_rs_finalize(SocketReadState *notify_rs)
+{
+/* Get Xen colo-frame's notify and handle the message */
+}
 
 /*
  * Return 0 is success.
@@ -1013,6 +1037,17 @@ static void colo_compare_complete(UserCreatable *uc, 
Error **errp)
 net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize, s->vnet_hdr);
 net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize, s->vnet_hdr);
 
+/* Try to enable remote notify chardev, currently just for Xen COLO */
+if (s->notify_dev) {
+if (find_and_check_chardev(&chr, s->notify_dev, errp) ||
+!qemu_chr_fe_init(&s->chr_notify_dev, chr, errp)) {
+return;
+}
+
+net_socket_rs_init(&s->notify_rs, compare_notify_rs_finalize,
+   s->vnet_hdr);
+}
+
 QTAILQ_INSERT_TAIL(&net_compares, s, next);
 
 g_queue_init(&s->conn_list);
@@ -1091,6 +1126,10 @@ static void colo_compare_finalize(Object *obj)
 qemu_chr_fe_deinit(&s->chr_pri_in, false);
 qemu_chr_fe_deinit(&s->chr_sec_in, false);
 qemu_chr_fe_deinit(&s->chr_out, false);
+if (s->notify_dev) {
+qemu_chr_fe_deinit(&s->chr_notify_dev, false);
+}
+
 if (s->iothread) {
 colo_compare_timer_del(s);
 }
-- 
2.5.0




Re: [Qemu-devel] [PATCH v10 6/6] ppc: spapr: Handle "ibm, nmi-register" and "ibm, nmi-interlock" RTAS calls

2019-07-01 Thread David Gibson
On Wed, Jun 12, 2019 at 02:51:38PM +0530, Aravinda Prasad wrote:
> This patch adds support in QEMU to handle "ibm,nmi-register"
> and "ibm,nmi-interlock" RTAS calls and sets the default
> value of SPAPR_CAP_FWNMI_MCE to SPAPR_CAP_ON for machine
> type 4.0.
> 
> The machine check notification address is saved when the
> OS issues "ibm,nmi-register" RTAS call.
> 
> This patch also handles the case when multiple processors
> experience machine check at or about the same time by
> handling "ibm,nmi-interlock" call. In such cases, as per
> PAPR, subsequent processors serialize waiting for the first
> processor to issue the "ibm,nmi-interlock" call. The second
> processor that also received a machine check error waits
> till the first processor is done reading the error log.
> The first processor issues "ibm,nmi-interlock" call
> when the error log is consumed.
> 
> Signed-off-by: Aravinda Prasad 
> ---
>  hw/ppc/spapr.c |6 -
>  hw/ppc/spapr_rtas.c|   63 
> 
>  include/hw/ppc/spapr.h |5 +++-
>  3 files changed, 72 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 3d6d139..213d493 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -2946,6 +2946,9 @@ static void spapr_machine_init(MachineState *machine)
>  /* Create the error string for live migration blocker */
>  error_setg(&spapr->fwnmi_migration_blocker,
>  "Live migration not supported during machine check 
> handling");
> +
> +/* Register ibm,nmi-register and ibm,nmi-interlock RTAS calls */
> +spapr_fwnmi_register();
>  }
>  
>  spapr->rtas_blob = g_malloc(spapr->rtas_size);
> @@ -4408,7 +4411,7 @@ static void spapr_machine_class_init(ObjectClass *oc, 
> void *data)
>  smc->default_caps.caps[SPAPR_CAP_NESTED_KVM_HV] = SPAPR_CAP_OFF;
>  smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_ON;
>  smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF;
> -smc->default_caps.caps[SPAPR_CAP_FWNMI_MCE] = SPAPR_CAP_OFF;
> +smc->default_caps.caps[SPAPR_CAP_FWNMI_MCE] = SPAPR_CAP_ON;

Turning this on by default really isn't ok if it stops you running TCG
guests at all.

>  spapr_caps_add_properties(smc, &error_abort);
>  smc->irq = &spapr_irq_dual;
>  smc->dr_phb_enabled = true;
> @@ -4512,6 +4515,7 @@ static void 
> spapr_machine_3_1_class_options(MachineClass *mc)
>  smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN;
>  smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN;
>  smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_OFF;
> +smc->default_caps.caps[SPAPR_CAP_FWNMI_MCE] = SPAPR_CAP_OFF;

We're now well past 4.0, and in fact we're about to go into soft
freeze for 4.1, so we're going to miss that too.  So 4.1 and earlier
will need to retain the old default.

>  }
>  
>  DEFINE_SPAPR_MACHINE(3_1, "3.1", false);
> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
> index a015a80..e010cb2 100644
> --- a/hw/ppc/spapr_rtas.c
> +++ b/hw/ppc/spapr_rtas.c
> @@ -49,6 +49,7 @@
>  #include "hw/ppc/fdt.h"
>  #include "target/ppc/mmu-hash64.h"
>  #include "target/ppc/mmu-book3s-v3.h"
> +#include "migration/blocker.h"
>  
>  static void rtas_display_character(PowerPCCPU *cpu, SpaprMachineState *spapr,
> uint32_t token, uint32_t nargs,
> @@ -352,6 +353,60 @@ static void rtas_get_power_level(PowerPCCPU *cpu, 
> SpaprMachineState *spapr,
>  rtas_st(rets, 1, 100);
>  }
>  
> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
> +  SpaprMachineState *spapr,
> +  uint32_t token, uint32_t nargs,
> +  target_ulong args,
> +  uint32_t nret, target_ulong rets)
> +{
> +int ret;
> +hwaddr rtas_addr = spapr_get_rtas_addr();
> +
> +if (!rtas_addr) {
> +rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
> +return;
> +}
> +
> +if (spapr_get_cap(spapr, SPAPR_CAP_FWNMI_MCE) == SPAPR_CAP_OFF) {
> +rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
> +return;
> +}
> +
> +ret = kvmppc_fwnmi_enable(cpu);
> +if (ret == 1) {
> +rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);

I don't understand this case separate from the others.  We've already
set the cap, so fwnmi support should be checked and available.

> +return;
> +} else if (ret < 0) {
> +error_report("Couldn't enable KVM FWNMI capability");
> +rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
> +return;
> +}
> +
> +spapr->guest_machine_check_addr = rtas_ld(args, 1);
> +rtas_st(rets, 0, RTAS_OUT_SUCCESS);
> +}
> +
> +static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu,
> +   SpaprMachineState *spapr,
> +   uint32_t token, uint32_t nargs,
> +  

Re: [Qemu-devel] [PATCH v9 0/2] Add Arm SBSA Reference Machine

2019-07-01 Thread Hongbo Zhang
On Mon, 1 Jul 2019 at 22:54, Peter Maydell  wrote:
>
> On Sun, 30 Jun 2019 at 11:21, Hongbo Zhang  wrote:
> >
> > For the Aarch64, there is one machine 'virt', it is primarily meant to
> > run on KVM and execute virtualization workloads, but we need an
> > environment as faithful as possible to physical hardware,  to support
> > firmware and OS development for pysical Aarch64 machines.
> >
> > This machine comes with:
> >  - Re-designed memory map.
> >  - CPU cortex-a57.
> >  - EL2 and EL3 enabled.
> >  - GIC version 3.
> >  - System bus AHCI controller.
> >  - System bus XHCI controller.
> >  - CDROM and hard disc on AHCI bus.
> >  - E1000E ethernet card on PCIE bus.
> >  - VGA display adaptor on PCIE bus.
> >  - Only minimal device tree nodes.
> > And without:
> >  - virtio deivces.
> >  - fw_cfg device.
> >  - ACPI tables.
>
> I've pointed out a number of issues with these patches, but they
> all turn out to be very minor (mostly fixable by moving code between
> patch 1 and 2). The other thing we need is a MAINTAINERS section for
> the new board:
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index cad58b94879..0bf3739f06a 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -728,6 +728,13 @@ F: include/hw/arm/fsl-imx6.h
>  F: include/hw/misc/imx6_*.h
>  F: include/hw/ssi/imx_spi.h
>
> +SBSA-REF
> +M: Hongbo Zhang 
> +M: Peter Maydell 
> +L: qemu-...@nongnu.org
> +S: Maintained
> +F: hw/arm/sbsa-ref.c
> +
>  Sharp SL-5500 (Collie) PDA
>  M: Peter Maydell 
>  L: qemu-...@nongnu.org
>
>
> So rather than making you do another respin, I'm planning to
> make the fixes in my target-arm.next tree as I apply the patches.
> That way we can get this in before softfreeze (which is tomorrow).
>
Thank you for the efforts.

> thanks
> -- PMM



[Qemu-devel] [PULL 17/17] migration/colo.c: Add missed filter notify for Xen COLO.

2019-07-01 Thread Jason Wang
From: Zhang Chen 

We need to notify net filter to do checkpoint for Xen COLO, like KVM side.

Signed-off-by: Zhang Chen 
Signed-off-by: Jason Wang 
---
 migration/colo.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/migration/colo.c b/migration/colo.c
index 8c16440..9f84b1f 100644
--- a/migration/colo.c
+++ b/migration/colo.c
@@ -259,6 +259,8 @@ ReplicationStatus *qmp_query_xen_replication_status(Error 
**errp)
 void qmp_xen_colo_do_checkpoint(Error **errp)
 {
 replication_do_checkpoint_all(errp);
+/* Notify all filters of all NIC to do checkpoint */
+colo_notify_filters_event(COLO_EVENT_CHECKPOINT, errp);
 }
 #endif
 
-- 
2.5.0




[Qemu-devel] [PULL 12/17] net/announce: Expand test for stopping self announce

2019-07-01 Thread Jason Wang
From: "Dr. David Alan Gilbert" 

Expand self-announce test to check we can stop an announce timer.
We set it up to send 300 packets, but after we receive
the first one we tell it to stop.

We error if:
   a) We receive more than 30 of the packets
   b) We're still receiving packets after a lot longer than the
  30 seconds should have arrived

Signed-off-by: Dr. David Alan Gilbert 
Signed-off-by: Jason Wang 
---
 tests/virtio-net-test.c | 57 ++---
 1 file changed, 54 insertions(+), 3 deletions(-)

diff --git a/tests/virtio-net-test.c b/tests/virtio-net-test.c
index 663cf7e..7aa9622 100644
--- a/tests/virtio-net-test.c
+++ b/tests/virtio-net-test.c
@@ -184,21 +184,72 @@ static void announce_self(void *obj, void *data, 
QGuestAllocator *t_alloc)
 QDict *rsp;
 int ret;
 uint16_t *proto = (uint16_t *)&buffer[12];
+size_t total_received = 0;
+uint64_t start, now, last_rxt, deadline;
 
+/* Send a set of packets over a few second period */
 rsp = qmp("{ 'execute' : 'announce-self', "
   " 'arguments': {"
-  " 'initial': 50, 'max': 550,"
-  " 'rounds': 10, 'step': 50 } }");
+  " 'initial': 20, 'max': 100,"
+  " 'rounds': 300, 'step': 10, 'id': 'bob' } }");
 assert(!qdict_haskey(rsp, "error"));
 qobject_unref(rsp);
 
-/* Catch the packet and make sure it's a RARP */
+/* Catch the first packet and make sure it's a RARP */
 ret = qemu_recv(sv[0], &len, sizeof(len), 0);
 g_assert_cmpint(ret, ==,  sizeof(len));
 len = ntohl(len);
 
 ret = qemu_recv(sv[0], buffer, len, 0);
 g_assert_cmpint(*proto, ==, htons(ETH_P_RARP));
+
+/*
+ * Stop the announcment by settings rounds to 0 on the
+ * existing timer.
+ */
+rsp = qmp("{ 'execute' : 'announce-self', "
+  " 'arguments': {"
+  " 'initial': 20, 'max': 100,"
+  " 'rounds': 0, 'step': 10, 'id': 'bob' } }");
+assert(!qdict_haskey(rsp, "error"));
+qobject_unref(rsp);
+
+/* Now make sure the packets stop */
+
+/* Times are in us */
+start = g_get_monotonic_time();
+/* 30 packets, max gap 100ms, * 4 for wiggle */
+deadline = start + 1000 * (100 * 30 * 4);
+last_rxt = start;
+
+while (true) {
+int saved_err;
+ret = qemu_recv(sv[0], buffer, 60, MSG_DONTWAIT);
+saved_err = errno;
+now = g_get_monotonic_time();
+g_assert_cmpint(now, <, deadline);
+
+if (ret >= 0) {
+if (ret) {
+last_rxt = now;
+}
+total_received += ret;
+
+/* Check it's not spewing loads */
+g_assert_cmpint(total_received, <, 60 * 30 * 2);
+} else {
+g_assert_cmpint(saved_err, ==, EAGAIN);
+
+/* 400ms, i.e. 4 worst case gaps */
+if ((now - last_rxt) > (1000 * 100 * 4)) {
+/* Nothings arrived for a while - must have stopped */
+break;
+};
+
+/* 100ms */
+g_usleep(1000 * 100);
+}
+};
 }
 
 static void virtio_net_test_cleanup(void *sockets)
-- 
2.5.0




[Qemu-devel] [PULL 16/17] COLO-compare: Add colo-compare remote notify support

2019-07-01 Thread Jason Wang
From: Zhang Chen 

This patch make colo-compare can send message to remote COLO frame(Xen) when 
occur checkpoint.

Signed-off-by: Zhang Chen 
Signed-off-by: Jason Wang 
---
 net/colo-compare.c | 54 --
 1 file changed, 44 insertions(+), 10 deletions(-)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index ee03c25..909dd6c 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -120,11 +120,6 @@ enum {
 SECONDARY_IN,
 };
 
-static void colo_compare_inconsistency_notify(void)
-{
-notifier_list_notify(&colo_compare_notifiers,
-migrate_get_current());
-}
 
 static int compare_chr_send(CompareState *s,
 const uint8_t *buf,
@@ -132,6 +127,27 @@ static int compare_chr_send(CompareState *s,
 uint32_t vnet_hdr_len,
 bool notify_remote_frame);
 
+static void notify_remote_frame(CompareState *s)
+{
+char msg[] = "DO_CHECKPOINT";
+int ret = 0;
+
+ret = compare_chr_send(s, (uint8_t *)msg, strlen(msg), 0, true);
+if (ret < 0) {
+error_report("Notify Xen COLO-frame failed");
+}
+}
+
+static void colo_compare_inconsistency_notify(CompareState *s)
+{
+if (s->notify_dev) {
+notify_remote_frame(s);
+} else {
+notifier_list_notify(&colo_compare_notifiers,
+ migrate_get_current());
+}
+}
+
 static gint seq_sorter(Packet *a, Packet *b, gpointer data)
 {
 struct tcp_hdr *atcp, *btcp;
@@ -435,7 +451,7 @@ sec:
 qemu_hexdump((char *)spkt->data, stderr,
  "colo-compare spkt", spkt->size);
 
-colo_compare_inconsistency_notify();
+colo_compare_inconsistency_notify(s);
 }
 }
 
@@ -577,7 +593,7 @@ void colo_compare_unregister_notifier(Notifier *notify)
 }
 
 static int colo_old_packet_check_one_conn(Connection *conn,
-   void *user_data)
+  CompareState *s)
 {
 GList *result = NULL;
 int64_t check_time = REGULAR_PACKET_CHECK_MS;
@@ -588,7 +604,7 @@ static int colo_old_packet_check_one_conn(Connection *conn,
 
 if (result) {
 /* Do checkpoint will flush old packet */
-colo_compare_inconsistency_notify();
+colo_compare_inconsistency_notify(s);
 return 0;
 }
 
@@ -608,7 +624,7 @@ static void colo_old_packet_check(void *opaque)
  * If we find one old packet, stop finding job and notify
  * COLO frame do checkpoint.
  */
-g_queue_find_custom(&s->conn_list, NULL,
+g_queue_find_custom(&s->conn_list, s,
 (GCompareFunc)colo_old_packet_check_one_conn);
 }
 
@@ -637,7 +653,8 @@ static void colo_compare_packet(CompareState *s, Connection 
*conn,
  */
 trace_colo_compare_main("packet different");
 g_queue_push_head(&conn->primary_list, pkt);
-colo_compare_inconsistency_notify();
+
+colo_compare_inconsistency_notify(s);
 break;
 }
 }
@@ -989,7 +1006,24 @@ static void compare_sec_rs_finalize(SocketReadState 
*sec_rs)
 
 static void compare_notify_rs_finalize(SocketReadState *notify_rs)
 {
+CompareState *s = container_of(notify_rs, CompareState, notify_rs);
+
 /* Get Xen colo-frame's notify and handle the message */
+char *data = g_memdup(notify_rs->buf, notify_rs->packet_len);
+char msg[] = "COLO_COMPARE_GET_XEN_INIT";
+int ret;
+
+if (!strcmp(data, "COLO_USERSPACE_PROXY_INIT")) {
+ret = compare_chr_send(s, (uint8_t *)msg, strlen(msg), 0, true);
+if (ret < 0) {
+error_report("Notify Xen COLO-frame INIT failed");
+}
+}
+
+if (!strcmp(data, "COLO_CHECKPOINT")) {
+/* colo-compare do checkpoint, flush pri packet and remove sec packet 
*/
+g_queue_foreach(&s->conn_list, colo_flush_packets, s);
+}
 }
 
 /*
-- 
2.5.0




Re: [Qemu-devel] [PATCH v9 0/2] Add Arm SBSA Reference Machine

2019-07-01 Thread Hongbo Zhang
On Tue, 2 Jul 2019 at 00:08, Leif Lindholm  wrote:
>
> Hi Peter,
>
> On Mon, Jul 01, 2019 at 03:54:24PM +0100, Peter Maydell wrote:
> > I've pointed out a number of issues with these patches, but they
> > all turn out to be very minor (mostly fixable by moving code between
> > patch 1 and 2). The other thing we need is a MAINTAINERS section for
> > the new board:
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index cad58b94879..0bf3739f06a 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -728,6 +728,13 @@ F: include/hw/arm/fsl-imx6.h
> >  F: include/hw/misc/imx6_*.h
> >  F: include/hw/ssi/imx_spi.h
> >
> > +SBSA-REF
> > +M: Hongbo Zhang 
> > +M: Peter Maydell 
> > +L: qemu-...@nongnu.org
> > +S: Maintained
> > +F: hw/arm/sbsa-ref.c
> > +
>
> Sadly, Hongbo is no longer in Linaro (but has generously helped keep
> working on this platform being upstreamed since he left). It is my
> understanding that in his new role, Hongbo does not have the bandwidth
> to keep maintaining this platform once it's in.
>
> Unless I have misunderstood this (Hongbo, please confirm - we would
> certainly love to have your help if you feel that you do have the
> banwidth), could we please add Radek as a maintainer instead?:
>
Yes we can add Radoslaw as maintainer.
As to me, my new role still have relation with Arm and virtualization,
I will keep watching this :)

> M: Radoslaw Biernacki 
>
> If you think it could be useful, feel free to add me as a designated
> reviewer:
>
> R: Leif Lindholm 
>
> (I would not be offended if you don't, I have plenty to keep me busy :)
>
> >  Sharp SL-5500 (Collie) PDA
> >  M: Peter Maydell 
> >  L: qemu-...@nongnu.org
> >
> >
> > So rather than making you do another respin, I'm planning to
> > make the fixes in my target-arm.next tree as I apply the patches.
> > That way we can get this in before softfreeze (which is tomorrow).
>
> Many thanks!
>
> Best Regards,
>
> Leif



Re: [Qemu-devel] [PATCH v2 5/9] hw/block/pflash_cfi01: Add the DeviceReset() handler

2019-07-01 Thread John Snow



On 7/1/19 8:12 PM, Philippe Mathieu-Daudé wrote:
> A "system reset" sets the device state machine in READ_ARRAY mode
> and, after some delay, set the SR.7 READY bit.
> 
> We do not model timings, so we set the SR.7 bit directly.
> 
> This pflash device is a child of TYPE_DEVICE.
> The TYPE_DEVICE interface provide a DeviceReset handler which will
> be called after the device is realized, and each time the machine
> resets itself.
> 
> To avoid incoherent states when the machine resets (see but report
> below), factor out the reset code into pflash_cfi01_system_reset,
> and register the method as a device reset callback.
> 
> Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1678713
> Reported-by: Laszlo Ersek 
> Signed-off-by: Philippe Mathieu-Daudé 

Does reset always get called as part of realize, really?

Or are we just trusting that the device is probably going to get reset
by the guest during bringup?

> ---
>  hw/block/pflash_cfi01.c | 15 +--
>  1 file changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
> index dd1dfd266b..8d632ea941 100644
> --- a/hw/block/pflash_cfi01.c
> +++ b/hw/block/pflash_cfi01.c
> @@ -763,8 +763,6 @@ static void pflash_cfi01_realize(DeviceState *dev, Error 
> **errp)
>  pfl->max_device_width = pfl->device_width;
>  }
>  
> -pflash_mode_read_array(pfl);
> -pfl->status = 0x80; /* WSM ready */
>  /* Hardcoded CFI table */
>  /* Standard "QRY" string */
>  pfl->cfi_table[0x10] = 'Q';
> @@ -852,6 +850,18 @@ static void pflash_cfi01_realize(DeviceState *dev, Error 
> **errp)
>  pfl->cfi_table[0x3f] = 0x01; /* Number of protection fields */
>  }
>  
> +static void pflash_cfi01_system_reset(DeviceState *dev)
> +{
> +PFlashCFI01 *pfl = PFLASH_CFI01(dev);
> +
> +pflash_mode_read_array(pfl);
> +/*
> + * The WSM ready timer occurs at most 150ns after system reset.
> + * This model deliberately ignores this delay.
> + */
> +pfl->status = 0x80;
> +}
> +
>  static Property pflash_cfi01_properties[] = {
>  DEFINE_PROP_DRIVE("drive", PFlashCFI01, blk),
>  /* num-blocks is the number of blocks actually visible to the guest,
> @@ -896,6 +906,7 @@ static void pflash_cfi01_class_init(ObjectClass *klass, 
> void *data)
>  {
>  DeviceClass *dc = DEVICE_CLASS(klass);
>  
> +dc->reset = pflash_cfi01_system_reset;
>  dc->realize = pflash_cfi01_realize;
>  dc->props = pflash_cfi01_properties;
>  dc->vmsd = &vmstate_pflash;
> 



[Qemu-devel] [PULL 09/17] net/announce: Add HMP optional interface list

2019-07-01 Thread Jason Wang
From: "Dr. David Alan Gilbert" 

Add the optional interface list to the HMP command.

i.e.

   All interfaces
announce_self

   Just the named interfaces:
announce_self vn1,vn2

Signed-off-by: Dr. David Alan Gilbert 
Signed-off-by: Jason Wang 
---
 hmp-commands.hx|  6 --
 monitor/hmp-cmds.c | 38 +-
 2 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 8b7aec3..d42c09f 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -955,8 +955,8 @@ ETEXI
 
 {
 .name   = "announce_self",
-.args_type  = "",
-.params = "",
+.args_type  = "interfaces:s?",
+.params = "[interfaces]",
 .help   = "Trigger GARP/RARP announcements",
 .cmd= hmp_announce_self,
 },
@@ -967,6 +967,8 @@ STEXI
 Trigger a round of GARP/RARP broadcasts; this is useful for explicitly 
updating the
 network infrastructure after a reconfiguration or some forms of migration.
 The timings of the round are set by the migration announce parameters.
+An optional comma separated @var{interfaces} list restricts the announce to the
+named set of interfaces.
 ETEXI
 
 {
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index c283dde..0fce179 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -27,6 +27,7 @@
 #include "monitor/monitor-internal.h"
 #include "monitor/qdev.h"
 #include "qapi/error.h"
+#include "qapi/clone-visitor.h"
 #include "qapi/opts-visitor.h"
 #include "qapi/qapi-builtin-visit.h"
 #include "qapi/qapi-commands-block.h"
@@ -38,6 +39,7 @@
 #include "qapi/qapi-commands-run-state.h"
 #include "qapi/qapi-commands-tpm.h"
 #include "qapi/qapi-commands-ui.h"
+#include "qapi/qapi-visit-net.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qerror.h"
 #include "qapi/string-input-visitor.h"
@@ -67,6 +69,32 @@ static void hmp_handle_error(Monitor *mon, Error **errp)
 }
 }
 
+/*
+ * Produce a strList from a comma separated list.
+ * A NULL or empty input string return NULL.
+ */
+static strList *strList_from_comma_list(const char *in)
+{
+strList *res = NULL;
+strList **hook = &res;
+
+while (in && in[0]) {
+char *comma = strchr(in, ',');
+*hook = g_new0(strList, 1);
+
+if (comma) {
+(*hook)->value = g_strndup(in, comma - in);
+in = comma + 1; /* skip the , */
+} else {
+(*hook)->value = g_strdup(in);
+in = NULL;
+}
+hook = &(*hook)->next;
+}
+
+return res;
+}
+
 void hmp_info_name(Monitor *mon, const QDict *qdict)
 {
 NameInfo *info;
@@ -1631,7 +1659,15 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
 
 void hmp_announce_self(Monitor *mon, const QDict *qdict)
 {
-qmp_announce_self(migrate_announce_params(), NULL);
+const char *interfaces_str = qdict_get_try_str(qdict, "interfaces");
+AnnounceParameters *params = QAPI_CLONE(AnnounceParameters,
+migrate_announce_params());
+
+qapi_free_strList(params->interfaces);
+params->interfaces = strList_from_comma_list(interfaces_str);
+params->has_interfaces = params->interfaces != NULL;
+qmp_announce_self(params, NULL);
+qapi_free_AnnounceParameters(params);
 }
 
 void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
-- 
2.5.0




[Qemu-devel] [PULL 13/17] COLO-compare: Add new parameter to communicate with remote colo-frame

2019-07-01 Thread Jason Wang
From: Zhang Chen 

We add the "notify_dev=chardevID" parameter. After that colo-compare can 
connect with
remote(currently just for Xen, KVM-COLO didn't need it.) colo-frame through 
chardev socket,
it can notify remote(Xen) colo-frame to handle checkpoint event.

Signed-off-by: Zhang Chen 
Signed-off-by: Jason Wang 
---
 net/colo-compare.c | 21 +
 qemu-options.hx| 33 -
 2 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index 103297b..10fae2b 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -83,6 +83,7 @@ typedef struct CompareState {
 char *pri_indev;
 char *sec_indev;
 char *outdev;
+char *notify_dev;
 CharBackend chr_pri_in;
 CharBackend chr_sec_in;
 CharBackend chr_out;
@@ -897,6 +898,21 @@ static void compare_set_vnet_hdr(Object *obj,
 s->vnet_hdr = value;
 }
 
+static char *compare_get_notify_dev(Object *obj, Error **errp)
+{
+CompareState *s = COLO_COMPARE(obj);
+
+return g_strdup(s->notify_dev);
+}
+
+static void compare_set_notify_dev(Object *obj, const char *value, Error 
**errp)
+{
+CompareState *s = COLO_COMPARE(obj);
+
+g_free(s->notify_dev);
+s->notify_dev = g_strdup(value);
+}
+
 static void compare_pri_rs_finalize(SocketReadState *pri_rs)
 {
 CompareState *s = container_of(pri_rs, CompareState, pri_rs);
@@ -1057,6 +1073,10 @@ static void colo_compare_init(Object *obj)
 (Object **)&s->iothread,
 object_property_allow_set_link,
 OBJ_PROP_LINK_STRONG, NULL);
+/* This parameter just for Xen COLO */
+object_property_add_str(obj, "notify_dev",
+compare_get_notify_dev, compare_set_notify_dev,
+NULL);
 
 s->vnet_hdr = false;
 object_property_add_bool(obj, "vnet_hdr_support", compare_get_vnet_hdr,
@@ -1103,6 +1123,7 @@ static void colo_compare_finalize(Object *obj)
 g_free(s->pri_indev);
 g_free(s->sec_indev);
 g_free(s->outdev);
+g_free(s->notify_dev);
 }
 
 static const TypeInfo colo_compare_info = {
diff --git a/qemu-options.hx b/qemu-options.hx
index 0d8beb4..c18b790 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4477,7 +4477,7 @@ Dump the network traffic on netdev @var{dev} to the file 
specified by
 The file format is libpcap, so it can be analyzed with tools such as tcpdump
 or Wireshark.
 
-@item -object 
colo-compare,id=@var{id},primary_in=@var{chardevid},secondary_in=@var{chardevid},outdev=@var{chardevid},iothread=@var{id}[,vnet_hdr_support]
+@item -object 
colo-compare,id=@var{id},primary_in=@var{chardevid},secondary_in=@var{chardevid},outdev=@var{chardevid},iothread=@var{id}[,vnet_hdr_support][,notify_dev=@var{id}]
 
 Colo-compare gets packet from primary_in@var{chardevid} and 
secondary_in@var{chardevid}, than compare primary packet with
 secondary packet. If the packets are same, we will output primary
@@ -4486,11 +4486,15 @@ do checkpoint and send primary packet to 
outdev@var{chardevid}.
 In order to improve efficiency, we need to put the task of comparison
 in another thread. If it has the vnet_hdr_support flag, colo compare
 will send/recv packet with vnet_hdr_len.
+If you want to use Xen COLO, will need the notify_dev to notify Xen
+colo-frame to do checkpoint.
 
 we must use it with the help of filter-mirror and filter-redirector.
 
 @example
 
+KVM COLO
+
 primary:
 -netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown
 -device e1000,id=e0,netdev=hn0,mac=52:a4:00:12:78:66
@@ -4514,6 +4518,33 @@ secondary:
 -object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0
 -object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1
 
+
+Xen COLO
+
+primary:
+-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown
+-device e1000,id=e0,netdev=hn0,mac=52:a4:00:12:78:66
+-chardev socket,id=mirror0,host=3.3.3.3,port=9003,server,nowait
+-chardev socket,id=compare1,host=3.3.3.3,port=9004,server,nowait
+-chardev socket,id=compare0,host=3.3.3.3,port=9001,server,nowait
+-chardev socket,id=compare0-0,host=3.3.3.3,port=9001
+-chardev socket,id=compare_out,host=3.3.3.3,port=9005,server,nowait
+-chardev socket,id=compare_out0,host=3.3.3.3,port=9005
+-chardev socket,id=notify_way,host=3.3.3.3,port=9009,server,nowait
+-object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0
+-object filter-redirector,netdev=hn0,id=redire0,queue=rx,indev=compare_out
+-object filter-redirector,netdev=hn0,id=redire1,queue=rx,outdev=compare0
+-object iothread,id=iothread1
+-object 
colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0,notify_dev=nofity_way,iothread=iothread1
+
+secondary:
+-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,down script=/etc/qemu-ifdown
+-device e1000,netdev=hn0,mac=52:a4:00:12:78:66
+-chardev socket,id=red0,host=3.3.3.3,port=9003
+-chardev socket,id

[Qemu-devel] [PULL 07/17] net: remove unused get_str_sep() function

2019-07-01 Thread Jason Wang
From: Stefano Garzarella 

Since the get_str_sep() function is no longer used in
net/net.c, we can remove it.

Signed-off-by: Stefano Garzarella 
Reviewed-by: Markus Armbruster 
Signed-off-by: Jason Wang 
---
 net/net.c | 20 
 1 file changed, 20 deletions(-)

diff --git a/net/net.c b/net/net.c
index 5ce3996..7d40982 100644
--- a/net/net.c
+++ b/net/net.c
@@ -64,26 +64,6 @@ static QTAILQ_HEAD(, NetClientState) net_clients;
 /***/
 /* network device redirectors */
 
-static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
-{
-const char *p, *p1;
-int len;
-p = *pp;
-p1 = strchr(p, sep);
-if (!p1)
-return -1;
-len = p1 - p;
-p1++;
-if (buf_size > 0) {
-if (len > buf_size - 1)
-len = buf_size - 1;
-memcpy(buf, p, len);
-buf[len] = '\0';
-}
-*pp = p1;
-return 0;
-}
-
 int parse_host_port(struct sockaddr_in *saddr, const char *str,
 Error **errp)
 {
-- 
2.5.0




[Qemu-devel] [PULL 2/4] block: include base when checking image chain for block allocation

2019-07-01 Thread Max Reitz
From: Andrey Shinkevich 

This patch is used in the 'block/stream: introduce a bottom node'
that is following. Instead of the base node, the caller may pass
the node that has the base as its backing image to the function
bdrv_is_allocated_above() with a new parameter include_base = true
and get rid of the dependency on the base that may change during
commit/stream parallel jobs. Now, if the specified base is not
found in the backing image chain, the QEMU will abort.

Suggested-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: Andrey Shinkevich 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Alberto Garcia 
Message-id: 1559152576-281803-2-git-send-email-andrey.shinkev...@virtuozzo.com
[mreitz: Squashed in the following as a rebase on conflicting patches:]
Message-id: e3cf99ae-62e9-8b6e-5a06-d3c8b9363...@redhat.com
Signed-off-by: Max Reitz 
---
 include/block/block.h |  3 ++-
 block/commit.c|  2 +-
 block/io.c| 21 +++--
 block/mirror.c|  2 +-
 block/qcow2.c |  3 ++-
 block/replication.c   |  2 +-
 block/stream.c|  2 +-
 qemu-img.c|  2 +-
 8 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/include/block/block.h b/include/block/block.h
index f9415ed740..734c9d2f76 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -449,7 +449,8 @@ int bdrv_block_status_above(BlockDriverState *bs, 
BlockDriverState *base,
 int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes,
   int64_t *pnum);
 int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
-int64_t offset, int64_t bytes, int64_t *pnum);
+bool include_base, int64_t offset, int64_t bytes,
+int64_t *pnum);
 
 bool bdrv_is_read_only(BlockDriverState *bs);
 int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
diff --git a/block/commit.c b/block/commit.c
index 212c6f639e..ca7e408b26 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -174,7 +174,7 @@ static int coroutine_fn commit_run(Job *job, Error **errp)
 break;
 }
 /* Copy if allocated above the base */
-ret = bdrv_is_allocated_above(blk_bs(s->top), blk_bs(s->base),
+ret = bdrv_is_allocated_above(blk_bs(s->top), blk_bs(s->base), false,
   offset, COMMIT_BUFFER_SIZE, &n);
 copy = (ret == 1);
 trace_commit_one_iteration(s, offset, n, ret);
diff --git a/block/io.c b/block/io.c
index 9ba1bada36..24a18759fd 100644
--- a/block/io.c
+++ b/block/io.c
@@ -2295,10 +2295,11 @@ int coroutine_fn bdrv_is_allocated(BlockDriverState 
*bs, int64_t offset,
 /*
  * Given an image chain: ... -> [BASE] -> [INTER1] -> [INTER2] -> [TOP]
  *
- * Return true if (a prefix of) the given range is allocated in any image
- * between BASE and TOP (inclusive).  BASE can be NULL to check if the given
- * offset is allocated in any image of the chain.  Return false otherwise,
- * or negative errno on failure.
+ * Return 1 if (a prefix of) the given range is allocated in any image
+ * between BASE and TOP (BASE is only included if include_base is set).
+ * BASE can be NULL to check if the given offset is allocated in any
+ * image of the chain.  Return 0 otherwise, or negative errno on
+ * failure.
  *
  * 'pnum' is set to the number of bytes (including and immediately
  * following the specified offset) that are known to be in the same
@@ -2310,17 +2311,21 @@ int coroutine_fn bdrv_is_allocated(BlockDriverState 
*bs, int64_t offset,
  */
 int bdrv_is_allocated_above(BlockDriverState *top,
 BlockDriverState *base,
-int64_t offset, int64_t bytes, int64_t *pnum)
+bool include_base, int64_t offset,
+int64_t bytes, int64_t *pnum)
 {
 BlockDriverState *intermediate;
 int ret;
 int64_t n = bytes;
 
+assert(base || !include_base);
+
 intermediate = top;
-while (intermediate && intermediate != base) {
+while (include_base || intermediate != base) {
 int64_t pnum_inter;
 int64_t size_inter;
 
+assert(intermediate);
 ret = bdrv_is_allocated(intermediate, offset, bytes, &pnum_inter);
 if (ret < 0) {
 return ret;
@@ -2339,6 +2344,10 @@ int bdrv_is_allocated_above(BlockDriverState *top,
 n = pnum_inter;
 }
 
+if (intermediate == base) {
+break;
+}
+
 intermediate = backing_bs(intermediate);
 }
 
diff --git a/block/mirror.c b/block/mirror.c
index d17be4cdbc..2fcec70e35 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -808,7 +808,7 @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
 return 0;
 }
 
-ret = bdrv_is_allocated_above(bs, base, offset, bytes, &count);
+ret = bdrv_is_allocated_above(bs, base, false, offset,

[Qemu-devel] [PULL 11/17] net/announce: Add HMP optional ID

2019-07-01 Thread Jason Wang
From: "Dr. David Alan Gilbert" 

Add the optional ID to the HMP command.

e.g.
   # start an announce for a long time on eth1
   migrate_set_parameter announce-rounds 1000
   announce_self "eth1" e1

   # start an announce on eth2
   announce_self "eth2" e2

   # Change e1 to be announcing on eth1 and eth3
   announce_self "eth1,eth3" e1

   # Cancel e1
   migrate_set_parameter announce-rounds 0
   announce_self "" e1

Signed-off-by: Dr. David Alan Gilbert 
Signed-off-by: Jason Wang 
---
 hmp-commands.hx| 7 ---
 monitor/hmp-cmds.c | 3 +++
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index d42c09f..bfa5681 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -955,8 +955,8 @@ ETEXI
 
 {
 .name   = "announce_self",
-.args_type  = "interfaces:s?",
-.params = "[interfaces]",
+.args_type  = "interfaces:s?,id:s?",
+.params = "[interfaces] [id]",
 .help   = "Trigger GARP/RARP announcements",
 .cmd= hmp_announce_self,
 },
@@ -968,7 +968,8 @@ Trigger a round of GARP/RARP broadcasts; this is useful for 
explicitly updating
 network infrastructure after a reconfiguration or some forms of migration.
 The timings of the round are set by the migration announce parameters.
 An optional comma separated @var{interfaces} list restricts the announce to the
-named set of interfaces.
+named set of interfaces. An optional @var{id} can be used to start a separate 
announce
+timer and to change the parameters of it later.
 ETEXI
 
 {
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 0fce179..9de3538 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -1660,12 +1660,15 @@ void hmp_info_snapshots(Monitor *mon, const QDict 
*qdict)
 void hmp_announce_self(Monitor *mon, const QDict *qdict)
 {
 const char *interfaces_str = qdict_get_try_str(qdict, "interfaces");
+const char *id = qdict_get_try_str(qdict, "id");
 AnnounceParameters *params = QAPI_CLONE(AnnounceParameters,
 migrate_announce_params());
 
 qapi_free_strList(params->interfaces);
 params->interfaces = strList_from_comma_list(interfaces_str);
 params->has_interfaces = params->interfaces != NULL;
+params->id = g_strdup(id);
+params->has_id = !!params->id;
 qmp_announce_self(params, NULL);
 qapi_free_AnnounceParameters(params);
 }
-- 
2.5.0




[Qemu-devel] [PULL 03/17] ftgmac100: do not link to netdev

2019-07-01 Thread Jason Wang
From: Cédric Le Goater 

qdev_set_nic_properties() is already used in the Aspeed SoC level to
bind the ftgmac100 device to the netdev.

This is fixing support for multiple net devices.

Signed-off-by: Cédric Le Goater 
Signed-off-by: Jason Wang 
---
 hw/net/ftgmac100.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
index eb76047..d2cded5 100644
--- a/hw/net/ftgmac100.c
+++ b/hw/net/ftgmac100.c
@@ -1017,8 +1017,6 @@ static void ftgmac100_realize(DeviceState *dev, Error 
**errp)
 sysbus_init_irq(sbd, &s->irq);
 qemu_macaddr_default_if_unset(&s->conf.macaddr);
 
-s->conf.peers.ncs[0] = nd_table[0].netdev;
-
 s->nic = qemu_new_nic(&net_ftgmac100_info, &s->conf,
   object_get_typename(OBJECT(dev)), DEVICE(dev)->id,
   s);
-- 
2.5.0




[Qemu-devel] [PULL 10/17] net/announce: Add optional ID

2019-07-01 Thread Jason Wang
From: "Dr. David Alan Gilbert" 

Previously there was a single instance of the timer used by
monitor triggered announces, that's OK, but when combined with the
previous change that lets you have announces for subsets of interfaces
it's a bit restrictive if you want to do different things to different
interfaces.

Add an 'id' field to the announce, and maintain a list of the
timers based on id.

This allows you to for example:
a) Start an announce going on interface eth0 for a long time
b) Start an announce going on interface eth1 for a long time
c) Kill the announce on eth0 while leaving eth1 going.

Signed-off-by: Dr. David Alan Gilbert 
Signed-off-by: Jason Wang 
---
 hw/net/virtio-net.c|  4 ++--
 include/net/announce.h |  8 ++--
 net/announce.c | 52 +++---
 net/trace-events   |  3 ++-
 qapi/net.json  |  9 +++--
 5 files changed, 62 insertions(+), 14 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index c3f5fcc..b9e1cd7 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -2360,7 +2360,7 @@ static int virtio_net_post_load_device(void *opaque, int 
version_id)
 timer_mod(n->announce_timer.tm,
   qemu_clock_get_ms(n->announce_timer.type));
 } else {
-qemu_announce_timer_del(&n->announce_timer);
+qemu_announce_timer_del(&n->announce_timer, false);
 }
 }
 
@@ -2784,7 +2784,7 @@ static void virtio_net_device_unrealize(DeviceState *dev, 
Error **errp)
 virtio_net_del_queue(n, i);
 }
 
-qemu_announce_timer_del(&n->announce_timer);
+qemu_announce_timer_del(&n->announce_timer, false);
 g_free(n->vqs);
 qemu_del_nic(n->nic);
 virtio_net_rsc_cleanup(n);
diff --git a/include/net/announce.h b/include/net/announce.h
index 7734704..3d90c83 100644
--- a/include/net/announce.h
+++ b/include/net/announce.h
@@ -22,8 +22,12 @@ struct AnnounceTimer {
 /* Returns: update the timer to the next time point */
 int64_t qemu_announce_timer_step(AnnounceTimer *timer);
 
-/* Delete the underlying timer and other data */
-void qemu_announce_timer_del(AnnounceTimer *timer);
+/*
+ * Delete the underlying timer and other data
+ * If 'free_named' true and the timer is a named timer, then remove
+ * it from the list of named timers and free the AnnounceTimer itself.
+ */
+void qemu_announce_timer_del(AnnounceTimer *timer, bool free_named);
 
 /*
  * Under BQL/main thread
diff --git a/net/announce.c b/net/announce.c
index 1ce42b5..db90d3b 100644
--- a/net/announce.c
+++ b/net/announce.c
@@ -15,6 +15,8 @@
 #include "qapi/qapi-commands-net.h"
 #include "trace.h"
 
+static GData *named_timers;
+
 int64_t qemu_announce_timer_step(AnnounceTimer *timer)
 {
 int64_t step;
@@ -31,8 +33,13 @@ int64_t qemu_announce_timer_step(AnnounceTimer *timer)
 return step;
 }
 
-void qemu_announce_timer_del(AnnounceTimer *timer)
+/*
+ * If 'free_named' is true, then remove the timer from the list
+ * and free the timer itself.
+ */
+void qemu_announce_timer_del(AnnounceTimer *timer, bool free_named)
 {
+bool free_timer = false;
 if (timer->tm) {
 timer_del(timer->tm);
 timer_free(timer->tm);
@@ -40,6 +47,24 @@ void qemu_announce_timer_del(AnnounceTimer *timer)
 }
 qapi_free_strList(timer->params.interfaces);
 timer->params.interfaces = NULL;
+if (free_named && timer->params.has_id) {
+AnnounceTimer *list_timer;
+/*
+ * Sanity check: There should only be one timer on the list with
+ * the id.
+ */
+list_timer = g_datalist_get_data(&named_timers, timer->params.id);
+assert(timer == list_timer);
+free_timer = true;
+g_datalist_remove_data(&named_timers, timer->params.id);
+}
+trace_qemu_announce_timer_del(free_named, free_timer, timer->params.id);
+g_free(timer->params.id);
+timer->params.id = NULL;
+
+if (free_timer) {
+g_free(timer);
+}
 }
 
 /*
@@ -56,7 +81,7 @@ void qemu_announce_timer_reset(AnnounceTimer *timer,
  * We're under the BQL, so the current timer can't
  * be firing, so we should be able to delete it.
  */
-qemu_announce_timer_del(timer);
+qemu_announce_timer_del(timer, false);
 
 QAPI_CLONE_MEMBERS(AnnounceParameters, &timer->params, params);
 timer->round = params->rounds;
@@ -120,7 +145,8 @@ static void qemu_announce_self_iter(NICState *nic, void 
*opaque)
 skip = false;
 }
 
-trace_qemu_announce_self_iter(nic->ncs->name,
+trace_qemu_announce_self_iter(timer->params.has_id ? timer->params.id : 
"_",
+  nic->ncs->name,
   qemu_ether_ntoa(&nic->conf->macaddr), skip);
 
 if (!skip) {
@@ -143,7 +169,7 @@ static void qemu_announce_self_once(void *opaque)
 if (--timer->round) {
 qemu_announce_timer_step(timer);
 } else {
-qemu_announce_timer_d

[Qemu-devel] [PULL 05/17] net: avoid using variable length array in net_client_init()

2019-07-01 Thread Jason Wang
From: Stefano Garzarella 

net_client_init() uses a variable length array to store the prefix
of 'ipv6-net' parameter (e.g. if ipv6-net=fec0::0/64, the prefix
is 'fec0::0').
This patch introduces g_strsplit() to split the 'ipv6-net' parameter,
so we can remove the variable length array.

Suggested-by: Markus Armbruster 
Signed-off-by: Stefano Garzarella 
Reviewed-by: Markus Armbruster 
Signed-off-by: Jason Wang 
---
 net/net.c | 31 +++
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/net/net.c b/net/net.c
index d21c2c7..76ba0b7 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1105,6 +1105,7 @@ static void show_netdevs(void)
 
 static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
 {
+gchar **substrings = NULL;
 void *object = NULL;
 Error *err = NULL;
 int ret = -1;
@@ -1120,28 +1121,33 @@ static int net_client_init(QemuOpts *opts, bool 
is_netdev, Error **errp)
 const char *ip6_net = qemu_opt_get(opts, "ipv6-net");
 
 if (ip6_net) {
-char buf[strlen(ip6_net) + 1];
+char *prefix_addr;
+unsigned long prefix_len = 64; /* Default 64bit prefix length. */
+
+substrings = g_strsplit(ip6_net, "/", 2);
+if (!substrings || !substrings[0]) {
+error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "ipv6-net",
+   "a valid IPv6 prefix");
+goto out;
+}
 
-if (get_str_sep(buf, sizeof(buf), &ip6_net, '/') < 0) {
-/* Default 64bit prefix length.  */
-qemu_opt_set(opts, "ipv6-prefix", ip6_net, &error_abort);
-qemu_opt_set_number(opts, "ipv6-prefixlen", 64, &error_abort);
-} else {
+prefix_addr = substrings[0];
+
+if (substrings[1]) {
 /* User-specified prefix length.  */
-unsigned long len;
 int err;
 
-qemu_opt_set(opts, "ipv6-prefix", buf, &error_abort);
-err = qemu_strtoul(ip6_net, NULL, 10, &len);
-
+err = qemu_strtoul(substrings[1], NULL, 10, &prefix_len);
 if (err) {
 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
"ipv6-prefixlen", "a number");
 goto out;
 }
-
-qemu_opt_set_number(opts, "ipv6-prefixlen", len, &error_abort);
 }
+
+qemu_opt_set(opts, "ipv6-prefix", prefix_addr, &error_abort);
+qemu_opt_set_number(opts, "ipv6-prefixlen", prefix_len,
+&error_abort);
 qemu_opt_unset(opts, "ipv6-net");
 }
 }
@@ -1164,6 +1170,7 @@ static int net_client_init(QemuOpts *opts, bool 
is_netdev, Error **errp)
 
 out:
 error_propagate(errp, err);
+g_strfreev(substrings);
 visit_free(v);
 return ret;
 }
-- 
2.5.0




[Qemu-devel] [PULL 00/17] Net patches

2019-07-01 Thread Jason Wang
The following changes since commit 7d0e02405fc02a181319b1ab8681d2f72246b7c6:

  Merge remote-tracking branch 
'remotes/vivier2/tags/trivial-patches-pull-request' into staging (2019-07-01 
17:40:32 +0100)

are available in the git repository at:

  https://github.com/jasowang/qemu.git tags/net-pull-request

for you to fetch changes up to 0e8818f023616677416840d6ddc880db8de3c967:

  migration/colo.c: Add missed filter notify for Xen COLO. (2019-07-02 10:21:07 
+0800)




Cédric Le Goater (1):
  ftgmac100: do not link to netdev

Dr. David Alan Gilbert (5):
  net/announce: Allow optional list of interfaces
  net/announce: Add HMP optional interface list
  net/announce: Add optional ID
  net/announce: Add HMP optional ID
  net/announce: Expand test for stopping self announce

Markus Armbruster (2):
  MAINTAINERS: Add qemu-bridge-helper.c to "Network device backends"
  qemu-bridge-helper: Document known shortcomings

Stefano Garzarella (4):
  net: fix assertion failure when ipv6-prefixlen is not a number
  net: avoid using variable length array in net_client_init()
  net: use g_strsplit() for parsing host address and port
  net: remove unused get_str_sep() function

Zhang Chen (5):
  COLO-compare: Add new parameter to communicate with remote colo-frame
  COLO-compare: Add remote notification chardev handler frame
  COLO-compare: Make the compare_chr_send() can send notification message.
  COLO-compare: Add colo-compare remote notify support
  migration/colo.c: Add missed filter notify for Xen COLO.

 MAINTAINERS |   1 +
 hmp-commands.hx |   7 ++-
 hw/net/ftgmac100.c  |   2 -
 hw/net/virtio-net.c |   4 +-
 include/net/announce.h  |   8 ++-
 migration/colo.c|   2 +
 monitor/hmp-cmds.c  |  41 -
 net/announce.c  |  89 +++
 net/colo-compare.c  | 155 ++--
 net/net.c   |  99 +++
 net/trace-events|   3 +-
 qapi/net.json   |  16 -
 qemu-bridge-helper.c|  12 +++-
 qemu-options.hx |  33 ++-
 tests/virtio-net-test.c |  57 +-
 15 files changed, 430 insertions(+), 99 deletions(-)




[Qemu-devel] [PULL 02/17] qemu-bridge-helper: Document known shortcomings

2019-07-01 Thread Jason Wang
From: Markus Armbruster 

Signed-off-by: Markus Armbruster 
Signed-off-by: Jason Wang 
---
 qemu-bridge-helper.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/qemu-bridge-helper.c b/qemu-bridge-helper.c
index f9940de..95624bc 100644
--- a/qemu-bridge-helper.c
+++ b/qemu-bridge-helper.c
@@ -10,7 +10,17 @@
  *
  * This work is licensed under the terms of the GNU GPL, version 2.  See
  * the COPYING file in the top-level directory.
- *
+ */
+
+/*
+ * Known shortcomings:
+ * - There is no manual page
+ * - The syntax of the ACL file is not documented anywhere
+ * - parse_acl_file() doesn't report fopen() failure properly, fails
+ *   to check ferror() after fgets() failure, arbitrarily truncates
+ *   long lines, handles whitespace inconsistently, error messages
+ *   don't point to the offending file and line, errors in included
+ *   files are reported, but otherwise ignored, ...
  */
 
 #include "qemu/osdep.h"
-- 
2.5.0




[Qemu-devel] [PULL 3/4] block/stream: refactor stream_run: drop goto

2019-07-01 Thread Max Reitz
From: Andrey Shinkevich 

The goto is unnecessary in the stream_run() since the common exit
code was removed in the commit eb23654dbe43b549ea2a9ebff9d8e:
"jobs: utilize job_exit shim".

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: Andrey Shinkevich 
Reviewed-by: Alberto Garcia 
Reviewed-by: Max Reitz 
Message-id: 1559152576-281803-3-git-send-email-andrey.shinkev...@virtuozzo.com
Reviewed-by: Max Reitz 
Signed-off-by: Max Reitz 
---
 block/stream.c | 13 -
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/block/stream.c b/block/stream.c
index 97fddb2608..65b13b27e0 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -120,13 +120,12 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
 void *buf;
 
 if (!bs->backing) {
-goto out;
+return 0;
 }
 
 len = bdrv_getlength(bs);
 if (len < 0) {
-ret = len;
-goto out;
+return len;
 }
 job_progress_set_remaining(&s->common.job, len);
 
@@ -203,14 +202,10 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
 bdrv_disable_copy_on_read(bs);
 }
 
-/* Do not remove the backing file if an error was there but ignored.  */
-ret = error;
-
 qemu_vfree(buf);
 
-out:
-/* Modify backing chain and close BDSes in main loop */
-return ret;
+/* Do not remove the backing file if an error was there but ignored. */
+return error;
 }
 
 static const BlockJobDriver stream_job_driver = {
-- 
2.21.0




[Qemu-devel] [PULL 01/17] MAINTAINERS: Add qemu-bridge-helper.c to "Network device backends"

2019-07-01 Thread Jason Wang
From: Markus Armbruster 

Signed-off-by: Markus Armbruster 
Signed-off-by: Jason Wang 
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 8206fc5..c7b0c2c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1934,6 +1934,7 @@ M: Jason Wang 
 S: Maintained
 F: net/
 F: include/net/
+F: qemu-bridge-helper.c
 T: git https://github.com/jasowang/qemu.git net
 F: qapi/net.json
 
-- 
2.5.0




Re: [Qemu-devel] [PATCH v5 6/8] hmat acpi: Build Memory Subsystem Address Range Structure(s) in ACPI HMAT

2019-07-01 Thread Tao Xu

On 7/1/2019 7:25 PM, Igor Mammedov wrote:

On Fri, 14 Jun 2019 23:56:24 +0800
Tao Xu  wrote:


From: Liu Jingqi 

HMAT is defined in ACPI 6.2: 5.2.27 Heterogeneous Memory Attribute Table (HMAT).
The specification references below link:
http://www.uefi.org/sites/default/files/resources/ACPI_6_2.pdf

It describes the memory attributes, such as memory side cache
attributes and bandwidth and latency details, related to the
System Physical Address (SPA) Memory Ranges. The software is
expected to use this information as hint for optimization.

This structure describes the System Physical Address(SPA) range
occupied by memory subsystem and its associativity with processor
proximity domain as well as hint for memory usage.

Signed-off-by: Liu Jingqi 
Signed-off-by: Tao Xu 
---

Changes in v5 -> v4:
 - Add more descriptions from ACPI spec (Igor)
 - Remove all the dependcy on PCMachineState (Igor)
---
  hw/acpi/Kconfig   |   5 ++
  hw/acpi/Makefile.objs |   1 +
  hw/acpi/hmat.c| 153 ++
  hw/acpi/hmat.h|  43 
  hw/core/machine.c |   2 +
  hw/i386/acpi-build.c  |   3 +
  include/sysemu/numa.h |   2 +
  numa.c|   6 ++
  8 files changed, 215 insertions(+)
  create mode 100644 hw/acpi/hmat.c
  create mode 100644 hw/acpi/hmat.h

diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig
index 7c59cf900b..039bb99efa 100644
--- a/hw/acpi/Kconfig
+++ b/hw/acpi/Kconfig
@@ -7,6 +7,7 @@ config ACPI_X86
  select ACPI_NVDIMM
  select ACPI_CPU_HOTPLUG
  select ACPI_MEMORY_HOTPLUG
+select ACPI_HMAT
  
  config ACPI_X86_ICH

  bool
@@ -31,3 +32,7 @@ config ACPI_VMGENID
  bool
  default y
  depends on PC
+
+config ACPI_HMAT
+bool
+depends on ACPI
diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
index 661a9b8c2f..20cc2fb124 100644
--- a/hw/acpi/Makefile.objs
+++ b/hw/acpi/Makefile.objs
@@ -6,6 +6,7 @@ common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o
  common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu.o
  common-obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
  common-obj-$(CONFIG_ACPI_VMGENID) += vmgenid.o
+common-obj-$(CONFIG_ACPI_HMAT) += hmat.o
  common-obj-$(call lnot,$(CONFIG_ACPI_X86)) += acpi-stub.o
  
  common-obj-y += acpi_interface.o

diff --git a/hw/acpi/hmat.c b/hw/acpi/hmat.c
new file mode 100644
index 00..6fd434c4d9
--- /dev/null
+++ b/hw/acpi/hmat.c
@@ -0,0 +1,153 @@
+/*
+ * HMAT ACPI Implementation
+ *
+ * Copyright(C) 2019 Intel Corporation.
+ *
+ * Author:
+ *  Liu jingqi 
+ *  Tao Xu 
+ *
+ * HMAT is defined in ACPI 6.2: 5.2.27 Heterogeneous Memory Attribute Table
+ * (HMAT)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see 
+ */
+
+#include "qemu/osdep.h"
+#include "sysemu/numa.h"
+#include "hw/acpi/hmat.h"
+#include "hw/mem/pc-dimm.h"
+
+/* ACPI 6.2: 5.2.27.3 Memory Subsystem Address Range Structure: Table 5-141 */
+static void build_hmat_spa(GArray *table_data, uint16_t flags,
+   uint64_t base, uint64_t length, int node)
+{
+
+/* Memory Subsystem Address Range Structure */
+/* Type */
+build_append_int_noprefix(table_data, 0, 2);
+/* Reserved */
+build_append_int_noprefix(table_data, 0, 2);
+/* Length */
+build_append_int_noprefix(table_data, 40, 4);
+/* Flags */
+build_append_int_noprefix(table_data, flags, 2);
+/* Reserved */
+build_append_int_noprefix(table_data, 0, 2);
+/* Process Proximity Domain */
+build_append_int_noprefix(table_data, node, 4);
+/* Memory Proximity Domain */
+build_append_int_noprefix(table_data, node, 4);
+/* Reserved */
+build_append_int_noprefix(table_data, 0, 4);
+/* System Physical Address Range Base */
+build_append_int_noprefix(table_data, base, 8);
+/* System Physical Address Range Length */
+build_append_int_noprefix(table_data, length, 8);
+}
+
+static int pc_dimm_device_list(Object *obj, void *opaque)
+{
+GSList **list = opaque;
+
+if (object_dynamic_cast(obj, TYPE_PC_DIMM)) {
+DeviceState *dev = DEVICE(obj);
+if (dev->realized) { /* only realized memory devices matter */
+*list = g_slist_append(*list, DEVICE(obj));
+}
+}
+
+object_child_foreach(obj, pc_dimm_device_list, opaque);
+return 0;
+}
+
+/* Build HMAT sub table structures */
+static void hmat_build

[Qemu-devel] [PULL 1/4] block/rbd: increase dynamically the image size

2019-07-01 Thread Max Reitz
From: Stefano Garzarella 

RBD APIs don't allow us to write more than the size set with
rbd_create() or rbd_resize().
In order to support growing images (eg. qcow2), we resize the
image before write operations that exceed the current size.

Signed-off-by: Stefano Garzarella 
Message-id: 20190509145927.293369-1-sgarz...@redhat.com
Signed-off-by: Max Reitz 
---
 block/rbd.c | 42 +++---
 1 file changed, 39 insertions(+), 3 deletions(-)

diff --git a/block/rbd.c b/block/rbd.c
index f2ac2c06f4..59757b3120 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -103,6 +103,7 @@ typedef struct BDRVRBDState {
 rbd_image_t image;
 char *image_name;
 char *snap;
+uint64_t image_size;
 } BDRVRBDState;
 
 static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
@@ -778,6 +779,14 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict 
*options, int flags,
 goto failed_open;
 }
 
+r = rbd_get_size(s->image, &s->image_size);
+if (r < 0) {
+error_setg_errno(errp, -r, "error getting image size from %s",
+ s->image_name);
+rbd_close(s->image);
+goto failed_open;
+}
+
 /* If we are using an rbd snapshot, we must be r/o, otherwise
  * leave as-is */
 if (s->snap != NULL) {
@@ -834,6 +843,22 @@ static void qemu_rbd_close(BlockDriverState *bs)
 rados_shutdown(s->cluster);
 }
 
+/* Resize the RBD image and update the 'image_size' with the current size */
+static int qemu_rbd_resize(BlockDriverState *bs, uint64_t size)
+{
+BDRVRBDState *s = bs->opaque;
+int r;
+
+r = rbd_resize(s->image, size);
+if (r < 0) {
+return r;
+}
+
+s->image_size = size;
+
+return 0;
+}
+
 static const AIOCBInfo rbd_aiocb_info = {
 .aiocb_size = sizeof(RBDAIOCB),
 };
@@ -935,13 +960,25 @@ static BlockAIOCB *rbd_start_aio(BlockDriverState *bs,
 }
 
 switch (cmd) {
-case RBD_AIO_WRITE:
+case RBD_AIO_WRITE: {
+/*
+ * RBD APIs don't allow us to write more than actual size, so in order
+ * to support growing images, we resize the image before write
+ * operations that exceed the current size.
+ */
+if (off + size > s->image_size) {
+r = qemu_rbd_resize(bs, off + size);
+if (r < 0) {
+goto failed_completion;
+}
+}
 #ifdef LIBRBD_SUPPORTS_IOVEC
 r = rbd_aio_writev(s->image, qiov->iov, qiov->niov, off, c);
 #else
 r = rbd_aio_write(s->image, off, size, rcb->buf, c);
 #endif
 break;
+}
 case RBD_AIO_READ:
 #ifdef LIBRBD_SUPPORTS_IOVEC
 r = rbd_aio_readv(s->image, qiov->iov, qiov->niov, off, c);
@@ -1052,7 +1089,6 @@ static int coroutine_fn 
qemu_rbd_co_truncate(BlockDriverState *bs,
  PreallocMode prealloc,
  Error **errp)
 {
-BDRVRBDState *s = bs->opaque;
 int r;
 
 if (prealloc != PREALLOC_MODE_OFF) {
@@ -1061,7 +1097,7 @@ static int coroutine_fn 
qemu_rbd_co_truncate(BlockDriverState *bs,
 return -ENOTSUP;
 }
 
-r = rbd_resize(s->image, offset);
+r = qemu_rbd_resize(bs, offset);
 if (r < 0) {
 error_setg_errno(errp, -r, "Failed to resize file");
 return r;
-- 
2.21.0




[Qemu-devel] [PULL 04/17] net: fix assertion failure when ipv6-prefixlen is not a number

2019-07-01 Thread Jason Wang
From: Stefano Garzarella 

If 'ipv6-prefixlen' is not a number, the current behaviour
produces an assertion failure:
$ qemu-system-x86_64 -net user,ipv6-net=feca::0/a
qemu-system-x86_64: qemu/util/qemu-option.c:1175: qemu_opts_foreach:
Assertion `!errp || !*errp' failed.
Aborted (core dumped)

This patch fixes it, jumping to the end of the function when
'ipv6-prefixlen' is not a number, and printing the more friendly
message:
$ qemu-system-x86_64 -net user,ipv6-net=feca::0/a
qemu-system-x86_64: Parameter 'ipv6-prefixlen' expects a number

Signed-off-by: Stefano Garzarella 
Reviewed-by: Markus Armbruster 
Signed-off-by: Jason Wang 
---
 net/net.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/net/net.c b/net/net.c
index 3e65c93..d21c2c7 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1136,11 +1136,11 @@ static int net_client_init(QemuOpts *opts, bool 
is_netdev, Error **errp)
 
 if (err) {
 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
-  "ipv6-prefix", "a number");
-} else {
-qemu_opt_set_number(opts, "ipv6-prefixlen", len,
-&error_abort);
+   "ipv6-prefixlen", "a number");
+goto out;
 }
+
+qemu_opt_set_number(opts, "ipv6-prefixlen", len, &error_abort);
 }
 qemu_opt_unset(opts, "ipv6-net");
 }
@@ -1162,6 +1162,7 @@ static int net_client_init(QemuOpts *opts, bool 
is_netdev, Error **errp)
 qapi_free_NetLegacy(object);
 }
 
+out:
 error_propagate(errp, err);
 visit_free(v);
 return ret;
-- 
2.5.0




Re: [Qemu-devel] [PATCH v5 5/8] acpi: introduce AcpiDeviceIfClass.build_mem_ranges hook

2019-07-01 Thread Tao Xu

On 7/1/2019 6:59 PM, Igor Mammedov wrote:

On Fri, 14 Jun 2019 23:56:23 +0800
Tao Xu  wrote:


Add build_mem_ranges callback to AcpiDeviceIfClass and use
it for generating SRAT and HMAT numa memory ranges.

Suggested-by: Igor Mammedov 
Co-developed-by: Liu Jingqi 
Signed-off-by: Liu Jingqi 
Signed-off-by: Tao Xu 
---

Changes in v5 -> v4:
 - Add the missing if 'mem_len > 0' in pc_build_mem_ranges() (Igor)
 - Correct the descriptions of build_mem_ranges
 in AcpiDeviceIfClass (Igor)
 - Use GArray for NUMA memory ranges data (Igor)
 - Add the reason of using stub (Igor)
---
  hw/acpi/piix4.c  |   1 +
  hw/i386/acpi-build.c | 133 +--
  hw/isa/lpc_ich9.c|   1 +
  include/hw/acpi/acpi_dev_interface.h |   4 +
  include/hw/i386/pc.h |   1 +
  include/sysemu/numa.h|  12 +++
  stubs/Makefile.objs  |   1 +
  stubs/pc_build_mem_ranges.c  |  14 +++
  8 files changed, 120 insertions(+), 47 deletions(-)
  create mode 100644 stubs/pc_build_mem_ranges.c

diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index ec4e186cec..bc078c1ad7 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -702,6 +702,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void 
*data)
  adevc->ospm_status = piix4_ospm_status;
  adevc->send_event = piix4_send_gpe;
  adevc->madt_cpu = pc_madt_cpu_entry;
+adevc->build_mem_ranges = pc_build_mem_ranges;
  }
  
  static const TypeInfo piix4_pm_info = {

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 055e677c30..44dd447fa5 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2279,18 +2279,89 @@ build_tpm2(GArray *table_data, BIOSLinker *linker, 
GArray *tcpalog)
  #define HOLE_640K_START  (640 * KiB)
  #define HOLE_640K_END   (1 * MiB)
  
+void pc_build_mem_ranges(AcpiDeviceIf *adev, MachineState *ms)

+{
+uint64_t mem_len, mem_base, next_base;
+int i;
+PCMachineState *pcms = PC_MACHINE(ms);
+NumaState *nstat = ms->numa_state;
+NumaMemRange *mem_range;
+nstat->mem_ranges_num = 0;
+next_base = 0;
+
+/*
+ * the memory map is a bit tricky, it contains at least one hole
+ * from 640k-1M and possibly another one from 3.5G-4G.
+ */
+
+for (i = 0; i < pcms->numa_nodes; ++i) {
+mem_base = next_base;
+mem_len = pcms->node_mem[i];
+next_base = mem_base + mem_len;
+
+/* Cut out the 640K hole */
+if (mem_base <= HOLE_640K_START &&
+next_base > HOLE_640K_START) {
+mem_len -= next_base - HOLE_640K_START;
+if (mem_len > 0) {
+mem_range = acpi_data_push(nstat->mem_ranges,
+   sizeof *mem_range);
+mem_range->base = mem_base;
+mem_range->length = mem_len;
+mem_range->node = i;
+nstat->mem_ranges_num++;
+}
+
+/* Check for the rare case: 640K < RAM < 1M */
+if (next_base <= HOLE_640K_END) {
+next_base = HOLE_640K_END;
+continue;
+}
+mem_base = HOLE_640K_END;
+mem_len = next_base - HOLE_640K_END;
+}
+
+/* Cut out the ACPI_PCI hole */
+if (mem_base <= pcms->below_4g_mem_size &&
+next_base > pcms->below_4g_mem_size) {
+mem_len -= next_base - pcms->below_4g_mem_size;
+if (mem_len > 0) {
+mem_range = acpi_data_push(nstat->mem_ranges,
+   sizeof *mem_range);
+mem_range->base = mem_base;
+mem_range->length = mem_len;
+mem_range->node = i;
+nstat->mem_ranges_num++;
+}
+mem_base = 1ULL << 32;
+mem_len = next_base - pcms->below_4g_mem_size;
+next_base = mem_base + mem_len;
+}
+if (mem_len > 0) {
+mem_range = acpi_data_push(nstat->mem_ranges,
+   sizeof *mem_range);
+mem_range->base = mem_base;
+mem_range->length = mem_len;
+mem_range->node = i;
+nstat->mem_ranges_num++;
+}
+}
+}
+
  static void
  build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
  {
  AcpiSystemResourceAffinityTable *srat;
  AcpiSratMemoryAffinity *numamem;
  
-int i;

-int srat_start, numa_start, slots;
-uint64_t mem_len, mem_base, next_base;
+int i, srat_start, numa_start, slots;
  MachineClass *mc = MACHINE_GET_CLASS(machine);
  const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine);
  PCMachineState *pcms = PC_MACHINE(machine);
+AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(pcms->acpi_dev);
+AcpiDeviceIf *adev = ACPI_DEVICE_IF(pcms->acpi_dev);
+NumaState *nstat = machine->numa_state;
+

Re: [Qemu-devel] [PATCH v2] target/riscv: Hardwire mcounter.TM and upper bits of [m|s]counteren

2019-07-01 Thread Bin Meng
On Tue, Jul 2, 2019 at 8:20 AM Alistair Francis  wrote:
>
> On Mon, Jul 1, 2019 at 8:56 AM  wrote:
> >
> > From: Jonathan Behrens 
> >
> > QEMU currently always triggers an illegal instruction exception when
> > code attempts to read the time CSR. This is valid behavor, but only if
> > the TM bit in mcounteren is hardwired to zero. This change also
> > corrects mcounteren and scounteren CSRs to be 32-bits on both 32-bit
> > and 64-bit targets.
> >
> > Signed-off-by: Jonathan Behrens 
>
> Reviewed-by: Alistair Francis 
>

I am a little bit lost here. I think we agreed to allow directly read
to time CSR when mcounteren.TM is set, no?

Regards,
Bin



[Qemu-devel] [PULL 15/17] COLO-compare: Make the compare_chr_send() can send notification message.

2019-07-01 Thread Jason Wang
From: Zhang Chen 

We need use this function to send notification message for remote 
colo-frame(Xen).
So we add new parameter for this job.

Signed-off-by: Zhang Chen 
Signed-off-by: Jason Wang 
---
 net/colo-compare.c | 41 +
 1 file changed, 33 insertions(+), 8 deletions(-)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index fda55d5..ee03c25 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -129,7 +129,8 @@ static void colo_compare_inconsistency_notify(void)
 static int compare_chr_send(CompareState *s,
 const uint8_t *buf,
 uint32_t size,
-uint32_t vnet_hdr_len);
+uint32_t vnet_hdr_len,
+bool notify_remote_frame);
 
 static gint seq_sorter(Packet *a, Packet *b, gpointer data)
 {
@@ -241,7 +242,8 @@ static void colo_release_primary_pkt(CompareState *s, 
Packet *pkt)
 ret = compare_chr_send(s,
pkt->data,
pkt->size,
-   pkt->vnet_hdr_len);
+   pkt->vnet_hdr_len,
+   false);
 if (ret < 0) {
 error_report("colo send primary packet failed");
 }
@@ -671,7 +673,8 @@ static void colo_compare_connection(void *opaque, void 
*user_data)
 static int compare_chr_send(CompareState *s,
 const uint8_t *buf,
 uint32_t size,
-uint32_t vnet_hdr_len)
+uint32_t vnet_hdr_len,
+bool notify_remote_frame)
 {
 int ret = 0;
 uint32_t len = htonl(size);
@@ -680,7 +683,14 @@ static int compare_chr_send(CompareState *s,
 return 0;
 }
 
-ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
+if (notify_remote_frame) {
+ret = qemu_chr_fe_write_all(&s->chr_notify_dev,
+(uint8_t *)&len,
+sizeof(len));
+} else {
+ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
+}
+
 if (ret != sizeof(len)) {
 goto err;
 }
@@ -691,13 +701,26 @@ static int compare_chr_send(CompareState *s,
  * know how to parse net packet correctly.
  */
 len = htonl(vnet_hdr_len);
-ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
+
+if (!notify_remote_frame) {
+ret = qemu_chr_fe_write_all(&s->chr_out,
+(uint8_t *)&len,
+sizeof(len));
+}
+
 if (ret != sizeof(len)) {
 goto err;
 }
 }
 
-ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
+if (notify_remote_frame) {
+ret = qemu_chr_fe_write_all(&s->chr_notify_dev,
+(uint8_t *)buf,
+size);
+} else {
+ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
+}
+
 if (ret != size) {
 goto err;
 }
@@ -943,7 +966,8 @@ static void compare_pri_rs_finalize(SocketReadState *pri_rs)
 compare_chr_send(s,
  pri_rs->buf,
  pri_rs->packet_len,
- pri_rs->vnet_hdr_len);
+ pri_rs->vnet_hdr_len,
+ false);
 } else {
 /* compare packet in the specified connection */
 colo_compare_connection(conn, s);
@@ -1075,7 +1099,8 @@ static void colo_flush_packets(void *opaque, void 
*user_data)
 compare_chr_send(s,
  pkt->data,
  pkt->size,
- pkt->vnet_hdr_len);
+ pkt->vnet_hdr_len,
+ false);
 packet_destroy(pkt, NULL);
 }
 while (!g_queue_is_empty(&conn->secondary_list)) {
-- 
2.5.0




[Qemu-devel] [PULL 12/27] hw/block/pflash_cfi02: Fix command address comparison

2019-07-01 Thread Philippe Mathieu-Daudé
From: Stephen Checkoway 

Most AMD commands only examine 11 bits of the address. This masks the
addresses used in the comparison to 11 bits. The exceptions are word or
sector addresses which use offset directly rather than the shifted
offset, boff.

Signed-off-by: Stephen Checkoway 
Message-Id: <20190426162624.55977-4-stephen.checko...@oberlin.edu>
Acked-by: Thomas Huth 
Acked-by: Alistair Francis 
Acked-by: Philippe Mathieu-Daudé 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/block/pflash_cfi02.c   |  8 +++-
 tests/pflash-cfi02-test.c | 12 ++--
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index e64dc69c6c..4be3837be5 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -281,11 +281,13 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 }
 offset &= pfl->chip_len - 1;
 
-boff = offset & (pfl->sector_len - 1);
+boff = offset;
 if (pfl->width == 2)
 boff = boff >> 1;
 else if (pfl->width == 4)
 boff = boff >> 2;
+/* Only the least-significant 11 bits are used in most cases. */
+boff &= 0x7FF;
 switch (pfl->wcycle) {
 case 0:
 /* Set the device in I/O access mode if required */
@@ -538,6 +540,10 @@ static void pflash_cfi02_realize(DeviceState *dev, Error 
**errp)
 }
 }
 
+/* Only 11 bits are used in the comparison. */
+pfl->unlock_addr0 &= 0x7FF;
+pfl->unlock_addr1 &= 0x7FF;
+
 pflash_setup_mappings(pfl);
 pfl->rom_mode = 1;
 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->mem);
diff --git a/tests/pflash-cfi02-test.c b/tests/pflash-cfi02-test.c
index e7e16a8dd8..e090b2e3a0 100644
--- a/tests/pflash-cfi02-test.c
+++ b/tests/pflash-cfi02-test.c
@@ -21,8 +21,8 @@
 
 #define FLASH_WIDTH 2
 #define CFI_ADDR (FLASH_WIDTH * 0x55)
-#define UNLOCK0_ADDR (FLASH_WIDTH * 0x)
-#define UNLOCK1_ADDR (FLASH_WIDTH * 0x2AAA)
+#define UNLOCK0_ADDR (FLASH_WIDTH * 0x555)
+#define UNLOCK1_ADDR (FLASH_WIDTH * 0x2AA)
 
 #define CFI_CMD 0x98
 #define UNLOCK0_CMD 0xAA
@@ -190,6 +190,14 @@ static void test_flash(void)
 g_assert_cmphex(flash_read(6), ==, 0xCDEF);
 g_assert_cmphex(flash_read(8), ==, 0x);
 
+/* Test ignored high order bits of address. */
+flash_write(FLASH_WIDTH * 0x, UNLOCK0_CMD);
+flash_write(FLASH_WIDTH * 0x2AAA, UNLOCK1_CMD);
+flash_write(FLASH_WIDTH * 0x, AUTOSELECT_CMD);
+g_assert_cmpint(flash_read(FLASH_WIDTH * 0x), ==, 0x00BF);
+g_assert_cmpint(flash_read(FLASH_WIDTH * 0x0001), ==, 0x236D);
+reset();
+
 qtest_quit(global_qtest);
 }
 
-- 
2.20.1




[Qemu-devel] [PULL 08/17] net/announce: Allow optional list of interfaces

2019-07-01 Thread Jason Wang
From: "Dr. David Alan Gilbert" 

Allow the caller to restrict the set of interfaces that announces are
sent on.  The default is still to send on all interfaces.

e.g.

  { "execute": "announce-self", "arguments": { "initial": 50, "max": 550, 
"rounds": 5, "step": 50, "interfaces": ["vn2", "vn1"] } }

This doesn't affect the behaviour of migraiton announcments.

Note: There's still only one timer for the qmp command, so that
performing an 'announce-self' on one list of interfaces followed
by another 'announce-self' on another list will stop the announces
on the existing set.

Signed-off-by: Dr. David Alan Gilbert 
Signed-off-by: Jason Wang 
---
 include/net/announce.h |  2 +-
 net/announce.c | 39 ---
 net/trace-events   |  2 +-
 qapi/net.json  | 11 ---
 4 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/include/net/announce.h b/include/net/announce.h
index 04a035f..7734704 100644
--- a/include/net/announce.h
+++ b/include/net/announce.h
@@ -22,7 +22,7 @@ struct AnnounceTimer {
 /* Returns: update the timer to the next time point */
 int64_t qemu_announce_timer_step(AnnounceTimer *timer);
 
-/* Delete the underlying timer */
+/* Delete the underlying timer and other data */
 void qemu_announce_timer_del(AnnounceTimer *timer);
 
 /*
diff --git a/net/announce.c b/net/announce.c
index 91e9a6e..1ce42b5 100644
--- a/net/announce.c
+++ b/net/announce.c
@@ -38,6 +38,8 @@ void qemu_announce_timer_del(AnnounceTimer *timer)
 timer_free(timer->tm);
 timer->tm = NULL;
 }
+qapi_free_strList(timer->params.interfaces);
+timer->params.interfaces = NULL;
 }
 
 /*
@@ -96,24 +98,47 @@ static int announce_self_create(uint8_t *buf,
 
 static void qemu_announce_self_iter(NICState *nic, void *opaque)
 {
+AnnounceTimer *timer = opaque;
 uint8_t buf[60];
 int len;
+bool skip;
+
+if (timer->params.has_interfaces) {
+strList *entry = timer->params.interfaces;
+/* Skip unless we find our name in the requested list */
+skip = true;
+
+while (entry) {
+if (!strcmp(entry->value, nic->ncs->name)) {
+/* Found us */
+skip = false;
+break;
+}
+entry = entry->next;
+}
+} else {
+skip = false;
+}
+
+trace_qemu_announce_self_iter(nic->ncs->name,
+  qemu_ether_ntoa(&nic->conf->macaddr), skip);
 
-trace_qemu_announce_self_iter(qemu_ether_ntoa(&nic->conf->macaddr));
-len = announce_self_create(buf, nic->conf->macaddr.a);
+if (!skip) {
+len = announce_self_create(buf, nic->conf->macaddr.a);
 
-qemu_send_packet_raw(qemu_get_queue(nic), buf, len);
+qemu_send_packet_raw(qemu_get_queue(nic), buf, len);
 
-/* if the NIC provides it's own announcement support, use it as well */
-if (nic->ncs->info->announce) {
-nic->ncs->info->announce(nic->ncs);
+/* if the NIC provides it's own announcement support, use it as well */
+if (nic->ncs->info->announce) {
+nic->ncs->info->announce(nic->ncs);
+}
 }
 }
 static void qemu_announce_self_once(void *opaque)
 {
 AnnounceTimer *timer = (AnnounceTimer *)opaque;
 
-qemu_foreach_nic(qemu_announce_self_iter, NULL);
+qemu_foreach_nic(qemu_announce_self_iter, timer);
 
 if (--timer->round) {
 qemu_announce_timer_step(timer);
diff --git a/net/trace-events b/net/trace-events
index a7937f3..875ef2a 100644
--- a/net/trace-events
+++ b/net/trace-events
@@ -1,7 +1,7 @@
 # See docs/devel/tracing.txt for syntax documentation.
 
 # announce.c
-qemu_announce_self_iter(const char *mac) "%s"
+qemu_announce_self_iter(const char *name, const char *mac, int skip) "%s:%s 
skip: %d"
 
 # vhost-user.c
 vhost_user_event(const char *chr, int event) "chr: %s got event: %d"
diff --git a/qapi/net.json b/qapi/net.json
index 5f7bff1..6f2cd4f 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -699,6 +699,9 @@
 #
 # @step: Delay increase (in ms) after each self-announcement attempt
 #
+# @interfaces: An optional list of interface names, which restricts the
+#announcement to the listed interfaces. (Since 4.1)
+#
 # Since: 4.0
 ##
 
@@ -706,7 +709,8 @@
   'data': { 'initial': 'int',
 'max': 'int',
 'rounds': 'int',
-'step': 'int' } }
+'step': 'int',
+'*interfaces': ['str'] } }
 
 ##
 # @announce-self:
@@ -718,9 +722,10 @@
 #
 # Example:
 #
-# -> { "execute": "announce-self"
+# -> { "execute": "announce-self",
 #  "arguments": {
-#  "initial": 50, "max": 550, "rounds": 10, "step": 50 } }
+#  "initial": 50, "max": 550, "rounds": 10, "step": 50,
+#  "interfaces": ["vn2", "vn3"] } }
 # <- { "return": {} }
 #
 # Since: 4.0
-- 
2.5.0




[Qemu-devel] [PULL 26/27] hw/block/pflash_cfi02: Document commands

2019-07-01 Thread Philippe Mathieu-Daudé
Reviewed-by: Alistair Francis 
Message-Id: <20190627202719.17739-28-phi...@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/block/pflash_cfi02.c | 40 +++-
 1 file changed, 19 insertions(+), 21 deletions(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index b2d37c33bb..83084b9d72 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -327,7 +327,7 @@ static uint64_t pflash_read(void *opaque, hwaddr offset, 
unsigned int width)
 pfl->wcycle = 0;
 pfl->cmd = 0;
 /* fall through to the read code */
-case 0x80:
+case 0x80: /* Erase (unlock) */
 /* We accept reads during second unlock sequence... */
 case 0x00:
 if (pflash_erase_suspend_mode(pfl) &&
@@ -342,8 +342,7 @@ static uint64_t pflash_read(void *opaque, hwaddr offset, 
unsigned int width)
 /* Flash area read */
 ret = pflash_data_read(pfl, offset, width);
 break;
-case 0x90:
-/* flash ID read */
+case 0x90: /* flash ID read */
 switch (boff) {
 case 0x00:
 case 0x01:
@@ -364,11 +363,11 @@ static uint64_t pflash_read(void *opaque, hwaddr offset, 
unsigned int width)
 }
 DPRINTF("%s: ID " TARGET_FMT_plx " %" PRIx64 "\n", __func__, boff, 
ret);
 break;
-case 0x10:
-case 0x30:
+case 0x10: /* Chip Erase */
+case 0x30: /* Sector Erase */
 /* Toggle bit 2 during erase, but not program. */
 toggle_dq2(pfl);
-case 0xA0:
+case 0xA0: /* Program */
 /* Toggle bit 6 */
 toggle_dq6(pfl);
 /* Status register read */
@@ -470,7 +469,7 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 return;
 }
 /* Handle erase resume in erase suspend mode, otherwise reset. */
-if (cmd == 0x30) {
+if (cmd == 0x30) { /* Erase Resume */
 if (pflash_erase_suspend_mode(pfl)) {
 /* Resume the erase. */
 timer_mod(&pfl->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
@@ -485,7 +484,7 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 goto reset_flash;
 }
 /* Ignore erase suspend. */
-if (cmd == 0xB0) {
+if (cmd == 0xB0) { /* Erase Suspend */
 return;
 }
 if (boff != pfl->unlock_addr0 || cmd != 0xAA) {
@@ -516,9 +515,9 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 case 0x20:
 pfl->bypass = 1;
 goto do_bypass;
-case 0x80:
-case 0x90:
-case 0xA0:
+case 0x80: /* Erase */
+case 0x90: /* Autoselect */
+case 0xA0: /* Program */
 pfl->cmd = cmd;
 DPRINTF("%s: starting command %02x\n", __func__, cmd);
 break;
@@ -529,10 +528,10 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 break;
 case 3:
 switch (pfl->cmd) {
-case 0x80:
+case 0x80: /* Erase */
 /* We need another unlock sequence */
 goto check_unlock0;
-case 0xA0:
+case 0xA0: /* Program */
 if (pflash_erase_suspend_mode(pfl) &&
 pflash_sector_is_erasing(pfl, offset)) {
 /* Ignore writes to erasing sectors. */
@@ -562,7 +561,7 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 if (pfl->bypass)
 goto do_bypass;
 goto reset_flash;
-case 0x90:
+case 0x90: /* Autoselect */
 if (pfl->bypass && cmd == 0x00) {
 /* Unlock bypass reset */
 goto reset_flash;
@@ -585,11 +584,11 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 }
 case 4:
 switch (pfl->cmd) {
-case 0xA0:
+case 0xA0: /* Program */
 /* Ignore writes while flash data write is occurring */
 /* As we suppose write is immediate, this should never happen */
 return;
-case 0x80:
+case 0x80: /* Erase */
 goto check_unlock1;
 default:
 /* Should never happen */
@@ -604,7 +603,7 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 goto reset_flash;
 }
 switch (cmd) {
-case 0x10:
+case 0x10: /* Chip Erase */
 if (boff != pfl->unlock_addr0) {
 DPRINTF("%s: chip erase: invalid address " TARGET_FMT_plx "\n",
 __func__, offset);
@@ -621,8 +620,7 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 timer_mod(&pfl->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
   (1ULL << pfl->cfi_table[0x22]) * SCALE_MS);
 break;
-case 0x30:
-/* Sector erase */
+case 0x30: /* Sector erase

[Qemu-devel] [PULL 13/27] tests/pflash-cfi02: Refactor to support testing multiple configurations

2019-07-01 Thread Philippe Mathieu-Daudé
Introduce the FlashConfig structure, to be able to run the same set
of tests on different flash models/configurations.

Signed-off-by: Stephen Checkoway 
Message-Id: <20190426162624.55977-6-stephen.checko...@oberlin.edu>
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
[PMD: Extracted from bigger patch]
Reviewed-by: Alistair Francis 
Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/pflash-cfi02-test.c | 386 +++---
 1 file changed, 277 insertions(+), 109 deletions(-)

diff --git a/tests/pflash-cfi02-test.c b/tests/pflash-cfi02-test.c
index e090b2e3a0..b00f5ca2e7 100644
--- a/tests/pflash-cfi02-test.c
+++ b/tests/pflash-cfi02-test.c
@@ -17,12 +17,18 @@
  */
 
 #define MP_FLASH_SIZE_MAX (32 * 1024 * 1024)
+#define FLASH_SIZE (8 * 1024 * 1024)
 #define BASE_ADDR (0x1ULL - MP_FLASH_SIZE_MAX)
 
-#define FLASH_WIDTH 2
-#define CFI_ADDR (FLASH_WIDTH * 0x55)
-#define UNLOCK0_ADDR (FLASH_WIDTH * 0x555)
-#define UNLOCK1_ADDR (FLASH_WIDTH * 0x2AA)
+/* Use a newtype to keep flash addresses separate from byte addresses. */
+typedef struct {
+uint64_t addr;
+} faddr;
+#define FLASH_ADDR(x) ((faddr) { .addr = (x) })
+
+#define CFI_ADDR FLASH_ADDR(0x55)
+#define UNLOCK0_ADDR FLASH_ADDR(0x555)
+#define UNLOCK1_ADDR FLASH_ADDR(0x2AA)
 
 #define CFI_CMD 0x98
 #define UNLOCK0_CMD 0xAA
@@ -35,170 +41,313 @@
 #define UNLOCK_BYPASS_CMD 0x20
 #define UNLOCK_BYPASS_RESET_CMD 0x00
 
+typedef struct {
+int bank_width;
+
+QTestState *qtest;
+} FlashConfig;
+
 static char image_path[] = "/tmp/qtest.XX";
 
-static inline void flash_write(uint64_t byte_addr, uint16_t data)
+/*
+ * The pflash implementation allows some parameters to be unspecified. We want
+ * to test those configurations but we also need to know the real values in
+ * our testing code. So after we launch qemu, we'll need a new FlashConfig
+ * with the correct values filled in.
+ */
+static FlashConfig expand_config_defaults(const FlashConfig *c)
 {
-qtest_writew(global_qtest, BASE_ADDR + byte_addr, data);
+FlashConfig ret = *c;
+
+if (ret.bank_width == 0) {
+ret.bank_width = 2;
+}
+
+/* XXX: Limitations of test harness. */
+assert(ret.bank_width == 2);
+return ret;
 }
 
-static inline uint16_t flash_read(uint64_t byte_addr)
+/*
+ * Return a bit mask suitable for extracting the least significant
+ * status/query response from an interleaved response.
+ */
+static inline uint64_t device_mask(const FlashConfig *c)
 {
-return qtest_readw(global_qtest, BASE_ADDR + byte_addr);
+return (uint64_t)-1;
 }
 
-static void unlock(void)
+/*
+ * Return a bit mask exactly as long as the bank_width.
+ */
+static inline uint64_t bank_mask(const FlashConfig *c)
 {
-flash_write(UNLOCK0_ADDR, UNLOCK0_CMD);
-flash_write(UNLOCK1_ADDR, UNLOCK1_CMD);
+if (c->bank_width == 8) {
+return (uint64_t)-1;
+}
+return (1ULL << (c->bank_width * 8)) - 1ULL;
 }
 
-static void reset(void)
+static inline void flash_write(const FlashConfig *c, uint64_t byte_addr,
+   uint64_t data)
 {
-flash_write(0, RESET_CMD);
-}
-
-static void sector_erase(uint64_t byte_addr)
-{
-unlock();
-flash_write(UNLOCK0_ADDR, 0x80);
-unlock();
-flash_write(byte_addr, SECTOR_ERASE_CMD);
-}
-
-static void wait_for_completion(uint64_t byte_addr)
-{
-/* If DQ6 is toggling, step the clock and ensure the toggle stops. */
-if ((flash_read(byte_addr) & 0x40) ^ (flash_read(byte_addr) & 0x40)) {
-/* Wait for erase or program to finish. */
-clock_step_next();
-/* Ensure that DQ6 has stopped toggling. */
-g_assert_cmphex(flash_read(byte_addr), ==, flash_read(byte_addr));
+/* Sanity check our tests. */
+assert((data & ~bank_mask(c)) == 0);
+uint64_t addr = BASE_ADDR + byte_addr;
+switch (c->bank_width) {
+case 1:
+qtest_writeb(c->qtest, addr, data);
+break;
+case 2:
+qtest_writew(c->qtest, addr, data);
+break;
+case 4:
+qtest_writel(c->qtest, addr, data);
+break;
+case 8:
+qtest_writeq(c->qtest, addr, data);
+break;
+default:
+abort();
 }
 }
 
-static void bypass_program(uint64_t byte_addr, uint16_t data)
+static inline uint64_t flash_read(const FlashConfig *c, uint64_t byte_addr)
 {
-flash_write(UNLOCK0_ADDR, PROGRAM_CMD);
-flash_write(byte_addr, data);
+uint64_t addr = BASE_ADDR + byte_addr;
+switch (c->bank_width) {
+case 1:
+return qtest_readb(c->qtest, addr);
+case 2:
+return qtest_readw(c->qtest, addr);
+case 4:
+return qtest_readl(c->qtest, addr);
+case 8:
+return qtest_readq(c->qtest, addr);
+default:
+abort();
+}
+}
+
+/*
+ * Convert a flash address expressed in the maximum width of the device as a
+ * byte address.
+ */
+static inline uint64_t as_byte_addr(const FlashConfig *c, faddr flash_addr)
+{
+/*
+ 

Re: [Qemu-devel] [PATCH V2 0/5] Add Xen COLO support

2019-07-01 Thread Jason Wang



On 2019/6/10 上午12:44, Zhang Chen wrote:

From: Zhang Chen 

Xen COLO based on KVM COLO architecture, it shared COLO proxy and block
replication with KVM COLO. The only differece is Xen COLO have own
COLO-frame to handle live migration related function, so we need this
series make Xen COLO frame can communicate with other COLO modules in
qemu. Xen side related patches have been merged.

V2:
  - Rebase on upstream code.
  - Optimize code by Zhijian's comments in patch 4/5.
  - Remove origin 5/6 patch.

V1:
  - Initial patch.

Zhang Chen (5):
   COLO-compare: Add new parameter to communicate with remote colo-frame
   COLO-compare: Add remote notification chardev handler frame
   COLO-compare: Make the compare_chr_send() can send notification
 message.
   COLO-compare: Add colo-compare remote notify support
   migration/colo.c: Add missed filter notify for Xen COLO.

  migration/colo.c   |   2 +
  net/colo-compare.c | 155 +++--
  qemu-options.hx|  33 +-
  3 files changed, 171 insertions(+), 19 deletions(-)



Applied.

Thanks







[Qemu-devel] [PULL 21/27] hw/block/pflash_cfi02: Fix CFI in autoselect mode

2019-07-01 Thread Philippe Mathieu-Daudé
From: Stephen Checkoway 

After a flash device enters CFI mode from autoselect mode, the reset
command returns the device to autoselect mode. An additional reset
command is necessary to return to read array mode.

Signed-off-by: Stephen Checkoway 
Message-Id: <20190426162624.55977-7-stephen.checko...@oberlin.edu>
Tested-by: Philippe Mathieu-Daudé 
Acked-by: Thomas Huth 
Acked-by: Alistair Francis 
Acked-by: Philippe Mathieu-Daudé 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/block/pflash_cfi02.c   | 22 ++
 tests/pflash-cfi02-test.c | 39 +++
 2 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 08b2bc83cb..13f76fa71d 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -66,6 +66,7 @@ do {   \
 /* Special write cycles for CFI queries. */
 enum {
 WCYCLE_CFI  = 7,
+WCYCLE_AUTOSELECT_CFI   = 8,
 };
 
 struct PFlashCFI02 {
@@ -311,6 +312,12 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 cmd = value;
 if (pfl->cmd != 0xA0) {
 if (cmd == 0xF0) {
+if (pfl->wcycle == WCYCLE_AUTOSELECT_CFI) {
+/* Return to autoselect mode. */
+pfl->wcycle = 3;
+pfl->cmd = 0x90;
+return;
+}
 goto reset_flash;
 }
 }
@@ -333,7 +340,6 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 /* We're in read mode */
 check_unlock0:
 if (boff == 0x55 && cmd == 0x98) {
-enter_CFI_mode:
 /* Enter CFI query mode */
 pfl->wcycle = WCYCLE_CFI;
 pfl->cmd = 0x98;
@@ -410,9 +416,16 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 /* Unlock bypass reset */
 goto reset_flash;
 }
-/* We can enter CFI query mode from autoselect mode */
-if (boff == 0x55 && cmd == 0x98)
-goto enter_CFI_mode;
+/*
+ * We can enter CFI query mode from autoselect mode, but we must
+ * return to autoselect mode after a reset.
+ */
+if (boff == 0x55 && cmd == 0x98) {
+/* Enter autoselect CFI query mode */
+pfl->wcycle = WCYCLE_AUTOSELECT_CFI;
+pfl->cmd = 0x98;
+return;
+}
 /* No break here */
 default:
 DPRINTF("%s: invalid write for command %02x\n",
@@ -493,6 +506,7 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 break;
 /* Special values for CFI queries */
 case WCYCLE_CFI:
+case WCYCLE_AUTOSELECT_CFI:
 DPRINTF("%s: invalid write in CFI query mode\n", __func__);
 goto reset_flash;
 default:
diff --git a/tests/pflash-cfi02-test.c b/tests/pflash-cfi02-test.c
index 1659eaebce..00e2261742 100644
--- a/tests/pflash-cfi02-test.c
+++ b/tests/pflash-cfi02-test.c
@@ -407,6 +407,42 @@ static void test_geometry(const void *opaque)
 qtest_quit(qtest);
 }
 
+/*
+ * Test that
+ * 1. enter autoselect mode;
+ * 2. enter CFI mode; and then
+ * 3. exit CFI mode
+ * leaves the flash device in autoselect mode.
+ */
+static void test_cfi_in_autoselect(const void *opaque)
+{
+const FlashConfig *config = opaque;
+QTestState *qtest;
+qtest = qtest_initf("-M musicpal,accel=qtest"
+" -drive if=pflash,file=%s,format=raw,copy-on-read",
+image_path);
+FlashConfig explicit_config = expand_config_defaults(config);
+explicit_config.qtest = qtest;
+const FlashConfig *c = &explicit_config;
+
+/* 1. Enter autoselect. */
+unlock(c);
+flash_cmd(c, UNLOCK0_ADDR, AUTOSELECT_CMD);
+g_assert_cmpint(flash_query(c, FLASH_ADDR(0)), ==, replicate(c, 0xBF));
+
+/* 2. Enter CFI. */
+flash_cmd(c, CFI_ADDR, CFI_CMD);
+g_assert_cmpint(flash_query(c, FLASH_ADDR(0x10)), ==, replicate(c, 'Q'));
+g_assert_cmpint(flash_query(c, FLASH_ADDR(0x11)), ==, replicate(c, 'R'));
+g_assert_cmpint(flash_query(c, FLASH_ADDR(0x12)), ==, replicate(c, 'Y'));
+
+/* 3. Exit CFI. */
+reset(c);
+g_assert_cmpint(flash_query(c, FLASH_ADDR(0)), ==, replicate(c, 0xBF));
+
+qtest_quit(qtest);
+}
+
 static void cleanup(void *opaque)
 {
 unlink(image_path);
@@ -474,6 +510,9 @@ int main(int argc, char **argv)
 qtest_add_data_func(path, config, test_geometry);
 g_free(path);
 }
+
+qtest_add_data_func("pflash-cfi02/cfi-in-autoselect", &configuration[0],
+test_cfi_in_autoselect);
 int result = g_test_run();
 cleanup(NULL);
 return result;
-- 
2.20.1




[Qemu-devel] [PULL 06/17] net: use g_strsplit() for parsing host address and port

2019-07-01 Thread Jason Wang
From: Stefano Garzarella 

Use the glib function to split host address and port in
the parse_host_port() function.

Suggested-by: Markus Armbruster 
Signed-off-by: Stefano Garzarella 
Reviewed-by: Markus Armbruster 
Signed-off-by: Jason Wang 
---
 net/net.c | 43 +++
 1 file changed, 27 insertions(+), 16 deletions(-)

diff --git a/net/net.c b/net/net.c
index 76ba0b7..5ce3996 100644
--- a/net/net.c
+++ b/net/net.c
@@ -87,32 +87,39 @@ static int get_str_sep(char *buf, int buf_size, const char 
**pp, int sep)
 int parse_host_port(struct sockaddr_in *saddr, const char *str,
 Error **errp)
 {
-char buf[512];
+gchar **substrings;
 struct hostent *he;
-const char *p, *r;
-int port;
+const char *addr, *p, *r;
+int port, ret = 0;
 
-p = str;
-if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
+substrings = g_strsplit(str, ":", 2);
+if (!substrings || !substrings[0] || !substrings[1]) {
 error_setg(errp, "host address '%s' doesn't contain ':' "
"separating host from port", str);
-return -1;
+ret = -1;
+goto out;
 }
+
+addr = substrings[0];
+p = substrings[1];
+
 saddr->sin_family = AF_INET;
-if (buf[0] == '\0') {
+if (addr[0] == '\0') {
 saddr->sin_addr.s_addr = 0;
 } else {
-if (qemu_isdigit(buf[0])) {
-if (!inet_aton(buf, &saddr->sin_addr)) {
+if (qemu_isdigit(addr[0])) {
+if (!inet_aton(addr, &saddr->sin_addr)) {
 error_setg(errp, "host address '%s' is not a valid "
-   "IPv4 address", buf);
-return -1;
+   "IPv4 address", addr);
+ret = -1;
+goto out;
 }
 } else {
-he = gethostbyname(buf);
+he = gethostbyname(addr);
 if (he == NULL) {
-error_setg(errp, "can't resolve host address '%s'", buf);
-return - 1;
+error_setg(errp, "can't resolve host address '%s'", addr);
+ret = -1;
+goto out;
 }
 saddr->sin_addr = *(struct in_addr *)he->h_addr;
 }
@@ -120,10 +127,14 @@ int parse_host_port(struct sockaddr_in *saddr, const char 
*str,
 port = strtol(p, (char **)&r, 0);
 if (r == p) {
 error_setg(errp, "port number '%s' is invalid", p);
-return -1;
+ret = -1;
+goto out;
 }
 saddr->sin_port = htons(port);
-return 0;
+
+out:
+g_strfreev(substrings);
+return ret;
 }
 
 char *qemu_mac_strdup_printf(const uint8_t *macaddr)
-- 
2.5.0




[Qemu-devel] [PULL 19/27] hw/block/pflash_cfi02: Extract pflash_regions_count()

2019-07-01 Thread Philippe Mathieu-Daudé
Extract the pflash_regions_count() function, the code will be
easier to review.

Reviewed-by: Alistair Francis 
Message-Id: <20190627202719.17739-20-phi...@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/block/pflash_cfi02.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 1f096ec185..a0d3bd60dc 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -157,6 +157,11 @@ static void pflash_register_memory(PFlashCFI02 *pfl, int 
rom_mode)
 pfl->rom_mode = rom_mode;
 }
 
+static size_t pflash_regions_count(PFlashCFI02 *pfl)
+{
+return pfl->cfi_table[0x2c];
+}
+
 static void pflash_timer (void *opaque)
 {
 PFlashCFI02 *pfl = opaque;
@@ -192,9 +197,8 @@ static uint64_t pflash_data_read(PFlashCFI02 *pfl, hwaddr 
offset,
 static uint32_t pflash_sector_len(PFlashCFI02 *pfl, hwaddr offset)
 {
 assert(offset < pfl->chip_len);
-int nb_regions = pfl->cfi_table[0x2C];
 hwaddr addr = 0;
-for (int i = 0; i < nb_regions; ++i) {
+for (int i = 0; i < pflash_regions_count(pfl); ++i) {
 uint64_t region_size = (uint64_t)pfl->nb_blocs[i] * pfl->sector_len[i];
 if (addr <= offset && offset < addr + region_size) {
 return pfl->sector_len[i];
-- 
2.20.1




[Qemu-devel] [PULL 10/27] hw/block/pflash_cfi02: Extract the pflash_data_read() function

2019-07-01 Thread Philippe Mathieu-Daudé
Extract the code block in a new function, remove a goto statement.

Signed-off-by: Stephen Checkoway 
Message-Id: <20190426162624.55977-3-stephen.checko...@oberlin.edu>
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
[PMD: Extracted from bigger patch, remove the XXX tracing comment]
Reviewed-by: Alistair Francis 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/block/pflash_cfi02.c | 24 ++--
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 49afecb921..c079a63880 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -165,12 +165,23 @@ static void pflash_timer (void *opaque)
 pfl->cmd = 0;
 }
 
+/*
+ * Read data from flash.
+ */
+static uint64_t pflash_data_read(PFlashCFI02 *pfl, hwaddr offset,
+ unsigned int width)
+{
+uint8_t *p = (uint8_t *)pfl->storage + offset;
+uint64_t ret = pfl->be ? ldn_be_p(p, width) : ldn_le_p(p, width);
+trace_pflash_data_read(offset, width << 1, ret);
+return ret;
+}
+
 static uint32_t pflash_read(PFlashCFI02 *pfl, hwaddr offset,
 int width, int be)
 {
 hwaddr boff;
 uint32_t ret;
-uint8_t *p;
 
 ret = -1;
 /* Lazy reset to ROMD mode after a certain amount of read accesses */
@@ -194,15 +205,8 @@ static uint32_t pflash_read(PFlashCFI02 *pfl, hwaddr 
offset,
 case 0x80:
 /* We accept reads during second unlock sequence... */
 case 0x00:
-flash_read:
 /* Flash area read */
-p = (uint8_t *)pfl->storage + offset;
-if (pfl->be) {
-ret = ldn_be_p(p, width);
-} else {
-ret = ldn_le_p(p, width);
-}
-trace_pflash_data_read(offset, width << 1, ret);
+ret = pflash_data_read(pfl, offset, width);
 break;
 case 0x90:
 /* flash ID read */
@@ -222,7 +226,7 @@ static uint32_t pflash_read(PFlashCFI02 *pfl, hwaddr offset,
 }
 /* Fall through to data read. */
 default:
-goto flash_read;
+ret = pflash_data_read(pfl, offset, width);
 }
 DPRINTF("%s: ID " TARGET_FMT_plx " %" PRIx32 "\n", __func__, boff, 
ret);
 break;
-- 
2.20.1




[Qemu-devel] [PULL 17/27] hw/block/pflash_cfi02: Document 'Page Mode' operations are not supported

2019-07-01 Thread Philippe Mathieu-Daudé
The 'page mode' feature entry was implicitly set as zero
(not supported). Document it exists, so we won't discard
it if we squeeze the CFI table.

Signed-off-by: Stephen Checkoway 
Message-Id: <20190426162624.55977-6-stephen.checko...@oberlin.edu>
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
[PMD: Extracted from bigger patch]
Reviewed-by: Alistair Francis 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/block/pflash_cfi02.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 23d05a6308..01d9c5d75a 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -637,7 +637,9 @@ static void pflash_cfi02_realize(DeviceState *dev, Error 
**errp)
 pfl->cfi_table[0x0a + pri_ofs] = 0x00;
 /* Burst mode not supported. */
 pfl->cfi_table[0x0b + pri_ofs] = 0x00;
-assert(0x0b + pri_ofs < ARRAY_SIZE(pfl->cfi_table));
+/* Page mode not supported. */
+pfl->cfi_table[0x0c + pri_ofs] = 0x00;
+assert(0x0c + pri_ofs < ARRAY_SIZE(pfl->cfi_table));
 }
 
 static Property pflash_cfi02_properties[] = {
-- 
2.20.1




[Qemu-devel] [PULL 27/27] hw/block/pflash_cfi02: Reduce I/O accesses to 16-bit

2019-07-01 Thread Philippe Mathieu-Daudé
Parallel NOR flashes are limited to 16-bit bus accesses.
Remove the 32-bit dead code.

Reviewed-by: Alistair Francis 
Message-Id: <20190627202719.17739-29-phi...@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/block/pflash_cfi02.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 83084b9d72..5392290c72 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -317,8 +317,6 @@ static uint64_t pflash_read(void *opaque, hwaddr offset, 
unsigned int width)
 boff = offset & 0xFF;
 if (pfl->width == 2) {
 boff = boff >> 1;
-} else if (pfl->width == 4) {
-boff = boff >> 2;
 }
 switch (pfl->cmd) {
 default:
@@ -449,8 +447,6 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 boff = offset;
 if (pfl->width == 2) {
 boff = boff >> 1;
-} else if (pfl->width == 4) {
-boff = boff >> 2;
 }
 /* Only the least-significant 11 bits are used in most cases. */
 boff &= 0x7FF;
@@ -710,6 +706,7 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 static const MemoryRegionOps pflash_cfi02_ops = {
 .read = pflash_read,
 .write = pflash_write,
+.impl.max_access_size = 2,
 .valid.min_access_size = 1,
 .valid.max_access_size = 4,
 .endianness = DEVICE_NATIVE_ENDIAN,
-- 
2.20.1




[Qemu-devel] [PULL 22/27] hw/block/pflash_cfi02: Fix reset command not ignored during erase

2019-07-01 Thread Philippe Mathieu-Daudé
From: Stephen Checkoway 

When the flash device is performing a chip erase, all commands are
ignored. When it is performing a sector erase, only the erase suspend
command is valid, which is currently not supported.

In particular, the reset command should not cause the device to reset to
read array mode while programming is on going.

Signed-off-by: Stephen Checkoway 
Message-Id: <20190426162624.55977-8-stephen.checko...@oberlin.edu>
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/block/pflash_cfi02.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 13f76fa71d..39daa95833 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -311,7 +311,8 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 trace_pflash_io_write(offset, width, width << 1, value, pfl->wcycle);
 cmd = value;
 if (pfl->cmd != 0xA0) {
-if (cmd == 0xF0) {
+/* Reset does nothing during chip erase and sector erase. */
+if (cmd == 0xF0 && pfl->cmd != 0x10 && pfl->cmd != 0x30) {
 if (pfl->wcycle == WCYCLE_AUTOSELECT_CFI) {
 /* Return to autoselect mode. */
 pfl->wcycle = 3;
-- 
2.20.1




[Qemu-devel] [PULL 16/27] hw/block/pflash_cfi02: Hold the PRI table offset in a variable

2019-07-01 Thread Philippe Mathieu-Daudé
Manufacturers are allowed to move the PRI table, this is why the
offset is queryable via fixed offsets 0x15/0x16.
Add a variable to hold the offset, so it will be easier to later
move the PRI table.

Reviewed-by: Alistair Francis 
Message-Id: <20190627202719.17739-17-phi...@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/block/pflash_cfi02.c | 31 +--
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index f1bac480f5..23d05a6308 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -552,6 +552,7 @@ static void pflash_cfi02_realize(DeviceState *dev, Error 
**errp)
 pfl->status = 0;
 
 /* Hardcoded CFI table (mostly from SG29 Spansion flash) */
+const uint16_t pri_ofs = 0x31;
 /* Standard "QRY" string */
 pfl->cfi_table[0x10] = 'Q';
 pfl->cfi_table[0x11] = 'R';
@@ -560,8 +561,8 @@ static void pflash_cfi02_realize(DeviceState *dev, Error 
**errp)
 pfl->cfi_table[0x13] = 0x02;
 pfl->cfi_table[0x14] = 0x00;
 /* Primary extended table address */
-pfl->cfi_table[0x15] = 0x31;
-pfl->cfi_table[0x16] = 0x00;
+pfl->cfi_table[0x15] = pri_ofs;
+pfl->cfi_table[0x16] = pri_ofs >> 8;
 /* Alternate command set (none) */
 pfl->cfi_table[0x17] = 0x00;
 pfl->cfi_table[0x18] = 0x00;
@@ -609,32 +610,34 @@ static void pflash_cfi02_realize(DeviceState *dev, Error 
**errp)
 pfl->cfi_table[0x2E] = (pfl->nb_blocs - 1) >> 8;
 pfl->cfi_table[0x2F] = pfl->sector_len >> 8;
 pfl->cfi_table[0x30] = pfl->sector_len >> 16;
+assert(0x30 < pri_ofs);
 
 /* Extended */
-pfl->cfi_table[0x31] = 'P';
-pfl->cfi_table[0x32] = 'R';
-pfl->cfi_table[0x33] = 'I';
+pfl->cfi_table[0x00 + pri_ofs] = 'P';
+pfl->cfi_table[0x01 + pri_ofs] = 'R';
+pfl->cfi_table[0x02 + pri_ofs] = 'I';
 
 /* Extended version 1.0 */
-pfl->cfi_table[0x34] = '1';
-pfl->cfi_table[0x35] = '0';
+pfl->cfi_table[0x03 + pri_ofs] = '1';
+pfl->cfi_table[0x04 + pri_ofs] = '0';
 
 /* Address sensitive unlock required. */
-pfl->cfi_table[0x36] = 0x00;
+pfl->cfi_table[0x05 + pri_ofs] = 0x00;
 /* Erase suspend not supported. */
-pfl->cfi_table[0x37] = 0x00;
+pfl->cfi_table[0x06 + pri_ofs] = 0x00;
 /* Sector protect not supported. */
-pfl->cfi_table[0x38] = 0x00;
+pfl->cfi_table[0x07 + pri_ofs] = 0x00;
 /* Temporary sector unprotect not supported. */
-pfl->cfi_table[0x39] = 0x00;
+pfl->cfi_table[0x08 + pri_ofs] = 0x00;
 
 /* Sector protect/unprotect scheme. */
-pfl->cfi_table[0x3a] = 0x00;
+pfl->cfi_table[0x09 + pri_ofs] = 0x00;
 
 /* Simultaneous operation not supported. */
-pfl->cfi_table[0x3b] = 0x00;
+pfl->cfi_table[0x0a + pri_ofs] = 0x00;
 /* Burst mode not supported. */
-pfl->cfi_table[0x3c] = 0x00;
+pfl->cfi_table[0x0b + pri_ofs] = 0x00;
+assert(0x0b + pri_ofs < ARRAY_SIZE(pfl->cfi_table));
 }
 
 static Property pflash_cfi02_properties[] = {
-- 
2.20.1




[Qemu-devel] [PULL 24/27] hw/block/pflash_cfi02: Implement erase suspend/resume

2019-07-01 Thread Philippe Mathieu-Daudé
From: Stephen Checkoway 

During a sector erase (but not a chip erase), the embeded erase program
can be suspended. Once suspended, the sectors not selected for erasure
may be read and programmed. Autoselect mode is allowed during erase
suspend mode. Presumably, CFI queries are similarly allowed so this
commit allows them as well.

Since guest firmware can use status bits DQ7, DQ6, DQ3, and DQ2 to
determine the current state of sector erasure, these bits are properly
implemented.

Signed-off-by: Stephen Checkoway 
Message-Id: <20190426162624.55977-10-stephen.checko...@oberlin.edu>
Acked-by: Thomas Huth 
Acked-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
[PMD: Rebased]
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/block/pflash_cfi02.c   | 154 ++
 tests/pflash-cfi02-test.c | 110 +++
 2 files changed, 250 insertions(+), 14 deletions(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 5874bd55ad..a3665da3b8 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -30,7 +30,6 @@
  *
  * It does not support flash interleaving.
  * It does not implement software data protection as found in many real chips
- * It does not implement erase suspend/resume commands
  */
 
 #include "qemu/osdep.h"
@@ -38,6 +37,7 @@
 #include "hw/block/block.h"
 #include "hw/block/flash.h"
 #include "qapi/error.h"
+#include "qemu/bitmap.h"
 #include "qemu/timer.h"
 #include "sysemu/block-backend.h"
 #include "qemu/host-utils.h"
@@ -76,6 +76,7 @@ struct PFlashCFI02 {
 BlockBackend *blk;
 uint32_t uniform_nb_blocs;
 uint32_t uniform_sector_len;
+uint32_t total_sectors;
 uint32_t nb_blocs[PFLASH_MAX_ERASE_REGIONS];
 uint32_t sector_len[PFLASH_MAX_ERASE_REGIONS];
 uint32_t chip_len;
@@ -106,6 +107,8 @@ struct PFlashCFI02 {
 int rom_mode;
 int read_counter; /* used for lazy switch-back to rom mode */
 int sectors_to_erase;
+uint64_t erase_time_remaining;
+unsigned long *sector_erase_map;
 char *name;
 void *storage;
 };
@@ -151,6 +154,14 @@ static inline void reset_dq3(PFlashCFI02 *pfl)
 pfl->status &= ~0x08;
 }
 
+/*
+ * Toggle status bit DQ2.
+ */
+static inline void toggle_dq2(PFlashCFI02 *pfl)
+{
+pfl->status ^= 0x04;
+}
+
 /*
  * Set up replicated mappings of the same region.
  */
@@ -179,6 +190,29 @@ static size_t pflash_regions_count(PFlashCFI02 *pfl)
 return pfl->cfi_table[0x2c];
 }
 
+/*
+ * Returns the time it takes to erase the number of sectors scheduled for
+ * erasure based on CFI address 0x21 which is "Typical timeout per individual
+ * block erase 2^N ms."
+ */
+static uint64_t pflash_erase_time(PFlashCFI02 *pfl)
+{
+/*
+ * If there are no sectors to erase (which can happen if all of the sectors
+ * to be erased are protected), then erase takes 100 us. Protected sectors
+ * aren't supported so this should never happen.
+ */
+return ((1ULL << pfl->cfi_table[0x21]) * pfl->sectors_to_erase) * SCALE_US;
+}
+
+/*
+ * Returns true if the device is currently in erase suspend mode.
+ */
+static inline bool pflash_erase_suspend_mode(PFlashCFI02 *pfl)
+{
+return pfl->erase_time_remaining > 0;
+}
+
 static void pflash_timer(void *opaque)
 {
 PFlashCFI02 *pfl = opaque;
@@ -193,12 +227,7 @@ static void pflash_timer(void *opaque)
  */
 if ((pfl->status & 0x08) == 0) {
 assert_dq3(pfl);
-/*
- * CFI address 0x21 is "Typical timeout per individual block erase
- * 2^N ms"
- */
-uint64_t timeout = ((1ULL << pfl->cfi_table[0x21]) *
-pfl->sectors_to_erase) * 100;
+uint64_t timeout = pflash_erase_time(pfl);
 timer_mod(&pfl->timer,
   qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + timeout);
 DPRINTF("%s: erase timeout fired; erasing %d sectors\n",
@@ -206,6 +235,7 @@ static void pflash_timer(void *opaque)
 return;
 }
 DPRINTF("%s: sector erase complete\n", __func__);
+bitmap_zero(pfl->sector_erase_map, pfl->total_sectors);
 pfl->sectors_to_erase = 0;
 reset_dq3(pfl);
 }
@@ -233,24 +263,44 @@ static uint64_t pflash_data_read(PFlashCFI02 *pfl, hwaddr 
offset,
 return ret;
 }
 
+typedef struct {
+uint32_t len;
+uint32_t num;
+} SectorInfo;
+
 /*
  * offset should be a byte offset of the QEMU device and _not_ a device
  * offset.
  */
-static uint32_t pflash_sector_len(PFlashCFI02 *pfl, hwaddr offset)
+static SectorInfo pflash_sector_info(PFlashCFI02 *pfl, hwaddr offset)
 {
 assert(offset < pfl->chip_len);
 hwaddr addr = 0;
+uint32_t sector_num = 0;
 for (int i = 0; i < pflash_regions_count(pfl); ++i) {
 uint64_t region_size = (uint64_t)pfl->nb_blocs[i] * pfl->sector_len[i];
 if (addr <= offset && offset < addr + region_size) {
-return pfl->sector_len[i];
+   

[Qemu-devel] [PULL 11/27] hw/block/pflash_cfi02: Unify the MemoryRegionOps

2019-07-01 Thread Philippe Mathieu-Daudé
The pflash_read()/pflash_write() can check the device endianess
via the pfl->be variable, so remove the 'int be' argument.

Since the big/little MemoryRegionOps are now identical, it is
pointless to declare them both. Unify them.

Signed-off-by: Stephen Checkoway 
Message-Id: <20190426162624.55977-3-stephen.checko...@oberlin.edu>
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
[PMD: Extracted from bigger patch to ease review]
Reviewed-by: Alistair Francis 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/block/pflash_cfi02.c | 60 +++--
 1 file changed, 15 insertions(+), 45 deletions(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index c079a63880..e64dc69c6c 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -177,11 +177,11 @@ static uint64_t pflash_data_read(PFlashCFI02 *pfl, hwaddr 
offset,
 return ret;
 }
 
-static uint32_t pflash_read(PFlashCFI02 *pfl, hwaddr offset,
-int width, int be)
+static uint64_t pflash_read(void *opaque, hwaddr offset, unsigned int width)
 {
+PFlashCFI02 *pfl = opaque;
 hwaddr boff;
-uint32_t ret;
+uint64_t ret;
 
 ret = -1;
 /* Lazy reset to ROMD mode after a certain amount of read accesses */
@@ -228,14 +228,14 @@ static uint32_t pflash_read(PFlashCFI02 *pfl, hwaddr 
offset,
 default:
 ret = pflash_data_read(pfl, offset, width);
 }
-DPRINTF("%s: ID " TARGET_FMT_plx " %" PRIx32 "\n", __func__, boff, 
ret);
+DPRINTF("%s: ID " TARGET_FMT_plx " %" PRIx64 "\n", __func__, boff, 
ret);
 break;
 case 0xA0:
 case 0x10:
 case 0x30:
 /* Status register read */
 ret = pfl->status;
-DPRINTF("%s: status %" PRIx32 "\n", __func__, ret);
+DPRINTF("%s: status %" PRIx64 "\n", __func__, ret);
 toggle_dq6(pfl);
 break;
 case 0x98:
@@ -253,8 +253,7 @@ static uint32_t pflash_read(PFlashCFI02 *pfl, hwaddr offset,
 }
 
 /* update flash content on disk */
-static void pflash_update(PFlashCFI02 *pfl, int offset,
-  int size)
+static void pflash_update(PFlashCFI02 *pfl, int offset, int size)
 {
 int offset_end;
 if (pfl->blk) {
@@ -267,9 +266,10 @@ static void pflash_update(PFlashCFI02 *pfl, int offset,
 }
 }
 
-static void pflash_write(PFlashCFI02 *pfl, hwaddr offset,
- uint32_t value, int width, int be)
+static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
+ unsigned int width)
 {
+PFlashCFI02 *pfl = opaque;
 hwaddr boff;
 uint8_t *p;
 uint8_t cmd;
@@ -477,39 +477,9 @@ static void pflash_write(PFlashCFI02 *pfl, hwaddr offset,
 pfl->cmd = 0;
 }
 
-static uint64_t pflash_be_readfn(void *opaque, hwaddr addr, unsigned size)
-{
-return pflash_read(opaque, addr, size, 1);
-}
-
-static void pflash_be_writefn(void *opaque, hwaddr addr,
-  uint64_t value, unsigned size)
-{
-pflash_write(opaque, addr, value, size, 1);
-}
-
-static uint64_t pflash_le_readfn(void *opaque, hwaddr addr, unsigned size)
-{
-return pflash_read(opaque, addr, size, 0);
-}
-
-static void pflash_le_writefn(void *opaque, hwaddr addr,
-  uint64_t value, unsigned size)
-{
-pflash_write(opaque, addr, value, size, 0);
-}
-
-static const MemoryRegionOps pflash_cfi02_ops_be = {
-.read = pflash_be_readfn,
-.write = pflash_be_writefn,
-.valid.min_access_size = 1,
-.valid.max_access_size = 4,
-.endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static const MemoryRegionOps pflash_cfi02_ops_le = {
-.read = pflash_le_readfn,
-.write = pflash_le_writefn,
+static const MemoryRegionOps pflash_cfi02_ops = {
+.read = pflash_read,
+.write = pflash_write,
 .valid.min_access_size = 1,
 .valid.max_access_size = 4,
 .endianness = DEVICE_NATIVE_ENDIAN,
@@ -537,9 +507,9 @@ static void pflash_cfi02_realize(DeviceState *dev, Error 
**errp)
 
 chip_len = pfl->sector_len * pfl->nb_blocs;
 
-memory_region_init_rom_device(&pfl->orig_mem, OBJECT(pfl), pfl->be ?
-  &pflash_cfi02_ops_be : &pflash_cfi02_ops_le,
-  pfl, pfl->name, chip_len, &local_err);
+memory_region_init_rom_device(&pfl->orig_mem, OBJECT(pfl),
+  &pflash_cfi02_ops, pfl, pfl->name,
+  chip_len, &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
 return;
-- 
2.20.1




[Qemu-devel] [PULL 15/27] hw/block/pflash_cfi02: Document the current CFI values

2019-07-01 Thread Philippe Mathieu-Daudé
Signed-off-by: Stephen Checkoway 
Message-Id: <20190426162624.55977-6-stephen.checko...@oberlin.edu>
Reviewed-by: Philippe Mathieu-Daudé 
[PMD: Extracted from bigger patch]
Acked-by: Alistair Francis 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/block/pflash_cfi02.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 1a794fa83c..f1bac480f5 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -550,6 +550,7 @@ static void pflash_cfi02_realize(DeviceState *dev, Error 
**errp)
 pfl->wcycle = 0;
 pfl->cmd = 0;
 pfl->status = 0;
+
 /* Hardcoded CFI table (mostly from SG29 Spansion flash) */
 /* Standard "QRY" string */
 pfl->cfi_table[0x10] = 'Q';
@@ -575,7 +576,7 @@ static void pflash_cfi02_realize(DeviceState *dev, Error 
**errp)
 pfl->cfi_table[0x1D] = 0x00;
 /* Vpp max (no Vpp pin) */
 pfl->cfi_table[0x1E] = 0x00;
-/* Reserved */
+/* Timeout per single byte/word write (128 ms) */
 pfl->cfi_table[0x1F] = 0x07;
 /* Timeout for min size buffer write (NA) */
 pfl->cfi_table[0x20] = 0x00;
@@ -614,17 +615,25 @@ static void pflash_cfi02_realize(DeviceState *dev, Error 
**errp)
 pfl->cfi_table[0x32] = 'R';
 pfl->cfi_table[0x33] = 'I';
 
+/* Extended version 1.0 */
 pfl->cfi_table[0x34] = '1';
 pfl->cfi_table[0x35] = '0';
 
+/* Address sensitive unlock required. */
 pfl->cfi_table[0x36] = 0x00;
+/* Erase suspend not supported. */
 pfl->cfi_table[0x37] = 0x00;
+/* Sector protect not supported. */
 pfl->cfi_table[0x38] = 0x00;
+/* Temporary sector unprotect not supported. */
 pfl->cfi_table[0x39] = 0x00;
 
+/* Sector protect/unprotect scheme. */
 pfl->cfi_table[0x3a] = 0x00;
 
+/* Simultaneous operation not supported. */
 pfl->cfi_table[0x3b] = 0x00;
+/* Burst mode not supported. */
 pfl->cfi_table[0x3c] = 0x00;
 }
 
-- 
2.20.1




[Qemu-devel] [PULL 09/27] hw/block/pflash_cfi02: Use the ldst API in pflash_read()

2019-07-01 Thread Philippe Mathieu-Daudé
The load/store API eases code review.

Signed-off-by: Stephen Checkoway 
Message-Id: <20190426162624.55977-3-stephen.checko...@oberlin.edu>
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
[PMD: Extracted from bigger patch, simplified tracing]
Reviewed-by: Alistair Francis 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/block/pflash_cfi02.c | 32 +---
 1 file changed, 5 insertions(+), 27 deletions(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index ae38ed0bae..49afecb921 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -196,33 +196,11 @@ static uint32_t pflash_read(PFlashCFI02 *pfl, hwaddr 
offset,
 case 0x00:
 flash_read:
 /* Flash area read */
-p = pfl->storage;
-switch (width) {
-case 1:
-ret = p[offset];
-break;
-case 2:
-if (be) {
-ret = p[offset] << 8;
-ret |= p[offset + 1];
-} else {
-ret = p[offset];
-ret |= p[offset + 1] << 8;
-}
-break;
-case 4:
-if (be) {
-ret = p[offset] << 24;
-ret |= p[offset + 1] << 16;
-ret |= p[offset + 2] << 8;
-ret |= p[offset + 3];
-} else {
-ret = p[offset];
-ret |= p[offset + 1] << 8;
-ret |= p[offset + 2] << 16;
-ret |= p[offset + 3] << 24;
-}
-break;
+p = (uint8_t *)pfl->storage + offset;
+if (pfl->be) {
+ret = ldn_be_p(p, width);
+} else {
+ret = ldn_le_p(p, width);
 }
 trace_pflash_data_read(offset, width << 1, ret);
 break;
-- 
2.20.1




[Qemu-devel] [PULL 14/27] hw/block/pflash_cfi02: Remove pointless local variable

2019-07-01 Thread Philippe Mathieu-Daudé
We can directly use pfl->total_len, remove the local 'chip_len'
variable.

Signed-off-by: Stephen Checkoway 
Message-Id: <20190426162624.55977-6-stephen.checko...@oberlin.edu>
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
[PMD: Extracted from bigger patch]
Reviewed-by: Alistair Francis 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/block/pflash_cfi02.c | 14 ++
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 4be3837be5..1a794fa83c 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -409,7 +409,7 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 /* Chip erase */
 DPRINTF("%s: start chip erase\n", __func__);
 if (!pfl->ro) {
-memset(pfl->storage, 0xFF, pfl->chip_len);
+memset(pfl->storage, 0xff, pfl->chip_len);
 pflash_update(pfl, 0, pfl->chip_len);
 }
 set_dq7(pfl, 0x00);
@@ -490,7 +490,6 @@ static const MemoryRegionOps pflash_cfi02_ops = {
 static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
 {
 PFlashCFI02 *pfl = PFLASH_CFI02(dev);
-uint32_t chip_len;
 int ret;
 Error *local_err = NULL;
 
@@ -507,18 +506,17 @@ static void pflash_cfi02_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
-chip_len = pfl->sector_len * pfl->nb_blocs;
+pfl->chip_len = pfl->sector_len * pfl->nb_blocs;
 
 memory_region_init_rom_device(&pfl->orig_mem, OBJECT(pfl),
   &pflash_cfi02_ops, pfl, pfl->name,
-  chip_len, &local_err);
+  pfl->chip_len, &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
 return;
 }
 
 pfl->storage = memory_region_get_ram_ptr(&pfl->orig_mem);
-pfl->chip_len = chip_len;
 
 if (pfl->blk) {
 uint64_t perm;
@@ -533,8 +531,8 @@ static void pflash_cfi02_realize(DeviceState *dev, Error 
**errp)
 }
 
 if (pfl->blk) {
-if (!blk_check_size_and_read_all(pfl->blk, pfl->storage, chip_len,
- errp)) {
+if (!blk_check_size_and_read_all(pfl->blk, pfl->storage,
+ pfl->chip_len, errp)) {
 vmstate_unregister_ram(&pfl->orig_mem, DEVICE(pfl));
 return;
 }
@@ -594,7 +592,7 @@ static void pflash_cfi02_realize(DeviceState *dev, Error 
**errp)
 /* Max timeout for chip erase */
 pfl->cfi_table[0x26] = 0x0D;
 /* Device size */
-pfl->cfi_table[0x27] = ctz32(chip_len);
+pfl->cfi_table[0x27] = ctz32(pfl->chip_len);
 /* Flash device interface (8 & 16 bits) */
 pfl->cfi_table[0x28] = 0x02;
 pfl->cfi_table[0x29] = 0x00;
-- 
2.20.1




[Qemu-devel] [PULL 23/27] hw/block/pflash_cfi02: Implement multi-sector erase

2019-07-01 Thread Philippe Mathieu-Daudé
From: Stephen Checkoway 

After two unlock cycles and a sector erase command, the AMD flash chips
start a 50 us erase time out. Any additional sector erase commands add a
sector to be erased and restart the 50 us timeout. During the timeout,
status bit DQ3 is cleared. After the time out, DQ3 is asserted during
erasure.

Signed-off-by: Stephen Checkoway 
Message-Id: <20190426162624.55977-9-stephen.checko...@oberlin.edu>
Acked-by: Thomas Huth 
Acked-by: Philippe Mathieu-Daudé 
[PMD: Rebased]
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/block/pflash_cfi02.c   | 94 +++
 tests/pflash-cfi02-test.c | 70 +
 2 files changed, 137 insertions(+), 27 deletions(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 39daa95833..5874bd55ad 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -31,7 +31,6 @@
  * It does not support flash interleaving.
  * It does not implement software data protection as found in many real chips
  * It does not implement erase suspend/resume commands
- * It does not implement multiple sectors erase
  */
 
 #include "qemu/osdep.h"
@@ -106,6 +105,7 @@ struct PFlashCFI02 {
 MemoryRegion orig_mem;
 int rom_mode;
 int read_counter; /* used for lazy switch-back to rom mode */
+int sectors_to_erase;
 char *name;
 void *storage;
 };
@@ -135,6 +135,22 @@ static inline void toggle_dq6(PFlashCFI02 *pfl)
 pfl->status ^= 0x40;
 }
 
+/*
+ * Turn on DQ3.
+ */
+static inline void assert_dq3(PFlashCFI02 *pfl)
+{
+pfl->status |= 0x08;
+}
+
+/*
+ * Turn off DQ3.
+ */
+static inline void reset_dq3(PFlashCFI02 *pfl)
+{
+pfl->status &= ~0x08;
+}
+
 /*
  * Set up replicated mappings of the same region.
  */
@@ -163,11 +179,37 @@ static size_t pflash_regions_count(PFlashCFI02 *pfl)
 return pfl->cfi_table[0x2c];
 }
 
-static void pflash_timer (void *opaque)
+static void pflash_timer(void *opaque)
 {
 PFlashCFI02 *pfl = opaque;
 
 trace_pflash_timer_expired(pfl->cmd);
+if (pfl->cmd == 0x30) {
+/*
+ * Sector erase. If DQ3 is 0 when the timer expires, then the 50
+ * us erase timeout has expired so we need to start the timer for the
+ * sector erase algorithm. Otherwise, the erase completed and we should
+ * go back to read array mode.
+ */
+if ((pfl->status & 0x08) == 0) {
+assert_dq3(pfl);
+/*
+ * CFI address 0x21 is "Typical timeout per individual block erase
+ * 2^N ms"
+ */
+uint64_t timeout = ((1ULL << pfl->cfi_table[0x21]) *
+pfl->sectors_to_erase) * 100;
+timer_mod(&pfl->timer,
+  qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + timeout);
+DPRINTF("%s: erase timeout fired; erasing %d sectors\n",
+__func__, pfl->sectors_to_erase);
+return;
+}
+DPRINTF("%s: sector erase complete\n", __func__);
+pfl->sectors_to_erase = 0;
+reset_dq3(pfl);
+}
+
 /* Reset flash */
 toggle_dq7(pfl);
 if (pfl->bypass) {
@@ -299,6 +341,24 @@ static void pflash_update(PFlashCFI02 *pfl, int offset, 
int size)
 }
 }
 
+static void pflash_sector_erase(PFlashCFI02 *pfl, hwaddr offset)
+{
+uint64_t sector_len = pflash_sector_len(pfl, offset);
+offset &= ~(sector_len - 1);
+DPRINTF("%s: start sector erase at %0*" PRIx64 "-%0*" PRIx64 "\n",
+__func__, pfl->width * 2, offset,
+pfl->width * 2, offset + sector_len - 1);
+if (!pfl->ro) {
+uint8_t *p = pfl->storage;
+memset(p + offset, 0xff, sector_len);
+pflash_update(pfl, offset, sector_len);
+}
+set_dq7(pfl, 0x00);
+++pfl->sectors_to_erase;
+/* Set (or reset) the 50 us timer for additional erase commands.  */
+timer_mod(&pfl->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 5);
+}
+
 static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
  unsigned int width)
 {
@@ -306,7 +366,6 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 hwaddr boff;
 uint8_t *p;
 uint8_t cmd;
-uint32_t sector_len;
 
 trace_pflash_io_write(offset, width, width << 1, value, pfl->wcycle);
 cmd = value;
@@ -469,20 +528,7 @@ static void pflash_write(void *opaque, hwaddr offset, 
uint64_t value,
 break;
 case 0x30:
 /* Sector erase */
-p = pfl->storage;
-sector_len = pflash_sector_len(pfl, offset);
-offset &= ~(sector_len - 1);
-DPRINTF("%s: start sector erase at %0*" PRIx64 "-%0*" PRIx64 "\n",
-__func__, pfl->width * 2, offset,
-pfl->width * 2, offset + sector_len - 1);
-if (!pfl->ro) {
-memset(p + offset, 0xff, sector_len);
-pflash_update(pfl, offset, sector_len);

[Qemu-devel] [PULL 08/27] hw/block/pflash_cfi02: Use the ldst API in pflash_write()

2019-07-01 Thread Philippe Mathieu-Daudé
The load/store API eases code review.

Signed-off-by: Stephen Checkoway 
Message-Id: <20190426162624.55977-3-stephen.checko...@oberlin.edu>
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
[PMD: Extracted from bigger patch]
Reviewed-by: Alistair Francis 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/block/pflash_cfi02.c | 38 --
 1 file changed, 8 insertions(+), 30 deletions(-)

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 9e8c28af8f..ae38ed0bae 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -365,38 +365,16 @@ static void pflash_write(PFlashCFI02 *pfl, hwaddr offset,
 goto check_unlock0;
 case 0xA0:
 trace_pflash_data_write(offset, width << 1, value, 0);
-p = pfl->storage;
 if (!pfl->ro) {
-switch (width) {
-case 1:
-p[offset] &= value;
-pflash_update(pfl, offset, 1);
-break;
-case 2:
-if (be) {
-p[offset] &= value >> 8;
-p[offset + 1] &= value;
-} else {
-p[offset] &= value;
-p[offset + 1] &= value >> 8;
-}
-pflash_update(pfl, offset, 2);
-break;
-case 4:
-if (be) {
-p[offset] &= value >> 24;
-p[offset + 1] &= value >> 16;
-p[offset + 2] &= value >> 8;
-p[offset + 3] &= value;
-} else {
-p[offset] &= value;
-p[offset + 1] &= value >> 8;
-p[offset + 2] &= value >> 16;
-p[offset + 3] &= value >> 24;
-}
-pflash_update(pfl, offset, 4);
-break;
+p = (uint8_t *)pfl->storage + offset;
+if (pfl->be) {
+uint64_t current = ldn_be_p(p, width);
+stn_be_p(p, width, current & value);
+} else {
+uint64_t current = ldn_le_p(p, width);
+stn_le_p(p, width, current & value);
 }
+pflash_update(pfl, offset, width);
 }
 /*
  * While programming, status bit DQ7 should hold the opposite
-- 
2.20.1




  1   2   3   4   5   >