target/arm: Don't clear supported PMU events when initializing PMCEID1

A bug was introduced during a respin of:

commit 57a4a11b2b281bb548b419ca81bfafb214e4c77a
target/arm: Add array for supported PMU events, generate PMCEID[01]_EL0

This patch introduced two calls to get_pmceid() during CPU
initialization - one each for PMCEID0 and PMCEID1. In addition to
building the register values, get_pmceid() clears an internal array
mapping event numbers to their implementations (supported_event_map)
before rebuilding it. This is an optimization since much of the logic is
shared. However, since it was called twice, the contents of
supported_event_map reflect only the events in PMCEID1 (the second call
to get_pmceid()).

Fix this bug by moving the initialization of PMCEID0 and PMCEID1 back
into a single function call, and name it more appropriately since it is
doing more than simply generating the contents of the PMCEID[01]
registers.

Backports commit bf8d09694ccc07487cd73d7562081fdaec3370c8 from qemu
This commit is contained in:
Aaron Lindsay OS 2019-01-29 17:09:33 -05:00 committed by Lioncash
parent 3fa54df972
commit 8d7bb2cab3
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
8 changed files with 31 additions and 28 deletions

View file

@ -3337,7 +3337,7 @@
#define fp_exception_el fp_exception_el_aarch64 #define fp_exception_el fp_exception_el_aarch64
#define gen_a64_set_pc_im gen_a64_set_pc_im_aarch64 #define gen_a64_set_pc_im gen_a64_set_pc_im_aarch64
#define gen_cmtst_i64 gen_cmtst_i64_aarch64 #define gen_cmtst_i64 gen_cmtst_i64_aarch64
#define get_pmceid get_pmceid_aarch64 #define pmu_init pmu_init_aarch64
#define helper_advsimd_acge_f16 helper_advsimd_acge_f16_aarch64 #define helper_advsimd_acge_f16 helper_advsimd_acge_f16_aarch64
#define helper_advsimd_acgt_f16 helper_advsimd_acgt_f16_aarch64 #define helper_advsimd_acgt_f16 helper_advsimd_acgt_f16_aarch64
#define helper_advsimd_add2h helper_advsimd_add2h_aarch64 #define helper_advsimd_add2h helper_advsimd_add2h_aarch64

View file

@ -3337,7 +3337,7 @@
#define fp_exception_el fp_exception_el_aarch64eb #define fp_exception_el fp_exception_el_aarch64eb
#define gen_a64_set_pc_im gen_a64_set_pc_im_aarch64eb #define gen_a64_set_pc_im gen_a64_set_pc_im_aarch64eb
#define gen_cmtst_i64 gen_cmtst_i64_aarch64eb #define gen_cmtst_i64 gen_cmtst_i64_aarch64eb
#define get_pmceid get_pmceid_aarch64eb #define pmu_init pmu_init_aarch64eb
#define helper_advsimd_acge_f16 helper_advsimd_acge_f16_aarch64eb #define helper_advsimd_acge_f16 helper_advsimd_acge_f16_aarch64eb
#define helper_advsimd_acgt_f16 helper_advsimd_acgt_f16_aarch64eb #define helper_advsimd_acgt_f16 helper_advsimd_acgt_f16_aarch64eb
#define helper_advsimd_add2h helper_advsimd_add2h_aarch64eb #define helper_advsimd_add2h helper_advsimd_add2h_aarch64eb

View file

@ -3322,7 +3322,7 @@
#define cmtst_op cmtst_op_arm #define cmtst_op cmtst_op_arm
#define fp_exception_el fp_exception_el_arm #define fp_exception_el fp_exception_el_arm
#define gen_cmtst_i64 gen_cmtst_i64_arm #define gen_cmtst_i64 gen_cmtst_i64_arm
#define get_pmceid get_pmceid_arm #define pmu_init pmu_init_arm
#define mla_op mla_op_arm #define mla_op mla_op_arm
#define mls_op mls_op_arm #define mls_op mls_op_arm
#define pmccntr_op_start pmccntr_op_start_arm #define pmccntr_op_start pmccntr_op_start_arm

View file

@ -3322,7 +3322,7 @@
#define cmtst_op cmtst_op_armeb #define cmtst_op cmtst_op_armeb
#define fp_exception_el fp_exception_el_armeb #define fp_exception_el fp_exception_el_armeb
#define gen_cmtst_i64 gen_cmtst_i64_armeb #define gen_cmtst_i64 gen_cmtst_i64_armeb
#define get_pmceid get_pmceid_armeb #define pmu_init pmu_init_armeb
#define mla_op mla_op_armeb #define mla_op mla_op_armeb
#define mls_op mls_op_armeb #define mls_op mls_op_armeb
#define pmccntr_op_start pmccntr_op_start_armeb #define pmccntr_op_start pmccntr_op_start_armeb

View file

@ -3331,7 +3331,7 @@ arm_symbols = (
'cmtst_op', 'cmtst_op',
'fp_exception_el', 'fp_exception_el',
'gen_cmtst_i64', 'gen_cmtst_i64',
'get_pmceid', 'pmu_init',
'mla_op', 'mla_op',
'mls_op', 'mls_op',
'pmccntr_op_start', 'pmccntr_op_start',
@ -3383,7 +3383,7 @@ aarch64_symbols = (
'fp_exception_el', 'fp_exception_el',
'gen_a64_set_pc_im', 'gen_a64_set_pc_im',
'gen_cmtst_i64', 'gen_cmtst_i64',
'get_pmceid', 'pmu_init',
'helper_advsimd_acge_f16', 'helper_advsimd_acge_f16',
'helper_advsimd_acgt_f16', 'helper_advsimd_acgt_f16',
'helper_advsimd_add2h', 'helper_advsimd_add2h',

View file

@ -764,8 +764,7 @@ static int arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **err
} }
if (arm_feature(env, ARM_FEATURE_PMU)) { if (arm_feature(env, ARM_FEATURE_PMU)) {
cpu->pmceid0 = get_pmceid(&cpu->env, 0); pmu_init(cpu);
cpu->pmceid1 = get_pmceid(&cpu->env, 1);
arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0); arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0);
arm_register_el_change_hook(cpu, &pmu_post_el_change, 0); arm_register_el_change_hook(cpu, &pmu_post_el_change, 0);

View file

@ -964,14 +964,13 @@ void pmu_pre_el_change(ARMCPU *cpu, void *ignored);
void pmu_post_el_change(ARMCPU *cpu, void *ignored); void pmu_post_el_change(ARMCPU *cpu, void *ignored);
/* /*
* get_pmceid * pmu_init
* @env: CPUARMState * @cpu: ARMCPU
* @which: which PMCEID register to return (0 or 1)
* *
* Return the PMCEID[01]_EL0 register values corresponding to the counters * Initialize the CPU's PMCEID[01]_EL0 registers and associated internal state
* which are supported given the current configuration * for the current configuration
*/ */
uint64_t get_pmceid(CPUARMState *env, unsigned which); void pmu_init(ARMCPU *cpu);
/* SCTLR bit meanings. Several bits have been reused in newer /* SCTLR bit meanings. Several bits have been reused in newer
* versions of the architecture; in that case we define constants * versions of the architecture; in that case we define constants

View file

@ -952,22 +952,24 @@ static const pm_event pm_events[] = {
#define UNSUPPORTED_EVENT UINT16_MAX #define UNSUPPORTED_EVENT UINT16_MAX
/* /*
* Called upon initialization to build PMCEID0_EL0 or PMCEID1_EL0 (indicated by * Called upon CPU initialization to initialize PMCEID[01]_EL0 and build a map
* 'which'). We also use it to build a map of ARM event numbers to indices in * of ARM event numbers to indices in our pm_events array.
* our pm_events array.
* *
* Note: Events in the 0x40XX range are not currently supported. * Note: Events in the 0x40XX range are not currently supported.
*/ */
uint64_t get_pmceid(CPUARMState *env, unsigned which) void pmu_init(ARMCPU *cpu)
{ {
uint64_t pmceid = 0;
unsigned int i; unsigned int i;
assert(which <= 1); /*
* Empty supported_event_map and cpu->pmceid[01] before adding supported
for (i = 0; i < ARRAY_SIZE(env->supported_event_map); i++) { * events to them
env->supported_event_map[i] = UNSUPPORTED_EVENT; */
for (i = 0; i < ARRAY_SIZE(cpu->env.supported_event_map); i++) {
cpu->env.supported_event_map[i] = UNSUPPORTED_EVENT;
} }
cpu->pmceid0 = 0;
cpu->pmceid1 = 0;
for (i = 0; i < ARRAY_SIZE(pm_events); i++) { for (i = 0; i < ARRAY_SIZE(pm_events); i++) {
const pm_event *cnt = &pm_events[i]; const pm_event *cnt = &pm_events[i];
@ -975,13 +977,16 @@ uint64_t get_pmceid(CPUARMState *env, unsigned which)
/* We do not currently support events in the 0x40xx range */ /* We do not currently support events in the 0x40xx range */
assert(cnt->number <= 0x3f); assert(cnt->number <= 0x3f);
if ((cnt->number & 0x20) == (which << 6) && if (cnt->supported(&cpu->env)) {
cnt->supported(env)) { cpu->env.supported_event_map[cnt->number] = i;
pmceid |= (1 << (cnt->number & 0x1f)); uint64_t event_mask = 1 << (cnt->number & 0x1f);
env->supported_event_map[cnt->number] = i; if (cnt->number & 0x20) {
cpu->pmceid1 |= event_mask;
} else {
cpu->pmceid0 |= event_mask;
}
} }
} }
return pmceid;
} }
/* /*