[Stable-11.0.4 v2 125/161] target/s390x: Make PRNO TRNG interruptible
Michael Tokarev <[email protected]>
| Newsgroups | gmane.comp.emulators.qemu.stable,gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
From: Ilya Leoshkevich <[email protected]> fill_buf_random() writes the entire guest-requested amount of random bytes in one go. Since the length is a full 64-bit value, a guest can request several gigabytes and keep the vCPU spinning inside the helper, without a chance to react to interrupts. Do the same thing as HELPER(mvcl): check cpu_loop_exit_requested() at the bottom of the loop, and when a return to the main loop is pending, stop and report partial completion with condition code 3. Reported-by: Christian Borntraeger <[email protected]> Fixes: 3dbc5fdacb5a ("target/s390x: support PRNO_TRNG instruction") Cc: [email protected] Reviewed-by: Richard Henderson <[email protected]> Signed-off-by: Ilya Leoshkevich <[email protected]> Reviewed-by: Harald Freudenberger <[email protected]> Link: https://lore.kernel.org/qemu-devel/[email protected] Signed-off-by: Eric Farman <[email protected]> (cherry picked from commit aae77f5dddef62da7e1479c257d99d2ab574df56) (Mjt: context fixup for v11.0.0-713-gde96db79aa58 "target/s390x: Compile crypto_helper.c as common unit") Signed-off-by: Michael Tokarev <[email protected]> diff --git a/target/s390x/tcg/crypto_helper.c b/target/s390x/tcg/crypto_helper.c index 074d745eb3f..2a947a88c97 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -16,6 +16,7 @@ #include "qemu/guest-random.h" #include "s390x-internal.h" #include "tcg_s390x.h" +#include "exec/cpu-common.h" #include "exec/helper-proto.h" #include "accel/tcg/cpu-ldst.h" #include "accel/tcg/cpu-mmu-index.h" @@ -245,8 +246,8 @@ static int cpacf_sha512(CPUS390XState *env, const int mmu_idx, uintptr_t ra, return !len ? 0 : 3; } -static void fill_buf_random(CPUS390XState *env, const int mmu_idx, uintptr_t ra, - uint64_t *buf_reg, uint64_t *len_reg) +static int fill_buf_random(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t *buf_reg, uint64_t *len_reg) { uint8_t tmp[256]; uint64_t len = *len_reg; @@ -267,7 +268,13 @@ static void fill_buf_random(CPUS390XState *env, const int mmu_idx, uintptr_t ra, --*len_reg; } len -= block; + + if (cpu_loop_exit_requested(env_cpu(env))) { + break; + } } + + return len == 0 ? 0 : 3; } uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t r3, @@ -280,6 +287,7 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t r3, uint8_t subfunc[16] = { 0 }; uint64_t param_addr; int i; + int cc; switch (type) { case S390_FEAT_TYPE_KMAC: @@ -309,9 +317,13 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t r3, return cpacf_sha512(env, mmu_idx, ra, env->regs[1], &env->regs[r2], &env->regs[r2 + 1], type); case 114: /* CPACF_PRNO_TRNG */ - fill_buf_random(env, mmu_idx, ra, &env->regs[r1], &env->regs[r1 + 1]); - fill_buf_random(env, mmu_idx, ra, &env->regs[r2], &env->regs[r2 + 1]); - break; + cc = fill_buf_random(env, mmu_idx, ra, + &env->regs[r1], &env->regs[r1 + 1]); + if (cc == 0) { + cc = fill_buf_random(env, mmu_idx, ra, + &env->regs[r2], &env->regs[r2 + 1]); + } + return cc; default: /* we don't implement any other subfunction yet */ g_assert_not_reached(); -- 2.47.3