From 4ddef6e70162aadb09a25b07dd9de15dcb00b9a7 Mon Sep 17 00:00:00 2001 From: David Karoly Date: Fri, 18 Feb 2022 17:41:52 +0100 Subject: [PATCH] kernel/arm: detect read/write access in data abort handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use Data Fault Status Register's bit 11 to initialize isWrite. see: ARMv7 Architecture Reference Manual,section B3.9.5 Distinguishing read and write accesses on Data Abort exceptions Change-Id: I7da6702fc0e9579e5cb09cba3c5c89f004ec268a Reviewed-on: https://review.haiku-os.org/c/haiku/+/4972 Tested-by: Commit checker robot Reviewed-by: Jérôme Duval Reviewed-by: waddlesplash --- headers/private/system/arch/arm/arch_cpu_defs.h | 4 ++++ src/system/kernel/arch/arm/arch_int.cpp | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/headers/private/system/arch/arm/arch_cpu_defs.h b/headers/private/system/arch/arm/arch_cpu_defs.h index 180ef73edf..c4c6d74e9c 100644 --- a/headers/private/system/arch/arm/arch_cpu_defs.h +++ b/headers/private/system/arch/arm/arch_cpu_defs.h @@ -1,4 +1,7 @@ /* + * Copyright 2022, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ @@ -8,5 +11,6 @@ #define SPINLOCK_PAUSE() do {} while (false) +#define FSR_WNR 0x800 #endif /* _SYSTEM_ARCH_ARM_DEFS_H */ diff --git a/src/system/kernel/arch/arm/arch_int.cpp b/src/system/kernel/arch/arm/arch_int.cpp index 7dfc4583b7..00be3be99a 100644 --- a/src/system/kernel/arch/arm/arch_int.cpp +++ b/src/system/kernel/arch/arm/arch_int.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2021, Haiku Inc. All rights reserved. + * Copyright 2003-2022, Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -15,6 +15,7 @@ #include +#include #include #include #include @@ -245,13 +246,14 @@ arch_arm_data_abort(struct iframe *frame) { Thread *thread = thread_get_current_thread(); bool isUser = (frame->spsr & 0x1f) == 0x10; + int32 fsr = arm_get_fsr(); addr_t far = arm_get_far(); - bool isWrite = true; + bool isWrite = (fsr & FSR_WNR) == FSR_WNR; addr_t newip = 0; #ifdef TRACE_ARCH_INT print_iframe("Data Abort", frame); - dprintf("FAR: %08lx, thread: %s\n", far, thread->name); + dprintf("FAR: %08lx, isWrite: %d, thread: %s\n", far, isWrite, thread->name); #endif IFrameScope scope(frame);