mirror of https://github.com/proxmox/mirror_qemu
target/arm: Implement ARMv8.5-RNG
Use the newly introduced infrastructure for guest random numbers. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>master
parent
108b3ba891
commit
de39064567
|
@ -3521,6 +3521,11 @@ static inline bool isar_feature_aa64_condm_5(const ARMISARegisters *id)
|
|||
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) >= 2;
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa64_rndr(const ARMISARegisters *id)
|
||||
{
|
||||
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RNDR) != 0;
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
|
||||
{
|
||||
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
|
||||
|
|
|
@ -310,6 +310,7 @@ static void aarch64_max_initfn(Object *obj)
|
|||
t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
|
||||
t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
|
||||
t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* v8.5-CondM */
|
||||
t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1);
|
||||
cpu->isar.id_aa64isar0 = t;
|
||||
|
||||
t = cpu->isar.id_aa64isar1;
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include "fpu/softfloat.h"
|
||||
#include "qemu/range.h"
|
||||
#include "qapi/qapi-commands-target.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/guest-random.h"
|
||||
|
||||
#define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */
|
||||
|
||||
|
@ -5746,6 +5748,45 @@ static const ARMCPRegInfo pauth_reginfo[] = {
|
|||
.fieldoffset = offsetof(CPUARMState, keys.apib.hi) },
|
||||
REGINFO_SENTINEL
|
||||
};
|
||||
|
||||
static uint64_t rndr_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||
{
|
||||
Error *err = NULL;
|
||||
uint64_t ret;
|
||||
|
||||
/* Success sets NZCV = 0000. */
|
||||
env->NF = env->CF = env->VF = 0, env->ZF = 1;
|
||||
|
||||
if (qemu_guest_getrandom(&ret, sizeof(ret), &err) < 0) {
|
||||
/*
|
||||
* ??? Failed, for unknown reasons in the crypto subsystem.
|
||||
* The best we can do is log the reason and return the
|
||||
* timed-out indication to the guest. There is no reason
|
||||
* we know to expect this failure to be transitory, so the
|
||||
* guest may well hang retrying the operation.
|
||||
*/
|
||||
qemu_log_mask(LOG_UNIMP, "%s: Crypto failure: %s",
|
||||
ri->name, error_get_pretty(err));
|
||||
error_free(err);
|
||||
|
||||
env->ZF = 0; /* NZCF = 0100 */
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* We do not support re-seeding, so the two registers operate the same. */
|
||||
static const ARMCPRegInfo rndr_reginfo[] = {
|
||||
{ .name = "RNDR", .state = ARM_CP_STATE_AA64,
|
||||
.type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END | ARM_CP_IO,
|
||||
.opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 0,
|
||||
.access = PL0_R, .readfn = rndr_readfn },
|
||||
{ .name = "RNDRRS", .state = ARM_CP_STATE_AA64,
|
||||
.type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END | ARM_CP_IO,
|
||||
.opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 1,
|
||||
.access = PL0_R, .readfn = rndr_readfn },
|
||||
REGINFO_SENTINEL
|
||||
};
|
||||
#endif
|
||||
|
||||
static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
|
@ -6690,6 +6731,9 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
|||
if (cpu_isar_feature(aa64_pauth, cpu)) {
|
||||
define_arm_cp_regs(cpu, pauth_reginfo);
|
||||
}
|
||||
if (cpu_isar_feature(aa64_rndr, cpu)) {
|
||||
define_arm_cp_regs(cpu, rndr_reginfo);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue