Skip to content

Commit 34577fc

Browse files
rth7680pm215
authored andcommitted
target/arm: Redirect VHE FOO_EL1 -> FOO_EL2 during translation
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
1 parent e87878d commit 34577fc

File tree

4 files changed

+21
-52
lines changed

4 files changed

+21
-52
lines changed

target/arm/cpregs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,12 @@ struct ARMCPRegInfo {
936936
*/
937937
uint32_t nv2_redirect_offset;
938938

939+
/*
940+
* With VHE, with E2H, at EL2, access to this EL0/EL1 reg redirects
941+
* to the EL2 reg with the specified key.
942+
*/
943+
uint32_t vhe_redir_to_el2;
944+
939945
/* This is used only by VHE. */
940946
void *opaque;
941947
/*

target/arm/gdbstub.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,11 @@ static int arm_gdb_get_sysreg(CPUState *cs, GByteArray *buf, int reg)
249249
if (ri) {
250250
switch (cpreg_field_type(ri)) {
251251
case MO_64:
252+
if (ri->vhe_redir_to_el2 &&
253+
(arm_hcr_el2_eff(env) & HCR_E2H) &&
254+
arm_current_el(env) == 2) {
255+
ri = get_arm_cp_reginfo(cpu->cp_regs, ri->vhe_redir_to_el2);
256+
}
252257
return gdb_get_reg64(buf, (uint64_t)read_raw_cp_reg(env, ri));
253258
case MO_32:
254259
return gdb_get_reg32(buf, (uint32_t)read_raw_cp_reg(env, ri));

target/arm/helper.c

Lines changed: 1 addition & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4417,47 +4417,6 @@ static CPAccessResult access_el1nvvct(CPUARMState *env, const ARMCPRegInfo *ri,
44174417
return e2h_access(env, ri, isread);
44184418
}
44194419

4420-
/* Test if system register redirection is to occur in the current state. */
4421-
static bool redirect_for_e2h(CPUARMState *env)
4422-
{
4423-
return arm_current_el(env) == 2 && (arm_hcr_el2_eff(env) & HCR_E2H);
4424-
}
4425-
4426-
static uint64_t el2_e2h_read(CPUARMState *env, const ARMCPRegInfo *ri)
4427-
{
4428-
CPReadFn *readfn;
4429-
4430-
if (redirect_for_e2h(env)) {
4431-
/* Switch to the saved EL2 version of the register. */
4432-
ri = ri->opaque;
4433-
readfn = ri->readfn;
4434-
} else {
4435-
readfn = ri->orig_readfn;
4436-
}
4437-
if (readfn == NULL) {
4438-
readfn = raw_read;
4439-
}
4440-
return readfn(env, ri);
4441-
}
4442-
4443-
static void el2_e2h_write(CPUARMState *env, const ARMCPRegInfo *ri,
4444-
uint64_t value)
4445-
{
4446-
CPWriteFn *writefn;
4447-
4448-
if (redirect_for_e2h(env)) {
4449-
/* Switch to the saved EL2 version of the register. */
4450-
ri = ri->opaque;
4451-
writefn = ri->writefn;
4452-
} else {
4453-
writefn = ri->orig_writefn;
4454-
}
4455-
if (writefn == NULL) {
4456-
writefn = raw_write;
4457-
}
4458-
writefn(env, ri, value);
4459-
}
4460-
44614420
static uint64_t el2_e2h_e12_read(CPUARMState *env, const ARMCPRegInfo *ri)
44624421
{
44634422
/* Pass the EL1 register accessor its ri, not the EL12 alias ri */
@@ -4632,17 +4591,7 @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
46324591
(gpointer)(uintptr_t)a->new_key, new_reg);
46334592
g_assert(ok);
46344593

4635-
src_reg->opaque = dst_reg;
4636-
src_reg->orig_readfn = src_reg->readfn ?: raw_read;
4637-
src_reg->orig_writefn = src_reg->writefn ?: raw_write;
4638-
if (!src_reg->raw_readfn) {
4639-
src_reg->raw_readfn = raw_read;
4640-
}
4641-
if (!src_reg->raw_writefn) {
4642-
src_reg->raw_writefn = raw_write;
4643-
}
4644-
src_reg->readfn = el2_e2h_read;
4645-
src_reg->writefn = el2_e2h_write;
4594+
src_reg->vhe_redir_to_el2 = a->dst_key;
46464595
}
46474596
}
46484597
#endif

target/arm/tcg/translate-a64.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2573,6 +2573,15 @@ static void handle_sys(DisasContext *s, bool isread,
25732573
}
25742574
}
25752575

2576+
if (ri->vhe_redir_to_el2 && s->current_el == 2 && s->e2h) {
2577+
/*
2578+
* This one of the FOO_EL1 registers which redirect to FOO_EL2
2579+
* from EL2 when HCR_EL2.E2H is set.
2580+
*/
2581+
key = ri->vhe_redir_to_el2;
2582+
ri = redirect_cpreg(s, key, isread);
2583+
}
2584+
25762585
if (ri->accessfn || (ri->fgt && s->fgt_active)) {
25772586
/* Emit code to perform further access permissions checks at
25782587
* runtime; this may result in an exception.

0 commit comments

Comments
 (0)