mirror of https://github.com/xemu-project/xemu.git
target/arm: Improve IMPDEF algorithm for IRG
When GCR_EL1.RRND==1, the choosing of the random value is IMPDEF, and the kernel is not expected to have set RGSR_EL1. Force a non-zero value into SEED, so that we do not continually return the same tag. Reported-by: Vincenzo Frascino <vincenzo.frascino@arm.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20200724163853.504655-4-richard.henderson@linaro.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
7ad01d78a9
commit
d4f6dda182
|
@ -24,6 +24,8 @@
|
||||||
#include "exec/ram_addr.h"
|
#include "exec/ram_addr.h"
|
||||||
#include "exec/cpu_ldst.h"
|
#include "exec/cpu_ldst.h"
|
||||||
#include "exec/helper-proto.h"
|
#include "exec/helper-proto.h"
|
||||||
|
#include "qapi/error.h"
|
||||||
|
#include "qemu/guest-random.h"
|
||||||
|
|
||||||
|
|
||||||
static int choose_nonexcluded_tag(int tag, int offset, uint16_t exclude)
|
static int choose_nonexcluded_tag(int tag, int offset, uint16_t exclude)
|
||||||
|
@ -211,16 +213,37 @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx,
|
||||||
|
|
||||||
uint64_t HELPER(irg)(CPUARMState *env, uint64_t rn, uint64_t rm)
|
uint64_t HELPER(irg)(CPUARMState *env, uint64_t rn, uint64_t rm)
|
||||||
{
|
{
|
||||||
int rtag;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Our IMPDEF choice for GCR_EL1.RRND==1 is to behave as if
|
|
||||||
* GCR_EL1.RRND==0, always producing deterministic results.
|
|
||||||
*/
|
|
||||||
uint16_t exclude = extract32(rm | env->cp15.gcr_el1, 0, 16);
|
uint16_t exclude = extract32(rm | env->cp15.gcr_el1, 0, 16);
|
||||||
|
int rrnd = extract32(env->cp15.gcr_el1, 16, 1);
|
||||||
int start = extract32(env->cp15.rgsr_el1, 0, 4);
|
int start = extract32(env->cp15.rgsr_el1, 0, 4);
|
||||||
int seed = extract32(env->cp15.rgsr_el1, 8, 16);
|
int seed = extract32(env->cp15.rgsr_el1, 8, 16);
|
||||||
int offset, i;
|
int offset, i, rtag;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Our IMPDEF choice for GCR_EL1.RRND==1 is to continue to use the
|
||||||
|
* deterministic algorithm. Except that with RRND==1 the kernel is
|
||||||
|
* not required to have set RGSR_EL1.SEED != 0, which is required for
|
||||||
|
* the deterministic algorithm to function. So we force a non-zero
|
||||||
|
* SEED for that case.
|
||||||
|
*/
|
||||||
|
if (unlikely(seed == 0) && rrnd) {
|
||||||
|
do {
|
||||||
|
Error *err = NULL;
|
||||||
|
uint16_t two;
|
||||||
|
|
||||||
|
if (qemu_guest_getrandom(&two, sizeof(two), &err) < 0) {
|
||||||
|
/*
|
||||||
|
* Failed, for unknown reasons in the crypto subsystem.
|
||||||
|
* Best we can do is log the reason and use a constant seed.
|
||||||
|
*/
|
||||||
|
qemu_log_mask(LOG_UNIMP, "IRG: Crypto failure: %s\n",
|
||||||
|
error_get_pretty(err));
|
||||||
|
error_free(err);
|
||||||
|
two = 1;
|
||||||
|
}
|
||||||
|
seed = two;
|
||||||
|
} while (seed == 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* RandomTag */
|
/* RandomTag */
|
||||||
for (i = offset = 0; i < 4; ++i) {
|
for (i = offset = 0; i < 4; ++i) {
|
||||||
|
|
Loading…
Reference in New Issue