From 06fae14eb94d329531e955a6b8a78c21107d8f6f Mon Sep 17 00:00:00 2001 From: milek7 Date: Thu, 7 Mar 2024 03:29:12 +0100 Subject: [PATCH] arm64: Save/restore FPU state when handling IRQ or syscall Change-Id: I8b2a36d57f410c0d06ca5ce90d1b997494072c94 Reviewed-on: https://review.haiku-os.org/c/haiku/+/7510 Reviewed-by: waddlesplash Tested-by: Commit checker robot --- headers/private/kernel/arch/arm64/arch_cpu.h | 3 +++ src/system/kernel/arch/arm64/arch_int.cpp | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/headers/private/kernel/arch/arm64/arch_cpu.h b/headers/private/kernel/arch/arm64/arch_cpu.h index 53a77cddcd..3d661901a8 100644 --- a/headers/private/kernel/arch/arm64/arch_cpu.h +++ b/headers/private/kernel/arch/arm64/arch_cpu.h @@ -138,6 +138,9 @@ struct iframe { // exception info uint64 esr; uint64 far; + + // fpu + struct aarch64_fpu_state fpu; }; diff --git a/src/system/kernel/arch/arm64/arch_int.cpp b/src/system/kernel/arch/arm64/arch_int.cpp index 2a13d59104..2cfcea780e 100644 --- a/src/system/kernel/arch/arm64/arch_int.cpp +++ b/src/system/kernel/arch/arm64/arch_int.cpp @@ -39,6 +39,11 @@ // threads yet. struct iframe_stack gBootFrameStack; +// In order to avoid store/restore of large FPU state, it is assumed that +// this code and page fault handling doesn't use FPU. +// Instead this is called manually when handling IRQ or syscall. +extern "C" void _fp_save(aarch64_fpu_state *fpu); +extern "C" void _fp_restore(aarch64_fpu_state *fpu); void arch_int_enable_io_interrupt(int32 irq) @@ -340,6 +345,8 @@ do_sync_handler(iframe * frame) } } + _fp_save(&frame->fpu); + thread_at_kernel_entry(system_time()); enable_interrupts(); @@ -362,6 +369,8 @@ do_sync_handler(iframe * frame) } } + _fp_restore(&frame->fpu); + return; } } @@ -393,11 +402,15 @@ do_irq_handler(iframe * frame) IFrameScope scope(frame); + _fp_save(&frame->fpu); + InterruptController *ic = InterruptController::Get(); if (ic != NULL) ic->HandleInterrupt(); after_exception(); + + _fp_restore(&frame->fpu); }