Re: [Qemu-devel] [PATCH for-2.12] tcg: Mark muluh_i64 and mulsh_i64 as 64-bit ops

2018-03-26 Thread Emilio G. Cota
On Tue, Mar 27, 2018 at 11:47:57 +0800, Richard Henderson wrote:
> Failure to do so results in the tcg optimizer sign-extending
> any constant fold from 32-bits.  This turns out to be visible
> in the RISC-V testsuite using a host that emits these opcodes
> (e.g. any non-x86_64).
>
> Reported-by: Michael Clark 
> Signed-off-by: Richard Henderson 

Reviewed-by: Emilio G. Cota 

E.




[Qemu-devel] [PATCH v2 10/14] hardfloat: support float32/64 division

2018-03-26 Thread Emilio G. Cota
Performance results for fp-bench run under aarch64-linux-user
on an Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz host:

- before:
div-single: 30.30 MFlops
div-double: 29.59 MFlops

- after:
div-single: 94.07 MFlops
div-double: 106.79 MFlops

- w/ both using float32/64_is_normal etc.:
div-single: 94.08 MFlops
div-double: 99.09 MFlops

- w/ both using fpclassify etc.:
div-single: 88.82 MFlops
div-double: 105.20 MFlops

Signed-off-by: Emilio G. Cota 
---
 fpu/softfloat.c | 64 +++--
 1 file changed, 62 insertions(+), 2 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 9739a86..f414b41 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1440,7 +1440,8 @@ float16 float16_div(float16 a, float16 b, float_status 
*status)
 return float16_round_pack_canonical(pr, status);
 }
 
-float32 float32_div(float32 a, float32 b, float_status *status)
+static float32 __attribute__((flatten, noinline))
+soft_float32_div(float32 a, float32 b, float_status *status)
 {
 FloatParts pa = float32_unpack_canonical(a, status);
 FloatParts pb = float32_unpack_canonical(b, status);
@@ -1449,7 +1450,8 @@ float32 float32_div(float32 a, float32 b, float_status 
*status)
 return float32_round_pack_canonical(pr, status);
 }
 
-float64 float64_div(float64 a, float64 b, float_status *status)
+static float64 __attribute__((flatten, noinline))
+soft_float64_div(float64 a, float64 b, float_status *status)
 {
 FloatParts pa = float64_unpack_canonical(a, status);
 FloatParts pb = float64_unpack_canonical(b, status);
@@ -1458,6 +1460,64 @@ float64 float64_div(float64 a, float64 b, float_status 
*status)
 return float64_round_pack_canonical(pr, status);
 }
 
+#define GEN_FPU_DIV(name, soft_t, host_t, host_abs_func, min_normal)\
+soft_t name(soft_t a, soft_t b, float_status *s)\
+{   \
+soft_t ## _input_flush2(, , s); \
+if (likely((soft_t ## _is_normal(a) || soft_t ## _is_zero(a)) && \
+   soft_t ## _is_normal(b) &&   \
+   s->float_exception_flags & float_flag_inexact && \
+   s->float_rounding_mode == float_round_nearest_even)) { \
+host_t ha = soft_t ## _to_ ## host_t(a);\
+host_t hb = soft_t ## _to_ ## host_t(b);\
+host_t hr = ha / hb;\
+soft_t r = host_t ## _to_ ## soft_t(hr);\
+\
+if (unlikely(soft_t ## _is_infinity(r))) {  \
+s->float_exception_flags |= float_flag_overflow;\
+} else if (unlikely(host_abs_func(hr) <= min_normal) && \
+   !soft_t ## _is_zero(a)) {\
+goto soft;  \
+}   \
+return r;   \
+}   \
+soft:   \
+return soft_ ## soft_t ## _div(a, b, s);\
+}
+
+GEN_FPU_DIV(float32_div, float32, float, fabsf, FLT_MIN)
+#undef GEN_FPU_DIV
+
+#define GEN_FPU_DIV(name, soft_t, host_t, host_abs_func, min_normal)\
+soft_t name(soft_t a, soft_t b, float_status *s)\
+{   \
+host_t ha, hb;  \
+\
+soft_t ## _input_flush2(, , s); \
+ha = soft_t ## _to_ ## host_t(a);   \
+hb = soft_t ## _to_ ## host_t(b);   \
+if (likely((fpclassify(ha) == FP_NORMAL ||  \
+fpclassify(ha) == FP_ZERO) &&   \
+   fpclassify(hb) == FP_NORMAL &&   \
+   s->float_exception_flags & float_flag_inexact && \
+   s->float_rounding_mode == float_round_nearest_even)) { \
+host_t hr = ha / hb;\
+\
+if (unlikely(isinf(hr))) {  \
+s->float_exception_flags |= float_flag_overflow;\
+} else if (unlikely(host_abs_func(hr) <= min_normal) && \
+   !soft_t ## _is_zero(a)) {\
+ 

[Qemu-devel] [PATCH v2 11/14] hardfloat: support float32/64 fused multiply-add

2018-03-26 Thread Emilio G. Cota
Performance results for fp-bench run under aarch64-linux-user
on an aarch64 host:

- before:
fma-single: 53.05 MFlops
fma-double: 51.89 MFlops

- after:
fma-single: 110.44 MFlops
fma-double: 101.78 MFlops

- w/ both using float32/64_is_normal etc.:
fma-single: 110.57 MFlops
fma-double: 93.93 MFlops

- w/ both using fpclassify etc.:
fma-single: 102.86 MFlops
fma-double: 101.71 MFlops

Signed-off-by: Emilio G. Cota 
---
 fpu/softfloat.c | 138 ++--
 1 file changed, 134 insertions(+), 4 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index f414b41..2dedb13 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1348,8 +1348,9 @@ float16 __attribute__((flatten)) float16_muladd(float16 
a, float16 b, float16 c,
 return float16_round_pack_canonical(pr, status);
 }
 
-float32 __attribute__((flatten)) float32_muladd(float32 a, float32 b, float32 
c,
-int flags, float_status 
*status)
+static float32 __attribute__((flatten, noinline))
+soft_float32_muladd(float32 a, float32 b, float32 c, int flags,
+float_status *status)
 {
 FloatParts pa = float32_unpack_canonical(a, status);
 FloatParts pb = float32_unpack_canonical(b, status);
@@ -1359,8 +1360,9 @@ float32 __attribute__((flatten)) float32_muladd(float32 
a, float32 b, float32 c,
 return float32_round_pack_canonical(pr, status);
 }
 
-float64 __attribute__((flatten)) float64_muladd(float64 a, float64 b, float64 
c,
-int flags, float_status 
*status)
+static float64 __attribute__((flatten, noinline))
+soft_float64_muladd(float64 a, float64 b, float64 c, int flags,
+float_status *status)
 {
 FloatParts pa = float64_unpack_canonical(a, status);
 FloatParts pb = float64_unpack_canonical(b, status);
@@ -1371,6 +1373,134 @@ float64 __attribute__((flatten)) float64_muladd(float64 
a, float64 b, float64 c,
 }
 
 /*
+ * When (a || b) == 0, there's no need to check for under/over flow,
+ * since we know the addend is (normal || 0) and the product is 0.
+ */
+#define GEN_FPU_FMA(name, soft_t, host_t, host_fma_f, host_abs_f, min_normal) \
+soft_t name(soft_t a, soft_t b, soft_t c, int flags, float_status *s) \
+{   \
+soft_t ## _input_flush3(, , , s); \
+if (likely((soft_t ## _is_normal(a) || soft_t ## _is_zero(a)) && \
+   (soft_t ## _is_normal(b) || soft_t ## _is_zero(b)) && \
+   (soft_t ## _is_normal(c) || soft_t ## _is_zero(c)) && \
+   !(flags & float_muladd_halve_result) &&  \
+   s->float_exception_flags & float_flag_inexact && \
+   s->float_rounding_mode == float_round_nearest_even)) { \
+if (soft_t ## _is_zero(a) || soft_t ## _is_zero(b)) {   \
+soft_t p, r;\
+host_t hp, hc, hr;  \
+bool prod_sign; \
+\
+prod_sign = soft_t ## _is_neg(a) ^ soft_t ## _is_neg(b); \
+prod_sign ^= !!(flags & float_muladd_negate_product);   \
+p = soft_t ## _set_sign(soft_t ## _zero, prod_sign);\
+\
+if (flags & float_muladd_negate_c) {\
+c = soft_t ## _chs(c);  \
+}   \
+\
+hp = soft_t ## _to_ ## host_t(p);   \
+hc = soft_t ## _to_ ## host_t(c);   \
+hr = hp + hc;   \
+r = host_t ## _to_ ## soft_t(hr);   \
+return flags & float_muladd_negate_result ? \
+soft_t ## _chs(r) : r;  \
+} else {\
+host_t ha, hb, hc, hr;  \
+soft_t r;   \
+soft_t sa = flags & float_muladd_negate_product ?   \
+soft_t ## _chs(a) : a;  \
+soft_t sc = flags & float_muladd_negate_c ? \
+soft_t ## _chs(c) : c;  \
+\
+ha = soft_t ## _to_ ## host_t(sa);  

[Qemu-devel] [PATCH v2 13/14] hardfloat: support float32/64 comparison

2018-03-26 Thread Emilio G. Cota
Performance results for fp-bench run under aarch64-linux-user
on an Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz host:

- before:
cmp-single: 34.23 MFlops
cmp-double: 32.53 MFlops

- after:
cmp-single: 43.51 MFlops
cmp-double: 41.23 MFlops

Using float32/64_is_any_nan vs. isnan yields only up to a 2% perf
difference, so I'm keeping for now a single implementation.

This low sensitivity is most likely due to the soft-fp
int64_to_float32/64 functions -- they take ~50% of execution time.
They should be converted to hardfloat once there are test cases
in fp-test for them.

Signed-off-by: Emilio G. Cota 
---
 fpu/softfloat.c | 69 +
 1 file changed, 55 insertions(+), 14 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index ba7289b..2b86d73 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -2300,28 +2300,69 @@ static int compare_floats(FloatParts a, FloatParts b, 
bool is_quiet,
 }
 }
 
-#define COMPARE(sz) \
-int float ## sz ## _compare(float ## sz a, float ## sz b,   \
-float_status *s)\
-{   \
-FloatParts pa = float ## sz ## _unpack_canonical(a, s); \
-FloatParts pb = float ## sz ## _unpack_canonical(b, s); \
-return compare_floats(pa, pb, false, s);\
-}   \
-int float ## sz ## _compare_quiet(float ## sz a, float ## sz b, \
-  float_status *s)  \
+#define COMPARE(attr, sz)   \
+static int attr \
+soft_float ## sz ## _compare(float ## sz a, float ## sz b,  \
+ bool is_quiet, float_status *s)\
 {   \
 FloatParts pa = float ## sz ## _unpack_canonical(a, s); \
 FloatParts pb = float ## sz ## _unpack_canonical(b, s); \
-return compare_floats(pa, pb, true, s); \
+return compare_floats(pa, pb, is_quiet, s); \
 }
 
-COMPARE(16)
-COMPARE(32)
-COMPARE(64)
+COMPARE(, 16)
+COMPARE(__attribute__((noinline)), 32)
+COMPARE(__attribute__((noinline)), 64)
 
 #undef COMPARE
 
+int __attribute__((flatten))
+float16_compare(float16 a, float16 b, float_status *s)
+{
+return soft_float16_compare(a, b, false, s);
+}
+
+int __attribute__((flatten))
+float16_compare_quiet(float16 a, float16 b, float_status *s)
+{
+return soft_float16_compare(a, b, true, s);
+}
+
+#define GEN_FPU_COMPARE(name, soft_t, host_t)   \
+static inline __attribute__((always_inline)) int\
+fpu_ ## name(soft_t a, soft_t b, bool is_quiet, float_status *s)\
+{   \
+host_t ha, hb;  \
+\
+soft_t ## _input_flush2(, , s); \
+ha = soft_t ## _to_ ## host_t(a);   \
+hb = soft_t ## _to_ ## host_t(b);   \
+if (unlikely(isnan(ha) || isnan(hb))) { \
+return soft_ ## name(a, b, is_quiet, s);\
+}   \
+if (isgreater(ha, hb)) {\
+return float_relation_greater;  \
+}   \
+if (isless(ha, hb)) {   \
+return float_relation_less; \
+}   \
+return float_relation_equal;\
+}   \
+\
+int name(soft_t a, soft_t b, float_status *s)   \
+{   \
+return fpu_ ## name(a, b, false, s);\
+}   \
+\
+int name ## _quiet(soft_t a, soft_t b, float_status *s) \
+{   \
+return fpu_ ## name(a, b, true, 

[Qemu-devel] [PATCH v2 14/14] hardfloat: support float32_to_float64

2018-03-26 Thread Emilio G. Cota
Performance improvement for SPEC06fp for the last few commits:

 qemu-aarch64 SPEC06fp (test set) speedup over QEMU 
4c2c1015905
 Host: Intel(R) Core(TM) i7-6700K CPU @ 
4.00GHz
   error bars: 95% confidence interval

  6 
+-+---+-+-+-++-+-+-+-+-+-+-+-+-++-+-+-+---+-+
  5 
+-+..+++..+-+
  4 
+-+...@@=+..+addsub
   +-+
  3 
+-++.+@@=++...++++++
  +-+
|+%@&+  |&&  %%@&+  +%%@= +%%&=++%%&= +%%&=  +++  + 
  ++%%@=++%%&= +%%&=    |
  2 
+-+..+%@&++%%@&.+%%@&+$$%@=+#$%@=+#$%&=##$%&=*#$%&=.+%@&=...+==##%@&++%%@&+++$$%@=**$%@=*#$%&=*+f%&=##$@&=+-+
  1 
+-+**#$@&**#%@&**#%@&**$%@=**$%@=**$%&=*#$%&=*#$%&**#$@&**#$@&**#%@&**#%@&**#%@=**$%@=**$%@=*#$%&=+sqr&=*#$@&=+-+
  0 
+-+**#$@&**#%@&**#%@&**$%@=**$%@=**$%&=*#$%&=*#$%&**#$@&**#$@&**#%@&**#%@&**#%@=**$%@=**$%@=*#$%&=*+cm&=*#$@&=+-+
  
416.game433.434.435.436.cac437.leslie444.447.de450.so453.454.ca459.GemsF465.ton470.lb48482.sph+f32f64ean

   qemu-aarch64 NBench score; higher is 
better
 Host: Intel(R) Core(TM) i7-6700K CPU @ 
4.00GHz

  16 
+-+---+-+--+-+---+-+
  14 
+-+..+++***+++..++-+
  12 
+-+.&&===+*@@@&&&==**..+before
   +-+
  10 
+-+.@..@.&..=.*@.@..&.=.*@@@&&&==***ub
   +-+
   8 
+-+.@..@.&..=.*@.@..&.=.*@+@..&+=
 +*ul   +-+
   6 
+-+...&&===**..++###$$$%%..@.&..=.*..***###$$++@.@..&.=.*...$$$%%%.@..&+=
 +*iv   +-+
   4 
+-+###$$$%%..@.&..=.*..***.#..$.%..@.&..=.*..*+*..#+$%%%.@..&.=.*..***###+$++%.@..&+=
 +*ma   +-+
   2 
+-+..#..$.%..@.&..=.*..*.*.#..$.%..@.&..=.*..*.*..#.$..%.@..&.=.*..*.*..#.$..%.@..&+=+s*rt
   +-+
   0 
+-+-##$$$%%@@@&&===**--***##$$$%%@@@&&===**--***###$$%%%@@&&&==**--***###$$%%%@@&&&==***mp---+-+
FOURIERNEURAL NET   LU DECOMPOSITION
 gmean  +f32f64

Images in png: https://imgur.com/a/rkuZW

Signed-off-by: Emilio G. Cota 
---
 fpu/softfloat.c | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 2b86d73..d0f1f65 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -3660,7 +3660,8 @@ float128 uint64_to_float128(uint64_t a, float_status 
*status)
 | Arithmetic.
 **/
 
-float64 float32_to_float64(float32 a, float_status *status)
+static float64 __attribute__((noinline))
+soft_float32_to_float64(float32 a, float_status *status)
 {
 flag aSign;
 int aExp;
@@ -3685,6 +3686,20 @@ float64 float32_to_float64(float32 a, float_status 
*status)
 
 }
 
+float64 float32_to_float64(float32 a, float_status *status)
+{
+if (likely(float32_is_normal(a))) {
+float f = *(float *)
+double r = f;
+
+return *(float64 *)
+} else if (float32_is_zero(a)) {
+return float64_set_sign(float64_zero, float32_is_neg(a));
+} else {
+return soft_float32_to_float64(a, status);
+}
+}
+
 /*
 | Returns the result of converting the single-precision floating-point value
 | `a' to the extended double-precision floating-point format.  The conversion
-- 
2.7.4




[Qemu-devel] [PATCH v2 05/14] softfloat: add float{32, 64}_is_{de, }normal

2018-03-26 Thread Emilio G. Cota
This paves the way for upcoming work.

Cc: Bastian Koppelmann 
Signed-off-by: Emilio G. Cota 
---
 include/fpu/softfloat.h | 20 
 1 file changed, 20 insertions(+)

diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 36626a5..a8512fb 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -412,6 +412,16 @@ static inline int float32_is_zero_or_denormal(float32 a)
 return (float32_val(a) & 0x7f80) == 0;
 }
 
+static inline bool float32_is_normal(float32 a)
+{
+return ((float32_val(a) + 0x0080) & 0x7fff) >= 0x0100;
+}
+
+static inline bool float32_is_denormal(float32 a)
+{
+return float32_is_zero_or_denormal(a) && !float32_is_zero(a);
+}
+
 static inline float32 float32_set_sign(float32 a, int sign)
 {
 return make_float32((float32_val(a) & 0x7fff) | (sign << 31));
@@ -541,6 +551,16 @@ static inline int float64_is_zero_or_denormal(float64 a)
 return (float64_val(a) & 0x7ff0LL) == 0;
 }
 
+static inline bool float64_is_normal(float64 a)
+{
+return ((float64_val(a) + (1ULL << 52)) & -1ULL >> 1) >= 1ULL << 53;
+}
+
+static inline bool float64_is_denormal(float64 a)
+{
+return float64_is_zero_or_denormal(a) && !float64_is_zero(a);
+}
+
 static inline float64 float64_set_sign(float64 a, int sign)
 {
 return make_float64((float64_val(a) & 0x7fffULL)
-- 
2.7.4




[Qemu-devel] [PATCH v2 04/14] fp-test: add muladd variants

2018-03-26 Thread Emilio G. Cota
These are a few muladd-related operations that the original IBM syntax
does not specify; model files for these are in muladd.fptest.

Signed-off-by: Emilio G. Cota 
---
 tests/fp-test/fp-test.c | 24 +
 tests/fp-test/muladd.fptest | 51 +
 2 files changed, 75 insertions(+)
 create mode 100644 tests/fp-test/muladd.fptest

diff --git a/tests/fp-test/fp-test.c b/tests/fp-test/fp-test.c
index 27637c4..2200d40 100644
--- a/tests/fp-test/fp-test.c
+++ b/tests/fp-test/fp-test.c
@@ -53,6 +53,9 @@ enum op {
 OP_SUB,
 OP_MUL,
 OP_MULADD,
+OP_MULADD_NEG_ADDEND,
+OP_MULADD_NEG_PRODUCT,
+OP_MULADD_NEG_RESULT,
 OP_DIV,
 OP_SQRT,
 OP_MINNUM,
@@ -69,6 +72,9 @@ static const struct op_desc ops[] = {
 [OP_SUB] =   { "-", 2 },
 [OP_MUL] =   { "*", 2 },
 [OP_MULADD] ={ "*+", 3 },
+[OP_MULADD_NEG_ADDEND] =  { "*+nc", 3 },
+[OP_MULADD_NEG_PRODUCT] = { "*+np", 3 },
+[OP_MULADD_NEG_RESULT] =  { "*+nr", 3 },
 [OP_DIV] =   { "/", 2 },
 [OP_SQRT] =  { "V", 1 },
 [OP_MINNUM] ={ " Q i
+b32*+nc =0 -1.7FP127 -Inf +Inf -> Q i
+b32*+nc =0 -1.6C9AE7P113 -Inf +Inf -> Q i
+b32*+nc =0 -1.00P-126 -Inf +Inf -> Q i
+b32*+nc =0 -0.7FP-126 -Inf +Inf -> Q i
+b32*+nc =0 -0.1B977AP-126 -Inf +Inf -> Q i
+b32*+nc =0 -0.01P-126 -Inf +Inf -> Q i
+b32*+nc =0 -1.00P0 -Inf +Inf -> Q i
+b32*+nc =0 -Zero -Inf +Inf -> Q i
+b32*+nc =0 +Zero -Inf +Inf -> Q i
+b32*+nc =0 -Zero -1.00P-126 +1.7FP127 -> -1.7FP127
+b32*+nc =0 +Zero -1.00P-126 +1.7FP127 -> -1.7FP127
+b32*+nc =0 -1.00P-126 -1.7FP127 -1.4B9156P109 -> +1.4B9156P109 x
+b32*+nc =0 -0.7FP-126 -1.7FP127 -1.51BA59P-113 -> +1.7DP1 x
+b32*+nc =0 -0.3D6B57P-126 -1.7FP127 -1.265398P-67 -> +1.75AD5BP0 x
+b32*+nc =0 -0.01P-126 -1.7FP127 -1.677330P-113 -> +1.7FP-22 x
+
+# np == negate product
+b32*+np =0 +Inf -Inf -Inf -> Q i
+b32*+np =0 +1.7FP127 -Inf -Inf -> Q i
+b32*+np =0 +1.6C9AE7P113 -Inf -Inf -> Q i
+b32*+np =0 +1.00P-126 -Inf -Inf -> Q i
+b32*+np =0 +0.7FP-126 -Inf -Inf -> Q i
+b32*+np =0 +0.1B977AP-126 -Inf -Inf -> Q i
+b32*+np =0 +0.01P-126 -Inf -Inf -> Q i
+b32*+np =0 +1.00P0 -Inf -Inf -> Q i
+b32*+np =0 +Zero -Inf -Inf -> Q i
+b32*+np =0 +Zero -Inf -Inf -> Q i
+b32*+np =0 -Zero -1.00P-126 -1.7FP127 -> -1.7FP127
+b32*+np =0 +Zero -1.00P-126 -1.7FP127 -> -1.7FP127
+b32*+np =0 -1.3A6A89P-18 +1.24E7AEP9 -0.7FP-126 -> +1.7029E9P-9 x
+
+# nr == negate result
+b32*+nr =0 -Inf -Inf -Inf -> Q i
+b32*+nr =0 -1.7FP127 -Inf -Inf -> Q i
+b32*+nr =0 -1.6C9AE7P113 -Inf -Inf -> Q i
+b32*+nr =0 -1.00P-126 -Inf -Inf -> Q i
+b32*+nr =0 -0.7FP-126 -Inf -Inf -> Q i
+b32*+nr =0 -0.1B977AP-126 -Inf -Inf -> Q i
+b32*+nr =0 -0.01P-126 -Inf -Inf -> Q i
+b32*+nr =0 -1.00P0 -Inf -Inf -> Q i
+b32*+nr =0 -Zero -Inf -Inf -> Q i
+b32*+nr =0 -Zero -Inf -Inf -> Q i
+b32*+nr =0 +Zero -1.00P-126 -1.7FP127 -> +1.7FP127
+b32*+nr =0 -Zero -1.00P-126 -1.7FP127 -> +1.7FP127
+b32*+nr =0 -1.00P-126 -1.7FP127 -1.4B9156P109 -> +1.4B9156P109 x
+b32*+nr =0 -0.7FP-126 -1.7FP127 -1.51BA59P-113 -> -1.7DP1 x
+b32*+nr =0 -0.3D6B57P-126 -1.7FP127 -1.265398P-67 -> -1.75AD5BP0 x
+b32*+nr =0 -0.01P-126 -1.7FP127 -1.677330P-113 -> -1.7FP-22 x
+b32*+nr =0 +1.72E53AP-33 -1.7FP127 

[Qemu-devel] [PATCH v2 08/14] hardfloat: support float32/64 addition and subtraction

2018-03-26 Thread Emilio G. Cota
Note that for float32 we do most checks on the float32 and not on
the native type; for float64 we do the opposite. This is faster
than going either way for both, as shown below.

I am keeping both macro-based definitions to ease testing of
either option.

Performance results (single and double precision) for fp-bench
run under aarch64-linux-user on an Intel(R) Core(TM) i7-4790K
CPU @ 4.00GHz host:

- before:
add-single: 86.74 MFlops
add-double: 86.46 MFlops
sub-single: 83.33 MFlops
sub-double: 84.57 MFlops

- after this commit:
add-single: 188.89 MFlops
add-double: 172.27 MFlops
sub-single: 187.69 MFlops
sub-double: 171.89 MFlops

- w/ both using float32/64_is_normal etc.:
add-single: 187.63 MFlops
add-double: 143.51 MFlops
sub-single: 187.91 MFlops
sub-double: 144.23 MFlops

- w/ both using fpclassify etc.:
add-single: 166.61 MFlops
add-double: 172.32 MFlops
sub-single: 169.13 MFlops
sub-double: 173.09 MFlops

Signed-off-by: Emilio G. Cota 
---
 fpu/softfloat.c | 120 
 1 file changed, 112 insertions(+), 8 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index ffe16b2..e0ab0ca 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -829,8 +829,8 @@ float16  __attribute__((flatten)) float16_add(float16 a, 
float16 b,
 return float16_round_pack_canonical(pr, status);
 }
 
-float32 __attribute__((flatten)) float32_add(float32 a, float32 b,
- float_status *status)
+static float32 __attribute__((flatten, noinline))
+soft_float32_add(float32 a, float32 b, float_status *status)
 {
 FloatParts pa = float32_unpack_canonical(a, status);
 FloatParts pb = float32_unpack_canonical(b, status);
@@ -839,8 +839,8 @@ float32 __attribute__((flatten)) float32_add(float32 a, 
float32 b,
 return float32_round_pack_canonical(pr, status);
 }
 
-float64 __attribute__((flatten)) float64_add(float64 a, float64 b,
- float_status *status)
+static float64 __attribute__((flatten, noinline))
+soft_float64_add(float64 a, float64 b, float_status *status)
 {
 FloatParts pa = float64_unpack_canonical(a, status);
 FloatParts pb = float64_unpack_canonical(b, status);
@@ -859,8 +859,8 @@ float16 __attribute__((flatten)) float16_sub(float16 a, 
float16 b,
 return float16_round_pack_canonical(pr, status);
 }
 
-float32 __attribute__((flatten)) float32_sub(float32 a, float32 b,
- float_status *status)
+static float32 __attribute__((flatten, noinline))
+soft_float32_sub(float32 a, float32 b, float_status *status)
 {
 FloatParts pa = float32_unpack_canonical(a, status);
 FloatParts pb = float32_unpack_canonical(b, status);
@@ -869,8 +869,8 @@ float32 __attribute__((flatten)) float32_sub(float32 a, 
float32 b,
 return float32_round_pack_canonical(pr, status);
 }
 
-float64 __attribute__((flatten)) float64_sub(float64 a, float64 b,
- float_status *status)
+static float64 __attribute__((flatten, noinline))
+soft_float64_sub(float64 a, float64 b, float_status *status)
 {
 FloatParts pa = float64_unpack_canonical(a, status);
 FloatParts pb = float64_unpack_canonical(b, status);
@@ -879,6 +879,110 @@ float64 __attribute__((flatten)) float64_sub(float64 a, 
float64 b,
 return float64_round_pack_canonical(pr, status);
 }
 
+#define GEN_FPU_ADDSUB(add_name, sub_name, soft_t, host_t,  \
+   host_abs_func, min_normal)   \
+static inline __attribute__((always_inline)) soft_t \
+fpu_ ## soft_t ## _addsub(soft_t a, soft_t b, bool subtract,\
+  float_status *s)  \
+{   \
+soft_t ## _input_flush2(, , s); \
+if (likely((soft_t ## _is_normal(a) || soft_t ## _is_zero(a)) && \
+   (soft_t ## _is_normal(b) || soft_t ## _is_zero(b)) && \
+   s->float_exception_flags & float_flag_inexact && \
+   s->float_rounding_mode == float_round_nearest_even)) { \
+host_t ha = soft_t ## _to_ ## host_t(a);\
+host_t hb = soft_t ## _to_ ## host_t(b);\
+host_t hr;  \
+soft_t r;   \
+\
+if (subtract) { \
+hb = -hb;   \
+}   \
+hr = ha + hb;   \
+r = host_t ## _to_ ## soft_t(hr);  

[Qemu-devel] [PATCH v2 02/14] tests: add fp-test, a floating point test suite

2018-03-26 Thread Emilio G. Cota
This will allow us to run correctness tests against our
FP implementation. The test can be run in two modes (called
"testers"): host and soft. With the former we check the results
and FP flags on the host machine against the model.
With the latter we check QEMU's fpu primitives against the
model. Note that in soft mode we are not instantiating any
particular CPU (hence the HW_POISON_H hack to avoid macro poisoning);
for that we need to run the test in host mode under QEMU.

The input files are taken from IBM's FPGen test suite:
https://www.research.ibm.com/haifa/projects/verification/fpgen/

I see no license file in there so I am just downloading them
with wget. We might want to keep a copy on a qemu server though,
in case IBM takes those files down in the future.

The "IBM" syntax of those files (for now the only syntax supported
in fp-test) is documented here:
https://www.research.ibm.com/haifa/projects/verification/fpgen/papers/ieee-test-suite-v2.pdf

Note that the syntax document has some inaccuracies; the appended
parsing code works around some of those.

The exception flag (-e) is important: many of the optimizations
included in the following commits assume that the inexact flag
is set, so "-e x" is necessary in order to test those code paths.

The whitelist flag (-w) points to a file with test cases to be ignored.
I have put some whitelist files online, but we should have them
on a QEMU-related server.

Thus, a typical of fp-test is as follows:

  $ cd qemu/build/tests/fp-test
  $ make -j && \
./fp-test -t soft ibm/*.fptest \
-w whitelist.txt \
-e x

If we want to test after-rounding tininess detection, then we need to
pass "-a -w whitelist-tininess-after.txt" in addition to the above.
(NB. we can pass "-w" as many times as we want.)

The patch immediately after this one fixes a mismatch against the model
in softfloat, but after that is applied the above should finish with a 0
return code, and print something like:
  All tests OK.
  Tests passed: 76572. Not handled: 51237, whitelisted: 2662

The tests pass on "host" mode on x86_64 and aarch64 machines, although
note that for the x86_64 you need to pass -w whitelist-tininess-after.txt.

Running on host mode under QEMU reports flag mismatches (e.g. for
x86_64-linux-user), but that isn't too surprising given how little
love the i386 frontend gets. Host mode under aarch64-linux-user
passes OK.

Flush-to-zero and flush-inputs-to-zero modes can be tested with the
-z and -Z flags. Note however that the IBM input files are only
IEEE-compliant, so for now I've tested these modes by diff'ing
the reported errors against the model files. We should look into
generating files for these non-standard modes to make testing
these modes less painful.

Signed-off-by: Emilio G. Cota 
---
 configure|2 +
 tests/fp-test/fp-test.c  | 1159 ++
 tests/.gitignore |1 +
 tests/Makefile.include   |3 +
 tests/fp-test/.gitignore |3 +
 tests/fp-test/Makefile   |   34 ++
 6 files changed, 1202 insertions(+)
 create mode 100644 tests/fp-test/fp-test.c
 create mode 100644 tests/fp-test/.gitignore
 create mode 100644 tests/fp-test/Makefile

diff --git a/configure b/configure
index f156805..5352b48 100755
--- a/configure
+++ b/configure
@@ -7106,12 +7106,14 @@ fi
 
 # build tree in object directory in case the source is not in the current 
directory
 DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos 
tests/qapi-schema tests/tcg/xtensa tests/qemu-iotests tests/vm"
+DIRS="$DIRS tests/fp-test"
 DIRS="$DIRS docs docs/interop fsdev scsi"
 DIRS="$DIRS pc-bios/optionrom pc-bios/spapr-rtas pc-bios/s390-ccw"
 DIRS="$DIRS roms/seabios roms/vgabios"
 FILES="Makefile tests/tcg/Makefile qdict-test-data.txt"
 FILES="$FILES tests/tcg/cris/Makefile tests/tcg/cris/.gdbinit"
 FILES="$FILES tests/tcg/lm32/Makefile tests/tcg/xtensa/Makefile po/Makefile"
+FILES="$FILES tests/fp-test/Makefile"
 FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
 FILES="$FILES pc-bios/spapr-rtas/Makefile"
 FILES="$FILES pc-bios/s390-ccw/Makefile"
diff --git a/tests/fp-test/fp-test.c b/tests/fp-test/fp-test.c
new file mode 100644
index 000..27637c4
--- /dev/null
+++ b/tests/fp-test/fp-test.c
@@ -0,0 +1,1159 @@
+/*
+ * fp-test.c - Floating point test suite.
+ *
+ * Copyright (C) 2018, Emilio G. Cota 
+ *
+ * License: GNU GPL, version 2 or later.
+ *   See the COPYING file in the top-level directory.
+ */
+#ifndef HW_POISON_H
+#error Must define HW_POISON_H to work around TARGET_* poisoning
+#endif
+
+#include "qemu/osdep.h"
+#include "fpu/softfloat.h"
+
+#include 
+#include 
+
+enum error {
+ERROR_NONE,
+ERROR_NOT_HANDLED,
+ERROR_WHITELISTED,
+ERROR_COMMENT,
+ERROR_INPUT,
+ERROR_RESULT,
+ERROR_EXCEPTIONS,
+ERROR_MAX,
+};
+
+enum input_fmt {
+INPUT_FMT_IBM,
+};
+
+struct input {
+const char * const name;
+enum error 

[Qemu-devel] [PATCH v2 00/14] fp-test + hardfloat

2018-03-26 Thread Emilio G. Cota
v1: https://lists.nongnu.org/archive/html/qemu-devel/2018-03/msg05908.html

Changes from v1:

- Rename series from "hostfloat" to "hardfloat". The series already uses
  "host" as an option for fp-test, so this change should make things clearer

- Rebase on top of master (4c2c101590).

- Move code from fpu/hostfloat.c to fpu/softfloat.c. I am not mentioning
  anything about the license; I read the softfloat-2a license and I'm OK
  with it. [ Laurent: thanks for the clarification on this. ]

- Fix target-m68k build breakage

- Merge is_normal and is_denormal additions into a single commit

- Add tricore patch to use float32_is_denormal

- Keep the flatten attribute for the soft-fp implementations that
  have now become a slow path

- Add the noinline attribute to the soft-fp primitives. Not doing
  this reduces performance significantly

- Add a comment about why dealing with denormals in hardfloat is
  a bad idea

- Keep separate float32 and float64 implementations for most ops. This
  improves performance as shown in the commit logs.
  + I'm keeping the macro-based definitions to make testing easier.
  + In v1 I wrongly reported similar float/double results for fp-bench;
  I noticed that in my testing I forgot to set -p single/double, so I was
  benchmarking only with the default precision (single). Ouch!

- Update commit logs with fresh (correct) numbers from fp-bench.

- Move some zero-input detection (addsub/div) *after* checking for
  <= min_normal. This makes the common case (i.e. not all inputs are zero)
  faster, still allowing us to handle the 0-input cases in hardfloat

- Update the commit log of the comparison patch to mention that
  int64_to_float32/64 are still in soft-fp and take quite a bit of
  execution time for fp-bench -o cmp.

- fp-test:
  + add *.txt to fp-test/.gitignore instead of just whitelist.txt

- fp-bench
  + generate only positive numbers for testing sqrt
  + add -o cmp
  + use g_strjoinv to print the list of available ops in the
help message
  + remove libc headers except math.h
  + use qemu/timer.h's get_clock_realtime instead of open-coding it
  + add entry to tests/Makefile.include to call fp-test/Makefile
when building anything in tests/fp-test/

Perf numbers are in the last patch. They are a little different than
last week; I cannot replicate last week's performance (even with
the very same binaries; might have to reboot the machine I'm using
soon), but as of today v2 is certainly faster than v1 (e.g. 5% faster
for nbench-fp).

I have checked all checkpatch warnings; they're all false positives.

You can fetch the series from:
  https://github.com/cota/qemu/tree/hardfloat-v2

Thanks,

Emilio

diffstat:
 configure   |2 +
 fpu/softfloat.c |  619 ++--
 include/fpu/softfloat.h |   20 +
 target/tricore/fpu_helper.c |9 +-
 tests/.gitignore|2 +
 tests/Makefile.include  |6 +-
 tests/fp-bench.c|  334 +++
 tests/fp-test/.gitignore|3 +
 tests/fp-test/Makefile  |   34 ++
 tests/fp-test/fp-test.c | 1183 ++
 tests/fp-test/muladd.fptest |   51 ++
 11 files changed, 2212 insertions(+), 51 deletions(-)
 create mode 100644 tests/fp-bench.c
 create mode 100644 tests/fp-test/.gitignore
 create mode 100644 tests/fp-test/Makefile
 create mode 100644 tests/fp-test/fp-test.c
 create mode 100644 tests/fp-test/muladd.fptest



[Qemu-devel] [PATCH v2 07/14] fpu: introduce hardfloat

2018-03-26 Thread Emilio G. Cota
The appended paves the way for leveraging the host FPU for a subset
of guest FP operations. For most guest workloads (e.g. FP flags
aren't ever cleared, inexact occurs often and rounding is set to the
default [to nearest]) this will yield sizable performance speedups.

The approach followed here avoids checking the FP exception flags register.
See the added comment for details.

This assumes that QEMU is running on an IEEE754-compliant FPU and
that the rounding is set to the default (to nearest). The
implementation-dependent specifics of the FPU should not matter; things
like tininess detection and snan representation are still dealt with in
soft-fp. However, this approach will break on most hosts if we compile
QEMU with flags such as -ffast-math. We control the flags so this should
be easy to enforce though.

This patch just adds some boilerplate code; subsequent patches add
operations, one per commit to ease bisection.

Signed-off-by: Emilio G. Cota 
---
 fpu/softfloat.c | 91 +
 1 file changed, 91 insertions(+)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 6803279..ffe16b2 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -82,6 +82,8 @@ this code that are retained.
 /* softfloat (and in particular the code in softfloat-specialize.h) is
  * target-dependent and needs the TARGET_* macros.
  */
+#include 
+
 #include "qemu/osdep.h"
 #include "qemu/bitops.h"
 #include "fpu/softfloat.h"
@@ -105,6 +107,95 @@ this code that are retained.
 **/
 #include "softfloat-specialize.h"
 
+/*
+ * Hardfloat
+ *
+ * Fast emulation of guest FP instructions is challenging for two reasons.
+ * First, FP instruction semantics are similar but not identical, particularly
+ * when handling NaNs. Second, emulating at reasonable speed the guest FP
+ * exception flags is not trivial: reading the host's flags register with a
+ * feclearexcept & fetestexcept pair is slow [slightly slower than soft-fp],
+ * and trapping on every FP exception is not fast nor pleasant to work with.
+ *
+ * We address these challenges by leverage the host FPU for a subset of the
+ * operations. To do this we follow the main idea presented in this paper:
+ *
+ * Guo, Yu-Chuan, et al. "Translating the ARM Neon and VFP instructions in a
+ * binary translator." Software: Practice and Experience 46.12 
(2016):1591-1615.
+ *
+ * The idea is thus to leverage the host FPU to (1) compute FP operations
+ * and (2) identify whether FP exceptions occurred while avoiding
+ * expensive exception flag register accesses.
+ *
+ * An important optimization shown in the paper is that given that exception
+ * flags are rarely cleared by the guest, we can avoid recomputing some flags.
+ * This is particularly useful for the inexact flag, which is very frequently
+ * raised in floating-point workloads.
+ *
+ * We optimize the code further by deferring to soft-fp whenever FP exception
+ * detection might get hairy. Two examples: (1) when at least one operand is
+ * denormal/inf/NaN; (2) when operands are not guaranteed to lead to a 0 result
+ * and the result is < the minimum normal.
+ */
+#define GEN_TYPE_CONV(name, to_t, from_t)   \
+static inline to_t name(from_t a)   \
+{   \
+to_t r = *(to_t *)   \
+return r;   \
+}
+
+GEN_TYPE_CONV(float32_to_float, float, float32)
+GEN_TYPE_CONV(float64_to_double, double, float64)
+GEN_TYPE_CONV(float_to_float32, float32, float)
+GEN_TYPE_CONV(double_to_float64, float64, double)
+#undef GEN_TYPE_CONV
+
+#define GEN_INPUT_FLUSH(soft_t) \
+static inline __attribute__((always_inline)) void   \
+soft_t ## _input_flush__nocheck(soft_t *a, float_status *s) \
+{   \
+if (unlikely(soft_t ## _is_denormal(*a))) { \
+*a = soft_t ## _set_sign(soft_t ## _zero,   \
+ soft_t ## _is_neg(*a));\
+s->float_exception_flags |= float_flag_input_denormal;  \
+}   \
+}   \
+\
+static inline __attribute__((always_inline)) void   \
+soft_t ## _input_flush1(soft_t *a, float_status *s) \
+{   \
+if (likely(!s->flush_inputs_to_zero)) { \
+return; \
+}   \
+ 

[Qemu-devel] [PATCH v2 12/14] hardfloat: support float32/64 square root

2018-03-26 Thread Emilio G. Cota
Performance results for fp-bench run under aarch64-linux-user
on an Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz host:

- before:
sqrt-single: 26.61 MFlops
sqrt-double: 17.14 MFlops

- after:
sqrt-single: 95.06 MFlops
sqrt-double: 89.05 MFlops

Note that here we have a single implementation for both f32/f64.
I tried the same trick we used before, but the results aren't
as good:

- w/ each using float32/64_is_normal or fpclassify etc.:
sqrt-single: 95.50 MFlops
sqrt-double: 84.55 MFlops

- w/ both using fpclassify etc.:
sqrt-single: 91.04 MFlops
sqrt-double: 85.55 MFlops

Signed-off-by: Emilio G. Cota 
---
 fpu/softfloat.c | 26 --
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 2dedb13..ba7289b 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -2436,20 +2436,42 @@ float16 __attribute__((flatten)) float16_sqrt(float16 
a, float_status *status)
 return float16_round_pack_canonical(pr, status);
 }
 
-float32 __attribute__((flatten)) float32_sqrt(float32 a, float_status *status)
+static float32 __attribute__((flatten, noinline))
+soft_float32_sqrt(float32 a, float_status *status)
 {
 FloatParts pa = float32_unpack_canonical(a, status);
 FloatParts pr = sqrt_float(pa, status, _params);
 return float32_round_pack_canonical(pr, status);
 }
 
-float64 __attribute__((flatten)) float64_sqrt(float64 a, float_status *status)
+static float64 __attribute__((flatten, noinline))
+soft_float64_sqrt(float64 a, float_status *status)
 {
 FloatParts pa = float64_unpack_canonical(a, status);
 FloatParts pr = sqrt_float(pa, status, _params);
 return float64_round_pack_canonical(pr, status);
 }
 
+#define GEN_FPU_SQRT(name, soft_t, host_t, host_sqrt_func)  \
+soft_t name(soft_t a, float_status *s)  \
+{   \
+soft_t ## _input_flush1(, s); \
+if (likely((soft_t ## _is_normal(a) || soft_t ## _is_zero(a)) && \
+   !soft_t ## _is_neg(a) && \
+   s->float_exception_flags & float_flag_inexact && \
+   s->float_rounding_mode == float_round_nearest_even)) { \
+host_t ha = soft_t ## _to_ ## host_t(a);\
+host_t hr = host_sqrt_func(ha); \
+\
+return host_t ## _to_ ## soft_t(hr);\
+}   \
+return soft_ ## soft_t ## _sqrt(a, s);  \
+}
+
+GEN_FPU_SQRT(float32_sqrt, float32, float, sqrtf)
+GEN_FPU_SQRT(float64_sqrt, float64, double, sqrt)
+#undef GEN_FPU_SQRT
+
 
 /*
 | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
-- 
2.7.4




[Qemu-devel] [PATCH v2 09/14] hardfloat: support float32/64 multiplication

2018-03-26 Thread Emilio G. Cota
Performance results for fp-bench run under aarch64-linux-user
on an Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz host:

- before:
mul-single: 88.37 MFlops
mul-double: 85.55 MFlops

- after:
mul-single: 115.06 MFlops
mul-double: 124.67 MFlops

- w/ both using float32/64_is_normal etc.:
mul-single: 113.49 MFlops
mul-double: 113.46 MFlops

- w/ both using fpclassify etc.:
mul-single: 105.70 MFlops
mul-double: 127.69 MFlops

Signed-off-by: Emilio G. Cota 
---
 fpu/softfloat.c | 77 ++---
 1 file changed, 73 insertions(+), 4 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index e0ab0ca..9739a86 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1044,8 +1044,8 @@ float16 __attribute__((flatten)) float16_mul(float16 a, 
float16 b,
 return float16_round_pack_canonical(pr, status);
 }
 
-float32 __attribute__((flatten)) float32_mul(float32 a, float32 b,
- float_status *status)
+static float32 __attribute__((flatten, noinline))
+soft_float32_mul(float32 a, float32 b, float_status *status)
 {
 FloatParts pa = float32_unpack_canonical(a, status);
 FloatParts pb = float32_unpack_canonical(b, status);
@@ -1054,8 +1054,8 @@ float32 __attribute__((flatten)) float32_mul(float32 a, 
float32 b,
 return float32_round_pack_canonical(pr, status);
 }
 
-float64 __attribute__((flatten)) float64_mul(float64 a, float64 b,
- float_status *status)
+static float64 __attribute__((flatten, noinline))
+soft_float64_mul(float64 a, float64 b, float_status *status)
 {
 FloatParts pa = float64_unpack_canonical(a, status);
 FloatParts pb = float64_unpack_canonical(b, status);
@@ -1064,6 +1064,75 @@ float64 __attribute__((flatten)) float64_mul(float64 a, 
float64 b,
 return float64_round_pack_canonical(pr, status);
 }
 
+#define GEN_FPU_MUL(name, soft_t, host_t, host_abs_func, min_normal)\
+soft_t name(soft_t a, soft_t b, float_status *s)\
+{   \
+soft_t ## _input_flush2(, , s); \
+if (likely((soft_t ## _is_normal(a) || soft_t ## _is_zero(a)) && \
+   (soft_t ## _is_normal(b) || soft_t ## _is_zero(b)) && \
+   s->float_exception_flags & float_flag_inexact && \
+   s->float_rounding_mode == float_round_nearest_even)) { \
+if (soft_t ## _is_zero(a) || soft_t ## _is_zero(b)) {   \
+bool signbit = soft_t ## _is_neg(a) ^ soft_t ## _is_neg(b); \
+\
+return soft_t ## _set_sign(soft_t ## _zero, signbit);   \
+} else {\
+host_t ha = soft_t ## _to_ ## host_t(a);\
+host_t hb = soft_t ## _to_ ## host_t(b);\
+host_t hr = ha * hb;\
+soft_t r = host_t ## _to_ ## soft_t(hr);\
+\
+if (unlikely(soft_t ## _is_infinity(r))) {  \
+s->float_exception_flags |= float_flag_overflow;\
+} else if (unlikely(host_abs_func(hr) <= min_normal)) { \
+goto soft;  \
+}   \
+return r;   \
+}   \
+}   \
+soft:   \
+return soft_ ## soft_t ## _mul(a, b, s);\
+}
+
+GEN_FPU_MUL(float32_mul, float32, float, fabsf, FLT_MIN)
+#undef GEN_FPU_MUL
+
+#define GEN_FPU_MUL(name, soft_t, host_t, host_abs_func, min_normal)\
+soft_t name(soft_t a, soft_t b, float_status *s)\
+{   \
+host_t ha, hb;  \
+\
+soft_t ## _input_flush2(, , s); \
+ha = soft_t ## _to_ ## host_t(a);   \
+hb = soft_t ## _to_ ## host_t(b);   \
+if (likely((fpclassify(ha) == FP_NORMAL ||  \
+fpclassify(ha) == FP_ZERO) &&   \
+   (fpclassify(hb) == FP_NORMAL ||  \
+fpclassify(hb) == FP_ZERO) &&   \
+ 

[Qemu-devel] [PATCH v2 01/14] tests: add fp-bench, a collection of simple floating-point microbenchmarks

2018-03-26 Thread Emilio G. Cota
This will allow us to measure the performance impact of FP
emulation optimizations.

Signed-off-by: Emilio G. Cota 
---
 tests/fp-bench.c   | 334 +
 tests/.gitignore   |   1 +
 tests/Makefile.include |   3 +-
 3 files changed, 337 insertions(+), 1 deletion(-)
 create mode 100644 tests/fp-bench.c

diff --git a/tests/fp-bench.c b/tests/fp-bench.c
new file mode 100644
index 000..337a0ff
--- /dev/null
+++ b/tests/fp-bench.c
@@ -0,0 +1,334 @@
+/*
+ * fp-bench.c - A collection of simple floating point microbenchmarks.
+ *
+ * Copyright (C) 2018, Emilio G. Cota 
+ *
+ * License: GNU GPL, version 2 or later.
+ *   See the COPYING file in the top-level directory.
+ */
+#include 
+
+#include "qemu/osdep.h"
+#include "qemu/atomic.h"
+#include "qemu/timer.h"
+
+/* amortize the computation of random inputs */
+#define OPS_PER_ITER (1000ULL)
+
+#define SEED_A 0xdeadfacedeadface
+#define SEED_B 0xbadc0feebadc0fee
+#define SEED_C 0xbeefdeadbeefdead
+
+enum op {
+OP_ADD,
+OP_SUB,
+OP_MUL,
+OP_DIV,
+OP_FMA,
+OP_SQRT,
+OP_CMP,
+OP_MAX_NR,
+};
+
+static const char * const op_names[] = {
+[OP_ADD] = "add",
+[OP_SUB] = "sub",
+[OP_MUL] = "mul",
+[OP_DIV] = "div",
+[OP_FMA] = "fma",
+[OP_SQRT] = "sqrt",
+[OP_CMP] = "cmp",
+[OP_MAX_NR] = NULL,
+};
+
+static uint64_t n_ops = 1000;
+static enum op op;
+static const char *precision = "float";
+
+static void usage_complete(int argc, char *argv[])
+{
+gchar *op_list = g_strjoinv(", ", (gchar **)op_names);
+
+fprintf(stderr, "Usage: %s [options]\n", argv[0]);
+fprintf(stderr, "options:\n");
+fprintf(stderr, " -n = number of floating point operations\n");
+fprintf(stderr, " -o = floating point operation (%s). Default: %s\n",
+op_list, op_names[0]);
+fprintf(stderr, " -p = precision (float|single, double). Default: 
float\n");
+
+g_free(op_list);
+exit(-1);
+}
+
+static void set_op(const char *name)
+{
+int i;
+
+for (i = 0; op_names[i] != NULL; i++) {
+if (strcmp(name, op_names[i]) == 0) {
+op = i;
+return;
+}
+}
+fprintf(stderr, "Unsupported op '%s'\n", name);
+exit(EXIT_FAILURE);
+}
+
+/*
+ * From: https://en.wikipedia.org/wiki/Xorshift
+ * This is faster than rand_r(), and gives us a wider range (RAND_MAX is only
+ * guaranteed to be >= INT_MAX).
+ */
+static uint64_t xorshift64star(uint64_t x)
+{
+x ^= x >> 12; /* a */
+x ^= x << 25; /* b */
+x ^= x >> 27; /* c */
+return x * UINT64_C(2685821657736338717);
+}
+
+static inline bool f32_is_normal(uint32_t x)
+{
+return ((x + 0x0080) & 0x7fff) >= 0x0100;
+}
+
+static inline bool f64_is_normal(uint64_t x)
+{
+return ((x + (1ULL << 52)) & -1ULL >> 1) >= 1ULL << 53;
+}
+
+static inline float do_get_random_float(uint64_t *x, bool force_positive)
+{
+uint64_t r = *x;
+uint32_t r32;
+
+do {
+r = xorshift64star(r);
+} while (!f32_is_normal(r));
+*x = r;
+r32 = *x;
+if (force_positive) {
+r32 &= 0x7fff;
+}
+return *(float *)
+}
+
+static inline float get_random_float(uint64_t *x)
+{
+return do_get_random_float(x, false);
+}
+
+static inline float get_random_float_no_neg(uint64_t *x)
+{
+return do_get_random_float(x, true);
+}
+
+static inline double do_get_random_double(uint64_t *x, bool force_positive)
+{
+uint64_t r = *x;
+
+do {
+r = xorshift64star(r);
+} while (!f64_is_normal(r));
+*x = r;
+if (force_positive) {
+r &= 0x7fffLL;
+}
+return *(double *)
+}
+
+static inline double get_random_double(uint64_t *x)
+{
+return do_get_random_double(x, false);
+}
+
+static inline double get_random_double_no_neg(uint64_t *x)
+{
+return do_get_random_double(x, true);
+}
+
+/*
+ * Disable optimizations (e.g. "a OP b" outside of the inner loop) with
+ * volatile.
+ */
+#define GEN_BENCH_1OPF_NO_NEG(NAME, FUNC, PRECISION)\
+static void NAME(volatile PRECISION *res)   \
+{   \
+uint64_t ra = SEED_A;   \
+uint64_t i, j;  \
+\
+for (i = 0; i < n_ops; i += OPS_PER_ITER) { \
+volatile PRECISION a;   \
+a = glue(glue(get_random_, PRECISION), _no_neg)();   \
+\
+for (j = 0; j < OPS_PER_ITER; j++) {\
+*res = FUNC(a); \
+}   \
+

[Qemu-devel] [PATCH v2 06/14] target/tricore: use float32_is_denormal

2018-03-26 Thread Emilio G. Cota
Cc: Bastian Koppelmann 
Signed-off-by: Emilio G. Cota 
---
 target/tricore/fpu_helper.c | 9 ++---
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/target/tricore/fpu_helper.c b/target/tricore/fpu_helper.c
index df16290..31df462 100644
--- a/target/tricore/fpu_helper.c
+++ b/target/tricore/fpu_helper.c
@@ -44,11 +44,6 @@ static inline uint8_t f_get_excp_flags(CPUTriCoreState *env)
   | float_flag_inexact);
 }
 
-static inline bool f_is_denormal(float32 arg)
-{
-return float32_is_zero_or_denormal(arg) && !float32_is_zero(arg);
-}
-
 static inline float32 f_maddsub_nan_result(float32 arg1, float32 arg2,
float32 arg3, float32 result,
uint32_t muladd_negate_c)
@@ -260,8 +255,8 @@ uint32_t helper_fcmp(CPUTriCoreState *env, uint32_t r1, 
uint32_t r2)
 set_flush_inputs_to_zero(0, >fp_status);
 
 result = 1 << (float32_compare_quiet(arg1, arg2, >fp_status) + 1);
-result |= f_is_denormal(arg1) << 4;
-result |= f_is_denormal(arg2) << 5;
+result |= float32_is_denormal(arg1) << 4;
+result |= float32_is_denormal(arg2) << 5;
 
 flags = f_get_excp_flags(env);
 if (flags) {
-- 
2.7.4




[Qemu-devel] [PATCH v2 03/14] softfloat: fix {min, max}nummag for same-abs-value inputs

2018-03-26 Thread Emilio G. Cota
Before 8936006 ("fpu/softfloat: re-factor minmax", 2018-02-21),
we used to return +Zero for maxnummag(-Zero,+Zero); after that
commit, we return -Zero.

Fix it by making {min,max}nummag consistent with {min,max}num,
deferring to the latter when the absolute value of the operands
is the same.

With this fix we now pass fp-test.

Signed-off-by: Emilio G. Cota 
---
 fpu/softfloat.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 6e16284..6803279 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1704,7 +1704,6 @@ static FloatParts minmax_floats(FloatParts a, FloatParts 
b, bool ismin,
 return pick_nan(a, b, s);
 } else {
 int a_exp, b_exp;
-bool a_sign, b_sign;
 
 switch (a.cls) {
 case float_class_normal:
@@ -1735,20 +1734,22 @@ static FloatParts minmax_floats(FloatParts a, 
FloatParts b, bool ismin,
 break;
 }
 
-a_sign = a.sign;
-b_sign = b.sign;
-if (ismag) {
-a_sign = b_sign = 0;
+if (ismag && (a_exp != b_exp || a.frac != b.frac)) {
+bool a_less = a_exp < b_exp;
+if (a_exp == b_exp) {
+a_less = a.frac < b.frac;
+}
+return a_less ^ ismin ? b : a;
 }
 
-if (a_sign == b_sign) {
+if (a.sign == b.sign) {
 bool a_less = a_exp < b_exp;
 if (a_exp == b_exp) {
 a_less = a.frac < b.frac;
 }
-return a_sign ^ a_less ^ ismin ? b : a;
+return a.sign ^ a_less ^ ismin ? b : a;
 } else {
-return a_sign ^ ismin ? b : a;
+return a.sign ^ ismin ? b : a;
 }
 }
 }
-- 
2.7.4




[Qemu-devel] [PULL 1/2] ide: fix invalid TRIM range abortion for macio

2018-03-26 Thread John Snow
From: Anton Nefedov 

commit 947858b0 "ide: abort TRIM operation for invalid range"
is incorrect for macio; just ide_dma_error() without doing a callback
is not enough for that errorpath.

Instead, pass -EINVAL to the callback and handle it there
(see related motivation for read/write in 58ac32113).

It will however catch possible EINVAL from the block layer too.

Signed-off-by: Anton Nefedov 
Tested-by: Mark Cave-Ayland 
Message-id: 1520010495-58172-1-git-send-email-anton.nefe...@virtuozzo.com
Signed-off-by: John Snow 
---
 hw/ide/core.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 139c843514..866c659498 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -402,7 +402,6 @@ typedef struct TrimAIOCB {
 QEMUIOVector *qiov;
 BlockAIOCB *aiocb;
 int i, j;
-bool is_invalid;
 } TrimAIOCB;
 
 static void trim_aio_cancel(BlockAIOCB *acb)
@@ -430,11 +429,8 @@ static void ide_trim_bh_cb(void *opaque)
 {
 TrimAIOCB *iocb = opaque;
 
-if (iocb->is_invalid) {
-ide_dma_error(iocb->s);
-} else {
-iocb->common.cb(iocb->common.opaque, iocb->ret);
-}
+iocb->common.cb(iocb->common.opaque, iocb->ret);
+
 qemu_bh_delete(iocb->bh);
 iocb->bh = NULL;
 qemu_aio_unref(iocb);
@@ -462,7 +458,7 @@ static void ide_issue_trim_cb(void *opaque, int ret)
 }
 
 if (!ide_sect_range_ok(s, sector, count)) {
-iocb->is_invalid = true;
+iocb->ret = -EINVAL;
 goto done;
 }
 
@@ -502,7 +498,6 @@ BlockAIOCB *ide_issue_trim(
 iocb->qiov = qiov;
 iocb->i = -1;
 iocb->j = 0;
-iocb->is_invalid = false;
 ide_issue_trim_cb(iocb, 0);
 return >common;
 }
@@ -848,6 +843,12 @@ static void ide_dma_cb(void *opaque, int ret)
 if (ret == -ECANCELED) {
 return;
 }
+
+if (ret == -EINVAL) {
+ide_dma_error(s);
+return;
+}
+
 if (ret < 0) {
 if (ide_handle_rw_error(s, -ret, ide_dma_cmd_to_retry(s->dma_cmd))) {
 s->bus->dma->aiocb = NULL;
-- 
2.14.3




[Qemu-devel] [PULL 0/2] Ide patches

2018-03-26 Thread John Snow
The following changes since commit 7b93d78a04aa242d377ae213b79db6c319c71847:

  Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging 
(2018-03-26 15:17:25 +0100)

are available in the Git repository at:

  https://github.com/jnsnow/qemu.git tags/ide-pull-request

for you to fetch changes up to eb69953ecb1cbe7b4c4093a97a4dab3daa315d4e:

  macio: fix NULL pointer dereference when issuing IDE trim (2018-03-27 
00:38:00 -0400)





Anton Nefedov (1):
  ide: fix invalid TRIM range abortion for macio

Mark Cave-Ayland (1):
  macio: fix NULL pointer dereference when issuing IDE trim

 hw/ide/core.c  | 17 +
 hw/ide/macio.c |  2 +-
 2 files changed, 10 insertions(+), 9 deletions(-)

-- 
2.14.3




[Qemu-devel] [PULL 2/2] macio: fix NULL pointer dereference when issuing IDE trim

2018-03-26 Thread John Snow
From: Mark Cave-Ayland 

Commit ef0e64a983 "ide: pass IDEState to trim AIO callback" changed the
IDE trim callback from using a BlockBackend to an IDEState but forgot to update
the dma_blk_io() call in hw/ide/macio.c accordingly.

Without this fix qemu-system-ppc segfaults when issuing an IDE trim command on
any of the PPC Mac machines (easily triggered by running the Debian installer).

Reported-by: Howard Spoelstra 
Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Anton Nefedov 
Message-id: 20180223184700.28854-1-mark.cave-ayl...@ilande.co.uk
Signed-off-by: John Snow 
---
 hw/ide/macio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index 2e043ef1ea..d3a85cba3b 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -187,7 +187,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
 break;
 case IDE_DMA_TRIM:
 s->bus->dma->aiocb = dma_blk_io(blk_get_aio_context(s->blk), >sg,
-offset, 0x1, ide_issue_trim, s->blk,
+offset, 0x1, ide_issue_trim, s,
 pmac_ide_transfer_cb, io,
 DMA_DIRECTION_TO_DEVICE);
 break;
-- 
2.14.3




[Qemu-devel] [RFC for-2.13 11/12] target/ppc: Remove unnecessary POWERPC_MMU_V3 flag from mmu_model

2018-03-26 Thread David Gibson
The only place we test this flag is in conjunction with
ppc64_use_proc_tbl().  That checks for the LPCR_UPRT bit, which we already
ensure can't be set except on a machine with a v3 MMU (i.e. POWER9).

Signed-off-by: David Gibson 
---
 target/ppc/cpu-qom.h| 4 +---
 target/ppc/mmu-hash64.c | 2 +-
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h
index 2bd58b2a84..ef96d42cf2 100644
--- a/target/ppc/cpu-qom.h
+++ b/target/ppc/cpu-qom.h
@@ -68,7 +68,6 @@ enum powerpc_mmu_t {
 /* PowerPC 601 MMU model (specific BATs format)*/
 POWERPC_MMU_601= 0x000A,
 #define POWERPC_MMU_64   0x0001
-#define POWERPC_MMU_V3   0x0010 /* ISA V3.00 MMU Support */
 /* 64 bits PowerPC MMU */
 POWERPC_MMU_64B= POWERPC_MMU_64 | 0x0001,
 /* Architecture 2.03 and later (has LPCR) */
@@ -78,8 +77,7 @@ enum powerpc_mmu_t {
 /* Architecture 2.07 variant   */
 POWERPC_MMU_2_07   = POWERPC_MMU_64 | 0x0004,
 /* Architecture 3.00 variant   */
-POWERPC_MMU_3_00   = POWERPC_MMU_64 | POWERPC_MMU_V3
- | 0x0005,
+POWERPC_MMU_3_00   = POWERPC_MMU_64 | 0x0005,
 };
 #define POWERPC_MMU_VER(x) ((x) & (POWERPC_MMU_64 | 0x))
 #define POWERPC_MMU_VER_64B POWERPC_MMU_VER(POWERPC_MMU_64B)
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index 3b00bdee91..d964f2f5b0 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -761,7 +761,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr 
eaddr,
 slb = slb_lookup(cpu, eaddr);
 if (!slb) {
 /* No entry found, check if in-memory segment tables are in use */
-if ((env->mmu_model & POWERPC_MMU_V3) && ppc64_use_proc_tbl(cpu)) {
+if (ppc64_use_proc_tbl(cpu)) {
 /* TODO - Unsupported */
 error_report("Segment Table Support Unimplemented");
 exit(1);
-- 
2.14.3




[Qemu-devel] [RFC for-2.13 12/12] target/ppc: Get rid of POWERPC_MMU_VER() macros

2018-03-26 Thread David Gibson
These macros were introduced to deal with the fact that the mmu_model
field has bit flags mixed in with what's otherwise an enum of various mmu
types.

We've now eliminated all those flags except for one, and that one -
POWERPC_MMU_64 - is already included/compared in the MMU_VER macros.  So,
we can get rid of those macros and just directly compare mmu_model values
in the places it was used.

Signed-off-by: David Gibson 
---
 target/ppc/cpu-qom.h|  6 --
 target/ppc/kvm.c|  8 
 target/ppc/mmu-hash64.c | 12 ++--
 target/ppc/mmu_helper.c | 24 
 target/ppc/translate.c  | 12 ++--
 5 files changed, 28 insertions(+), 34 deletions(-)

diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h
index ef96d42cf2..433a71e484 100644
--- a/target/ppc/cpu-qom.h
+++ b/target/ppc/cpu-qom.h
@@ -79,12 +79,6 @@ enum powerpc_mmu_t {
 /* Architecture 3.00 variant   */
 POWERPC_MMU_3_00   = POWERPC_MMU_64 | 0x0005,
 };
-#define POWERPC_MMU_VER(x) ((x) & (POWERPC_MMU_64 | 0x))
-#define POWERPC_MMU_VER_64B POWERPC_MMU_VER(POWERPC_MMU_64B)
-#define POWERPC_MMU_VER_2_03 POWERPC_MMU_VER(POWERPC_MMU_2_03)
-#define POWERPC_MMU_VER_2_06 POWERPC_MMU_VER(POWERPC_MMU_2_06)
-#define POWERPC_MMU_VER_2_07 POWERPC_MMU_VER(POWERPC_MMU_2_07)
-#define POWERPC_MMU_VER_3_00 POWERPC_MMU_VER(POWERPC_MMU_3_00)
 
 /*/
 /* Exception model   */
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 6c45815ee6..9f3f567dda 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -306,8 +306,8 @@ static void kvm_get_fallback_smmu_info(PowerPCCPU *cpu,
 info->flags |= KVM_PPC_1T_SEGMENTS;
 }
 
-if (POWERPC_MMU_VER(env->mmu_model) == POWERPC_MMU_VER_2_06 ||
-   POWERPC_MMU_VER(env->mmu_model) == POWERPC_MMU_VER_2_07) {
+if (env->mmu_model == POWERPC_MMU_2_06 ||
+env->mmu_model == POWERPC_MMU_2_07) {
 info->slb_size = 32;
 } else {
 info->slb_size = 64;
@@ -321,8 +321,8 @@ static void kvm_get_fallback_smmu_info(PowerPCCPU *cpu,
 i++;
 
 /* 64K on MMU 2.06 and later */
-if (POWERPC_MMU_VER(env->mmu_model) == POWERPC_MMU_VER_2_06 ||
-POWERPC_MMU_VER(env->mmu_model) == POWERPC_MMU_VER_2_07) {
+if (env->mmu_model == POWERPC_MMU_2_06 ||
+env->mmu_model == POWERPC_MMU_2_07) {
 info->sps[i].page_shift = 16;
 info->sps[i].slb_enc = 0x110;
 info->sps[i].enc[0].page_shift = 16;
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index d964f2f5b0..3514995e16 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -1033,8 +1033,8 @@ void helper_store_lpcr(CPUPPCState *env, target_ulong val)
 uint64_t lpcr = 0;
 
 /* Filter out bits */
-switch (POWERPC_MMU_VER(env->mmu_model)) {
-case POWERPC_MMU_VER_64B: /* 970 */
+switch (env->mmu_model) {
+case POWERPC_MMU_64B: /* 970 */
 if (val & 0x40) {
 lpcr |= LPCR_LPES0;
 }
@@ -1060,26 +1060,26 @@ void helper_store_lpcr(CPUPPCState *env, target_ulong 
val)
  * to dig HRMOR out of HID5
  */
 break;
-case POWERPC_MMU_VER_2_03: /* P5p */
+case POWERPC_MMU_2_03: /* P5p */
 lpcr = val & (LPCR_RMLS | LPCR_ILE |
   LPCR_LPES0 | LPCR_LPES1 |
   LPCR_RMI | LPCR_HDICE);
 break;
-case POWERPC_MMU_VER_2_06: /* P7 */
+case POWERPC_MMU_2_06: /* P7 */
 lpcr = val & (LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_DPFD |
   LPCR_VRMASD | LPCR_RMLS | LPCR_ILE |
   LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2 |
   LPCR_MER | LPCR_TC |
   LPCR_LPES0 | LPCR_LPES1 | LPCR_HDICE);
 break;
-case POWERPC_MMU_VER_2_07: /* P8 */
+case POWERPC_MMU_2_07: /* P8 */
 lpcr = val & (LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV |
   LPCR_DPFD | LPCR_VRMASD | LPCR_RMLS | LPCR_ILE |
   LPCR_AIL | LPCR_ONL | LPCR_P8_PECE0 | LPCR_P8_PECE1 |
   LPCR_P8_PECE2 | LPCR_P8_PECE3 | LPCR_P8_PECE4 |
   LPCR_MER | LPCR_TC | LPCR_LPES0 | LPCR_HDICE);
 break;
-case POWERPC_MMU_VER_3_00: /* P9 */
+case POWERPC_MMU_3_00: /* P9 */
 lpcr = val & (LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |
   (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |
   LPCR_UPRT | LPCR_EVIRT | LPCR_ONL |
diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
index 5568d1642b..8075b7149a 100644
--- a/target/ppc/mmu_helper.c
+++ b/target/ppc/mmu_helper.c
@@ -1266,7 +1266,7 @@ static void mmu6xx_dump_mmu(FILE *f, fprintf_function 

[Qemu-devel] [RFC for-2.13 09/12] target/ppc: Move 1T segment and AMR options to PPCHash64Options

2018-03-26 Thread David Gibson
Currently env->mmu_model is a bit of an unholy mess of an enum of distinct
MMU types, with various flag bits as well.  This makes which bits of the
field should be compared pretty confusing.

Make a start on cleaning that up by moving two of the flags bits -
POWERPC_MMU_1TSEG and POWERPC_MMU_AMR - which are specific to the 64-bit
hash MMU into a new flags field in PPCHash64Options structure.

Signed-off-by: David Gibson 
---
 hw/ppc/pnv.c|  3 ++-
 hw/ppc/spapr.c  |  2 +-
 target/ppc/cpu-qom.h| 11 +++
 target/ppc/kvm.c|  4 ++--
 target/ppc/mmu-hash64.c |  6 --
 target/ppc/mmu-hash64.h |  3 +++
 6 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 5a79b24828..0aa878b771 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -36,6 +36,7 @@
 #include "monitor/monitor.h"
 #include "hw/intc/intc.h"
 #include "hw/ipmi/ipmi.h"
+#include "target/ppc/mmu-hash64.h"
 
 #include "hw/ppc/xics.h"
 #include "hw/ppc/pnv_xscom.h"
@@ -187,7 +188,7 @@ static void pnv_dt_core(PnvChip *chip, PnvCore *pc, void 
*fdt)
 _FDT((fdt_setprop(fdt, offset, "ibm,purr", NULL, 0)));
 }
 
-if (env->mmu_model & POWERPC_MMU_1TSEG) {
+if (cpu->hash64_opts->flags & PPC_HASH64_1TSEG) {
 _FDT((fdt_setprop(fdt, offset, "ibm,processor-segment-sizes",
segs, sizeof(segs;
 }
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index a35bffd524..436ed39f7f 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -557,7 +557,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, 
int offset,
 _FDT((fdt_setprop(fdt, offset, "ibm,purr", NULL, 0)));
 }
 
-if (env->mmu_model & POWERPC_MMU_1TSEG) {
+if (cpu->hash64_opts->flags & PPC_HASH64_1TSEG) {
 _FDT((fdt_setprop(fdt, offset, "ibm,processor-segment-sizes",
   segs, sizeof(segs;
 }
diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h
index 3e5ef7375f..2bd58b2a84 100644
--- a/target/ppc/cpu-qom.h
+++ b/target/ppc/cpu-qom.h
@@ -68,22 +68,17 @@ enum powerpc_mmu_t {
 /* PowerPC 601 MMU model (specific BATs format)*/
 POWERPC_MMU_601= 0x000A,
 #define POWERPC_MMU_64   0x0001
-#define POWERPC_MMU_1TSEG0x0002
-#define POWERPC_MMU_AMR  0x0004
 #define POWERPC_MMU_V3   0x0010 /* ISA V3.00 MMU Support */
 /* 64 bits PowerPC MMU */
 POWERPC_MMU_64B= POWERPC_MMU_64 | 0x0001,
 /* Architecture 2.03 and later (has LPCR) */
 POWERPC_MMU_2_03   = POWERPC_MMU_64 | 0x0002,
 /* Architecture 2.06 variant   */
-POWERPC_MMU_2_06   = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
- | POWERPC_MMU_AMR | 0x0003,
+POWERPC_MMU_2_06   = POWERPC_MMU_64 | 0x0003,
 /* Architecture 2.07 variant   */
-POWERPC_MMU_2_07   = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
- | POWERPC_MMU_AMR | 0x0004,
+POWERPC_MMU_2_07   = POWERPC_MMU_64 | 0x0004,
 /* Architecture 3.00 variant   */
-POWERPC_MMU_3_00   = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
- | POWERPC_MMU_AMR | POWERPC_MMU_V3
+POWERPC_MMU_3_00   = POWERPC_MMU_64 | POWERPC_MMU_V3
  | 0x0005,
 };
 #define POWERPC_MMU_VER(x) ((x) & (POWERPC_MMU_64 | 0x))
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 01947169c9..3424917381 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -302,7 +302,7 @@ static void kvm_get_fallback_smmu_info(PowerPCCPU *cpu,
 /* HV KVM has backing store size restrictions */
 info->flags = KVM_PPC_PAGE_SIZES_REAL;
 
-if (env->mmu_model & POWERPC_MMU_1TSEG) {
+if (cpu->hash64_opts->flags & PPC_HASH64_1TSEG) {
 info->flags |= KVM_PPC_1T_SEGMENTS;
 }
 
@@ -482,7 +482,7 @@ static void kvm_fixup_page_sizes(PowerPCCPU *cpu)
 }
 env->slb_nr = smmu_info.slb_size;
 if (!(smmu_info.flags & KVM_PPC_1T_SEGMENTS)) {
-env->mmu_model &= ~POWERPC_MMU_1TSEG;
+cpu->hash64_opts->flags &= ~PPC_HASH64_1TSEG;
 }
 }
 
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index d369b1bf86..1d785f50d7 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -160,7 +160,7 @@ int ppc_store_slb(PowerPCCPU *cpu, target_ulong slot,
 if (vsid & (SLB_VSID_B & ~SLB_VSID_B_1T)) {
 return -1; /* Bad segment size */
 }
-if ((vsid & SLB_VSID_B) && !(env->mmu_model & POWERPC_MMU_1TSEG)) {
+if ((vsid & SLB_VSID_B) && !(cpu->hash64_opts->flags & PPC_HASH64_1TSEG)) {
 return -1; /* 1T segment on MMU that doesn't support it */
 }
 
@@ -369,7 +369,7 @@ static int ppc_hash64_amr_prot(PowerPCCPU *cpu, 
ppc_hash_pte64_t pte)
 int prot = PAGE_READ | 

[Qemu-devel] [RFC for-2.13 08/12] target/ppc: Make hash64_opts field mandatory for 64-bit hash MMUs

2018-03-26 Thread David Gibson
Currently some cpus set the hash64_opts field in the class structure, with
specific details of their variant of the 64-bit hash mmu.  For the
remaining cpus with that mmu, ppc_hash64_realize() fills in defaults.

But there are only a couple of cpus that use those fallbacks, so just have
them to set the has64_opts field instead, simplifying the logic.

Signed-off-by: David Gibson 
---
 target/ppc/mmu-hash64.c | 36 ++--
 target/ppc/mmu-hash64.h |  1 +
 target/ppc/translate_init.c |  2 ++
 3 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index d7a0e5615f..d369b1bf86 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -1100,25 +1100,12 @@ void ppc_hash64_init(PowerPCCPU *cpu)
 CPUPPCState *env = >env;
 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
 
-if (pcc->hash64_opts) {
-cpu->hash64_opts = g_memdup(pcc->hash64_opts,
-sizeof(*cpu->hash64_opts));
-} else if (env->mmu_model & POWERPC_MMU_64) {
-/* Use default sets of page sizes. We don't support MPSS */
-static const PPCHash64Options defopts = {
-.sps = {
-{ .page_shift = 12, /* 4K */
-  .slb_enc = 0,
-  .enc = { { .page_shift = 12, .pte_enc = 0 } }
-},
-{ .page_shift = 24, /* 16M */
-  .slb_enc = 0x100,
-  .enc = { { .page_shift = 24, .pte_enc = 0 } }
-},
-},
-};
-cpu->hash64_opts = g_memdup(, sizeof(*cpu->hash64_opts));
+if (!pcc->hash64_opts) {
+assert(!(env->mmu_model & POWERPC_MMU_64));
+return;
 }
+
+cpu->hash64_opts = g_memdup(pcc->hash64_opts, sizeof(*cpu->hash64_opts));
 }
 
 void ppc_hash64_finalize(PowerPCCPU *cpu)
@@ -1126,6 +1113,19 @@ void ppc_hash64_finalize(PowerPCCPU *cpu)
 g_free(cpu->hash64_opts);
 }
 
+const PPCHash64Options ppc_hash64_opts_basic = {
+.sps = {
+{ .page_shift = 12, /* 4K */
+  .slb_enc = 0,
+  .enc = { { .page_shift = 12, .pte_enc = 0 } }
+},
+{ .page_shift = 24, /* 16M */
+  .slb_enc = 0x100,
+  .enc = { { .page_shift = 24, .pte_enc = 0 } }
+},
+},
+};
+
 const PPCHash64Options ppc_hash64_opts_POWER7 = {
 .sps = {
 {
diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h
index d42cbc2762..ff0c48af55 100644
--- a/target/ppc/mmu-hash64.h
+++ b/target/ppc/mmu-hash64.h
@@ -155,6 +155,7 @@ struct PPCHash64Options {
 struct ppc_one_seg_page_size sps[PPC_PAGE_SIZES_MAX_SZ];
 };
 
+extern const PPCHash64Options ppc_hash64_opts_basic;
 extern const PPCHash64Options ppc_hash64_opts_POWER7;
 
 #endif /* CONFIG_USER_ONLY */
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index 040d6fbac3..ae005b2a54 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -8242,6 +8242,7 @@ POWERPC_FAMILY(970)(ObjectClass *oc, void *data)
 pcc->mmu_model = POWERPC_MMU_64B;
 #if defined(CONFIG_SOFTMMU)
 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
+pcc->hash64_opts = _hash64_opts_basic;
 #endif
 pcc->excp_model = POWERPC_EXCP_970;
 pcc->bus_model = PPC_FLAGS_INPUT_970;
@@ -8319,6 +8320,7 @@ POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data)
 pcc->mmu_model = POWERPC_MMU_2_03;
 #if defined(CONFIG_SOFTMMU)
 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
+pcc->hash64_opts = _hash64_opts_basic;
 #endif
 pcc->excp_model = POWERPC_EXCP_970;
 pcc->bus_model = PPC_FLAGS_INPUT_970;
-- 
2.14.3




[Qemu-devel] [RFC for-2.13 07/12] target/ppc: Split page size information into a separate allocation

2018-03-26 Thread David Gibson
env->sps contains page size encoding information as an embedded structure.
Since this information is specific to 64-bit hash MMUs, split it out into
a separately allocated structure, to reduce the basic env size for other
cpus.  Along the way we make a few other cleanups:

* Rename to PPCHash64Options which is more in line with qemu name
  conventions, and reflects that we're going to merge some more hash64
  mmu specific details in there in future

* Move structure definitions to the mmu-hash64.[ch] files.

Signed-off-by: David Gibson 
---
 hw/ppc/fdt.c|  4 ++--
 target/ppc/cpu-qom.h|  4 ++--
 target/ppc/cpu.h| 22 +
 target/ppc/kvm.c|  4 ++--
 target/ppc/mmu-hash64.c | 47 -
 target/ppc/mmu-hash64.h | 21 
 target/ppc/translate_init.c | 36 +++---
 7 files changed, 69 insertions(+), 69 deletions(-)

diff --git a/hw/ppc/fdt.c b/hw/ppc/fdt.c
index 2721603ffa..c4ba16f6b4 100644
--- a/hw/ppc/fdt.c
+++ b/hw/ppc/fdt.c
@@ -9,6 +9,7 @@
 
 #include "qemu/osdep.h"
 #include "target/ppc/cpu.h"
+#include "target/ppc/mmu-hash64.h"
 
 #include "hw/ppc/fdt.h"
 
@@ -16,13 +17,12 @@
 size_t ppc_create_page_sizes_prop(PowerPCCPU *cpu, uint32_t *prop,
   size_t maxsize)
 {
-CPUPPCState *env = >env;
 size_t maxcells = maxsize / sizeof(uint32_t);
 int i, j, count;
 uint32_t *p = prop;
 
 for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) {
-struct ppc_one_seg_page_size *sps = >sps.sps[i];
+struct ppc_one_seg_page_size *sps = >hash64_opts->sps[i];
 
 if (!sps->page_shift) {
 break;
diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h
index 9bbb05cf62..3e5ef7375f 100644
--- a/target/ppc/cpu-qom.h
+++ b/target/ppc/cpu-qom.h
@@ -160,7 +160,7 @@ enum powerpc_input_t {
 PPC_FLAGS_INPUT_RCPU,
 };
 
-struct ppc_segment_page_sizes;
+typedef struct PPCHash64Options PPCHash64Options;
 
 /**
  * PowerPCCPUClass:
@@ -194,7 +194,7 @@ typedef struct PowerPCCPUClass {
 uint32_t flags;
 int bfd_mach;
 uint32_t l1_dcache_size, l1_icache_size;
-const struct ppc_segment_page_sizes *sps;
+const PPCHash64Options *hash64_opts;
 struct ppc_radix_page_info *radix_page_info;
 void (*init_proc)(CPUPPCState *env);
 int  (*check_pow)(CPUPPCState *env);
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index c621a6bd5e..fb6c578eb5 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -948,28 +948,8 @@ enum {
 
 #define DBELL_PROCIDTAG_MASK   PPC_BITMASK(44, 63)
 
-/*/
-/* Segment page size information, used by recent hash MMUs
- * The format of this structure mirrors kvm_ppc_smmu_info
- */
-
 #define PPC_PAGE_SIZES_MAX_SZ   8
 
-struct ppc_one_page_size {
-uint32_t page_shift;  /* Page shift (or 0) */
-uint32_t pte_enc; /* Encoding in the HPTE (>>12) */
-};
-
-struct ppc_one_seg_page_size {
-uint32_t page_shift;  /* Base page shift of segment (or 0) */
-uint32_t slb_enc; /* SLB encoding for BookS */
-struct ppc_one_page_size enc[PPC_PAGE_SIZES_MAX_SZ];
-};
-
-struct ppc_segment_page_sizes {
-struct ppc_one_seg_page_size sps[PPC_PAGE_SIZES_MAX_SZ];
-};
-
 struct ppc_radix_page_info {
 uint32_t count;
 uint32_t entries[PPC_PAGE_SIZES_MAX_SZ];
@@ -1106,7 +1086,6 @@ struct CPUPPCState {
 uint64_t insns_flags;
 uint64_t insns_flags2;
 #if defined(TARGET_PPC64)
-struct ppc_segment_page_sizes sps;
 ppc_slb_t vrma_slb;
 target_ulong rmls;
 bool ci_large_pages;
@@ -1227,6 +1206,7 @@ struct PowerPCCPU {
 PPCVirtualHypervisor *vhyp;
 Object *intc;
 int32_t node_id; /* NUMA node this CPU belongs to */
+PPCHash64Options *hash64_opts;
 
 /* Fields related to migration compatibility hacks */
 bool pre_2_8_migration;
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 6160356a4a..01947169c9 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -442,7 +442,7 @@ static void kvm_fixup_page_sizes(PowerPCCPU *cpu)
 }
 
 /* Convert to QEMU form */
-memset(>sps, 0, sizeof(env->sps));
+memset(cpu->hash64_opts, 0, sizeof(*cpu->hash64_opts));
 
 /* If we have HV KVM, we need to forbid CI large pages if our
  * host page size is smaller than 64K.
@@ -456,7 +456,7 @@ static void kvm_fixup_page_sizes(PowerPCCPU *cpu)
  * the selected CPU has with the capabilities that KVM supports.
  */
 for (ik = iq = 0; ik < KVM_PPC_PAGE_SIZES_MAX_SZ; ik++) {
-struct ppc_one_seg_page_size *qsps = >sps.sps[iq];
+struct ppc_one_seg_page_size *qsps = >hash64_opts->sps[iq];
 struct kvm_ppc_one_seg_page_size *ksps = _info.sps[ik];
 
 if (!kvm_valid_page_size(smmu_info.flags, max_cpu_page_size,
diff --git a/target/ppc/mmu-hash64.c 

[Qemu-devel] [RFC for-2.13 10/12] target/ppc: Fold ci_large_pages flag into PPCHash64Options

2018-03-26 Thread David Gibson
The ci_large_pages boolean in CPUPPCState is only relevant to 64-bit hash
MMU machines, indicating whether it's possible to map large (> 4kiB) pages
as cache-inhibitied (i.e. for IO, rather than memory).  Fold it as another
flag into the PPCHash64Options structure.

Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c  | 3 +--
 target/ppc/cpu.h| 1 -
 target/ppc/kvm.c| 6 +-
 target/ppc/mmu-hash64.c | 2 +-
 target/ppc/mmu-hash64.h | 1 +
 target/ppc/translate_init.c | 3 ---
 6 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 436ed39f7f..95063df54d 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -263,7 +263,6 @@ static void spapr_populate_pa_features(sPAPRMachineState 
*spapr,
void *fdt, int offset,
bool legacy_guest)
 {
-CPUPPCState *env = >env;
 uint8_t pa_features_206[] = { 6, 0,
 0xf6, 0x1f, 0xc7, 0x00, 0x80, 0xc0 };
 uint8_t pa_features_207[] = { 24, 0,
@@ -315,7 +314,7 @@ static void spapr_populate_pa_features(sPAPRMachineState 
*spapr,
 return;
 }
 
-if (env->ci_large_pages) {
+if (cpu->hash64_opts->flags & PPC_HASH64_CI_LARGEPAGE) {
 /*
  * Note: we keep CI large pages off by default because a 64K capable
  * guest provisioned with large pages might otherwise try to map a qemu
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index fb6c578eb5..76ce67e9de 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1088,7 +1088,6 @@ struct CPUPPCState {
 #if defined(TARGET_PPC64)
 ppc_slb_t vrma_slb;
 target_ulong rmls;
-bool ci_large_pages;
 #endif
 
 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 3424917381..6c45815ee6 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -448,7 +448,11 @@ static void kvm_fixup_page_sizes(PowerPCCPU *cpu)
  * host page size is smaller than 64K.
  */
 if (smmu_info.flags & KVM_PPC_PAGE_SIZES_REAL) {
-env->ci_large_pages = getpagesize() >= 0x1;
+if (getpagesize() >= 0x1) {
+cpu->hash64_opts->flags |= PPC_HASH64_CI_LARGEPAGE;
+} else {
+cpu->hash64_opts->flags &= ~PPC_HASH64_CI_LARGEPAGE;
+}
 }
 
 /*
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index 1d785f50d7..3b00bdee91 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -1128,7 +1128,7 @@ const PPCHash64Options ppc_hash64_opts_basic = {
 };
 
 const PPCHash64Options ppc_hash64_opts_POWER7 = {
-.flags = PPC_HASH64_1TSEG | PPC_HASH64_AMR,
+.flags = PPC_HASH64_1TSEG | PPC_HASH64_AMR | PPC_HASH64_CI_LARGEPAGE,
 .sps = {
 {
 .page_shift = 12, /* 4K */
diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h
index 6cfca97a60..cddfe06a8b 100644
--- a/target/ppc/mmu-hash64.h
+++ b/target/ppc/mmu-hash64.h
@@ -154,6 +154,7 @@ struct ppc_one_seg_page_size {
 struct PPCHash64Options {
 #define PPC_HASH64_1TSEG0x1
 #define PPC_HASH64_AMR  0x2
+#define PPC_HASH64_CI_LARGEPAGE 0x4
 unsigned flags;
 struct ppc_one_seg_page_size sps[PPC_PAGE_SIZES_MAX_SZ];
 };
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index ae005b2a54..a925cf5cd3 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -8392,7 +8392,6 @@ static void init_proc_POWER7(CPUPPCState *env)
 #if !defined(CONFIG_USER_ONLY)
 env->slb_nr = 32;
 #endif
-env->ci_large_pages = true;
 env->dcache_line_size = 128;
 env->icache_line_size = 128;
 
@@ -8547,7 +8546,6 @@ static void init_proc_POWER8(CPUPPCState *env)
 #if !defined(CONFIG_USER_ONLY)
 env->slb_nr = 32;
 #endif
-env->ci_large_pages = true;
 env->dcache_line_size = 128;
 env->icache_line_size = 128;
 
@@ -8748,7 +8746,6 @@ static void init_proc_POWER9(CPUPPCState *env)
 #if !defined(CONFIG_USER_ONLY)
 env->slb_nr = 32;
 #endif
-env->ci_large_pages = true;
 env->dcache_line_size = 128;
 env->icache_line_size = 128;
 
-- 
2.14.3




[Qemu-devel] [RFC for-2.13 01/12] target/ppc: Standardize instance_init and realize function names

2018-03-26 Thread David Gibson
Because of the various hooks called some variant on "init" - and the rather
greater number that used to exist, I'm always wondering when a function
called simply "*_init" or "*_initfn" will be called.

To make it easier on myself, and maybe others, rename the instance_init
hooks for ppc cpus to *_instance_init().  While we're at it rename the
realize time hooks to *_realize() (from *_realizefn()) which seems to be
the more common current convention.

Signed-off-by: David Gibson 
---
 target/ppc/translate_init.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index 391b94b97d..56b80a204a 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -9726,7 +9726,7 @@ static inline bool ppc_cpu_is_valid(PowerPCCPUClass *pcc)
 #endif
 }
 
-static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
+static void ppc_cpu_realize(DeviceState *dev, Error **errp)
 {
 CPUState *cs = CPU(dev);
 PowerPCCPU *cpu = POWERPC_CPU(dev);
@@ -9952,7 +9952,7 @@ unrealize:
 cpu_exec_unrealizefn(cs);
 }
 
-static void ppc_cpu_unrealizefn(DeviceState *dev, Error **errp)
+static void ppc_cpu_unrealize(DeviceState *dev, Error **errp)
 {
 PowerPCCPU *cpu = POWERPC_CPU(dev);
 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
@@ -10438,7 +10438,7 @@ static bool ppc_cpu_is_big_endian(CPUState *cs)
 }
 #endif
 
-static void ppc_cpu_initfn(Object *obj)
+static void ppc_cpu_instance_init(Object *obj)
 {
 CPUState *cs = CPU(obj);
 PowerPCCPU *cpu = POWERPC_CPU(obj);
@@ -10561,9 +10561,9 @@ static void ppc_cpu_class_init(ObjectClass *oc, void 
*data)
 CPUClass *cc = CPU_CLASS(oc);
 DeviceClass *dc = DEVICE_CLASS(oc);
 
-device_class_set_parent_realize(dc, ppc_cpu_realizefn,
+device_class_set_parent_realize(dc, ppc_cpu_realize,
 >parent_realize);
-device_class_set_parent_unrealize(dc, ppc_cpu_unrealizefn,
+device_class_set_parent_unrealize(dc, ppc_cpu_unrealize,
   >parent_unrealize);
 pcc->pvr_match = ppc_pvr_match_default;
 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_always;
@@ -10623,7 +10623,7 @@ static const TypeInfo ppc_cpu_type_info = {
 .name = TYPE_POWERPC_CPU,
 .parent = TYPE_CPU,
 .instance_size = sizeof(PowerPCCPU),
-.instance_init = ppc_cpu_initfn,
+.instance_init = ppc_cpu_instance_init,
 .abstract = true,
 .class_size = sizeof(PowerPCCPUClass),
 .class_init = ppc_cpu_class_init,
-- 
2.14.3




[Qemu-devel] [RFC for-2.13 06/12] target/ppc: Move page size setup to helper function

2018-03-26 Thread David Gibson
Initialization of the env->sps structure at the end of instance_init is
specific to the 64-bit hash MMU, so move the code into a helper function
in mmu-hash64.c.

We also create a corresponding function to be called at finalize time -
it's empty for now, but we'll need it shortly.

Signed-off-by: David Gibson 
---
 target/ppc/mmu-hash64.c | 29 +
 target/ppc/mmu-hash64.h | 11 +++
 target/ppc/translate_init.c | 29 +
 3 files changed, 49 insertions(+), 20 deletions(-)

diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index a87fa7c83f..4cb7d1cf07 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -1095,3 +1095,32 @@ void helper_store_lpcr(CPUPPCState *env, target_ulong 
val)
 ppc_hash64_update_rmls(cpu);
 ppc_hash64_update_vrma(cpu);
 }
+
+void ppc_hash64_init(PowerPCCPU *cpu)
+{
+CPUPPCState *env = >env;
+PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
+
+if (pcc->sps) {
+env->sps = *pcc->sps;
+} else if (env->mmu_model & POWERPC_MMU_64) {
+/* Use default sets of page sizes. We don't support MPSS */
+static const struct ppc_segment_page_sizes defsps = {
+.sps = {
+{ .page_shift = 12, /* 4K */
+  .slb_enc = 0,
+  .enc = { { .page_shift = 12, .pte_enc = 0 } }
+},
+{ .page_shift = 24, /* 16M */
+  .slb_enc = 0x100,
+  .enc = { { .page_shift = 24, .pte_enc = 0 } }
+},
+},
+};
+env->sps = defsps;
+}
+}
+
+void ppc_hash64_finalize(PowerPCCPU *cpu)
+{
+}
diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h
index 95a8c330d6..074ded4c27 100644
--- a/target/ppc/mmu-hash64.h
+++ b/target/ppc/mmu-hash64.h
@@ -19,6 +19,8 @@ unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
   uint64_t pte0, uint64_t pte1);
 void ppc_hash64_update_vrma(PowerPCCPU *cpu);
 void ppc_hash64_update_rmls(PowerPCCPU *cpu);
+void ppc_hash64_init(PowerPCCPU *cpu);
+void ppc_hash64_finalize(PowerPCCPU *cpu);
 #endif
 
 /*
@@ -136,4 +138,13 @@ static inline uint64_t ppc_hash64_hpte1(PowerPCCPU *cpu,
 
 #endif /* CONFIG_USER_ONLY */
 
+#if defined(CONFIG_USER_ONLY) || !defined(TARGET_PPC64)
+static inline void ppc_hash64_init(PowerPCCPU *cpu)
+{
+}
+static inline void ppc_hash64_finalize(PowerPCCPU *cpu)
+{
+}
+#endif
+
 #endif /* MMU_HASH64_H */
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index 99be6fcd68..aa63a5dcb3 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -10464,26 +10464,14 @@ static void ppc_cpu_instance_init(Object *obj)
 env->has_hv_mode = !!(env->msr_mask & MSR_HVB);
 #endif
 
-#if defined(TARGET_PPC64)
-if (pcc->sps) {
-env->sps = *pcc->sps;
-} else if (env->mmu_model & POWERPC_MMU_64) {
-/* Use default sets of page sizes. We don't support MPSS */
-static const struct ppc_segment_page_sizes defsps = {
-.sps = {
-{ .page_shift = 12, /* 4K */
-  .slb_enc = 0,
-  .enc = { { .page_shift = 12, .pte_enc = 0 } }
-},
-{ .page_shift = 24, /* 16M */
-  .slb_enc = 0x100,
-  .enc = { { .page_shift = 24, .pte_enc = 0 } }
-},
-},
-};
-env->sps = defsps;
-}
-#endif /* defined(TARGET_PPC64) */
+ppc_hash64_init(cpu);
+}
+
+static void ppc_cpu_instance_finalize(Object *obj)
+{
+PowerPCCPU *cpu = POWERPC_CPU(obj);
+
+ppc_hash64_finalize(cpu);
 }
 
 static bool ppc_pvr_match_default(PowerPCCPUClass *pcc, uint32_t pvr)
@@ -10601,6 +10589,7 @@ static const TypeInfo ppc_cpu_type_info = {
 .parent = TYPE_CPU,
 .instance_size = sizeof(PowerPCCPU),
 .instance_init = ppc_cpu_instance_init,
+.instance_finalize = ppc_cpu_instance_finalize,
 .abstract = true,
 .class_size = sizeof(PowerPCCPUClass),
 .class_init = ppc_cpu_class_init,
-- 
2.14.3




[Qemu-devel] [RFC for-2.13 05/12] target/ppc: Remove fallback 64k pagesize information

2018-03-26 Thread David Gibson
CPU definitions for cpus with the 64-bit hash MMU can include a table of
available pagesizes.  If this isn't supplied ppc_cpu_instance_init() will
fill it in a fallback table based on the POWERPC_MMU_64K bit in mmu_model.

However, it turns out all the cpus which support 64K pages already include
an explicit table of page sizes, so there's no point to the fallback table
including 64k pages.

That removes the only place which tests POWERPC_MMU_64K, so we can remove
it.  Which in turn allows some logic to be removed from
kvm_fixup_page_sizes().

Signed-off-by: David Gibson 
---
 target/ppc/cpu-qom.h|  4 
 target/ppc/kvm.c|  7 ---
 target/ppc/translate_init.c | 20 ++--
 3 files changed, 2 insertions(+), 29 deletions(-)

diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h
index deaa46a14b..9bbb05cf62 100644
--- a/target/ppc/cpu-qom.h
+++ b/target/ppc/cpu-qom.h
@@ -70,7 +70,6 @@ enum powerpc_mmu_t {
 #define POWERPC_MMU_64   0x0001
 #define POWERPC_MMU_1TSEG0x0002
 #define POWERPC_MMU_AMR  0x0004
-#define POWERPC_MMU_64K  0x0008
 #define POWERPC_MMU_V3   0x0010 /* ISA V3.00 MMU Support */
 /* 64 bits PowerPC MMU */
 POWERPC_MMU_64B= POWERPC_MMU_64 | 0x0001,
@@ -78,15 +77,12 @@ enum powerpc_mmu_t {
 POWERPC_MMU_2_03   = POWERPC_MMU_64 | 0x0002,
 /* Architecture 2.06 variant   */
 POWERPC_MMU_2_06   = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
- | POWERPC_MMU_64K
  | POWERPC_MMU_AMR | 0x0003,
 /* Architecture 2.07 variant   */
 POWERPC_MMU_2_07   = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
- | POWERPC_MMU_64K
  | POWERPC_MMU_AMR | 0x0004,
 /* Architecture 3.00 variant   */
 POWERPC_MMU_3_00   = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
- | POWERPC_MMU_64K
  | POWERPC_MMU_AMR | POWERPC_MMU_V3
  | 0x0005,
 };
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 79a436a384..6160356a4a 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -425,7 +425,6 @@ static void kvm_fixup_page_sizes(PowerPCCPU *cpu)
 static bool has_smmu_info;
 CPUPPCState *env = >env;
 int iq, ik, jq, jk;
-bool has_64k_pages = false;
 
 /* We only handle page sizes for 64-bit server guests for now */
 if (!(env->mmu_model & POWERPC_MMU_64)) {
@@ -471,9 +470,6 @@ static void kvm_fixup_page_sizes(PowerPCCPU *cpu)
  ksps->enc[jk].page_shift)) {
 continue;
 }
-if (ksps->enc[jk].page_shift == 16) {
-has_64k_pages = true;
-}
 qsps->enc[jq].page_shift = ksps->enc[jk].page_shift;
 qsps->enc[jq].pte_enc = ksps->enc[jk].pte_enc;
 if (++jq >= PPC_PAGE_SIZES_MAX_SZ) {
@@ -488,9 +484,6 @@ static void kvm_fixup_page_sizes(PowerPCCPU *cpu)
 if (!(smmu_info.flags & KVM_PPC_1T_SEGMENTS)) {
 env->mmu_model &= ~POWERPC_MMU_1TSEG;
 }
-if (!has_64k_pages) {
-env->mmu_model &= ~POWERPC_MMU_64K;
-}
 }
 
 bool kvmppc_is_mem_backend_page_size_ok(const char *obj_path)
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index 29bd6f3654..99be6fcd68 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -10469,7 +10469,7 @@ static void ppc_cpu_instance_init(Object *obj)
 env->sps = *pcc->sps;
 } else if (env->mmu_model & POWERPC_MMU_64) {
 /* Use default sets of page sizes. We don't support MPSS */
-static const struct ppc_segment_page_sizes defsps_4k = {
+static const struct ppc_segment_page_sizes defsps = {
 .sps = {
 { .page_shift = 12, /* 4K */
   .slb_enc = 0,
@@ -10481,23 +10481,7 @@ static void ppc_cpu_instance_init(Object *obj)
 },
 },
 };
-static const struct ppc_segment_page_sizes defsps_64k = {
-.sps = {
-{ .page_shift = 12, /* 4K */
-  .slb_enc = 0,
-  .enc = { { .page_shift = 12, .pte_enc = 0 } }
-},
-{ .page_shift = 16, /* 64K */
-  .slb_enc = 0x110,
-  .enc = { { .page_shift = 16, .pte_enc = 1 } }
-},
-{ .page_shift = 24, /* 16M */
-  .slb_enc = 0x100,
-  .enc = { { .page_shift = 24, .pte_enc = 0 } }
-},
-},
-};
-env->sps = (env->mmu_model & POWERPC_MMU_64K) ? defsps_64k : defsps_4k;
+env->sps = defsps;
 }
 #endif /* defined(TARGET_PPC64) */
 }
-- 
2.14.3




[Qemu-devel] [RFC for-2.13 03/12] target/ppc: Pass cpu instead of env to ppc_create_page_sizes_prop()

2018-03-26 Thread David Gibson
As a rule we prefer to pass PowerPCCPU instead of CPUPPCState, and this
change will make some things simpler later on.

Signed-off-by: David Gibson 
---
 hw/ppc/fdt.c | 5 +++--
 hw/ppc/pnv.c | 4 ++--
 hw/ppc/spapr.c   | 4 ++--
 include/hw/ppc/fdt.h | 2 +-
 4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/hw/ppc/fdt.c b/hw/ppc/fdt.c
index 2ffc5866e4..2721603ffa 100644
--- a/hw/ppc/fdt.c
+++ b/hw/ppc/fdt.c
@@ -13,9 +13,10 @@
 #include "hw/ppc/fdt.h"
 
 #if defined(TARGET_PPC64)
-size_t ppc_create_page_sizes_prop(CPUPPCState *env, uint32_t *prop,
- size_t maxsize)
+size_t ppc_create_page_sizes_prop(PowerPCCPU *cpu, uint32_t *prop,
+  size_t maxsize)
 {
+CPUPPCState *env = >env;
 size_t maxcells = maxsize / sizeof(uint32_t);
 int i, j, count;
 uint32_t *p = prop;
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 98ee3c607a..5a79b24828 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -209,8 +209,8 @@ static void pnv_dt_core(PnvChip *chip, PnvCore *pc, void 
*fdt)
 _FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1)));
 }
 
-page_sizes_prop_size = ppc_create_page_sizes_prop(env, page_sizes_prop,
-  sizeof(page_sizes_prop));
+page_sizes_prop_size = ppc_create_page_sizes_prop(cpu, page_sizes_prop,
+  sizeof(page_sizes_prop));
 if (page_sizes_prop_size) {
 _FDT((fdt_setprop(fdt, offset, "ibm,segment-page-sizes",
page_sizes_prop, page_sizes_prop_size)));
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 2c0be8c898..a35bffd524 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -581,8 +581,8 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, 
int offset,
 _FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1)));
 }
 
-page_sizes_prop_size = ppc_create_page_sizes_prop(env, page_sizes_prop,
-  sizeof(page_sizes_prop));
+page_sizes_prop_size = ppc_create_page_sizes_prop(cpu, page_sizes_prop,
+  sizeof(page_sizes_prop));
 if (page_sizes_prop_size) {
 _FDT((fdt_setprop(fdt, offset, "ibm,segment-page-sizes",
   page_sizes_prop, page_sizes_prop_size)));
diff --git a/include/hw/ppc/fdt.h b/include/hw/ppc/fdt.h
index bd5b0a8c3d..a8cd85069f 100644
--- a/include/hw/ppc/fdt.h
+++ b/include/hw/ppc/fdt.h
@@ -23,7 +23,7 @@
 }  \
 } while (0)
 
-size_t ppc_create_page_sizes_prop(CPUPPCState *env, uint32_t *prop,
+size_t ppc_create_page_sizes_prop(PowerPCCPU *cpu, uint32_t *prop,
   size_t maxsize);
 
 #endif /* PPC_FDT_H */
-- 
2.14.3




[Qemu-devel] [RFC for-2.13 02/12] target/ppc: Simplify cpu valid check in ppc_cpu_realize

2018-03-26 Thread David Gibson
The #if isn't necessary, because there's a suitable one inside
ppc_cpu_is_valid().  We've already filtered for suitable cpu models in the
functions that search and register them.  So by the time we get to realize
having an invalid one indicates a code error, not a user error, so an
assert() is more appropriate than error_setg().

Signed-off-by: David Gibson 
---
 target/ppc/translate_init.c | 9 +
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index 56b80a204a..2ae718242a 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -9749,14 +9749,7 @@ static void ppc_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 }
 
-#if defined(TARGET_PPCEMB)
-if (!ppc_cpu_is_valid(pcc)) {
-error_setg(errp, "CPU does not possess a BookE or 4xx MMU. "
-   "Please use qemu-system-ppc or qemu-system-ppc64 instead "
-   "or choose another CPU model.");
-goto unrealize;
-}
-#endif
+assert(ppc_cpu_is_valid(pcc));
 
 create_ppc_opcodes(cpu, _err);
 if (local_err != NULL) {
-- 
2.14.3




[Qemu-devel] [RFC for-2.13 04/12] target/ppc: Avoid taking "env" parameter to mmu-hash64 functions

2018-03-26 Thread David Gibson
In most cases we prefer to pass a PowerPCCPU rather than the (embedded)
CPUPPCState.

For ppc_hash64_update_{rmls,vrma}() change to take "cpu" instead of "env".
For ppc_hash64_set_{dsi,isi}() remove the redundant "env" parameter.

In theory this makes more work for the functions, but since "cs", "cpu"
and "env" are related by at most constant offsets, the compiler should be
able to optimize out the difference at effectively zero cost.

helper_*() functions are left alone - since they're more closely tied to
the TCG generated code, passing "env" is still the standard there.

While we're there, fix an incorrect indentation.

Signed-off-by: David Gibson 
---
 target/ppc/mmu-hash64.c | 35 +++
 target/ppc/mmu-hash64.h |  4 ++--
 target/ppc/translate_init.c |  4 ++--
 3 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index c9b72b7429..a87fa7c83f 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -633,9 +633,9 @@ unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
 return 0;
 }
 
-static void ppc_hash64_set_isi(CPUState *cs, CPUPPCState *env,
-   uint64_t error_code)
+static void ppc_hash64_set_isi(CPUState *cs, uint64_t error_code)
 {
+CPUPPCState *env = _CPU(cs)->env;
 bool vpm;
 
 if (msr_ir) {
@@ -659,9 +659,9 @@ static void ppc_hash64_set_isi(CPUState *cs, CPUPPCState 
*env,
 env->error_code = error_code;
 }
 
-static void ppc_hash64_set_dsi(CPUState *cs, CPUPPCState *env, uint64_t dar,
-   uint64_t dsisr)
+static void ppc_hash64_set_dsi(CPUState *cs, uint64_t dar, uint64_t dsisr)
 {
+CPUPPCState *env = _CPU(cs)->env;
 bool vpm;
 
 if (msr_dr) {
@@ -741,13 +741,13 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr 
eaddr,
 } else {
 /* The access failed, generate the approriate interrupt */
 if (rwx == 2) {
-ppc_hash64_set_isi(cs, env, SRR1_PROTFAULT);
+ppc_hash64_set_isi(cs, SRR1_PROTFAULT);
 } else {
 int dsisr = DSISR_PROTFAULT;
 if (rwx == 1) {
 dsisr |= DSISR_ISSTORE;
 }
-ppc_hash64_set_dsi(cs, env, eaddr, dsisr);
+ppc_hash64_set_dsi(cs, eaddr, dsisr);
 }
 return 1;
 }
@@ -783,7 +783,7 @@ skip_slb_search:
 
 /* 3. Check for segment level no-execute violation */
 if ((rwx == 2) && (slb->vsid & SLB_VSID_N)) {
-ppc_hash64_set_isi(cs, env, SRR1_NOEXEC_GUARD);
+ppc_hash64_set_isi(cs, SRR1_NOEXEC_GUARD);
 return 1;
 }
 
@@ -791,13 +791,13 @@ skip_slb_search:
 ptex = ppc_hash64_htab_lookup(cpu, slb, eaddr, , );
 if (ptex == -1) {
 if (rwx == 2) {
-ppc_hash64_set_isi(cs, env, SRR1_NOPTE);
+ppc_hash64_set_isi(cs, SRR1_NOPTE);
 } else {
 int dsisr = DSISR_NOPTE;
 if (rwx == 1) {
 dsisr |= DSISR_ISSTORE;
 }
-ppc_hash64_set_dsi(cs, env, eaddr, dsisr);
+ppc_hash64_set_dsi(cs, eaddr, dsisr);
 }
 return 1;
 }
@@ -824,7 +824,7 @@ skip_slb_search:
 if (PAGE_EXEC & ~amr_prot) {
 srr1 |= SRR1_IAMR; /* Access violates virt pg class key prot */
 }
-ppc_hash64_set_isi(cs, env, srr1);
+ppc_hash64_set_isi(cs, srr1);
 } else {
 int dsisr = 0;
 if (need_prot[rwx] & ~pp_prot) {
@@ -836,7 +836,7 @@ skip_slb_search:
 if (need_prot[rwx] & ~amr_prot) {
 dsisr |= DSISR_AMR;
 }
-ppc_hash64_set_dsi(cs, env, eaddr, dsisr);
+ppc_hash64_set_dsi(cs, eaddr, dsisr);
 }
 return 1;
 }
@@ -942,8 +942,9 @@ void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu, 
target_ulong ptex,
 cpu->env.tlb_need_flush = TLB_NEED_GLOBAL_FLUSH | TLB_NEED_LOCAL_FLUSH;
 }
 
-void ppc_hash64_update_rmls(CPUPPCState *env)
+void ppc_hash64_update_rmls(PowerPCCPU *cpu)
 {
+CPUPPCState *env = >env;
 uint64_t lpcr = env->spr[SPR_LPCR];
 
 /*
@@ -976,8 +977,9 @@ void ppc_hash64_update_rmls(CPUPPCState *env)
 }
 }
 
-void ppc_hash64_update_vrma(CPUPPCState *env)
+void ppc_hash64_update_vrma(PowerPCCPU *cpu)
 {
+CPUPPCState *env = >env;
 const struct ppc_one_seg_page_size *sps = NULL;
 target_ulong esid, vsid, lpcr;
 ppc_slb_t *slb = >vrma_slb;
@@ -1002,7 +1004,7 @@ void ppc_hash64_update_vrma(CPUPPCState *env)
 vsid |= (vrmasd << 4) & (SLB_VSID_L | SLB_VSID_LP);
 esid = SLB_ESID_V;
 
-   for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) {
+for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) {
 const struct ppc_one_seg_page_size *sps1 = >sps.sps[i];
 
 if 

[Qemu-devel] [RFC for-2.13 00/12] target/ppc: Assorted cpu cleanups (esp. hash64 MMU)

2018-03-26 Thread David Gibson
Here's a set of cleanups for the ppc cpu code.  Most are related
specifically to the 64-bit hash MMU, but there are some others as
well.

In particular it establishes a new structure PPCHash64Options which
contains details of the hash64 mmu which can vary from one cpu to
another.  This attempts to gather such options in one place, instead
of spreading them around various bits of env->mmu_model as well as
other fields.

Most of these arose while I was looking to improve the way we handle
available page sizes for the pseries machine type, although they're
mostly not closely tied to that.

David Gibson (12):
  target/ppc: Standardize instance_init and realize function names
  target/ppc: Simplify cpu valid check in ppc_cpu_realize
  target/ppc: Pass cpu instead of env to ppc_create_page_sizes_prop()
  target/ppc: Avoid taking "env" parameter to mmu-hash64 functions
  target/ppc: Remove fallback 64k pagesize information
  target/ppc: Move page size setup to helper function
  target/ppc: Split page size information into a separate allocation
  target/ppc: Make hash64_opts field mandatory for 64-bit hash MMUs
  target/ppc: Move 1T segment and AMR options to PPCHash64Options
  target/ppc: Fold ci_large_pages flag into PPCHash64Options
  target/ppc: Remove unnecessary POWERPC_MMU_V3 flag from mmu_model
  target/ppc: Get rid of POWERPC_MMU_VER() macros

 hw/ppc/fdt.c|   7 +--
 hw/ppc/pnv.c|   7 +--
 hw/ppc/spapr.c  |   9 ++--
 include/hw/ppc/fdt.h|   2 +-
 target/ppc/cpu-qom.h|  27 ++
 target/ppc/cpu.h|  23 +
 target/ppc/kvm.c|  29 +--
 target/ppc/mmu-hash64.c | 123 +---
 target/ppc/mmu-hash64.h |  41 ++-
 target/ppc/mmu_helper.c |  24 -
 target/ppc/translate.c  |  12 ++---
 target/ppc/translate_init.c | 111 +--
 12 files changed, 205 insertions(+), 210 deletions(-)

-- 
2.14.3




[Qemu-devel] [Bug 1187334] Re: crash on hot-unplug of vmxnet3

2018-03-26 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

** Changed in: qemu
   Status: Incomplete => Expired

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1187334

Title:
  crash on hot-unplug of vmxnet3

Status in QEMU:
  Expired

Bug description:
  Hot-unplug of a vmxnet3 device crashes as follows:

  (qemu) device_add id=ff,driver=vmxnet3
  [vmxnet3][WR][vmxnet3_peer_has_vnet_hdr]: Peer has no virtio extension. Task 
offloads will be emulated.
  (qemu) device_del ff
  (qemu) qemu-system-x86_64: /home/pbonzini/work/upstream/qemu/net/net.c:315: 
qemu_del_net_client: Assertion `queues != 0' failed.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1187334/+subscriptions



[Qemu-devel] [PATCH RESEND v10] vhost: used_memslots refactoring

2018-03-26 Thread Jay Zhou
Used_memslots is shared by vhost kernel and user, it is equal to
dev->mem->nregions, which is correct for vhost kernel, but not for
vhost user, the latter one uses memory regions that have file
descriptor. E.g. a VM has a vhost-user NIC and 8(vhost user memslot
upper limit) memory slots, it will be failed to hotplug a new DIMM
device since vhost_has_free_slot() finds no free slot left. It
should be successful if only part of memory slots have file
descriptor, so setting used memslots for vhost-user and
vhost-kernel respectively.

Signed-off-by: Igor Mammedov 
Signed-off-by: Jay Zhou 
Signed-off-by: Liuzhe 
---

v10:
 - fix misaligned access to structures
 - refine on setting used_memslots for vhost-user to
   avoid side effect
 - distinguish "has free memslots" and "out of memslots"
v7 ... v9:
 - rebased on the master
v2 ... v6:
 - delete the "used_memslots" global variable, and add it
   for vhost-user and vhost-kernel separately
 - refine the function, commit log
 - used_memslots refactoring

 hw/virtio/vhost-backend.c | 21 -
 hw/virtio/vhost-user.c| 36 +---
 hw/virtio/vhost.c | 13 ++---
 include/hw/virtio/vhost-backend.h |  8 ++--
 4 files changed, 65 insertions(+), 13 deletions(-)

diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index 7f09efa..3539b5f 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -15,6 +15,8 @@
 #include "hw/virtio/vhost-backend.h"
 #include "qemu/error-report.h"
 
+static unsigned int vhost_kernel_used_memslots;
+
 static int vhost_kernel_call(struct vhost_dev *dev, unsigned long int request,
  void *arg)
 {
@@ -62,6 +64,21 @@ static int vhost_kernel_memslots_limit(struct vhost_dev *dev)
 return limit;
 }
 
+static void vhost_kernel_set_used_memslots(struct vhost_dev *dev)
+{
+vhost_kernel_used_memslots = dev->mem->nregions;
+}
+
+static bool vhost_kernel_has_free_memslots(struct vhost_dev *dev)
+{
+return vhost_kernel_used_memslots < vhost_kernel_memslots_limit(dev);
+}
+
+static bool vhost_kernel_out_of_memslots(struct vhost_dev *dev)
+{
+return vhost_kernel_used_memslots > vhost_kernel_memslots_limit(dev);
+}
+
 static int vhost_kernel_net_set_backend(struct vhost_dev *dev,
 struct vhost_vring_file *file)
 {
@@ -237,7 +254,9 @@ static const VhostOps kernel_ops = {
 .backend_type = VHOST_BACKEND_TYPE_KERNEL,
 .vhost_backend_init = vhost_kernel_init,
 .vhost_backend_cleanup = vhost_kernel_cleanup,
-.vhost_backend_memslots_limit = vhost_kernel_memslots_limit,
+.vhost_set_used_memslots = vhost_kernel_set_used_memslots,
+.vhost_backend_has_free_memslots = vhost_kernel_has_free_memslots,
+.vhost_out_of_memslots = vhost_kernel_out_of_memslots,
 .vhost_net_set_backend = vhost_kernel_net_set_backend,
 .vhost_scsi_set_endpoint = vhost_kernel_scsi_set_endpoint,
 .vhost_scsi_clear_endpoint = vhost_kernel_scsi_clear_endpoint,
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 44aea5c..9691806 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -170,6 +170,8 @@ static VhostUserMsg m __attribute__ ((unused));
 /* The version of the protocol we support */
 #define VHOST_USER_VERSION(0x1)
 
+static unsigned int vhost_user_used_memslots;
+
 struct vhost_user {
 struct vhost_dev *dev;
 CharBackend *chr;
@@ -1289,9 +1291,35 @@ static int vhost_user_get_vq_index(struct vhost_dev 
*dev, int idx)
 return idx;
 }
 
-static int vhost_user_memslots_limit(struct vhost_dev *dev)
+static void vhost_user_set_used_memslots(struct vhost_dev *dev)
+{
+int i, fd;
+unsigned int fd_num = 0;
+
+for (i = 0; i < dev->mem->nregions; ++i) {
+struct vhost_memory_region *reg = dev->mem->regions + i;
+ram_addr_t offset;
+MemoryRegion *mr;
+
+assert((uintptr_t)reg->userspace_addr == reg->userspace_addr);
+mr = memory_region_from_host((void *)(uintptr_t)reg->userspace_addr,
+ );
+fd = memory_region_get_fd(mr);
+if (fd > 0) {
+fd_num++;
+}
+}
+vhost_user_used_memslots = fd_num;
+}
+
+static bool vhost_user_has_free_memslots(struct vhost_dev *dev)
+{
+return vhost_user_used_memslots < VHOST_MEMORY_MAX_NREGIONS;
+}
+
+static bool vhost_user_out_of_memslots(struct vhost_dev *dev)
 {
-return VHOST_MEMORY_MAX_NREGIONS;
+return vhost_user_used_memslots > VHOST_MEMORY_MAX_NREGIONS;
 }
 
 static bool vhost_user_requires_shm_log(struct vhost_dev *dev)
@@ -1563,7 +1591,9 @@ const VhostOps user_ops = {
 .backend_type = VHOST_BACKEND_TYPE_USER,
 .vhost_backend_init = vhost_user_init,
 .vhost_backend_cleanup = vhost_user_cleanup,
-

[Qemu-devel] [PATCH for-2.12] tcg: Mark muluh_i64 and mulsh_i64 as 64-bit ops

2018-03-26 Thread Richard Henderson
Failure to do so results in the tcg optimizer sign-extending
any constant fold from 32-bits.  This turns out to be visible
in the RISC-V testsuite using a host that emits these opcodes
(e.g. any non-x86_64).

Reported-by: Michael Clark 
Signed-off-by: Richard Henderson 
---
 tcg/tcg-opc.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
index d81a6c4535..e3a43aabb6 100644
--- a/tcg/tcg-opc.h
+++ b/tcg/tcg-opc.h
@@ -182,8 +182,8 @@ DEF(add2_i64, 2, 4, 0, IMPL64 | 
IMPL(TCG_TARGET_HAS_add2_i64))
 DEF(sub2_i64, 2, 4, 0, IMPL64 | IMPL(TCG_TARGET_HAS_sub2_i64))
 DEF(mulu2_i64, 2, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_mulu2_i64))
 DEF(muls2_i64, 2, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_muls2_i64))
-DEF(muluh_i64, 1, 2, 0, IMPL(TCG_TARGET_HAS_muluh_i64))
-DEF(mulsh_i64, 1, 2, 0, IMPL(TCG_TARGET_HAS_mulsh_i64))
+DEF(muluh_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_muluh_i64))
+DEF(mulsh_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_mulsh_i64))
 
 #define TLADDR_ARGS  (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? 1 : 2)
 #define DATA64_ARGS  (TCG_TARGET_REG_BITS == 64 ? 1 : 2)
-- 
2.14.3




Re: [Qemu-devel] [PATCH] scsi-disk: Don't enlarge min_io_size to max_io_size

2018-03-26 Thread David Gibson
On Mon, 26 Mar 2018 15:26:39 +0800
Fam Zheng  wrote:

> On Thu, 03/22 09:19, Daniel Henrique Barboza wrote:
> > Hi,
> > 
> > On 03/22/2018 04:38 AM, Fam Zheng wrote:  
> > > Some backends report big max_io_sectors. Making min_io_size the same
> > > value in this case will make it impossible for guest to align memory,
> > > therefore the disk may not be usable at all.
> > > 
> > > Change the default behavior (when min_io_size and opt_io_size are not
> > > specified in the command line), do not assume max_io_sectors is a good
> > > value for opt_io_size and min_io_size, use 512 instead.
> > > 
> > > Reported-by: David Gibson 
> > > Signed-off-by: Fam Zheng 
> > > ---
> > >   hw/scsi/scsi-disk.c | 6 ++
> > >   1 file changed, 2 insertions(+), 4 deletions(-)
> > > 
> > > diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
> > > index 5b7a48f5a5..76e3c9eaa4 100644
> > > --- a/hw/scsi/scsi-disk.c
> > > +++ b/hw/scsi/scsi-disk.c
> > > @@ -714,10 +714,8 @@ static int scsi_disk_emulate_inquiry(SCSIRequest 
> > > *req, uint8_t *outbuf)
> > > 
> > >   /* min_io_size and opt_io_size can't be greater than
> > >* max_io_sectors */
> > > -min_io_size =
> > > -MIN_NON_ZERO(min_io_size, max_io_sectors);
> > > -opt_io_size =
> > > -MIN_NON_ZERO(opt_io_size, max_io_sectors);
> > > +min_io_size = MIN(min_io_size ? : 512, max_io_sectors);
> > > +opt_io_size = MIN(opt_io_size ? : 512, max_io_sectors);
> > >   }  
> > 
> > This code you're changing was added in d082d16a5c ("consider
> > bl->max_transfer ..").
> > I've borrowed this logic from scsi-generic.c, scsi_read_complete:
> > 
> >     if (s->type == TYPE_DISK &&
> >     r->req.cmd.buf[0] == INQUIRY &&
> >     r->req.cmd.buf[2] == 0xb0) {
> >     uint32_t max_transfer =
> >     blk_get_max_transfer(s->conf.blk) / s->blocksize;
> > 
> >     assert(max_transfer);
> >     stl_be_p(>buf[8], max_transfer);
> >     /* Also take care of the opt xfer len. */
> >     stl_be_p(>buf[12],
> >  MIN_NON_ZERO(max_transfer, ldl_be_p(>buf[12])));
> >     }
> > 
> > 
> > Unless I've misunderstood the bug, you will want to change this code too.
> > Otherwise
> > you'll fix it with emulated disks but it might appear when using SCSI
> > passthrough.  
> 
> I am assuming (because I don't have a reproducer myself)

Sorry, I should have given you specific reproduce instructions.  You
don't need a POWER host - I've verified that the bug trips under TCG.

  1. Grab a RHEL ppc64le install image (other installers could well
 also hit it, but I haven't tried them)
  2. Build current qemu master, including the ppc64-softmmu target
  3. Create a fresh new guest disk image
qemu-img create -f qcow2 disk.qcow2 20G
  4. Attempt to install the new guest:
$QEMU -nodefaults -nographic -machine pseries \
  -cpu POWER8 -smp 1 -m 1G \
  -chardev stdio,id=conmon,mux=on,signal=off \
  -device spapr-vty,chardev=conmon \
  -mon conmon \
  -device virtio-scsi-pci,id=scsi \
  -drive file=disk.qcow2,if=none,format=qcow2,id=hd \
  -device scsi-disk,drive=hd,bus=scsi.0 \
  -drive 
file=RHEL-7.4-20170711.0-Server-ppc64le-dvd1.iso,format=raw,media=cdrom,if=none,id=cd
 \
  -device scsi-cd,drive=cd,bus=scsi.0

That's using the RHEL7.4 GA image, a recent 7.5 snapshot also works as may 
others.

> what matters is
> min_io_size here.
> 
> David, could you help test if you see the same problem with "-device
> scsi-block"? If we I'll patch scsi-generic.c in v2 too.

I'm not sure exactly what you want me to check here?  You mean putting
the guest disk on a scsi-block instead of scsi-disk?  That's a bit more
fiddly, since I have to find a block device to back it instead of an
image.

-- 
David Gibson 
Principal Software Engineer, Virtualization, Red Hat


pgpIaCeTm5lby.pgp
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH 1/8] migration: stop compressing page in migration thread

2018-03-26 Thread Xiao Guangrong



On 03/26/2018 05:02 PM, Peter Xu wrote:

On Thu, Mar 22, 2018 at 07:38:07PM +0800, Xiao Guangrong wrote:



On 03/21/2018 04:19 PM, Peter Xu wrote:

On Fri, Mar 16, 2018 at 04:05:14PM +0800, Xiao Guangrong wrote:


Hi David,

Thanks for your review.

On 03/15/2018 06:25 PM, Dr. David Alan Gilbert wrote:


migration/ram.c | 32 


Hi,
 Do you have some performance numbers to show this helps?  Were those
taken on a normal system or were they taken with one of the compression
accelerators (which I think the compression migration was designed for)?


Yes, i have tested it on my desktop, i7-4790 + 16G, by locally live migrate
the VM which has 8 vCPUs + 6G memory and the max-bandwidth is limited to 350.

During the migration, a workload which has 8 threads repeatedly written total
6G memory in the VM. Before this patchset, its bandwidth is ~25 mbps, after
applying, the bandwidth is ~50 mbps.


Hi, Guangrong,

Not really review comments, but I got some questions. :)


Your comments are always valuable to me! :)



IIUC this patch will only change the behavior when last_sent_block
changed.  I see that the performance is doubled after the change,
which is really promising.  However I don't fully understand why it
brings such a big difference considering that IMHO current code is
sending dirty pages per-RAMBlock.  I mean, IMHO last_sent_block should
not change frequently?  Or am I wrong?


It's depends on the configuration, each memory-region which is ram or
file backend has a RAMBlock.

Actually, more benefits comes from the fact that the performance & throughput
of the multithreads has been improved as the threads is fed by the
migration thread and the result is consumed by the migration
thread.


I'm not sure whether I got your points - I think you mean that the
compression threads and the migration thread can form a better
pipeline if the migration thread does not do any compression at all.

I think I agree with that.

However it does not really explain to me on why a very rare event
(sending the first page of a RAMBlock, considering bitmap sync is
rare) can greatly affect the performance (it shows a doubled boost).



I understand it is trick indeed, but it is not very hard to explain.
Multi-threads (using 8 CPUs in our test) keep idle for a long time
for the origin code, however, after our patch, as the normal is
posted out async-ly that it's extremely fast as you said (the network
is almost idle for current implementation) so it has a long time that
the CPUs can be used effectively to generate more compressed data than
before.


Btw, about the numbers: IMHO the numbers might not be really "true
numbers".  Or say, even the bandwidth is doubled, IMHO it does not
mean the performance is doubled. Becasue the data has changed.

Previously there were only compressed pages, and now for each cycle of
RAMBlock looping we'll send a normal page (then we'll get more thing
to send).  So IMHO we don't really know whether we sent more pages
with this patch, we can only know we sent more bytes (e.g., an extreme
case is that the extra 25Mbps/s are all caused by those normal pages,
and we can be sending exactly the same number of pages like before, or
even worse?).



Current implementation uses CPU very ineffectively (it's our next work
to be posted out) that the network is almost idle so posting more data
out is a better choice,further more, migration thread plays a role for
parallel, it'd better to make it fast.





Another follow-up question would be: have you measured how long time
needed to compress a 4k page, and how many time to send it?  I think
"sending the page" is not really meaningful considering that we just
put a page into the buffer (which should be extremely fast since we
don't really flush it every time), however I would be curious on how
slow would compressing a page be.


I haven't benchmark the performance of zlib, i think it is CPU intensive
workload, particularly, there no compression-accelerator (e.g, QAT) on
our production. BTW, we were using lzo instead of zlib which worked
better for some workload.


Never mind. Good to know about that.



Putting a page into buffer should depend on the network, i,e, if the
network is congested it should take long time. :)


Again, considering that I don't know much on compression (especially I
hardly used that) mine are only questions, which should not block your
patches to be either queued/merged/reposted when proper. :)


Yes, i see. The discussion can potentially raise a better solution.

Thanks for your comment, Peter!



Re: [Qemu-devel] [PATCH v1] RISC-V: RISC-V TCG backend work in progress

2018-03-26 Thread Richard Henderson
On 03/27/2018 08:26 AM, Michael Clark wrote:
> IN:
> 0x00011138:  82b7  lui t0,-2147483648
> 0x0001113c:  8337  lui t1,-32768
> 0x00011140:  0262a433  mulhsu  s0,t0,t1
> 0x00011144:  84b7  lui s1,-2147483648
> 0x00011148:  00700193  addigp,zero,7
> 0x0001114c:  f49412e3  bne s0,s1,-188

At last something interesting.

-2147483648 * 18446744073709518848 (0x___8000)
= -39614081257132098428027797504
= -7FFF___C000__
=  __8000_ _0400__


> OP after optimization and liveness analysis:
>  ld_i32 tmp0,env,$0xffec  dead: 1
>  movi_i32 tmp1,$0x0
>  brcond_i32 tmp0,tmp1,lt,$L0  dead: 0 1
> 
>   00011138
>  movi_i64 t0  ,$0x8000sync: 0  dead: 0
> 
>   0001113c
>  movi_i64 t1  ,$0x8000sync: 0  dead: 0
> 
>   00011140
>  movi_i64 tmp2,$0x8000
>  mov_i64 s0  ,tmp2sync: 0  dead: 0 1
> 
>   00011144
>  movi_i64 s1  ,$0x8000sync: 0  dead: 0

So, yes, your test is correct, because here we load that high-part.  But
crucially, the multiply has produced a result *without* the sign-extension, so
the test fails.

It would have been handy to see the opcodes emitted before optimization, so
that we can verify what the riscv front-end did.  However, it's not that hard
to regenerate.

Annoyingly, the tcg optimizer hasn't been taught to fold things the same way
when the backend supports mulu2, so we *don't* fold the test away for an x86_64
host.

 mulu2_i64 tmp4,tmp5,t0  ,t1  dead: 0 2 3
 movi_i64 tmp4,$0x8000
 sub_i64 tmp2,tmp5,tmp4   dead: 1 2
 mov_i64 s0  ,tmp2sync: 0  dead: 0 1

And thus no doubt the test succeeds for that case.
So lemme try again with an aarch64 host.

 movi_i64 tmp2,$0x8000
 mov_i64 s0  ,tmp2sync: 0  dead: 0 1

Yay, reproduction.  The input to the optimization is

 mov_i64 tmp2,t0
 mov_i64 tmp3,t1
 mul_i64 tmp6,tmp2,tmp3
 muluh_i64 tmp5,tmp2,tmp3
 mov_i64 tmp4,tmp6
 movi_i64 tmp6,$0x3f
 sar_i64 tmp4,tmp2,tmp6
 and_i64 tmp4,tmp4,tmp3
 sub_i64 tmp2,tmp5,tmp4
 mov_i64 s0  ,tmp2

Now, dead-code and forward propagate constants by hand,

 movi_i64 tmp2,$0x8000
 movi_i64 tmp3,$0x8000
 muluh_i64 tmp5,tmp2,tmp3
 sub_i64 tmp2,tmp5,$0x8000
 mov_i64 s0  ,tmp2

Now, for the unsigned multiplication we get

18446744071562067968 * 18446744073709518848
= 34028236688132343332701689153060864
= __7FFF_8000 _4000__



Oops, I see the bug right away now.

Value returned is $3 = 18446744071562035200
(gdb) n
410 if (!(def->flags & TCG_OPF_64BIT)) {
411 res = (int32_t)res;

Failure to mark muluh_i64 and mulsh_i64 as 64-bit ops, so we've discarded the
high 32 bits of the result.

I'm surprised that we haven't seen this as a problem before.  Perhaps luck in
non-optimization; we need a test case this small (but no smaller, like RISU) to
be able to produce a bad result.

So.  Two line patch to follow.


r~



Re: [Qemu-devel] [PATCH v2 1/1] iotests: fix test case 185

2018-03-26 Thread QingFeng Hao



在 2018/3/26 18:29, Kevin Wolf 写道:

Am 23.03.2018 um 04:43 hat QingFeng Hao geschrieben:

Test case 185 failed since commit 4486e89c219 --- "vl: introduce vm_shutdown()".
It's because of the newly introduced function vm_shutdown calls bdrv_drain_all,
which is called later by bdrv_close_all. bdrv_drain_all resumes the jobs
that doubles the speed and offset is doubled.
Some jobs' status are changed as well.

The fix is to not resume the jobs that are already yielded and also change
185.out accordingly.

Suggested-by: Stefan Hajnoczi 
Signed-off-by: QingFeng Hao 


Stefan already commented on the fix itself, but I want to add two more
points:

Please change your subject line. "iotests: fix test case 185" means that
you are fixing the test case, not qemu code that makes the test case
fail. The subject line should describe the actual change. In all
likelihood it will start with "blockjob:" rather than "iotests:".

Sure! thanks for pointing that.



diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index fc645dac68..f8f208bbcf 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -99,6 +99,11 @@ typedef struct BlockJob {
  bool ready;
  
  /**

+ * Set to true when the job is yielded.
+ */
+bool yielded;


This is the same as !busy, so we don't need a new field for this.

Mostly yes, but the trick is that busy is set to be true in 
block_job_do_yield.

Kevin



--
Regards
QingFeng Hao




Re: [Qemu-devel] [PATCH v2 1/1] iotests: fix test case 185

2018-03-26 Thread QingFeng Hao


在 2018/3/23 18:04, Stefan Hajnoczi 写道:

On Fri, Mar 23, 2018 at 3:43 AM, QingFeng Hao  wrote:

Test case 185 failed since commit 4486e89c219 --- "vl: introduce vm_shutdown()".
It's because of the newly introduced function vm_shutdown calls bdrv_drain_all,
which is called later by bdrv_close_all. bdrv_drain_all resumes the jobs
that doubles the speed and offset is doubled.
Some jobs' status are changed as well.

The fix is to not resume the jobs that are already yielded and also change
185.out accordingly.

Suggested-by: Stefan Hajnoczi 
Signed-off-by: QingFeng Hao 
---
  blockjob.c | 10 +-
  include/block/blockjob.h   |  5 +
  tests/qemu-iotests/185.out | 11 +--


If drain no longer forces the block job to iterate, shouldn't the test
output remain the same?  (The means the test is fixed by the QEMU
patch.)


  3 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/blockjob.c b/blockjob.c
index ef3ed69ff1..fa9838ac97 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -206,11 +206,16 @@ void block_job_txn_add_job(BlockJobTxn *txn, BlockJob 
*job)

  static void block_job_pause(BlockJob *job)
  {
-job->pause_count++;
+if (!job->yielded) {
+job->pause_count++;
+}


The pause cannot be ignored.  This change introduces a bug.

Pause is not a synchronous operation that stops the job immediately.
Pause just remembers that the job needs to be paused.   When the job
runs again (e.g. timer callback, fd handler) it eventually reaches
block_job_pause_point() where it really pauses.

The bug in this patch is:

1. The job has a timer pending.
2. block_job_pause() is called during drain.
3. The timer fires during drain but now the job doesn't know it needs
to pause, so it continues running!

Instead what needs to happen is that block_job_pause() remains
unmodified but block_job_resume if extended:

static void block_job_resume(BlockJob *job)
{
 assert(job->pause_count > 0);
 job->pause_count--;
 if (job->pause_count) {
 return;
 }
+if (job_yielded_before_pause_and_is_still_yielded) {
Thanks a lot for your great comments! But I can't figure out how to 
check this.

 block_job_enter(job);
+}
}

This handles the case I mentioned above, where the yield ends before
pause ends (therefore resume must enter the job!).

To make this a little clearer, there are two cases to consider:

Case 1:
1. Job yields
2. Pause
3. Job is entered from timer/fd callback

How do I know that if job is entered from ...? thanks

4. Resume (enter job? yes)

Case 2:
1. Job yields
2. Pause
3. Resume (enter job? no)
4. Job is entered from timer/fd callback

Stefan



--
Regards
QingFeng Hao




Re: [Qemu-devel] [PATCH v2 4/5] qdict: remove useless cast

2018-03-26 Thread Fam Zheng
On Fri, 03/23 15:32, Laurent Vivier wrote:
> Re-run Coccinelle script scripts/coccinelle/qobject.cocci
> 
> Signed-off-by: Laurent Vivier 

This time for the right revision of the patch:

Acked-by: Fam Zheng 



Re: [Qemu-devel] [PATCH 3/4] qdict: remove useless cast

2018-03-26 Thread Fam Zheng
On Thu, 03/22 17:12, Laurent Vivier wrote:
> Re-run Coccinelle script scripts/coccinelle/qobject.cocci
> 
> Signed-off-by: Laurent Vivier 

Acked-by: Fam Zheng 



Re: [Qemu-devel] [PATCH v2 0/4] Monitor: OOB related patches

2018-03-26 Thread Peter Xu
On Mon, Mar 26, 2018 at 08:36:16PM -0500, Eric Blake wrote:
> This is patches 2, 3, 7, and 8 (with 7 rewritten) from Peter Xu's
> series.  I've pushed them to git://repo.or.cz/qemu/ericb.git qapi-next
> (on top of the other pending qapi patches at branch qapi); hopefully
> this will be part of my pull request tomorrow for -rc1.
> 
> Eric Blake (1):
>   tests: Add parameter to qtest_init_without_qmp_handshake
> 
> Peter Xu (3):
>   qmp: cleanup qmp queues properly
>   monitor: new parameter "x-oob"
>   tests: qmp-test: add test for new "x-oob"
> 
>  tests/libqtest.h  |  7 +++-
>  include/monitor/monitor.h |  1 +
>  vl.c  |  5 +++
>  tests/libqtest.c  | 10 +++--
>  monitor.c | 94 
> ---
>  tests/qmp-test.c  | 84 +-
>  6 files changed, 173 insertions(+), 28 deletions(-)

All of them look good to me.

Thanks Eric!

-- 
Peter Xu



Re: [Qemu-devel] [PATCH for-2.12 2/8] qmp: cleanup qmp queues properly

2018-03-26 Thread Peter Xu
On Mon, Mar 26, 2018 at 02:42:23PM -0500, Eric Blake wrote:
> On 03/26/2018 01:38 AM, Peter Xu wrote:
> > Marc-André Lureau reported that we can have this happen:
> > 
> > 1. client1 connects, send command C1
> > 2. client1 disconnects before getting response for C1
> > 3. client2 connects, who might receive response of C1
> > 
> > However client2 should not receive remaining responses for client1.
> > 
> > Basically, we should clean up the request/response queue elements when:
> > 
> > - before a session established
> 
> Why here? [1]

Yes it can be omitted. We can do it either here or closing, the only
difference should be that when added here there's more possibility
that the pending commands (requests from disconnected clients) be
executed rather than dropped.

Here I did the cleanup on both places.  Drop any of them would be fine
too.

> 
> > - after a session is closed
> > - before destroying the queues
> > 
> > Some helpers are introduced to achieve that.  We need to make sure we're
> > with the lock when operating on those queues.
> > 
> 
> It would also be helpful to mention that the patch includes code motion to
> declare struct QMPRequest earlier in the file.
> 
> > Reported-by: Marc-André Lureau 
> > Signed-off-by: Peter Xu 
> > ---
> >   monitor.c | 79 
> > +++
> >   1 file changed, 59 insertions(+), 20 deletions(-)
> > 
> 
> > +static void qmp_request_free(QMPRequest *req)
> > +{
> > +qobject_decref(req->id);
> > +qobject_decref(req->req);
> > +g_free(req);
> > +}
> > +
> > +static void qmp_response_free(QObject *obj)
> > +{
> > +qobject_decref(obj);
> > +}
> 
> Why do we need this function?  Unless you plan to add to it in later
> patches, I'd rather just inline things and directly call qobject_decref() at
> the callsites...

Yes we can omit that.

> 
> > +
> > +/* Must with the mon->qmp.qmp_queue_lock held */
> > +static void monitor_qmp_cleanup_req_queue_locked(Monitor *mon)
> > +{
> > +while (!g_queue_is_empty(mon->qmp.qmp_requests)) {
> > +qmp_request_free(g_queue_pop_head(mon->qmp.qmp_requests));
> > +}
> > +}
> > +
> > +/* Must with the mon->qmp.qmp_queue_lock held */
> > +static void monitor_qmp_cleanup_resp_queue_locked(Monitor *mon)
> > +{
> > +while (!g_queue_is_empty(mon->qmp.qmp_responses)) {
> > +qmp_response_free(g_queue_pop_head(mon->qmp.qmp_responses));
> 
> ...here,
> 
> > +}
> > +}
> > +
> > +static void monitor_qmp_cleanup_queues(Monitor *mon)
> > +{
> > +qemu_mutex_lock(>qmp.qmp_queue_lock);
> > +monitor_qmp_cleanup_req_queue_locked(mon);
> > +monitor_qmp_cleanup_resp_queue_locked(mon);
> > +qemu_mutex_unlock(>qmp.qmp_queue_lock);
> > +}
> > +
> > +
> >   static void monitor_flush_locked(Monitor *mon);
> >   static gboolean monitor_unblocked(GIOChannel *chan, GIOCondition cond,
> > @@ -497,7 +550,7 @@ static void monitor_qmp_bh_responder(void *opaque)
> >   break;
> >   }
> >   monitor_json_emitter_raw(response.mon, response.data);
> > -qobject_decref(response.data);
> > +qmp_response_free(response.data);
> 
> and here.
> 
> > @@ -4327,6 +4364,7 @@ static void monitor_qmp_event(void *opaque, int event)
> >   switch (event) {
> >   case CHR_EVENT_OPENED:
> > +monitor_qmp_cleanup_queues(mon);
> 
> [1] How would something be queued to need cleanup at this point, if we
> already start with a clean queue before the first monitor, and if all
> monitor close actions clean the queue?

(answered above)

Thanks,

-- 
Peter Xu



Re: [Qemu-devel] [PATCH for-2.12 0/8] Monitor: some oob related patches (fixes, new param, tests)

2018-03-26 Thread Peter Xu
On Mon, Mar 26, 2018 at 12:18:28PM +0200, Christian Borntraeger wrote:
> Thanks for the quick fixing. This series on top of master
> works fine on s390. (make check and iotests)

Appreciate the quick follow up.  Thanks Christian.

-- 
Peter Xu



[Qemu-devel] PATCH [02/02] leon3: add smp cpu index to asr17

2018-03-26 Thread Steven Seeger
>From 1ba3070160d5baab73ba9e500ed58d0ace7121aa Mon Sep 17 00:00:00 2001
From: Steven Seeger 
Date: Mon, 26 Mar 2018 20:50:53 -0400
Subject: [PATCH 2/6] leon3: add smp cpu index to asr17

Signed-off-by: Steven Seeger 
---
 target/sparc/helper.c| 5 +
 target/sparc/helper.h| 1 +
 target/sparc/translate.c | 1 +
 3 files changed, 7 insertions(+)

diff --git a/target/sparc/helper.c b/target/sparc/helper.c
index 1d854890b4..8304c3e3f3 100644
--- a/target/sparc/helper.c
+++ b/target/sparc/helper.c
@@ -117,6 +117,11 @@ target_ulong helper_udiv_cc(CPUSPARCState *env, 
target_ulong a, target_ulong b)
 return do_udiv(env, a, b, 1, GETPC());
 }
 
+target_ulong helper_asr17(CPUSPARCState *env, target_ulong input)
+{
+return input | (CPU(sparc_env_get_cpu(env))->cpu_index << 28);
+}
+
 static target_ulong do_sdiv(CPUSPARCState *env, target_ulong a,
 target_ulong b, int cc, uintptr_t ra)
 {
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
index b8f1e78c75..fe6554fd76 100644
--- a/target/sparc/helper.h
+++ b/target/sparc/helper.h
@@ -166,3 +166,4 @@ VIS_CMPHELPER(cmpne)
 #undef VIS_CMPHELPER
 DEF_HELPER_1(compute_psr, void, env)
 DEF_HELPER_FLAGS_1(compute_C_icc, TCG_CALL_NO_WG_SE, i32, env)
+DEF_HELPER_2(asr17, tl, env, tl)
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index ab8d0a0c72..de482952e1 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -3440,6 +3440,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned 
int insn)
 TCGv t = gen_dest_gpr(dc, rd);
 /* Read Asr17 for a Leon3 monoprocessor */
 tcg_gen_movi_tl(t, (1 << 8) | (dc->def->nwindows - 
1));
+gen_helper_asr17(t, cpu_env, t);
 gen_store_gpr(dc, rd, t);
 break;
 }
-- 
2.16.1







[Qemu-devel] [PATCH 01/02] leon3: change the handling for ASI_LEON_NOCACHE to be aware of if the MMU is enabled or not

2018-03-26 Thread Steven Seeger
>From f512606776e20dc603b8ea3faaeb103667de3178 Mon Sep 17 00:00:00 2001
From: Steven Seeger 
Date: Sun, 25 Mar 2018 17:58:21 -0400
Subject: [PATCH 1/6] leon3: change the handling for ASI_LEON_NOCACHE to be
 aware of if the MMU is enabled or not

Signed-off-by: Steven Seeger 
---
 target/sparc/translate.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index f55ec28665..ab8d0a0c72 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -2121,6 +2121,9 @@ static DisasASI get_asi(DisasContext *dc, int insn, 
TCGMemOp memop)
|| (asi == ASI_USERDATA
&& (dc->def->features & CPU_FEATURE_CASA))) {
 switch (asi) {
+case ASI_LEON_NOCACHE: /* force cache miss */
+type = GET_ASI_DIRECT;
+break;
 case ASI_USERDATA:   /* User data access */
 mem_idx = MMU_USER_IDX;
 type = GET_ASI_DIRECT;
@@ -2131,7 +2134,6 @@ static DisasASI get_asi(DisasContext *dc, int insn, 
TCGMemOp memop)
 break;
 case ASI_M_BYPASS:/* MMU passthrough */
 case ASI_LEON_BYPASS: /* LEON MMU passthrough */
-case ASI_LEON_NOCACHE:
 mem_idx = MMU_PHYS_IDX;
 type = GET_ASI_DIRECT;
 break;
-- 
2.16.1






Re: [Qemu-devel] [PATCH] iotests: fix wait_until_completed()

2018-03-26 Thread Peter Xu
On Mon, Mar 26, 2018 at 12:47:39PM +0200, Kevin Wolf wrote:
> Am 26.03.2018 um 08:11 hat Peter Xu geschrieben:
> > If there are more than one events, wait_until_completed() might return
> > the 2nd event even if the 1st event is JOB_COMPLETED, since the for loop
> > will continue to run even if completed is set to True.
> > 
> > It never happened before, but it can be triggered when OOB is enabled
> > due to the RESUME startup message. Fix that up by removing the boolean
> > and make sure we return the correct event.
> > 
> > Signed-off-by: Peter Xu 
> > ---
> >  tests/qemu-iotests/iotests.py | 20 
> >  1 file changed, 8 insertions(+), 12 deletions(-)
> > 
> > diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
> > index b5d7945af8..11704e6583 100644
> > --- a/tests/qemu-iotests/iotests.py
> > +++ b/tests/qemu-iotests/iotests.py
> > @@ -470,18 +470,14 @@ class QMPTestCase(unittest.TestCase):
> >  
> >  def wait_until_completed(self, drive='drive0', check_offset=True):
> >  '''Wait for a block job to finish, returning the event'''
> > -completed = False
> > -while not completed:
> > -for event in self.vm.get_qmp_events(wait=True):
> > -if event['event'] == 'BLOCK_JOB_COMPLETED':
> > -self.assert_qmp(event, 'data/device', drive)
> > -self.assert_qmp_absent(event, 'data/error')
> > -if check_offset:
> > -self.assert_qmp(event, 'data/offset', 
> > event['data']['len'])
> > -completed = True
> > -
> > -self.assert_no_active_block_jobs()
> > -return event
> > +for event in self.vm.get_qmp_events(wait=True):
> > +if event['event'] == 'BLOCK_JOB_COMPLETED':
> > +self.assert_qmp(event, 'data/device', drive)
> > +self.assert_qmp_absent(event, 'data/error')
> > +if check_offset:
> > +self.assert_qmp(event, 'data/offset', 
> > event['data']['len'])
> > +self.assert_no_active_block_jobs()
> > +return event
> >  
> >  def wait_ready(self, drive='drive0'):
> >  '''Wait until a block job BLOCK_JOB_READY event'''
> 
> If an event is pending, but it's not the expected event, won't we return
> None now instead of waiting for the BLOCK_JOB_COMPLETED event?

If so, we'll return none.  The patch fixes the other case when there
are two events: one JOB_COMPLETED plus another (e.g., RESUME) event.
When that happens, logically we should return one JOB_COMPLETED event,
but the old code will return the other event (e.g., RESUME).

> 
> Wouldn't it be much easier to just add a 'break'?

Yes, it's the same.  But IMHO those logics (e.g., the completed
variable) are not really needed at all.  This one is simpler.

Or do you want me to post the oneliner that you prefer?

Thanks,

-- 
Peter Xu



[Qemu-devel] [PATCH v2 1/4] qmp: cleanup qmp queues properly

2018-03-26 Thread Eric Blake
From: Peter Xu 

Marc-André Lureau reported that we can have this happen:

1. client1 connects, send command C1
2. client1 disconnects before getting response for C1
3. client2 connects, who might receive response of C1

However client2 should not receive remaining responses for client1.

Basically, we should clean up the request/response queue elements when:

- before a session established
- after a session is closed
- before destroying the queues

Some helpers are introduced to achieve that.  We need to make sure we're
with the lock when operating on those queues.

Reported-by: Marc-André Lureau 
Signed-off-by: Peter Xu 
Message-Id: <20180326063901.27425-3-pet...@redhat.com>
Reviewed-by: Marc-André Lureau 
[eblake: drop pointless qmp_response_free()]
Signed-off-by: Eric Blake 
---
 monitor.c | 72 ++-
 1 file changed, 53 insertions(+), 19 deletions(-)

diff --git a/monitor.c b/monitor.c
index 3b1ef34711b..8fa18936419 100644
--- a/monitor.c
+++ b/monitor.c
@@ -234,6 +234,22 @@ static struct {
 QEMUBH *qmp_respond_bh;
 } mon_global;

+struct QMPRequest {
+/* Owner of the request */
+Monitor *mon;
+/* "id" field of the request */
+QObject *id;
+/* Request object to be handled */
+QObject *req;
+/*
+ * Whether we need to resume the monitor afterward.  This flag is
+ * used to emulate the old QMP server behavior that the current
+ * command must be completed before execution of the next one.
+ */
+bool need_resume;
+};
+typedef struct QMPRequest QMPRequest;
+
 /* QMP checker flags */
 #define QMP_ACCEPT_UNKNOWNS 1

@@ -310,6 +326,38 @@ int monitor_read_password(Monitor *mon, ReadLineFunc 
*readline_func,
 }
 }

+static void qmp_request_free(QMPRequest *req)
+{
+qobject_decref(req->id);
+qobject_decref(req->req);
+g_free(req);
+}
+
+/* Must with the mon->qmp.qmp_queue_lock held */
+static void monitor_qmp_cleanup_req_queue_locked(Monitor *mon)
+{
+while (!g_queue_is_empty(mon->qmp.qmp_requests)) {
+qmp_request_free(g_queue_pop_head(mon->qmp.qmp_requests));
+}
+}
+
+/* Must with the mon->qmp.qmp_queue_lock held */
+static void monitor_qmp_cleanup_resp_queue_locked(Monitor *mon)
+{
+while (!g_queue_is_empty(mon->qmp.qmp_responses)) {
+qobject_decref(g_queue_pop_head(mon->qmp.qmp_responses));
+}
+}
+
+static void monitor_qmp_cleanup_queues(Monitor *mon)
+{
+qemu_mutex_lock(>qmp.qmp_queue_lock);
+monitor_qmp_cleanup_req_queue_locked(mon);
+monitor_qmp_cleanup_resp_queue_locked(mon);
+qemu_mutex_unlock(>qmp.qmp_queue_lock);
+}
+
+
 static void monitor_flush_locked(Monitor *mon);

 static gboolean monitor_unblocked(GIOChannel *chan, GIOCondition cond,
@@ -701,6 +749,8 @@ static void monitor_data_destroy(Monitor *mon)
 QDECREF(mon->outbuf);
 qemu_mutex_destroy(>out_lock);
 qemu_mutex_destroy(>qmp.qmp_queue_lock);
+monitor_qmp_cleanup_req_queue_locked(mon);
+monitor_qmp_cleanup_resp_queue_locked(mon);
 g_queue_free(mon->qmp.qmp_requests);
 g_queue_free(mon->qmp.qmp_responses);
 }
@@ -4009,22 +4059,6 @@ static void monitor_qmp_respond(Monitor *mon, QObject 
*rsp,
 qobject_decref(rsp);
 }

-struct QMPRequest {
-/* Owner of the request */
-Monitor *mon;
-/* "id" field of the request */
-QObject *id;
-/* Request object to be handled */
-QObject *req;
-/*
- * Whether we need to resume the monitor afterward.  This flag is
- * used to emulate the old QMP server behavior that the current
- * command must be completed before execution of the next one.
- */
-bool need_resume;
-};
-typedef struct QMPRequest QMPRequest;
-
 /*
  * Dispatch one single QMP request. The function will free the req_obj
  * and objects inside it before return.
@@ -4191,9 +4225,7 @@ static void handle_qmp_command(JSONMessageParser *parser, 
GQueue *tokens)
 qapi_event_send_command_dropped(id,
 COMMAND_DROP_REASON_QUEUE_FULL,
 _abort);
-qobject_decref(id);
-qobject_decref(req);
-g_free(req_obj);
+qmp_request_free(req_obj);
 return;
 }
 }
@@ -4327,6 +4359,7 @@ static void monitor_qmp_event(void *opaque, int event)

 switch (event) {
 case CHR_EVENT_OPENED:
+monitor_qmp_cleanup_queues(mon);
 mon->qmp.commands = _cap_negotiation_commands;
 monitor_qmp_caps_reset(mon);
 data = get_qmp_greeting(mon);
@@ -4335,6 +4368,7 @@ static void monitor_qmp_event(void *opaque, int event)
 mon_refcount++;
 break;
 case CHR_EVENT_CLOSED:
+monitor_qmp_cleanup_queues(mon);
 json_message_parser_destroy(>qmp.parser);
 json_message_parser_init(>qmp.parser, 

[Qemu-devel] [PATCH v2 2/4] monitor: new parameter "x-oob"

2018-03-26 Thread Eric Blake
From: Peter Xu 

Add new parameter to optionally enable Out-Of-Band for a QMP server.

An example command line:

  ./qemu-system-x86_64 -chardev stdio,id=char0 \
   -mon chardev=char0,mode=control,x-oob=on

By default, Out-Of-Band is off.

It is not allowed if either MUX or non-QMP is detected, since
Out-Of-Band is currently only for QMP, and non-MUX chardev backends.

Note that the client STILL has to request 'oob' during qmp_capabilities;
in part because the x-oob command line option may disappear in the
future if we decide the capabilities negotiation is sufficient.

Signed-off-by: Peter Xu 
Message-Id: <20180326063901.27425-4-pet...@redhat.com>
Reviewed-by: Marc-André Lureau 
[eblake: enhance commit message]
Signed-off-by: Eric Blake 
---
 include/monitor/monitor.h |  1 +
 vl.c  |  5 +
 monitor.c | 22 --
 3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index 0cb0538a315..d6ab70cae23 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -13,6 +13,7 @@ extern Monitor *cur_mon;
 #define MONITOR_USE_READLINE  0x02
 #define MONITOR_USE_CONTROL   0x04
 #define MONITOR_USE_PRETTY0x08
+#define MONITOR_USE_OOB   0x10

 bool monitor_cur_is_qmp(void);

diff --git a/vl.c b/vl.c
index c81cc866079..5fd01bd5f69 100644
--- a/vl.c
+++ b/vl.c
@@ -2404,6 +2404,11 @@ static int mon_init_func(void *opaque, QemuOpts *opts, 
Error **errp)
 if (qemu_opt_get_bool(opts, "pretty", 0))
 flags |= MONITOR_USE_PRETTY;

+/* OOB is off by default */
+if (qemu_opt_get_bool(opts, "x-oob", 0)) {
+flags |= MONITOR_USE_OOB;
+}
+
 chardev = qemu_opt_get(opts, "chardev");
 chr = qemu_chr_find(chardev);
 if (chr == NULL) {
diff --git a/monitor.c b/monitor.c
index 8fa18936419..e11724eec24 100644
--- a/monitor.c
+++ b/monitor.c
@@ -36,6 +36,7 @@
 #include "net/slirp.h"
 #include "chardev/char-fe.h"
 #include "chardev/char-io.h"
+#include "chardev/char-mux.h"
 #include "ui/qemu-spice.h"
 #include "sysemu/numa.h"
 #include "monitor/monitor.h"
@@ -4563,12 +4564,26 @@ static void monitor_qmp_setup_handlers_bh(void *opaque)
 void monitor_init(Chardev *chr, int flags)
 {
 Monitor *mon = g_malloc(sizeof(*mon));
+bool use_readline = flags & MONITOR_USE_READLINE;
+bool use_oob = flags & MONITOR_USE_OOB;

-monitor_data_init(mon, false, false);
+if (use_oob) {
+if (CHARDEV_IS_MUX(chr)) {
+error_report("Monitor Out-Of-Band is not supported with "
+ "MUX typed chardev backend");
+exit(1);
+}
+if (use_readline) {
+error_report("Monitor Out-Of-band is only supported by QMP");
+exit(1);
+}
+}
+
+monitor_data_init(mon, false, use_oob);

 qemu_chr_fe_init(>chr, chr, _abort);
 mon->flags = flags;
-if (flags & MONITOR_USE_READLINE) {
+if (use_readline) {
 mon->rs = readline_init(monitor_readline_printf,
 monitor_readline_flush,
 mon,
@@ -4664,6 +4679,9 @@ QemuOptsList qemu_mon_opts = {
 },{
 .name = "pretty",
 .type = QEMU_OPT_BOOL,
+},{
+.name = "x-oob",
+.type = QEMU_OPT_BOOL,
 },
 { /* end of list */ }
 },
-- 
2.14.3




[Qemu-devel] [PATCH v2 4/4] tests: qmp-test: add test for new "x-oob"

2018-03-26 Thread Eric Blake
From: Peter Xu 

Test the new OOB capability. It's mostly the reverted OOB test
(see commit 4fd78ad7), but differs in that:

- It uses the new qtest_init_without_qmp_handshake() parameter to
  create the monitor with "x-oob"
- Squashed the capability tests on greeting message
- Don't use qtest_global any more, instead use self-maintained
  QTestState, which is the trend

Signed-off-by: Peter Xu 
Message-Id: <20180326063901.27425-9-pet...@redhat.com>
Reviewed-by: Eric Blake 
[eblake: rebase to qtest_init changes]
Signed-off-by: Eric Blake 
---
 tests/qmp-test.c | 82 
 1 file changed, 82 insertions(+)

diff --git a/tests/qmp-test.c b/tests/qmp-test.c
index 2134d95db97..772058fc4c4 100644
--- a/tests/qmp-test.c
+++ b/tests/qmp-test.c
@@ -135,6 +135,87 @@ static void test_qmp_protocol(void)
 qtest_quit(qts);
 }

+/* Tests for Out-Of-Band support. */
+static void test_qmp_oob(void)
+{
+QTestState *qts;
+QDict *resp, *q;
+int acks = 0;
+const QListEntry *entry;
+QList *capabilities;
+QString *qstr;
+const char *cmd_id;
+
+qts = qtest_init_without_qmp_handshake(true, common_args);
+
+/* Check the greeting message. */
+resp = qtest_qmp_receive(qts);
+q = qdict_get_qdict(resp, "QMP");
+g_assert(q);
+capabilities = qdict_get_qlist(q, "capabilities");
+g_assert(capabilities && !qlist_empty(capabilities));
+entry = qlist_first(capabilities);
+g_assert(entry);
+qstr = qobject_to(QString, entry->value);
+g_assert(qstr);
+g_assert_cmpstr(qstring_get_str(qstr), ==, "oob");
+QDECREF(resp);
+
+/* Try a fake capability, it should fail. */
+resp = qtest_qmp(qts,
+ "{ 'execute': 'qmp_capabilities', "
+ "  'arguments': { 'enable': [ 'cap-does-not-exist' ] } 
}");
+g_assert(qdict_haskey(resp, "error"));
+QDECREF(resp);
+
+/* Now, enable OOB in current QMP session, it should succeed. */
+resp = qtest_qmp(qts,
+ "{ 'execute': 'qmp_capabilities', "
+ "  'arguments': { 'enable': [ 'oob' ] } }");
+g_assert(qdict_haskey(resp, "return"));
+QDECREF(resp);
+
+/*
+ * Try any command that does not support OOB but with OOB flag. We
+ * should get failure.
+ */
+resp = qtest_qmp(qts,
+ "{ 'execute': 'query-cpus',"
+ "  'control': { 'run-oob': true } }");
+g_assert(qdict_haskey(resp, "error"));
+QDECREF(resp);
+
+/*
+ * First send the "x-oob-test" command with lock=true and
+ * oob=false, it should hang the dispatcher and main thread;
+ * later, we send another lock=false with oob=true to continue
+ * that thread processing.  Finally we should receive replies from
+ * both commands.
+ */
+qtest_async_qmp(qts,
+"{ 'execute': 'x-oob-test',"
+"  'arguments': { 'lock': true }, "
+"  'id': 'lock-cmd'}");
+qtest_async_qmp(qts,
+"{ 'execute': 'x-oob-test', "
+"  'arguments': { 'lock': false }, "
+"  'control': { 'run-oob': true }, "
+"  'id': 'unlock-cmd' }");
+
+/* Ignore all events.  Wait for 2 acks */
+while (acks < 2) {
+resp = qtest_qmp_receive(qts);
+cmd_id = qdict_get_str(resp, "id");
+if (!g_strcmp0(cmd_id, "lock-cmd") ||
+!g_strcmp0(cmd_id, "unlock-cmd")) {
+acks++;
+}
+QDECREF(resp);
+}
+
+qtest_quit(qts);
+}
+
 static int query_error_class(const char *cmd)
 {
 static struct {
@@ -319,6 +400,7 @@ int main(int argc, char *argv[])
 g_test_init(, , NULL);

 qtest_add_func("qmp/protocol", test_qmp_protocol);
+qtest_add_func("qmp/oob", test_qmp_oob);
 qmp_schema_init();
 add_query_tests();

-- 
2.14.3




[Qemu-devel] [PATCH v2 3/4] tests: Add parameter to qtest_init_without_qmp_handshake

2018-03-26 Thread Eric Blake
Allow callers to choose whether to allow OOB support during a test;
for now, all existing callers pass false, but the next patch will
add a new caller.  Also, rewrite the monitor setup to be generic
(using the -qmp shorthand is insufficient for honoring the parameter).

Based on an idea by Peter Xu, in <20180326063901.27425-8-pet...@redhat.com>

Signed-off-by: Eric Blake 
---
 tests/libqtest.h |  7 +--
 tests/libqtest.c | 10 ++
 tests/qmp-test.c |  2 +-
 3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/tests/libqtest.h b/tests/libqtest.h
index 811169453ab..cbe8df44730 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -56,11 +56,14 @@ QTestState *qtest_init(const char *extra_args);

 /**
  * qtest_init_without_qmp_handshake:
- * @extra_args: other arguments to pass to QEMU.
+ * @use_oob: true to have the server advertise OOB support
+ * @extra_args: other arguments to pass to QEMU.  CAUTION: these
+ * arguments are subject to word splitting and shell evaluation.
  *
  * Returns: #QTestState instance.
  */
-QTestState *qtest_init_without_qmp_handshake(const char *extra_args);
+QTestState *qtest_init_without_qmp_handshake(bool use_oob,
+ const char *extra_args);

 /**
  * qtest_quit:
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 200b2b9e92a..6f33a37667c 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -166,7 +166,8 @@ static const char *qtest_qemu_binary(void)
 return qemu_bin;
 }

-QTestState *qtest_init_without_qmp_handshake(const char *extra_args)
+QTestState *qtest_init_without_qmp_handshake(bool use_oob,
+ const char *extra_args)
 {
 QTestState *s;
 int sock, qmpsock, i;
@@ -199,12 +200,13 @@ QTestState *qtest_init_without_qmp_handshake(const char 
*extra_args)
 command = g_strdup_printf("exec %s "
   "-qtest unix:%s,nowait "
   "-qtest-log %s "
-  "-qmp unix:%s,nowait "
+  "-chardev socket,path=%s,nowait,id=char0 "
+  "-mon chardev=char0,mode=control%s "
   "-machine accel=qtest "
   "-display none "
   "%s", qemu_binary, socket_path,
   getenv("QTEST_LOG") ? "/dev/fd/2" : 
"/dev/null",
-  qmp_socket_path,
+  qmp_socket_path, use_oob ? ",x-oob=on" : "",
   extra_args ?: "");
 execlp("/bin/sh", "sh", "-c", command, NULL);
 exit(1);
@@ -239,7 +241,7 @@ QTestState *qtest_init_without_qmp_handshake(const char 
*extra_args)

 QTestState *qtest_init(const char *extra_args)
 {
-QTestState *s = qtest_init_without_qmp_handshake(extra_args);
+QTestState *s = qtest_init_without_qmp_handshake(false, extra_args);

 /* Read the QMP greeting and then do the handshake */
 qtest_qmp_discard_response(s, "");
diff --git a/tests/qmp-test.c b/tests/qmp-test.c
index 8de99a4727e..2134d95db97 100644
--- a/tests/qmp-test.c
+++ b/tests/qmp-test.c
@@ -81,7 +81,7 @@ static void test_qmp_protocol(void)
 QList *capabilities;
 QTestState *qts;

-qts = qtest_init_without_qmp_handshake(common_args);
+qts = qtest_init_without_qmp_handshake(false, common_args);

 /* Test greeting */
 resp = qtest_qmp_receive(qts);
-- 
2.14.3




[Qemu-devel] [PATCH v2 0/4] Monitor: OOB related patches

2018-03-26 Thread Eric Blake
This is patches 2, 3, 7, and 8 (with 7 rewritten) from Peter Xu's
series.  I've pushed them to git://repo.or.cz/qemu/ericb.git qapi-next
(on top of the other pending qapi patches at branch qapi); hopefully
this will be part of my pull request tomorrow for -rc1.

Eric Blake (1):
  tests: Add parameter to qtest_init_without_qmp_handshake

Peter Xu (3):
  qmp: cleanup qmp queues properly
  monitor: new parameter "x-oob"
  tests: qmp-test: add test for new "x-oob"

 tests/libqtest.h  |  7 +++-
 include/monitor/monitor.h |  1 +
 vl.c  |  5 +++
 tests/libqtest.c  | 10 +++--
 monitor.c | 94 ---
 tests/qmp-test.c  | 84 +-
 6 files changed, 173 insertions(+), 28 deletions(-)

-- 
2.14.3




Re: [Qemu-devel] [PATCH v1] RISC-V: RISC-V TCG backend work in progress

2018-03-26 Thread Michael Clark
What is quite fascinating is that it appears that TCG constant folding is
causing the mulhsu test to fail, not the TCG backend, which suggests either
a RISC-V front-end bug or a TCG middle-end bug. Anyway, it's odd.

Below are the mulhsu tests. Note TEST_RR_OP 7 is the test that is failing.
I thought for a while that it might be constant synthesis i.e.
tcg_gen_movi, however none of the register values emitted by the middle-end
are actually used in comparison. It appears that QEMU middle-end is
resolving the branch via constant folding.

$ more ../riscv-qemu-tests/rv64m/mulhsu.s
.include "test.s"

START

  ## Arithmetic tests

  TEST_RR_OP 2,  mulhsu, 0x, 0x, 0x
  TEST_RR_OP 3,  mulhsu, 0x, 0x0001, 0x0001
  TEST_RR_OP 4,  mulhsu, 0x, 0x0003, 0x0007

  TEST_RR_OP 5,  mulhsu, 0x, 0x,
0x8000
  TEST_RR_OP 6,  mulhsu, 0x, 0x8000, 0x
  TEST_RR_OP 7,  mulhsu, 0x8000, 0x8000,
0x8000

  # Source/Destination tests

  TEST_RR_SRC1_EQ_DEST 8, mulhsu, 143, 13<<32, 11<<32
  TEST_RR_SRC2_EQ_DEST 9, mulhsu, 154, 14<<32, 11<<32
  TEST_RR_SRC12_EQ_DEST 10, mulhsu, 169, 13<<32

  # Bypassing tests

  TEST_RR_DEST_BYPASS 11, 0, mulhsu, 143, 13<<32, 11<<32
  TEST_RR_DEST_BYPASS 12, 1, mulhsu, 154, 14<<32, 11<<32
  TEST_RR_DEST_BYPASS 13, 2, mulhsu, 165, 15<<32, 11<<32

  TEST_RR_SRC12_BYPASS 14, 0, 0, mulhsu, 143, 13<<32, 11<<32
  TEST_RR_SRC12_BYPASS 15, 0, 1, mulhsu, 154, 14<<32, 11<<32
  TEST_RR_SRC12_BYPASS 16, 0, 2, mulhsu, 165, 15<<32, 11<<32
  TEST_RR_SRC12_BYPASS 17, 1, 0, mulhsu, 143, 13<<32, 11<<32
  TEST_RR_SRC12_BYPASS 18, 1, 1, mulhsu, 154, 14<<32, 11<<32
  TEST_RR_SRC12_BYPASS 19, 2, 0, mulhsu, 165, 15<<32, 11<<32

  TEST_RR_SRC21_BYPASS 20, 0, 0, mulhsu, 143, 13<<32, 11<<32
  TEST_RR_SRC21_BYPASS 21, 0, 1, mulhsu, 154, 14<<32, 11<<32
  TEST_RR_SRC21_BYPASS 22, 0, 2, mulhsu, 165, 15<<32, 11<<32
  TEST_RR_SRC21_BYPASS 23, 1, 0, mulhsu, 143, 13<<32, 11<<32
  TEST_RR_SRC21_BYPASS 24, 1, 1, mulhsu, 154, 14<<32, 11<<32
  TEST_RR_SRC21_BYPASS 25, 2, 0, mulhsu, 165, 15<<32, 11<<32

  TEST_RR_ZEROSRC1 26, mulhsu, 0, 31<<32
  TEST_RR_ZEROSRC2 27, mulhsu, 0, 32<<32
  TEST_RR_ZEROSRC12 28, mulhsu, 0
  TEST_RR_ZERODEST 29, mulhsu, 33<<32, 34<<32

EXIT

This is what the RISC-V front-end does for RISC-V's mulhsu. Note: RISC-V
has mulh (mulsh), mulhu (muluh) and mulhsu (no QEMU equivalent).

static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
{
TCGv rl = tcg_temp_new();
TCGv rh = tcg_temp_new();

tcg_gen_mulu2_tl(rl, rh, arg1, arg2);
/* fix up for one negative */
tcg_gen_sari_tl(rl, arg1, TARGET_LONG_BITS - 1);
tcg_gen_and_tl(rl, rl, arg2);
tcg_gen_sub_tl(ret, rh, rl);

tcg_temp_free(rl);
tcg_temp_free(rh);
}

If you look at the TCG output post optimization, you'll see that QEMU has
already calculated the multiplication results and has calculated the branch
targets. There are no multiplications performed via the backend and no
comparison of intermediate results sent to the backend.

$ ./riscv64-linux-user/qemu-riscv64 -d in_asm,op_opt,out_asm
../riscv-qemu-tests/rv64m/mulhsu
PROLOGUE: [size=132]
0x000dd000:  b1010113  addisp,sp,-1264
0x000dd004:  48813023  sd  s0,1152(sp)
0x000dd008:  48913423  sd  s1,1160(sp)
0x000dd00c:  49213823  sd  s2,1168(sp)
0x000dd010:  49313c23  sd  s3,1176(sp)
0x000dd014:  4b413023  sd  s4,1184(sp)
0x000dd018:  4b513423  sd  s5,1192(sp)
0x000dd01c:  4b613823  sd  s6,1200(sp)
0x000dd020:  4b713c23  sd  s7,1208(sp)
0x000dd024:  4d813023  sd  s8,1216(sp)
0x000dd028:  4d913423  sd  s9,1224(sp)
0x000dd02c:  4da13823  sd  s10,1232(sp)
0x000dd030:  4db13c23  sd  s11,1240(sp)
0x000dd034:  4e113023  sd  ra,1248(sp)
0x000dd038:  0212a4b7  lui s1,34775040
0x000dd03c:  00050413  mv  s0,a0
0x000dd040:  00058067  jr  a1
0x000dd044:  0513  mv  a0,zero
0x000dd048:  48013403  ld  s0,1152(sp)
0x000dd04c:  48813483  ld  s1,1160(sp)
0x000dd050:  49013903  ld  s2,1168(sp)
0x000dd054:  49813983  ld  s3,1176(sp)
0x000dd058:  4a013a03  ld  s4,1184(sp)
0x000dd05c:  4a813a83  ld  s5,1192(sp)
0x000dd060:  4b013b03  ld  s6,1200(sp)
0x000dd064:  4b813b83  ld  s7,1208(sp)
0x000dd068:  4c013c03  ld  s8,1216(sp)
0x000dd06c:  4c813c83  ld  s9,1224(sp)
0x000dd070:  4d013d03  ld  s10,1232(sp)
0x000dd074:  4d813d83  ld  s11,1240(sp)

Re: [Qemu-devel] [patches] Re: [PATCH v6 00/26] RISC-V: Fixes and cleanups for QEMU 2.12

2018-03-26 Thread Michael Clark
On Mon, Mar 26, 2018 at 4:14 PM, Michael Clark  wrote:

>
>
> On Mon, Mar 26, 2018 at 11:07 AM, Michael Clark  wrote:
>
>>
>>
>> On Sun, Mar 25, 2018 at 8:03 AM, Peter Maydell 
>> wrote:
>>
>>> On 24 March 2018 at 18:13, Michael Clark  wrote:
>>> > This is a series of bug fixes and code cleanups that we would
>>> > like to get in before the QEMU 2.12 release. We are respinning
>>> > v6 of this series to include two new bug fixes. These changes
>>> > are present in the downstream riscv.org riscv-all branch:
>>> >
>>> > - https://github.com/riscv/riscv-qemu/commits/riscv-all
>>> >
>>> > This series also addresses post-merge feedback such as updating
>>> > the cpu initialization model to conform with other architectures
>>> > as requested by Igor Mammedov.
>>>
>>> Hi. It looks to me like a fair number of these patches
>>> are already reviewed, so we don't need to wait on the
>>> rest being reviewed to get those into master.
>>>
>>> My suggestion is that you send a pullrequest now for the
>>> reviewed patches, and send a patchset for review for the
>>> new ones or the ones that still need review. (If there
>>> are patches that are reviewed but depend on earlier ones
>>> that need to go in set 2 then they go in set 2 as well.)
>>>
>>
>> Unfortunately the reviewed patches are mostly just minor cleanups. It's
>> almost not worth making a PR for them as *none* of the reviewed patches are
>> actually bug fixes. They are things like removing unused definitions or
>> replacing hardcoded constants with enums, removing unnesscary braces, etc,
>> etc
>>
>
> Apologies. There is one bug fix in the subset of reviewed patches. the
> -cpu model changes.
>
>
>> $ grep Reviewed outgoing/v6-00*
>> outgoing/v6-0001-RISC-V-Make-virt-create_fdt-interface-consistent.patch:Reviewed-by:
>> Philippe Mathieu-Daudé 
>> outgoing/v6-0002-RISC-V-Replace-hardcoded-constants-with-enum-valu.patch:Reviewed-by:
>> Philippe Mathieu-Daudé 
>> outgoing/v6-0003-RISC-V-Make-virt-board-description-match-spike.patch:Reviewed-by:
>> Philippe Mathieu-Daudé 
>> outgoing/v6-0004-RISC-V-Use-ROM-base-address-and-size-from-memmap.patch:Reviewed-by:
>> Philippe Mathieu-Daudé 
>> outgoing/v6-0005-RISC-V-Remove-identity_translate-from-load_elf.patch:Reviewed-by:
>> Philippe Mathieu-Daudé 
>> outgoing/v6-0007-RISC-V-Remove-unused-class-definitions.patch:Reviewed-by:
>> Philippe Mathieu-Daudé 
>> outgoing/v6-0009-RISC-V-Include-intruction-hex-in-disassembly.patch:Reviewed-by:
>> Philippe Mathieu-Daudé 
>> outgoing/v6-0012-RISC-V-Make-some-header-guards-more-specific.patch:Reviewed-by:
>> Philippe Mathieu-Daudé 
>> outgoing/v6-0013-RISC-V-Make-virt-header-comment-title-consistent.patch:Reviewed-by:
>> Philippe Mathieu-Daudé 
>> outgoing/v6-0015-RISC-V-Remove-EM_RISCV-ELF_MACHINE-indirection.patch:Reviewed-by:
>> Philippe Mathieu-Daudé 
>> outgoing/v6-0017-RISC-V-Remove-braces-from-satp-case-statement.patch:Reviewed-by:
>> Philippe Mathieu-Daudé 
>> outgoing/v6-0022-RISC-V-Convert-cpu-definition-towards-future-mode.patch:Reviewed-by:
>> Philippe Mathieu-Daudé 
>> outgoing/v6-0022-RISC-V-Convert-cpu-definition-towards-future-mode.patch:Reviewed-by:
>> Igor Mammedov 
>>
>> The unreviewed patches, as I've mentioned many times are the ones that
>> require reading the RISC-V Privileged ISA Specification or are actual bug
>> fixes and hence are harder to review. They are in the maintainer's tree and
>> are what folk who are interested in using RISC-V in QEMU are actually
>> running.
>>
>> I can drop the fix to make ROM read-only it is not critical, however it
>> is a bug fix. I went through with a critical eye and reviewed them myself
>> and picked up a few minor issues, but I believe the patchset as a whole
>> should be fine as long as I can find someone to Ack them. Otherwise we're
>> sort of in a Catch-22 situation.
>>
>
> Most of the spec compliance bug fixes are innocuous when it comes to
> running Linux, nevertheless, they are bugs and will be exposed by future
> verification and compliance tests. The only really critical bug fix is
> 26/26 mstatus.FS. Igor's fix for the cpu model 22/26 is important as it
> addresses remaining review feedback with the initial port submission. 25/26
> is a user-visible bugfix for the disassembler which is important for anyone
> using -d in_asm. I'm pretty comfortable with the amount of testing this
> series has had despite the lack of review. Testing is also important.
>
> The FDT ROM truncation issue fixed by 8/26 isn't seen in practice but it
> was seen during development as i've been working on patches to separate the
> bbl bootloader from the linux kernel (currently the kernel is embedded as a
> payload in embedded in the monitor 

Re: [Qemu-devel] [patches] Re: [PATCH v6 00/26] RISC-V: Fixes and cleanups for QEMU 2.12

2018-03-26 Thread Michael Clark
On Mon, Mar 26, 2018 at 11:07 AM, Michael Clark  wrote:

>
>
> On Sun, Mar 25, 2018 at 8:03 AM, Peter Maydell 
> wrote:
>
>> On 24 March 2018 at 18:13, Michael Clark  wrote:
>> > This is a series of bug fixes and code cleanups that we would
>> > like to get in before the QEMU 2.12 release. We are respinning
>> > v6 of this series to include two new bug fixes. These changes
>> > are present in the downstream riscv.org riscv-all branch:
>> >
>> > - https://github.com/riscv/riscv-qemu/commits/riscv-all
>> >
>> > This series also addresses post-merge feedback such as updating
>> > the cpu initialization model to conform with other architectures
>> > as requested by Igor Mammedov.
>>
>> Hi. It looks to me like a fair number of these patches
>> are already reviewed, so we don't need to wait on the
>> rest being reviewed to get those into master.
>>
>> My suggestion is that you send a pullrequest now for the
>> reviewed patches, and send a patchset for review for the
>> new ones or the ones that still need review. (If there
>> are patches that are reviewed but depend on earlier ones
>> that need to go in set 2 then they go in set 2 as well.)
>>
>
> Unfortunately the reviewed patches are mostly just minor cleanups. It's
> almost not worth making a PR for them as *none* of the reviewed patches are
> actually bug fixes. They are things like removing unused definitions or
> replacing hardcoded constants with enums, removing unnesscary braces, etc,
> etc
>

Apologies. There is one bug fix in the subset of reviewed patches. the -cpu
model changes.


> $ grep Reviewed outgoing/v6-00*
> outgoing/v6-0001-RISC-V-Make-virt-create_fdt-interface-consistent.patch:Reviewed-by:
> Philippe Mathieu-Daudé 
> outgoing/v6-0002-RISC-V-Replace-hardcoded-constants-
> with-enum-valu.patch:Reviewed-by: Philippe Mathieu-Daudé 
> outgoing/v6-0003-RISC-V-Make-virt-board-description-match-spike.patch:Reviewed-by:
> Philippe Mathieu-Daudé 
> outgoing/v6-0004-RISC-V-Use-ROM-base-address-and-size-from-memmap.patch:Reviewed-by:
> Philippe Mathieu-Daudé 
> outgoing/v6-0005-RISC-V-Remove-identity_translate-
> from-load_elf.patch:Reviewed-by: Philippe Mathieu-Daudé 
> outgoing/v6-0007-RISC-V-Remove-unused-class-definitions.patch:Reviewed-by:
> Philippe Mathieu-Daudé 
> outgoing/v6-0009-RISC-V-Include-intruction-hex-in-disassembly.patch:Reviewed-by:
> Philippe Mathieu-Daudé 
> outgoing/v6-0012-RISC-V-Make-some-header-guards-more-specific.patch:Reviewed-by:
> Philippe Mathieu-Daudé 
> outgoing/v6-0013-RISC-V-Make-virt-header-comment-title-consistent.patch:Reviewed-by:
> Philippe Mathieu-Daudé 
> outgoing/v6-0015-RISC-V-Remove-EM_RISCV-ELF_MACHINE-indirection.patch:Reviewed-by:
> Philippe Mathieu-Daudé 
> outgoing/v6-0017-RISC-V-Remove-braces-from-satp-case-statement.patch:Reviewed-by:
> Philippe Mathieu-Daudé 
> outgoing/v6-0022-RISC-V-Convert-cpu-definition-towards-future-mode.patch:Reviewed-by:
> Philippe Mathieu-Daudé 
> outgoing/v6-0022-RISC-V-Convert-cpu-definition-towards-future-mode.patch:Reviewed-by:
> Igor Mammedov 
>
> The unreviewed patches, as I've mentioned many times are the ones that
> require reading the RISC-V Privileged ISA Specification or are actual bug
> fixes and hence are harder to review. They are in the maintainer's tree and
> are what folk who are interested in using RISC-V in QEMU are actually
> running.
>
> I can drop the fix to make ROM read-only it is not critical, however it is
> a bug fix. I went through with a critical eye and reviewed them myself and
> picked up a few minor issues, but I believe the patchset as a whole should
> be fine as long as I can find someone to Ack them. Otherwise we're sort of
> in a Catch-22 situation.
>

Most of the spec compliance bug fixes are innocuous when it comes to
running Linux, nevertheless, they are bugs and will be exposed by future
verification and compliance tests. The only really critical bug fix is
26/26 mstatus.FS. Igor's fix for the cpu model 22/26 is important as it
addresses remaining review feedback with the initial port submission. 25/26
is a user-visible bugfix for the disassembler which is important for anyone
using -d in_asm. I'm pretty comfortable with the amount of testing this
series has had despite the lack of review. Testing is also important.

The FDT ROM truncation issue fixed by 8/26 isn't seen in practice but it
was seen during development as i've been working on patches to separate the
bbl bootloader from the linux kernel (currently the kernel is embedded as a
payload in embedded in the monitor firmware). I would like to change the
ports to use -bios to load firmware and -kernel can then point to a regular
linux kernel and we can indicate to the firmware where the kernel is 

Re: [Qemu-devel] [PATCH for-2.12 0/8] Monitor: some oob related patches (fixes, new param, tests)

2018-03-26 Thread Eric Blake

On 03/26/2018 01:38 AM, Peter Xu wrote:

I suppose these are all good even for 2.12, so marked in subject.
Tested with "make check" for all targets on x86_64, and iotest -raw.

Patch 1 fixes one OOB error message regression reported by Marc-Andre.

Patch 2 fixes one potential OOB problem when more than one clients are
there, reported by Marc-Andre (too).

Patch 3 introduce "-mon x-oob=on" parameter to allow user to
explicitly enable Out-Of-Band for a specific monitor.

Patch 4-6 are qapi-schema fixes and tests for Out-Of-Band.

Patch 7-8 add back the OOB test on the new parameter (with more
enhancements).

Please review, thanks.

Peter Xu (8):
   qmp: fix qmp_capabilities error regression
   qmp: cleanup qmp queues properly
   monitor: new parameter "x-oob"
   qapi: restrict allow-oob value to be "true"
   tests: let qapi-schema tests detect oob
   tests: add oob-test for qapi-schema
   tests: introduce qtest_init_with_qmp_format()
   tests: qmp-test: add test for new "x-oob"


Queuing 1, 4-6 without further changes.  I'll repost a v2 of 2, 3, my 
rewrite of 7, and 8.


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



Re: [Qemu-devel] [PATCH v6 06/26] RISC-V: Mark ROM read-only after copying in code

2018-03-26 Thread Michael Clark
On Sun, Mar 25, 2018 at 5:47 AM, Peter Maydell 
wrote:

> On 25 March 2018 at 00:23, Michael Clark  wrote:
> >
> >
> > On Sat, Mar 24, 2018 at 2:23 PM, Peter Maydell  >
> > wrote:
> >>
> >> On 24 March 2018 at 18:13, Michael Clark  wrote:
> >> > The sifive_u machine already marks its ROM readonly. This fixes
> >> > the remaining boards.
> >> >
> >> > Cc: Sagar Karandikar 
> >> > Cc: Bastian Koppelmann 
> >> > Signed-off-by: Michael Clark 
> >> > Signed-off-by: Palmer Dabbelt 
> >> > ---
> >> >  hw/riscv/sifive_u.c  |  9 +
> >> >  hw/riscv/spike.c | 18 ++
> >> >  hw/riscv/virt.c  |  7 ---
> >> >  include/hw/riscv/spike.h |  8 
> >> >  4 files changed, 19 insertions(+), 23 deletions(-)
> >> >
> >> > diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> >> > index 6116c38..25df16c 100644
> >> > --- a/hw/riscv/sifive_u.c
> >> > +++ b/hw/riscv/sifive_u.c
> >> > @@ -223,7 +223,7 @@ static void riscv_sifive_u_init(MachineState
> >> > *machine)
> >> >  SiFiveUState *s = g_new0(SiFiveUState, 1);
> >> >  MemoryRegion *sys_memory = get_system_memory();
> >> >  MemoryRegion *main_mem = g_new(MemoryRegion, 1);
> >> > -MemoryRegion *boot_rom = g_new(MemoryRegion, 1);
> >> > +MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
> >> >
> >> >  /* Initialize SOC */
> >> >  object_initialize(>soc, sizeof(s->soc),
> TYPE_RISCV_HART_ARRAY);
> >> > @@ -246,10 +246,10 @@ static void riscv_sifive_u_init(MachineState
> >> > *machine)
> >> >  create_fdt(s, memmap, machine->ram_size,
> machine->kernel_cmdline);
> >> >
> >> >  /* boot rom */
> >> > -memory_region_init_ram(boot_rom, NULL, "riscv.sifive.u.mrom",
> >> > +memory_region_init_ram(mask_rom, NULL, "riscv.sifive.u.mrom",
> >> > memmap[SIFIVE_U_MROM].base, _fatal);
> >> > -memory_region_set_readonly(boot_rom, true);
> >> > -memory_region_add_subregion(sys_memory, 0x0, boot_rom);
> >> > +memory_region_set_readonly(mask_rom, true);
> >> > +memory_region_add_subregion(sys_memory, 0x0, mask_rom);
> >>
> >> memory_region_init_ram + memory_region_set_readonly is
> >> equivalent to memory_region_init_rom.
> >>
> >> >  if (machine->kernel_filename) {
> >> >  load_kernel(machine->kernel_filename);
> >> > @@ -279,6 +279,7 @@ static void riscv_sifive_u_init(MachineState
> >> > *machine)
> >> >  qemu_fdt_dumpdtb(s->fdt, s->fdt_size);
> >> >  cpu_physical_memory_write(memmap[SIFIVE_U_MROM].base +
> >> >  sizeof(reset_vec), s->fdt, s->fdt_size);
> >> > +memory_region_set_readonly(mask_rom, true);
> >>
> >> Rather than doing this, you should use
> >> rom_add_blob_fixed(). That works even on ROMs which
> >> means you can just create them as read-only from the
> >> start rather than waiting til you've written to them
> >> and then marking them read-only. It also means that
> >> you get the contents correctly reset on reset, even
> >> if the user has been messing with their contents
> >> via the debugger or something.
> >>
> >> hw/arm/boot.c has code which (among a lot of other
> >> things) loads initial kernels and dtb images into
> >> guest memory. You can also find ppc code doing
> >> similar things.
> >
> >
> > I don't mind to make this change, however it is a case of good vs
> perfect.
> > Currently we have some machines with writable ROM sections, this change
> > fixes it and has been tested.
>
> Yes, I would put this on your set of things to
> address for 2.13.
>

Okay. It's on my list...

I will be replying to the other thread with a list of the oustanding
patches, whether they are bug fixes vs cleanups, and whether they are
reviewed.

The mstatus.FS fix is relatively critical and Igor's cpu init actually
fixes a bug with -cpu list. In any case I'll send a list shortly...


Re: [Qemu-devel] [PATCH] qmp-test: fix response leak

2018-03-26 Thread Eric Blake

On 03/26/2018 01:33 PM, Eric Blake wrote:

On 03/26/2018 12:20 PM, Marc-André Lureau wrote:

Apparently introduced in commit a4f90923b520f1dc0a768634877eb412e5052c26.

Signed-off-by: Marc-André Lureau 
---
  tests/qmp-test.c | 1 +
  1 file changed, 1 insertion(+)


Reviewed-by: Eric Blake 

I'll queue this through my qapi tree, unless applying Peter's for-2.12 
patches fixes it differently.


Okay, it's needed, and I'm queuing it.

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



Re: [Qemu-devel] [PATCH for-2.12 7/8] tests: introduce qtest_init_with_qmp_format()

2018-03-26 Thread Eric Blake

On 03/26/2018 01:39 AM, Peter Xu wrote:

It is abstracted from qtest_init_without_qmp_handshake(). It works just
like qtest_init_without_qmp_handshake() but further it would allow the
caller to specify the QMP parameter.

Signed-off-by: Peter Xu 
---
  tests/libqtest.c | 14 +++---
  tests/libqtest.h | 14 ++
  2 files changed, 25 insertions(+), 3 deletions(-)




+gchar *qmp_params;
  const char *qemu_binary = qtest_qemu_binary();
  
  s = g_new(QTestState, 1);
  
  socket_path = g_strdup_printf("/tmp/qtest-%d.sock", getpid());

  qmp_socket_path = g_strdup_printf("/tmp/qtest-%d.qmp", getpid());
+qmp_params = g_strdup_printf(qmp_format, qmp_socket_path);
  


Memory leak of qmp_params.  Avoided in my rewrite to use bool instead of 
a format string.


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



Re: [Qemu-devel] [PATCH for 2.13 17/19] linux-user: move riscv cpu loop to riscv directory

2018-03-26 Thread Michael Clark
On Mon, Mar 26, 2018 at 12:16 PM, Laurent Vivier  wrote:

> No code change, only move code from main.c to
> riscv/cpu_loop.c.
>
> Signed-off-by: Laurent Vivier 
>

Reviewed-by: Michael Clark 


> ---
>  linux-user/main.c   | 101 +-
> --
>  linux-user/riscv/cpu_loop.c |  92 ++
> ++
>  2 files changed, 93 insertions(+), 100 deletions(-)
>
> diff --git a/linux-user/main.c b/linux-user/main.c
> index 3b3613cb89..78ff99bd00 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -149,100 +149,6 @@ void fork_end(int child)
>  }
>  }
>
> -#ifdef TARGET_RISCV
> -
> -void cpu_loop(CPURISCVState *env)
> -{
> -CPUState *cs = CPU(riscv_env_get_cpu(env));
> -int trapnr, signum, sigcode;
> -target_ulong sigaddr;
> -target_ulong ret;
> -
> -for (;;) {
> -cpu_exec_start(cs);
> -trapnr = cpu_exec(cs);
> -cpu_exec_end(cs);
> -process_queued_cpu_work(cs);
> -
> -signum = 0;
> -sigcode = 0;
> -sigaddr = 0;
> -
> -switch (trapnr) {
> -case EXCP_INTERRUPT:
> -/* just indicate that signals should be handled asap */
> -break;
> -case EXCP_ATOMIC:
> -cpu_exec_step_atomic(cs);
> -break;
> -case RISCV_EXCP_U_ECALL:
> -env->pc += 4;
> -if (env->gpr[xA7] == TARGET_NR_arch_specific_syscall + 15) {
> -/* riscv_flush_icache_syscall is a no-op in QEMU as
> -   self-modifying code is automatically detected */
> -ret = 0;
> -} else {
> -ret = do_syscall(env,
> - env->gpr[xA7],
> - env->gpr[xA0],
> - env->gpr[xA1],
> - env->gpr[xA2],
> - env->gpr[xA3],
> - env->gpr[xA4],
> - env->gpr[xA5],
> - 0, 0);
> -}
> -if (ret == -TARGET_ERESTARTSYS) {
> -env->pc -= 4;
> -} else if (ret != -TARGET_QEMU_ESIGRETURN) {
> -env->gpr[xA0] = ret;
> -}
> -if (cs->singlestep_enabled) {
> -goto gdbstep;
> -}
> -break;
> -case RISCV_EXCP_ILLEGAL_INST:
> -signum = TARGET_SIGILL;
> -sigcode = TARGET_ILL_ILLOPC;
> -break;
> -case RISCV_EXCP_BREAKPOINT:
> -signum = TARGET_SIGTRAP;
> -sigcode = TARGET_TRAP_BRKPT;
> -sigaddr = env->pc;
> -break;
> -case RISCV_EXCP_INST_PAGE_FAULT:
> -case RISCV_EXCP_LOAD_PAGE_FAULT:
> -case RISCV_EXCP_STORE_PAGE_FAULT:
> -signum = TARGET_SIGSEGV;
> -sigcode = TARGET_SEGV_MAPERR;
> -break;
> -case EXCP_DEBUG:
> -gdbstep:
> -signum = gdb_handlesig(cs, TARGET_SIGTRAP);
> -sigcode = TARGET_TRAP_BRKPT;
> -break;
> -default:
> -EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x -
> aborting\n",
> - trapnr);
> -exit(EXIT_FAILURE);
> -}
> -
> -if (signum) {
> -target_siginfo_t info = {
> -.si_signo = signum,
> -.si_errno = 0,
> -.si_code = sigcode,
> -._sifields._sigfault._addr = sigaddr
> -};
> -queue_signal(env, info.si_signo, QEMU_SI_KILL, );
> -}
> -
> -process_pending_signals(env);
> -}
> -}
> -
> -#endif /* TARGET_RISCV */
> -
>  #ifdef TARGET_HPPA
>
>  static abi_ulong hppa_lws(CPUHPPAState *env)
> @@ -1319,12 +1225,7 @@ int main(int argc, char **argv, char **envp)
>
>  target_cpu_copy_regs(env, regs);
>
> -#if defined(TARGET_RISCV)
> -{
> -env->pc = regs->sepc;
> -env->gpr[xSP] = regs->sp;
> -}
> -#elif defined(TARGET_HPPA)
> +#if defined(TARGET_HPPA)
>  {
>  int i;
>  for (i = 1; i < 32; i++) {
> diff --git a/linux-user/riscv/cpu_loop.c b/linux-user/riscv/cpu_loop.c
> index b7700a5561..f137d39d7e 100644
> --- a/linux-user/riscv/cpu_loop.c
> +++ b/linux-user/riscv/cpu_loop.c
> @@ -21,6 +21,98 @@
>  #include "qemu.h"
>  #include "cpu_loop-common.h"
>
> +void cpu_loop(CPURISCVState *env)
> +{
> +CPUState *cs = CPU(riscv_env_get_cpu(env));
> +int trapnr, signum, sigcode;
> +target_ulong sigaddr;
> +target_ulong ret;
> +
> +for (;;) {
> +cpu_exec_start(cs);
> +trapnr = cpu_exec(cs);
> +cpu_exec_end(cs);
> +process_queued_cpu_work(cs);
> +
> +signum = 0;
> +sigcode = 0;
> +sigaddr = 0;
> +
> +switch (trapnr) {
> +case 

[Qemu-devel] [PULL 0/4] target/xtensa fixes for 2.12

2018-03-26 Thread Max Filippov
Hi Peter,

please pull the following fixes for target/xtensa for 2.12:

The following changes since commit 7b93d78a04aa242d377ae213b79db6c319c71847:

  Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging 
(2018-03-26 15:17:25 +0100)

are available in the git repository at:

  git://github.com/OSLL/qemu-xtensa.git tags/20180326-xtensa

for you to fetch changes up to d0ce7e9cfc8eda113f872b608fe4a3dd7662997e:

  target/xtensa: fix timers test (2018-03-26 14:17:04 -0700)


target/xtensa fixes for 2.12:

- add .inc. to non-top level source file names under target/xtensa;
- fix #include  in the import_core.sh script;
- remove stray linux-user/xtensa/syscall.h;
- fix timers test.


Max Filippov (4):
  target/xtensa: add .inc. to non-top level source file names
  target/xtensa/import_core.sh: fix #include 
  linux-user/xtensa: remove stray syscall.h
  target/xtensa: fix timers test

 linux-user/xtensa/syscall.h  | 0
 target/xtensa/core-dc232b.c  | 6 +++---
 target/xtensa/core-dc232b/{gdb-config.c => gdb-config.inc.c} | 0
 .../core-dc232b/{xtensa-modules.c => xtensa-modules.inc.c}   | 0
 target/xtensa/core-dc233c.c  | 4 ++--
 target/xtensa/core-dc233c/{gdb-config.c => gdb-config.inc.c} | 0
 .../core-dc233c/{xtensa-modules.c => xtensa-modules.inc.c}   | 0
 target/xtensa/core-de212.c   | 4 ++--
 target/xtensa/core-de212/{gdb-config.c => gdb-config.inc.c}  | 0
 .../xtensa/core-de212/{xtensa-modules.c => xtensa-modules.inc.c} | 0
 target/xtensa/core-fsf.c | 2 +-
 .../xtensa/core-fsf/{xtensa-modules.c => xtensa-modules.inc.c}   | 0
 target/xtensa/core-sample_controller.c   | 4 ++--
 .../core-sample_controller/{gdb-config.c => gdb-config.inc.c}| 0
 .../{xtensa-modules.c => xtensa-modules.inc.c}   | 0
 target/xtensa/import_core.sh | 9 +
 tests/tcg/xtensa/Makefile| 2 +-
 17 files changed, 16 insertions(+), 15 deletions(-)
 delete mode 100644 linux-user/xtensa/syscall.h
 rename target/xtensa/core-dc232b/{gdb-config.c => gdb-config.inc.c} (100%)
 rename target/xtensa/core-dc232b/{xtensa-modules.c => xtensa-modules.inc.c} 
(100%)
 rename target/xtensa/core-dc233c/{gdb-config.c => gdb-config.inc.c} (100%)
 rename target/xtensa/core-dc233c/{xtensa-modules.c => xtensa-modules.inc.c} 
(100%)
 rename target/xtensa/core-de212/{gdb-config.c => gdb-config.inc.c} (100%)
 rename target/xtensa/core-de212/{xtensa-modules.c => xtensa-modules.inc.c} 
(100%)
 rename target/xtensa/core-fsf/{xtensa-modules.c => xtensa-modules.inc.c} (100%)
 rename target/xtensa/core-sample_controller/{gdb-config.c => gdb-config.inc.c} 
(100%)
 rename target/xtensa/core-sample_controller/{xtensa-modules.c => 
xtensa-modules.inc.c} (100%)

-- 
Thanks.
-- Max



Re: [Qemu-devel] [PATCH for-2.12 8/8] tests: qmp-test: add test for new "x-oob"

2018-03-26 Thread Eric Blake

On 03/26/2018 01:39 AM, Peter Xu wrote:

Test the new OOB capability. It's mostly the reverted OOB test, but


Helpful to mention which commit id has the reverts you are restoring. 
Looks like 4fd78ad. Are you also restoring the tests reverted in cc79760 
and a4f9092?



differs in that:

- It uses the new qtest_init_with_qmp_format() to create the monitor
   with the new monitor parameter "-mon x-oob"
- Squashed the capability tests on greeting message
- Don't use qtest_global any more, instead use self-maintained
   QTestState, which is the trend

Signed-off-by: Peter Xu 
---
  tests/qmp-test.c | 84 
  1 file changed, 84 insertions(+)




+++ b/tests/qmp-test.c
@@ -134,6 +134,89 @@ static void test_qmp_protocol(void)
  qtest_quit(qts);
  }
  
+/* Tests for Out-Of-Band support. */

+static void test_qmp_oob(void)
+{
+QTestState *qts;
+QDict *resp, *q;
+int acks = 0;
+const QListEntry *entry;
+QList *capabilities;
+QString *qstr;
+const char *cmd_id;
+const char *qmp_params = "-chardev socket,path=%s,nowait,id=char0 "
+ "-mon chardev=char0,mode=control,x-oob=on";


Again, I'd rather fold this into 7/8 qtest_init_without_qmp_handshake by 
changing "-qmp unix:%s,nowait" into "-chardev 
socket,path=%s,nowait,id=char0 -mon chardev=char0,mode=control" for ALL 
tests (as that always works), then have a bool that decides whether we 
also append ",x-oob=on" as needed.



+
+qts = qtest_init_with_qmp_format(common_args, qmp_params);
+
+/* Ignore the greeting message. */


Comment is wrong - you aren't ignoring it, but...


+resp = qtest_qmp_receive(qts);
+q = qdict_get_qdict(resp, "QMP");
+g_assert(q);
+capabilities = qdict_get_qlist(q, "capabilities");
+g_assert(capabilities && !qlist_empty(capabilities));


...actually inspecting what it contains.


+entry = qlist_first(capabilities);
+g_assert(entry);
+qstr = qobject_to(QString, entry->value);
+g_assert(qstr);
+g_assert_cmpstr(qstring_get_str(qstr), ==, "oob");
+QDECREF(resp);
+


In the interest of getting this in -rc1, I will probably try and make 
the changes I've mentioned in this thread, and post a v2 along those 
lines; if you like my changes, I can send the pull request on my Tuesday 
morning instead of waiting for another round of back-and-forth.


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



Re: [Qemu-devel] [PATCH for-2.12 7/8] tests: introduce qtest_init_with_qmp_format()

2018-03-26 Thread Eric Blake

On 03/26/2018 01:39 AM, Peter Xu wrote:

It is abstracted from qtest_init_without_qmp_handshake(). It works just
like qtest_init_without_qmp_handshake() but further it would allow the
caller to specify the QMP parameter.

Signed-off-by: Peter Xu 
---
  tests/libqtest.c | 14 +++---
  tests/libqtest.h | 14 ++
  2 files changed, 25 insertions(+), 3 deletions(-)



[Reviewing in reverse order; you may want to look at 
scripts/git.orderfile for how to present your patches in a more logical 
manner with .h changes first.]


> diff --git a/tests/libqtest.h b/tests/libqtest.h
> index 811169453a..1f3605ce73 100644
> --- a/tests/libqtest.h
> +++ b/tests/libqtest.h
> @@ -62,6 +62,20 @@ QTestState *qtest_init(const char *extra_args);
>*/
>   QTestState *qtest_init_without_qmp_handshake(const char *extra_args);
>
> +/**
> + * qtest_init_with_qmp_format:
> + * @extra_args: other arguments to pass to QEMU.

Not your fault, but I'm already not a fan of 'extra_args'; it would be 
better to make these functions take an array of arguments, or even use 
varargs, instead of relying on shell word splitting.  Our testsuite is a 
gaping security hole if executed in a directory where a shell 
metacharacter causes the shell word splitting to do something different 
than planned.


> + * @qmp_format: format of QMP parameters, should contain one "%s"
> + *  field so that the socket path will be filled later.
> + *
> + * Note that this function will work just like
> + * qtest_init_without_qmp_handshake(), so no QMP handshake will be done.
> + *
> + * Returns: #QTestState instance.
> + */
> +QTestState *qtest_init_with_qmp_format(const char *extra_args,
> +   const char *qmp_format);

Ouch - you didn't use any attribute to mark the format string so that 
the compiler can enforce that it is treated as a printf-style argument. 
I wonder if it would have been better to just have a 'bool use_oob' 
parameter rather than playing ugly games with passing printf-style 
format arguments around.


> +
>   /**
>* qtest_quit:
>* @s: #QTestState instance to operate on.
>


diff --git a/tests/libqtest.c b/tests/libqtest.c
index 200b2b9e92..d2af1b17f0 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -166,19 +166,22 @@ static const char *qtest_qemu_binary(void)
  return qemu_bin;
  }
  
-QTestState *qtest_init_without_qmp_handshake(const char *extra_args)

+QTestState *qtest_init_with_qmp_format(const char *extra_args,
+   const char *qmp_format)
  {
  QTestState *s;
  int sock, qmpsock, i;
  gchar *socket_path;
  gchar *qmp_socket_path;
  gchar *command;
+gchar *qmp_params;
  const char *qemu_binary = qtest_qemu_binary();
  
  s = g_new(QTestState, 1);
  
  socket_path = g_strdup_printf("/tmp/qtest-%d.sock", getpid());

  qmp_socket_path = g_strdup_printf("/tmp/qtest-%d.qmp", getpid());
+qmp_params = g_strdup_printf(qmp_format, qmp_socket_path);


And in addition to my earlier comment about not using a compiler 
attribute, you aren't even bothering to assert that the caller didn't 
pass in a garbage string, which can really lead to weird breakages.


  
  /* It's possible that if an earlier test run crashed it might

   * have left a stale unix socket lying around. Delete any
@@ -199,12 +202,12 @@ QTestState *qtest_init_without_qmp_handshake(const char 
*extra_args)
  command = g_strdup_printf("exec %s "
"-qtest unix:%s,nowait "
"-qtest-log %s "
-  "-qmp unix:%s,nowait "
+  "%s "
"-machine accel=qtest "
"-display none "
"%s", qemu_binary, socket_path,
getenv("QTEST_LOG") ? "/dev/fd/2" : 
"/dev/null",
-  qmp_socket_path,
+  qmp_params,


Again, if you used the idea of a 'bool use_oob',  this would look more like:

"-qmp unix:%s,nowait%s ",
...
qmp_socket_path, use_oob ? "x-oob=on" : "",

which is a lot more limited in scope to prevent auditing nightmares, 
while no less powerful for what you are actually using this new function 
for.



extra_args ?: "");
  execlp("/bin/sh", "sh", "-c", command, NULL);
  exit(1);
@@ -237,6 +240,11 @@ QTestState *qtest_init_without_qmp_handshake(const char 
*extra_args)
  return s;
  }
  
+QTestState *qtest_init_without_qmp_handshake(const char *extra_args)

+{
+return qtest_init_with_qmp_format(extra_args, "-qmp unix:%s,nowait");
+}


There are so few callers of qtest_init_without_qmp_handshake() that I'd 
just add the parameter to the existing function and update its two 
callers, instead of adding yet another 

Re: [Qemu-devel] [PATCH 0/2] block/file-posix: Fix fully preallocated truncate

2018-03-26 Thread Max Reitz
On 2018-02-28 14:13, Max Reitz wrote:
> Fully preallocated truncation has a 50 % chance of working on images
> files over file-posix.  It works if $SIZE % 4G < 2G, and it fails
> otherwise.  To make things even more interesting, often you would not
> even notice because qemu reported success even though it did nothing
> (because after the successful lseek(), errno was still 0, so when the
> file-posix driver tried to return a negative error code, it actually
> reported success).
> 
> This issue is fixed by patch 1 in this series.  Thanks to Daniel for
> reporting!
> 
> 
> Max Reitz (2):
>   block/file-posix: Fix fully preallocated truncate
>   iotests: Test preallocated truncate of 2G image
> 
>  block/file-posix.c |  5 +++--
>  tests/qemu-iotests/106 | 24 
>  tests/qemu-iotests/106.out | 10 ++
>  3 files changed, 37 insertions(+), 2 deletions(-)

Applied to my block tree...  (*cough* *cough* -- I'm the worst when it
comes to keeping track of my own patches.)

Max



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH for-2.12 6/8] tests: add oob-test for qapi-schema

2018-03-26 Thread Eric Blake

On 03/26/2018 01:38 AM, Peter Xu wrote:

It simply tests the new OOB capability, and make sure the QAPISchema can
parse it correctly.

Signed-off-by: Peter Xu 
---
  tests/Makefile.include  | 1 +
  tests/qapi-schema/oob-test.err  | 1 +
  tests/qapi-schema/oob-test.exit | 1 +
  tests/qapi-schema/oob-test.json | 2 ++
  tests/qapi-schema/oob-test.out  | 0
  tests/qapi-schema/qapi-schema-test.json | 3 +++
  tests/qapi-schema/qapi-schema-test.out  | 2 ++
  tests/test-qmp-cmds.c   | 4 
  8 files changed, 14 insertions(+)
  create mode 100644 tests/qapi-schema/oob-test.err
  create mode 100644 tests/qapi-schema/oob-test.exit
  create mode 100644 tests/qapi-schema/oob-test.json
  create mode 100644 tests/qapi-schema/oob-test.out


Reviewed-by: Eric Blake 

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



[Qemu-devel] [PULL 3/4] iotests: enable shared migration cases in 169

2018-03-26 Thread Max Reitz
From: Vladimir Sementsov-Ogievskiy 

Shared migration for dirty bitmaps is fixed by previous patches,
so we can enable the test.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Message-id: 20180320170521.32152-5-vsement...@virtuozzo.com
Signed-off-by: Max Reitz 
---
 tests/qemu-iotests/169 | 8 +++-
 tests/qemu-iotests/169.out | 4 ++--
 2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/tests/qemu-iotests/169 b/tests/qemu-iotests/169
index 3a8db91f6f..153b10b6e7 100755
--- a/tests/qemu-iotests/169
+++ b/tests/qemu-iotests/169
@@ -140,16 +140,14 @@ def inject_test_case(klass, name, method, *args, 
**kwargs):
 mc = operator.methodcaller(method, *args, **kwargs)
 setattr(klass, 'test_' + name, new.instancemethod(mc, None, klass))
 
-for cmb in list(itertools.product((True, False), repeat=3)):
+for cmb in list(itertools.product((True, False), repeat=4)):
 name = ('_' if cmb[0] else '_not_') + 'persistent_'
 name += ('_' if cmb[1] else '_not_') + 'migbitmap_'
 name += '_online' if cmb[2] else '_offline'
-
-# TODO fix shared-storage bitmap migration and enable cases for it
-args = list(cmb) + [False]
+name += '_shared' if cmb[3] else '_nonshared'
 
 inject_test_case(TestDirtyBitmapMigration, name, 'do_test_migration',
- *args)
+ *list(cmb))
 
 
 if __name__ == '__main__':
diff --git a/tests/qemu-iotests/169.out b/tests/qemu-iotests/169.out
index 594c16f49f..b6f257674e 100644
--- a/tests/qemu-iotests/169.out
+++ b/tests/qemu-iotests/169.out
@@ -1,5 +1,5 @@
-
+
 --
-Ran 8 tests
+Ran 16 tests
 
 OK
-- 
2.14.3




[Qemu-devel] [PULL 1/4] qcow2-bitmap: add qcow2_reopen_bitmaps_rw_hint()

2018-03-26 Thread Max Reitz
From: Vladimir Sementsov-Ogievskiy 

Add version of qcow2_reopen_bitmaps_rw, which do the same work but
also return a hint about was header updated or not. This will be
used in the following fix for bitmaps reloading after migration.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: John Snow 
Reviewed-by: Max Reitz 
Message-id: 20180320170521.32152-2-vsement...@virtuozzo.com
Signed-off-by: Max Reitz 
---
 block/qcow2.h|  2 ++
 block/qcow2-bitmap.c | 15 ++-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/block/qcow2.h b/block/qcow2.h
index ccb92a9696..d301f77cea 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -671,6 +671,8 @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, 
BdrvCheckResult *res,
   void **refcount_table,
   int64_t *refcount_table_size);
 bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, Error **errp);
+int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs, bool *header_updated,
+ Error **errp);
 int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp);
 void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp);
 int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp);
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
index 3010adb909..6e93ec43e1 100644
--- a/block/qcow2-bitmap.c
+++ b/block/qcow2-bitmap.c
@@ -1004,7 +1004,8 @@ fail:
 return false;
 }
 
-int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp)
+int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs, bool *header_updated,
+ Error **errp)
 {
 BDRVQcow2State *s = bs->opaque;
 Qcow2BitmapList *bm_list;
@@ -1012,6 +1013,10 @@ int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error 
**errp)
 GSList *ro_dirty_bitmaps = NULL;
 int ret = 0;
 
+if (header_updated != NULL) {
+*header_updated = false;
+}
+
 if (s->nb_bitmaps == 0) {
 /* No bitmaps - nothing to do */
 return 0;
@@ -1055,6 +1060,9 @@ int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error 
**errp)
 error_setg_errno(errp, -ret, "Can't update bitmap directory");
 goto out;
 }
+if (header_updated != NULL) {
+*header_updated = true;
+}
 g_slist_foreach(ro_dirty_bitmaps, set_readonly_helper, false);
 }
 
@@ -1065,6 +1073,11 @@ out:
 return ret;
 }
 
+int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp)
+{
+return qcow2_reopen_bitmaps_rw_hint(bs, NULL, errp);
+}
+
 /* store_bitmap_data()
  * Store bitmap to image, filling bitmap table accordingly.
  */
-- 
2.14.3




[Qemu-devel] [PULL 4/4] vmdk: return ERROR when cluster sector is larger than vmdk limitation

2018-03-26 Thread Max Reitz
From: yuchenlin 

VMDK has a hard limitation of extent size, which is due to the size of grain
table entry is 32 bits. It means it can only point to a grain located at
offset = 2^32. To avoid writing the user data beyond limitation and record a 
useless offset
in grain table. We should return ERROR here.

Signed-off-by: yuchenlin 
Message-id: 2018032217.28024-1-yuchen...@synology.com
Reviewed-by: Fam Zheng 
Signed-off-by: Max Reitz 
---
 block/vmdk.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/block/vmdk.c b/block/vmdk.c
index f94c49a9c0..84f8bbe480 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -47,6 +47,8 @@
 #define VMDK4_FLAG_MARKER (1 << 17)
 #define VMDK4_GD_AT_END 0xULL
 
+#define VMDK_EXTENT_MAX_SECTORS (1ULL << 32)
+
 #define VMDK_GTE_ZEROED 0x1
 
 /* VMDK internal error codes */
@@ -1250,6 +1252,10 @@ static int get_cluster_offset(BlockDriverState *bs,
 return zeroed ? VMDK_ZEROED : VMDK_UNALLOC;
 }
 
+if (extent->next_cluster_sector >= VMDK_EXTENT_MAX_SECTORS) {
+return VMDK_ERROR;
+}
+
 cluster_sector = extent->next_cluster_sector;
 extent->next_cluster_sector += extent->cluster_sectors;
 
-- 
2.14.3




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

2018-03-26 Thread Max Reitz
The following changes since commit 7b93d78a04aa242d377ae213b79db6c319c71847:

  Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging 
(2018-03-26 15:17:25 +0100)

are available in the Git repository at:

  git://github.com/XanClic/qemu.git tags/pull-block-2018-03-26

for you to fetch changes up to a77672ea3d95094a0cb4f974de84fb7353c67cc0:

  vmdk: return ERROR when cluster sector is larger than vmdk limitation 
(2018-03-26 21:17:24 +0200)


A fix for dirty bitmap migration through shared storage, and a VMDK
patch keeping us from creating too large extents.


Vladimir Sementsov-Ogievskiy (3):
  qcow2-bitmap: add qcow2_reopen_bitmaps_rw_hint()
  qcow2: fix bitmaps loading when bitmaps already exist
  iotests: enable shared migration cases in 169

yuchenlin (1):
  vmdk: return ERROR when cluster sector is larger than vmdk limitation

 block/qcow2.h  |  2 ++
 block/qcow2-bitmap.c   | 15 ++-
 block/qcow2.c  | 17 -
 block/vmdk.c   |  6 ++
 tests/qemu-iotests/169 |  8 +++-
 tests/qemu-iotests/169.out |  4 ++--
 6 files changed, 43 insertions(+), 9 deletions(-)

-- 
2.14.3




[Qemu-devel] [PULL 2/4] qcow2: fix bitmaps loading when bitmaps already exist

2018-03-26 Thread Max Reitz
From: Vladimir Sementsov-Ogievskiy 

On reopen with existing bitmaps, instead of loading bitmaps, lets
reopen them if needed. This also fixes bitmaps migration through
shared storage.
Consider the case. Persistent bitmaps are stored on bdrv_inactivate.
Then, on destination process_incoming_migration_bh() calls
bdrv_invalidate_cache_all() which leads to
qcow2_load_autoloading_dirty_bitmaps() which fails if bitmaps are
already loaded on destination start.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Message-id: 20180320170521.32152-3-vsement...@virtuozzo.com
Signed-off-by: Max Reitz 
---
 block/qcow2.c | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index cf4f3becae..486f3e83b7 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1480,7 +1480,22 @@ static int coroutine_fn qcow2_do_open(BlockDriverState 
*bs, QDict *options,
 s->autoclear_features &= QCOW2_AUTOCLEAR_MASK;
 }
 
-if (qcow2_load_dirty_bitmaps(bs, _err)) {
+if (bdrv_dirty_bitmap_next(bs, NULL)) {
+/* It's some kind of reopen with already existing dirty bitmaps. There
+ * are no known cases where we need loading bitmaps in such situation,
+ * so it's safer don't load them.
+ *
+ * Moreover, if we have some readonly bitmaps and we are reopening for
+ * rw we should reopen bitmaps correspondingly.
+ */
+if (bdrv_has_readonly_bitmaps(bs) &&
+!bdrv_is_read_only(bs) && !(bdrv_get_flags(bs) & BDRV_O_INACTIVE))
+{
+bool header_updated = false;
+qcow2_reopen_bitmaps_rw_hint(bs, _updated, _err);
+update_header = update_header && !header_updated;
+}
+} else if (qcow2_load_dirty_bitmaps(bs, _err)) {
 update_header = false;
 }
 if (local_err != NULL) {
-- 
2.14.3




Re: [Qemu-devel] [PATCH for-2.12 3/8] monitor: new parameter "x-oob"

2018-03-26 Thread Eric Blake

On 03/26/2018 04:10 AM, Marc-André Lureau wrote:

Hi

On Mon, Mar 26, 2018 at 8:38 AM, Peter Xu  wrote:

Add new parameter to optionally enable Out-Of-Band for a QMP server.

An example command line:

   ./qemu-system-x86_64 -chardev stdio,id=char0 \
-mon chardev=char0,mode=control,x-oob=on

By default, Out-Of-Band is off.

It is not allowed if either MUX or non-QMP is detected, since
Out-Of-Band is currently only for QMP, and non-MUX chardev backends.


Worth documenting in the commit message at least that even when OOB is 
enabled, the client must STILL opt-in to using it by replying correctly 
to qmp_capabilities, as well as mention that in the future, we may 
remove x-oob and rely on JUST qmp_capabilities for enabling OOB.




@@ -4568,12 +4569,26 @@ static void monitor_qmp_setup_handlers_bh(void *opaque)
  void monitor_init(Chardev *chr, int flags)
  {
  Monitor *mon = g_malloc(sizeof(*mon));
+bool use_readline = flags & MONITOR_USE_READLINE;
+bool use_oob = flags & MONITOR_USE_OOB;
+
+if (use_oob) {
+if (CHARDEV_IS_MUX(chr)) {
+error_report("Monitor Out-Of-Band is not supported with "
+ "MUX typed chardev backend");
+exit(1);
+}
+if (use_readline) {
+error_report("Monitor Out-Of-band is only supported by QMP");
+exit(1);


Should these two checks be swapped?  Otherwise, if you use a MUX-typed 
chardev for HMP, the message implies that switching chardev backend 
might make it work, even though if you actually do that you'd then get 
the failure for not being QMP.



+}
+}


I would rather see the error reporting / exit in vl.c:mon_init_func()
function, to have a single place for exit()


To do that, monitor_init() should change signatures to take Error 
**errp.  Probably worth doing if you spin a v2 of this series (adding 
the parameter can be done as a separate patch, although there are only 5 
callers in the tree so adjusting the callers at the same time is 
probably not that hard to review).




Other than that, it looks fine.
Reviewed-by: Marc-André Lureau 


Okay, I'll see how my review goes on the rest of the series before 
deciding whether to request a v2.


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



Re: [Qemu-devel] [PATCH] i386/kvm: add support for KVM_CAP_X86_DISABLE_EXITS

2018-03-26 Thread Eduardo Habkost
On Sun, Mar 25, 2018 at 11:33:01AM +0800, Wanpeng Li wrote:
> 2018-03-24 4:18 GMT+08:00 Eduardo Habkost :
> > On Fri, Mar 16, 2018 at 07:36:42AM -0700, Wanpeng Li wrote:
> >> From: Wanpeng Li 
> >>
> >> This patch adds support for KVM_CAP_X86_DISABLE_EXITS. Provides userspace 
> >> with
> >> per-VM capability(KVM_CAP_X86_DISABLE_EXITS) to not intercept 
> >> MWAIT/HLT/PAUSE
> >> in order that to improve latency in some workloads.
> >>
> >> Cc: Paolo Bonzini 
> >> Cc: Radim Krčmář 
> >> Cc: Eduardo Habkost 
> >> Signed-off-by: Wanpeng Li 
> >
> >
> > Thanks.
> >
> > Patch looks good (except for comment below), but I would like to
> > see QEMU documentation mentioning what exactly are the practical
> > consequences of setting "+kvm-hint-dedicated" (especially what
> > could happen if people enable the flag without properly
> > configuring vCPU pinning).
> >
> >
> > [...]
> >> +if (env->features[FEAT_KVM_HINTS] & KVM_HINTS_DEDICATED) {
> >> +int disable_exits = kvm_check_extension(cs->kvm_state, 
> >> KVM_CAP_X86_DISABLE_EXITS);
> >> +if (disable_exits) {
> >> +disable_exits &= (KVM_X86_DISABLE_EXITS_MWAIT |
> >> +  KVM_X86_DISABLE_EXITS_HLT |
> >> +  KVM_X86_DISABLE_EXITS_PAUSE);
> >> +}
> >
> > Documentation/virtual/kvm/api.txt says that KVM_FEATURE_PV_UNHALT
> > shouldn't be enabled if disabling HLT exits.  This needs to be
> > handled by QEMU.
> 
> This is handled by KVM(in kvm_update_cpuid()) currently to avoid kvm
> userspace doing something crazy.
> https://git.kernel.org/pub/scm/virt/kvm/kvm.git/commit/?h=queue=caa057a2cad647fb368a12c8e6c410ac4c28e063

This seems to disable kvm-pv-unhalt silently if
KVM_X86_DISABLE_EXITS_HLT is enabled.  We shouldn't do that if
the user explicitly requested +kvm-pv-unhalt in the command-line.

> 
> >
> > Probably the simplest solution is to not allow kvm-hint-dedicated
> > to be enabled if kvm-pv-unhalt is.  This should be mentioned in
> > QEMU documentation, also, especially considering that we might
> > enable kvm-pv-unhalt by default in future QEMU versions.
> 
> As Locking guy Waiman mentioned before:
> > Generally speaking, unfair lock performs well for VMs with a small number 
> > of vCPUs. Native qspinlock may perform better than pvqspinlock if there is 
> > vCPU pinning and there is no vCPU over-commitment.
> I think +kvm-hint-dedicated, -kvm-pv-unhalt is more suitable for vCPU
> pinning and there is no vCPU over-commitment, on the contrary,
> -kvm-hint-dedicated, +kvm-pv-unhalt is more prefer.

Disabling kvm-pv-unhalt by default if only "-cpu
...,+kvm-hint-dedicated" is used makes sense.  But we still need
the system to not silently ignore options if
"-cpu ...,+kvm-pv-unhalt,+kvm-hint-dedicated" is specified.

-- 
Eduardo



Re: [Qemu-devel] [PATCH for-2.12 4/8] qapi: restrict allow-oob value to be "true"

2018-03-26 Thread Eric Blake

On 03/26/2018 04:11 AM, Marc-André Lureau wrote:

On Mon, Mar 26, 2018 at 8:38 AM, Peter Xu  wrote:

It was missed in the first version of OOB series.  We should check this
to make sure we throw the right error when fault value is passed in.

Signed-off-by: Peter Xu 


Not exactly required imho, but why not:
Reviewed-by: Marc-André Lureau 


Not technically required, but does add some consistency to the QAPI parser.

Reviewed-by: Eric Blake 

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



Re: [Qemu-devel] [PATCH for-2.12 2/8] qmp: cleanup qmp queues properly

2018-03-26 Thread Eric Blake

On 03/26/2018 01:38 AM, Peter Xu wrote:

Marc-André Lureau reported that we can have this happen:

1. client1 connects, send command C1
2. client1 disconnects before getting response for C1
3. client2 connects, who might receive response of C1

However client2 should not receive remaining responses for client1.

Basically, we should clean up the request/response queue elements when:

- before a session established


Why here? [1]


- after a session is closed
- before destroying the queues

Some helpers are introduced to achieve that.  We need to make sure we're
with the lock when operating on those queues.



It would also be helpful to mention that the patch includes code motion 
to declare struct QMPRequest earlier in the file.



Reported-by: Marc-André Lureau 
Signed-off-by: Peter Xu 
---
  monitor.c | 79 +++
  1 file changed, 59 insertions(+), 20 deletions(-)




+static void qmp_request_free(QMPRequest *req)
+{
+qobject_decref(req->id);
+qobject_decref(req->req);
+g_free(req);
+}
+
+static void qmp_response_free(QObject *obj)
+{
+qobject_decref(obj);
+}


Why do we need this function?  Unless you plan to add to it in later 
patches, I'd rather just inline things and directly call 
qobject_decref() at the callsites...



+
+/* Must with the mon->qmp.qmp_queue_lock held */
+static void monitor_qmp_cleanup_req_queue_locked(Monitor *mon)
+{
+while (!g_queue_is_empty(mon->qmp.qmp_requests)) {
+qmp_request_free(g_queue_pop_head(mon->qmp.qmp_requests));
+}
+}
+
+/* Must with the mon->qmp.qmp_queue_lock held */
+static void monitor_qmp_cleanup_resp_queue_locked(Monitor *mon)
+{
+while (!g_queue_is_empty(mon->qmp.qmp_responses)) {
+qmp_response_free(g_queue_pop_head(mon->qmp.qmp_responses));


...here,


+}
+}
+
+static void monitor_qmp_cleanup_queues(Monitor *mon)
+{
+qemu_mutex_lock(>qmp.qmp_queue_lock);
+monitor_qmp_cleanup_req_queue_locked(mon);
+monitor_qmp_cleanup_resp_queue_locked(mon);
+qemu_mutex_unlock(>qmp.qmp_queue_lock);
+}
+
+
  static void monitor_flush_locked(Monitor *mon);
  
  static gboolean monitor_unblocked(GIOChannel *chan, GIOCondition cond,

@@ -497,7 +550,7 @@ static void monitor_qmp_bh_responder(void *opaque)
  break;
  }
  monitor_json_emitter_raw(response.mon, response.data);
-qobject_decref(response.data);
+qmp_response_free(response.data);


and here.


@@ -4327,6 +4364,7 @@ static void monitor_qmp_event(void *opaque, int event)
  
  switch (event) {

  case CHR_EVENT_OPENED:
+monitor_qmp_cleanup_queues(mon);


[1] How would something be queued to need cleanup at this point, if we 
already start with a clean queue before the first monitor, and if all 
monitor close actions clean the queue?



  mon->qmp.commands = _cap_negotiation_commands;
  monitor_qmp_caps_reset(mon);
  data = get_qmp_greeting(mon);
@@ -4335,6 +4373,7 @@ static void monitor_qmp_event(void *opaque, int event)
  mon_refcount++;
  break;
  case CHR_EVENT_CLOSED:
+monitor_qmp_cleanup_queues(mon);
  json_message_parser_destroy(>qmp.parser);
  json_message_parser_init(>qmp.parser, handle_qmp_command);
  mon_refcount--;



--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



Re: [Qemu-devel] [PATCH for-2.12 1/8] qmp: fix qmp_capabilities error regression

2018-03-26 Thread Eric Blake

On 03/26/2018 01:38 AM, Peter Xu wrote:

When someone sents a command before QMP handshake, error was like this:


s/sents/sends/
s/error was/the error used to be/



  {"execute": "query-cpus"}
  {"error": {"class": "CommandNotFound", "desc":
 "Expecting capabilities negotiation with 'qmp_capabilities'"}}

While after cf869d5317 it becomes:

  {"execute": "query-cpus"}
  {"error": {"class": "CommandNotFound", "desc":
 "The command query-cpus has not been found"}}

Fix it back to the nicer one.

Fixes: cf869d5317 ("qmp: support out-of-band (oob) execution", 2018-03-19)
Reported-by: Marc-André Lureau 
Signed-off-by: Peter Xu 
---
  monitor.c | 23 ---
  1 file changed, 8 insertions(+), 15 deletions(-)



Reviewed-by: Eric Blake 

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



Re: [Qemu-devel] [PATCH v3 06/38] monitor: no need to remove desc before replacing it

2018-03-26 Thread Eric Blake

On 03/26/2018 10:08 AM, Marc-André Lureau wrote:

The following qdict_put() line does replace the value, as the
documentation says.

Signed-off-by: Marc-André Lureau 
---
  monitor.c | 1 -
  1 file changed, 1 deletion(-)


This patch is unneeded once Peter's change lands:
https://lists.gnu.org/archive/html/qemu-devel/2018-03/msg06513.html
as that patch also deletes the line in question.

It may be worth waiting for the OOB stuff to settle and then rebase the 
remaining cleanups as a separate series from the async command addition, 
especially if some of the cleanups are still relevant as minor bug fixes 
for 2.12.


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



[Qemu-devel] [PATCH for 2.13 07/19] linux-user: move mips/mips64 cpu loop to mips directory

2018-03-26 Thread Laurent Vivier
No code change, only move code from main.c to
mips/cpu_loop.c.

Include mips/cpu_loop.c in mips64/cpu_loop.c
to avoid to duplicate code.

Signed-off-by: Laurent Vivier 
---
 linux-user/main.c| 725 ---
 linux-user/mips/cpu_loop.c   | 723 ++
 linux-user/mips64/cpu_loop.c |   8 +-
 3 files changed, 724 insertions(+), 732 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index b5d0513b44..490733a3fb 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -149,705 +149,6 @@ void fork_end(int child)
 }
 }
 
-#ifdef TARGET_MIPS
-
-# ifdef TARGET_ABI_MIPSO32
-#  define MIPS_SYS(name, args) args,
-static const uint8_t mips_syscall_args[] = {
-   MIPS_SYS(sys_syscall, 8)/* 4000 */
-   MIPS_SYS(sys_exit   , 1)
-   MIPS_SYS(sys_fork   , 0)
-   MIPS_SYS(sys_read   , 3)
-   MIPS_SYS(sys_write  , 3)
-   MIPS_SYS(sys_open   , 3)/* 4005 */
-   MIPS_SYS(sys_close  , 1)
-   MIPS_SYS(sys_waitpid, 3)
-   MIPS_SYS(sys_creat  , 2)
-   MIPS_SYS(sys_link   , 2)
-   MIPS_SYS(sys_unlink , 1)/* 4010 */
-   MIPS_SYS(sys_execve , 0)
-   MIPS_SYS(sys_chdir  , 1)
-   MIPS_SYS(sys_time   , 1)
-   MIPS_SYS(sys_mknod  , 3)
-   MIPS_SYS(sys_chmod  , 2)/* 4015 */
-   MIPS_SYS(sys_lchown , 3)
-   MIPS_SYS(sys_ni_syscall , 0)
-   MIPS_SYS(sys_ni_syscall , 0)/* was sys_stat */
-   MIPS_SYS(sys_lseek  , 3)
-   MIPS_SYS(sys_getpid , 0)/* 4020 */
-   MIPS_SYS(sys_mount  , 5)
-   MIPS_SYS(sys_umount , 1)
-   MIPS_SYS(sys_setuid , 1)
-   MIPS_SYS(sys_getuid , 0)
-   MIPS_SYS(sys_stime  , 1)/* 4025 */
-   MIPS_SYS(sys_ptrace , 4)
-   MIPS_SYS(sys_alarm  , 1)
-   MIPS_SYS(sys_ni_syscall , 0)/* was sys_fstat */
-   MIPS_SYS(sys_pause  , 0)
-   MIPS_SYS(sys_utime  , 2)/* 4030 */
-   MIPS_SYS(sys_ni_syscall , 0)
-   MIPS_SYS(sys_ni_syscall , 0)
-   MIPS_SYS(sys_access , 2)
-   MIPS_SYS(sys_nice   , 1)
-   MIPS_SYS(sys_ni_syscall , 0)/* 4035 */
-   MIPS_SYS(sys_sync   , 0)
-   MIPS_SYS(sys_kill   , 2)
-   MIPS_SYS(sys_rename , 2)
-   MIPS_SYS(sys_mkdir  , 2)
-   MIPS_SYS(sys_rmdir  , 1)/* 4040 */
-   MIPS_SYS(sys_dup, 1)
-   MIPS_SYS(sys_pipe   , 0)
-   MIPS_SYS(sys_times  , 1)
-   MIPS_SYS(sys_ni_syscall , 0)
-   MIPS_SYS(sys_brk, 1)/* 4045 */
-   MIPS_SYS(sys_setgid , 1)
-   MIPS_SYS(sys_getgid , 0)
-   MIPS_SYS(sys_ni_syscall , 0)/* was signal(2) */
-   MIPS_SYS(sys_geteuid, 0)
-   MIPS_SYS(sys_getegid, 0)/* 4050 */
-   MIPS_SYS(sys_acct   , 0)
-   MIPS_SYS(sys_umount2, 2)
-   MIPS_SYS(sys_ni_syscall , 0)
-   MIPS_SYS(sys_ioctl  , 3)
-   MIPS_SYS(sys_fcntl  , 3)/* 4055 */
-   MIPS_SYS(sys_ni_syscall , 2)
-   MIPS_SYS(sys_setpgid, 2)
-   MIPS_SYS(sys_ni_syscall , 0)
-   MIPS_SYS(sys_olduname   , 1)
-   MIPS_SYS(sys_umask  , 1)/* 4060 */
-   MIPS_SYS(sys_chroot , 1)
-   MIPS_SYS(sys_ustat  , 2)
-   MIPS_SYS(sys_dup2   , 2)
-   MIPS_SYS(sys_getppid, 0)
-   MIPS_SYS(sys_getpgrp, 0)/* 4065 */
-   MIPS_SYS(sys_setsid , 0)
-   MIPS_SYS(sys_sigaction  , 3)
-   MIPS_SYS(sys_sgetmask   , 0)
-   MIPS_SYS(sys_ssetmask   , 1)
-   MIPS_SYS(sys_setreuid   , 2)/* 4070 */
-   MIPS_SYS(sys_setregid   , 2)
-   MIPS_SYS(sys_sigsuspend , 0)
-   MIPS_SYS(sys_sigpending , 1)
-   MIPS_SYS(sys_sethostname, 2)
-   MIPS_SYS(sys_setrlimit  , 2)/* 4075 */
-   MIPS_SYS(sys_getrlimit  , 2)
-   MIPS_SYS(sys_getrusage  , 2)
-   MIPS_SYS(sys_gettimeofday, 2)
-   MIPS_SYS(sys_settimeofday, 2)
-   MIPS_SYS(sys_getgroups  , 2)/* 4080 */
-   MIPS_SYS(sys_setgroups  , 2)
-   MIPS_SYS(sys_ni_syscall , 0)/* old_select */
-   MIPS_SYS(sys_symlink, 2)
-   MIPS_SYS(sys_ni_syscall , 0)/* was sys_lstat */
-   MIPS_SYS(sys_readlink   , 3)/* 4085 */
-   MIPS_SYS(sys_uselib , 1)
-   MIPS_SYS(sys_swapon , 2)
-   MIPS_SYS(sys_reboot , 3)
-   MIPS_SYS(old_readdir, 3)
-   MIPS_SYS(old_mmap   , 6)/* 4090 */
-   MIPS_SYS(sys_munmap , 2)
-   MIPS_SYS(sys_truncate   , 2)
-   MIPS_SYS(sys_ftruncate  , 2)
-   MIPS_SYS(sys_fchmod , 2)
-   MIPS_SYS(sys_fchown , 3)/* 4095 */
-   MIPS_SYS(sys_getpriority, 2)
-   MIPS_SYS(sys_setpriority, 3)
-   MIPS_SYS(sys_ni_syscall , 0)
-   MIPS_SYS(sys_statfs , 2)
-   MIPS_SYS(sys_fstatfs, 2)/* 4100 */
-   MIPS_SYS(sys_ni_syscall , 0)

[Qemu-devel] [PATCH for 2.13 18/19] linux-user: move hppa cpu loop to hppa directory

2018-03-26 Thread Laurent Vivier
No code change, only move code from main.c to
hppa/cpu_loop.c.

Signed-off-by: Laurent Vivier 
---
 linux-user/hppa/cpu_loop.c | 185 ++
 linux-user/main.c  | 194 +
 2 files changed, 186 insertions(+), 193 deletions(-)

diff --git a/linux-user/hppa/cpu_loop.c b/linux-user/hppa/cpu_loop.c
index b7700a5561..0301c766c6 100644
--- a/linux-user/hppa/cpu_loop.c
+++ b/linux-user/hppa/cpu_loop.c
@@ -21,6 +21,191 @@
 #include "qemu.h"
 #include "cpu_loop-common.h"
 
+static abi_ulong hppa_lws(CPUHPPAState *env)
+{
+uint32_t which = env->gr[20];
+abi_ulong addr = env->gr[26];
+abi_ulong old = env->gr[25];
+abi_ulong new = env->gr[24];
+abi_ulong size, ret;
+
+switch (which) {
+default:
+return -TARGET_ENOSYS;
+
+case 0: /* elf32 atomic 32bit cmpxchg */
+if ((addr & 3) || !access_ok(VERIFY_WRITE, addr, 4)) {
+return -TARGET_EFAULT;
+}
+old = tswap32(old);
+new = tswap32(new);
+ret = atomic_cmpxchg((uint32_t *)g2h(addr), old, new);
+ret = tswap32(ret);
+break;
+
+case 2: /* elf32 atomic "new" cmpxchg */
+size = env->gr[23];
+if (size >= 4) {
+return -TARGET_ENOSYS;
+}
+if (((addr | old | new) & ((1 << size) - 1))
+|| !access_ok(VERIFY_WRITE, addr, 1 << size)
+|| !access_ok(VERIFY_READ, old, 1 << size)
+|| !access_ok(VERIFY_READ, new, 1 << size)) {
+return -TARGET_EFAULT;
+}
+/* Note that below we use host-endian loads so that the cmpxchg
+   can be host-endian as well.  */
+switch (size) {
+case 0:
+old = *(uint8_t *)g2h(old);
+new = *(uint8_t *)g2h(new);
+ret = atomic_cmpxchg((uint8_t *)g2h(addr), old, new);
+ret = ret != old;
+break;
+case 1:
+old = *(uint16_t *)g2h(old);
+new = *(uint16_t *)g2h(new);
+ret = atomic_cmpxchg((uint16_t *)g2h(addr), old, new);
+ret = ret != old;
+break;
+case 2:
+old = *(uint32_t *)g2h(old);
+new = *(uint32_t *)g2h(new);
+ret = atomic_cmpxchg((uint32_t *)g2h(addr), old, new);
+ret = ret != old;
+break;
+case 3:
+{
+uint64_t o64, n64, r64;
+o64 = *(uint64_t *)g2h(old);
+n64 = *(uint64_t *)g2h(new);
+#ifdef CONFIG_ATOMIC64
+r64 = atomic_cmpxchg__nocheck((uint64_t *)g2h(addr), o64, n64);
+ret = r64 != o64;
+#else
+start_exclusive();
+r64 = *(uint64_t *)g2h(addr);
+ret = 1;
+if (r64 == o64) {
+*(uint64_t *)g2h(addr) = n64;
+ret = 0;
+}
+end_exclusive();
+#endif
+}
+break;
+}
+break;
+}
+
+env->gr[28] = ret;
+return 0;
+}
+
+void cpu_loop(CPUHPPAState *env)
+{
+CPUState *cs = CPU(hppa_env_get_cpu(env));
+target_siginfo_t info;
+abi_ulong ret;
+int trapnr;
+
+while (1) {
+cpu_exec_start(cs);
+trapnr = cpu_exec(cs);
+cpu_exec_end(cs);
+process_queued_cpu_work(cs);
+
+switch (trapnr) {
+case EXCP_SYSCALL:
+ret = do_syscall(env, env->gr[20],
+ env->gr[26], env->gr[25],
+ env->gr[24], env->gr[23],
+ env->gr[22], env->gr[21], 0, 0);
+switch (ret) {
+default:
+env->gr[28] = ret;
+/* We arrived here by faking the gateway page.  Return.  */
+env->iaoq_f = env->gr[31];
+env->iaoq_b = env->gr[31] + 4;
+break;
+case -TARGET_ERESTARTSYS:
+case -TARGET_QEMU_ESIGRETURN:
+break;
+}
+break;
+case EXCP_SYSCALL_LWS:
+env->gr[21] = hppa_lws(env);
+/* We arrived here by faking the gateway page.  Return.  */
+env->iaoq_f = env->gr[31];
+env->iaoq_b = env->gr[31] + 4;
+break;
+case EXCP_ITLB_MISS:
+case EXCP_DTLB_MISS:
+case EXCP_NA_ITLB_MISS:
+case EXCP_NA_DTLB_MISS:
+case EXCP_IMP:
+case EXCP_DMP:
+case EXCP_DMB:
+case EXCP_PAGE_REF:
+case EXCP_DMAR:
+case EXCP_DMPI:
+info.si_signo = TARGET_SIGSEGV;
+info.si_errno = 0;
+info.si_code = TARGET_SEGV_ACCERR;
+info._sifields._sigfault._addr = env->cr[CR_IOR];
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
+break;
+case EXCP_UNALIGN:
+info.si_signo = TARGET_SIGBUS;
+

[Qemu-devel] [PATCH for 2.13 12/19] linux-user: move microblaze cpu loop to microblaze directory

2018-03-26 Thread Laurent Vivier
No code change, only move code from main.c to
microblaze/cpu_loop.c.

Signed-off-by: Laurent Vivier 
---
 linux-user/main.c| 155 ---
 linux-user/microblaze/cpu_loop.c | 150 +
 2 files changed, 150 insertions(+), 155 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 560e4a5b6a..f8c35e7369 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -149,125 +149,6 @@ void fork_end(int child)
 }
 }
 
-#ifdef TARGET_MICROBLAZE
-void cpu_loop(CPUMBState *env)
-{
-CPUState *cs = CPU(mb_env_get_cpu(env));
-int trapnr, ret;
-target_siginfo_t info;
-
-while (1) {
-cpu_exec_start(cs);
-trapnr = cpu_exec(cs);
-cpu_exec_end(cs);
-process_queued_cpu_work(cs);
-
-switch (trapnr) {
-case 0xaa:
-{
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-/* XXX: check env->error_code */
-info.si_code = TARGET_SEGV_MAPERR;
-info._sifields._sigfault._addr = 0;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-}
-break;
-   case EXCP_INTERRUPT:
- /* just indicate that signals should be handled asap */
- break;
-case EXCP_BREAK:
-/* Return address is 4 bytes after the call.  */
-env->regs[14] += 4;
-env->sregs[SR_PC] = env->regs[14];
-ret = do_syscall(env, 
- env->regs[12], 
- env->regs[5], 
- env->regs[6], 
- env->regs[7], 
- env->regs[8], 
- env->regs[9], 
- env->regs[10],
- 0, 0);
-if (ret == -TARGET_ERESTARTSYS) {
-/* Wind back to before the syscall. */
-env->sregs[SR_PC] -= 4;
-} else if (ret != -TARGET_QEMU_ESIGRETURN) {
-env->regs[3] = ret;
-}
-/* All syscall exits result in guest r14 being equal to the
- * PC we return to, because the kernel syscall exit "rtbd" does
- * this. (This is true even for sigreturn(); note that r14 is
- * not a userspace-usable register, as the kernel may clobber it
- * at any point.)
- */
-env->regs[14] = env->sregs[SR_PC];
-break;
-case EXCP_HW_EXCP:
-env->regs[17] = env->sregs[SR_PC] + 4;
-if (env->iflags & D_FLAG) {
-env->sregs[SR_ESR] |= 1 << 12;
-env->sregs[SR_PC] -= 4;
-/* FIXME: if branch was immed, replay the imm as well.  */
-}
-
-env->iflags &= ~(IMM_FLAG | D_FLAG);
-
-switch (env->sregs[SR_ESR] & 31) {
-case ESR_EC_DIVZERO:
-info.si_signo = TARGET_SIGFPE;
-info.si_errno = 0;
-info.si_code = TARGET_FPE_FLTDIV;
-info._sifields._sigfault._addr = 0;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-break;
-case ESR_EC_FPU:
-info.si_signo = TARGET_SIGFPE;
-info.si_errno = 0;
-if (env->sregs[SR_FSR] & FSR_IO) {
-info.si_code = TARGET_FPE_FLTINV;
-}
-if (env->sregs[SR_FSR] & FSR_DZ) {
-info.si_code = TARGET_FPE_FLTDIV;
-}
-info._sifields._sigfault._addr = 0;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-break;
-default:
-printf ("Unhandled hw-exception: 0x%x\n",
-env->sregs[SR_ESR] & ESR_EC_MASK);
-cpu_dump_state(cs, stderr, fprintf, 0);
-exit(EXIT_FAILURE);
-break;
-}
-break;
-case EXCP_DEBUG:
-{
-int sig;
-
-sig = gdb_handlesig(cs, TARGET_SIGTRAP);
-if (sig)
-  {
-info.si_signo = sig;
-info.si_errno = 0;
-info.si_code = TARGET_TRAP_BRKPT;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-  }
-}
-break;
-case EXCP_ATOMIC:
-cpu_exec_step_atomic(cs);
-break;
-default:
-printf ("Unhandled trap: 0x%x\n", trapnr);
-cpu_dump_state(cs, stderr, fprintf, 0);
-exit(EXIT_FAILURE);
-}
-process_pending_signals (env);
-}
-}
-#endif
-
 #ifdef TARGET_M68K
 
 void 

[Qemu-devel] [PATCH for 2.13 16/19] linux-user: move tilegx cpu loop to tilegx directory

2018-03-26 Thread Laurent Vivier
No code change, only move code from main.c to
tilegx/cpu_loop.c.

Signed-off-by: Laurent Vivier 
---
 linux-user/main.c| 267 ---
 linux-user/tilegx/cpu_loop.c | 260 +
 2 files changed, 260 insertions(+), 267 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 9693383009..3b3613cb89 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -149,262 +149,6 @@ void fork_end(int child)
 }
 }
 
-#ifdef TARGET_TILEGX
-
-static void gen_sigill_reg(CPUTLGState *env)
-{
-target_siginfo_t info;
-
-info.si_signo = TARGET_SIGILL;
-info.si_errno = 0;
-info.si_code = TARGET_ILL_PRVREG;
-info._sifields._sigfault._addr = env->pc;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-}
-
-static void do_signal(CPUTLGState *env, int signo, int sigcode)
-{
-target_siginfo_t info;
-
-info.si_signo = signo;
-info.si_errno = 0;
-info._sifields._sigfault._addr = env->pc;
-
-if (signo == TARGET_SIGSEGV) {
-/* The passed in sigcode is a dummy; check for a page mapping
-   and pass either MAPERR or ACCERR.  */
-target_ulong addr = env->excaddr;
-info._sifields._sigfault._addr = addr;
-if (page_check_range(addr, 1, PAGE_VALID) < 0) {
-sigcode = TARGET_SEGV_MAPERR;
-} else {
-sigcode = TARGET_SEGV_ACCERR;
-}
-}
-info.si_code = sigcode;
-
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-}
-
-static void gen_sigsegv_maperr(CPUTLGState *env, target_ulong addr)
-{
-env->excaddr = addr;
-do_signal(env, TARGET_SIGSEGV, 0);
-}
-
-static void set_regval(CPUTLGState *env, uint8_t reg, uint64_t val)
-{
-if (unlikely(reg >= TILEGX_R_COUNT)) {
-switch (reg) {
-case TILEGX_R_SN:
-case TILEGX_R_ZERO:
-return;
-case TILEGX_R_IDN0:
-case TILEGX_R_IDN1:
-case TILEGX_R_UDN0:
-case TILEGX_R_UDN1:
-case TILEGX_R_UDN2:
-case TILEGX_R_UDN3:
-gen_sigill_reg(env);
-return;
-default:
-g_assert_not_reached();
-}
-}
-env->regs[reg] = val;
-}
-
-/*
- * Compare the 8-byte contents of the CmpValue SPR with the 8-byte value in
- * memory at the address held in the first source register. If the values are
- * not equal, then no memory operation is performed. If the values are equal,
- * the 8-byte quantity from the second source register is written into memory
- * at the address held in the first source register. In either case, the result
- * of the instruction is the value read from memory. The compare and write to
- * memory are atomic and thus can be used for synchronization purposes. This
- * instruction only operates for addresses aligned to a 8-byte boundary.
- * Unaligned memory access causes an Unaligned Data Reference interrupt.
- *
- * Functional Description (64-bit)
- *   uint64_t memVal = memoryReadDoubleWord (rf[SrcA]);
- *   rf[Dest] = memVal;
- *   if (memVal == SPR[CmpValueSPR])
- *   memoryWriteDoubleWord (rf[SrcA], rf[SrcB]);
- *
- * Functional Description (32-bit)
- *   uint64_t memVal = signExtend32 (memoryReadWord (rf[SrcA]));
- *   rf[Dest] = memVal;
- *   if (memVal == signExtend32 (SPR[CmpValueSPR]))
- *   memoryWriteWord (rf[SrcA], rf[SrcB]);
- *
- *
- * This function also processes exch and exch4 which need not process SPR.
- */
-static void do_exch(CPUTLGState *env, bool quad, bool cmp)
-{
-target_ulong addr;
-target_long val, sprval;
-
-start_exclusive();
-
-addr = env->atomic_srca;
-if (quad ? get_user_s64(val, addr) : get_user_s32(val, addr)) {
-goto sigsegv_maperr;
-}
-
-if (cmp) {
-if (quad) {
-sprval = env->spregs[TILEGX_SPR_CMPEXCH];
-} else {
-sprval = sextract64(env->spregs[TILEGX_SPR_CMPEXCH], 0, 32);
-}
-}
-
-if (!cmp || val == sprval) {
-target_long valb = env->atomic_srcb;
-if (quad ? put_user_u64(valb, addr) : put_user_u32(valb, addr)) {
-goto sigsegv_maperr;
-}
-}
-
-set_regval(env, env->atomic_dstr, val);
-end_exclusive();
-return;
-
- sigsegv_maperr:
-end_exclusive();
-gen_sigsegv_maperr(env, addr);
-}
-
-static void do_fetch(CPUTLGState *env, int trapnr, bool quad)
-{
-int8_t write = 1;
-target_ulong addr;
-target_long val, valb;
-
-start_exclusive();
-
-addr = env->atomic_srca;
-valb = env->atomic_srcb;
-if (quad ? get_user_s64(val, addr) : get_user_s32(val, addr)) {
-goto sigsegv_maperr;
-}
-
-switch (trapnr) {
-case TILEGX_EXCP_OPCODE_FETCHADD:
-case TILEGX_EXCP_OPCODE_FETCHADD4:
-valb += val;
-break;
-case TILEGX_EXCP_OPCODE_FETCHADDGEZ:
-valb += val;
-if (valb < 0) {
-write = 0;
-}
-break;
- 

[Qemu-devel] [PATCH for 2.13 19/19] linux-user: move xtensa cpu loop to xtensa directory

2018-03-26 Thread Laurent Vivier
No code change, only move code from main.c to
xtensa/cpu_loop.c.

Signed-off-by: Laurent Vivier 
---
 linux-user/main.c| 247 ---
 linux-user/xtensa/cpu_loop.c | 238 +
 2 files changed, 238 insertions(+), 247 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 8a0a5f9f39..32347545c9 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -149,242 +149,6 @@ void fork_end(int child)
 }
 }
 
-#ifdef TARGET_XTENSA
-
-static void xtensa_rfw(CPUXtensaState *env)
-{
-xtensa_restore_owb(env);
-env->pc = env->sregs[EPC1];
-}
-
-static void xtensa_rfwu(CPUXtensaState *env)
-{
-env->sregs[WINDOW_START] |= (1 << env->sregs[WINDOW_BASE]);
-xtensa_rfw(env);
-}
-
-static void xtensa_rfwo(CPUXtensaState *env)
-{
-env->sregs[WINDOW_START] &= ~(1 << env->sregs[WINDOW_BASE]);
-xtensa_rfw(env);
-}
-
-static void xtensa_overflow4(CPUXtensaState *env)
-{
-put_user_ual(env->regs[0], env->regs[5] - 16);
-put_user_ual(env->regs[1], env->regs[5] - 12);
-put_user_ual(env->regs[2], env->regs[5] -  8);
-put_user_ual(env->regs[3], env->regs[5] -  4);
-xtensa_rfwo(env);
-}
-
-static void xtensa_underflow4(CPUXtensaState *env)
-{
-get_user_ual(env->regs[0], env->regs[5] - 16);
-get_user_ual(env->regs[1], env->regs[5] - 12);
-get_user_ual(env->regs[2], env->regs[5] -  8);
-get_user_ual(env->regs[3], env->regs[5] -  4);
-xtensa_rfwu(env);
-}
-
-static void xtensa_overflow8(CPUXtensaState *env)
-{
-put_user_ual(env->regs[0], env->regs[9] - 16);
-get_user_ual(env->regs[0], env->regs[1] - 12);
-put_user_ual(env->regs[1], env->regs[9] - 12);
-put_user_ual(env->regs[2], env->regs[9] -  8);
-put_user_ual(env->regs[3], env->regs[9] -  4);
-put_user_ual(env->regs[4], env->regs[0] - 32);
-put_user_ual(env->regs[5], env->regs[0] - 28);
-put_user_ual(env->regs[6], env->regs[0] - 24);
-put_user_ual(env->regs[7], env->regs[0] - 20);
-xtensa_rfwo(env);
-}
-
-static void xtensa_underflow8(CPUXtensaState *env)
-{
-get_user_ual(env->regs[0], env->regs[9] - 16);
-get_user_ual(env->regs[1], env->regs[9] - 12);
-get_user_ual(env->regs[2], env->regs[9] -  8);
-get_user_ual(env->regs[7], env->regs[1] - 12);
-get_user_ual(env->regs[3], env->regs[9] -  4);
-get_user_ual(env->regs[4], env->regs[7] - 32);
-get_user_ual(env->regs[5], env->regs[7] - 28);
-get_user_ual(env->regs[6], env->regs[7] - 24);
-get_user_ual(env->regs[7], env->regs[7] - 20);
-xtensa_rfwu(env);
-}
-
-static void xtensa_overflow12(CPUXtensaState *env)
-{
-put_user_ual(env->regs[0],  env->regs[13] - 16);
-get_user_ual(env->regs[0],  env->regs[1]  - 12);
-put_user_ual(env->regs[1],  env->regs[13] - 12);
-put_user_ual(env->regs[2],  env->regs[13] -  8);
-put_user_ual(env->regs[3],  env->regs[13] -  4);
-put_user_ual(env->regs[4],  env->regs[0]  - 48);
-put_user_ual(env->regs[5],  env->regs[0]  - 44);
-put_user_ual(env->regs[6],  env->regs[0]  - 40);
-put_user_ual(env->regs[7],  env->regs[0]  - 36);
-put_user_ual(env->regs[8],  env->regs[0]  - 32);
-put_user_ual(env->regs[9],  env->regs[0]  - 28);
-put_user_ual(env->regs[10], env->regs[0]  - 24);
-put_user_ual(env->regs[11], env->regs[0]  - 20);
-xtensa_rfwo(env);
-}
-
-static void xtensa_underflow12(CPUXtensaState *env)
-{
-get_user_ual(env->regs[0],  env->regs[13] - 16);
-get_user_ual(env->regs[1],  env->regs[13] - 12);
-get_user_ual(env->regs[2],  env->regs[13] -  8);
-get_user_ual(env->regs[11], env->regs[1]  - 12);
-get_user_ual(env->regs[3],  env->regs[13] -  4);
-get_user_ual(env->regs[4],  env->regs[11] - 48);
-get_user_ual(env->regs[5],  env->regs[11] - 44);
-get_user_ual(env->regs[6],  env->regs[11] - 40);
-get_user_ual(env->regs[7],  env->regs[11] - 36);
-get_user_ual(env->regs[8],  env->regs[11] - 32);
-get_user_ual(env->regs[9],  env->regs[11] - 28);
-get_user_ual(env->regs[10], env->regs[11] - 24);
-get_user_ual(env->regs[11], env->regs[11] - 20);
-xtensa_rfwu(env);
-}
-
-void cpu_loop(CPUXtensaState *env)
-{
-CPUState *cs = CPU(xtensa_env_get_cpu(env));
-target_siginfo_t info;
-abi_ulong ret;
-int trapnr;
-
-while (1) {
-cpu_exec_start(cs);
-trapnr = cpu_exec(cs);
-cpu_exec_end(cs);
-process_queued_cpu_work(cs);
-
-env->sregs[PS] &= ~PS_EXCM;
-switch (trapnr) {
-case EXCP_INTERRUPT:
-break;
-
-case EXC_WINDOW_OVERFLOW4:
-xtensa_overflow4(env);
-break;
-case EXC_WINDOW_UNDERFLOW4:
-xtensa_underflow4(env);
-break;
-case EXC_WINDOW_OVERFLOW8:
-xtensa_overflow8(env);
-break;
-case EXC_WINDOW_UNDERFLOW8:
-xtensa_underflow8(env);
-break;
-  

[Qemu-devel] [PATCH for 2.13 14/19] linux-user: move alpha cpu loop to alpha directory

2018-03-26 Thread Laurent Vivier
No code change, only move code from main.c to
alpha/cpu_loop.c.

Signed-off-by: Laurent Vivier 
---
 linux-user/alpha/cpu_loop.c | 199 ++
 linux-user/main.c   | 204 
 2 files changed, 199 insertions(+), 204 deletions(-)

diff --git a/linux-user/alpha/cpu_loop.c b/linux-user/alpha/cpu_loop.c
index b7700a5561..b87fcaea87 100644
--- a/linux-user/alpha/cpu_loop.c
+++ b/linux-user/alpha/cpu_loop.c
@@ -21,6 +21,205 @@
 #include "qemu.h"
 #include "cpu_loop-common.h"
 
+void cpu_loop(CPUAlphaState *env)
+{
+CPUState *cs = CPU(alpha_env_get_cpu(env));
+int trapnr;
+target_siginfo_t info;
+abi_long sysret;
+
+while (1) {
+bool arch_interrupt = true;
+
+cpu_exec_start(cs);
+trapnr = cpu_exec(cs);
+cpu_exec_end(cs);
+process_queued_cpu_work(cs);
+
+switch (trapnr) {
+case EXCP_RESET:
+fprintf(stderr, "Reset requested. Exit\n");
+exit(EXIT_FAILURE);
+break;
+case EXCP_MCHK:
+fprintf(stderr, "Machine check exception. Exit\n");
+exit(EXIT_FAILURE);
+break;
+case EXCP_SMP_INTERRUPT:
+case EXCP_CLK_INTERRUPT:
+case EXCP_DEV_INTERRUPT:
+fprintf(stderr, "External interrupt. Exit\n");
+exit(EXIT_FAILURE);
+break;
+case EXCP_MMFAULT:
+info.si_signo = TARGET_SIGSEGV;
+info.si_errno = 0;
+info.si_code = (page_get_flags(env->trap_arg0) & PAGE_VALID
+? TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR);
+info._sifields._sigfault._addr = env->trap_arg0;
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
+break;
+case EXCP_UNALIGN:
+info.si_signo = TARGET_SIGBUS;
+info.si_errno = 0;
+info.si_code = TARGET_BUS_ADRALN;
+info._sifields._sigfault._addr = env->trap_arg0;
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
+break;
+case EXCP_OPCDEC:
+do_sigill:
+info.si_signo = TARGET_SIGILL;
+info.si_errno = 0;
+info.si_code = TARGET_ILL_ILLOPC;
+info._sifields._sigfault._addr = env->pc;
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
+break;
+case EXCP_ARITH:
+info.si_signo = TARGET_SIGFPE;
+info.si_errno = 0;
+info.si_code = TARGET_FPE_FLTINV;
+info._sifields._sigfault._addr = env->pc;
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
+break;
+case EXCP_FEN:
+/* No-op.  Linux simply re-enables the FPU.  */
+break;
+case EXCP_CALL_PAL:
+switch (env->error_code) {
+case 0x80:
+/* BPT */
+info.si_signo = TARGET_SIGTRAP;
+info.si_errno = 0;
+info.si_code = TARGET_TRAP_BRKPT;
+info._sifields._sigfault._addr = env->pc;
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
+break;
+case 0x81:
+/* BUGCHK */
+info.si_signo = TARGET_SIGTRAP;
+info.si_errno = 0;
+info.si_code = 0;
+info._sifields._sigfault._addr = env->pc;
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
+break;
+case 0x83:
+/* CALLSYS */
+trapnr = env->ir[IR_V0];
+sysret = do_syscall(env, trapnr,
+env->ir[IR_A0], env->ir[IR_A1],
+env->ir[IR_A2], env->ir[IR_A3],
+env->ir[IR_A4], env->ir[IR_A5],
+0, 0);
+if (sysret == -TARGET_ERESTARTSYS) {
+env->pc -= 4;
+break;
+}
+if (sysret == -TARGET_QEMU_ESIGRETURN) {
+break;
+}
+/* Syscall writes 0 to V0 to bypass error check, similar
+   to how this is handled internal to Linux kernel.
+   (Ab)use trapnr temporarily as boolean indicating error.  */
+trapnr = (env->ir[IR_V0] != 0 && sysret < 0);
+env->ir[IR_V0] = (trapnr ? -sysret : sysret);
+env->ir[IR_A3] = trapnr;
+break;
+case 0x86:
+/* IMB */
+/* ??? We can probably elide the code using page_unprotect
+   that is checking for self-modifying code.  Instead we
+   could simply call tb_flush here.  Until we work out the
+   changes required to turn off the extra write protection,
+   

[Qemu-devel] [PATCH for 2.13 02/19] linux-user: move i386/x86_64 cpu loop to i386 directory

2018-03-26 Thread Laurent Vivier
No code change, only move code from main.c to
i386/cpu_loop.c.

Include i386/cpu_loop.c in x86_64/cpu_loop.c
to avoid to duplicate code.

Signed-off-by: Laurent Vivier 
---
 linux-user/i386/cpu_loop.c   | 343 ++
 linux-user/main.c| 348 +--
 linux-user/x86_64/cpu_loop.c |   8 +-
 3 files changed, 345 insertions(+), 354 deletions(-)

diff --git a/linux-user/i386/cpu_loop.c b/linux-user/i386/cpu_loop.c
index b7700a5561..2374abfd0b 100644
--- a/linux-user/i386/cpu_loop.c
+++ b/linux-user/i386/cpu_loop.c
@@ -21,6 +21,349 @@
 #include "qemu.h"
 #include "cpu_loop-common.h"
 
+/***/
+/* CPUX86 core interface */
+
+uint64_t cpu_get_tsc(CPUX86State *env)
+{
+return cpu_get_host_ticks();
+}
+
+static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
+  int flags)
+{
+unsigned int e1, e2;
+uint32_t *p;
+e1 = (addr << 16) | (limit & 0x);
+e2 = ((addr >> 16) & 0xff) | (addr & 0xff00) | (limit & 0x000f);
+e2 |= flags;
+p = ptr;
+p[0] = tswap32(e1);
+p[1] = tswap32(e2);
+}
+
+static uint64_t *idt_table;
+#ifdef TARGET_X86_64
+static void set_gate64(void *ptr, unsigned int type, unsigned int dpl,
+   uint64_t addr, unsigned int sel)
+{
+uint32_t *p, e1, e2;
+e1 = (addr & 0x) | (sel << 16);
+e2 = (addr & 0x) | 0x8000 | (dpl << 13) | (type << 8);
+p = ptr;
+p[0] = tswap32(e1);
+p[1] = tswap32(e2);
+p[2] = tswap32(addr >> 32);
+p[3] = 0;
+}
+/* only dpl matters as we do only user space emulation */
+static void set_idt(int n, unsigned int dpl)
+{
+set_gate64(idt_table + n * 2, 0, dpl, 0, 0);
+}
+#else
+static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
+ uint32_t addr, unsigned int sel)
+{
+uint32_t *p, e1, e2;
+e1 = (addr & 0x) | (sel << 16);
+e2 = (addr & 0x) | 0x8000 | (dpl << 13) | (type << 8);
+p = ptr;
+p[0] = tswap32(e1);
+p[1] = tswap32(e2);
+}
+
+/* only dpl matters as we do only user space emulation */
+static void set_idt(int n, unsigned int dpl)
+{
+set_gate(idt_table + n, 0, dpl, 0, 0);
+}
+#endif
+
+void cpu_loop(CPUX86State *env)
+{
+CPUState *cs = CPU(x86_env_get_cpu(env));
+int trapnr;
+abi_ulong pc;
+abi_ulong ret;
+target_siginfo_t info;
+
+for(;;) {
+cpu_exec_start(cs);
+trapnr = cpu_exec(cs);
+cpu_exec_end(cs);
+process_queued_cpu_work(cs);
+
+switch(trapnr) {
+case 0x80:
+/* linux syscall from int $0x80 */
+ret = do_syscall(env,
+ env->regs[R_EAX],
+ env->regs[R_EBX],
+ env->regs[R_ECX],
+ env->regs[R_EDX],
+ env->regs[R_ESI],
+ env->regs[R_EDI],
+ env->regs[R_EBP],
+ 0, 0);
+if (ret == -TARGET_ERESTARTSYS) {
+env->eip -= 2;
+} else if (ret != -TARGET_QEMU_ESIGRETURN) {
+env->regs[R_EAX] = ret;
+}
+break;
+#ifndef TARGET_ABI32
+case EXCP_SYSCALL:
+/* linux syscall from syscall instruction */
+ret = do_syscall(env,
+ env->regs[R_EAX],
+ env->regs[R_EDI],
+ env->regs[R_ESI],
+ env->regs[R_EDX],
+ env->regs[10],
+ env->regs[8],
+ env->regs[9],
+ 0, 0);
+if (ret == -TARGET_ERESTARTSYS) {
+env->eip -= 2;
+} else if (ret != -TARGET_QEMU_ESIGRETURN) {
+env->regs[R_EAX] = ret;
+}
+break;
+#endif
+case EXCP0B_NOSEG:
+case EXCP0C_STACK:
+info.si_signo = TARGET_SIGBUS;
+info.si_errno = 0;
+info.si_code = TARGET_SI_KERNEL;
+info._sifields._sigfault._addr = 0;
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
+break;
+case EXCP0D_GPF:
+/* XXX: potential problem if ABI32 */
+#ifndef TARGET_X86_64
+if (env->eflags & VM_MASK) {
+handle_vm86_fault(env);
+} else
+#endif
+{
+info.si_signo = TARGET_SIGSEGV;
+info.si_errno = 0;
+info.si_code = TARGET_SI_KERNEL;
+info._sifields._sigfault._addr = 0;
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
+}
+break;
+case EXCP0E_PAGE:
+info.si_signo = TARGET_SIGSEGV;
+info.si_errno = 

[Qemu-devel] [PATCH for 2.13 13/19] linux-user: move m68k cpu loop to m68k directory

2018-03-26 Thread Laurent Vivier
No code change, only move code from main.c to
m68k/cpu_loop.c.

Signed-off-by: Laurent Vivier 
---
 linux-user/m68k/cpu_loop.c | 144 +++
 linux-user/main.c  | 150 +
 2 files changed, 145 insertions(+), 149 deletions(-)

diff --git a/linux-user/m68k/cpu_loop.c b/linux-user/m68k/cpu_loop.c
index b7700a5561..b4d3d8af3d 100644
--- a/linux-user/m68k/cpu_loop.c
+++ b/linux-user/m68k/cpu_loop.c
@@ -21,6 +21,150 @@
 #include "qemu.h"
 #include "cpu_loop-common.h"
 
+void cpu_loop(CPUM68KState *env)
+{
+CPUState *cs = CPU(m68k_env_get_cpu(env));
+int trapnr;
+unsigned int n;
+target_siginfo_t info;
+TaskState *ts = cs->opaque;
+
+for(;;) {
+cpu_exec_start(cs);
+trapnr = cpu_exec(cs);
+cpu_exec_end(cs);
+process_queued_cpu_work(cs);
+
+switch(trapnr) {
+case EXCP_ILLEGAL:
+{
+if (ts->sim_syscalls) {
+uint16_t nr;
+get_user_u16(nr, env->pc + 2);
+env->pc += 4;
+do_m68k_simcall(env, nr);
+} else {
+goto do_sigill;
+}
+}
+break;
+case EXCP_HALT_INSN:
+/* Semihosing syscall.  */
+env->pc += 4;
+do_m68k_semihosting(env, env->dregs[0]);
+break;
+case EXCP_LINEA:
+case EXCP_LINEF:
+case EXCP_UNSUPPORTED:
+do_sigill:
+info.si_signo = TARGET_SIGILL;
+info.si_errno = 0;
+info.si_code = TARGET_ILL_ILLOPN;
+info._sifields._sigfault._addr = env->pc;
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
+break;
+case EXCP_CHK:
+info.si_signo = TARGET_SIGFPE;
+info.si_errno = 0;
+info.si_code = TARGET_FPE_INTOVF;
+info._sifields._sigfault._addr = env->pc;
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
+break;
+case EXCP_DIV0:
+info.si_signo = TARGET_SIGFPE;
+info.si_errno = 0;
+info.si_code = TARGET_FPE_INTDIV;
+info._sifields._sigfault._addr = env->pc;
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
+break;
+case EXCP_TRAP0:
+{
+abi_long ret;
+ts->sim_syscalls = 0;
+n = env->dregs[0];
+env->pc += 2;
+ret = do_syscall(env,
+ n,
+ env->dregs[1],
+ env->dregs[2],
+ env->dregs[3],
+ env->dregs[4],
+ env->dregs[5],
+ env->aregs[0],
+ 0, 0);
+if (ret == -TARGET_ERESTARTSYS) {
+env->pc -= 2;
+} else if (ret != -TARGET_QEMU_ESIGRETURN) {
+env->dregs[0] = ret;
+}
+}
+break;
+case EXCP_INTERRUPT:
+/* just indicate that signals should be handled asap */
+break;
+case EXCP_ACCESS:
+{
+info.si_signo = TARGET_SIGSEGV;
+info.si_errno = 0;
+/* XXX: check env->error_code */
+info.si_code = TARGET_SEGV_MAPERR;
+info._sifields._sigfault._addr = env->mmu.ar;
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
+}
+break;
+case EXCP_DEBUG:
+{
+int sig;
+
+sig = gdb_handlesig(cs, TARGET_SIGTRAP);
+if (sig)
+  {
+info.si_signo = sig;
+info.si_errno = 0;
+info.si_code = TARGET_TRAP_BRKPT;
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
+  }
+}
+break;
+case EXCP_ATOMIC:
+cpu_exec_step_atomic(cs);
+break;
+default:
+EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", 
trapnr);
+abort();
+}
+process_pending_signals(env);
+}
+}
+
 void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
 {
+CPUState *cpu = ENV_GET_CPU(env);
+TaskState *ts = cpu->opaque;
+struct image_info *info = ts->info;
+
+env->pc = regs->pc;
+env->dregs[0] = regs->d0;
+env->dregs[1] = regs->d1;
+env->dregs[2] = regs->d2;
+env->dregs[3] = regs->d3;
+env->dregs[4] = regs->d4;
+env->dregs[5] = regs->d5;
+env->dregs[6] = regs->d6;
+env->dregs[7] = regs->d7;
+env->aregs[0] = regs->a0;
+env->aregs[1] = regs->a1;

[Qemu-devel] [PATCH for 2.13 15/19] linux-user: move s390x cpu loop to s390x directory

2018-03-26 Thread Laurent Vivier
No code change, only move code from main.c to
s390x/cpu_loop.c.

Signed-off-by: Laurent Vivier 
---
 linux-user/main.c   | 146 
 linux-user/s390x/cpu_loop.c | 139 +
 2 files changed, 139 insertions(+), 146 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index a3c68dad36..9693383009 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -149,143 +149,6 @@ void fork_end(int child)
 }
 }
 
-#ifdef TARGET_S390X
-
-/* s390x masks the fault address it reports in si_addr for SIGSEGV and SIGBUS 
*/
-#define S390X_FAIL_ADDR_MASK -4096LL
-
-void cpu_loop(CPUS390XState *env)
-{
-CPUState *cs = CPU(s390_env_get_cpu(env));
-int trapnr, n, sig;
-target_siginfo_t info;
-target_ulong addr;
-abi_long ret;
-
-while (1) {
-cpu_exec_start(cs);
-trapnr = cpu_exec(cs);
-cpu_exec_end(cs);
-process_queued_cpu_work(cs);
-
-switch (trapnr) {
-case EXCP_INTERRUPT:
-/* Just indicate that signals should be handled asap.  */
-break;
-
-case EXCP_SVC:
-n = env->int_svc_code;
-if (!n) {
-/* syscalls > 255 */
-n = env->regs[1];
-}
-env->psw.addr += env->int_svc_ilen;
-ret = do_syscall(env, n, env->regs[2], env->regs[3],
- env->regs[4], env->regs[5],
- env->regs[6], env->regs[7], 0, 0);
-if (ret == -TARGET_ERESTARTSYS) {
-env->psw.addr -= env->int_svc_ilen;
-} else if (ret != -TARGET_QEMU_ESIGRETURN) {
-env->regs[2] = ret;
-}
-break;
-
-case EXCP_DEBUG:
-sig = gdb_handlesig(cs, TARGET_SIGTRAP);
-if (sig) {
-n = TARGET_TRAP_BRKPT;
-goto do_signal_pc;
-}
-break;
-case EXCP_PGM:
-n = env->int_pgm_code;
-switch (n) {
-case PGM_OPERATION:
-case PGM_PRIVILEGED:
-sig = TARGET_SIGILL;
-n = TARGET_ILL_ILLOPC;
-goto do_signal_pc;
-case PGM_PROTECTION:
-case PGM_ADDRESSING:
-sig = TARGET_SIGSEGV;
-/* XXX: check env->error_code */
-n = TARGET_SEGV_MAPERR;
-addr = env->__excp_addr & S390X_FAIL_ADDR_MASK;
-goto do_signal;
-case PGM_EXECUTE:
-case PGM_SPECIFICATION:
-case PGM_SPECIAL_OP:
-case PGM_OPERAND:
-do_sigill_opn:
-sig = TARGET_SIGILL;
-n = TARGET_ILL_ILLOPN;
-goto do_signal_pc;
-
-case PGM_FIXPT_OVERFLOW:
-sig = TARGET_SIGFPE;
-n = TARGET_FPE_INTOVF;
-goto do_signal_pc;
-case PGM_FIXPT_DIVIDE:
-sig = TARGET_SIGFPE;
-n = TARGET_FPE_INTDIV;
-goto do_signal_pc;
-
-case PGM_DATA:
-n = (env->fpc >> 8) & 0xff;
-if (n == 0xff) {
-/* compare-and-trap */
-goto do_sigill_opn;
-} else {
-/* An IEEE exception, simulated or otherwise.  */
-if (n & 0x80) {
-n = TARGET_FPE_FLTINV;
-} else if (n & 0x40) {
-n = TARGET_FPE_FLTDIV;
-} else if (n & 0x20) {
-n = TARGET_FPE_FLTOVF;
-} else if (n & 0x10) {
-n = TARGET_FPE_FLTUND;
-} else if (n & 0x08) {
-n = TARGET_FPE_FLTRES;
-} else {
-/* ??? Quantum exception; BFP, DFP error.  */
-goto do_sigill_opn;
-}
-sig = TARGET_SIGFPE;
-goto do_signal_pc;
-}
-
-default:
-fprintf(stderr, "Unhandled program exception: %#x\n", n);
-cpu_dump_state(cs, stderr, fprintf, 0);
-exit(EXIT_FAILURE);
-}
-break;
-
-do_signal_pc:
-addr = env->psw.addr;
-do_signal:
-info.si_signo = sig;
-info.si_errno = 0;
-info.si_code = n;
-info._sifields._sigfault._addr = addr;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-break;
-
-case EXCP_ATOMIC:
-cpu_exec_step_atomic(cs);
-break;
-default:
-fprintf(stderr, "Unhandled trap: 0x%x\n", trapnr);
-cpu_dump_state(cs, stderr, fprintf, 0);
-exit(EXIT_FAILURE);
-}
-

[Qemu-devel] [PATCH for 2.13 17/19] linux-user: move riscv cpu loop to riscv directory

2018-03-26 Thread Laurent Vivier
No code change, only move code from main.c to
riscv/cpu_loop.c.

Signed-off-by: Laurent Vivier 
---
 linux-user/main.c   | 101 +---
 linux-user/riscv/cpu_loop.c |  92 
 2 files changed, 93 insertions(+), 100 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 3b3613cb89..78ff99bd00 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -149,100 +149,6 @@ void fork_end(int child)
 }
 }
 
-#ifdef TARGET_RISCV
-
-void cpu_loop(CPURISCVState *env)
-{
-CPUState *cs = CPU(riscv_env_get_cpu(env));
-int trapnr, signum, sigcode;
-target_ulong sigaddr;
-target_ulong ret;
-
-for (;;) {
-cpu_exec_start(cs);
-trapnr = cpu_exec(cs);
-cpu_exec_end(cs);
-process_queued_cpu_work(cs);
-
-signum = 0;
-sigcode = 0;
-sigaddr = 0;
-
-switch (trapnr) {
-case EXCP_INTERRUPT:
-/* just indicate that signals should be handled asap */
-break;
-case EXCP_ATOMIC:
-cpu_exec_step_atomic(cs);
-break;
-case RISCV_EXCP_U_ECALL:
-env->pc += 4;
-if (env->gpr[xA7] == TARGET_NR_arch_specific_syscall + 15) {
-/* riscv_flush_icache_syscall is a no-op in QEMU as
-   self-modifying code is automatically detected */
-ret = 0;
-} else {
-ret = do_syscall(env,
- env->gpr[xA7],
- env->gpr[xA0],
- env->gpr[xA1],
- env->gpr[xA2],
- env->gpr[xA3],
- env->gpr[xA4],
- env->gpr[xA5],
- 0, 0);
-}
-if (ret == -TARGET_ERESTARTSYS) {
-env->pc -= 4;
-} else if (ret != -TARGET_QEMU_ESIGRETURN) {
-env->gpr[xA0] = ret;
-}
-if (cs->singlestep_enabled) {
-goto gdbstep;
-}
-break;
-case RISCV_EXCP_ILLEGAL_INST:
-signum = TARGET_SIGILL;
-sigcode = TARGET_ILL_ILLOPC;
-break;
-case RISCV_EXCP_BREAKPOINT:
-signum = TARGET_SIGTRAP;
-sigcode = TARGET_TRAP_BRKPT;
-sigaddr = env->pc;
-break;
-case RISCV_EXCP_INST_PAGE_FAULT:
-case RISCV_EXCP_LOAD_PAGE_FAULT:
-case RISCV_EXCP_STORE_PAGE_FAULT:
-signum = TARGET_SIGSEGV;
-sigcode = TARGET_SEGV_MAPERR;
-break;
-case EXCP_DEBUG:
-gdbstep:
-signum = gdb_handlesig(cs, TARGET_SIGTRAP);
-sigcode = TARGET_TRAP_BRKPT;
-break;
-default:
-EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n",
- trapnr);
-exit(EXIT_FAILURE);
-}
-
-if (signum) {
-target_siginfo_t info = {
-.si_signo = signum,
-.si_errno = 0,
-.si_code = sigcode,
-._sifields._sigfault._addr = sigaddr
-};
-queue_signal(env, info.si_signo, QEMU_SI_KILL, );
-}
-
-process_pending_signals(env);
-}
-}
-
-#endif /* TARGET_RISCV */
-
 #ifdef TARGET_HPPA
 
 static abi_ulong hppa_lws(CPUHPPAState *env)
@@ -1319,12 +1225,7 @@ int main(int argc, char **argv, char **envp)
 
 target_cpu_copy_regs(env, regs);
 
-#if defined(TARGET_RISCV)
-{
-env->pc = regs->sepc;
-env->gpr[xSP] = regs->sp;
-}
-#elif defined(TARGET_HPPA)
+#if defined(TARGET_HPPA)
 {
 int i;
 for (i = 1; i < 32; i++) {
diff --git a/linux-user/riscv/cpu_loop.c b/linux-user/riscv/cpu_loop.c
index b7700a5561..f137d39d7e 100644
--- a/linux-user/riscv/cpu_loop.c
+++ b/linux-user/riscv/cpu_loop.c
@@ -21,6 +21,98 @@
 #include "qemu.h"
 #include "cpu_loop-common.h"
 
+void cpu_loop(CPURISCVState *env)
+{
+CPUState *cs = CPU(riscv_env_get_cpu(env));
+int trapnr, signum, sigcode;
+target_ulong sigaddr;
+target_ulong ret;
+
+for (;;) {
+cpu_exec_start(cs);
+trapnr = cpu_exec(cs);
+cpu_exec_end(cs);
+process_queued_cpu_work(cs);
+
+signum = 0;
+sigcode = 0;
+sigaddr = 0;
+
+switch (trapnr) {
+case EXCP_INTERRUPT:
+/* just indicate that signals should be handled asap */
+break;
+case EXCP_ATOMIC:
+cpu_exec_step_atomic(cs);
+break;
+case RISCV_EXCP_U_ECALL:
+env->pc += 4;
+if (env->gpr[xA7] == TARGET_NR_arch_specific_syscall + 15) {
+/* riscv_flush_icache_syscall is a no-op in QEMU as
+   self-modifying code is 

[Qemu-devel] [PATCH for 2.13 01/19] linux-user: create a dummy per arch cpu_loop.c

2018-03-26 Thread Laurent Vivier
Create a cpu_loop-common.h for future use by
these new files and use it in the existing
main.c

Introduce target_cpu_copy_regs():
declare the function in cpu_loop-common.h
and an empty function for each target,
to move all the cpu_loop prologues to this function.

Signed-off-by: Laurent Vivier 
---
 linux-user/Makefile.objs |  3 ++-
 linux-user/aarch64/cpu_loop.c| 26 ++
 linux-user/alpha/cpu_loop.c  | 26 ++
 linux-user/arm/cpu_loop.c| 26 ++
 linux-user/cpu_loop-common.h | 37 +
 linux-user/cris/cpu_loop.c   | 26 ++
 linux-user/hppa/cpu_loop.c   | 26 ++
 linux-user/i386/cpu_loop.c   | 26 ++
 linux-user/m68k/cpu_loop.c   | 26 ++
 linux-user/main.c| 17 +++--
 linux-user/microblaze/cpu_loop.c | 26 ++
 linux-user/mips/cpu_loop.c   | 26 ++
 linux-user/mips64/cpu_loop.c | 26 ++
 linux-user/nios2/cpu_loop.c  | 26 ++
 linux-user/openrisc/cpu_loop.c   | 26 ++
 linux-user/ppc/cpu_loop.c| 26 ++
 linux-user/riscv/cpu_loop.c  | 26 ++
 linux-user/s390x/cpu_loop.c  | 26 ++
 linux-user/sh4/cpu_loop.c| 26 ++
 linux-user/sparc/cpu_loop.c  | 26 ++
 linux-user/sparc64/cpu_loop.c| 26 ++
 linux-user/tilegx/cpu_loop.c | 26 ++
 linux-user/x86_64/cpu_loop.c | 26 ++
 linux-user/xtensa/cpu_loop.c | 26 ++
 24 files changed, 588 insertions(+), 15 deletions(-)
 create mode 100644 linux-user/aarch64/cpu_loop.c
 create mode 100644 linux-user/alpha/cpu_loop.c
 create mode 100644 linux-user/arm/cpu_loop.c
 create mode 100644 linux-user/cpu_loop-common.h
 create mode 100644 linux-user/cris/cpu_loop.c
 create mode 100644 linux-user/hppa/cpu_loop.c
 create mode 100644 linux-user/i386/cpu_loop.c
 create mode 100644 linux-user/m68k/cpu_loop.c
 create mode 100644 linux-user/microblaze/cpu_loop.c
 create mode 100644 linux-user/mips/cpu_loop.c
 create mode 100644 linux-user/mips64/cpu_loop.c
 create mode 100644 linux-user/nios2/cpu_loop.c
 create mode 100644 linux-user/openrisc/cpu_loop.c
 create mode 100644 linux-user/ppc/cpu_loop.c
 create mode 100644 linux-user/riscv/cpu_loop.c
 create mode 100644 linux-user/s390x/cpu_loop.c
 create mode 100644 linux-user/sh4/cpu_loop.c
 create mode 100644 linux-user/sparc/cpu_loop.c
 create mode 100644 linux-user/sparc64/cpu_loop.c
 create mode 100644 linux-user/tilegx/cpu_loop.c
 create mode 100644 linux-user/x86_64/cpu_loop.c
 create mode 100644 linux-user/xtensa/cpu_loop.c

diff --git a/linux-user/Makefile.objs b/linux-user/Makefile.objs
index 811a7f5ce5..59a5c17354 100644
--- a/linux-user/Makefile.objs
+++ b/linux-user/Makefile.objs
@@ -1,6 +1,7 @@
 obj-y = main.o syscall.o strace.o mmap.o signal.o \
elfload.o linuxload.o uaccess.o uname.o \
-   safe-syscall.o $(TARGET_ABI_DIR)/signal.o
+   safe-syscall.o $(TARGET_ABI_DIR)/signal.o \
+$(TARGET_ABI_DIR)/cpu_loop.o
 
 obj-$(TARGET_HAS_BFLT) += flatload.o
 obj-$(TARGET_I386) += vm86.o
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
new file mode 100644
index 00..b7700a5561
--- /dev/null
+++ b/linux-user/aarch64/cpu_loop.c
@@ -0,0 +1,26 @@
+/*
+ *  qemu user cpu loop
+ *
+ *  Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "cpu_loop-common.h"
+
+void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
+{
+}
diff --git a/linux-user/alpha/cpu_loop.c b/linux-user/alpha/cpu_loop.c
new file mode 100644
index 00..b7700a5561
--- /dev/null
+++ b/linux-user/alpha/cpu_loop.c
@@ -0,0 +1,26 @@
+/*
+ *  qemu user cpu loop
+ *
+ *  Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as 

[Qemu-devel] [PATCH for 2.13 10/19] linux-user: move sh4 cpu loop to sh4 directory

2018-03-26 Thread Laurent Vivier
No code change, only move code from main.c to
sh4/cpu_loop.c.

Signed-off-by: Laurent Vivier 
---
 linux-user/main.c | 90 ---
 linux-user/sh4/cpu_loop.c | 85 
 2 files changed, 85 insertions(+), 90 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 8530dbfdf1..211148858e 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -149,87 +149,6 @@ void fork_end(int child)
 }
 }
 
-#ifdef TARGET_SH4
-void cpu_loop(CPUSH4State *env)
-{
-CPUState *cs = CPU(sh_env_get_cpu(env));
-int trapnr, ret;
-target_siginfo_t info;
-
-while (1) {
-bool arch_interrupt = true;
-
-cpu_exec_start(cs);
-trapnr = cpu_exec(cs);
-cpu_exec_end(cs);
-process_queued_cpu_work(cs);
-
-switch (trapnr) {
-case 0x160:
-env->pc += 2;
-ret = do_syscall(env,
- env->gregs[3],
- env->gregs[4],
- env->gregs[5],
- env->gregs[6],
- env->gregs[7],
- env->gregs[0],
- env->gregs[1],
- 0, 0);
-if (ret == -TARGET_ERESTARTSYS) {
-env->pc -= 2;
-} else if (ret != -TARGET_QEMU_ESIGRETURN) {
-env->gregs[0] = ret;
-}
-break;
-case EXCP_INTERRUPT:
-/* just indicate that signals should be handled asap */
-break;
-case EXCP_DEBUG:
-{
-int sig;
-
-sig = gdb_handlesig(cs, TARGET_SIGTRAP);
-if (sig) {
-info.si_signo = sig;
-info.si_errno = 0;
-info.si_code = TARGET_TRAP_BRKPT;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-} else {
-arch_interrupt = false;
-}
-}
-break;
-   case 0xa0:
-   case 0xc0:
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-info.si_code = TARGET_SEGV_MAPERR;
-info._sifields._sigfault._addr = env->tea;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-   break;
-case EXCP_ATOMIC:
-cpu_exec_step_atomic(cs);
-arch_interrupt = false;
-break;
-default:
-printf ("Unhandled trap: 0x%x\n", trapnr);
-cpu_dump_state(cs, stderr, fprintf, 0);
-exit(EXIT_FAILURE);
-}
-process_pending_signals (env);
-
-/* Most of the traps imply an exception or interrupt, which
-   implies an REI instruction has been executed.  Which means
-   that LDST (aka LOK_ADDR) should be cleared.  But there are
-   a few exceptions for traps internal to QEMU.  */
-if (arch_interrupt) {
-env->lock_addr = -1;
-}
-}
-}
-#endif
-
 #ifdef TARGET_CRIS
 void cpu_loop(CPUCRISState *env)
 {
@@ -2358,15 +2277,6 @@ int main(int argc, char **argv, char **envp)
 env->pc = regs->sepc;
 env->gpr[xSP] = regs->sp;
 }
-#elif defined(TARGET_SH4)
-{
-int i;
-
-for(i = 0; i < 16; i++) {
-env->gregs[i] = regs->regs[i];
-}
-env->pc = regs->pc;
-}
 #elif defined(TARGET_ALPHA)
 {
 int i;
diff --git a/linux-user/sh4/cpu_loop.c b/linux-user/sh4/cpu_loop.c
index b7700a5561..3f0b9320e7 100644
--- a/linux-user/sh4/cpu_loop.c
+++ b/linux-user/sh4/cpu_loop.c
@@ -21,6 +21,91 @@
 #include "qemu.h"
 #include "cpu_loop-common.h"
 
+void cpu_loop(CPUSH4State *env)
+{
+CPUState *cs = CPU(sh_env_get_cpu(env));
+int trapnr, ret;
+target_siginfo_t info;
+
+while (1) {
+bool arch_interrupt = true;
+
+cpu_exec_start(cs);
+trapnr = cpu_exec(cs);
+cpu_exec_end(cs);
+process_queued_cpu_work(cs);
+
+switch (trapnr) {
+case 0x160:
+env->pc += 2;
+ret = do_syscall(env,
+ env->gregs[3],
+ env->gregs[4],
+ env->gregs[5],
+ env->gregs[6],
+ env->gregs[7],
+ env->gregs[0],
+ env->gregs[1],
+ 0, 0);
+if (ret == -TARGET_ERESTARTSYS) {
+env->pc -= 2;
+} else if (ret != -TARGET_QEMU_ESIGRETURN) {
+env->gregs[0] = ret;
+}
+break;
+case EXCP_INTERRUPT:
+/* just indicate that signals should be handled asap */
+break;
+case EXCP_DEBUG:
+{
+int sig;
+
+  

[Qemu-devel] [PATCH for 2.13 11/19] linux-user: move cris cpu loop to cris directory

2018-03-26 Thread Laurent Vivier
No code change, only move code from main.c to
cris/cpu_loop.c.

Signed-off-by: Laurent Vivier 
---
 linux-user/cris/cpu_loop.c | 89 +
 linux-user/main.c  | 90 --
 2 files changed, 89 insertions(+), 90 deletions(-)

diff --git a/linux-user/cris/cpu_loop.c b/linux-user/cris/cpu_loop.c
index b7700a5561..96406e5c97 100644
--- a/linux-user/cris/cpu_loop.c
+++ b/linux-user/cris/cpu_loop.c
@@ -21,6 +21,95 @@
 #include "qemu.h"
 #include "cpu_loop-common.h"
 
+void cpu_loop(CPUCRISState *env)
+{
+CPUState *cs = CPU(cris_env_get_cpu(env));
+int trapnr, ret;
+target_siginfo_t info;
+
+while (1) {
+cpu_exec_start(cs);
+trapnr = cpu_exec(cs);
+cpu_exec_end(cs);
+process_queued_cpu_work(cs);
+
+switch (trapnr) {
+case 0xaa:
+{
+info.si_signo = TARGET_SIGSEGV;
+info.si_errno = 0;
+/* XXX: check env->error_code */
+info.si_code = TARGET_SEGV_MAPERR;
+info._sifields._sigfault._addr = env->pregs[PR_EDA];
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
+}
+break;
+   case EXCP_INTERRUPT:
+ /* just indicate that signals should be handled asap */
+ break;
+case EXCP_BREAK:
+ret = do_syscall(env, 
+ env->regs[9], 
+ env->regs[10], 
+ env->regs[11], 
+ env->regs[12], 
+ env->regs[13], 
+ env->pregs[7], 
+ env->pregs[11],
+ 0, 0);
+if (ret == -TARGET_ERESTARTSYS) {
+env->pc -= 2;
+} else if (ret != -TARGET_QEMU_ESIGRETURN) {
+env->regs[10] = ret;
+}
+break;
+case EXCP_DEBUG:
+{
+int sig;
+
+sig = gdb_handlesig(cs, TARGET_SIGTRAP);
+if (sig)
+  {
+info.si_signo = sig;
+info.si_errno = 0;
+info.si_code = TARGET_TRAP_BRKPT;
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
+  }
+}
+break;
+case EXCP_ATOMIC:
+cpu_exec_step_atomic(cs);
+break;
+default:
+printf ("Unhandled trap: 0x%x\n", trapnr);
+cpu_dump_state(cs, stderr, fprintf, 0);
+exit(EXIT_FAILURE);
+}
+process_pending_signals (env);
+}
+}
+
 void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
 {
+CPUState *cpu = ENV_GET_CPU(env);
+TaskState *ts = cpu->opaque;
+struct image_info *info = ts->info;
+
+env->regs[0] = regs->r0;
+env->regs[1] = regs->r1;
+env->regs[2] = regs->r2;
+env->regs[3] = regs->r3;
+env->regs[4] = regs->r4;
+env->regs[5] = regs->r5;
+env->regs[6] = regs->r6;
+env->regs[7] = regs->r7;
+env->regs[8] = regs->r8;
+env->regs[9] = regs->r9;
+env->regs[10] = regs->r10;
+env->regs[11] = regs->r11;
+env->regs[12] = regs->r12;
+env->regs[13] = regs->r13;
+env->regs[14] = info->start_stack;
+env->regs[15] = regs->acr;
+env->pc = regs->erp;
 }
diff --git a/linux-user/main.c b/linux-user/main.c
index 211148858e..560e4a5b6a 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -149,76 +149,6 @@ void fork_end(int child)
 }
 }
 
-#ifdef TARGET_CRIS
-void cpu_loop(CPUCRISState *env)
-{
-CPUState *cs = CPU(cris_env_get_cpu(env));
-int trapnr, ret;
-target_siginfo_t info;
-
-while (1) {
-cpu_exec_start(cs);
-trapnr = cpu_exec(cs);
-cpu_exec_end(cs);
-process_queued_cpu_work(cs);
-
-switch (trapnr) {
-case 0xaa:
-{
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-/* XXX: check env->error_code */
-info.si_code = TARGET_SEGV_MAPERR;
-info._sifields._sigfault._addr = env->pregs[PR_EDA];
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-}
-break;
-   case EXCP_INTERRUPT:
- /* just indicate that signals should be handled asap */
- break;
-case EXCP_BREAK:
-ret = do_syscall(env, 
- env->regs[9], 
- env->regs[10], 
- env->regs[11], 
- env->regs[12], 
- env->regs[13], 
- env->pregs[7], 
- env->pregs[11],
- 0, 0);
-if (ret == -TARGET_ERESTARTSYS) {
-   

[Qemu-devel] [PATCH for 2.13 05/19] linux-user: move sparc/sparc64 cpu loop to sparc directory

2018-03-26 Thread Laurent Vivier
No code change, only move code from main.c to
sparc/cpu_loop.c.

Include sparc/cpu_loop.c in sparc64/cpu_loop.c
to avoid to duplicate code.

Signed-off-by: Laurent Vivier 
---
 linux-user/main.c | 288 +-
 linux-user/sparc/cpu_loop.c   | 280 
 linux-user/sparc64/cpu_loop.c |   8 +-
 3 files changed, 282 insertions(+), 294 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index f8ea0c8b96..349dcd6a20 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -149,281 +149,6 @@ void fork_end(int child)
 }
 }
 
-#ifdef TARGET_SPARC
-#define SPARC64_STACK_BIAS 2047
-
-//#define DEBUG_WIN
-
-/* WARNING: dealing with register windows _is_ complicated. More info
-   can be found at http://www.sics.se/~psm/sparcstack.html */
-static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
-{
-index = (index + cwp * 16) % (16 * env->nwindows);
-/* wrap handling : if cwp is on the last window, then we use the
-   registers 'after' the end */
-if (index < 8 && env->cwp == env->nwindows - 1)
-index += 16 * env->nwindows;
-return index;
-}
-
-/* save the register window 'cwp1' */
-static inline void save_window_offset(CPUSPARCState *env, int cwp1)
-{
-unsigned int i;
-abi_ulong sp_ptr;
-
-sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
-#ifdef TARGET_SPARC64
-if (sp_ptr & 3)
-sp_ptr += SPARC64_STACK_BIAS;
-#endif
-#if defined(DEBUG_WIN)
-printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n",
-   sp_ptr, cwp1);
-#endif
-for(i = 0; i < 16; i++) {
-/* FIXME - what to do if put_user() fails? */
-put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
-sp_ptr += sizeof(abi_ulong);
-}
-}
-
-static void save_window(CPUSPARCState *env)
-{
-#ifndef TARGET_SPARC64
-unsigned int new_wim;
-new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) &
-((1LL << env->nwindows) - 1);
-save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
-env->wim = new_wim;
-#else
-save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
-env->cansave++;
-env->canrestore--;
-#endif
-}
-
-static void restore_window(CPUSPARCState *env)
-{
-#ifndef TARGET_SPARC64
-unsigned int new_wim;
-#endif
-unsigned int i, cwp1;
-abi_ulong sp_ptr;
-
-#ifndef TARGET_SPARC64
-new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
-((1LL << env->nwindows) - 1);
-#endif
-
-/* restore the invalid window */
-cwp1 = cpu_cwp_inc(env, env->cwp + 1);
-sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
-#ifdef TARGET_SPARC64
-if (sp_ptr & 3)
-sp_ptr += SPARC64_STACK_BIAS;
-#endif
-#if defined(DEBUG_WIN)
-printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n",
-   sp_ptr, cwp1);
-#endif
-for(i = 0; i < 16; i++) {
-/* FIXME - what to do if get_user() fails? */
-get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
-sp_ptr += sizeof(abi_ulong);
-}
-#ifdef TARGET_SPARC64
-env->canrestore++;
-if (env->cleanwin < env->nwindows - 1)
-env->cleanwin++;
-env->cansave--;
-#else
-env->wim = new_wim;
-#endif
-}
-
-static void flush_windows(CPUSPARCState *env)
-{
-int offset, cwp1;
-
-offset = 1;
-for(;;) {
-/* if restore would invoke restore_window(), then we can stop */
-cwp1 = cpu_cwp_inc(env, env->cwp + offset);
-#ifndef TARGET_SPARC64
-if (env->wim & (1 << cwp1))
-break;
-#else
-if (env->canrestore == 0)
-break;
-env->cansave++;
-env->canrestore--;
-#endif
-save_window_offset(env, cwp1);
-offset++;
-}
-cwp1 = cpu_cwp_inc(env, env->cwp + 1);
-#ifndef TARGET_SPARC64
-/* set wim so that restore will reload the registers */
-env->wim = 1 << cwp1;
-#endif
-#if defined(DEBUG_WIN)
-printf("flush_windows: nb=%d\n", offset - 1);
-#endif
-}
-
-void cpu_loop (CPUSPARCState *env)
-{
-CPUState *cs = CPU(sparc_env_get_cpu(env));
-int trapnr;
-abi_long ret;
-target_siginfo_t info;
-
-while (1) {
-cpu_exec_start(cs);
-trapnr = cpu_exec(cs);
-cpu_exec_end(cs);
-process_queued_cpu_work(cs);
-
-/* Compute PSR before exposing state.  */
-if (env->cc_op != CC_OP_FLAGS) {
-cpu_get_psr(env);
-}
-
-switch (trapnr) {
-#ifndef TARGET_SPARC64
-case 0x88:
-case 0x90:
-#else
-case 0x110:
-case 0x16d:
-#endif
-ret = do_syscall (env, env->gregs[1],
-  env->regwptr[0], env->regwptr[1],
-  env->regwptr[2], env->regwptr[3],
-  env->regwptr[4], env->regwptr[5],
-  0, 0);
-if (ret == 

[Qemu-devel] [PATCH for 2.13 08/19] linux-user: move nios2 cpu loop to nios2 directory

2018-03-26 Thread Laurent Vivier
No code change, only move code from main.c to
nios2/cpu_loop.c.

Signed-off-by: Laurent Vivier 
---
 linux-user/main.c   | 133 
 linux-user/nios2/cpu_loop.c | 126 +
 2 files changed, 126 insertions(+), 133 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 490733a3fb..6ee474e5c2 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -149,109 +149,6 @@ void fork_end(int child)
 }
 }
 
-#ifdef TARGET_NIOS2
-
-void cpu_loop(CPUNios2State *env)
-{
-CPUState *cs = ENV_GET_CPU(env);
-Nios2CPU *cpu = NIOS2_CPU(cs);
-target_siginfo_t info;
-int trapnr, gdbsig, ret;
-
-for (;;) {
-cpu_exec_start(cs);
-trapnr = cpu_exec(cs);
-cpu_exec_end(cs);
-gdbsig = 0;
-
-switch (trapnr) {
-case EXCP_INTERRUPT:
-/* just indicate that signals should be handled asap */
-break;
-case EXCP_TRAP:
-if (env->regs[R_AT] == 0) {
-abi_long ret;
-qemu_log_mask(CPU_LOG_INT, "\nSyscall\n");
-
-ret = do_syscall(env, env->regs[2],
- env->regs[4], env->regs[5], env->regs[6],
- env->regs[7], env->regs[8], env->regs[9],
- 0, 0);
-
-if (env->regs[2] == 0) {/* FIXME: syscall 0 workaround */
-ret = 0;
-}
-
-env->regs[2] = abs(ret);
-/* Return value is 0..4096 */
-env->regs[7] = (ret > 0xf000ULL);
-env->regs[CR_ESTATUS] = env->regs[CR_STATUS];
-env->regs[CR_STATUS] &= ~0x3;
-env->regs[R_EA] = env->regs[R_PC] + 4;
-env->regs[R_PC] += 4;
-break;
-} else {
-qemu_log_mask(CPU_LOG_INT, "\nTrap\n");
-
-env->regs[CR_ESTATUS] = env->regs[CR_STATUS];
-env->regs[CR_STATUS] &= ~0x3;
-env->regs[R_EA] = env->regs[R_PC] + 4;
-env->regs[R_PC] = cpu->exception_addr;
-
-gdbsig = TARGET_SIGTRAP;
-break;
-}
-case 0xaa:
-switch (env->regs[R_PC]) {
-/*case 0x1000:*/  /* TODO:__kuser_helper_version */
-case 0x1004:  /* __kuser_cmpxchg */
-start_exclusive();
-if (env->regs[4] & 0x3) {
-goto kuser_fail;
-}
-ret = get_user_u32(env->regs[2], env->regs[4]);
-if (ret) {
-end_exclusive();
-goto kuser_fail;
-}
-env->regs[2] -= env->regs[5];
-if (env->regs[2] == 0) {
-put_user_u32(env->regs[6], env->regs[4]);
-}
-end_exclusive();
-env->regs[R_PC] = env->regs[R_RA];
-break;
-/*case 0x1040:*/  /* TODO:__kuser_sigtramp */
-default:
-;
-kuser_fail:
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-/* TODO: check env->error_code */
-info.si_code = TARGET_SEGV_MAPERR;
-info._sifields._sigfault._addr = env->regs[R_PC];
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-}
-break;
-default:
-EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n",
- trapnr);
-gdbsig = TARGET_SIGILL;
-break;
-}
-if (gdbsig) {
-gdb_handlesig(cs, gdbsig);
-if (gdbsig != TARGET_SIGTRAP) {
-exit(EXIT_FAILURE);
-}
-}
-
-process_pending_signals(env);
-}
-}
-
-#endif /* TARGET_NIOS2 */
-
 #ifdef TARGET_OPENRISC
 
 void cpu_loop(CPUOpenRISCState *env)
@@ -2542,36 +2439,6 @@ int main(int argc, char **argv, char **envp)
 env->regs[31] = regs->r31; 
 env->sregs[SR_PC] = regs->pc;
 }
-#elif defined(TARGET_NIOS2)
-{
-env->regs[0] = 0;
-env->regs[1] = regs->r1;
-env->regs[2] = regs->r2;
-env->regs[3] = regs->r3;
-env->regs[4] = regs->r4;
-env->regs[5] = regs->r5;
-env->regs[6] = regs->r6;
-env->regs[7] = regs->r7;
-env->regs[8] = regs->r8;
-env->regs[9] = regs->r9;
-env->regs[10] = regs->r10;
-env->regs[11] = regs->r11;
-env->regs[12] = regs->r12;
-env->regs[13] = regs->r13;
-env->regs[14] = regs->r14;
-env->regs[15] = regs->r15;
-/* TODO: unsigned long  orig_r2; */
-env->regs[R_RA] = regs->ra;
-env->regs[R_FP] = regs->fp;
-env->regs[R_SP] = regs->sp;
-env->regs[R_GP] = 

[Qemu-devel] [PATCH for 2.13 04/19] linux-user: move arm cpu loop to arm directory

2018-03-26 Thread Laurent Vivier
No code change, only move code from main.c to
arm/cpu_loop.c and duplicate some macro
defined for both arm and aarch64.

Signed-off-by: Laurent Vivier 
---
 linux-user/arm/cpu_loop.c | 430 +
 linux-user/main.c | 433 +-
 2 files changed, 432 insertions(+), 431 deletions(-)

diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
index b7700a5561..d911929bf6 100644
--- a/linux-user/arm/cpu_loop.c
+++ b/linux-user/arm/cpu_loop.c
@@ -19,8 +19,438 @@
 
 #include "qemu/osdep.h"
 #include "qemu.h"
+#include "elf.h"
 #include "cpu_loop-common.h"
 
+#define get_user_code_u32(x, gaddr, env)\
+({ abi_long __r = get_user_u32((x), (gaddr));   \
+if (!__r && bswap_code(arm_sctlr_b(env))) { \
+(x) = bswap32(x);   \
+}   \
+__r;\
+})
+
+#define get_user_code_u16(x, gaddr, env)\
+({ abi_long __r = get_user_u16((x), (gaddr));   \
+if (!__r && bswap_code(arm_sctlr_b(env))) { \
+(x) = bswap16(x);   \
+}   \
+__r;\
+})
+
+#define get_user_data_u32(x, gaddr, env)\
+({ abi_long __r = get_user_u32((x), (gaddr));   \
+if (!__r && arm_cpu_bswap_data(env)) {  \
+(x) = bswap32(x);   \
+}   \
+__r;\
+})
+
+#define get_user_data_u16(x, gaddr, env)\
+({ abi_long __r = get_user_u16((x), (gaddr));   \
+if (!__r && arm_cpu_bswap_data(env)) {  \
+(x) = bswap16(x);   \
+}   \
+__r;\
+})
+
+#define put_user_data_u32(x, gaddr, env)\
+({ typeof(x) __x = (x); \
+if (arm_cpu_bswap_data(env)) {  \
+__x = bswap32(__x); \
+}   \
+put_user_u32(__x, (gaddr)); \
+})
+
+#define put_user_data_u16(x, gaddr, env)\
+({ typeof(x) __x = (x); \
+if (arm_cpu_bswap_data(env)) {  \
+__x = bswap16(__x); \
+}   \
+put_user_u16(__x, (gaddr)); \
+})
+
+/* Commpage handling -- there is no commpage for AArch64 */
+
+/*
+ * See the Linux kernel's Documentation/arm/kernel_user_helpers.txt
+ * Input:
+ * r0 = pointer to oldval
+ * r1 = pointer to newval
+ * r2 = pointer to target value
+ *
+ * Output:
+ * r0 = 0 if *ptr was changed, non-0 if no exchange happened
+ * C set if *ptr was changed, clear if no exchange happened
+ *
+ * Note segv's in kernel helpers are a bit tricky, we can set the
+ * data address sensibly but the PC address is just the entry point.
+ */
+static void arm_kernel_cmpxchg64_helper(CPUARMState *env)
+{
+uint64_t oldval, newval, val;
+uint32_t addr, cpsr;
+target_siginfo_t info;
+
+/* Based on the 32 bit code in do_kernel_trap */
+
+/* XXX: This only works between threads, not between processes.
+   It's probably possible to implement this with native host
+   operations. However things like ldrex/strex are much harder so
+   there's not much point trying.  */
+start_exclusive();
+cpsr = cpsr_read(env);
+addr = env->regs[2];
+
+if (get_user_u64(oldval, env->regs[0])) {
+env->exception.vaddress = env->regs[0];
+goto segv;
+};
+
+if (get_user_u64(newval, env->regs[1])) {
+env->exception.vaddress = env->regs[1];
+goto segv;
+};
+
+if (get_user_u64(val, addr)) {
+env->exception.vaddress = addr;
+goto segv;
+}
+
+if (val == oldval) {
+val = newval;
+
+if (put_user_u64(val, addr)) {
+env->exception.vaddress = addr;
+goto segv;
+};
+
+env->regs[0] = 0;
+cpsr |= CPSR_C;
+} else {
+env->regs[0] = -1;
+cpsr &= ~CPSR_C;
+}
+cpsr_write(env, cpsr, CPSR_C, CPSRWriteByInstr);
+end_exclusive();
+return;
+
+segv:
+end_exclusive();
+/* We get the PC of the entry address - which is as good as anything,
+   on a real kernel what you get depends on which mode it uses. */
+info.si_signo = TARGET_SIGSEGV;
+info.si_errno = 0;
+/* XXX: check env->error_code */
+info.si_code = TARGET_SEGV_MAPERR;
+

[Qemu-devel] [PATCH for 2.13 06/19] linux-user: move ppc/ppc64 cpu loop to ppc directory

2018-03-26 Thread Laurent Vivier
No code change, only move code from main.c to
ppc/cpu_loop.c.

Signed-off-by: Laurent Vivier 
---
 linux-user/main.c | 560 +-
 linux-user/ppc/cpu_loop.c | 553 +
 2 files changed, 554 insertions(+), 559 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 349dcd6a20..b5d0513b44 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -149,547 +149,6 @@ void fork_end(int child)
 }
 }
 
-#ifdef TARGET_PPC
-static inline uint64_t cpu_ppc_get_tb(CPUPPCState *env)
-{
-return cpu_get_host_ticks();
-}
-
-uint64_t cpu_ppc_load_tbl(CPUPPCState *env)
-{
-return cpu_ppc_get_tb(env);
-}
-
-uint32_t cpu_ppc_load_tbu(CPUPPCState *env)
-{
-return cpu_ppc_get_tb(env) >> 32;
-}
-
-uint64_t cpu_ppc_load_atbl(CPUPPCState *env)
-{
-return cpu_ppc_get_tb(env);
-}
-
-uint32_t cpu_ppc_load_atbu(CPUPPCState *env)
-{
-return cpu_ppc_get_tb(env) >> 32;
-}
-
-uint32_t cpu_ppc601_load_rtcu(CPUPPCState *env)
-__attribute__ (( alias ("cpu_ppc_load_tbu") ));
-
-uint32_t cpu_ppc601_load_rtcl(CPUPPCState *env)
-{
-return cpu_ppc_load_tbl(env) & 0x3F80;
-}
-
-/* XXX: to be fixed */
-int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, uint32_t *valp)
-{
-return -1;
-}
-
-int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
-{
-return -1;
-}
-
-static int do_store_exclusive(CPUPPCState *env)
-{
-target_ulong addr;
-target_ulong page_addr;
-target_ulong val, val2 __attribute__((unused)) = 0;
-int flags;
-int segv = 0;
-
-addr = env->reserve_ea;
-page_addr = addr & TARGET_PAGE_MASK;
-start_exclusive();
-mmap_lock();
-flags = page_get_flags(page_addr);
-if ((flags & PAGE_READ) == 0) {
-segv = 1;
-} else {
-int reg = env->reserve_info & 0x1f;
-int size = env->reserve_info >> 5;
-int stored = 0;
-
-if (addr == env->reserve_addr) {
-switch (size) {
-case 1: segv = get_user_u8(val, addr); break;
-case 2: segv = get_user_u16(val, addr); break;
-case 4: segv = get_user_u32(val, addr); break;
-#if defined(TARGET_PPC64)
-case 8: segv = get_user_u64(val, addr); break;
-case 16: {
-segv = get_user_u64(val, addr);
-if (!segv) {
-segv = get_user_u64(val2, addr + 8);
-}
-break;
-}
-#endif
-default: abort();
-}
-if (!segv && val == env->reserve_val) {
-val = env->gpr[reg];
-switch (size) {
-case 1: segv = put_user_u8(val, addr); break;
-case 2: segv = put_user_u16(val, addr); break;
-case 4: segv = put_user_u32(val, addr); break;
-#if defined(TARGET_PPC64)
-case 8: segv = put_user_u64(val, addr); break;
-case 16: {
-if (val2 == env->reserve_val2) {
-if (msr_le) {
-val2 = val;
-val = env->gpr[reg+1];
-} else {
-val2 = env->gpr[reg+1];
-}
-segv = put_user_u64(val, addr);
-if (!segv) {
-segv = put_user_u64(val2, addr + 8);
-}
-}
-break;
-}
-#endif
-default: abort();
-}
-if (!segv) {
-stored = 1;
-}
-}
-}
-env->crf[0] = (stored << 1) | xer_so;
-env->reserve_addr = (target_ulong)-1;
-}
-if (!segv) {
-env->nip += 4;
-}
-mmap_unlock();
-end_exclusive();
-return segv;
-}
-
-void cpu_loop(CPUPPCState *env)
-{
-CPUState *cs = CPU(ppc_env_get_cpu(env));
-target_siginfo_t info;
-int trapnr;
-target_ulong ret;
-
-for(;;) {
-cpu_exec_start(cs);
-trapnr = cpu_exec(cs);
-cpu_exec_end(cs);
-process_queued_cpu_work(cs);
-
-switch(trapnr) {
-case POWERPC_EXCP_NONE:
-/* Just go on */
-break;
-case POWERPC_EXCP_CRITICAL: /* Critical input*/
-cpu_abort(cs, "Critical interrupt while in user mode. "
-  "Aborting\n");
-break;
-case POWERPC_EXCP_MCHECK:   /* Machine check exception   */
-cpu_abort(cs, "Machine check exception while in user mode. "
-  "Aborting\n");
-break;
-case POWERPC_EXCP_DSI:  /* Data storage exception*/
-/* XXX: check this. Seems bugged */
-switch (env->error_code & 0xFF00) {
-case 0x4000:
-case 

[Qemu-devel] [PATCH for 2.13 00/19] linux-user: move arch specific parts from main.c to arch directories

2018-03-26 Thread Laurent Vivier
This series moves from main.c the architecture specific parts
to the architecture directory.

This is the continuation of my series
  "linux-user: move arch specific parts to arch directories"
that includes since the v2 only the signal.c parts.

For each architecture, there are two parts:

  - cpu_loop(), and the function with its
dependencies is moved to /cpu_loop.c

  - the prologue of the cpu_loop(), that was inlined
in main(). We move it to a new function in
/cpu_loop.c, target_cpu_copy_regs().

The first patch adds the skeleton to move the
parts to the architecture directories, a cpu_loop.c
file with an empty target_cpu_copy_regs() function,
called from main().

There is no change in the code.

Based-on: <20180323225739.17329-1-laur...@vivier.eu>
"[PATCH for 2.13 v2 00/20] linux-user: move arch specific parts to arch 
directories"

Laurent Vivier (19):
  linux-user: create a dummy per arch cpu_loop.c
  linux-user: move i386/x86_64 cpu loop to i386 directory
  linux-user: move aarch64 cpu loop to aarch64 directory
  linux-user: move arm cpu loop to arm directory
  linux-user: move sparc/sparc64 cpu loop to sparc directory
  linux-user: move ppc/ppc64 cpu loop to ppc directory
  linux-user: move mips/mips64 cpu loop to mips directory
  linux-user: move nios2 cpu loop to nios2 directory
  linux-user: move openrisc cpu loop to openrisc directory
  linux-user: move sh4 cpu loop to sh4 directory
  linux-user: move cris cpu loop to cris directory
  linux-user: move microblaze cpu loop to microblaze directory
  linux-user: move m68k cpu loop to m68k directory
  linux-user: move alpha cpu loop to alpha directory
  linux-user: move s390x cpu loop to s390x directory
  linux-user: move tilegx cpu loop to tilegx directory
  linux-user: move riscv cpu loop to riscv directory
  linux-user: move hppa cpu loop to hppa directory
  linux-user: move xtensa cpu loop to xtensa directory

 linux-user/Makefile.objs |3 +-
 linux-user/aarch64/cpu_loop.c|  182 ++
 linux-user/alpha/cpu_loop.c  |  225 ++
 linux-user/arm/cpu_loop.c|  456 
 linux-user/cpu_loop-common.h |   37 +
 linux-user/cris/cpu_loop.c   |  115 +
 linux-user/hppa/cpu_loop.c   |  211 ++
 linux-user/i386/cpu_loop.c   |  369 
 linux-user/m68k/cpu_loop.c   |  170 ++
 linux-user/main.c| 4439 +-
 linux-user/microblaze/cpu_loop.c |  176 ++
 linux-user/mips/cpu_loop.c   |  749 +++
 linux-user/mips64/cpu_loop.c |   20 +
 linux-user/nios2/cpu_loop.c  |  152 ++
 linux-user/openrisc/cpu_loop.c   |  115 +
 linux-user/ppc/cpu_loop.c|  579 +
 linux-user/riscv/cpu_loop.c  |  118 +
 linux-user/s390x/cpu_loop.c  |  165 ++
 linux-user/sh4/cpu_loop.c|  111 +
 linux-user/sparc/cpu_loop.c  |  306 +++
 linux-user/sparc64/cpu_loop.c|   20 +
 linux-user/tilegx/cpu_loop.c |  286 +++
 linux-user/x86_64/cpu_loop.c |   20 +
 linux-user/xtensa/cpu_loop.c |  264 +++
 24 files changed, 4904 insertions(+), 4384 deletions(-)
 create mode 100644 linux-user/aarch64/cpu_loop.c
 create mode 100644 linux-user/alpha/cpu_loop.c
 create mode 100644 linux-user/arm/cpu_loop.c
 create mode 100644 linux-user/cpu_loop-common.h
 create mode 100644 linux-user/cris/cpu_loop.c
 create mode 100644 linux-user/hppa/cpu_loop.c
 create mode 100644 linux-user/i386/cpu_loop.c
 create mode 100644 linux-user/m68k/cpu_loop.c
 create mode 100644 linux-user/microblaze/cpu_loop.c
 create mode 100644 linux-user/mips/cpu_loop.c
 create mode 100644 linux-user/mips64/cpu_loop.c
 create mode 100644 linux-user/nios2/cpu_loop.c
 create mode 100644 linux-user/openrisc/cpu_loop.c
 create mode 100644 linux-user/ppc/cpu_loop.c
 create mode 100644 linux-user/riscv/cpu_loop.c
 create mode 100644 linux-user/s390x/cpu_loop.c
 create mode 100644 linux-user/sh4/cpu_loop.c
 create mode 100644 linux-user/sparc/cpu_loop.c
 create mode 100644 linux-user/sparc64/cpu_loop.c
 create mode 100644 linux-user/tilegx/cpu_loop.c
 create mode 100644 linux-user/x86_64/cpu_loop.c
 create mode 100644 linux-user/xtensa/cpu_loop.c

-- 
2.14.3




[Qemu-devel] [PATCH for 2.13 03/19] linux-user: move aarch64 cpu loop to aarch64 directory

2018-03-26 Thread Laurent Vivier
No code change, only move code from main.c to
aarch64/cpu_loop.c and duplicate some macro
defined for both arm and aarch64.

Signed-off-by: Laurent Vivier 
---
 linux-user/aarch64/cpu_loop.c | 156 ++
 linux-user/main.c | 109 +
 2 files changed, 158 insertions(+), 107 deletions(-)

diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index b7700a5561..c97a646546 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -21,6 +21,162 @@
 #include "qemu.h"
 #include "cpu_loop-common.h"
 
+#define get_user_code_u32(x, gaddr, env)\
+({ abi_long __r = get_user_u32((x), (gaddr));   \
+if (!__r && bswap_code(arm_sctlr_b(env))) { \
+(x) = bswap32(x);   \
+}   \
+__r;\
+})
+
+#define get_user_code_u16(x, gaddr, env)\
+({ abi_long __r = get_user_u16((x), (gaddr));   \
+if (!__r && bswap_code(arm_sctlr_b(env))) { \
+(x) = bswap16(x);   \
+}   \
+__r;\
+})
+
+#define get_user_data_u32(x, gaddr, env)\
+({ abi_long __r = get_user_u32((x), (gaddr));   \
+if (!__r && arm_cpu_bswap_data(env)) {  \
+(x) = bswap32(x);   \
+}   \
+__r;\
+})
+
+#define get_user_data_u16(x, gaddr, env)\
+({ abi_long __r = get_user_u16((x), (gaddr));   \
+if (!__r && arm_cpu_bswap_data(env)) {  \
+(x) = bswap16(x);   \
+}   \
+__r;\
+})
+
+#define put_user_data_u32(x, gaddr, env)\
+({ typeof(x) __x = (x); \
+if (arm_cpu_bswap_data(env)) {  \
+__x = bswap32(__x); \
+}   \
+put_user_u32(__x, (gaddr)); \
+})
+
+#define put_user_data_u16(x, gaddr, env)\
+({ typeof(x) __x = (x); \
+if (arm_cpu_bswap_data(env)) {  \
+__x = bswap16(__x); \
+}   \
+put_user_u16(__x, (gaddr)); \
+})
+
+/* AArch64 main loop */
+void cpu_loop(CPUARMState *env)
+{
+CPUState *cs = CPU(arm_env_get_cpu(env));
+int trapnr, sig;
+abi_long ret;
+target_siginfo_t info;
+
+for (;;) {
+cpu_exec_start(cs);
+trapnr = cpu_exec(cs);
+cpu_exec_end(cs);
+process_queued_cpu_work(cs);
+
+switch (trapnr) {
+case EXCP_SWI:
+ret = do_syscall(env,
+ env->xregs[8],
+ env->xregs[0],
+ env->xregs[1],
+ env->xregs[2],
+ env->xregs[3],
+ env->xregs[4],
+ env->xregs[5],
+ 0, 0);
+if (ret == -TARGET_ERESTARTSYS) {
+env->pc -= 4;
+} else if (ret != -TARGET_QEMU_ESIGRETURN) {
+env->xregs[0] = ret;
+}
+break;
+case EXCP_INTERRUPT:
+/* just indicate that signals should be handled asap */
+break;
+case EXCP_UDEF:
+info.si_signo = TARGET_SIGILL;
+info.si_errno = 0;
+info.si_code = TARGET_ILL_ILLOPN;
+info._sifields._sigfault._addr = env->pc;
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
+break;
+case EXCP_PREFETCH_ABORT:
+case EXCP_DATA_ABORT:
+info.si_signo = TARGET_SIGSEGV;
+info.si_errno = 0;
+/* XXX: check env->error_code */
+info.si_code = TARGET_SEGV_MAPERR;
+info._sifields._sigfault._addr = env->exception.vaddress;
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
+break;
+case EXCP_DEBUG:
+case EXCP_BKPT:
+sig = gdb_handlesig(cs, TARGET_SIGTRAP);
+if (sig) {
+info.si_signo = sig;
+info.si_errno = 0;
+info.si_code = TARGET_TRAP_BRKPT;
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
+}
+break;
+case EXCP_SEMIHOST:
+

[Qemu-devel] [PATCH for 2.13 09/19] linux-user: move openrisc cpu loop to openrisc directory

2018-03-26 Thread Laurent Vivier
No code change, only move code from main.c to
openrisc/cpu_loop.c.

Signed-off-by: Laurent Vivier 
---
 linux-user/main.c  | 96 --
 linux-user/openrisc/cpu_loop.c | 89 +++
 2 files changed, 89 insertions(+), 96 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 6ee474e5c2..8530dbfdf1 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -149,92 +149,6 @@ void fork_end(int child)
 }
 }
 
-#ifdef TARGET_OPENRISC
-
-void cpu_loop(CPUOpenRISCState *env)
-{
-CPUState *cs = CPU(openrisc_env_get_cpu(env));
-int trapnr;
-abi_long ret;
-target_siginfo_t info;
-
-for (;;) {
-cpu_exec_start(cs);
-trapnr = cpu_exec(cs);
-cpu_exec_end(cs);
-process_queued_cpu_work(cs);
-
-switch (trapnr) {
-case EXCP_SYSCALL:
-env->pc += 4;   /* 0xc00; */
-ret = do_syscall(env,
- cpu_get_gpr(env, 11), /* return value   */
- cpu_get_gpr(env, 3),  /* r3 - r7 are params */
- cpu_get_gpr(env, 4),
- cpu_get_gpr(env, 5),
- cpu_get_gpr(env, 6),
- cpu_get_gpr(env, 7),
- cpu_get_gpr(env, 8), 0, 0);
-if (ret == -TARGET_ERESTARTSYS) {
-env->pc -= 4;
-} else if (ret != -TARGET_QEMU_ESIGRETURN) {
-cpu_set_gpr(env, 11, ret);
-}
-break;
-case EXCP_DPF:
-case EXCP_IPF:
-case EXCP_RANGE:
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-info.si_code = TARGET_SEGV_MAPERR;
-info._sifields._sigfault._addr = env->pc;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-break;
-case EXCP_ALIGN:
-info.si_signo = TARGET_SIGBUS;
-info.si_errno = 0;
-info.si_code = TARGET_BUS_ADRALN;
-info._sifields._sigfault._addr = env->pc;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-break;
-case EXCP_ILLEGAL:
-info.si_signo = TARGET_SIGILL;
-info.si_errno = 0;
-info.si_code = TARGET_ILL_ILLOPC;
-info._sifields._sigfault._addr = env->pc;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-break;
-case EXCP_FPE:
-info.si_signo = TARGET_SIGFPE;
-info.si_errno = 0;
-info.si_code = 0;
-info._sifields._sigfault._addr = env->pc;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-break;
-case EXCP_INTERRUPT:
-/* We processed the pending cpu work above.  */
-break;
-case EXCP_DEBUG:
-trapnr = gdb_handlesig(cs, TARGET_SIGTRAP);
-if (trapnr) {
-info.si_signo = trapnr;
-info.si_errno = 0;
-info.si_code = TARGET_TRAP_BRKPT;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, );
-}
-break;
-case EXCP_ATOMIC:
-cpu_exec_step_atomic(cs);
-break;
-default:
-g_assert_not_reached();
-}
-process_pending_signals(env);
-}
-}
-
-#endif /* TARGET_OPENRISC */
-
 #ifdef TARGET_SH4
 void cpu_loop(CPUSH4State *env)
 {
@@ -2439,16 +2353,6 @@ int main(int argc, char **argv, char **envp)
 env->regs[31] = regs->r31; 
 env->sregs[SR_PC] = regs->pc;
 }
-#elif defined(TARGET_OPENRISC)
-{
-int i;
-
-for (i = 0; i < 32; i++) {
-cpu_set_gpr(env, i, regs->gpr[i]);
-}
-env->pc = regs->pc;
-cpu_set_sr(env, regs->sr);
-}
 #elif defined(TARGET_RISCV)
 {
 env->pc = regs->sepc;
diff --git a/linux-user/openrisc/cpu_loop.c b/linux-user/openrisc/cpu_loop.c
index b7700a5561..6c6ea871e1 100644
--- a/linux-user/openrisc/cpu_loop.c
+++ b/linux-user/openrisc/cpu_loop.c
@@ -21,6 +21,95 @@
 #include "qemu.h"
 #include "cpu_loop-common.h"
 
+void cpu_loop(CPUOpenRISCState *env)
+{
+CPUState *cs = CPU(openrisc_env_get_cpu(env));
+int trapnr;
+abi_long ret;
+target_siginfo_t info;
+
+for (;;) {
+cpu_exec_start(cs);
+trapnr = cpu_exec(cs);
+cpu_exec_end(cs);
+process_queued_cpu_work(cs);
+
+switch (trapnr) {
+case EXCP_SYSCALL:
+env->pc += 4;   /* 0xc00; */
+ret = do_syscall(env,
+ cpu_get_gpr(env, 11), /* return value   */
+ cpu_get_gpr(env, 3),  /* r3 - r7 are params */
+ cpu_get_gpr(env, 4),
+ cpu_get_gpr(env, 5),
+ cpu_get_gpr(env, 6),
+

Re: [Qemu-devel] [PATCH v2] target/xtensa: fix timers test

2018-03-26 Thread Philippe Mathieu-Daudé
On 03/26/2018 02:56 PM, Max Filippov wrote:
> The value of CCOUNT special register is calculated as time elapsed
> since CCOUNT == 0 multiplied by the core frequency. In icount mode time
> increment between consecutive instructions that don't involve time
> warps is constant, but unless the result of multiplication of this
> constant by the core frequency is a whole number the CCOUNT increment
> between these instructions may not be constant. E.g. with icount=7 each
> instruction takes 128ns, with core clock of 10MHz CCOUNT values for
> consecutive instructions are:
> 
>   502: (128 * 502 * 1000) / 10 = 642.56
>   503: (128 * 503 * 1000) / 10 = 643.84
>   504: (128 * 504 * 1000) / 10 = 645.12
> 
> I.e.the CCOUNT increments depend on the absolute time. This results in
> varying CCOUNT differences for consecutive instructions in tests that
> involve time warps and don't set CCOUNT explicitly.
> 
> Change frequency of the core used in tests so that clock cycle takes
> exactly 64ns. Change icount power used in tests to 6, so that each
> instruction takes exactly 1 clock cycle. With these changes CCOUNT
> increments only depend on the number of executed instructions and that's
> what timer tests expect, so they work correctly.
> 
> Longer story:
>   http://lists.nongnu.org/archive/html/qemu-devel/2018-03/msg04326.html
> 
> Cc: Pavel Dovgaluk 
> Cc: Philippe Mathieu-Daudé 
> Signed-off-by: Max Filippov 

Reviewed-by: Philippe Mathieu-Daudé 

> ---
> Changes v1->v2:
> - expand changelog;
> - replace clock_freq_khz initializer constant with a more meaningful
>   expression.

Thanks :)

> 
>  target/xtensa/core-dc232b.c | 2 +-
>  tests/tcg/xtensa/Makefile   | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/target/xtensa/core-dc232b.c b/target/xtensa/core-dc232b.c
> index aa07018af4e7..7331eeea2fb6 100644
> --- a/target/xtensa/core-dc232b.c
> +++ b/target/xtensa/core-dc232b.c
> @@ -47,7 +47,7 @@ static XtensaConfig dc232b __attribute__((unused)) = {
>  }
>  },
>  .isa_internal = _modules,
> -.clock_freq_khz = 1,
> +.clock_freq_khz = (NANOSECONDS_PER_SECOND / 64) / 1000,
>  DEFAULT_SECTIONS
>  };
>  
> diff --git a/tests/tcg/xtensa/Makefile b/tests/tcg/xtensa/Makefile
> index 2882c431e4a9..091518c05583 100644
> --- a/tests/tcg/xtensa/Makefile
> +++ b/tests/tcg/xtensa/Makefile
> @@ -5,7 +5,7 @@ CROSS=xtensa-$(CORE)-elf-
>  
>  ifndef XT
>  SIM = ../../../xtensa-softmmu/qemu-system-xtensa
> -SIMFLAGS = -M sim -cpu $(CORE) -nographic -semihosting -icount 7 $(EXTFLAGS) 
> -kernel
> +SIMFLAGS = -M sim -cpu $(CORE) -nographic -semihosting -icount 6 $(EXTFLAGS) 
> -kernel
>  SIMDEBUG = -s -S
>  else
>  SIM = xt-run
> 



Re: [Qemu-devel] [Qemu-trivial] [PATCH for-2.12] maint: Add .mailmap entries for patches claiming list authorship

2018-03-26 Thread Philippe Mathieu-Daudé
On 03/26/2018 03:41 PM, Eric Blake wrote:
> The list did not author any patches, but it does rewrite the
> 'From:' header of messages sent from any domain with restrictive
> SPF policies that would otherwise prevent the message from reaching
> all list recipients.  If a maintainer is not careful to undo the
> list header rewrite, and the author did not include a manual
> 'From:' line in the body to fix the munged header, then 'git am'
> happily attributes the patch to the list.  Add some mailmap
> entries to correct the few that have escaped our attention; while
> we also work on improving the tooling to catch the problem in
> the future before a merge is even made.

Thanks!

> 
> Also improve the comments occurring in the file, including line
> length improvements.
> 
> Signed-off-by: Eric Blake 

Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 

> ---
> 
> Probably worth inclusion in 2.12-rc1, since it makes statistics
> about the release easier to follow.
> 
>  .mailmap | 18 ++
>  1 file changed, 14 insertions(+), 4 deletions(-)
> 
> diff --git a/.mailmap b/.mailmap
> index cf689b9ec99..b02c357e9a1 100644
> --- a/.mailmap
> +++ b/.mailmap
> @@ -1,6 +1,7 @@
> -# This mailmap just translates the weird addresses from the original import 
> into git
> -# into proper addresses so that they are counted properly in git shortlog 
> output.
> -#
> +# This mailmap fixes up author names/addresses.
> +
> +# The first section translates weird addresses from the original git import
> +# into proper addresses so that they are counted properly by git shortlog.
>  Andrzej Zaborowski  balrog 
> 
>  Anthony Liguori  aliguori 
> 
>  Anthony Liguori  Anthony Liguori 
> @@ -15,10 +16,19 @@ Paul Burton  
> 
>  Paul Burton  
>  Thiemo Seufer  ths 
> 
>  malc  malc 
> +
>  # There is also a:
>  #(no author) <(no author)@c046a42c-6fe2-441c-8c8c-71466251a162>
>  # for the cvs2svn initialization commit e63c3dc74bf.
> -#
> +
> +# Next, translate a few commits where mailman rewrote the From: line due
> +# to strict SPF, although we prefer to avoid adding more entries like that.
> +Ed Swierk  Ed Swierk via Qemu-devel 
> 
> +Ian McKellar  Ian McKellar via Qemu-devel 
> 
> +Julia Suvorova  Julia Suvorova via Qemu-devel 
> 
> +Justin Terry (VM)  Justin Terry (VM) via Qemu-devel 
> 
> +
> +
>  # Also list preferred name forms where people have changed their
>  # git author config
>  Daniel P. Berrangé 
> 



Re: [Qemu-devel] nbd BLOCK_STATUS with -m32

2018-03-26 Thread Eric Blake

On 03/26/2018 01:39 PM, Max Reitz wrote:

Hi,

iotests 209 and 123 fail under 32-bit (or at least with -m32), both with
gcc and mingw.

Diff for 209:

@@ -1,2 +1,2 @@
-[{ "start": 0, "length": 524288, "depth": 0, "zero": false, "data": true},
-{ "start": 524288, "length": 524288, "depth": 0, "zero": true, "data":
false}]
+qemu-img: Protocol error: invalid payload for NBD_REPLY_TYPE_BLOCK_STATUS
+qemu-img: Could not read file metadata: Invalid argument


Diff for 123:

@@ -3,6 +3,10 @@
  Formatting 'TEST_DIR/source.IMGFMT', fmt=IMGFMT size=1048576
  wrote 1048576/1048576 bytes at offset 0
  1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-img: Protocol error: invalid payload for NBD_REPLY_TYPE_BLOCK_STATUS
+qemu-img: error getting block status at offset 0: Invalid argument


Looks to be same root cause; probably an incorrect type promotion or 
truncation somewhere.  I'll step through the code and submit a patch, 
hopefully in time for -rc1.


--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



  1   2   3   4   >