From 10d033ebf04a59af960094d6e254f21f58871ea7 Mon Sep 17 00:00:00 2001 From: Andrew Boie Date: Wed, 6 Nov 2019 15:54:34 -0800 Subject: [PATCH] x86: enable recoverable exceptions on 64-bit These were previously assumed to always be fatal. We can't have the faulting thread's XMM registers clobbered, so put the SIMD/FPU state onto the stack as well. This is fairly large (512 bytes) and the execption stack is already uncomfortably small, so increase to 2K. Signed-off-by: Andrew Boie --- arch/x86/core/Kconfig.intel64 | 2 +- arch/x86/core/intel64/locore.S | 32 +++++++++++++++++++++++++++++++- include/arch/x86/intel64/arch.h | 1 + 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/arch/x86/core/Kconfig.intel64 b/arch/x86/core/Kconfig.intel64 index d56b204ee74..a0b5f2f975d 100644 --- a/arch/x86/core/Kconfig.intel64 +++ b/arch/x86/core/Kconfig.intel64 @@ -25,7 +25,7 @@ config OFFLOAD_WORKQUEUE_STACK_SIZE config EXCEPTION_STACK_SIZE int "Size of the exception stack(s)" - default 1024 + default 2048 help The exception stack(s) (one per CPU) are used both for exception processing and early kernel/CPU initialization. They need only diff --git a/arch/x86/core/intel64/locore.S b/arch/x86/core/intel64/locore.S index 632872d51b6..ef09a5188a6 100644 --- a/arch/x86/core/intel64/locore.S +++ b/arch/x86/core/intel64/locore.S @@ -268,6 +268,8 @@ except: /* */ pushq %r15 + subq $X86_FXSAVE_SIZE, %rsp + fxsave (%rsp) pushq %r14 pushq %r13 pushq %r12 @@ -284,9 +286,37 @@ except: /* pushq %rax movq %rsp, %rdi + + /* TODO we don't need to push so many registers if we are not + * dumping out exception info since RBX, RBP, R12-R15 are callee-saved + */ call z_x86_exception - hlt /* should not return, but just in case .. */ + /* If we returned, the exception was handled successfully and the + * thread may resume (the pushed RIP may have been modified) + */ + popq %rax + popq %rbx + popq %rcx + popq %rdx + popq %rbp + popq %rsi + popq %rdi + popq %r8 + popq %r9 + popq %r10 + popq %r11 + popq %r12 + popq %r13 + popq %r14 + fxrstor (%rsp) + addq $X86_FXSAVE_SIZE, %rsp + popq %r15 + + /* Drop the vector/err code pushed by the HW or EXCEPT_*() stub */ + add $16, %rsp + + iretq EXCEPT ( 0); EXCEPT ( 1); EXCEPT ( 2); EXCEPT ( 3) EXCEPT ( 4); EXCEPT ( 5); EXCEPT ( 6); EXCEPT ( 7) diff --git a/include/arch/x86/intel64/arch.h b/include/arch/x86/intel64/arch.h index ccaf020cf1b..6630700609c 100644 --- a/include/arch/x86/intel64/arch.h +++ b/include/arch/x86/intel64/arch.h @@ -46,6 +46,7 @@ struct x86_esf { unsigned long r12; unsigned long r13; unsigned long r14; + char fxsave[X86_FXSAVE_SIZE]; unsigned long r15; unsigned long vector; unsigned long code;