@samitouri / QOSamiQemu / commits / 29315d22b2

hw/tpm: Add internal buffer state for chunking

- Introduce GByteArray buffers to hold the command request and response data during chunked TPM CRB transactions. - Add helper function to clean them. Signed-off-by: Arun Menon <armenon@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com> Link: https://lore.kernel.org/qemu-devel/20260506075813.120781-4-armenon@redhat.com Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>

Arun Menon committed May 6, 2026 at 13:28 UTC 29315d22b25930692b21f76b8c71910196bf960b
1 file changed +29 -4
hw/tpm/tpm_crb.c
+29 -4
@@ -38,10 +38,13 @@ struct CRBState {
38 TPMBackend *tpmbe;
39 TPMBackendCmd cmd;
40 uint32_t regs[TPM_CRB_R_MAX];
41 + size_t be_buffer_size;
42 MemoryRegion mmio;
43 MemoryRegion cmdmem;
44
44 - size_t be_buffer_size;
45 + GByteArray *command_buffer;
46 + GByteArray *response_buffer;
47 + uint32_t response_offset;
48
49 TPMPPI ppi;
50
@@ -86,6 +89,13 @@ enum crb_cancel {
89
90 #define TPM_CRB_NO_LOCALITY 0xff
91
92 +static void tpm_crb_clear_internal_buffers(CRBState *s)
93 +{
94 + g_byte_array_set_size(s->response_buffer, 0);
95 + g_byte_array_set_size(s->command_buffer, 0);
96 + s->response_offset = 0;
97 +}
98 +
99 static uint64_t tpm_crb_mmio_read(void *opaque, hwaddr addr,
100 unsigned size)
101 {
@@ -135,9 +145,11 @@ static void tpm_crb_mmio_write(void *opaque, hwaddr addr,
145 }
146 break;
147 case A_CRB_CTRL_CANCEL:
138 - if (val == CRB_CANCEL_INVOKE &&
139 - s->regs[R_CRB_CTRL_START] & CRB_START_INVOKE) {
140 - tpm_backend_cancel_cmd(s->tpmbe);
148 + if (val == CRB_CANCEL_INVOKE) {
149 + if (s->regs[R_CRB_CTRL_START] & CRB_START_INVOKE) {
150 + tpm_backend_cancel_cmd(s->tpmbe);
151 + }
152 + tpm_crb_clear_internal_buffers(s);
153 }
154 break;
155 case A_CRB_CTRL_START:
@@ -239,6 +251,7 @@ static void tpm_crb_reset(void *dev)
251
252 tpm_ppi_reset(&s->ppi);
253 tpm_backend_reset(s->tpmbe);
254 + tpm_crb_clear_internal_buffers(s);
255
256 memset(s->regs, 0, sizeof(s->regs));
257
@@ -305,6 +318,9 @@ static void tpm_crb_realize(DeviceState *dev, Error **errp)
318 memory_region_add_subregion(get_system_memory(),
319 TPM_CRB_ADDR_BASE + sizeof(s->regs), &s->cmdmem);
320
321 + s->command_buffer = g_byte_array_new();
322 + s->response_buffer = g_byte_array_new();
323 +
324 tpm_ppi_init(&s->ppi, get_system_memory(),
325 TPM_PPI_ADDR_BASE, OBJECT(s));
326
@@ -315,12 +331,21 @@ static void tpm_crb_realize(DeviceState *dev, Error **errp)
331 }
332 }
333
334 +static void tpm_crb_unrealize(DeviceState *dev)
335 +{
336 + CRBState *s = CRB(dev);
337 +
338 + g_clear_pointer(&s->command_buffer, g_byte_array_unref);
339 + g_clear_pointer(&s->response_buffer, g_byte_array_unref);
340 +}
341 +
342 static void tpm_crb_class_init(ObjectClass *klass, const void *data)
343 {
344 DeviceClass *dc = DEVICE_CLASS(klass);
345 TPMIfClass *tc = TPM_IF_CLASS(klass);
346
347 dc->realize = tpm_crb_realize;
348 + dc->unrealize = tpm_crb_unrealize;
349 device_class_set_props(dc, tpm_crb_properties);
350 dc->vmsd = &vmstate_tpm_crb;
351 dc->user_creatable = true;