arm64: print debug info for invalid vector entry
Previously, this would just print a 'halting via unknown'
in debug mode when an SError occurred and SError ignore was
not turned on. This changes the trap code so that we print
out the known cause of the trap.
KERNEL INVALID VECTOR ENTRY!
Vector: 0x580 (SError 64-bit EL0/EL1)
Fault attributed to program counter: 0x221dc0
ESR: 0xbf000000 FAR: 0x2881c98000824100
halting...
Kernel entry via Unknown (0)
This was encountered after some rust-seL4 changes to the
initialiser for Microkit related to untyped mappings broke
boot: https://github.com/seL4/microkit/issues/541
Signed-off-by: Julia Vassiliki <julia.vassiliki@unsw.edu.au>
This commit is contained in:
parent
535c377f20
commit
c4b44a24b4
3 changed files with 103 additions and 28 deletions
|
|
@ -57,3 +57,6 @@ void c_handle_vcpu_fault(word_t hsr)
|
||||||
VISIBLE SECTION(".vectors.text");
|
VISIBLE SECTION(".vectors.text");
|
||||||
#endif /* CONFIG_ARM_HYPERVISOR_SUPPORT */
|
#endif /* CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||||
|
|
||||||
|
#if defined(CONFIG_ARCH_AARCH64) && defined(CONFIG_DEBUG_BUILD)
|
||||||
|
void VISIBLE c_handle_invalid_vector_entry(word_t vect_offset, word_t pc);
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -65,3 +65,54 @@ void VISIBLE NORETURN restore_user_context(void)
|
||||||
);
|
);
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_DEBUG_BUILD)
|
||||||
|
/* See 'arm_vector_table' for details on 'vect_offset' */
|
||||||
|
static const char *vect_offset_to_name(word_t vect_offset)
|
||||||
|
{
|
||||||
|
switch (vect_offset) {
|
||||||
|
case 0x000:
|
||||||
|
return "Synchronous EL1t/EL2t";
|
||||||
|
case 0x080:
|
||||||
|
return "IRQ EL1t/EL2t";
|
||||||
|
case 0x100:
|
||||||
|
return "FIQ EL1t/EL2t";
|
||||||
|
case 0x180:
|
||||||
|
return "SError EL1t/EL2t";
|
||||||
|
case 0x200:
|
||||||
|
return "Synchronous Current EL";
|
||||||
|
case 0x280:
|
||||||
|
return "IRQ Current EL";
|
||||||
|
case 0x300:
|
||||||
|
return "FIQ Current EL";
|
||||||
|
case 0x380:
|
||||||
|
return "SError Current EL";
|
||||||
|
case 0x400:
|
||||||
|
return "Synchronous 64-bit EL0/EL1";
|
||||||
|
case 0x480:
|
||||||
|
return "IRQ 64-bit EL0/EL1";
|
||||||
|
case 0x500:
|
||||||
|
return "FIQ 64-bit EL0/EL1";
|
||||||
|
case 0x580:
|
||||||
|
return "SError 64-bit EL0/EL1";
|
||||||
|
case 0x600:
|
||||||
|
return "Synchronous 32-bit EL0/EL1";
|
||||||
|
case 0x680:
|
||||||
|
return "IRQ 32-bit EL0/EL1";
|
||||||
|
case 0x700:
|
||||||
|
return "FIQ 32-bit EL0/EL1";
|
||||||
|
case 0x780:
|
||||||
|
return "SError 32-bit EL0/EL1";
|
||||||
|
default:
|
||||||
|
return "<Unknown>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VISIBLE c_handle_invalid_vector_entry(word_t vect_offset, word_t pc)
|
||||||
|
{
|
||||||
|
printf("\n\nKERNEL INVALID VECTOR ENTRY!\n");
|
||||||
|
printf("Vector: 0x%"SEL4_PRIx_word" (%s)\n", vect_offset, vect_offset_to_name(vect_offset));
|
||||||
|
printf("Fault attributed to program counter: 0x%"SEL4_PRIx_word"\n", pc);
|
||||||
|
printf("ESR: 0x%"SEL4_PRIx_word" FAR: 0x%"SEL4_PRIx_word"\n", getESR(), getFAR());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -40,28 +40,58 @@
|
||||||
b \label
|
b \label
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_BUILD
|
||||||
|
.macro ventry_invalid
|
||||||
|
.align 7
|
||||||
|
/* compute vect_offset argument */
|
||||||
|
adr x0, .
|
||||||
|
adr x19, arm_vector_table
|
||||||
|
sub x0, x0, x19
|
||||||
|
b invalid_vector_entry
|
||||||
|
.endm
|
||||||
|
#else
|
||||||
|
.macro ventry_invalid
|
||||||
|
ventry invalid_vector_entry
|
||||||
|
.endm
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_AARCH64_SERROR_IGNORE
|
||||||
|
.macro ventry_serror
|
||||||
|
.align 7
|
||||||
|
eret
|
||||||
|
.endm
|
||||||
|
#else
|
||||||
|
.macro ventry_serror
|
||||||
|
ventry_invalid
|
||||||
|
.endm
|
||||||
|
#endif
|
||||||
|
|
||||||
.section .vectors, "ax"
|
.section .vectors, "ax"
|
||||||
|
|
||||||
|
/* The layout of this table are specified in Table D1-7, 'Vector offsets from
|
||||||
|
* vector table base address' of ARM DDI 0487B.b ID092517.
|
||||||
|
* Each vector entry has 128-byte alignment, and so supports 32 instructions.
|
||||||
|
*/
|
||||||
BEGIN_FUNC(arm_vector_table)
|
BEGIN_FUNC(arm_vector_table)
|
||||||
ventry invalid_vector_entry // Synchronous EL1t/EL2t
|
ventry_invalid // Synchronous EL1t/EL2t
|
||||||
ventry invalid_vector_entry // IRQ EL1t/EL2t
|
ventry_invalid // IRQ EL1t/EL2t
|
||||||
ventry invalid_vector_entry // FIQ EL1t/EL2t
|
ventry_invalid // FIQ EL1t/EL2t
|
||||||
ventry invalid_vector_entry // SError EL1t/EL2t
|
ventry_invalid // SError EL1t/EL2t
|
||||||
|
|
||||||
ventry cur_el_sync // Current EL Synchronous (EL1/2)
|
ventry cur_el_sync // Current EL Synchronous (EL1/2)
|
||||||
ventry cur_el_irq // IRQ
|
ventry cur_el_irq // IRQ
|
||||||
ventry invalid_vector_entry // FIQ
|
ventry_invalid // FIQ
|
||||||
ventry cur_el_serr // SError
|
ventry_serror // SError
|
||||||
|
|
||||||
ventry lower_el_sync // Synchronous 64-bit EL0/EL1
|
ventry lower_el_sync // Synchronous 64-bit EL0/EL1
|
||||||
ventry lower_el_irq // IRQ 64-bit EL0/EL1
|
ventry lower_el_irq // IRQ 64-bit EL0/EL1
|
||||||
ventry invalid_vector_entry // FIQ 64-bit EL0/EL1
|
ventry_invalid // FIQ 64-bit EL0/EL1
|
||||||
ventry lower_el_serr // SError 64-bit EL0/EL1
|
ventry_serror // SError 64-bit EL0/EL1
|
||||||
|
|
||||||
ventry invalid_vector_entry // Synchronous 32-bit EL0/EL1
|
ventry_invalid // Synchronous 32-bit EL0/EL1
|
||||||
ventry invalid_vector_entry // IRQ 32-bit EL0/EL1
|
ventry_invalid // IRQ 32-bit EL0/EL1
|
||||||
ventry invalid_vector_entry // FIQ 32-bit EL0/EL1
|
ventry_invalid // FIQ 32-bit EL0/EL1
|
||||||
ventry invalid_vector_entry // SError 32-bit EL0/EL1
|
ventry_invalid // SError 32-bit EL0/EL1
|
||||||
END_FUNC(arm_vector_table)
|
END_FUNC(arm_vector_table)
|
||||||
|
|
||||||
.section .vectors.text, "ax"
|
.section .vectors.text, "ax"
|
||||||
|
|
@ -92,8 +122,13 @@ END_FUNC(arm_vector_table)
|
||||||
stp x22, x23, [sp, #PT_ELR_EL1]
|
stp x22, x23, [sp, #PT_ELR_EL1]
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
/* Takes argument x0: vect_offset (in debug builds) */
|
||||||
BEGIN_FUNC(invalid_vector_entry)
|
BEGIN_FUNC(invalid_vector_entry)
|
||||||
lsp_i x19
|
lsp_i x19
|
||||||
|
#ifdef CONFIG_DEBUG_BUILD
|
||||||
|
mrs x1, ELR
|
||||||
|
bl c_handle_invalid_vector_entry
|
||||||
|
#endif
|
||||||
b halt
|
b halt
|
||||||
END_FUNC(invalid_vector_entry)
|
END_FUNC(invalid_vector_entry)
|
||||||
|
|
||||||
|
|
@ -123,6 +158,8 @@ cur_el_ia:
|
||||||
b halt
|
b halt
|
||||||
|
|
||||||
cur_el_inv:
|
cur_el_inv:
|
||||||
|
/* 0x200 corresponding to the offset in the vector table */
|
||||||
|
mov x0, #0x200
|
||||||
b invalid_vector_entry
|
b invalid_vector_entry
|
||||||
END_FUNC(cur_el_sync)
|
END_FUNC(cur_el_sync)
|
||||||
|
|
||||||
|
|
@ -137,14 +174,6 @@ BEGIN_FUNC(cur_el_irq)
|
||||||
b c_handle_interrupt
|
b c_handle_interrupt
|
||||||
END_FUNC(cur_el_irq)
|
END_FUNC(cur_el_irq)
|
||||||
|
|
||||||
BEGIN_FUNC(cur_el_serr)
|
|
||||||
#ifdef CONFIG_AARCH64_SERROR_IGNORE
|
|
||||||
eret
|
|
||||||
#else
|
|
||||||
b invalid_vector_entry
|
|
||||||
#endif
|
|
||||||
END_FUNC(cur_el_serr)
|
|
||||||
|
|
||||||
BEGIN_FUNC(lower_el_sync)
|
BEGIN_FUNC(lower_el_sync)
|
||||||
kernel_enter
|
kernel_enter
|
||||||
|
|
||||||
|
|
@ -225,11 +254,3 @@ BEGIN_FUNC(lower_el_irq)
|
||||||
lsp_i x19
|
lsp_i x19
|
||||||
b c_handle_interrupt
|
b c_handle_interrupt
|
||||||
END_FUNC(lower_el_irq)
|
END_FUNC(lower_el_irq)
|
||||||
|
|
||||||
BEGIN_FUNC(lower_el_serr)
|
|
||||||
#ifdef CONFIG_AARCH64_SERROR_IGNORE
|
|
||||||
eret
|
|
||||||
#else
|
|
||||||
b invalid_vector_entry
|
|
||||||
#endif
|
|
||||||
END_FUNC(lower_el_serr)
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue