hw: fix vmm_arm test on arm_v8a

Fixes #4975 regression
This commit is contained in:
Christian Prochaska 2023-09-30 15:29:02 +02:00 committed by Christian Helmuth
parent ae899b9bc7
commit aea90dc7da
6 changed files with 124 additions and 119 deletions

View File

@ -38,15 +38,14 @@ struct Genode::Vcpu_state : Genode::Cpu_state
Genode::uint64_t exception_type { 0 }; Genode::uint64_t exception_type { 0 };
Genode::uint64_t esr_el2 { 0 }; Genode::uint64_t esr_el2 { 0 };
/** Fpu registers **/ /** Fpu registers - q must start at 16-byte aligned offset **/
Genode::uint128_t q[32] { 0 };
Genode::uint32_t fpcr { 0 }; Genode::uint32_t fpcr { 0 };
Genode::uint32_t fpsr { 0 }; Genode::uint32_t fpsr { 0 };
Genode::uint128_t q[32] { 0 };
Genode::uint64_t elr_el1 { 0 }; Genode::uint64_t elr_el1 { 0 };
Genode::uint64_t sp_el1 { 0 }; Genode::uint64_t sp_el1 { 0 };
Genode::uint32_t spsr_el1 { 0 }; Genode::uint64_t spsr_el1 { 0 };
Genode::uint32_t esr_el1 { 0 };
Genode::uint64_t sctlr_el1 { 0 }; Genode::uint64_t sctlr_el1 { 0 };
Genode::uint64_t actlr_el1 { 0 }; Genode::uint64_t actlr_el1 { 0 };

View File

@ -34,13 +34,14 @@
stp x29, x30, [x0], #16 stp x29, x30, [x0], #16
mrs x1, sp_el0 mrs x1, sp_el0
mrs x2, elr_el1 mrs x2, elr_el1
mrs x3, spsr_el1 mrs x3, esr_el1
mrs x4, mdscr_el1 mrs x4, spsr_el1
adr x5, . mrs x5, mdscr_el1
and x5, x5, #0xf80 adr x6, .
and x6, x6, #0xf80
stp x1, x2, [x0], #16 stp x1, x2, [x0], #16
stp xzr, x3, [x0], #16 /* ec will be updated later if needed */ stp x3, x4, [x0], #16
stp x4, x5, [x0], #16 stp x5, x6, [x0], #16
b _kernel_entry b _kernel_entry
.balign 128 .balign 128
.endr .endr
@ -93,7 +94,7 @@ _kernel_entry:
mov sp, x1 /* reset stack */ mov sp, x1 /* reset stack */
str x0, [sp, #-16] /* store cpu state pointer */ str x0, [sp, #-16] /* store cpu state pointer */
add x1, x0, #8*31 add x1, x0, #8*31
ldp x2, x3, [x1], #16+8 /* load sp, ip, skip ec */ ldp x2, x3, [x1], #16+8 /* load sp, ip, skip esr_el1 */
ldp x4, x5, [x1], #16+8 /* load pstate, mdscr_el1, skip exception_type */ ldp x4, x5, [x1], #16+8 /* load pstate, mdscr_el1, skip exception_type */
msr sp_el0, x2 msr sp_el0, x2
msr elr_el1, x3 msr elr_el1, x3

View File

@ -40,14 +40,13 @@ void Thread::exception(Cpu & cpu)
case Cpu::SYNC_LEVEL_EL0: [[fallthrough]]; case Cpu::SYNC_LEVEL_EL0: [[fallthrough]];
case Cpu::SYNC_LEVEL_EL1: case Cpu::SYNC_LEVEL_EL1:
{ {
Cpu::Esr::access_t esr = Cpu::Esr_el1::read(); switch (Cpu::Esr::Ec::get(regs->esr_el1)) {
switch (Cpu::Esr::Ec::get(esr)) {
case Cpu::Esr::Ec::SVC: case Cpu::Esr::Ec::SVC:
_call(); _call();
return; return;
case Cpu::Esr::Ec::INST_ABORT_SAME_LEVEL: [[fallthrough]]; case Cpu::Esr::Ec::INST_ABORT_SAME_LEVEL: [[fallthrough]];
case Cpu::Esr::Ec::DATA_ABORT_SAME_LEVEL: case Cpu::Esr::Ec::DATA_ABORT_SAME_LEVEL:
Genode::raw("Fault in kernel/core ESR=", Genode::Hex(esr)); Genode::raw("Fault in kernel/core ESR=", Genode::Hex(regs->esr_el1));
[[fallthrough]]; [[fallthrough]];
case Cpu::Esr::Ec::INST_ABORT_LOW_LEVEL: [[fallthrough]]; case Cpu::Esr::Ec::INST_ABORT_LOW_LEVEL: [[fallthrough]];
case Cpu::Esr::Ec::DATA_ABORT_LOW_LEVEL: case Cpu::Esr::Ec::DATA_ABORT_LOW_LEVEL:
@ -55,12 +54,11 @@ void Thread::exception(Cpu & cpu)
return; return;
case Cpu::Esr::Ec::SOFTWARE_STEP_LOW_LEVEL: [[fallthrough]]; case Cpu::Esr::Ec::SOFTWARE_STEP_LOW_LEVEL: [[fallthrough]];
case Cpu::Esr::Ec::BRK: case Cpu::Esr::Ec::BRK:
regs->ec = Cpu::Esr::Ec::get(esr);
_exception(); _exception();
return; return;
default: default:
Genode::raw("Unknown cpu exception EC=", Cpu::Esr::Ec::get(esr), Genode::raw("Unknown cpu exception EC=", Cpu::Esr::Ec::get(regs->esr_el1),
" ISS=", Cpu::Esr::Iss::get(esr), " ISS=", Cpu::Esr::Iss::get(regs->esr_el1),
" ip=", (void*)regs->ip); " ip=", (void*)regs->ip);
}; };

View File

@ -53,15 +53,19 @@ _to_vm:
add x0, x0, #31*8 /* skip x0...x30, loaded later */ add x0, x0, #31*8 /* skip x0...x30, loaded later */
ldr x1, [x0], #1*8 /* sp */ ldp x1, x2, [x0], #2*8 /* sp, ip */
ldp x2, x3, [x0], #2*8 /* ip, pstate */ ldp x3, x4, [x0], #2*8 /* esr_el1, pstate */
msr sp_el0, x1 msr sp_el0, x1
msr elr_el2, x2 msr elr_el2, x2
msr spsr_el2, x3 msr esr_el1, x3
msr spsr_el2, x4
add x0, x0, #2*8 /* skip exception_type and esr_el2 */ add x0, x0, #2*8 /* skip exception_type and esr_el2 */
/** FPU register **/ /** FPU register **/
ldp w1, w2, [x0], #2*4
msr fpcr, x1
msr fpsr, x2
ldp q0, q1, [x0], #2*16 ldp q0, q1, [x0], #2*16
ldp q2, q3, [x0], #2*16 ldp q2, q3, [x0], #2*16
ldp q4, q5, [x0], #2*16 ldp q4, q5, [x0], #2*16
@ -78,45 +82,40 @@ _to_vm:
ldp q26, q27, [x0], #2*16 ldp q26, q27, [x0], #2*16
ldp q28, q29, [x0], #2*16 ldp q28, q29, [x0], #2*16
ldp q30, q31, [x0], #2*16 ldp q30, q31, [x0], #2*16
ldp w1, w2, [x0], #2*4
msr fpcr, x1
msr fpsr, x2
/** system register **/ /** system register **/
ldp x1, x2, [x0], #2*8 /* elr_el1, sp_el1 */ ldp x1, x2, [x0], #2*8 /* elr_el1, sp_el1 */
ldp w3, w4, [x0], #2*4 /* spsr_el1, esr_el1 */ ldp x3, x4, [x0], #2*8 /* spsr_el1, sctlr_el1 */
ldp x5, x6, [x0], #2*8 /* sctlr_el1, actlr_el1 */ ldp x5, x6, [x0], #2*8 /* actlr_el1, vbar_el1 */
ldr x7, [x0], #8 /* vbar_el1 */ ldp w7, w8, [x0], #2*4 /* cpacr_el1, afsr0_el1 */
ldp w8, w9, [x0], #2*4 /* cpacr_el1, afsr0_el1 */ ldp w9, w10, [x0], #2*4 /* afsr1_el1, contextidr_el1 */
ldp w10, w11, [x0], #2*4 /* afsr1_el1, contextidr_el1 */ ldp x11, x12, [x0], #2*8 /* ttbr0_el1, ttbr1_el1 */
ldp x12, x13, [x0], #2*8 /* ttbr0_el1, ttbr1_el1 */ ldp x13, x14, [x0], #2*8 /* tcr_el1, mair_el1 */
ldp x14, x15, [x0], #2*8 /* tcr_el1, mair_el1 */ ldp x15, x16, [x0], #2*8 /* amair_el1, far_el1 */
ldp x16, x17, [x0], #2*8 /* amair_el1, far_el1 */ ldp x17, x18, [x0], #2*8 /* par_el1, tpidrro_el0 */
ldp x18, x19, [x0], #2*8 /* par_el1, tpidrro_el0 */ ldp x19, x20, [x0], #2*8 /* tpidr_el0, tpidr_el1 */
ldp x20, x21, [x0], #2*8 /* tpidr_el0, tpidr_el1 */ ldr x21, [x0], #3*8 /* vmpidr_el2 */
ldr x22, [x0], #3*8 /* vmpidr_el2 */
msr elr_el1, x1 msr elr_el1, x1
msr sp_el1, x2 msr sp_el1, x2
msr spsr_el1, x3 msr spsr_el1, x3
msr esr_el1, x4 msr sctlr_el1, x4
msr sctlr_el1, x5 msr actlr_el1, x5
msr actlr_el1, x6 msr vbar_el1, x6
msr vbar_el1, x7 msr cpacr_el1, x7
msr cpacr_el1, x8 msr afsr0_el1, x8
msr afsr0_el1, x9 msr afsr1_el1, x9
msr afsr1_el1, x10 msr contextidr_el1, x10
msr contextidr_el1, x11 msr ttbr0_el1, x11
msr ttbr0_el1, x12 msr ttbr1_el1, x12
msr ttbr1_el1, x13 msr tcr_el1, x13
msr tcr_el1, x14 msr mair_el1, x14
msr mair_el1, x15 msr amair_el1, x15
msr amair_el1, x16 msr far_el1, x16
msr far_el1, x17 msr par_el1, x17
msr par_el1, x18 msr tpidrro_el0, x18
msr tpidrro_el0, x19 msr tpidr_el0, x19
msr tpidr_el0, x20 msr tpidr_el1, x20
msr tpidr_el1, x21 msr vmpidr_el2, x21
msr vmpidr_el2, x22
/********************** /**********************
@ -224,16 +223,20 @@ _from_vm:
stp x28, x29, [x0], #2*8 stp x28, x29, [x0], #2*8
str x30, [x0], #1*8 str x30, [x0], #1*8
/** save sp, ip, pstate and exception reason **/ /** save sp, ip, esr_el1, pstate and exception reason **/
mrs x2, sp_el0 mrs x2, sp_el0
mrs x3, elr_el2 mrs x3, elr_el2
mrs x4, spsr_el2 mrs x4, esr_el1
mrs x5, esr_el2 mrs x5, spsr_el2
stp x2, x3, [x0], #2*8 mrs x6, esr_el2
stp x4, x1, [x0], #2*8 stp x2, x3, [x0], #2*8 /* sp, ip */
str x5, [x0], #1*8 stp x4, x5, [x0], #2*8 /* esr_el1, pstate */
stp x1, x6, [x0], #2*8 /* exception_type, esr_el2 */
/** fpu registers **/ /** fpu registers **/
mrs x1, fpcr
mrs x2, fpsr
stp w1, w2, [x0], #2*4
stp q0, q1, [x0], #32 stp q0, q1, [x0], #32
stp q2, q3, [x0], #32 stp q2, q3, [x0], #32
stp q4, q5, [x0], #32 stp q4, q5, [x0], #32
@ -251,56 +254,51 @@ _from_vm:
stp q28, q29, [x0], #32 stp q28, q29, [x0], #32
stp q30, q31, [x0], #32 stp q30, q31, [x0], #32
mrs x1, fpcr
mrs x2, fpsr
mrs x3, elr_el1 mrs x3, elr_el1
mrs x4, sp_el1 mrs x4, sp_el1
mrs x5, spsr_el1 mrs x5, spsr_el1
mrs x6, esr_el1 mrs x6, sctlr_el1
mrs x7, sctlr_el1 mrs x7, actlr_el1
mrs x8, actlr_el1 mrs x8, vbar_el1
mrs x9, vbar_el1 mrs x9, cpacr_el1
mrs x10, cpacr_el1 mrs x10, afsr0_el1
mrs x11, afsr0_el1 mrs x11, afsr1_el1
mrs x12, afsr1_el1 mrs x12, contextidr_el1
mrs x13, contextidr_el1 mrs x13, ttbr0_el1
mrs x14, ttbr0_el1 mrs x14, ttbr1_el1
mrs x15, ttbr1_el1 mrs x15, tcr_el1
mrs x16, tcr_el1 mrs x16, mair_el1
mrs x17, mair_el1 mrs x17, amair_el1
mrs x18, amair_el1 mrs x18, far_el1
mrs x19, far_el1 mrs x19, par_el1
mrs x20, par_el1 mrs x20, tpidrro_el0
mrs x21, tpidrro_el0 mrs x21, tpidr_el0
mrs x22, tpidr_el0 mrs x22, tpidr_el1
mrs x23, tpidr_el1 mrs x23, far_el2
mrs x24, far_el2 mrs x24, hpfar_el2
mrs x25, hpfar_el2
stp w1, w2, [x0], #2*4
stp x3, x4, [x0], #2*8 stp x3, x4, [x0], #2*8
stp w5, w6, [x0], #2*4 stp x5, x6, [x0], #2*8
stp x7, x8, [x0], #2*8 stp x7, x8, [x0], #2*8
str x9, [x0], #1*8 stp w9, w10, [x0], #2*4
stp w10, w11, [x0], #2*4 stp w11, w12, [x0], #2*4
stp w12, w13, [x0], #2*4 stp x13, x14, [x0], #2*8
stp x14, x15, [x0], #2*8 stp x15, x16, [x0], #2*8
stp x16, x17, [x0], #2*8 stp x17, x18, [x0], #2*8
stp x18, x19, [x0], #2*8 stp x19, x20, [x0], #2*8
stp x20, x21, [x0], #2*8 stp x21, x22, [x0], #3*8
stp x22, x23, [x0], #3*8 stp x23, x24, [x0], #2*8
stp x24, x25, [x0], #2*8
/********************** /**********************
** save timer state ** ** save timer state **
**********************/ **********************/
mrs x26, cntvoff_el2 mrs x25, cntvoff_el2
mrs x27, cntv_cval_el0 mrs x26, cntv_cval_el0
mrs x28, cntv_ctl_el0 mrs x27, cntv_ctl_el0
mrs x29, cntkctl_el1 mrs x28, cntkctl_el1
stp x26, x27, [x0], #2*8 stp x25, x26, [x0], #2*8
stp w28, w29, [x0] stp w27, w28, [x0]
mov x0, #0b111 mov x0, #0b111
msr cnthctl_el2, x0 msr cnthctl_el2, x0
@ -332,17 +330,19 @@ _from_vm:
** Load host context ** ** Load host context **
***********************/ ***********************/
add x30, x30, #32*8 /* skip general-purpose regs, sp */ add x30, x30, #32*8 /* skip general-purpose regs, sp */
ldp x0, x1, [x30] /* host state ip, and pstate */ ldr x0, [x30], #2*8 /* host state ip, skip esr_el1 */
add x30, x30, #34*16 /* skip fpu regs etc. */ ldr x1, [x30], #3*8 /* host state pstate,
ldp w2, w3, [x30], #4*4 /* fpcr and fpsr */ skip exception_type and esr_el2 */
ldr x4, [x30], #2*8 /* sp_el1 */ ldp w2, w3, [x30], #2*4 /* fpcr and fpsr */
ldp x5, x6, [x30], #2*8 /* sctlr_el1, actlr_el1 */ add x30, x30, #32*16+8 /* skip remaining fpu regs and elr_el1 */
ldr x7, [x30], #1*8 /* vbar_el1 */ ldr x4, [x30], #2*8 /* sp_el1 */
ldr w8, [x30], #4*4 /* cpacr_el1 */ ldp x5, x6, [x30], #2*8 /* sctlr_el1, actlr_el1 */
ldp x9, x10, [x30], #2*8 /* ttbr0_el1, ttbr1_el1 */ ldr x7, [x30], #1*8 /* vbar_el1 */
ldp x11, x12, [x30], #2*8 /* tcr_el1, mair_el1 */ ldr w8, [x30], #4*4 /* cpacr_el1 */
ldr x13, [x30] /* amair_el1 */ ldp x9, x10, [x30], #2*8 /* ttbr0_el1, ttbr1_el1 */
ldp x11, x12, [x30], #2*8 /* tcr_el1, mair_el1 */
ldr x13, [x30] /* amair_el1 */
msr elr_el2, x0 msr elr_el2, x0
msr spsr_el2, x1 msr spsr_el2, x1

View File

@ -16,21 +16,28 @@
/* Genode includes */ /* Genode includes */
#include <base/stdint.h> #include <base/stdint.h>
#include <util/register.h>
namespace Genode { struct Cpu_state; } namespace Genode { struct Cpu_state; }
struct Genode::Cpu_state struct Genode::Cpu_state
{ {
enum Cpu_exception { struct Esr : Genode::Register<64>
SOFTWARE_STEP = 0x32, {
BREAKPOINT = 0x3c, struct Ec : Bitfield<26, 6>
{
enum Exception {
SOFTWARE_STEP = 0b110010,
BREAKPOINT = 0b111100,
};
};
}; };
addr_t r[31] { 0 }; /* general purpose register 0...30 */ addr_t r[31] { 0 }; /* general purpose register 0...30 */
addr_t sp { 0 }; /* stack pointer */ addr_t sp { 0 }; /* stack pointer */
addr_t ip { 0 }; /* instruction pointer */ addr_t ip { 0 }; /* instruction pointer */
addr_t ec { 0 }; /* exception class */ addr_t esr_el1 { 0 }; /* exception syndrome */
}; };
#endif /* _INCLUDE__SPEC__ARM_64__CPU__CPU_STATE_H_ */ #endif /* _INCLUDE__SPEC__ARM_64__CPU__CPU_STATE_H_ */

View File

@ -72,11 +72,11 @@ void Monitor::Monitored_thread::_handle_exception()
_original_first_instruction); _original_first_instruction);
stop_reply_signal = Stop_reply_signal::STOP; stop_reply_signal = Stop_reply_signal::STOP;
} else { } else {
switch(thread_state.ec) { switch(Cpu_state::Esr::Ec::get(thread_state.esr_el1)) {
case Cpu_state::Cpu_exception::SOFTWARE_STEP: case Cpu_state::Esr::Ec::SOFTWARE_STEP:
stop_reply_signal = Stop_reply_signal::TRAP; stop_reply_signal = Stop_reply_signal::TRAP;
break; break;
case Cpu_state::Cpu_exception::BREAKPOINT: case Cpu_state::Esr::Ec::BREAKPOINT:
stop_reply_signal = Stop_reply_signal::TRAP; stop_reply_signal = Stop_reply_signal::TRAP;
break; break;
default: default: