From fb4a08121695a88acefcbcd86f1376df079eefee Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Tue, 22 Jun 2021 22:19:23 +0200 Subject: [PATCH 01/17] s390x/cpumodel: add 3931 and 3932 This defines 5 new facilities and the new 3931 and 3932 machines. As before the name is not yet known and we do use gen16a and gen16b. The new features are part of the full model. The default model is still empty (same as z15) and will be added in a separate patch at a later point in time. Also add the dependencies of new facilities and as a fix for z15 add a dependency from S390_FEAT_VECTOR_PACKED_DECIMAL_ENH to S390_VECTOR_PACKED_DECIMAL. [merged <20210701084348.26556-1-borntraeger@de.ibm.com>] Signed-off-by: Christian Borntraeger Message-Id: <20210622201923.150205-2-borntraeger@de.ibm.com> Reviewed-by: David Hildenbrand Signed-off-by: Cornelia Huck --- target/s390x/cpu_features_def.h.inc | 5 +++++ target/s390x/cpu_models.c | 6 ++++++ target/s390x/gen-features.c | 14 ++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc index 7db3449e04..e86662bb3b 100644 --- a/target/s390x/cpu_features_def.h.inc +++ b/target/s390x/cpu_features_def.h.inc @@ -109,6 +109,11 @@ DEF_FEAT(VECTOR_PACKED_DECIMAL_ENH, "vxpdeh", STFL, 152, "Vector-Packed-Decimal- DEF_FEAT(MSA_EXT_9, "msa9-base", STFL, 155, "Message-security-assist-extension-9 facility (excluding subfunctions)") DEF_FEAT(ETOKEN, "etoken", STFL, 156, "Etoken facility") DEF_FEAT(UNPACK, "unpack", STFL, 161, "Unpack facility") +DEF_FEAT(NNPA, "nnpa", STFL, 165, "NNPA facility") +DEF_FEAT(VECTOR_PACKED_DECIMAL_ENH2, "vxpdeh2", STFL, 192, "Vector-Packed-Decimal-Enhancement facility 2") +DEF_FEAT(BEAR_ENH, "beareh", STFL, 193, "BEAR-enhancement facility") +DEF_FEAT(RDP, "rdp", STFL, 194, "Reset-DAT-protection facility") +DEF_FEAT(PAI, "pai", STFL, 196, "Processor-Activity-Instrumentation facility") /* Features exposed via SCLP SCCB Byte 80 - 98 (bit numbers relative to byte-80) */ DEF_FEAT(SIE_GSLS, "gsls", SCLP_CONF_CHAR, 40, "SIE: Guest-storage-limit-suppression facility") diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c index 94090a6e22..9699823b20 100644 --- a/target/s390x/cpu_models.c +++ b/target/s390x/cpu_models.c @@ -88,6 +88,8 @@ static S390CPUDef s390_cpu_defs[] = { CPUDEF_INIT(0x3907, 14, 1, 47, 0x08000000U, "z14ZR1", "IBM z14 Model ZR1 GA1"), CPUDEF_INIT(0x8561, 15, 1, 47, 0x08000000U, "gen15a", "IBM z15 T01 GA1"), CPUDEF_INIT(0x8562, 15, 1, 47, 0x08000000U, "gen15b", "IBM z15 T02 GA1"), + CPUDEF_INIT(0x3931, 16, 1, 47, 0x08000000U, "gen16a", "IBM 3931 GA1"), + CPUDEF_INIT(0x3932, 16, 1, 47, 0x08000000U, "gen16b", "IBM 3932 GA1"), }; #define QEMU_MAX_CPU_TYPE 0x3906 @@ -812,6 +814,8 @@ static void check_consistency(const S390CPUModel *model) { S390_FEAT_MSA_EXT_9, S390_FEAT_MSA_EXT_4 }, { S390_FEAT_MULTIPLE_EPOCH, S390_FEAT_TOD_CLOCK_STEERING }, { S390_FEAT_VECTOR_PACKED_DECIMAL, S390_FEAT_VECTOR }, + { S390_FEAT_VECTOR_PACKED_DECIMAL_ENH, S390_FEAT_VECTOR_PACKED_DECIMAL }, + { S390_FEAT_VECTOR_PACKED_DECIMAL_ENH2, S390_FEAT_VECTOR_PACKED_DECIMAL_ENH }, { S390_FEAT_VECTOR_ENH, S390_FEAT_VECTOR }, { S390_FEAT_INSTRUCTION_EXEC_PROT, S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2 }, { S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2, S390_FEAT_ESOP }, @@ -843,6 +847,8 @@ static void check_consistency(const S390CPUModel *model) { S390_FEAT_PTFF_STOUE, S390_FEAT_MULTIPLE_EPOCH }, { S390_FEAT_AP_QUEUE_INTERRUPT_CONTROL, S390_FEAT_AP }, { S390_FEAT_DIAG_318, S390_FEAT_EXTENDED_LENGTH_SCCB }, + { S390_FEAT_NNPA, S390_FEAT_VECTOR }, + { S390_FEAT_RDP, S390_FEAT_LOCAL_TLB_CLEARING }, }; int i; diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index 242c95ede4..7d85322d68 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -424,6 +424,8 @@ static uint16_t base_GEN15_GA1[] = { S390_FEAT_MISC_INSTRUCTION_EXT3, }; +#define base_GEN16_GA1 EmptyFeat + /* Full features (in order of release) * Automatically includes corresponding base features. * Full features are all features this hardware supports even if kvm/QEMU do not @@ -567,6 +569,15 @@ static uint16_t full_GEN15_GA1[] = { S390_FEAT_UNPACK, }; +static uint16_t full_GEN16_GA1[] = { + S390_FEAT_NNPA, + S390_FEAT_VECTOR_PACKED_DECIMAL_ENH2, + S390_FEAT_BEAR_ENH, + S390_FEAT_RDP, + S390_FEAT_PAI, +}; + + /* Default features (in order of release) * Automatically includes corresponding base features. * Default features are all features this version of QEMU supports for this @@ -652,6 +663,8 @@ static uint16_t default_GEN15_GA1[] = { S390_FEAT_ETOKEN, }; +#define default_GEN16_GA1 EmptyFeat + /* QEMU (CPU model) features */ static uint16_t qemu_V2_11[] = { @@ -785,6 +798,7 @@ static CpuFeatDefSpec CpuFeatDef[] = { CPU_FEAT_INITIALIZER(GEN14_GA1), CPU_FEAT_INITIALIZER(GEN14_GA2), CPU_FEAT_INITIALIZER(GEN15_GA1), + CPU_FEAT_INITIALIZER(GEN16_GA1), }; #define FEAT_GROUP_INITIALIZER(_name) \ From 28761057043aa234b33a3301b39c8707984bb0a0 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Wed, 30 Jun 2021 12:50:58 +0200 Subject: [PATCH 02/17] target/s390x: Fix CC set by CONVERT TO FIXED/LOGICAL The FP-to-integer conversion instructions need to set CC 3 whenever a "special case" occurs; this is the case whenever the instruction also signals the IEEE invalid exception. (See e.g. figure 19-18 in the Principles of Operation.) However, qemu currently will set CC 3 only in the case where the input was a NaN. This is indeed one of the special cases, but there are others, most notably the case where the input is out of range of the target data type. This patch fixes the problem by switching these instructions to the "static" CC method and computing the correct result directly in the helper. (It cannot be re-computed later as the information about the invalid exception is no longer available.) This fixes a bug observed when running the wasmtime test suite under the s390x-linux-user target. Signed-off-by: Ulrich Weigand Reviewed-by: Richard Henderson Message-Id: <20210630105058.GA29130@oc3748833570.ibm.com> Signed-off-by: Cornelia Huck --- target/s390x/fpu_helper.c | 63 ++++++++++++++++++++++++++++++++++++--- target/s390x/helper.h | 24 +++++++-------- target/s390x/translate.c | 39 ++++++++---------------- 3 files changed, 83 insertions(+), 43 deletions(-) diff --git a/target/s390x/fpu_helper.c b/target/s390x/fpu_helper.c index 13af158748..a42741eec6 100644 --- a/target/s390x/fpu_helper.c +++ b/target/s390x/fpu_helper.c @@ -168,6 +168,34 @@ uint32_t set_cc_nz_f128(float128 v) } } +/* condition codes for FP to integer conversion ops */ +static uint32_t set_cc_conv_f32(float32 v, float_status *stat) +{ + if (stat->float_exception_flags & float_flag_invalid) { + return 3; + } else { + return set_cc_nz_f32(v); + } +} + +static uint32_t set_cc_conv_f64(float64 v, float_status *stat) +{ + if (stat->float_exception_flags & float_flag_invalid) { + return 3; + } else { + return set_cc_nz_f64(v); + } +} + +static uint32_t set_cc_conv_f128(float128 v, float_status *stat) +{ + if (stat->float_exception_flags & float_flag_invalid) { + return 3; + } else { + return set_cc_nz_f128(v); + } +} + static inline uint8_t round_from_m34(uint32_t m34) { return extract32(m34, 0, 4); @@ -506,9 +534,11 @@ uint64_t HELPER(cgeb)(CPUS390XState *env, uint64_t v2, uint32_t m34) { int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); int64_t ret = float32_to_int64(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f32(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); + env->cc_op = cc; if (float32_is_any_nan(v2)) { return INT64_MIN; } @@ -520,9 +550,11 @@ uint64_t HELPER(cgdb)(CPUS390XState *env, uint64_t v2, uint32_t m34) { int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); int64_t ret = float64_to_int64(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f64(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); + env->cc_op = cc; if (float64_is_any_nan(v2)) { return INT64_MIN; } @@ -535,9 +567,11 @@ uint64_t HELPER(cgxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34) int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); float128 v2 = make_float128(h, l); int64_t ret = float128_to_int64(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f128(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); + env->cc_op = cc; if (float128_is_any_nan(v2)) { return INT64_MIN; } @@ -549,9 +583,11 @@ uint64_t HELPER(cfeb)(CPUS390XState *env, uint64_t v2, uint32_t m34) { int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); int32_t ret = float32_to_int32(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f32(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); + env->cc_op = cc; if (float32_is_any_nan(v2)) { return INT32_MIN; } @@ -563,9 +599,11 @@ uint64_t HELPER(cfdb)(CPUS390XState *env, uint64_t v2, uint32_t m34) { int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); int32_t ret = float64_to_int32(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f64(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); + env->cc_op = cc; if (float64_is_any_nan(v2)) { return INT32_MIN; } @@ -578,9 +616,11 @@ uint64_t HELPER(cfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34) int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); float128 v2 = make_float128(h, l); int32_t ret = float128_to_int32(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f128(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); + env->cc_op = cc; if (float128_is_any_nan(v2)) { return INT32_MIN; } @@ -592,8 +632,11 @@ uint64_t HELPER(clgeb)(CPUS390XState *env, uint64_t v2, uint32_t m34) { int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); uint64_t ret = float32_to_uint64(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f32(v2, &env->fpu_status); + s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); + env->cc_op = cc; if (float32_is_any_nan(v2)) { return 0; } @@ -605,9 +648,11 @@ uint64_t HELPER(clgdb)(CPUS390XState *env, uint64_t v2, uint32_t m34) { int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); uint64_t ret = float64_to_uint64(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f64(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); + env->cc_op = cc; if (float64_is_any_nan(v2)) { return 0; } @@ -618,11 +663,14 @@ uint64_t HELPER(clgdb)(CPUS390XState *env, uint64_t v2, uint32_t m34) uint64_t HELPER(clgxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34) { int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); - uint64_t ret = float128_to_uint64(make_float128(h, l), &env->fpu_status); + float128 v2 = make_float128(h, l); + uint64_t ret = float128_to_uint64(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f128(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); - if (float128_is_any_nan(make_float128(h, l))) { + env->cc_op = cc; + if (float128_is_any_nan(v2)) { return 0; } return ret; @@ -633,9 +681,11 @@ uint64_t HELPER(clfeb)(CPUS390XState *env, uint64_t v2, uint32_t m34) { int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); uint32_t ret = float32_to_uint32(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f32(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); + env->cc_op = cc; if (float32_is_any_nan(v2)) { return 0; } @@ -647,9 +697,11 @@ uint64_t HELPER(clfdb)(CPUS390XState *env, uint64_t v2, uint32_t m34) { int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); uint32_t ret = float64_to_uint32(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f64(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); + env->cc_op = cc; if (float64_is_any_nan(v2)) { return 0; } @@ -660,11 +712,14 @@ uint64_t HELPER(clfdb)(CPUS390XState *env, uint64_t v2, uint32_t m34) uint64_t HELPER(clfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34) { int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); - uint32_t ret = float128_to_uint32(make_float128(h, l), &env->fpu_status); + float128 v2 = make_float128(h, l); + uint32_t ret = float128_to_uint32(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f128(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); - if (float128_is_any_nan(make_float128(h, l))) { + env->cc_op = cc; + if (float128_is_any_nan(v2)) { return 0; } return ret; diff --git a/target/s390x/helper.h b/target/s390x/helper.h index ba045f559d..6215ca00bc 100644 --- a/target/s390x/helper.h +++ b/target/s390x/helper.h @@ -64,18 +64,18 @@ DEF_HELPER_FLAGS_5(cxb, TCG_CALL_NO_WG_SE, i32, env, i64, i64, i64, i64) DEF_HELPER_FLAGS_3(keb, TCG_CALL_NO_WG, i32, env, i64, i64) DEF_HELPER_FLAGS_3(kdb, TCG_CALL_NO_WG, i32, env, i64, i64) DEF_HELPER_FLAGS_5(kxb, TCG_CALL_NO_WG, i32, env, i64, i64, i64, i64) -DEF_HELPER_FLAGS_3(cgeb, TCG_CALL_NO_WG, i64, env, i64, i32) -DEF_HELPER_FLAGS_3(cgdb, TCG_CALL_NO_WG, i64, env, i64, i32) -DEF_HELPER_FLAGS_4(cgxb, TCG_CALL_NO_WG, i64, env, i64, i64, i32) -DEF_HELPER_FLAGS_3(cfeb, TCG_CALL_NO_WG, i64, env, i64, i32) -DEF_HELPER_FLAGS_3(cfdb, TCG_CALL_NO_WG, i64, env, i64, i32) -DEF_HELPER_FLAGS_4(cfxb, TCG_CALL_NO_WG, i64, env, i64, i64, i32) -DEF_HELPER_FLAGS_3(clgeb, TCG_CALL_NO_WG, i64, env, i64, i32) -DEF_HELPER_FLAGS_3(clgdb, TCG_CALL_NO_WG, i64, env, i64, i32) -DEF_HELPER_FLAGS_4(clgxb, TCG_CALL_NO_WG, i64, env, i64, i64, i32) -DEF_HELPER_FLAGS_3(clfeb, TCG_CALL_NO_WG, i64, env, i64, i32) -DEF_HELPER_FLAGS_3(clfdb, TCG_CALL_NO_WG, i64, env, i64, i32) -DEF_HELPER_FLAGS_4(clfxb, TCG_CALL_NO_WG, i64, env, i64, i64, i32) +DEF_HELPER_3(cgeb, i64, env, i64, i32) +DEF_HELPER_3(cgdb, i64, env, i64, i32) +DEF_HELPER_4(cgxb, i64, env, i64, i64, i32) +DEF_HELPER_3(cfeb, i64, env, i64, i32) +DEF_HELPER_3(cfdb, i64, env, i64, i32) +DEF_HELPER_4(cfxb, i64, env, i64, i64, i32) +DEF_HELPER_3(clgeb, i64, env, i64, i32) +DEF_HELPER_3(clgdb, i64, env, i64, i32) +DEF_HELPER_4(clgxb, i64, env, i64, i64, i32) +DEF_HELPER_3(clfeb, i64, env, i64, i32) +DEF_HELPER_3(clfdb, i64, env, i64, i32) +DEF_HELPER_4(clfxb, i64, env, i64, i64, i32) DEF_HELPER_FLAGS_3(fieb, TCG_CALL_NO_WG, i64, env, i64, i32) DEF_HELPER_FLAGS_3(fidb, TCG_CALL_NO_WG, i64, env, i64, i32) DEF_HELPER_FLAGS_4(fixb, TCG_CALL_NO_WG, i64, env, i64, i64, i32) diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 03dab9f350..71ae3f333e 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -563,21 +563,6 @@ static void set_cc_nz_u64(DisasContext *s, TCGv_i64 val) gen_op_update1_cc_i64(s, CC_OP_NZ, val); } -static void gen_set_cc_nz_f32(DisasContext *s, TCGv_i64 val) -{ - gen_op_update1_cc_i64(s, CC_OP_NZ_F32, val); -} - -static void gen_set_cc_nz_f64(DisasContext *s, TCGv_i64 val) -{ - gen_op_update1_cc_i64(s, CC_OP_NZ_F64, val); -} - -static void gen_set_cc_nz_f128(DisasContext *s, TCGv_i64 vh, TCGv_i64 vl) -{ - gen_op_update2_cc_i64(s, CC_OP_NZ_F128, vh, vl); -} - /* CC value is in env->cc_op */ static void set_cc_static(DisasContext *s) { @@ -1836,7 +1821,7 @@ static DisasJumpType op_cfeb(DisasContext *s, DisasOps *o) } gen_helper_cfeb(o->out, cpu_env, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f32(s, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1849,7 +1834,7 @@ static DisasJumpType op_cfdb(DisasContext *s, DisasOps *o) } gen_helper_cfdb(o->out, cpu_env, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f64(s, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1862,7 +1847,7 @@ static DisasJumpType op_cfxb(DisasContext *s, DisasOps *o) } gen_helper_cfxb(o->out, cpu_env, o->in1, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f128(s, o->in1, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1875,7 +1860,7 @@ static DisasJumpType op_cgeb(DisasContext *s, DisasOps *o) } gen_helper_cgeb(o->out, cpu_env, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f32(s, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1888,7 +1873,7 @@ static DisasJumpType op_cgdb(DisasContext *s, DisasOps *o) } gen_helper_cgdb(o->out, cpu_env, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f64(s, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1901,7 +1886,7 @@ static DisasJumpType op_cgxb(DisasContext *s, DisasOps *o) } gen_helper_cgxb(o->out, cpu_env, o->in1, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f128(s, o->in1, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1914,7 +1899,7 @@ static DisasJumpType op_clfeb(DisasContext *s, DisasOps *o) } gen_helper_clfeb(o->out, cpu_env, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f32(s, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1927,7 +1912,7 @@ static DisasJumpType op_clfdb(DisasContext *s, DisasOps *o) } gen_helper_clfdb(o->out, cpu_env, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f64(s, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1940,7 +1925,7 @@ static DisasJumpType op_clfxb(DisasContext *s, DisasOps *o) } gen_helper_clfxb(o->out, cpu_env, o->in1, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f128(s, o->in1, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1953,7 +1938,7 @@ static DisasJumpType op_clgeb(DisasContext *s, DisasOps *o) } gen_helper_clgeb(o->out, cpu_env, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f32(s, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1966,7 +1951,7 @@ static DisasJumpType op_clgdb(DisasContext *s, DisasOps *o) } gen_helper_clgdb(o->out, cpu_env, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f64(s, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1979,7 +1964,7 @@ static DisasJumpType op_clgxb(DisasContext *s, DisasOps *o) } gen_helper_clgxb(o->out, cpu_env, o->in1, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f128(s, o->in1, o->in2); + set_cc_static(s); return DISAS_NEXT; } From af4ba0ec8f017c402c239f2888ef62f63770ba8b Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Mon, 5 Jul 2021 11:03:41 +0200 Subject: [PATCH 03/17] s390x/tcg: Fix m5 vs. m4 field for VECTOR MULTIPLY SUM LOGICAL The element size is located in m5, not in m4. As there is no m4, qemu currently crashes with an assertion, trying to lookup that field. Reproduced and tested via GO, which ends up using VMSL once the Vector enhancements facility is around for verifying certificates with elliptic curves. Reported-by: Jonathan Albrecht Resolves: https://gitlab.com/qemu-project/qemu/-/issues/449 Signed-off-by: David Hildenbrand Reviewed-by: Thomas Huth Fixes: 8c18fa5b3eba ("s390x/tcg: Implement VECTOR MULTIPLY SUM LOGICAL") Message-Id: <20210705090341.58289-1-david@redhat.com> Signed-off-by: Cornelia Huck --- target/s390x/translate_vx.c.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc index a9d51b1f4c..0afa46e463 100644 --- a/target/s390x/translate_vx.c.inc +++ b/target/s390x/translate_vx.c.inc @@ -1783,7 +1783,7 @@ static DisasJumpType op_vmsl(DisasContext *s, DisasOps *o) { TCGv_i64 l1, h1, l2, h2; - if (get_field(s, m4) != ES_64) { + if (get_field(s, m5) != ES_64) { gen_program_exception(s, PGM_SPECIFICATION); return DISAS_NORETURN; } From 33f6a7d66f9e87368ae43fec4adf0d04d9ded0bd Mon Sep 17 00:00:00 2001 From: "Cho, Yu-Chen" Date: Wed, 7 Jul 2021 18:53:11 +0800 Subject: [PATCH 04/17] target/s390x: meson: add target_user_arch the lack of target_user_arch makes it hard to fully leverage the build system in order to separate user code from sysemu code. Provide it, so that we can avoid the proliferation of #ifdef in target code. Signed-off-by: Claudio Fontana Signed-off-by: Cho, Yu-Chen Acked-by: Cornelia Huck Reviewed-by: Richard Henderson Reviewed-by: Thomas Huth Message-Id: <20210707105324.23400-2-acho@suse.com> Signed-off-by: Cornelia Huck --- target/s390x/meson.build | 3 +++ 1 file changed, 3 insertions(+) diff --git a/target/s390x/meson.build b/target/s390x/meson.build index c42eadb7d2..1219f64112 100644 --- a/target/s390x/meson.build +++ b/target/s390x/meson.build @@ -58,5 +58,8 @@ if host_machine.cpu_family() == 's390x' and cc.has_link_argument('-Wl,--s390-pgs if_true: declare_dependency(link_args: ['-Wl,--s390-pgste'])) endif +s390x_user_ss = ss.source_set() + target_arch += {'s390x': s390x_ss} target_softmmu_arch += {'s390x': s390x_softmmu_ss} +target_user_arch += {'s390x': s390x_user_ss} From 85f1b67d4bcbdc6a12c3d2416df1a6d599414ee5 Mon Sep 17 00:00:00 2001 From: "Cho, Yu-Chen" Date: Wed, 7 Jul 2021 18:53:12 +0800 Subject: [PATCH 05/17] hw/s390x: rename tod-qemu.c to tod-tcg.c we stop short of renaming the actual qom object though, so type remains TYPE_QEMU_S390_TOD, ie "s390-tod-qemu". Signed-off-by: Claudio Fontana Signed-off-by: Cho, Yu-Chen Reviewed-by: David Hildenbrand Reviewed-by: Cornelia Huck Reviewed-by: Thomas Huth Message-Id: <20210707105324.23400-3-acho@suse.com> Signed-off-by: Cornelia Huck --- hw/s390x/meson.build | 2 +- hw/s390x/{tod-qemu.c => tod-tcg.c} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename hw/s390x/{tod-qemu.c => tod-tcg.c} (97%) diff --git a/hw/s390x/meson.build b/hw/s390x/meson.build index 327e9c93af..02e81a9467 100644 --- a/hw/s390x/meson.build +++ b/hw/s390x/meson.build @@ -16,7 +16,7 @@ s390x_ss.add(files( 'sclp.c', 'sclpcpu.c', 'sclpquiesce.c', - 'tod-qemu.c', + 'tod-tcg.c', 'tod.c', )) s390x_ss.add(when: 'CONFIG_KVM', if_true: files( diff --git a/hw/s390x/tod-qemu.c b/hw/s390x/tod-tcg.c similarity index 97% rename from hw/s390x/tod-qemu.c rename to hw/s390x/tod-tcg.c index e91b9590f5..aa44deb809 100644 --- a/hw/s390x/tod-qemu.c +++ b/hw/s390x/tod-tcg.c @@ -1,5 +1,5 @@ /* - * TOD (Time Of Day) clock - QEMU implementation + * TOD (Time Of Day) clock - TCG implementation * * Copyright 2018 Red Hat, Inc. * Author(s): David Hildenbrand From 4f91550a0962519e5c54330833486d7940417be0 Mon Sep 17 00:00:00 2001 From: "Cho, Yu-Chen" Date: Wed, 7 Jul 2021 18:53:13 +0800 Subject: [PATCH 06/17] hw/s390x: tod: make explicit checks for accelerators when initializing replace general "else" with specific checks for each possible accelerator. Handle qtest as a NOP, and error out for an unknown accelerator used in combination with tod. Signed-off-by: Claudio Fontana Signed-off-by: Cho, Yu-Chen Reviewed-by: David Hildenbrand Reviewed-by: Cornelia Huck Reviewed-by: Thomas Huth Message-Id: <20210707105324.23400-4-acho@suse.com> Signed-off-by: Cornelia Huck --- hw/s390x/tod.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hw/s390x/tod.c b/hw/s390x/tod.c index 3c2979175e..fd5a36bf24 100644 --- a/hw/s390x/tod.c +++ b/hw/s390x/tod.c @@ -14,6 +14,8 @@ #include "qemu/error-report.h" #include "qemu/module.h" #include "sysemu/kvm.h" +#include "sysemu/tcg.h" +#include "sysemu/qtest.h" #include "migration/qemu-file-types.h" #include "migration/register.h" @@ -23,8 +25,13 @@ void s390_init_tod(void) if (kvm_enabled()) { obj = object_new(TYPE_KVM_S390_TOD); - } else { + } else if (tcg_enabled()) { obj = object_new(TYPE_QEMU_S390_TOD); + } else if (qtest_enabled()) { + return; + } else { + error_report("current accelerator not handled in s390_init_tod!"); + abort(); } object_property_add_child(qdev_get_machine(), TYPE_S390_TOD, obj); object_unref(obj); From 1be53ca48c6d58355a71f3272bf7fc7c22f1e441 Mon Sep 17 00:00:00 2001 From: "Cho, Yu-Chen" Date: Wed, 7 Jul 2021 18:53:14 +0800 Subject: [PATCH 07/17] hw/s390x: only build tod-tcg from the CONFIG_TCG build this will allow in later patches to remove unneeded stubs in target/s390x. Signed-off-by: Claudio Fontana Signed-off-by: Cho, Yu-Chen Reviewed-by: David Hildenbrand Reviewed-by: Cornelia Huck Reviewed-by: Thomas Huth Message-Id: <20210707105324.23400-5-acho@suse.com> Signed-off-by: Cornelia Huck --- hw/s390x/meson.build | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/s390x/meson.build b/hw/s390x/meson.build index 02e81a9467..28484256ec 100644 --- a/hw/s390x/meson.build +++ b/hw/s390x/meson.build @@ -16,7 +16,6 @@ s390x_ss.add(files( 'sclp.c', 'sclpcpu.c', 'sclpquiesce.c', - 'tod-tcg.c', 'tod.c', )) s390x_ss.add(when: 'CONFIG_KVM', if_true: files( @@ -25,6 +24,9 @@ s390x_ss.add(when: 'CONFIG_KVM', if_true: files( 's390-stattrib-kvm.c', 'pv.c', )) +s390x_ss.add(when: 'CONFIG_TCG', if_true: files( + 'tod-tcg.c', +)) s390x_ss.add(when: 'CONFIG_S390_CCW_VIRTIO', if_true: files('s390-virtio-ccw.c')) s390x_ss.add(when: 'CONFIG_TERMINAL3270', if_true: files('3270-ccw.c')) s390x_ss.add(when: 'CONFIG_VFIO', if_true: files('s390-pci-vfio.c')) From dda740dec54f947e23b90e1e042281e9a65ec128 Mon Sep 17 00:00:00 2001 From: "Cho, Yu-Chen" Date: Wed, 7 Jul 2021 18:53:15 +0800 Subject: [PATCH 08/17] target/s390x: remove tcg-stub.c now that we protect all calls to the tcg-specific functions with if (tcg_enabled()), we do not need the TCG stub anymore. Signed-off-by: Claudio Fontana Signed-off-by: Cho, Yu-Chen Reviewed-by: David Hildenbrand Reviewed-by: Cornelia Huck Reviewed-by: Thomas Huth Message-Id: <20210707105324.23400-6-acho@suse.com> Signed-off-by: Cornelia Huck --- target/s390x/meson.build | 2 +- target/s390x/tcg-stub.c | 30 ------------------------------ 2 files changed, 1 insertion(+), 31 deletions(-) delete mode 100644 target/s390x/tcg-stub.c diff --git a/target/s390x/meson.build b/target/s390x/meson.build index 1219f64112..a5e1ded93f 100644 --- a/target/s390x/meson.build +++ b/target/s390x/meson.build @@ -21,7 +21,7 @@ s390x_ss.add(when: 'CONFIG_TCG', if_true: files( 'vec_helper.c', 'vec_int_helper.c', 'vec_string_helper.c', -), if_false: files('tcg-stub.c')) +)) s390x_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c')) diff --git a/target/s390x/tcg-stub.c b/target/s390x/tcg-stub.c deleted file mode 100644 index d22c898802..0000000000 --- a/target/s390x/tcg-stub.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * QEMU TCG support -- s390x specific function stubs. - * - * Copyright (C) 2018 Red Hat Inc - * - * Authors: - * David Hildenbrand - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ - -#include "qemu/osdep.h" -#include "qemu-common.h" -#include "cpu.h" -#include "tcg_s390x.h" - -void tcg_s390_tod_updated(CPUState *cs, run_on_cpu_data opaque) -{ -} -void QEMU_NORETURN tcg_s390_program_interrupt(CPUS390XState *env, - uint32_t code, uintptr_t ra) -{ - g_assert_not_reached(); -} -void QEMU_NORETURN tcg_s390_data_exception(CPUS390XState *env, uint32_t dxc, - uintptr_t ra) -{ - g_assert_not_reached(); -} From b6b4722307f31491ee553c674ded2a8bba6173e1 Mon Sep 17 00:00:00 2001 From: "Cho, Yu-Chen" Date: Wed, 7 Jul 2021 18:53:16 +0800 Subject: [PATCH 09/17] target/s390x: rename internal.h to s390x-internal.h The internal.h file is renamed to s390x-internal.h, because of the risk of collision with other files with the same name. Signed-off-by: Claudio Fontana Signed-off-by: Cho, Yu-Chen Acked-by: David Hildenbrand Acked-by: Cornelia Huck Reviewed-by: Thomas Huth Message-Id: <20210707105324.23400-7-acho@suse.com> Signed-off-by: Cornelia Huck --- target/s390x/arch_dump.c | 2 +- target/s390x/cc_helper.c | 2 +- target/s390x/cpu.c | 2 +- target/s390x/cpu_models.c | 2 +- target/s390x/crypto_helper.c | 2 +- target/s390x/diag.c | 2 +- target/s390x/excp_helper.c | 2 +- target/s390x/fpu_helper.c | 2 +- target/s390x/gdbstub.c | 2 +- target/s390x/helper.c | 2 +- target/s390x/int_helper.c | 2 +- target/s390x/interrupt.c | 2 +- target/s390x/ioinst.c | 2 +- target/s390x/kvm.c | 2 +- target/s390x/machine.c | 2 +- target/s390x/mem_helper.c | 2 +- target/s390x/misc_helper.c | 2 +- target/s390x/mmu_helper.c | 2 +- target/s390x/{internal.h => s390x-internal.h} | 0 target/s390x/sigp.c | 2 +- target/s390x/translate.c | 2 +- target/s390x/vec_fpu_helper.c | 2 +- target/s390x/vec_helper.c | 2 +- target/s390x/vec_string_helper.c | 2 +- 24 files changed, 23 insertions(+), 23 deletions(-) rename target/s390x/{internal.h => s390x-internal.h} (100%) diff --git a/target/s390x/arch_dump.c b/target/s390x/arch_dump.c index cc1330876b..08daf93ae1 100644 --- a/target/s390x/arch_dump.c +++ b/target/s390x/arch_dump.c @@ -13,7 +13,7 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "elf.h" #include "sysemu/dump.h" diff --git a/target/s390x/cc_helper.c b/target/s390x/cc_helper.c index e7a74d66dd..c2c96c3a3c 100644 --- a/target/s390x/cc_helper.c +++ b/target/s390x/cc_helper.c @@ -20,7 +20,7 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "tcg_s390x.h" #include "exec/exec-all.h" #include "exec/helper-proto.h" diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c index 890f382a36..1795042e97 100644 --- a/target/s390x/cpu.c +++ b/target/s390x/cpu.c @@ -23,7 +23,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "kvm_s390x.h" #include "sysemu/kvm.h" #include "sysemu/reset.h" diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c index 9699823b20..442f06e140 100644 --- a/target/s390x/cpu_models.c +++ b/target/s390x/cpu_models.c @@ -12,7 +12,7 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "kvm_s390x.h" #include "sysemu/kvm.h" #include "sysemu/tcg.h" diff --git a/target/s390x/crypto_helper.c b/target/s390x/crypto_helper.c index ff3fbc3950..138d9e7ad9 100644 --- a/target/s390x/crypto_helper.c +++ b/target/s390x/crypto_helper.c @@ -12,7 +12,7 @@ #include "qemu/osdep.h" #include "qemu/main-loop.h" -#include "internal.h" +#include "s390x-internal.h" #include "tcg_s390x.h" #include "exec/helper-proto.h" #include "exec/exec-all.h" diff --git a/target/s390x/diag.c b/target/s390x/diag.c index d620cd4bd4..c17a2498a7 100644 --- a/target/s390x/diag.c +++ b/target/s390x/diag.c @@ -14,7 +14,7 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "hw/watchdog/wdt_diag288.h" #include "sysemu/cpus.h" #include "hw/s390x/ipl.h" diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c index 9c361428c8..a61917d04f 100644 --- a/target/s390x/excp_helper.c +++ b/target/s390x/excp_helper.c @@ -20,7 +20,7 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "exec/helper-proto.h" #include "qemu/timer.h" #include "exec/exec-all.h" diff --git a/target/s390x/fpu_helper.c b/target/s390x/fpu_helper.c index a42741eec6..4067205405 100644 --- a/target/s390x/fpu_helper.c +++ b/target/s390x/fpu_helper.c @@ -20,7 +20,7 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "tcg_s390x.h" #include "exec/exec-all.h" #include "exec/cpu_ldst.h" diff --git a/target/s390x/gdbstub.c b/target/s390x/gdbstub.c index 5b4e38a13b..a5d69d0e0b 100644 --- a/target/s390x/gdbstub.c +++ b/target/s390x/gdbstub.c @@ -20,7 +20,7 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "exec/exec-all.h" #include "exec/gdbstub.h" #include "qemu/bitops.h" diff --git a/target/s390x/helper.c b/target/s390x/helper.c index 1445b74451..8015c4e3d1 100644 --- a/target/s390x/helper.c +++ b/target/s390x/helper.c @@ -20,7 +20,7 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "exec/gdbstub.h" #include "qemu/timer.h" #include "qemu/qemu-print.h" diff --git a/target/s390x/int_helper.c b/target/s390x/int_helper.c index 658507dd6d..954542388a 100644 --- a/target/s390x/int_helper.c +++ b/target/s390x/int_helper.c @@ -20,7 +20,7 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "tcg_s390x.h" #include "exec/exec-all.h" #include "qemu/host-utils.h" diff --git a/target/s390x/interrupt.c b/target/s390x/interrupt.c index 9b4d08f2be..3fde18ba46 100644 --- a/target/s390x/interrupt.c +++ b/target/s390x/interrupt.c @@ -10,7 +10,7 @@ #include "qemu/osdep.h" #include "cpu.h" #include "kvm_s390x.h" -#include "internal.h" +#include "s390x-internal.h" #include "exec/exec-all.h" #include "sysemu/kvm.h" #include "sysemu/tcg.h" diff --git a/target/s390x/ioinst.c b/target/s390x/ioinst.c index 1ee11522e1..4eb0a7a9f8 100644 --- a/target/s390x/ioinst.c +++ b/target/s390x/ioinst.c @@ -12,7 +12,7 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "hw/s390x/ioinst.h" #include "trace.h" #include "hw/s390x/s390-pci-bus.h" diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c index 2388924587..5b1fdb55c4 100644 --- a/target/s390x/kvm.c +++ b/target/s390x/kvm.c @@ -26,7 +26,7 @@ #include "qemu-common.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "kvm_s390x.h" #include "sysemu/kvm_int.h" #include "qemu/cutils.h" diff --git a/target/s390x/machine.c b/target/s390x/machine.c index 5b4e82f1ab..4f11f6ac6e 100644 --- a/target/s390x/machine.c +++ b/target/s390x/machine.c @@ -16,7 +16,7 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "kvm_s390x.h" #include "migration/vmstate.h" #include "tcg_s390x.h" diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index f6a7d29273..9bae13ecf0 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -20,7 +20,7 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "tcg_s390x.h" #include "exec/helper-proto.h" #include "exec/exec-all.h" diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c index 7ea90d414a..33e6999e15 100644 --- a/target/s390x/misc_helper.c +++ b/target/s390x/misc_helper.c @@ -22,7 +22,7 @@ #include "qemu/cutils.h" #include "qemu/main-loop.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "exec/memory.h" #include "qemu/host-utils.h" #include "exec/helper-proto.h" diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c index d492b23a17..52fdd86c63 100644 --- a/target/s390x/mmu_helper.c +++ b/target/s390x/mmu_helper.c @@ -19,7 +19,7 @@ #include "qemu/error-report.h" #include "exec/address-spaces.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "kvm_s390x.h" #include "sysemu/kvm.h" #include "sysemu/tcg.h" diff --git a/target/s390x/internal.h b/target/s390x/s390x-internal.h similarity index 100% rename from target/s390x/internal.h rename to target/s390x/s390x-internal.h diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c index c2d5cdf061..d57427ced8 100644 --- a/target/s390x/sigp.c +++ b/target/s390x/sigp.c @@ -10,7 +10,7 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "sysemu/hw_accel.h" #include "sysemu/runstate.h" #include "exec/address-spaces.h" diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 71ae3f333e..e14eab5794 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -30,7 +30,7 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "disas/disas.h" #include "exec/exec-all.h" #include "tcg/tcg-op.h" diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c index 8e2b274547..1a77993471 100644 --- a/target/s390x/vec_fpu_helper.c +++ b/target/s390x/vec_fpu_helper.c @@ -12,7 +12,7 @@ #include "qemu/osdep.h" #include "qemu-common.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "vec.h" #include "tcg_s390x.h" #include "tcg/tcg-gvec-desc.h" diff --git a/target/s390x/vec_helper.c b/target/s390x/vec_helper.c index 599bab06bd..ededf13cf0 100644 --- a/target/s390x/vec_helper.c +++ b/target/s390x/vec_helper.c @@ -11,7 +11,7 @@ */ #include "qemu/osdep.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "vec.h" #include "tcg/tcg.h" #include "tcg/tcg-gvec-desc.h" diff --git a/target/s390x/vec_string_helper.c b/target/s390x/vec_string_helper.c index c516c0ceeb..ac315eb095 100644 --- a/target/s390x/vec_string_helper.c +++ b/target/s390x/vec_string_helper.c @@ -12,7 +12,7 @@ #include "qemu/osdep.h" #include "qemu-common.h" #include "cpu.h" -#include "internal.h" +#include "s390x-internal.h" #include "vec.h" #include "tcg/tcg.h" #include "tcg/tcg-gvec-desc.h" From c9274b6bf0571ecbaaed3e9c3b229e17607a0ea2 Mon Sep 17 00:00:00 2001 From: "Cho, Yu-Chen" Date: Wed, 7 Jul 2021 18:53:17 +0800 Subject: [PATCH 10/17] target/s390x: start moving TCG-only code to tcg/ move everything related to translate, as well as HELPER code in tcg/ mmu_helper.c stays put for now, as it contains both TCG and KVM code. After the reshuffling, update MAINTAINERS accordingly. Make use of the new directory: target/s390x/tcg/ Signed-off-by: Claudio Fontana Signed-off-by: Cho, Yu-Chen Acked-by: David Hildenbrand Acked-by: Cornelia Huck Reviewed-by: Thomas Huth Message-Id: <20210707105324.23400-8-acho@suse.com> Signed-off-by: Cornelia Huck --- MAINTAINERS | 1 + hw/s390x/tod-tcg.c | 2 +- include/hw/s390x/tod.h | 2 +- target/s390x/interrupt.c | 2 +- target/s390x/machine.c | 2 +- target/s390x/meson.build | 17 ++--------------- target/s390x/{ => tcg}/cc_helper.c | 0 target/s390x/{ => tcg}/crypto_helper.c | 0 target/s390x/{ => tcg}/excp_helper.c | 0 target/s390x/{ => tcg}/fpu_helper.c | 0 target/s390x/{ => tcg}/insn-data.def | 0 target/s390x/{ => tcg}/insn-format.def | 0 target/s390x/{ => tcg}/int_helper.c | 0 target/s390x/{ => tcg}/mem_helper.c | 0 target/s390x/tcg/meson.build | 14 ++++++++++++++ target/s390x/{ => tcg}/misc_helper.c | 0 target/s390x/{ => tcg}/s390-tod.h | 0 target/s390x/{ => tcg}/tcg_s390x.h | 0 target/s390x/{ => tcg}/translate.c | 0 target/s390x/{ => tcg}/translate_vx.c.inc | 0 target/s390x/{ => tcg}/vec.h | 0 target/s390x/{ => tcg}/vec_fpu_helper.c | 0 target/s390x/{ => tcg}/vec_helper.c | 0 target/s390x/{ => tcg}/vec_int_helper.c | 0 target/s390x/{ => tcg}/vec_string_helper.c | 0 25 files changed, 21 insertions(+), 19 deletions(-) rename target/s390x/{ => tcg}/cc_helper.c (100%) rename target/s390x/{ => tcg}/crypto_helper.c (100%) rename target/s390x/{ => tcg}/excp_helper.c (100%) rename target/s390x/{ => tcg}/fpu_helper.c (100%) rename target/s390x/{ => tcg}/insn-data.def (100%) rename target/s390x/{ => tcg}/insn-format.def (100%) rename target/s390x/{ => tcg}/int_helper.c (100%) rename target/s390x/{ => tcg}/mem_helper.c (100%) create mode 100644 target/s390x/tcg/meson.build rename target/s390x/{ => tcg}/misc_helper.c (100%) rename target/s390x/{ => tcg}/s390-tod.h (100%) rename target/s390x/{ => tcg}/tcg_s390x.h (100%) rename target/s390x/{ => tcg}/translate.c (100%) rename target/s390x/{ => tcg}/translate_vx.c.inc (100%) rename target/s390x/{ => tcg}/vec.h (100%) rename target/s390x/{ => tcg}/vec_fpu_helper.c (100%) rename target/s390x/{ => tcg}/vec_helper.c (100%) rename target/s390x/{ => tcg}/vec_int_helper.c (100%) rename target/s390x/{ => tcg}/vec_string_helper.c (100%) diff --git a/MAINTAINERS b/MAINTAINERS index 684142e12e..8ec845f4e0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -297,6 +297,7 @@ M: Richard Henderson M: David Hildenbrand S: Maintained F: target/s390x/ +F: target/s390x/tcg F: hw/s390x/ F: disas/s390.c F: tests/tcg/s390x/ diff --git a/hw/s390x/tod-tcg.c b/hw/s390x/tod-tcg.c index aa44deb809..9bb94ff72b 100644 --- a/hw/s390x/tod-tcg.c +++ b/hw/s390x/tod-tcg.c @@ -16,7 +16,7 @@ #include "qemu/cutils.h" #include "qemu/module.h" #include "cpu.h" -#include "tcg_s390x.h" +#include "tcg/tcg_s390x.h" static void qemu_s390_tod_get(const S390TODState *td, S390TOD *tod, Error **errp) diff --git a/include/hw/s390x/tod.h b/include/hw/s390x/tod.h index ff3195a4bf..0935e85089 100644 --- a/include/hw/s390x/tod.h +++ b/include/hw/s390x/tod.h @@ -12,7 +12,7 @@ #define HW_S390_TOD_H #include "hw/qdev-core.h" -#include "target/s390x/s390-tod.h" +#include "tcg/s390-tod.h" #include "qom/object.h" typedef struct S390TOD { diff --git a/target/s390x/interrupt.c b/target/s390x/interrupt.c index 3fde18ba46..734f0c62de 100644 --- a/target/s390x/interrupt.c +++ b/target/s390x/interrupt.c @@ -15,7 +15,7 @@ #include "sysemu/kvm.h" #include "sysemu/tcg.h" #include "hw/s390x/ioinst.h" -#include "tcg_s390x.h" +#include "tcg/tcg_s390x.h" #if !defined(CONFIG_USER_ONLY) #include "hw/s390x/s390_flic.h" #endif diff --git a/target/s390x/machine.c b/target/s390x/machine.c index 4f11f6ac6e..81a8a7ff99 100644 --- a/target/s390x/machine.c +++ b/target/s390x/machine.c @@ -19,7 +19,7 @@ #include "s390x-internal.h" #include "kvm_s390x.h" #include "migration/vmstate.h" -#include "tcg_s390x.h" +#include "tcg/tcg_s390x.h" #include "sysemu/kvm.h" #include "sysemu/tcg.h" diff --git a/target/s390x/meson.build b/target/s390x/meson.build index a5e1ded93f..60d7f1b908 100644 --- a/target/s390x/meson.build +++ b/target/s390x/meson.build @@ -8,21 +8,6 @@ s390x_ss.add(files( 'interrupt.c', )) -s390x_ss.add(when: 'CONFIG_TCG', if_true: files( - 'cc_helper.c', - 'crypto_helper.c', - 'excp_helper.c', - 'fpu_helper.c', - 'int_helper.c', - 'mem_helper.c', - 'misc_helper.c', - 'translate.c', - 'vec_fpu_helper.c', - 'vec_helper.c', - 'vec_int_helper.c', - 'vec_string_helper.c', -)) - s390x_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c')) gen_features = executable('gen-features', 'gen-features.c', native: true, @@ -60,6 +45,8 @@ endif s390x_user_ss = ss.source_set() +subdir('tcg') + target_arch += {'s390x': s390x_ss} target_softmmu_arch += {'s390x': s390x_softmmu_ss} target_user_arch += {'s390x': s390x_user_ss} diff --git a/target/s390x/cc_helper.c b/target/s390x/tcg/cc_helper.c similarity index 100% rename from target/s390x/cc_helper.c rename to target/s390x/tcg/cc_helper.c diff --git a/target/s390x/crypto_helper.c b/target/s390x/tcg/crypto_helper.c similarity index 100% rename from target/s390x/crypto_helper.c rename to target/s390x/tcg/crypto_helper.c diff --git a/target/s390x/excp_helper.c b/target/s390x/tcg/excp_helper.c similarity index 100% rename from target/s390x/excp_helper.c rename to target/s390x/tcg/excp_helper.c diff --git a/target/s390x/fpu_helper.c b/target/s390x/tcg/fpu_helper.c similarity index 100% rename from target/s390x/fpu_helper.c rename to target/s390x/tcg/fpu_helper.c diff --git a/target/s390x/insn-data.def b/target/s390x/tcg/insn-data.def similarity index 100% rename from target/s390x/insn-data.def rename to target/s390x/tcg/insn-data.def diff --git a/target/s390x/insn-format.def b/target/s390x/tcg/insn-format.def similarity index 100% rename from target/s390x/insn-format.def rename to target/s390x/tcg/insn-format.def diff --git a/target/s390x/int_helper.c b/target/s390x/tcg/int_helper.c similarity index 100% rename from target/s390x/int_helper.c rename to target/s390x/tcg/int_helper.c diff --git a/target/s390x/mem_helper.c b/target/s390x/tcg/mem_helper.c similarity index 100% rename from target/s390x/mem_helper.c rename to target/s390x/tcg/mem_helper.c diff --git a/target/s390x/tcg/meson.build b/target/s390x/tcg/meson.build new file mode 100644 index 0000000000..ee4e8fec77 --- /dev/null +++ b/target/s390x/tcg/meson.build @@ -0,0 +1,14 @@ +s390x_ss.add(when: 'CONFIG_TCG', if_true: files( + 'cc_helper.c', + 'crypto_helper.c', + 'excp_helper.c', + 'fpu_helper.c', + 'int_helper.c', + 'mem_helper.c', + 'misc_helper.c', + 'translate.c', + 'vec_fpu_helper.c', + 'vec_helper.c', + 'vec_int_helper.c', + 'vec_string_helper.c', +)) diff --git a/target/s390x/misc_helper.c b/target/s390x/tcg/misc_helper.c similarity index 100% rename from target/s390x/misc_helper.c rename to target/s390x/tcg/misc_helper.c diff --git a/target/s390x/s390-tod.h b/target/s390x/tcg/s390-tod.h similarity index 100% rename from target/s390x/s390-tod.h rename to target/s390x/tcg/s390-tod.h diff --git a/target/s390x/tcg_s390x.h b/target/s390x/tcg/tcg_s390x.h similarity index 100% rename from target/s390x/tcg_s390x.h rename to target/s390x/tcg/tcg_s390x.h diff --git a/target/s390x/translate.c b/target/s390x/tcg/translate.c similarity index 100% rename from target/s390x/translate.c rename to target/s390x/tcg/translate.c diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/tcg/translate_vx.c.inc similarity index 100% rename from target/s390x/translate_vx.c.inc rename to target/s390x/tcg/translate_vx.c.inc diff --git a/target/s390x/vec.h b/target/s390x/tcg/vec.h similarity index 100% rename from target/s390x/vec.h rename to target/s390x/tcg/vec.h diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/tcg/vec_fpu_helper.c similarity index 100% rename from target/s390x/vec_fpu_helper.c rename to target/s390x/tcg/vec_fpu_helper.c diff --git a/target/s390x/vec_helper.c b/target/s390x/tcg/vec_helper.c similarity index 100% rename from target/s390x/vec_helper.c rename to target/s390x/tcg/vec_helper.c diff --git a/target/s390x/vec_int_helper.c b/target/s390x/tcg/vec_int_helper.c similarity index 100% rename from target/s390x/vec_int_helper.c rename to target/s390x/tcg/vec_int_helper.c diff --git a/target/s390x/vec_string_helper.c b/target/s390x/tcg/vec_string_helper.c similarity index 100% rename from target/s390x/vec_string_helper.c rename to target/s390x/tcg/vec_string_helper.c From 72ffb6310baab625958fa39155d98cce6a3bb235 Mon Sep 17 00:00:00 2001 From: "Cho, Yu-Chen" Date: Wed, 7 Jul 2021 18:53:18 +0800 Subject: [PATCH 11/17] target/s390x: move sysemu-only code out to cpu-sysemu.c move sysemu-only code out to cpu-sysemu.c Signed-off-by: Claudio Fontana Signed-off-by: Cho, Yu-Chen Acked-by: Cornelia Huck Reviewed-by: Thomas Huth Message-Id: <20210707105324.23400-9-acho@suse.com> Signed-off-by: Cornelia Huck --- target/s390x/cpu-sysemu.c | 309 ++++++++++++++++++++++++++++++++++ target/s390x/cpu.c | 287 ++----------------------------- target/s390x/meson.build | 1 + target/s390x/s390x-internal.h | 6 + target/s390x/trace-events | 2 +- 5 files changed, 327 insertions(+), 278 deletions(-) create mode 100644 target/s390x/cpu-sysemu.c diff --git a/target/s390x/cpu-sysemu.c b/target/s390x/cpu-sysemu.c new file mode 100644 index 0000000000..16e5301084 --- /dev/null +++ b/target/s390x/cpu-sysemu.c @@ -0,0 +1,309 @@ +/* + * QEMU S/390 CPU - System Emulation-only code + * + * Copyright (c) 2009 Ulrich Hecht + * Copyright (c) 2011 Alexander Graf + * Copyright (c) 2012 SUSE LINUX Products GmbH + * Copyright (c) 2012 IBM Corp. + * + * 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 "qapi/error.h" +#include "cpu.h" +#include "s390x-internal.h" +#include "kvm_s390x.h" +#include "sysemu/kvm.h" +#include "sysemu/reset.h" +#include "qemu/timer.h" +#include "trace.h" +#include "qapi/qapi-visit-run-state.h" +#include "sysemu/hw_accel.h" + +#include "hw/s390x/pv.h" +#include "hw/boards.h" +#include "sysemu/arch_init.h" +#include "sysemu/sysemu.h" +#include "sysemu/tcg.h" +#include "hw/core/sysemu-cpu-ops.h" + +/* S390CPUClass::load_normal() */ +static void s390_cpu_load_normal(CPUState *s) +{ + S390CPU *cpu = S390_CPU(s); + uint64_t spsw; + + if (!s390_is_pv()) { + spsw = ldq_phys(s->as, 0); + cpu->env.psw.mask = spsw & PSW_MASK_SHORT_CTRL; + /* + * Invert short psw indication, so SIE will report a specification + * exception if it was not set. + */ + cpu->env.psw.mask ^= PSW_MASK_SHORTPSW; + cpu->env.psw.addr = spsw & PSW_MASK_SHORT_ADDR; + } else { + /* + * Firmware requires us to set the load state before we set + * the cpu to operating on protected guests. + */ + s390_cpu_set_state(S390_CPU_STATE_LOAD, cpu); + } + s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu); +} + +void s390_cpu_machine_reset_cb(void *opaque) +{ + S390CPU *cpu = opaque; + + run_on_cpu(CPU(cpu), s390_do_cpu_full_reset, RUN_ON_CPU_NULL); +} + +static GuestPanicInformation *s390_cpu_get_crash_info(CPUState *cs) +{ + GuestPanicInformation *panic_info; + S390CPU *cpu = S390_CPU(cs); + + cpu_synchronize_state(cs); + panic_info = g_malloc0(sizeof(GuestPanicInformation)); + + panic_info->type = GUEST_PANIC_INFORMATION_TYPE_S390; + panic_info->u.s390.core = cpu->env.core_id; + panic_info->u.s390.psw_mask = cpu->env.psw.mask; + panic_info->u.s390.psw_addr = cpu->env.psw.addr; + panic_info->u.s390.reason = cpu->env.crash_reason; + + return panic_info; +} + +static void s390_cpu_get_crash_info_qom(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + CPUState *cs = CPU(obj); + GuestPanicInformation *panic_info; + + if (!cs->crash_occurred) { + error_setg(errp, "No crash occurred"); + return; + } + + panic_info = s390_cpu_get_crash_info(cs); + + visit_type_GuestPanicInformation(v, "crash-information", &panic_info, + errp); + qapi_free_GuestPanicInformation(panic_info); +} + +void s390_cpu_init_sysemu(Object *obj) +{ + CPUState *cs = CPU(obj); + S390CPU *cpu = S390_CPU(obj); + + cs->start_powered_off = true; + object_property_add(obj, "crash-information", "GuestPanicInformation", + s390_cpu_get_crash_info_qom, NULL, NULL, NULL); + cpu->env.tod_timer = + timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_tod_timer, cpu); + cpu->env.cpu_timer = + timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_cpu_timer, cpu); + s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu); +} + +bool s390_cpu_realize_sysemu(DeviceState *dev, Error **errp) +{ + S390CPU *cpu = S390_CPU(dev); + MachineState *ms = MACHINE(qdev_get_machine()); + unsigned int max_cpus = ms->smp.max_cpus; + + if (cpu->env.core_id >= max_cpus) { + error_setg(errp, "Unable to add CPU with core-id: %" PRIu32 + ", maximum core-id: %d", cpu->env.core_id, + max_cpus - 1); + return false; + } + + if (cpu_exists(cpu->env.core_id)) { + error_setg(errp, "Unable to add CPU with core-id: %" PRIu32 + ", it already exists", cpu->env.core_id); + return false; + } + + /* sync cs->cpu_index and env->core_id. The latter is needed for TCG. */ + CPU(cpu)->cpu_index = cpu->env.core_id; + return true; +} + +void s390_cpu_finalize(Object *obj) +{ + S390CPU *cpu = S390_CPU(obj); + + timer_free(cpu->env.tod_timer); + timer_free(cpu->env.cpu_timer); + + qemu_unregister_reset(s390_cpu_machine_reset_cb, cpu); + g_free(cpu->irqstate); +} + +static const struct SysemuCPUOps s390_sysemu_ops = { + .get_phys_page_debug = s390_cpu_get_phys_page_debug, + .get_crash_info = s390_cpu_get_crash_info, + .write_elf64_note = s390_cpu_write_elf64_note, + .legacy_vmsd = &vmstate_s390_cpu, +}; + +void s390_cpu_class_init_sysemu(CPUClass *cc) +{ + S390CPUClass *scc = S390_CPU_CLASS(cc); + + scc->load_normal = s390_cpu_load_normal; + cc->sysemu_ops = &s390_sysemu_ops; +} + +static bool disabled_wait(CPUState *cpu) +{ + return cpu->halted && !(S390_CPU(cpu)->env.psw.mask & + (PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK)); +} + +static unsigned s390_count_running_cpus(void) +{ + CPUState *cpu; + int nr_running = 0; + + CPU_FOREACH(cpu) { + uint8_t state = S390_CPU(cpu)->env.cpu_state; + if (state == S390_CPU_STATE_OPERATING || + state == S390_CPU_STATE_LOAD) { + if (!disabled_wait(cpu)) { + nr_running++; + } + } + } + + return nr_running; +} + +unsigned int s390_cpu_halt(S390CPU *cpu) +{ + CPUState *cs = CPU(cpu); + trace_cpu_halt(cs->cpu_index); + + if (!cs->halted) { + cs->halted = 1; + cs->exception_index = EXCP_HLT; + } + + return s390_count_running_cpus(); +} + +void s390_cpu_unhalt(S390CPU *cpu) +{ + CPUState *cs = CPU(cpu); + trace_cpu_unhalt(cs->cpu_index); + + if (cs->halted) { + cs->halted = 0; + cs->exception_index = -1; + } +} + +unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu) + { + trace_cpu_set_state(CPU(cpu)->cpu_index, cpu_state); + + switch (cpu_state) { + case S390_CPU_STATE_STOPPED: + case S390_CPU_STATE_CHECK_STOP: + /* halt the cpu for common infrastructure */ + s390_cpu_halt(cpu); + break; + case S390_CPU_STATE_OPERATING: + case S390_CPU_STATE_LOAD: + /* + * Starting a CPU with a PSW WAIT bit set: + * KVM: handles this internally and triggers another WAIT exit. + * TCG: will actually try to continue to run. Don't unhalt, will + * be done when the CPU actually has work (an interrupt). + */ + if (!tcg_enabled() || !(cpu->env.psw.mask & PSW_MASK_WAIT)) { + s390_cpu_unhalt(cpu); + } + break; + default: + error_report("Requested CPU state is not a valid S390 CPU state: %u", + cpu_state); + exit(1); + } + if (kvm_enabled() && cpu->env.cpu_state != cpu_state) { + kvm_s390_set_cpu_state(cpu, cpu_state); + } + cpu->env.cpu_state = cpu_state; + + return s390_count_running_cpus(); +} + +int s390_set_memory_limit(uint64_t new_limit, uint64_t *hw_limit) +{ + if (kvm_enabled()) { + return kvm_s390_set_mem_limit(new_limit, hw_limit); + } + return 0; +} + +void s390_set_max_pagesize(uint64_t pagesize, Error **errp) +{ + if (kvm_enabled()) { + kvm_s390_set_max_pagesize(pagesize, errp); + } +} + +void s390_cmma_reset(void) +{ + if (kvm_enabled()) { + kvm_s390_cmma_reset(); + } +} + +int s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch_id, + int vq, bool assign) +{ + if (kvm_enabled()) { + return kvm_s390_assign_subch_ioeventfd(notifier, sch_id, vq, assign); + } else { + return 0; + } +} + +void s390_crypto_reset(void) +{ + if (kvm_enabled()) { + kvm_s390_crypto_reset(); + } +} + +void s390_enable_css_support(S390CPU *cpu) +{ + if (kvm_enabled()) { + kvm_s390_enable_css_support(cpu); + } +} + +void s390_do_cpu_set_diag318(CPUState *cs, run_on_cpu_data arg) +{ + if (kvm_enabled()) { + kvm_s390_set_diag318(cs, arg.host_ulong); + } +} diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c index 1795042e97..2b2b70e1c6 100644 --- a/target/s390x/cpu.c +++ b/target/s390x/cpu.c @@ -27,21 +27,11 @@ #include "kvm_s390x.h" #include "sysemu/kvm.h" #include "sysemu/reset.h" -#include "qemu/timer.h" -#include "qemu/error-report.h" #include "qemu/module.h" #include "trace.h" -#include "qapi/visitor.h" #include "qapi/qapi-types-machine.h" -#include "qapi/qapi-visit-run-state.h" #include "sysemu/hw_accel.h" #include "hw/qdev-properties.h" -#ifndef CONFIG_USER_ONLY -#include "hw/s390x/pv.h" -#include "hw/boards.h" -#include "sysemu/arch_init.h" -#include "sysemu/tcg.h" -#endif #include "fpu/softfloat-helpers.h" #include "disas/capstone.h" @@ -72,33 +62,6 @@ static bool s390_cpu_has_work(CPUState *cs) return s390_cpu_has_int(cpu); } -#if !defined(CONFIG_USER_ONLY) -/* S390CPUClass::load_normal() */ -static void s390_cpu_load_normal(CPUState *s) -{ - S390CPU *cpu = S390_CPU(s); - uint64_t spsw; - - if (!s390_is_pv()) { - spsw = ldq_phys(s->as, 0); - cpu->env.psw.mask = spsw & PSW_MASK_SHORT_CTRL; - /* - * Invert short psw indication, so SIE will report a specification - * exception if it was not set. - */ - cpu->env.psw.mask ^= PSW_MASK_SHORTPSW; - cpu->env.psw.addr = spsw & PSW_MASK_SHORT_ADDR; - } else { - /* - * Firmware requires us to set the load state before we set - * the cpu to operating on protected guests. - */ - s390_cpu_set_state(S390_CPU_STATE_LOAD, cpu); - } - s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu); -} -#endif - /* S390CPUClass::reset() */ static void s390_cpu_reset(CPUState *s, cpu_reset_type type) { @@ -169,15 +132,6 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type) } } -#if !defined(CONFIG_USER_ONLY) -static void s390_cpu_machine_reset_cb(void *opaque) -{ - S390CPU *cpu = opaque; - - run_on_cpu(CPU(cpu), s390_do_cpu_full_reset, RUN_ON_CPU_NULL); -} -#endif - static void s390_cpu_disas_set_info(CPUState *cpu, disassemble_info *info) { info->mach = bfd_mach_s390_64; @@ -191,9 +145,6 @@ static void s390_cpu_realizefn(DeviceState *dev, Error **errp) { CPUState *cs = CPU(dev); S390CPUClass *scc = S390_CPU_GET_CLASS(dev); -#if !defined(CONFIG_USER_ONLY) - S390CPU *cpu = S390_CPU(dev); -#endif Error *err = NULL; /* the model has to be realized before qemu_init_vcpu() due to kvm */ @@ -203,23 +154,9 @@ static void s390_cpu_realizefn(DeviceState *dev, Error **errp) } #if !defined(CONFIG_USER_ONLY) - MachineState *ms = MACHINE(qdev_get_machine()); - unsigned int max_cpus = ms->smp.max_cpus; - if (cpu->env.core_id >= max_cpus) { - error_setg(&err, "Unable to add CPU with core-id: %" PRIu32 - ", maximum core-id: %d", cpu->env.core_id, - max_cpus - 1); + if (!s390_cpu_realize_sysemu(dev, &err)) { goto out; } - - if (cpu_exists(cpu->env.core_id)) { - error_setg(&err, "Unable to add CPU with core-id: %" PRIu32 - ", it already exists", cpu->env.core_id); - goto out; - } - - /* sync cs->cpu_index and env->core_id. The latter is needed for TCG. */ - cs->cpu_index = cpu->env.core_id; #endif cpu_exec_realizefn(cs, &err); @@ -228,7 +165,7 @@ static void s390_cpu_realizefn(DeviceState *dev, Error **errp) } #if !defined(CONFIG_USER_ONLY) - qemu_register_reset(s390_cpu_machine_reset_cb, cpu); + qemu_register_reset(s390_cpu_machine_reset_cb, S390_CPU(dev)); #endif s390_cpu_gdb_init(cs); qemu_init_vcpu(cs); @@ -250,44 +187,6 @@ out: error_propagate(errp, err); } -#if !defined(CONFIG_USER_ONLY) -static GuestPanicInformation *s390_cpu_get_crash_info(CPUState *cs) -{ - GuestPanicInformation *panic_info; - S390CPU *cpu = S390_CPU(cs); - - cpu_synchronize_state(cs); - panic_info = g_malloc0(sizeof(GuestPanicInformation)); - - panic_info->type = GUEST_PANIC_INFORMATION_TYPE_S390; - panic_info->u.s390.core = cpu->env.core_id; - panic_info->u.s390.psw_mask = cpu->env.psw.mask; - panic_info->u.s390.psw_addr = cpu->env.psw.addr; - panic_info->u.s390.reason = cpu->env.crash_reason; - - return panic_info; -} - -static void s390_cpu_get_crash_info_qom(Object *obj, Visitor *v, - const char *name, void *opaque, - Error **errp) -{ - CPUState *cs = CPU(obj); - GuestPanicInformation *panic_info; - - if (!cs->crash_occurred) { - error_setg(errp, "No crash occurred"); - return; - } - - panic_info = s390_cpu_get_crash_info(cs); - - visit_type_GuestPanicInformation(v, "crash-information", &panic_info, - errp); - qapi_free_GuestPanicInformation(panic_info); -} -#endif - static void s390_cpu_initfn(Object *obj) { CPUState *cs = CPU(obj); @@ -295,168 +194,11 @@ static void s390_cpu_initfn(Object *obj) cpu_set_cpustate_pointers(cpu); cs->exception_index = EXCP_HLT; -#if !defined(CONFIG_USER_ONLY) - cs->start_powered_off = true; - object_property_add(obj, "crash-information", "GuestPanicInformation", - s390_cpu_get_crash_info_qom, NULL, NULL, NULL); - cpu->env.tod_timer = - timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_tod_timer, cpu); - cpu->env.cpu_timer = - timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_cpu_timer, cpu); - s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu); -#endif -} - -static void s390_cpu_finalize(Object *obj) -{ -#if !defined(CONFIG_USER_ONLY) - S390CPU *cpu = S390_CPU(obj); - - timer_free(cpu->env.tod_timer); - timer_free(cpu->env.cpu_timer); - - qemu_unregister_reset(s390_cpu_machine_reset_cb, cpu); - g_free(cpu->irqstate); -#endif -} #if !defined(CONFIG_USER_ONLY) -static bool disabled_wait(CPUState *cpu) -{ - return cpu->halted && !(S390_CPU(cpu)->env.psw.mask & - (PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK)); -} - -static unsigned s390_count_running_cpus(void) -{ - CPUState *cpu; - int nr_running = 0; - - CPU_FOREACH(cpu) { - uint8_t state = S390_CPU(cpu)->env.cpu_state; - if (state == S390_CPU_STATE_OPERATING || - state == S390_CPU_STATE_LOAD) { - if (!disabled_wait(cpu)) { - nr_running++; - } - } - } - - return nr_running; -} - -unsigned int s390_cpu_halt(S390CPU *cpu) -{ - CPUState *cs = CPU(cpu); - trace_cpu_halt(cs->cpu_index); - - if (!cs->halted) { - cs->halted = 1; - cs->exception_index = EXCP_HLT; - } - - return s390_count_running_cpus(); -} - -void s390_cpu_unhalt(S390CPU *cpu) -{ - CPUState *cs = CPU(cpu); - trace_cpu_unhalt(cs->cpu_index); - - if (cs->halted) { - cs->halted = 0; - cs->exception_index = -1; - } -} - -unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu) - { - trace_cpu_set_state(CPU(cpu)->cpu_index, cpu_state); - - switch (cpu_state) { - case S390_CPU_STATE_STOPPED: - case S390_CPU_STATE_CHECK_STOP: - /* halt the cpu for common infrastructure */ - s390_cpu_halt(cpu); - break; - case S390_CPU_STATE_OPERATING: - case S390_CPU_STATE_LOAD: - /* - * Starting a CPU with a PSW WAIT bit set: - * KVM: handles this internally and triggers another WAIT exit. - * TCG: will actually try to continue to run. Don't unhalt, will - * be done when the CPU actually has work (an interrupt). - */ - if (!tcg_enabled() || !(cpu->env.psw.mask & PSW_MASK_WAIT)) { - s390_cpu_unhalt(cpu); - } - break; - default: - error_report("Requested CPU state is not a valid S390 CPU state: %u", - cpu_state); - exit(1); - } - if (kvm_enabled() && cpu->env.cpu_state != cpu_state) { - kvm_s390_set_cpu_state(cpu, cpu_state); - } - cpu->env.cpu_state = cpu_state; - - return s390_count_running_cpus(); -} - -int s390_set_memory_limit(uint64_t new_limit, uint64_t *hw_limit) -{ - if (kvm_enabled()) { - return kvm_s390_set_mem_limit(new_limit, hw_limit); - } - return 0; -} - -void s390_set_max_pagesize(uint64_t pagesize, Error **errp) -{ - if (kvm_enabled()) { - kvm_s390_set_max_pagesize(pagesize, errp); - } -} - -void s390_cmma_reset(void) -{ - if (kvm_enabled()) { - kvm_s390_cmma_reset(); - } -} - -int s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch_id, - int vq, bool assign) -{ - if (kvm_enabled()) { - return kvm_s390_assign_subch_ioeventfd(notifier, sch_id, vq, assign); - } else { - return 0; - } -} - -void s390_crypto_reset(void) -{ - if (kvm_enabled()) { - kvm_s390_crypto_reset(); - } -} - -void s390_enable_css_support(S390CPU *cpu) -{ - if (kvm_enabled()) { - kvm_s390_enable_css_support(cpu); - } -} - -void s390_do_cpu_set_diag318(CPUState *cs, run_on_cpu_data arg) -{ - if (kvm_enabled()) { - kvm_s390_set_diag318(cs, arg.host_ulong); - } -} + s390_cpu_init_sysemu(obj); #endif +} static gchar *s390_gdb_arch_name(CPUState *cs) { @@ -476,17 +218,6 @@ static void s390_cpu_reset_full(DeviceState *dev) return s390_cpu_reset(s, S390_CPU_RESET_CLEAR); } -#ifndef CONFIG_USER_ONLY -#include "hw/core/sysemu-cpu-ops.h" - -static const struct SysemuCPUOps s390_sysemu_ops = { - .get_phys_page_debug = s390_cpu_get_phys_page_debug, - .get_crash_info = s390_cpu_get_crash_info, - .write_elf64_note = s390_cpu_write_elf64_note, - .legacy_vmsd = &vmstate_s390_cpu, -}; -#endif - #ifdef CONFIG_TCG #include "hw/core/tcg-cpu-ops.h" @@ -515,9 +246,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data) dc->user_creatable = true; device_class_set_parent_reset(dc, s390_cpu_reset_full, &scc->parent_reset); -#if !defined(CONFIG_USER_ONLY) - scc->load_normal = s390_cpu_load_normal; -#endif + scc->reset = s390_cpu_reset; cc->class_by_name = s390_cpu_class_by_name, cc->has_work = s390_cpu_has_work; @@ -526,7 +255,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data) cc->gdb_read_register = s390_cpu_gdb_read_register; cc->gdb_write_register = s390_cpu_gdb_write_register; #ifndef CONFIG_USER_ONLY - cc->sysemu_ops = &s390_sysemu_ops; + s390_cpu_class_init_sysemu(cc); #endif cc->disas_set_info = s390_cpu_disas_set_info; cc->gdb_num_core_regs = S390_NUM_CORE_REGS; @@ -546,7 +275,11 @@ static const TypeInfo s390_cpu_type_info = { .instance_size = sizeof(S390CPU), .instance_align = __alignof__(S390CPU), .instance_init = s390_cpu_initfn, + +#ifndef CONFIG_USER_ONLY .instance_finalize = s390_cpu_finalize, +#endif /* !CONFIG_USER_ONLY */ + .abstract = true, .class_size = sizeof(S390CPUClass), .class_init = s390_cpu_class_init, diff --git a/target/s390x/meson.build b/target/s390x/meson.build index 60d7f1b908..a73bae3dc5 100644 --- a/target/s390x/meson.build +++ b/target/s390x/meson.build @@ -28,6 +28,7 @@ s390x_softmmu_ss.add(files( 'machine.c', 'mmu_helper.c', 'sigp.c', + 'cpu-sysemu.c', )) # Newer kernels on s390 check for an S390_PGSTE program header and diff --git a/target/s390x/s390x-internal.h b/target/s390x/s390x-internal.h index 9256275376..17edd4d13b 100644 --- a/target/s390x/s390x-internal.h +++ b/target/s390x/s390x-internal.h @@ -240,6 +240,12 @@ uint32_t calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src, uint64_t dst, #ifndef CONFIG_USER_ONLY unsigned int s390_cpu_halt(S390CPU *cpu); void s390_cpu_unhalt(S390CPU *cpu); +void s390_cpu_init_sysemu(Object *obj); +bool s390_cpu_realize_sysemu(DeviceState *dev, Error **errp); +void s390_cpu_finalize(Object *obj); +void s390_cpu_class_init_sysemu(CPUClass *cc); +void s390_cpu_machine_reset_cb(void *opaque); + #else static inline unsigned int s390_cpu_halt(S390CPU *cpu) { diff --git a/target/s390x/trace-events b/target/s390x/trace-events index e661a81e3a..e83a8cf85e 100644 --- a/target/s390x/trace-events +++ b/target/s390x/trace-events @@ -16,7 +16,7 @@ kvm_clear_cmma(int rc) "CMMA: clearing with result code %d" kvm_failed_cpu_state_set(int cpu_index, uint8_t state, const char *msg) "Warning: Unable to set cpu %d state %" PRIu8 " to KVM: %s" kvm_assign_subch_ioeventfd(int fd, uint32_t addr, bool assign, int datamatch) "fd: %d sch: @0x%x assign: %d vq: %d" -# cpu.c +# cpu-sysemu.c cpu_set_state(int cpu_index, uint8_t state) "setting cpu %d state to %" PRIu8 cpu_halt(int cpu_index) "halting cpu %d" cpu_unhalt(int cpu_index) "unhalting cpu %d" From 98be64d2f4dd5ff66b16e3525ee7d099d82f5ec8 Mon Sep 17 00:00:00 2001 From: "Cho, Yu-Chen" Date: Wed, 7 Jul 2021 18:53:19 +0800 Subject: [PATCH 12/17] target/s390x: split cpu-dump from helper.c Splitting this functionality also allows us to make helper.c sysemu-only. Signed-off-by: Claudio Fontana Signed-off-by: Cho, Yu-Chen Acked-by: Cornelia Huck Reviewed-by: Thomas Huth Message-Id: <20210707105324.23400-10-acho@suse.com> Signed-off-by: Cornelia Huck --- target/s390x/cpu-dump.c | 134 ++++++++++++++++++++++++++++++++++ target/s390x/cpu.c | 43 +++++++++++ target/s390x/helper.c | 151 --------------------------------------- target/s390x/meson.build | 1 + 4 files changed, 178 insertions(+), 151 deletions(-) create mode 100644 target/s390x/cpu-dump.c diff --git a/target/s390x/cpu-dump.c b/target/s390x/cpu-dump.c new file mode 100644 index 0000000000..0f5c062994 --- /dev/null +++ b/target/s390x/cpu-dump.c @@ -0,0 +1,134 @@ +/* + * S/390 CPU dump to FILE + * + * Copyright (c) 2009 Ulrich Hecht + * Copyright (c) 2011 Alexander Graf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "s390x-internal.h" +#include "qemu/qemu-print.h" +#include "sysemu/tcg.h" + +void s390_cpu_dump_state(CPUState *cs, FILE *f, int flags) +{ + S390CPU *cpu = S390_CPU(cs); + CPUS390XState *env = &cpu->env; + int i; + + qemu_fprintf(f, "PSW=mask %016" PRIx64 " addr %016" PRIx64, + s390_cpu_get_psw_mask(env), env->psw.addr); + if (!tcg_enabled()) { + qemu_fprintf(f, "\n"); + } else if (env->cc_op > 3) { + qemu_fprintf(f, " cc %15s\n", cc_name(env->cc_op)); + } else { + qemu_fprintf(f, " cc %02x\n", env->cc_op); + } + + for (i = 0; i < 16; i++) { + qemu_fprintf(f, "R%02d=%016" PRIx64, i, env->regs[i]); + if ((i % 4) == 3) { + qemu_fprintf(f, "\n"); + } else { + qemu_fprintf(f, " "); + } + } + + if (flags & CPU_DUMP_FPU) { + if (s390_has_feat(S390_FEAT_VECTOR)) { + for (i = 0; i < 32; i++) { + qemu_fprintf(f, "V%02d=%016" PRIx64 "%016" PRIx64 "%c", + i, env->vregs[i][0], env->vregs[i][1], + i % 2 ? '\n' : ' '); + } + } else { + for (i = 0; i < 16; i++) { + qemu_fprintf(f, "F%02d=%016" PRIx64 "%c", + i, *get_freg(env, i), + (i % 4) == 3 ? '\n' : ' '); + } + } + } + +#ifndef CONFIG_USER_ONLY + for (i = 0; i < 16; i++) { + qemu_fprintf(f, "C%02d=%016" PRIx64, i, env->cregs[i]); + if ((i % 4) == 3) { + qemu_fprintf(f, "\n"); + } else { + qemu_fprintf(f, " "); + } + } +#endif + +#ifdef DEBUG_INLINE_BRANCHES + for (i = 0; i < CC_OP_MAX; i++) { + qemu_fprintf(f, " %15s = %10ld\t%10ld\n", cc_name(i), + inline_branch_miss[i], inline_branch_hit[i]); + } +#endif + + qemu_fprintf(f, "\n"); +} + +const char *cc_name(enum cc_op cc_op) +{ + static const char * const cc_names[] = { + [CC_OP_CONST0] = "CC_OP_CONST0", + [CC_OP_CONST1] = "CC_OP_CONST1", + [CC_OP_CONST2] = "CC_OP_CONST2", + [CC_OP_CONST3] = "CC_OP_CONST3", + [CC_OP_DYNAMIC] = "CC_OP_DYNAMIC", + [CC_OP_STATIC] = "CC_OP_STATIC", + [CC_OP_NZ] = "CC_OP_NZ", + [CC_OP_ADDU] = "CC_OP_ADDU", + [CC_OP_SUBU] = "CC_OP_SUBU", + [CC_OP_LTGT_32] = "CC_OP_LTGT_32", + [CC_OP_LTGT_64] = "CC_OP_LTGT_64", + [CC_OP_LTUGTU_32] = "CC_OP_LTUGTU_32", + [CC_OP_LTUGTU_64] = "CC_OP_LTUGTU_64", + [CC_OP_LTGT0_32] = "CC_OP_LTGT0_32", + [CC_OP_LTGT0_64] = "CC_OP_LTGT0_64", + [CC_OP_ADD_64] = "CC_OP_ADD_64", + [CC_OP_SUB_64] = "CC_OP_SUB_64", + [CC_OP_ABS_64] = "CC_OP_ABS_64", + [CC_OP_NABS_64] = "CC_OP_NABS_64", + [CC_OP_ADD_32] = "CC_OP_ADD_32", + [CC_OP_SUB_32] = "CC_OP_SUB_32", + [CC_OP_ABS_32] = "CC_OP_ABS_32", + [CC_OP_NABS_32] = "CC_OP_NABS_32", + [CC_OP_COMP_32] = "CC_OP_COMP_32", + [CC_OP_COMP_64] = "CC_OP_COMP_64", + [CC_OP_TM_32] = "CC_OP_TM_32", + [CC_OP_TM_64] = "CC_OP_TM_64", + [CC_OP_NZ_F32] = "CC_OP_NZ_F32", + [CC_OP_NZ_F64] = "CC_OP_NZ_F64", + [CC_OP_NZ_F128] = "CC_OP_NZ_F128", + [CC_OP_ICM] = "CC_OP_ICM", + [CC_OP_SLA_32] = "CC_OP_SLA_32", + [CC_OP_SLA_64] = "CC_OP_SLA_64", + [CC_OP_FLOGR] = "CC_OP_FLOGR", + [CC_OP_LCBB] = "CC_OP_LCBB", + [CC_OP_VC] = "CC_OP_VC", + [CC_OP_MULS_32] = "CC_OP_MULS_32", + [CC_OP_MULS_64] = "CC_OP_MULS_64", + }; + + return cc_names[cc_op]; +} diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c index 2b2b70e1c6..5c456f6014 100644 --- a/target/s390x/cpu.c +++ b/target/s390x/cpu.c @@ -34,10 +34,53 @@ #include "hw/qdev-properties.h" #include "fpu/softfloat-helpers.h" #include "disas/capstone.h" +#include "sysemu/tcg.h" #define CR0_RESET 0xE0UL #define CR14_RESET 0xC2000000UL; +void s390_cpu_set_psw(CPUS390XState *env, uint64_t mask, uint64_t addr) +{ +#ifndef CONFIG_USER_ONLY + uint64_t old_mask = env->psw.mask; +#endif + + env->psw.addr = addr; + env->psw.mask = mask; + + /* KVM will handle all WAITs and trigger a WAIT exit on disabled_wait */ + if (!tcg_enabled()) { + return; + } + env->cc_op = (mask >> 44) & 3; + +#ifndef CONFIG_USER_ONLY + if ((old_mask ^ mask) & PSW_MASK_PER) { + s390_cpu_recompute_watchpoints(env_cpu(env)); + } + + if (mask & PSW_MASK_WAIT) { + s390_handle_wait(env_archcpu(env)); + } +#endif +} + +uint64_t s390_cpu_get_psw_mask(CPUS390XState *env) +{ + uint64_t r = env->psw.mask; + + if (tcg_enabled()) { + uint64_t cc = calc_cc(env, env->cc_op, env->cc_src, + env->cc_dst, env->cc_vr); + + assert(cc <= 3); + r &= ~PSW_MASK_CC; + r |= cc << 44; + } + + return r; +} + static void s390_cpu_set_pc(CPUState *cs, vaddr value) { S390CPU *cpu = S390_CPU(cs); diff --git a/target/s390x/helper.c b/target/s390x/helper.c index 8015c4e3d1..c72e990f4d 100644 --- a/target/s390x/helper.c +++ b/target/s390x/helper.c @@ -23,7 +23,6 @@ #include "s390x-internal.h" #include "exec/gdbstub.h" #include "qemu/timer.h" -#include "qemu/qemu-print.h" #include "hw/s390x/ioinst.h" #include "hw/s390x/pv.h" #include "sysemu/hw_accel.h" @@ -289,153 +288,3 @@ int s390_store_adtl_status(S390CPU *cpu, hwaddr addr, hwaddr len) /* For user-only, tcg is always enabled. */ #define tcg_enabled() true #endif /* CONFIG_USER_ONLY */ - -void s390_cpu_set_psw(CPUS390XState *env, uint64_t mask, uint64_t addr) -{ -#ifndef CONFIG_USER_ONLY - uint64_t old_mask = env->psw.mask; -#endif - - env->psw.addr = addr; - env->psw.mask = mask; - - /* KVM will handle all WAITs and trigger a WAIT exit on disabled_wait */ - if (!tcg_enabled()) { - return; - } - env->cc_op = (mask >> 44) & 3; - -#ifndef CONFIG_USER_ONLY - if ((old_mask ^ mask) & PSW_MASK_PER) { - s390_cpu_recompute_watchpoints(env_cpu(env)); - } - - if (mask & PSW_MASK_WAIT) { - s390_handle_wait(env_archcpu(env)); - } -#endif -} - -uint64_t s390_cpu_get_psw_mask(CPUS390XState *env) -{ - uint64_t r = env->psw.mask; - - if (tcg_enabled()) { - uint64_t cc = calc_cc(env, env->cc_op, env->cc_src, - env->cc_dst, env->cc_vr); - - assert(cc <= 3); - r &= ~PSW_MASK_CC; - r |= cc << 44; - } - - return r; -} - -void s390_cpu_dump_state(CPUState *cs, FILE *f, int flags) -{ - S390CPU *cpu = S390_CPU(cs); - CPUS390XState *env = &cpu->env; - int i; - - qemu_fprintf(f, "PSW=mask %016" PRIx64 " addr %016" PRIx64, - s390_cpu_get_psw_mask(env), env->psw.addr); - if (!tcg_enabled()) { - qemu_fprintf(f, "\n"); - } else if (env->cc_op > 3) { - qemu_fprintf(f, " cc %15s\n", cc_name(env->cc_op)); - } else { - qemu_fprintf(f, " cc %02x\n", env->cc_op); - } - - for (i = 0; i < 16; i++) { - qemu_fprintf(f, "R%02d=%016" PRIx64, i, env->regs[i]); - if ((i % 4) == 3) { - qemu_fprintf(f, "\n"); - } else { - qemu_fprintf(f, " "); - } - } - - if (flags & CPU_DUMP_FPU) { - if (s390_has_feat(S390_FEAT_VECTOR)) { - for (i = 0; i < 32; i++) { - qemu_fprintf(f, "V%02d=%016" PRIx64 "%016" PRIx64 "%c", - i, env->vregs[i][0], env->vregs[i][1], - i % 2 ? '\n' : ' '); - } - } else { - for (i = 0; i < 16; i++) { - qemu_fprintf(f, "F%02d=%016" PRIx64 "%c", - i, *get_freg(env, i), - (i % 4) == 3 ? '\n' : ' '); - } - } - } - -#ifndef CONFIG_USER_ONLY - for (i = 0; i < 16; i++) { - qemu_fprintf(f, "C%02d=%016" PRIx64, i, env->cregs[i]); - if ((i % 4) == 3) { - qemu_fprintf(f, "\n"); - } else { - qemu_fprintf(f, " "); - } - } -#endif - -#ifdef DEBUG_INLINE_BRANCHES - for (i = 0; i < CC_OP_MAX; i++) { - qemu_fprintf(f, " %15s = %10ld\t%10ld\n", cc_name(i), - inline_branch_miss[i], inline_branch_hit[i]); - } -#endif - - qemu_fprintf(f, "\n"); -} - -const char *cc_name(enum cc_op cc_op) -{ - static const char * const cc_names[] = { - [CC_OP_CONST0] = "CC_OP_CONST0", - [CC_OP_CONST1] = "CC_OP_CONST1", - [CC_OP_CONST2] = "CC_OP_CONST2", - [CC_OP_CONST3] = "CC_OP_CONST3", - [CC_OP_DYNAMIC] = "CC_OP_DYNAMIC", - [CC_OP_STATIC] = "CC_OP_STATIC", - [CC_OP_NZ] = "CC_OP_NZ", - [CC_OP_ADDU] = "CC_OP_ADDU", - [CC_OP_SUBU] = "CC_OP_SUBU", - [CC_OP_LTGT_32] = "CC_OP_LTGT_32", - [CC_OP_LTGT_64] = "CC_OP_LTGT_64", - [CC_OP_LTUGTU_32] = "CC_OP_LTUGTU_32", - [CC_OP_LTUGTU_64] = "CC_OP_LTUGTU_64", - [CC_OP_LTGT0_32] = "CC_OP_LTGT0_32", - [CC_OP_LTGT0_64] = "CC_OP_LTGT0_64", - [CC_OP_ADD_64] = "CC_OP_ADD_64", - [CC_OP_SUB_64] = "CC_OP_SUB_64", - [CC_OP_ABS_64] = "CC_OP_ABS_64", - [CC_OP_NABS_64] = "CC_OP_NABS_64", - [CC_OP_ADD_32] = "CC_OP_ADD_32", - [CC_OP_SUB_32] = "CC_OP_SUB_32", - [CC_OP_ABS_32] = "CC_OP_ABS_32", - [CC_OP_NABS_32] = "CC_OP_NABS_32", - [CC_OP_COMP_32] = "CC_OP_COMP_32", - [CC_OP_COMP_64] = "CC_OP_COMP_64", - [CC_OP_TM_32] = "CC_OP_TM_32", - [CC_OP_TM_64] = "CC_OP_TM_64", - [CC_OP_NZ_F32] = "CC_OP_NZ_F32", - [CC_OP_NZ_F64] = "CC_OP_NZ_F64", - [CC_OP_NZ_F128] = "CC_OP_NZ_F128", - [CC_OP_ICM] = "CC_OP_ICM", - [CC_OP_SLA_32] = "CC_OP_SLA_32", - [CC_OP_SLA_64] = "CC_OP_SLA_64", - [CC_OP_FLOGR] = "CC_OP_FLOGR", - [CC_OP_LCBB] = "CC_OP_LCBB", - [CC_OP_VC] = "CC_OP_VC", - [CC_OP_MULS_32] = "CC_OP_MULS_32", - [CC_OP_MULS_64] = "CC_OP_MULS_64", - }; - - return cc_names[cc_op]; -} diff --git a/target/s390x/meson.build b/target/s390x/meson.build index a73bae3dc5..6e1aa3b0cd 100644 --- a/target/s390x/meson.build +++ b/target/s390x/meson.build @@ -6,6 +6,7 @@ s390x_ss.add(files( 'gdbstub.c', 'helper.c', 'interrupt.c', + 'cpu-dump.c', )) s390x_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c')) From da9448854693bb5958d181b8f67bdb7760e0d0b0 Mon Sep 17 00:00:00 2001 From: "Cho, Yu-Chen" Date: Wed, 7 Jul 2021 18:53:20 +0800 Subject: [PATCH 13/17] target/s390x: make helper.c sysemu-only Now that we have moved cpu-dump functionality out of helper.c, we can make the module sysemu-only. Signed-off-by: Claudio Fontana Signed-off-by: Cho, Yu-Chen Acked-by: Cornelia Huck Reviewed-by: Thomas Huth Message-Id: <20210707105324.23400-11-acho@suse.com> Signed-off-by: Cornelia Huck --- target/s390x/helper.c | 9 +-------- target/s390x/meson.build | 2 +- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/target/s390x/helper.c b/target/s390x/helper.c index c72e990f4d..6e35473c7f 100644 --- a/target/s390x/helper.c +++ b/target/s390x/helper.c @@ -1,5 +1,5 @@ /* - * S/390 helpers + * S/390 helpers - sysemu only * * Copyright (c) 2009 Ulrich Hecht * Copyright (c) 2011 Alexander Graf @@ -27,11 +27,8 @@ #include "hw/s390x/pv.h" #include "sysemu/hw_accel.h" #include "sysemu/runstate.h" -#ifndef CONFIG_USER_ONLY #include "sysemu/tcg.h" -#endif -#ifndef CONFIG_USER_ONLY void s390x_tod_timer(void *opaque) { cpu_inject_clock_comparator((S390CPU *) opaque); @@ -284,7 +281,3 @@ int s390_store_adtl_status(S390CPU *cpu, hwaddr addr, hwaddr len) cpu_physical_memory_unmap(sa, len, 1, len); return 0; } -#else -/* For user-only, tcg is always enabled. */ -#define tcg_enabled() true -#endif /* CONFIG_USER_ONLY */ diff --git a/target/s390x/meson.build b/target/s390x/meson.build index 6e1aa3b0cd..bbcaede384 100644 --- a/target/s390x/meson.build +++ b/target/s390x/meson.build @@ -4,7 +4,6 @@ s390x_ss.add(files( 'cpu_features.c', 'cpu_models.c', 'gdbstub.c', - 'helper.c', 'interrupt.c', 'cpu-dump.c', )) @@ -23,6 +22,7 @@ s390x_ss.add(gen_features_h) s390x_softmmu_ss = ss.source_set() s390x_softmmu_ss.add(files( + 'helper.c', 'arch_dump.c', 'diag.c', 'ioinst.c', From 1fc66ac17a604b3df78518ed9bc9bdf5552ee33a Mon Sep 17 00:00:00 2001 From: "Cho, Yu-Chen" Date: Wed, 7 Jul 2021 18:53:21 +0800 Subject: [PATCH 14/17] target/s390x: use kvm_enabled() to wrap call to kvm_s390_get_hpage_1m this will allow to remove the kvm stubs. Signed-off-by: Claudio Fontana Signed-off-by: Cho, Yu-Chen Reviewed-by: Thomas Huth Message-Id: <20210707105324.23400-12-acho@suse.com> Signed-off-by: Cornelia Huck --- target/s390x/diag.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/target/s390x/diag.c b/target/s390x/diag.c index c17a2498a7..8405f69df0 100644 --- a/target/s390x/diag.c +++ b/target/s390x/diag.c @@ -20,6 +20,7 @@ #include "hw/s390x/ipl.h" #include "hw/s390x/s390-virtio-ccw.h" #include "hw/s390x/pv.h" +#include "sysemu/kvm.h" #include "kvm_s390x.h" int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3) @@ -168,7 +169,7 @@ out: return; } - if (kvm_s390_get_hpage_1m()) { + if (kvm_enabled() && kvm_s390_get_hpage_1m()) { error_report("Protected VMs can currently not be backed with " "huge pages"); env->regs[r1 + 1] = DIAG_308_RC_INVAL_FOR_PV; From 777ef689b5e5732c4d99f78f9e39f797dfe5fba2 Mon Sep 17 00:00:00 2001 From: "Cho, Yu-Chen" Date: Wed, 7 Jul 2021 18:53:22 +0800 Subject: [PATCH 15/17] target/s390x: remove kvm-stub.c all function calls are protected by kvm_enabled(), so we do not need the stubs. Signed-off-by: Claudio Fontana Signed-off-by: Cho, Yu-Chen Reviewed-by: Cornelia Huck Reviewed-by: Thomas Huth Message-Id: <20210707105324.23400-13-acho@suse.com> Signed-off-by: Cornelia Huck --- MAINTAINERS | 1 - target/s390x/kvm-stub.c | 121 --------------------------------------- target/s390x/meson.build | 2 +- 3 files changed, 1 insertion(+), 123 deletions(-) delete mode 100644 target/s390x/kvm-stub.c diff --git a/MAINTAINERS b/MAINTAINERS index 8ec845f4e0..4e04800576 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -396,7 +396,6 @@ M: Christian Borntraeger S: Supported F: target/s390x/kvm.c F: target/s390x/kvm_s390x.h -F: target/s390x/kvm-stub.c F: target/s390x/ioinst.[ch] F: target/s390x/machine.c F: target/s390x/sigp.c diff --git a/target/s390x/kvm-stub.c b/target/s390x/kvm-stub.c deleted file mode 100644 index 8a308cfebb..0000000000 --- a/target/s390x/kvm-stub.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * QEMU KVM support -- s390x specific function stubs. - * - * Copyright (c) 2009 Ulrich Hecht - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ - -#include "qemu/osdep.h" -#include "cpu.h" -#include "kvm_s390x.h" - -void kvm_s390_access_exception(S390CPU *cpu, uint16_t code, uint64_t te_code) -{ -} - -int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, uint8_t ar, void *hostbuf, - int len, bool is_write) -{ - return -ENOSYS; -} - -void kvm_s390_program_interrupt(S390CPU *cpu, uint16_t code) -{ -} - -int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state) -{ - return -ENOSYS; -} - -void kvm_s390_vcpu_interrupt_pre_save(S390CPU *cpu) -{ -} - -int kvm_s390_vcpu_interrupt_post_load(S390CPU *cpu) -{ - return 0; -} - -int kvm_s390_get_hpage_1m(void) -{ - return 0; -} - -int kvm_s390_get_ri(void) -{ - return 0; -} - -int kvm_s390_get_clock(uint8_t *tod_high, uint64_t *tod_low) -{ - return -ENOSYS; -} - -int kvm_s390_get_clock_ext(uint8_t *tod_high, uint64_t *tod_low) -{ - return -ENOSYS; -} - -int kvm_s390_set_clock(uint8_t tod_high, uint64_t tod_low) -{ - return -ENOSYS; -} - -int kvm_s390_set_clock_ext(uint8_t tod_high, uint64_t tod_low) -{ - return -ENOSYS; -} - -void kvm_s390_enable_css_support(S390CPU *cpu) -{ -} - -int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch, - int vq, bool assign) -{ - return -ENOSYS; -} - -void kvm_s390_cmma_reset(void) -{ -} - -void kvm_s390_reset_vcpu_initial(S390CPU *cpu) -{ -} - -void kvm_s390_reset_vcpu_clear(S390CPU *cpu) -{ -} - -void kvm_s390_reset_vcpu_normal(S390CPU *cpu) -{ -} - -int kvm_s390_set_mem_limit(uint64_t new_limit, uint64_t *hw_limit) -{ - return 0; -} - -void kvm_s390_set_max_pagesize(uint64_t pagesize, Error **errp) -{ -} - -void kvm_s390_crypto_reset(void) -{ -} - -void kvm_s390_stop_interrupt(S390CPU *cpu) -{ -} - -void kvm_s390_restart_interrupt(S390CPU *cpu) -{ -} - -void kvm_s390_set_diag318(CPUState *cs, uint64_t diag318_info) -{ -} diff --git a/target/s390x/meson.build b/target/s390x/meson.build index bbcaede384..6c8e03b8fb 100644 --- a/target/s390x/meson.build +++ b/target/s390x/meson.build @@ -8,7 +8,7 @@ s390x_ss.add(files( 'cpu-dump.c', )) -s390x_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c')) +s390x_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c')) gen_features = executable('gen-features', 'gen-features.c', native: true, build_by_default: false) From 67043607d17cf62f4ae8110151c44fb73295e66f Mon Sep 17 00:00:00 2001 From: "Cho, Yu-Chen" Date: Wed, 7 Jul 2021 18:53:23 +0800 Subject: [PATCH 16/17] target/s390x: move kvm files into kvm/ move kvm files into kvm/ After the reshuffling, update MAINTAINERS accordingly. Make use of the new directory: target/s390x/kvm/ Signed-off-by: Claudio Fontana Signed-off-by: Cho, Yu-Chen Reviewed-by: Cornelia Huck Reviewed-by: Thomas Huth Message-Id: <20210707105324.23400-14-acho@suse.com> Signed-off-by: Cornelia Huck --- MAINTAINERS | 3 +-- hw/intc/s390_flic_kvm.c | 2 +- hw/s390x/s390-stattrib-kvm.c | 2 +- hw/s390x/tod-kvm.c | 2 +- hw/vfio/ap.c | 2 +- meson.build | 1 + target/s390x/cpu-sysemu.c | 2 +- target/s390x/cpu.c | 2 +- target/s390x/cpu_models.c | 2 +- target/s390x/diag.c | 2 +- target/s390x/interrupt.c | 2 +- target/s390x/{ => kvm}/kvm.c | 0 target/s390x/{ => kvm}/kvm_s390x.h | 0 target/s390x/kvm/meson.build | 17 +++++++++++++++++ target/s390x/kvm/trace-events | 7 +++++++ target/s390x/kvm/trace.h | 1 + target/s390x/machine.c | 2 +- target/s390x/meson.build | 16 +--------------- target/s390x/mmu_helper.c | 2 +- target/s390x/trace-events | 6 ------ 20 files changed, 39 insertions(+), 34 deletions(-) rename target/s390x/{ => kvm}/kvm.c (100%) rename target/s390x/{ => kvm}/kvm_s390x.h (100%) create mode 100644 target/s390x/kvm/meson.build create mode 100644 target/s390x/kvm/trace-events create mode 100644 target/s390x/kvm/trace.h diff --git a/MAINTAINERS b/MAINTAINERS index 4e04800576..11d9ce72aa 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -394,8 +394,7 @@ M: Halil Pasic M: Cornelia Huck M: Christian Borntraeger S: Supported -F: target/s390x/kvm.c -F: target/s390x/kvm_s390x.h +F: target/s390x/kvm/ F: target/s390x/ioinst.[ch] F: target/s390x/machine.c F: target/s390x/sigp.c diff --git a/hw/intc/s390_flic_kvm.c b/hw/intc/s390_flic_kvm.c index 929cfa3a68..efe5054182 100644 --- a/hw/intc/s390_flic_kvm.c +++ b/hw/intc/s390_flic_kvm.c @@ -11,7 +11,7 @@ */ #include "qemu/osdep.h" -#include "kvm_s390x.h" +#include "kvm/kvm_s390x.h" #include #include "qemu/error-report.h" #include "qemu/module.h" diff --git a/hw/s390x/s390-stattrib-kvm.c b/hw/s390x/s390-stattrib-kvm.c index f0b11a74e4..24cd01382e 100644 --- a/hw/s390x/s390-stattrib-kvm.c +++ b/hw/s390x/s390-stattrib-kvm.c @@ -16,7 +16,7 @@ #include "qemu/error-report.h" #include "sysemu/kvm.h" #include "exec/ram_addr.h" -#include "kvm_s390x.h" +#include "kvm/kvm_s390x.h" Object *kvm_s390_stattrib_create(void) { diff --git a/hw/s390x/tod-kvm.c b/hw/s390x/tod-kvm.c index 0b94477486..ec855811ae 100644 --- a/hw/s390x/tod-kvm.c +++ b/hw/s390x/tod-kvm.c @@ -13,7 +13,7 @@ #include "qemu/module.h" #include "sysemu/runstate.h" #include "hw/s390x/tod.h" -#include "kvm_s390x.h" +#include "kvm/kvm_s390x.h" static void kvm_s390_get_tod_raw(S390TOD *tod, Error **errp) { diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c index 4b32aca1a0..e0dd561e85 100644 --- a/hw/vfio/ap.c +++ b/hw/vfio/ap.c @@ -21,7 +21,7 @@ #include "qemu/module.h" #include "qemu/option.h" #include "qemu/config-file.h" -#include "kvm_s390x.h" +#include "kvm/kvm_s390x.h" #include "migration/vmstate.h" #include "hw/qdev-properties.h" #include "hw/s390x/ap-bridge.h" diff --git a/meson.build b/meson.build index 7e12de01be..b458cd33b8 100644 --- a/meson.build +++ b/meson.build @@ -2102,6 +2102,7 @@ if have_system or have_user 'target/ppc', 'target/riscv', 'target/s390x', + 'target/s390x/kvm', 'target/sparc', ] endif diff --git a/target/s390x/cpu-sysemu.c b/target/s390x/cpu-sysemu.c index 16e5301084..df2c6bf694 100644 --- a/target/s390x/cpu-sysemu.c +++ b/target/s390x/cpu-sysemu.c @@ -24,7 +24,7 @@ #include "qapi/error.h" #include "cpu.h" #include "s390x-internal.h" -#include "kvm_s390x.h" +#include "kvm/kvm_s390x.h" #include "sysemu/kvm.h" #include "sysemu/reset.h" #include "qemu/timer.h" diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c index 5c456f6014..7b7b05f1d3 100644 --- a/target/s390x/cpu.c +++ b/target/s390x/cpu.c @@ -24,7 +24,7 @@ #include "qapi/error.h" #include "cpu.h" #include "s390x-internal.h" -#include "kvm_s390x.h" +#include "kvm/kvm_s390x.h" #include "sysemu/kvm.h" #include "sysemu/reset.h" #include "qemu/module.h" diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c index 442f06e140..624c7ea971 100644 --- a/target/s390x/cpu_models.c +++ b/target/s390x/cpu_models.c @@ -13,7 +13,7 @@ #include "qemu/osdep.h" #include "cpu.h" #include "s390x-internal.h" -#include "kvm_s390x.h" +#include "kvm/kvm_s390x.h" #include "sysemu/kvm.h" #include "sysemu/tcg.h" #include "qapi/error.h" diff --git a/target/s390x/diag.c b/target/s390x/diag.c index 8405f69df0..76b01dcd68 100644 --- a/target/s390x/diag.c +++ b/target/s390x/diag.c @@ -21,7 +21,7 @@ #include "hw/s390x/s390-virtio-ccw.h" #include "hw/s390x/pv.h" #include "sysemu/kvm.h" -#include "kvm_s390x.h" +#include "kvm/kvm_s390x.h" int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3) { diff --git a/target/s390x/interrupt.c b/target/s390x/interrupt.c index 734f0c62de..5195f060ec 100644 --- a/target/s390x/interrupt.c +++ b/target/s390x/interrupt.c @@ -9,7 +9,7 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "kvm_s390x.h" +#include "kvm/kvm_s390x.h" #include "s390x-internal.h" #include "exec/exec-all.h" #include "sysemu/kvm.h" diff --git a/target/s390x/kvm.c b/target/s390x/kvm/kvm.c similarity index 100% rename from target/s390x/kvm.c rename to target/s390x/kvm/kvm.c diff --git a/target/s390x/kvm_s390x.h b/target/s390x/kvm/kvm_s390x.h similarity index 100% rename from target/s390x/kvm_s390x.h rename to target/s390x/kvm/kvm_s390x.h diff --git a/target/s390x/kvm/meson.build b/target/s390x/kvm/meson.build new file mode 100644 index 0000000000..d1356356b1 --- /dev/null +++ b/target/s390x/kvm/meson.build @@ -0,0 +1,17 @@ + +s390x_ss.add(when: 'CONFIG_KVM', if_true: files( + 'kvm.c' +)) + +# Newer kernels on s390 check for an S390_PGSTE program header and +# enable the pgste page table extensions in that case. This makes +# the vm.allocate_pgste sysctl unnecessary. We enable this program +# header if +# - we build on s390x +# - we build the system emulation for s390x (qemu-system-s390x) +# - KVM is enabled +# - the linker supports --s390-pgste +if host_machine.cpu_family() == 's390x' and cc.has_link_argument('-Wl,--s390-pgste') + s390x_softmmu_ss.add(when: 'CONFIG_KVM', + if_true: declare_dependency(link_args: ['-Wl,--s390-pgste'])) +endif diff --git a/target/s390x/kvm/trace-events b/target/s390x/kvm/trace-events new file mode 100644 index 0000000000..5289f5f675 --- /dev/null +++ b/target/s390x/kvm/trace-events @@ -0,0 +1,7 @@ +# See docs/devel/tracing.txt for syntax documentation. + +# kvm.c +kvm_enable_cmma(int rc) "CMMA: enabling with result code %d" +kvm_clear_cmma(int rc) "CMMA: clearing with result code %d" +kvm_failed_cpu_state_set(int cpu_index, uint8_t state, const char *msg) "Warning: Unable to set cpu %d state %" PRIu8 " to KVM: %s" +kvm_assign_subch_ioeventfd(int fd, uint32_t addr, bool assign, int datamatch) "fd: %d sch: @0x%x assign: %d vq: %d" diff --git a/target/s390x/kvm/trace.h b/target/s390x/kvm/trace.h new file mode 100644 index 0000000000..ae195b1306 --- /dev/null +++ b/target/s390x/kvm/trace.h @@ -0,0 +1 @@ +#include "trace/trace-target_s390x_kvm.h" diff --git a/target/s390x/machine.c b/target/s390x/machine.c index 81a8a7ff99..37a076858c 100644 --- a/target/s390x/machine.c +++ b/target/s390x/machine.c @@ -17,7 +17,7 @@ #include "qemu/osdep.h" #include "cpu.h" #include "s390x-internal.h" -#include "kvm_s390x.h" +#include "kvm/kvm_s390x.h" #include "migration/vmstate.h" #include "tcg/tcg_s390x.h" #include "sysemu/kvm.h" diff --git a/target/s390x/meson.build b/target/s390x/meson.build index 6c8e03b8fb..ec73bed524 100644 --- a/target/s390x/meson.build +++ b/target/s390x/meson.build @@ -8,8 +8,6 @@ s390x_ss.add(files( 'cpu-dump.c', )) -s390x_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c')) - gen_features = executable('gen-features', 'gen-features.c', native: true, build_by_default: false) @@ -32,22 +30,10 @@ s390x_softmmu_ss.add(files( 'cpu-sysemu.c', )) -# Newer kernels on s390 check for an S390_PGSTE program header and -# enable the pgste page table extensions in that case. This makes -# the vm.allocate_pgste sysctl unnecessary. We enable this program -# header if -# - we build on s390x -# - we build the system emulation for s390x (qemu-system-s390x) -# - KVM is enabled -# - the linker supports --s390-pgste -if host_machine.cpu_family() == 's390x' and cc.has_link_argument('-Wl,--s390-pgste') - s390x_softmmu_ss.add(when: 'CONFIG_KVM', - if_true: declare_dependency(link_args: ['-Wl,--s390-pgste'])) -endif - s390x_user_ss = ss.source_set() subdir('tcg') +subdir('kvm') target_arch += {'s390x': s390x_ss} target_softmmu_arch += {'s390x': s390x_softmmu_ss} diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c index 52fdd86c63..d779a9fc51 100644 --- a/target/s390x/mmu_helper.c +++ b/target/s390x/mmu_helper.c @@ -20,7 +20,7 @@ #include "exec/address-spaces.h" #include "cpu.h" #include "s390x-internal.h" -#include "kvm_s390x.h" +#include "kvm/kvm_s390x.h" #include "sysemu/kvm.h" #include "sysemu/tcg.h" #include "exec/exec-all.h" diff --git a/target/s390x/trace-events b/target/s390x/trace-events index e83a8cf85e..729cb012b4 100644 --- a/target/s390x/trace-events +++ b/target/s390x/trace-events @@ -10,12 +10,6 @@ ioinst_sch_id(const char *insn, int cssid, int ssid, int schid) "IOINST: %s (%x. ioinst_chp_id(const char *insn, int cssid, int chpid) "IOINST: %s (%x.%02x)" ioinst_chsc_cmd(uint16_t cmd, uint16_t len) "IOINST: chsc command 0x%04x, len 0x%04x" -# kvm.c -kvm_enable_cmma(int rc) "CMMA: enabling with result code %d" -kvm_clear_cmma(int rc) "CMMA: clearing with result code %d" -kvm_failed_cpu_state_set(int cpu_index, uint8_t state, const char *msg) "Warning: Unable to set cpu %d state %" PRIu8 " to KVM: %s" -kvm_assign_subch_ioeventfd(int fd, uint32_t addr, bool assign, int datamatch) "fd: %d sch: @0x%x assign: %d vq: %d" - # cpu-sysemu.c cpu_set_state(int cpu_index, uint8_t state) "setting cpu %d state to %" PRIu8 cpu_halt(int cpu_index) "halting cpu %d" From 7ab3eb42b0d795f7321c4fca0ea06cb76a005b04 Mon Sep 17 00:00:00 2001 From: "Cho, Yu-Chen" Date: Wed, 7 Jul 2021 18:53:24 +0800 Subject: [PATCH 17/17] target/s390x: split sysemu part of cpu models split sysemu part of cpu models, also create a tiny _user.c with just the (at least for now), empty implementation of apply_cpu_model. Signed-off-by: Claudio Fontana Signed-off-by: Cho, Yu-Chen Reviewed-by: Thomas Huth Message-Id: <20210707105324.23400-15-acho@suse.com> Signed-off-by: Cornelia Huck --- MAINTAINERS | 1 + target/s390x/cpu_models.c | 417 +----------------------------- target/s390x/cpu_models_sysemu.c | 426 +++++++++++++++++++++++++++++++ target/s390x/cpu_models_user.c | 20 ++ target/s390x/meson.build | 4 + target/s390x/s390x-internal.h | 2 + 6 files changed, 454 insertions(+), 416 deletions(-) create mode 100644 target/s390x/cpu_models_sysemu.c create mode 100644 target/s390x/cpu_models_user.c diff --git a/MAINTAINERS b/MAINTAINERS index 11d9ce72aa..af1edb3e6e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -298,6 +298,7 @@ M: David Hildenbrand S: Maintained F: target/s390x/ F: target/s390x/tcg +F: target/s390x/cpu_models_*.[ch] F: hw/s390x/ F: disas/s390.c F: tests/tcg/s390x/ diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c index 624c7ea971..4e4598cc77 100644 --- a/target/s390x/cpu_models.c +++ b/target/s390x/cpu_models.c @@ -18,18 +18,11 @@ #include "sysemu/tcg.h" #include "qapi/error.h" #include "qapi/visitor.h" -#include "qemu/error-report.h" #include "qemu/module.h" #include "qemu/qemu-print.h" -#include "qapi/qmp/qerror.h" -#include "qapi/qobject-input-visitor.h" -#include "qapi/qmp/qdict.h" #ifndef CONFIG_USER_ONLY -#include "sysemu/arch_init.h" #include "sysemu/sysemu.h" -#include "hw/pci/pci.h" #endif -#include "qapi/qapi-commands-machine-target.h" #include "hw/s390x/pv.h" #define CPUDEF_INIT(_type, _gen, _ec_ga, _mha_pow, _hmfai, _name, _desc) \ @@ -416,381 +409,6 @@ void s390_cpu_list(void) } } -static S390CPUModel *get_max_cpu_model(Error **errp); - -#ifndef CONFIG_USER_ONLY -static void list_add_feat(const char *name, void *opaque); - -static void check_unavailable_features(const S390CPUModel *max_model, - const S390CPUModel *model, - strList **unavailable) -{ - S390FeatBitmap missing; - - /* check general model compatibility */ - if (max_model->def->gen < model->def->gen || - (max_model->def->gen == model->def->gen && - max_model->def->ec_ga < model->def->ec_ga)) { - list_add_feat("type", unavailable); - } - - /* detect missing features if any to properly report them */ - bitmap_andnot(missing, model->features, max_model->features, - S390_FEAT_MAX); - if (!bitmap_empty(missing, S390_FEAT_MAX)) { - s390_feat_bitmap_to_ascii(missing, unavailable, list_add_feat); - } -} - -struct CpuDefinitionInfoListData { - CpuDefinitionInfoList *list; - S390CPUModel *model; -}; - -static void create_cpu_model_list(ObjectClass *klass, void *opaque) -{ - struct CpuDefinitionInfoListData *cpu_list_data = opaque; - CpuDefinitionInfoList **cpu_list = &cpu_list_data->list; - CpuDefinitionInfo *info; - char *name = g_strdup(object_class_get_name(klass)); - S390CPUClass *scc = S390_CPU_CLASS(klass); - - /* strip off the -s390x-cpu */ - g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0; - info = g_new0(CpuDefinitionInfo, 1); - info->name = name; - info->has_migration_safe = true; - info->migration_safe = scc->is_migration_safe; - info->q_static = scc->is_static; - info->q_typename = g_strdup(object_class_get_name(klass)); - /* check for unavailable features */ - if (cpu_list_data->model) { - Object *obj; - S390CPU *sc; - obj = object_new_with_class(klass); - sc = S390_CPU(obj); - if (sc->model) { - info->has_unavailable_features = true; - check_unavailable_features(cpu_list_data->model, sc->model, - &info->unavailable_features); - } - object_unref(obj); - } - - QAPI_LIST_PREPEND(*cpu_list, info); -} - -CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) -{ - struct CpuDefinitionInfoListData list_data = { - .list = NULL, - }; - - list_data.model = get_max_cpu_model(NULL); - - object_class_foreach(create_cpu_model_list, TYPE_S390_CPU, false, - &list_data); - - return list_data.list; -} - -static void cpu_model_from_info(S390CPUModel *model, const CpuModelInfo *info, - Error **errp) -{ - Error *err = NULL; - const QDict *qdict = NULL; - const QDictEntry *e; - Visitor *visitor; - ObjectClass *oc; - S390CPU *cpu; - Object *obj; - - if (info->props) { - qdict = qobject_to(QDict, info->props); - if (!qdict) { - error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict"); - return; - } - } - - oc = cpu_class_by_name(TYPE_S390_CPU, info->name); - if (!oc) { - error_setg(errp, "The CPU definition \'%s\' is unknown.", info->name); - return; - } - if (S390_CPU_CLASS(oc)->kvm_required && !kvm_enabled()) { - error_setg(errp, "The CPU definition '%s' requires KVM", info->name); - return; - } - obj = object_new_with_class(oc); - cpu = S390_CPU(obj); - - if (!cpu->model) { - error_setg(errp, "Details about the host CPU model are not available, " - "it cannot be used."); - object_unref(obj); - return; - } - - if (qdict) { - visitor = qobject_input_visitor_new(info->props); - if (!visit_start_struct(visitor, NULL, NULL, 0, errp)) { - visit_free(visitor); - object_unref(obj); - return; - } - for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) { - if (!object_property_set(obj, e->key, visitor, &err)) { - break; - } - } - if (!err) { - visit_check_struct(visitor, &err); - } - visit_end_struct(visitor, NULL); - visit_free(visitor); - if (err) { - error_propagate(errp, err); - object_unref(obj); - return; - } - } - - /* copy the model and throw the cpu away */ - memcpy(model, cpu->model, sizeof(*model)); - object_unref(obj); -} - -static void qdict_add_disabled_feat(const char *name, void *opaque) -{ - qdict_put_bool(opaque, name, false); -} - -static void qdict_add_enabled_feat(const char *name, void *opaque) -{ - qdict_put_bool(opaque, name, true); -} - -/* convert S390CPUDef into a static CpuModelInfo */ -static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model, - bool delta_changes) -{ - QDict *qdict = qdict_new(); - S390FeatBitmap bitmap; - - /* always fallback to the static base model */ - info->name = g_strdup_printf("%s-base", model->def->name); - - if (delta_changes) { - /* features deleted from the base feature set */ - bitmap_andnot(bitmap, model->def->base_feat, model->features, - S390_FEAT_MAX); - if (!bitmap_empty(bitmap, S390_FEAT_MAX)) { - s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat); - } - - /* features added to the base feature set */ - bitmap_andnot(bitmap, model->features, model->def->base_feat, - S390_FEAT_MAX); - if (!bitmap_empty(bitmap, S390_FEAT_MAX)) { - s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_enabled_feat); - } - } else { - /* expand all features */ - s390_feat_bitmap_to_ascii(model->features, qdict, - qdict_add_enabled_feat); - bitmap_complement(bitmap, model->features, S390_FEAT_MAX); - s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat); - } - - if (!qdict_size(qdict)) { - qobject_unref(qdict); - } else { - info->props = QOBJECT(qdict); - info->has_props = true; - } -} - -CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, - CpuModelInfo *model, - Error **errp) -{ - Error *err = NULL; - CpuModelExpansionInfo *expansion_info = NULL; - S390CPUModel s390_model; - bool delta_changes = false; - - /* convert it to our internal representation */ - cpu_model_from_info(&s390_model, model, &err); - if (err) { - error_propagate(errp, err); - return NULL; - } - - if (type == CPU_MODEL_EXPANSION_TYPE_STATIC) { - delta_changes = true; - } else if (type != CPU_MODEL_EXPANSION_TYPE_FULL) { - error_setg(errp, "The requested expansion type is not supported."); - return NULL; - } - - /* convert it back to a static representation */ - expansion_info = g_new0(CpuModelExpansionInfo, 1); - expansion_info->model = g_malloc0(sizeof(*expansion_info->model)); - cpu_info_from_model(expansion_info->model, &s390_model, delta_changes); - return expansion_info; -} - -static void list_add_feat(const char *name, void *opaque) -{ - strList **last = (strList **) opaque; - - QAPI_LIST_PREPEND(*last, g_strdup(name)); -} - -CpuModelCompareInfo *qmp_query_cpu_model_comparison(CpuModelInfo *infoa, - CpuModelInfo *infob, - Error **errp) -{ - Error *err = NULL; - CpuModelCompareResult feat_result, gen_result; - CpuModelCompareInfo *compare_info; - S390FeatBitmap missing, added; - S390CPUModel modela, modelb; - - /* convert both models to our internal representation */ - cpu_model_from_info(&modela, infoa, &err); - if (err) { - error_propagate(errp, err); - return NULL; - } - cpu_model_from_info(&modelb, infob, &err); - if (err) { - error_propagate(errp, err); - return NULL; - } - compare_info = g_new0(CpuModelCompareInfo, 1); - - /* check the cpu generation and ga level */ - if (modela.def->gen == modelb.def->gen) { - if (modela.def->ec_ga == modelb.def->ec_ga) { - /* ec and corresponding bc are identical */ - gen_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL; - } else if (modela.def->ec_ga < modelb.def->ec_ga) { - gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET; - } else { - gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET; - } - } else if (modela.def->gen < modelb.def->gen) { - gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET; - } else { - gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET; - } - if (gen_result != CPU_MODEL_COMPARE_RESULT_IDENTICAL) { - /* both models cannot be made identical */ - list_add_feat("type", &compare_info->responsible_properties); - } - - /* check the feature set */ - if (bitmap_equal(modela.features, modelb.features, S390_FEAT_MAX)) { - feat_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL; - } else { - bitmap_andnot(missing, modela.features, modelb.features, S390_FEAT_MAX); - s390_feat_bitmap_to_ascii(missing, - &compare_info->responsible_properties, - list_add_feat); - bitmap_andnot(added, modelb.features, modela.features, S390_FEAT_MAX); - s390_feat_bitmap_to_ascii(added, &compare_info->responsible_properties, - list_add_feat); - if (bitmap_empty(missing, S390_FEAT_MAX)) { - feat_result = CPU_MODEL_COMPARE_RESULT_SUBSET; - } else if (bitmap_empty(added, S390_FEAT_MAX)) { - feat_result = CPU_MODEL_COMPARE_RESULT_SUPERSET; - } else { - feat_result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE; - } - } - - /* combine the results */ - if (gen_result == feat_result) { - compare_info->result = gen_result; - } else if (feat_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) { - compare_info->result = gen_result; - } else if (gen_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) { - compare_info->result = feat_result; - } else { - compare_info->result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE; - } - return compare_info; -} - -CpuModelBaselineInfo *qmp_query_cpu_model_baseline(CpuModelInfo *infoa, - CpuModelInfo *infob, - Error **errp) -{ - Error *err = NULL; - CpuModelBaselineInfo *baseline_info; - S390CPUModel modela, modelb, model; - uint16_t cpu_type; - uint8_t max_gen_ga; - uint8_t max_gen; - - /* convert both models to our internal representation */ - cpu_model_from_info(&modela, infoa, &err); - if (err) { - error_propagate(errp, err); - return NULL; - } - - cpu_model_from_info(&modelb, infob, &err); - if (err) { - error_propagate(errp, err); - return NULL; - } - - /* features both models support */ - bitmap_and(model.features, modela.features, modelb.features, S390_FEAT_MAX); - - /* detect the maximum model not regarding features */ - if (modela.def->gen == modelb.def->gen) { - if (modela.def->type == modelb.def->type) { - cpu_type = modela.def->type; - } else { - cpu_type = 0; - } - max_gen = modela.def->gen; - max_gen_ga = MIN(modela.def->ec_ga, modelb.def->ec_ga); - } else if (modela.def->gen > modelb.def->gen) { - cpu_type = modelb.def->type; - max_gen = modelb.def->gen; - max_gen_ga = modelb.def->ec_ga; - } else { - cpu_type = modela.def->type; - max_gen = modela.def->gen; - max_gen_ga = modela.def->ec_ga; - } - - model.def = s390_find_cpu_def(cpu_type, max_gen, max_gen_ga, - model.features); - - /* models without early base features (esan3) are bad */ - if (!model.def) { - error_setg(errp, "No compatible CPU model could be created as" - " important base features are disabled"); - return NULL; - } - - /* strip off features not part of the max model */ - bitmap_and(model.features, model.features, model.def->full_feat, - S390_FEAT_MAX); - - baseline_info = g_new0(CpuModelBaselineInfo, 1); - baseline_info->model = g_malloc0(sizeof(*baseline_info->model)); - cpu_info_from_model(baseline_info->model, &model, true); - return baseline_info; -} -#endif - static void check_consistency(const S390CPUModel *model) { static int dep[][2] = { @@ -906,7 +524,7 @@ static void check_compatibility(const S390CPUModel *max_model, "available in the configuration: "); } -static S390CPUModel *get_max_cpu_model(Error **errp) +S390CPUModel *get_max_cpu_model(Error **errp) { Error *err = NULL; static S390CPUModel max_model; @@ -931,39 +549,6 @@ static S390CPUModel *get_max_cpu_model(Error **errp) return &max_model; } -static inline void apply_cpu_model(const S390CPUModel *model, Error **errp) -{ -#ifndef CONFIG_USER_ONLY - Error *err = NULL; - static S390CPUModel applied_model; - static bool applied; - - /* - * We have the same model for all VCPUs. KVM can only be configured before - * any VCPUs are defined in KVM. - */ - if (applied) { - if (model && memcmp(&applied_model, model, sizeof(S390CPUModel))) { - error_setg(errp, "Mixed CPU models are not supported on s390x."); - } - return; - } - - if (kvm_enabled()) { - kvm_s390_apply_cpu_model(model, &err); - if (err) { - error_propagate(errp, err); - return; - } - } - - applied = true; - if (model) { - applied_model = *model; - } -#endif -} - void s390_realize_cpu_model(CPUState *cs, Error **errp) { Error *err = NULL; diff --git a/target/s390x/cpu_models_sysemu.c b/target/s390x/cpu_models_sysemu.c new file mode 100644 index 0000000000..05c3ccaaff --- /dev/null +++ b/target/s390x/cpu_models_sysemu.c @@ -0,0 +1,426 @@ +/* + * CPU models for s390x - System Emulation-only + * + * Copyright 2016 IBM Corp. + * + * Author(s): David Hildenbrand + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "s390x-internal.h" +#include "kvm/kvm_s390x.h" +#include "sysemu/kvm.h" +#include "sysemu/tcg.h" +#include "qapi/error.h" +#include "qapi/visitor.h" +#include "qapi/qmp/qerror.h" +#include "qapi/qobject-input-visitor.h" +#include "qapi/qmp/qdict.h" +#include "qapi/qapi-commands-machine-target.h" + +static void list_add_feat(const char *name, void *opaque); + +static void check_unavailable_features(const S390CPUModel *max_model, + const S390CPUModel *model, + strList **unavailable) +{ + S390FeatBitmap missing; + + /* check general model compatibility */ + if (max_model->def->gen < model->def->gen || + (max_model->def->gen == model->def->gen && + max_model->def->ec_ga < model->def->ec_ga)) { + list_add_feat("type", unavailable); + } + + /* detect missing features if any to properly report them */ + bitmap_andnot(missing, model->features, max_model->features, + S390_FEAT_MAX); + if (!bitmap_empty(missing, S390_FEAT_MAX)) { + s390_feat_bitmap_to_ascii(missing, unavailable, list_add_feat); + } +} + +struct CpuDefinitionInfoListData { + CpuDefinitionInfoList *list; + S390CPUModel *model; +}; + +static void create_cpu_model_list(ObjectClass *klass, void *opaque) +{ + struct CpuDefinitionInfoListData *cpu_list_data = opaque; + CpuDefinitionInfoList **cpu_list = &cpu_list_data->list; + CpuDefinitionInfo *info; + char *name = g_strdup(object_class_get_name(klass)); + S390CPUClass *scc = S390_CPU_CLASS(klass); + + /* strip off the -s390x-cpu */ + g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0; + info = g_new0(CpuDefinitionInfo, 1); + info->name = name; + info->has_migration_safe = true; + info->migration_safe = scc->is_migration_safe; + info->q_static = scc->is_static; + info->q_typename = g_strdup(object_class_get_name(klass)); + /* check for unavailable features */ + if (cpu_list_data->model) { + Object *obj; + S390CPU *sc; + obj = object_new_with_class(klass); + sc = S390_CPU(obj); + if (sc->model) { + info->has_unavailable_features = true; + check_unavailable_features(cpu_list_data->model, sc->model, + &info->unavailable_features); + } + object_unref(obj); + } + + QAPI_LIST_PREPEND(*cpu_list, info); +} + +CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) +{ + struct CpuDefinitionInfoListData list_data = { + .list = NULL, + }; + + list_data.model = get_max_cpu_model(NULL); + + object_class_foreach(create_cpu_model_list, TYPE_S390_CPU, false, + &list_data); + + return list_data.list; +} + +static void cpu_model_from_info(S390CPUModel *model, const CpuModelInfo *info, + Error **errp) +{ + Error *err = NULL; + const QDict *qdict = NULL; + const QDictEntry *e; + Visitor *visitor; + ObjectClass *oc; + S390CPU *cpu; + Object *obj; + + if (info->props) { + qdict = qobject_to(QDict, info->props); + if (!qdict) { + error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict"); + return; + } + } + + oc = cpu_class_by_name(TYPE_S390_CPU, info->name); + if (!oc) { + error_setg(errp, "The CPU definition \'%s\' is unknown.", info->name); + return; + } + if (S390_CPU_CLASS(oc)->kvm_required && !kvm_enabled()) { + error_setg(errp, "The CPU definition '%s' requires KVM", info->name); + return; + } + obj = object_new_with_class(oc); + cpu = S390_CPU(obj); + + if (!cpu->model) { + error_setg(errp, "Details about the host CPU model are not available, " + "it cannot be used."); + object_unref(obj); + return; + } + + if (qdict) { + visitor = qobject_input_visitor_new(info->props); + if (!visit_start_struct(visitor, NULL, NULL, 0, errp)) { + visit_free(visitor); + object_unref(obj); + return; + } + for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) { + if (!object_property_set(obj, e->key, visitor, &err)) { + break; + } + } + if (!err) { + visit_check_struct(visitor, &err); + } + visit_end_struct(visitor, NULL); + visit_free(visitor); + if (err) { + error_propagate(errp, err); + object_unref(obj); + return; + } + } + + /* copy the model and throw the cpu away */ + memcpy(model, cpu->model, sizeof(*model)); + object_unref(obj); +} + +static void qdict_add_disabled_feat(const char *name, void *opaque) +{ + qdict_put_bool(opaque, name, false); +} + +static void qdict_add_enabled_feat(const char *name, void *opaque) +{ + qdict_put_bool(opaque, name, true); +} + +/* convert S390CPUDef into a static CpuModelInfo */ +static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model, + bool delta_changes) +{ + QDict *qdict = qdict_new(); + S390FeatBitmap bitmap; + + /* always fallback to the static base model */ + info->name = g_strdup_printf("%s-base", model->def->name); + + if (delta_changes) { + /* features deleted from the base feature set */ + bitmap_andnot(bitmap, model->def->base_feat, model->features, + S390_FEAT_MAX); + if (!bitmap_empty(bitmap, S390_FEAT_MAX)) { + s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat); + } + + /* features added to the base feature set */ + bitmap_andnot(bitmap, model->features, model->def->base_feat, + S390_FEAT_MAX); + if (!bitmap_empty(bitmap, S390_FEAT_MAX)) { + s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_enabled_feat); + } + } else { + /* expand all features */ + s390_feat_bitmap_to_ascii(model->features, qdict, + qdict_add_enabled_feat); + bitmap_complement(bitmap, model->features, S390_FEAT_MAX); + s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat); + } + + if (!qdict_size(qdict)) { + qobject_unref(qdict); + } else { + info->props = QOBJECT(qdict); + info->has_props = true; + } +} + +CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, + CpuModelInfo *model, + Error **errp) +{ + Error *err = NULL; + CpuModelExpansionInfo *expansion_info = NULL; + S390CPUModel s390_model; + bool delta_changes = false; + + /* convert it to our internal representation */ + cpu_model_from_info(&s390_model, model, &err); + if (err) { + error_propagate(errp, err); + return NULL; + } + + if (type == CPU_MODEL_EXPANSION_TYPE_STATIC) { + delta_changes = true; + } else if (type != CPU_MODEL_EXPANSION_TYPE_FULL) { + error_setg(errp, "The requested expansion type is not supported."); + return NULL; + } + + /* convert it back to a static representation */ + expansion_info = g_new0(CpuModelExpansionInfo, 1); + expansion_info->model = g_malloc0(sizeof(*expansion_info->model)); + cpu_info_from_model(expansion_info->model, &s390_model, delta_changes); + return expansion_info; +} + +static void list_add_feat(const char *name, void *opaque) +{ + strList **last = (strList **) opaque; + + QAPI_LIST_PREPEND(*last, g_strdup(name)); +} + +CpuModelCompareInfo *qmp_query_cpu_model_comparison(CpuModelInfo *infoa, + CpuModelInfo *infob, + Error **errp) +{ + Error *err = NULL; + CpuModelCompareResult feat_result, gen_result; + CpuModelCompareInfo *compare_info; + S390FeatBitmap missing, added; + S390CPUModel modela, modelb; + + /* convert both models to our internal representation */ + cpu_model_from_info(&modela, infoa, &err); + if (err) { + error_propagate(errp, err); + return NULL; + } + cpu_model_from_info(&modelb, infob, &err); + if (err) { + error_propagate(errp, err); + return NULL; + } + compare_info = g_new0(CpuModelCompareInfo, 1); + + /* check the cpu generation and ga level */ + if (modela.def->gen == modelb.def->gen) { + if (modela.def->ec_ga == modelb.def->ec_ga) { + /* ec and corresponding bc are identical */ + gen_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL; + } else if (modela.def->ec_ga < modelb.def->ec_ga) { + gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET; + } else { + gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET; + } + } else if (modela.def->gen < modelb.def->gen) { + gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET; + } else { + gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET; + } + if (gen_result != CPU_MODEL_COMPARE_RESULT_IDENTICAL) { + /* both models cannot be made identical */ + list_add_feat("type", &compare_info->responsible_properties); + } + + /* check the feature set */ + if (bitmap_equal(modela.features, modelb.features, S390_FEAT_MAX)) { + feat_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL; + } else { + bitmap_andnot(missing, modela.features, modelb.features, S390_FEAT_MAX); + s390_feat_bitmap_to_ascii(missing, + &compare_info->responsible_properties, + list_add_feat); + bitmap_andnot(added, modelb.features, modela.features, S390_FEAT_MAX); + s390_feat_bitmap_to_ascii(added, &compare_info->responsible_properties, + list_add_feat); + if (bitmap_empty(missing, S390_FEAT_MAX)) { + feat_result = CPU_MODEL_COMPARE_RESULT_SUBSET; + } else if (bitmap_empty(added, S390_FEAT_MAX)) { + feat_result = CPU_MODEL_COMPARE_RESULT_SUPERSET; + } else { + feat_result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE; + } + } + + /* combine the results */ + if (gen_result == feat_result) { + compare_info->result = gen_result; + } else if (feat_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) { + compare_info->result = gen_result; + } else if (gen_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) { + compare_info->result = feat_result; + } else { + compare_info->result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE; + } + return compare_info; +} + +CpuModelBaselineInfo *qmp_query_cpu_model_baseline(CpuModelInfo *infoa, + CpuModelInfo *infob, + Error **errp) +{ + Error *err = NULL; + CpuModelBaselineInfo *baseline_info; + S390CPUModel modela, modelb, model; + uint16_t cpu_type; + uint8_t max_gen_ga; + uint8_t max_gen; + + /* convert both models to our internal representation */ + cpu_model_from_info(&modela, infoa, &err); + if (err) { + error_propagate(errp, err); + return NULL; + } + + cpu_model_from_info(&modelb, infob, &err); + if (err) { + error_propagate(errp, err); + return NULL; + } + + /* features both models support */ + bitmap_and(model.features, modela.features, modelb.features, S390_FEAT_MAX); + + /* detect the maximum model not regarding features */ + if (modela.def->gen == modelb.def->gen) { + if (modela.def->type == modelb.def->type) { + cpu_type = modela.def->type; + } else { + cpu_type = 0; + } + max_gen = modela.def->gen; + max_gen_ga = MIN(modela.def->ec_ga, modelb.def->ec_ga); + } else if (modela.def->gen > modelb.def->gen) { + cpu_type = modelb.def->type; + max_gen = modelb.def->gen; + max_gen_ga = modelb.def->ec_ga; + } else { + cpu_type = modela.def->type; + max_gen = modela.def->gen; + max_gen_ga = modela.def->ec_ga; + } + + model.def = s390_find_cpu_def(cpu_type, max_gen, max_gen_ga, + model.features); + + /* models without early base features (esan3) are bad */ + if (!model.def) { + error_setg(errp, "No compatible CPU model could be created as" + " important base features are disabled"); + return NULL; + } + + /* strip off features not part of the max model */ + bitmap_and(model.features, model.features, model.def->full_feat, + S390_FEAT_MAX); + + baseline_info = g_new0(CpuModelBaselineInfo, 1); + baseline_info->model = g_malloc0(sizeof(*baseline_info->model)); + cpu_info_from_model(baseline_info->model, &model, true); + return baseline_info; +} + +void apply_cpu_model(const S390CPUModel *model, Error **errp) +{ + Error *err = NULL; + static S390CPUModel applied_model; + static bool applied; + + /* + * We have the same model for all VCPUs. KVM can only be configured before + * any VCPUs are defined in KVM. + */ + if (applied) { + if (model && memcmp(&applied_model, model, sizeof(S390CPUModel))) { + error_setg(errp, "Mixed CPU models are not supported on s390x."); + } + return; + } + + if (kvm_enabled()) { + kvm_s390_apply_cpu_model(model, &err); + if (err) { + error_propagate(errp, err); + return; + } + } + + applied = true; + if (model) { + applied_model = *model; + } +} diff --git a/target/s390x/cpu_models_user.c b/target/s390x/cpu_models_user.c new file mode 100644 index 0000000000..df24d12d9e --- /dev/null +++ b/target/s390x/cpu_models_user.c @@ -0,0 +1,20 @@ +/* + * CPU models for s390x - User-mode + * + * Copyright 2016 IBM Corp. + * + * Author(s): David Hildenbrand + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "s390x-internal.h" +#include "qapi/error.h" + +void apply_cpu_model(const S390CPUModel *model, Error **errp) +{ +} diff --git a/target/s390x/meson.build b/target/s390x/meson.build index ec73bed524..84c1402a6a 100644 --- a/target/s390x/meson.build +++ b/target/s390x/meson.build @@ -28,9 +28,13 @@ s390x_softmmu_ss.add(files( 'mmu_helper.c', 'sigp.c', 'cpu-sysemu.c', + 'cpu_models_sysemu.c', )) s390x_user_ss = ss.source_set() +s390x_user_ss.add(files( + 'cpu_models_user.c', +)) subdir('tcg') subdir('kvm') diff --git a/target/s390x/s390x-internal.h b/target/s390x/s390x-internal.h index 17edd4d13b..5506f185e8 100644 --- a/target/s390x/s390x-internal.h +++ b/target/s390x/s390x-internal.h @@ -261,6 +261,8 @@ static inline void s390_cpu_unhalt(S390CPU *cpu) /* cpu_models.c */ void s390_cpu_model_class_register_props(ObjectClass *oc); void s390_realize_cpu_model(CPUState *cs, Error **errp); +S390CPUModel *get_max_cpu_model(Error **errp); +void apply_cpu_model(const S390CPUModel *model, Error **errp); ObjectClass *s390_cpu_class_by_name(const char *name);