All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] target/s390x/tcg: fix register update on guest memory fault in cpacf_aes_ecb
@ 2026-10-08 15:44 Andrew Holden
  2026-10-09  7:42 ` Harald Freudenberger
  0 siblings, 1 reply; 3+ messages in thread
From: Andrew Holden @ 2026-10-08 15:44 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-s390x, iii, richard.henderson, david, cohuck, freude,
	Andrew Holden

The KM instruction loop in cpacf_aes_ecb() updated the source pointer,
destination pointer, and length registers only after the entire loop
completed, using a 'done' accumulator. If a guest memory access fault
fires mid-loop, siglongjmp unwinds the C stack before the register
update is reached. The registers then reflect block 0 rather than the
block being processed, causing the instruction to restart from the
beginning on every fault. This results in quadratic reprocessing and
violates the PoP requirement that registers reflect partial completion
per block processed.

Fix this by updating the registers inside the loop body after each
successfully processed block, and removing the 'done' accumulator.

Signed-off-by: Andrew Holden <andy0x48@linux.ibm.com>
---
 target/s390x/tcg/cpacf_aes.c | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/target/s390x/tcg/cpacf_aes.c b/target/s390x/tcg/cpacf_aes.c
index 92884c4120..41ebc57087 100644
--- a/target/s390x/tcg/cpacf_aes.c
+++ b/target/s390x/tcg/cpacf_aes.c
@@ -62,7 +62,7 @@ int cpacf_aes_ecb(CPUS390XState *env, const int mmu_idx, uintptr_t ra,
 {
     enum { MAX_BLOCKS_PER_RUN = 8192 / AES_BLOCK_SIZE };
     uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE];
-    uint64_t len = *src_len_reg, done = 0;
+    uint64_t len = *src_len_reg;
     int i, keysize, addr_reg_size;
     uint8_t key[32];
     AES_KEY exkey;
@@ -116,23 +116,21 @@ int cpacf_aes_ecb(CPUS390XState *env, const int mmu_idx, uintptr_t ra,
 
     /* process up to MAX_BLOCKS_PER_RUN aes blocks */
     for (i = 0; i < MAX_BLOCKS_PER_RUN && len >= AES_BLOCK_SIZE; i++) {
-        aes_read_block(env, mmu_idx, ra, *src_ptr_reg + done, in);
+        aes_read_block(env, mmu_idx, ra, *src_ptr_reg, in);
         if (mod) {
             AES_decrypt(in, out, &exkey);
         } else {
             AES_encrypt(in, out, &exkey);
         }
-        aes_write_block(env, mmu_idx, ra, *dst_ptr_reg + done, out);
+        aes_write_block(env, mmu_idx, ra, *dst_ptr_reg, out);
+        *src_ptr_reg = deposit64(*src_ptr_reg, 0, addr_reg_size,
+                                 *src_ptr_reg + AES_BLOCK_SIZE);
+        *dst_ptr_reg = deposit64(*dst_ptr_reg, 0, addr_reg_size,
+                                 *dst_ptr_reg + AES_BLOCK_SIZE);
+        *src_len_reg -= AES_BLOCK_SIZE;
         len -= AES_BLOCK_SIZE;
-        done += AES_BLOCK_SIZE;
     }
 
-    *src_ptr_reg = deposit64(*src_ptr_reg, 0, addr_reg_size,
-                             *src_ptr_reg + done);
-    *dst_ptr_reg = deposit64(*dst_ptr_reg, 0, addr_reg_size,
-                             *dst_ptr_reg + done);
-    *src_len_reg -= done;
-
     return !len ? 0 : 3;
 }
 
-- 
2.56.0



^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-10-12  9:22 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-08 15:44 [PATCH] target/s390x/tcg: fix register update on guest memory fault in cpacf_aes_ecb Andrew Holden
2026-10-09  7:42 ` Harald Freudenberger
2026-10-12  9:21   ` Andrew Holden

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.