Refactor "do_hash_operation()" by extracting hash execution and result handling into dedicated helper functions:
- "hash_write_digest_and_unmap_iov()": Writes the digest result to memory and unmaps IOVs after processing. - "hash_execute_non_acc_mode()": Handles one-shot (non-accumulated) hash operations. - "hash_execute_acc_mode()": Handles accumulated hashing, including update and finalize logic. No functional changes introduced. Signed-off-by: Jamin Lin <jamin_...@aspeedtech.com> --- hw/misc/aspeed_hace.c | 133 ++++++++++++++++++++++++++---------------- 1 file changed, 83 insertions(+), 50 deletions(-) diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index 22eea62693..eb513ba00f 100644 --- a/hw/misc/aspeed_hace.c +++ b/hw/misc/aspeed_hace.c @@ -228,26 +228,96 @@ static int hash_prepare_sg_iov(AspeedHACEState *s, struct iovec *iov, return iov_idx; } -static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode, - bool acc_mode) +static void hash_write_digest_and_unmap_iov(AspeedHACEState *s, + struct iovec *iov, + int iov_idx, + uint8_t *digest_buf, + size_t digest_len) +{ + if (address_space_write(&s->dram_as, s->regs[R_HASH_DEST], + MEMTXATTRS_UNSPECIFIED, digest_buf, digest_len)) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Failed to write digest to 0x%x\n", + __func__, s->regs[R_HASH_DEST]); + } + + for (; iov_idx > 0; iov_idx--) { + address_space_unmap(&s->dram_as, iov[iov_idx - 1].iov_base, + iov[iov_idx - 1].iov_len, false, + iov[iov_idx - 1].iov_len); + } +} + +static void hash_execute_non_acc_mode(AspeedHACEState *s, int algo, + struct iovec *iov, int iov_idx) { g_autofree uint8_t *digest_buf = NULL; - struct iovec iov[ASPEED_HACE_MAX_SG]; - bool acc_final_request = false; Error *local_err = NULL; - size_t digest_len = 0; - int iov_idx = -1; + size_t digest_len; + + if (qcrypto_hash_bytesv(algo, iov, iov_idx, &digest_buf, + &digest_len, &local_err) < 0) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: qcrypto hash bytesv failed : %s", + __func__, error_get_pretty(local_err)); + error_free(local_err); + return; + } + + hash_write_digest_and_unmap_iov(s, iov, iov_idx, digest_buf, digest_len); +} + +static void hash_execute_acc_mode(AspeedHACEState *s, int algo, + struct iovec *iov, int iov_idx, + bool final_request) +{ + g_autofree uint8_t *digest_buf = NULL; + Error *local_err = NULL; + size_t digest_len; - if (acc_mode && s->hash_ctx == NULL) { + if (s->hash_ctx == NULL) { s->hash_ctx = qcrypto_hash_new(algo, &local_err); if (s->hash_ctx == NULL) { - qemu_log_mask(LOG_GUEST_ERROR, "qcrypto hash failed : %s", - error_get_pretty(local_err)); + qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto hash new failed : %s", + __func__, error_get_pretty(local_err)); error_free(local_err); return; } } + if (qcrypto_hash_updatev(s->hash_ctx, iov, iov_idx, &local_err) < 0) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto hash updatev failed : %s", + __func__, error_get_pretty(local_err)); + error_free(local_err); + return; + } + + if (final_request) { + if (qcrypto_hash_finalize_bytes(s->hash_ctx, &digest_buf, + &digest_len, &local_err)) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: qcrypto hash finalize bytes failed : %s", + __func__, error_get_pretty(local_err)); + error_free(local_err); + local_err = NULL; + } + + qcrypto_hash_free(s->hash_ctx); + + s->hash_ctx = NULL; + s->total_req_len = 0; + } + + hash_write_digest_and_unmap_iov(s, iov, iov_idx, digest_buf, digest_len); +} + +static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode, + bool acc_mode) +{ + struct iovec iov[ASPEED_HACE_MAX_SG]; + bool acc_final_request = false; + int iov_idx = -1; + /* Prepares the iov for hashing operations based on the selected mode */ if (sg_mode) { iov_idx = hash_prepare_sg_iov(s, iov, acc_mode, &acc_final_request); @@ -261,48 +331,11 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode, return; } + /* Executes the hash operation */ if (acc_mode) { - if (qcrypto_hash_updatev(s->hash_ctx, iov, iov_idx, &local_err) < 0) { - qemu_log_mask(LOG_GUEST_ERROR, "qcrypto hash update failed : %s", - error_get_pretty(local_err)); - error_free(local_err); - return; - } - - if (acc_final_request) { - if (qcrypto_hash_finalize_bytes(s->hash_ctx, &digest_buf, - &digest_len, &local_err)) { - qemu_log_mask(LOG_GUEST_ERROR, - "qcrypto hash finalize failed : %s", - error_get_pretty(local_err)); - error_free(local_err); - local_err = NULL; - } - - qcrypto_hash_free(s->hash_ctx); - - s->hash_ctx = NULL; - s->total_req_len = 0; - } - } else if (qcrypto_hash_bytesv(algo, iov, iov_idx, &digest_buf, - &digest_len, &local_err) < 0) { - qemu_log_mask(LOG_GUEST_ERROR, "qcrypto hash bytesv failed : %s", - error_get_pretty(local_err)); - error_free(local_err); - return; - } - - if (address_space_write(&s->dram_as, s->regs[R_HASH_DEST], - MEMTXATTRS_UNSPECIFIED, - digest_buf, digest_len)) { - qemu_log_mask(LOG_GUEST_ERROR, - "aspeed_hace: address space write failed\n"); - } - - for (; iov_idx > 0; iov_idx--) { - address_space_unmap(&s->dram_as, iov[iov_idx - 1].iov_base, - iov[iov_idx - 1].iov_len, false, - iov[iov_idx - 1].iov_len); + hash_execute_acc_mode(s, algo, iov, iov_idx, acc_final_request); + } else { + hash_execute_non_acc_mode(s, algo, iov, iov_idx); } } -- 2.43.0