RE: [PATCH v3 03/16] hw/misc/aspeed_hace: Support scatter-gather mode for the crypto command
Kane Chen <[email protected]>
| Newsgroups | org.nongnu.qemu-arm,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <SI6PR06MB7631B92531CED76C4C358857F7DD2@SI6PR06MB7631.apcprd06.prod.outlook.com> |
> -----Original Message----- > From: Jamin Lin <[email protected]> > Sent: Tuesday, August 11, 2026 11:11 AM > To: Daniel P. Berrangé <[email protected]>; Cédric Le Goater > <[email protected]>; Peter Maydell <[email protected]>; Steven Lee > <[email protected]>; Troy Lee <[email protected]>; Kane Chen > <[email protected]>; Andrew Jeffery > <[email protected]>; Joel Stanley <[email protected]>; Eric Blake > <[email protected]>; Markus Armbruster <[email protected]>; Fabiano > Rosas <[email protected]>; Laurent Vivier <[email protected]>; Paolo Bonzini > <[email protected]>; open list:All patches CC here > <[email protected]>; open list:ASPEED BMCs > <[email protected]> > Cc: Jamin Lin <[email protected]>; Troy Lee > <[email protected]> > Subject: [PATCH v3 03/16] hw/misc/aspeed_hace: Support scatter-gather mode > for the crypto command > > The AST2600 and later crypto engines drive the source and destination through > scatter-gather lists (HACE10[18]/[19]) rather than the single contiguous buffers > used by the AST2500 direct access mode. Each SG list entry is a length word > (SG_LIST_LEN_LAST marks the final entry) followed by a DRAM address, > matching the hash engine layout. > > Add a crypt_prepare_sg() helper that gathers the source into / scatters the > destination out of the bounce buffer by walking the SG list, and select it or the > existing crypt_prepare_direct() from do_crypt_operation based on HACE10[18], > mirroring the hash engine's direct/scatter-gather dispatch. > > Signed-off-by: Jamin Lin <[email protected]> > --- > hw/misc/aspeed_hace.c | 70 > +++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 64 insertions(+), 6 deletions(-) > > diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index > 0f35d74137..646ff50476 100644 > --- a/hw/misc/aspeed_hace.c > +++ b/hw/misc/aspeed_hace.c > @@ -608,13 +608,58 @@ static bool crypt_prepare_direct(AspeedHACEState > *s, uint64_t addr, } > > /* > - * Perform an AES/DES/3DES ECB/CBC operation in direct access mode: the > source > - * and destination are single contiguous buffers (HACE00/HACE04) and the > IV/key > - * come from the context buffer (HACE08). For CBC the resulting chaining IV is > - * written back to the context buffer so the driver can continue the chain. > + * Scatter-gather mode: the source/destination register points at an SG > +list > + * whose entries are a length word (SG_LIST_LEN_LAST flags the final > +entry) > + * followed by a DRAM address, matching the hash engine layout. Gather > +@len > + * bytes into @buf, or scatter @buf back out when @to_dram is true. > + * Returns true on success. > + */ > +static bool crypt_prepare_sg(AspeedHACEState *s, uint64_t addr, > + uint8_t *buf, uint32_t len, bool to_dram) > +{ > + uint32_t copied = 0; > + uint32_t sg_addr; > + uint32_t sg_len; > + uint32_t entry; > + int i; > + > + for (i = 0; i < ASPEED_HACE_MAX_SG && copied < len; i++) { > + entry = address_space_ldl_le(&s->dram_as, addr, > + MEMTXATTRS_UNSPECIFIED, > NULL); > + sg_addr = address_space_ldl_le(&s->dram_as, addr + > SG_LIST_LEN_SIZE, > + MEMTXATTRS_UNSPECIFIED, > NULL); > + sg_len = entry & SG_LIST_LEN_MASK; > + > + sg_addr &= SG_LIST_ADDR_MASK; > + addr += SG_LIST_ENTRY_SIZE; > + > + if (sg_len > len - copied) { > + sg_len = len - copied; > + } > + if (address_space_rw(&s->dram_as, sg_addr, > MEMTXATTRS_UNSPECIFIED, > + buf + copied, sg_len, to_dram)) { > + return false; > + } > + copied += sg_len; > + > + if (entry & SG_LIST_LEN_LAST) { > + break; > + } > + } > + > + return copied == len; > +} > + > +/* > + * Perform an AES/DES/3DES ECB/CBC operation. The source and > +destination are > + * either single contiguous buffers (direct access mode) or > +scatter-gather > + * lists (HACE10[18]/[19]), addressed by HACE00/HACE04; the IV/key come > +from > + * the context buffer (HACE08). For CBC the resulting chaining IV is > +written > + * back to the context buffer so the driver can continue the chain. > */ > static void do_crypt_operation(AspeedHACEState *s, uint32_t cmd) { > + bool sg_mode = cmd & CRYPT_CMD_SRC_SG_CTRL; > uint32_t len = s->regs[R_CRYPT_DATA_LEN]; > bool encrypt = cmd & CRYPT_CMD_ENCRYPT; > g_autoptr(QCryptoCipher) cipher = NULL; @@ -631,6 +676,7 @@ static > void do_crypt_operation(AspeedHACEState *s, uint32_t cmd) > size_t iv_offset; > size_t blocklen; > size_t keylen; > + bool status; > > if (len == 0) { > return; > @@ -684,8 +730,14 @@ static void do_crypt_operation(AspeedHACEState *s, > uint32_t cmd) > src_buf = g_malloc0(len); > dst_buf = g_malloc0(len); > > + /* Gather the source into the bounce buffer, per the selected mode. > + */ > src_addr = s->regs[R_CRYPT_SRC]; > - if (!crypt_prepare_direct(s, src_addr, src_buf, len, false)) { > + if (sg_mode) { > + status = crypt_prepare_sg(s, src_addr, src_buf, len, false); > + } else { > + status = crypt_prepare_direct(s, src_addr, src_buf, len, false); > + } > + if (!status) { > qemu_log_mask(LOG_GUEST_ERROR, > "%s: Failed to read src, addr=0x%" HWADDR_PRIx > "\n", > __func__, src_addr); @@ -714,8 +766,14 @@ > static void do_crypt_operation(AspeedHACEState *s, uint32_t cmd) > } > } > > + /* Scatter the result back out, per the selected mode. */ > dst_addr = s->regs[R_CRYPT_DEST]; > - if (!crypt_prepare_direct(s, dst_addr, dst_buf, len, true)) { > + if (sg_mode) { > + status = crypt_prepare_sg(s, dst_addr, dst_buf, len, true); > + } else { > + status = crypt_prepare_direct(s, dst_addr, dst_buf, len, true); > + } > + if (!status) { > qemu_log_mask(LOG_GUEST_ERROR, > "%s: Failed to write dst, addr=0x%" HWADDR_PRIx > "\n", > __func__, dst_addr); > -- > 2.43.0 Reviewed-by: Kane Chen <[email protected]>