diff options
author | AlexeiFedorov <Alexei.Fedorov@arm.com> | 2023-06-07 17:30:10 +0100 |
---|---|---|
committer | Soby Mathew <soby.mathew@arm.com> | 2023-09-13 09:49:37 +0100 |
commit | f81345ce2cd13d59cb6efa5847ec02baf54cd489 (patch) | |
tree | ca115e7029fc8f338a96f41ce044583aafa3bc2f | |
parent | cd04e41b418decee80a03d25eb7598e7a6b8da95 (diff) |
feat(rme): add Realm SVE tests for EAC1
This patch adds SVE tests for RMM EAC1.
The 'feature_flag' parameter passed to
'host_create_realm_payload()' function is modified
to contain 'sve_vl', 'num_bps', 'num_wps' and
'pmu_num_ctrs entries'. This allows to pass values
which can exceed these fields in feature_register_0
for testing. It makes possible to pass
'Create SVE Realm with invalid VL' which was
skipped originally, when SVE was configured with
the maximum supported vector length value.
Signed-off-by: AlexeiFedorov <Alexei.Fedorov@arm.com>
Change-Id: Icd5e57c1bb0cb8dee27b7ace5643aec597e036c1
5 files changed, 109 insertions, 70 deletions
diff --git a/include/runtime_services/host_realm_managment/host_realm_rmi.h b/include/runtime_services/host_realm_managment/host_realm_rmi.h index e25a30d..30caaac 100644 --- a/include/runtime_services/host_realm_managment/host_realm_rmi.h +++ b/include/runtime_services/host_realm_managment/host_realm_rmi.h @@ -218,14 +218,9 @@ #define RMI_FEATURE_TRUE 1U /* RmiRealmFlags format */ -#define RMI_REALM_FLAGS_LPA2_SHIFT 0UL -#define RMI_REALM_FLAGS_LPA2_WIDTH 1UL - -#define RMI_REALM_FLAGS_SVE_SHIFT 1UL -#define RMI_REALM_FLAGS_SVE_WIDTH 1UL - -#define RMI_REALM_FLAGS_PMU_SHIFT 2UL -#define RMI_REALM_FLAGS_PMU_WIDTH 1UL +#define RMI_REALM_FLAGS_LPA2 BIT(0) +#define RMI_REALM_FLAGS_SVE BIT(1) +#define RMI_REALM_FLAGS_PMU BIT(2) /* RmiInterfaceVersion type */ #define RMI_MAJOR_VERSION 0U @@ -283,6 +278,20 @@ #define RMI_FEATURE_REGISTER_0_HASH_SHA_256 BIT(28) #define RMI_FEATURE_REGISTER_0_HASH_SHA_512 BIT(29) +/* + * Format of feature_flag[63:32]. + * Value -1 indicates not set field, and parameter will be set + * from the corresponding field of feature register 0. + */ +#define FEATURE_SVE_VL_SHIFT 32UL +#define FEATURE_SVE_VL_WIDTH 8UL +#define FEATURE_NUM_BPS_SHIFT 40UL +#define FEATURE_NUM_BPS_WIDTH 8UL +#define FEATURE_NUM_WPS_SHIFT 48UL +#define FEATURE_NUM_WPS_WIDTH 8UL +#define FEATURE_PMU_NUM_CTRS_SHIFT 56UL +#define FEATURE_PMU_NUM_CTRS_WIDTH 8UL + /* RmiStatusCode types */ /* * Status codes which can be returned from RMM commands. @@ -500,6 +509,10 @@ struct realm { u_register_t ipa_ns_buffer; u_register_t ns_buffer_size; u_register_t aux_pages[REC_PARAMS_AUX_GRANULES]; + uint8_t sve_vl; + uint8_t num_bps; + uint8_t num_wps; + uint8_t pmu_num_ctrs; enum realm_state state; }; diff --git a/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c b/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c index 79020df..fc18a75 100644 --- a/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c +++ b/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c @@ -185,6 +185,8 @@ bool host_create_realm_payload(u_register_t realm_payload_adr, u_register_t realm_pages_size, u_register_t feature_flag) { + int8_t value; + if (realm_payload_adr == TFTF_BASE) { ERROR("realm_payload_adr should be grater then TFTF_BASE\n"); return false; @@ -220,9 +222,43 @@ bool host_create_realm_payload(u_register_t realm_payload_adr, /* Disable PMU if not required */ if ((feature_flag & RMI_FEATURE_REGISTER_0_PMU_EN) == 0UL) { - realm.rmm_feat_reg0 &= - ~(RMI_FEATURE_REGISTER_0_PMU_EN | - MASK(RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS)); + realm.rmm_feat_reg0 &= ~RMI_FEATURE_REGISTER_0_PMU_EN; + realm.pmu_num_ctrs = 0U; + } else { + value = EXTRACT(FEATURE_PMU_NUM_CTRS, feature_flag); + if (value != -1) { + realm.pmu_num_ctrs = (unsigned int)value; + } else { + realm.pmu_num_ctrs = + EXTRACT(RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS, + realm.rmm_feat_reg0); + } + } + + /* Disable SVE if not required */ + if ((feature_flag & RMI_FEATURE_REGISTER_0_SVE_EN) == 0UL) { + realm.rmm_feat_reg0 &= ~RMI_FEATURE_REGISTER_0_SVE_EN; + realm.sve_vl = 0U; + } else { + realm.sve_vl = EXTRACT(FEATURE_SVE_VL, feature_flag); + } + + /* Requested number of breakpoints */ + value = EXTRACT(FEATURE_NUM_BPS, feature_flag); + if (value != -1) { + realm.num_bps = (unsigned int)value; + } else { + realm.num_bps = EXTRACT(RMI_FEATURE_REGISTER_0_NUM_BPS, + realm.rmm_feat_reg0); + } + + /* Requested number of watchpoints */ + value = EXTRACT(FEATURE_NUM_WPS, feature_flag); + if (value != -1) { + realm.num_wps = (unsigned int)value; + } else { + realm.num_wps = EXTRACT(RMI_FEATURE_REGISTER_0_NUM_WPS, + realm.rmm_feat_reg0); } /* Set SVE bits from feature_flag */ @@ -238,7 +274,7 @@ bool host_create_realm_payload(u_register_t realm_payload_adr, /* Create Realm */ if (host_realm_create(&realm) != REALM_SUCCESS) { ERROR("%s() failed\n", "host_realm_create"); - goto destroy_realm; + return false; } if (host_realm_init_ipa_state(&realm, 0U, 0U, 1ULL << 32) diff --git a/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c b/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c index 012c331..3983a34 100644 --- a/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c +++ b/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c @@ -126,8 +126,8 @@ static inline u_register_t host_rmi_realm_activate(u_register_t rd) u_register_t host_rmi_realm_create(u_register_t rd, u_register_t params_ptr) { - return host_rmi_handler(&(smc_args) {RMI_REALM_CREATE, - rd, params_ptr}, 3U).ret0; + return host_rmi_handler(&(smc_args) {RMI_REALM_CREATE, rd, params_ptr}, + 3U).ret0; } u_register_t host_rmi_realm_destroy(u_register_t rd) @@ -142,8 +142,9 @@ static inline u_register_t host_rmi_data_destroy(u_register_t rd, { smc_ret_values rets; - rets = host_rmi_handler(&(smc_args) {RMI_DATA_DESTROY, - rd, map_addr, (u_register_t)&rets}, 4U); + rets = host_rmi_handler(&(smc_args) {RMI_DATA_DESTROY, rd, map_addr, + (u_register_t)&rets}, 4U); + *data = rets.ret1; *top = rets.ret2; return rets.ret0; @@ -153,9 +154,8 @@ static inline u_register_t host_rmi_rec_create(u_register_t rd, u_register_t rec, u_register_t params_ptr) { - - return host_rmi_handler(&(smc_args) {RMI_REC_CREATE, rd, rec, params_ptr}, - 4U).ret0; + return host_rmi_handler(&(smc_args) {RMI_REC_CREATE, + rd, rec, params_ptr}, 4U).ret0; } static inline u_register_t host_rmi_rec_destroy(u_register_t rec) @@ -693,17 +693,17 @@ static u_register_t host_realm_tear_down_rtt_range(struct realm *realm, u_register_t host_rmi_granule_delegate(u_register_t addr) { - return host_rmi_handler(&(smc_args){RMI_GRANULE_DELEGATE, addr}, 2U).ret0; + return host_rmi_handler(&(smc_args) {RMI_GRANULE_DELEGATE, addr}, 2U).ret0; } u_register_t host_rmi_granule_undelegate(u_register_t addr) { - return host_rmi_handler(&(smc_args){RMI_GRANULE_UNDELEGATE, addr}, 2U).ret0; + return host_rmi_handler(&(smc_args) {RMI_GRANULE_UNDELEGATE, addr}, 2U).ret0; } u_register_t host_rmi_version(void) { - return host_rmi_handler(&(smc_args){RMI_VERSION}, 1U).ret0; + return host_rmi_handler(&(smc_args) {RMI_VERSION}, 1U).ret0; } u_register_t host_realm_create(struct realm *realm) @@ -763,21 +763,23 @@ u_register_t host_realm_create(struct realm *realm) /* Populate params */ params->s2sz = EXTRACT(RMI_FEATURE_REGISTER_0_S2SZ, realm->rmm_feat_reg0); - params->sve_vl = EXTRACT(RMI_FEATURE_REGISTER_0_SVE_VL, - realm->rmm_feat_reg0); - params->num_bps = EXTRACT(RMI_FEATURE_REGISTER_0_NUM_BPS, - realm->rmm_feat_reg0); - params->num_wps = EXTRACT(RMI_FEATURE_REGISTER_0_NUM_WPS, - realm->rmm_feat_reg0); + params->num_bps = realm->num_bps; + params->num_wps = realm->num_wps; + + /* SVE enable and vector length */ + if ((realm->rmm_feat_reg0 & RMI_FEATURE_REGISTER_0_SVE_EN) != 0UL) { + params->flags = RMI_REALM_FLAGS_SVE; + params->sve_vl = realm->sve_vl; + } else { + params->flags = 0UL; + params->sve_vl = 0U; + } /* PMU enable and number of event counters */ if ((realm->rmm_feat_reg0 & RMI_FEATURE_REGISTER_0_PMU_EN) != 0UL) { - params->flags = INPLACE(RMI_REALM_FLAGS_PMU, RMI_FEATURE_TRUE); - params->pmu_num_ctrs = EXTRACT( - RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS, - realm->rmm_feat_reg0); + params->flags |= RMI_REALM_FLAGS_PMU; + params->pmu_num_ctrs = realm->pmu_num_ctrs; } else { - params->flags = INPLACE(RMI_REALM_FLAGS_PMU, RMI_FEATURE_FALSE); params->pmu_num_ctrs = 0U; } @@ -1177,7 +1179,7 @@ u_register_t host_realm_rec_enter(struct realm *realm, do { re_enter_rec = false; - ret = host_rmi_handler(&(smc_args){RMI_REC_ENTER, + ret = host_rmi_handler(&(smc_args) {RMI_REC_ENTER, realm->rec, realm->run}, 3U).ret0; VERBOSE("%s() run->exit.exit_reason=%lu " "run->exit.esr=0x%lx EC_BITS=%u ISS_DFSC_MASK=0x%lx\n", diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_payload_sve_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_payload_sve_tests.c index 3bde128..8782c9e 100644 --- a/tftf/tests/runtime_services/realm_payload/host_realm_payload_sve_tests.c +++ b/tftf/tests/runtime_services/realm_payload/host_realm_payload_sve_tests.c @@ -45,13 +45,13 @@ static sve_vector_t ns_sve_vectors_read[SVE_NUM_VECTORS] __aligned(16); static test_result_t host_create_sve_realm_payload(bool sve_en, uint8_t sve_vq) { - u_register_t rmi_feat_reg0; + u_register_t feature_flag; if (sve_en) { - rmi_feat_reg0 = RMI_FEATURE_REGISTER_0_SVE_EN | - INPLACE(RMI_FEATURE_REGISTER_0_SVE_VL, sve_vq); + feature_flag = RMI_FEATURE_REGISTER_0_SVE_EN | + INPLACE(FEATURE_SVE_VL, sve_vq); } else { - rmi_feat_reg0 = 0UL; + feature_flag = 0UL; } /* Initialise Realm payload */ @@ -60,7 +60,7 @@ static test_result_t host_create_sve_realm_payload(bool sve_en, uint8_t sve_vq) (u_register_t)(PAGE_POOL_MAX_SIZE + NS_REALM_SHARED_MEM_SIZE), (u_register_t)PAGE_POOL_MAX_SIZE, - rmi_feat_reg0)) { + feature_flag)) { return TEST_RESULT_FAIL; } @@ -90,14 +90,14 @@ test_result_t host_check_rmi_reports_proper_sve_vl(void) rmi_sve_vq = EXTRACT(RMI_FEATURE_REGISTER_0_SVE_VL, rmi_feat_reg0); /* - * configure NS to arch supported max VL and get the value reported + * Configure NS to arch supported max VL and get the value reported * by rdvl */ sve_config_vq(SVE_VQ_ARCH_MAX); ns_sve_vq = SVE_VL_TO_VQ(sve_vector_length_get()); if (rmi_sve_vq != ns_sve_vq) { - ERROR("RMI max SVE VL %u bits doesn't matches NS max " + ERROR("RMI max SVE VL %u bits don't match NS max " "SVE VL %u bits\n", SVE_VQ_TO_BITS(rmi_sve_vq), SVE_VQ_TO_BITS(ns_sve_vq)); return TEST_RESULT_FAIL; @@ -135,7 +135,7 @@ test_result_t host_sve_realm_cmd_rdvl(void) goto rm_realm; } - /* check if rdvl matches the SVE VL created */ + /* Check if rdvl matches the SVE VL created */ sd = host_get_shared_structure(); rl_output = (struct sve_cmd_rdvl *)sd->realm_cmd_output_buffer; rl_max_sve_vq = SVE_VL_TO_VQ(rl_output->rdvl); @@ -170,19 +170,12 @@ test_result_t host_sve_realm_test_invalid_vl(void) sve_vq = EXTRACT(RMI_FEATURE_REGISTER_0_SVE_VL, rmi_feat_reg0); /* - * If RMM supports MAX SVE VQ, we can't pass in an invalid sve_vq to - * create a realm, so skip the test. Else pass a sve_vq that is greater - * than the value supported by RMM and check whether creating Realm fails + * Pass a sve_vq that is greater than the value supported by RMM + * and check whether creating Realm fails */ - if (sve_vq == SVE_VQ_ARCH_MAX) { - INFO("RMI supports arch max SVE VL, skipping\n"); - return TEST_RESULT_SKIPPED; - } - rc = host_create_sve_realm_payload(true, (sve_vq + 1)); - if (rc == TEST_RESULT_SUCCESS) { - ERROR("Error: Realm created with invalid SVE VL\n"); + ERROR("Error: Realm created with invalid SVE VL %u\n", (sve_vq + 1)); host_destroy_realm(); return TEST_RESULT_FAIL; } @@ -263,9 +256,7 @@ test_result_t host_non_sve_realm_cmd_id_registers(void) static void print_sve_vl_bitmap(uint32_t vl_bitmap) { - uint8_t vq; - - for (vq = 0U; vq <= SVE_VQ_ARCH_MAX; vq++) { + for (uint8_t vq = 0U; vq <= SVE_VQ_ARCH_MAX; vq++) { if ((vl_bitmap & BIT_32(vq)) != 0U) { INFO("\t%u\n", SVE_VQ_TO_BITS(vq)); } @@ -393,17 +384,10 @@ test_result_t host_sve_realm_check_config_register(void) */ static bool callback_enter_realm(void) { - bool realm_rc; - - realm_rc = host_enter_realm_execute(REALM_SVE_OPS, NULL, + return !host_enter_realm_execute(REALM_SVE_OPS, NULL, RMI_EXIT_HOST_CALL); - if (realm_rc != true) { - return true; } - return false; -} - /* Intermittently switch to Realm while doing NS SVE ops */ test_result_t host_sve_realm_check_vectors_operations(void) { @@ -425,7 +409,7 @@ test_result_t host_sve_realm_check_vectors_operations(void) return rc; } - /* get at random value to do sve_subtract */ + /* Get at random value to do sve_subtract */ val = rand(); for (i = 0U; i < NS_SVE_OP_ARRAYSIZE; i++) { ns_sve_op_1[i] = val - i; @@ -451,6 +435,7 @@ test_result_t host_sve_realm_check_vectors_operations(void) /* Check result of SVE operations. */ rc = TEST_RESULT_SUCCESS; + for (i = 0U; i < NS_SVE_OP_ARRAYSIZE; i++) { if (ns_sve_op_1[i] != (val - i - SVE_TEST_ITERATIONS)) { ERROR("SVE op failed at idx: %u, expected: 0x%x " @@ -503,14 +488,14 @@ test_result_t host_sve_realm_check_vectors_leaked(void) /* 1. Set NS SVE VQ to max and write known pattern */ sve_config_vq(sve_vq); - (void)memset((void *)&ns_sve_vectors_write, 0xaa, + (void)memset((void *)&ns_sve_vectors_write, 0xAA, SVE_VQ_TO_BYTES(sve_vq) * SVE_NUM_VECTORS); sve_fill_vector_regs(ns_sve_vectors_write); - /* 2. NS programs ZCR_EL2 with VQ as 0 */ + /* 2. NS programs ZCR_EL2 with VQ as 0 */ sve_config_vq(SVE_VQ_ARCH_MIN); - /* 3. Create Realm with max VQ (higher than NS SVE VQ). */ + /* 3. Create Realm with max VQ (higher than NS SVE VQ) */ rc = host_create_sve_realm_payload(true, sve_vq); if (rc != TEST_RESULT_SUCCESS) { return rc; diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c index 43747b1..e6afd57 100644 --- a/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c +++ b/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c @@ -37,8 +37,7 @@ test_result_t host_test_realm_create_enter(void) (u_register_t)PAGE_POOL_BASE, (u_register_t)(PAGE_POOL_MAX_SIZE + NS_REALM_SHARED_MEM_SIZE), - (u_register_t)PAGE_POOL_MAX_SIZE, - 0UL)) { + (u_register_t)PAGE_POOL_MAX_SIZE, 0UL)) { return TEST_RESULT_FAIL; } if (!host_create_shared_mem(NS_REALM_SHARED_MEM_BASE, @@ -210,18 +209,22 @@ static bool host_realm_handle_irq_exit(struct realm *realm_ptr) static test_result_t host_test_realm_pmuv3(uint8_t cmd) { struct realm *realm_ptr; + u_register_t feature_flag; bool ret1, ret2; SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP(); host_set_pmu_state(); + feature_flag = RMI_FEATURE_REGISTER_0_PMU_EN | + INPLACE(FEATURE_PMU_NUM_CTRS, (unsigned long long)(-1)); + if (!host_create_realm_payload((u_register_t)REALM_IMAGE_BASE, (u_register_t)PAGE_POOL_BASE, (u_register_t)(PAGE_POOL_MAX_SIZE + NS_REALM_SHARED_MEM_SIZE), (u_register_t)PAGE_POOL_MAX_SIZE, - RMI_FEATURE_REGISTER_0_PMU_EN)) { + feature_flag)) { return TEST_RESULT_FAIL; } if (!host_create_shared_mem(NS_REALM_SHARED_MEM_BASE, |