SELFOUR-615: arm entry point stubs
This commit is contained in:
parent
297ad035a6
commit
ef00e98689
11 changed files with 188 additions and 199 deletions
|
|
@ -23,4 +23,21 @@ static inline void arch_c_exit_hook(void) {
|
|||
void c_handle_syscall(word_t cptr, word_t msgInfo, syscall_t syscall)
|
||||
VISIBLE SECTION(".vectors.text");
|
||||
|
||||
void c_handle_interrupt(void)
|
||||
VISIBLE SECTION(".vectors.text");
|
||||
|
||||
void c_handle_undefined_instruction(void)
|
||||
VISIBLE SECTION(".vectors.text");
|
||||
|
||||
void c_handle_data_fault(void)
|
||||
VISIBLE SECTION(".vectors.text");
|
||||
|
||||
void c_handle_instruction_fault(void)
|
||||
VISIBLE SECTION(".vectors.text");
|
||||
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
void c_handle_vcpu_fault(word_t hsr)
|
||||
VISIBLE SECTION(".vectors.text");
|
||||
#endif /* CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||
|
||||
#endif /* __KERNEL_ARM_TRAPS_H */
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include <api/debug.h>
|
||||
|
||||
#if defined(DEBUG) || defined(CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES)
|
||||
#define TRACK_KERNEL_ENTRIES 1
|
||||
#ifdef CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES
|
||||
/**
|
||||
* Calculate the maximum number of kernel entries that can be tracked,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@
|
|||
/* This C function should be the first thing called from C after entry from
|
||||
* assembly. It provides a single place to do any entry work that is not
|
||||
* done in assembly for various reasons */
|
||||
static inline void c_entry_hook(void) {
|
||||
static inline void c_entry_hook(void)
|
||||
{
|
||||
arch_c_entry_hook();
|
||||
#if defined(CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES) || defined(CONFIG_BENCHMARK_TRACK_UTILISATION)
|
||||
ksEnter = timestamp();
|
||||
|
|
@ -29,14 +30,12 @@ static inline void c_entry_hook(void) {
|
|||
* the kernel (be it to assembly or returning to user space). It provides
|
||||
* a place to provide any additional instrumentation or functionality
|
||||
* in C before leaving the kernel */
|
||||
static inline void c_exit_hook(void) {
|
||||
static inline void c_exit_hook(void)
|
||||
{
|
||||
#ifdef CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES
|
||||
benchmark_track_exit();
|
||||
#endif /* CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES */
|
||||
arch_c_exit_hook();
|
||||
}
|
||||
|
||||
void c_handle_syscall(word_t cptr, word_t msgInfo, syscall_t syscall)
|
||||
VISIBLE SECTION(".vectors.text");
|
||||
|
||||
#endif /* __KERNEL_TRAPS_H */
|
||||
|
|
|
|||
|
|
@ -24,7 +24,9 @@ typedef enum {
|
|||
Entry_UnknownSyscall,
|
||||
Entry_UserLevelFault,
|
||||
Entry_VMFault,
|
||||
Entry_Syscall
|
||||
Entry_Syscall,
|
||||
Entry_UnimplementedDevice,
|
||||
Entry_VCPUFault
|
||||
} entry_type_t;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -39,13 +39,7 @@ handleInterruptEntry(void)
|
|||
{
|
||||
irq_t irq;
|
||||
|
||||
c_entry_hook();
|
||||
|
||||
irq = getActiveIRQ();
|
||||
#if defined(DEBUG) || defined(CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES)
|
||||
ksKernelEntry.path = Entry_Interrupt;
|
||||
ksKernelEntry.word = irq;
|
||||
#endif /* DEBUG */
|
||||
|
||||
if (irq != irqInvalid) {
|
||||
handleInterrupt(irq);
|
||||
|
|
@ -59,8 +53,6 @@ handleInterruptEntry(void)
|
|||
schedule();
|
||||
activateThread();
|
||||
|
||||
c_exit_hook();
|
||||
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
|
||||
|
|
@ -68,9 +60,6 @@ exception_t
|
|||
handleUnknownSyscall(word_t w)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_BUILD
|
||||
ksKernelEntry.path = Entry_UnknownSyscall;
|
||||
ksKernelEntry.word = w;
|
||||
|
||||
if (w == SysDebugPutChar) {
|
||||
kernel_putchar(getRegister(ksCurThread, capRegister));
|
||||
return EXCEPTION_NONE;
|
||||
|
|
@ -190,22 +179,12 @@ handleUnknownSyscall(word_t w)
|
|||
exception_t
|
||||
handleUserLevelFault(word_t w_a, word_t w_b)
|
||||
{
|
||||
c_entry_hook();
|
||||
#if defined(DEBUG) || defined(CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES)
|
||||
ksKernelEntry.path = Entry_UserLevelFault;
|
||||
ksKernelEntry.word = w_a;
|
||||
#endif /* DEBUG */
|
||||
|
||||
current_fault = fault_user_exception_new(w_a, w_b);
|
||||
handleFault(ksCurThread);
|
||||
|
||||
schedule();
|
||||
activateThread();
|
||||
|
||||
#ifdef CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES
|
||||
benchmark_track_exit();
|
||||
#endif
|
||||
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
|
||||
|
|
@ -213,11 +192,6 @@ exception_t
|
|||
handleVMFaultEvent(vm_fault_type_t vm_faultType)
|
||||
{
|
||||
exception_t status;
|
||||
c_entry_hook();
|
||||
#if defined(DEBUG) || defined(CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES)
|
||||
ksKernelEntry.path = Entry_VMFault;
|
||||
ksKernelEntry.word = vm_faultType;
|
||||
#endif /* DEBUG */
|
||||
|
||||
status = handleVMFault(ksCurThread, vm_faultType);
|
||||
if (status != EXCEPTION_NONE) {
|
||||
|
|
@ -227,8 +201,6 @@ handleVMFaultEvent(vm_fault_type_t vm_faultType)
|
|||
schedule();
|
||||
activateThread();
|
||||
|
||||
c_exit_hook();
|
||||
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
|
||||
|
|
@ -252,10 +224,6 @@ handleInvocation(bool_t isCall, bool_t isBlocking)
|
|||
/* faulting section */
|
||||
lu_ret = lookupCapAndSlot(thread, cptr);
|
||||
|
||||
#if defined(DEBUG) || defined(CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES)
|
||||
ksKernelEntry.is_fastpath = false;
|
||||
#endif
|
||||
|
||||
if (unlikely(lu_ret.status != EXCEPTION_NONE)) {
|
||||
userError("Invocation of invalid cap #%lu.", cptr);
|
||||
current_fault = fault_cap_fault_new(cptr, false);
|
||||
|
|
|
|||
|
|
@ -95,30 +95,6 @@ END_FUNC(arm_vector_table)
|
|||
#define HSREC_DATA_ABORT 0x24
|
||||
#define HSRIL32 (1 << 25)
|
||||
|
||||
/* Helper to return to userland. */
|
||||
.macro RET_TO_USER, cur_thread_reg
|
||||
/* cur_thread_reg should contain the address of ksCurThread. */
|
||||
/* Set stack pointer to point at the r0 of the user context. */
|
||||
ldr sp, [\cur_thread_reg]
|
||||
/* Pop user registers */
|
||||
pop {r0-r12}
|
||||
/* Retore the user stack pointer */
|
||||
pop {lr}
|
||||
msr sp_usr, lr
|
||||
|
||||
/* prepare the eception return lr */
|
||||
ldr lr, [sp, #4]
|
||||
msr elr_hyp, lr
|
||||
/* prepare the user status register */
|
||||
ldr lr, [sp, #8]
|
||||
msr spsr_hyp, lr
|
||||
|
||||
/* Finally, pop our LR */
|
||||
pop {lr}
|
||||
/* Return to user */
|
||||
eret
|
||||
.endm
|
||||
|
||||
.macro EX_ENTRY
|
||||
/* Create some scratch space */
|
||||
push {lr}
|
||||
|
|
@ -133,6 +109,16 @@ END_FUNC(arm_vector_table)
|
|||
push {lr}
|
||||
.endm
|
||||
|
||||
/* Prepare to enter the kernel */
|
||||
.macro PUSH_STACK
|
||||
/* store FaultInstruction */
|
||||
str lr, [sp, #(PT_FaultInstruction - PT_SP)]
|
||||
/* Stack all user registers */
|
||||
push {r0-r12}
|
||||
/* Load the kernel's real stack pointer */
|
||||
mov sp, #(PPTR_KERNEL_STACK_TOP)
|
||||
.endm
|
||||
|
||||
/********************************
|
||||
*** Traps taken to HYP mode ***
|
||||
********************************/
|
||||
|
|
@ -155,95 +141,36 @@ BEGIN_FUNC(arm_hyp_trap)
|
|||
beq arm_undefined_inst
|
||||
|
||||
/** Everything else is assumed to be a VCPU trap **/
|
||||
|
||||
/* Store FaultInstruction */
|
||||
mrs lr, elr_hyp
|
||||
str lr, [sp, #(PT_FaultInstruction - PT_SP)]
|
||||
/* Stack all user registers */
|
||||
push {r0-r12}
|
||||
/* Load the kernel's real stack pointer */
|
||||
mov sp, #(PPTR_KERNEL_STACK_TOP)
|
||||
|
||||
/* Call out to the user */
|
||||
ldr r7, =ksCurThread
|
||||
PUSH_STACK
|
||||
mrc HSR(r0)
|
||||
blx handleVCPUFault
|
||||
|
||||
/* Exception return */
|
||||
RET_TO_USER r7
|
||||
b c_handle_vcpu_fault
|
||||
END_FUNC(arm_hyp_trap)
|
||||
|
||||
|
||||
BEGIN_FUNC(arm_undefined_inst)
|
||||
/* Store FaultInstruction */
|
||||
mrs lr, elr_hyp
|
||||
str lr, [sp, #(PT_FaultInstruction - PT_SP)]
|
||||
/* Stack all user registers */
|
||||
push {r0-r12}
|
||||
/* Load the kernel's real stack pointer */
|
||||
mov sp, #(PPTR_KERNEL_STACK_TOP)
|
||||
|
||||
/* Call out to the user */
|
||||
ldr r7, =ksCurThread
|
||||
mov r0, #0
|
||||
mov r1, #0
|
||||
blx handleUserLevelFault
|
||||
|
||||
/* Exception return */
|
||||
RET_TO_USER r7
|
||||
PUSH_STACK
|
||||
b c_handle_undefined_instruction
|
||||
END_FUNC(arm_undefined_inst)
|
||||
|
||||
BEGIN_FUNC(arm_prefetch_abort)
|
||||
/* Store FaultInstruction */
|
||||
mrs lr, elr_hyp
|
||||
str lr, [sp, #(PT_FaultInstruction - PT_SP)]
|
||||
/* Stack all user registers */
|
||||
push {r0-r12}
|
||||
/* Load the kernel's real stack pointer */
|
||||
mov sp, #(PPTR_KERNEL_STACK_TOP)
|
||||
|
||||
/* Call out to the user */
|
||||
ldr r7, =ksCurThread
|
||||
mov r0, #seL4_InstructionFault
|
||||
blx handleVMFaultEvent
|
||||
|
||||
/* Exception return */
|
||||
RET_TO_USER r7
|
||||
PUSH_STACK
|
||||
b c_handle_instruction_fault
|
||||
END_FUNC(arm_prefetch_abort)
|
||||
|
||||
BEGIN_FUNC(arm_data_abort)
|
||||
/* Store FaultInstruction */
|
||||
mrs lr, elr_hyp
|
||||
str lr, [sp, #(PT_FaultInstruction - PT_SP)]
|
||||
/* Stack all user registers */
|
||||
push {r0-r12}
|
||||
/* Load the kernel's real stack pointer */
|
||||
mov sp, #(PPTR_KERNEL_STACK_TOP)
|
||||
|
||||
/* Call out to the user */
|
||||
ldr r7, =ksCurThread
|
||||
mov r0, #seL4_DataFault
|
||||
blx handleVMFaultEvent
|
||||
|
||||
/* Exception return */
|
||||
RET_TO_USER r7
|
||||
PUSH_STACK
|
||||
b c_handle_data_fault
|
||||
END_FUNC(arm_data_abort)
|
||||
|
||||
BEGIN_FUNC(arm_syscall)
|
||||
/* Store FaultInstruction */
|
||||
mrs lr, elr_hyp
|
||||
sub lr, lr, #4
|
||||
str lr, [sp, #(PT_FaultInstruction - PT_SP)]
|
||||
|
||||
/* Stack all user registers */
|
||||
push {r0-r12}
|
||||
|
||||
/* Load the kernel's real stack pointer */
|
||||
mov sp, #(PPTR_KERNEL_STACK_TOP)
|
||||
|
||||
/* Load system call number as a c_handle_syscall argument. r0 and r1 are passed
|
||||
* unmodified (cptr and msgIngo respectively).
|
||||
*/
|
||||
PUSH_STACK
|
||||
/* r0: cptr, r1: msgInfo, r2: syscallNo */
|
||||
mov r2, r7
|
||||
b c_handle_syscall
|
||||
END_FUNC(arm_syscall)
|
||||
|
|
@ -295,20 +222,9 @@ END_FUNC(arm_hyp_syscall)
|
|||
|
||||
BEGIN_FUNC(arm_hyp_irq_exception)
|
||||
EX_ENTRY
|
||||
|
||||
/* Store FaultInstruction */
|
||||
mrs lr, elr_hyp
|
||||
str lr, [sp, #(PT_FaultInstruction - PT_SP)]
|
||||
/* Stack all user registers */
|
||||
push {r0-r12}
|
||||
|
||||
/* Handle the exception */
|
||||
ldr r7, =ksCurThread
|
||||
mov sp, #(PPTR_KERNEL_STACK_TOP)
|
||||
blx handleInterruptEntry
|
||||
|
||||
/* Return to the user */
|
||||
RET_TO_USER r7
|
||||
PUSH_STACK
|
||||
b c_handle_interrupt
|
||||
END_FUNC(arm_hyp_irq_exception)
|
||||
|
||||
BEGIN_FUNC(arm_hyp_reset_exception)
|
||||
|
|
|
|||
|
|
@ -38,20 +38,6 @@ END_FUNC(arm_vector_table)
|
|||
#include <arch/machine/registerset.h>
|
||||
#include <mode/api/constants.h>
|
||||
|
||||
/* Helper to return to userland. */
|
||||
.macro RET_TO_USER, cur_thread_reg
|
||||
/* cur_thread_reg should contain the address of ksCurThread. */
|
||||
/* Set stack pointer to point at the LR_svc of the user context. */
|
||||
ldr sp, [\cur_thread_reg]
|
||||
add sp, sp, #PT_LR_svc
|
||||
|
||||
/* Unstack user registers */
|
||||
ldmdb sp, {r0-lr}^
|
||||
|
||||
/* Jump to user NextPC and restore user CPSR */
|
||||
rfeia sp
|
||||
.endm
|
||||
|
||||
BEGIN_FUNC(arm_undefined_inst_exception)
|
||||
/* Full save/restore, documented in arm_swi_syscall */
|
||||
srsia #PMODE_SUPERVISOR
|
||||
|
|
@ -66,15 +52,7 @@ BEGIN_FUNC(arm_undefined_inst_exception)
|
|||
sub r8, r8, #4
|
||||
str r8, [sp, #(PT_FaultInstruction - PT_LR_svc)]
|
||||
ldr sp, =(PPTR_KERNEL_STACK_TOP)
|
||||
|
||||
ldr r7, =ksCurThread
|
||||
|
||||
/* There's only one user-level fault on ARM, and the code is (0,0) */
|
||||
mov r0, #0
|
||||
mov r1, #0
|
||||
blx handleUserLevelFault
|
||||
|
||||
RET_TO_USER r7
|
||||
b c_handle_undefined_instruction
|
||||
#endif
|
||||
END_FUNC(arm_undefined_inst_exception)
|
||||
|
||||
|
|
@ -98,7 +76,7 @@ BEGIN_FUNC(arm_swi_syscall)
|
|||
ldr sp, =(PPTR_KERNEL_STACK_TOP)
|
||||
|
||||
/* Load system call number as a c_handle_syscall argument. r0 and r1 are passed
|
||||
* unmodified (cptr and msgInfo respectively).
|
||||
* unmodified (cptr and msgInfo) respectively.
|
||||
*/
|
||||
mov r2, r7
|
||||
b c_handle_syscall
|
||||
|
|
@ -127,11 +105,7 @@ BEGIN_FUNC(arm_prefetch_abort_exception)
|
|||
str r8, [sp, #(PT_FaultInstruction - PT_LR_svc)]
|
||||
ldr sp, =(PPTR_KERNEL_STACK_TOP)
|
||||
|
||||
ldr r7, =ksCurThread
|
||||
mov r0, #seL4_InstructionFault
|
||||
blx handleVMFaultEvent
|
||||
|
||||
RET_TO_USER r7
|
||||
b c_handle_instruction_fault
|
||||
|
||||
kernel_prefetch_fault:
|
||||
#ifdef DEBUG
|
||||
|
|
@ -175,10 +149,8 @@ BEGIN_FUNC(arm_data_abort_exception)
|
|||
ldr sp, =(PPTR_KERNEL_STACK_TOP)
|
||||
|
||||
ldr r7, =ksCurThread
|
||||
mov r0, #seL4_DataFault
|
||||
blx handleVMFaultEvent
|
||||
b c_handle_data_fault
|
||||
|
||||
RET_TO_USER r7
|
||||
|
||||
kernel_data_fault:
|
||||
#ifdef DEBUG
|
||||
|
|
@ -207,12 +179,8 @@ BEGIN_FUNC(arm_irq_exception)
|
|||
sub r8, r8, #4
|
||||
str r8, [sp]
|
||||
str r8, [sp, #(PT_FaultInstruction - PT_LR_svc)]
|
||||
|
||||
ldr r7, =ksCurThread
|
||||
ldr sp, =(PPTR_KERNEL_STACK_TOP)
|
||||
blx handleInterruptEntry
|
||||
|
||||
RET_TO_USER r7
|
||||
b c_handle_interrupt
|
||||
END_FUNC(arm_irq_exception)
|
||||
|
||||
BEGIN_FUNC(arm_reset_exception)
|
||||
|
|
|
|||
|
|
@ -10,14 +10,83 @@
|
|||
|
||||
#include <config.h>
|
||||
#include <arch/kernel/traps.h>
|
||||
#include <arch/object/vcpu.h>
|
||||
#include <arch/machine/registerset.h>
|
||||
#include <api/syscall.h>
|
||||
|
||||
#include <benchmark_track_types.h>
|
||||
#include <benchmark_track.h>
|
||||
#include <benchmark_utilisation.h>
|
||||
|
||||
/** DONT_TRANSLATE */
|
||||
void NORETURN slowpath(syscall_t syscall)
|
||||
void VISIBLE NORETURN
|
||||
c_handle_undefined_instruction(void)
|
||||
{
|
||||
c_entry_hook();
|
||||
|
||||
#ifdef TRACK_KERNEL_ENTRIES
|
||||
ksKernelEntry.path = Entry_UserLevelFault;
|
||||
ksKernelEntry.word = getRegister(ksCurThread, LR_svc);
|
||||
#endif
|
||||
|
||||
/* There's only one user-level fault on ARM, and the code is (0,0) */
|
||||
handleUserLevelFault(0, 0);
|
||||
restore_user_context();
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
/** DONT_TRANSLATE */
|
||||
static inline void NORETURN
|
||||
c_handle_vm_fault(vm_fault_type_t type)
|
||||
{
|
||||
c_entry_hook();
|
||||
|
||||
#ifdef TRACK_KERNEL_ENTRIES
|
||||
ksKernelEntry.path = Entry_VMFault;
|
||||
ksKernelEntry.word = getRegister(ksCurThread, LR_svc);
|
||||
#endif
|
||||
|
||||
handleVMFaultEvent(type);
|
||||
restore_user_context();
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
/** DONT_TRANSLATE */
|
||||
void VISIBLE NORETURN
|
||||
c_handle_data_fault(void)
|
||||
{
|
||||
c_handle_vm_fault(seL4_DataFault);
|
||||
}
|
||||
|
||||
/** DONT_TRANSLATE */
|
||||
void VISIBLE NORETURN
|
||||
c_handle_instruction_fault(void)
|
||||
{
|
||||
c_handle_vm_fault(seL4_InstructionFault);
|
||||
}
|
||||
|
||||
/** DONT_TRANSLATE */
|
||||
void VISIBLE NORETURN
|
||||
c_handle_interrupt(void)
|
||||
{
|
||||
c_entry_hook();
|
||||
|
||||
#ifdef TRACK_KERNEL_ENTRIES
|
||||
ksKernelEntry.path = Entry_Interrupt;
|
||||
ksKernelEntry.word = getActiveIRQ();
|
||||
#endif
|
||||
|
||||
handleInterruptEntry();
|
||||
restore_user_context();
|
||||
}
|
||||
|
||||
/** DONT_TRANSLATE */
|
||||
void NORETURN
|
||||
slowpath(syscall_t syscall)
|
||||
{
|
||||
#ifdef TRACK_KERNEL_ENTIRES
|
||||
ksEntry.is_fastpath = 0;
|
||||
#endif /* TRACK KERNEL ENTRIES */
|
||||
handleSyscall(syscall);
|
||||
|
||||
restore_user_context();
|
||||
|
|
@ -25,11 +94,13 @@ void NORETURN slowpath(syscall_t syscall)
|
|||
}
|
||||
|
||||
/** DONT_TRANSLATE */
|
||||
void VISIBLE c_handle_syscall(word_t cptr, word_t msgInfo, syscall_t syscall)
|
||||
void VISIBLE
|
||||
c_handle_syscall(word_t cptr, word_t msgInfo, syscall_t syscall)
|
||||
{
|
||||
c_entry_hook();
|
||||
#if defined(DEBUG) || defined(CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES)
|
||||
#if TRACK_KERNEL_ENTRIES
|
||||
benchmark_debug_syscall_start(cptr, msgInfo, syscall);
|
||||
ksKernelEntry.is_fastpath = 1;
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifdef CONFIG_FASTPATH
|
||||
|
|
@ -43,6 +114,10 @@ void VISIBLE c_handle_syscall(word_t cptr, word_t msgInfo, syscall_t syscall)
|
|||
#endif /* CONFIG_FASTPATH */
|
||||
|
||||
if (unlikely(syscall < SYSCALL_MIN || syscall > SYSCALL_MAX)) {
|
||||
#ifdef TRACK_KERNEL_ENTIRES
|
||||
ksKernelEntry.path = Entry_UnknownSyscall;
|
||||
/* ksKernelEntry.word word is already set to syscall */
|
||||
#endif /* TRACK_KERNEL_ENTRIES */
|
||||
handleUnknownSyscall(syscall);
|
||||
restore_user_context();
|
||||
UNREACHABLE();
|
||||
|
|
@ -51,3 +126,20 @@ void VISIBLE c_handle_syscall(word_t cptr, word_t msgInfo, syscall_t syscall)
|
|||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
/** DONT_TRANSLATE */
|
||||
VISIBLE NORETURN void
|
||||
c_handle_vcpu_fault(word_t hsr)
|
||||
{
|
||||
c_entry_hook();
|
||||
|
||||
#ifdef TRACK_KERNEL_ENTRIES
|
||||
ksKernelEntry.path = Entry_VCPUFault;
|
||||
ksKernelEntry.word = hsr;
|
||||
#endif
|
||||
handleVCPUFault(hsr);
|
||||
restore_user_context();
|
||||
UNREACHABLE();
|
||||
}
|
||||
#endif /* CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||
|
|
|
|||
|
|
@ -596,12 +596,10 @@ invokeVCPUSetTCB(vcpu_t *vcpu, tcb_t *tcb)
|
|||
void
|
||||
handleVCPUFault(word_t hsr)
|
||||
{
|
||||
c_entry_hook();
|
||||
current_fault = fault_vcpu_fault_new(hsr);
|
||||
handleFault(ksCurThread);
|
||||
schedule();
|
||||
activateThread();
|
||||
c_exit_hook();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -18,22 +18,38 @@
|
|||
#include <benchmark_track.h>
|
||||
#include <benchmark_utilisation.h>
|
||||
|
||||
void VISIBLE c_handle_interrupt(int irq, int syscall)
|
||||
/** DONT_TRANSLATE */
|
||||
void VISIBLE
|
||||
c_handle_interrupt(int irq, int syscall)
|
||||
{
|
||||
/* for annoying reasons we cannot currently consider this the C entry
|
||||
* point as we would like to call various functions that are considered
|
||||
* as entry points from the point of view of the arm code. Therefore
|
||||
* we are *not* calling c_entry_hook here */
|
||||
c_entry_hook();
|
||||
|
||||
if (irq == int_unimpl_dev) {
|
||||
handleUnimplementedDevice();
|
||||
#ifdef TRACK_KERNEL_ENTRIES
|
||||
ksKernelEntry.path = Entry_UnimplementedDevice;
|
||||
ksKernelEntry.word = irq;
|
||||
#endif
|
||||
} else if (irq == int_page_fault) {
|
||||
/* Error code is in Error. Pull out bit 5, which is whether it was instruction or data */
|
||||
handleVMFaultEvent((ksCurThread->tcbArch.tcbContext.registers[Error] >> 4) & 1);
|
||||
vm_fault_type_t type = (ksCurThread->tcbArch.tcbContext.registers[Error] >> 4u) & 1u;
|
||||
#ifdef TRACK_KERNEL_ENTRIES
|
||||
ksKernelEntry.path = Entry_VMFault;
|
||||
ksKernelEntry.word = type;
|
||||
#endif
|
||||
handleVMFaultEvent(type);
|
||||
} else if (irq < int_irq_min) {
|
||||
#ifdef TRACK_KERNEL_ENTRIES
|
||||
ksKernelEntry.path = Entry_UserLevelFault;
|
||||
ksKernelEntry.word = irq;
|
||||
#endif
|
||||
handleUserLevelFault(irq, ksCurThread->tcbArch.tcbContext.registers[Error]);
|
||||
} else if (likely(irq < int_trap_min)) {
|
||||
x86KScurInterrupt = irq;
|
||||
#ifdef TRACK_KERNEL_ENTRIES
|
||||
ksKernelEntry.path = Entry_Interrupt;
|
||||
ksKernelEntry.word = irq;
|
||||
#endif
|
||||
handleInterruptEntry();
|
||||
} else if (irq == int_spurious) {
|
||||
/* fall through to restore_user_context and do nothing */
|
||||
|
|
@ -45,14 +61,16 @@ void VISIBLE c_handle_interrupt(int irq, int syscall)
|
|||
ksCurThread->tcbArch.tcbContext.registers[FaultIP] -= 2;
|
||||
/* trap number is MSBs of the syscall number and the LSBS of EAX */
|
||||
sys_num = (irq << 24) | (syscall & 0x00ffffff);
|
||||
/* in this case we are calling a function that is *not*
|
||||
* an entry point */
|
||||
c_entry_hook();
|
||||
#ifdef TRACK_KERNEL_ENTIRES
|
||||
ksKernelEntry.path = Entry_UnknownSyscall;
|
||||
ksKernelEntry.word = sys_num;
|
||||
#endif
|
||||
handleUnknownSyscall(sys_num);
|
||||
}
|
||||
restore_user_context();
|
||||
}
|
||||
|
||||
/** DONT_TRANSLATE */
|
||||
void NORETURN
|
||||
slowpath(syscall_t syscall)
|
||||
{
|
||||
|
|
@ -61,21 +79,32 @@ slowpath(syscall_t syscall)
|
|||
ksCurThread->tcbArch.tcbContext.registers[NextIP] += 2;
|
||||
/* check for undefined syscall */
|
||||
if (unlikely(syscall < SYSCALL_MIN || syscall > SYSCALL_MAX)) {
|
||||
#ifdef TRACK_KERNEL_ENTIRES
|
||||
ksKernelEntry.path = Entry_UnknownSyscall;
|
||||
/* ksKernelEntry.word word is already set to syscall */
|
||||
#endif /* TRACK_KERNEL_ENTRIES */
|
||||
handleUnknownSyscall(syscall);
|
||||
} else {
|
||||
#ifdef TRACK_KERNEL_ENTIRES
|
||||
ksEntry.is_fastpath = 0;
|
||||
#endif /* TRACK KERNEL ENTRIES */
|
||||
handleSyscall(syscall);
|
||||
}
|
||||
|
||||
restore_user_context();
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void VISIBLE c_handle_syscall(word_t cptr, word_t msgInfo, syscall_t syscall)
|
||||
/** DONT_TRANSLATE */
|
||||
void VISIBLE
|
||||
c_handle_syscall(word_t cptr, word_t msgInfo, syscall_t syscall)
|
||||
{
|
||||
c_entry_hook();
|
||||
|
||||
#if defined(DEBUG) || defined(CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES)
|
||||
#ifdef TRACK_KERNEL_ENTRIES
|
||||
benchmark_debug_syscall_start(cptr, msgInfo, syscall);
|
||||
#endif /* DEBUG */
|
||||
ksKernelEntry.is_fastpath = 1;
|
||||
#endif /* TRACK_KERNEL_ENTRIES */
|
||||
|
||||
#ifdef CONFIG_FASTPATH
|
||||
if (syscall == SysCall) {
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ switchFpuOwner(tcb_t *new_owner)
|
|||
VISIBLE exception_t
|
||||
handleUnimplementedDevice(void)
|
||||
{
|
||||
c_entry_hook();
|
||||
/*
|
||||
* If we have already given the FPU to the user, we should not reach here.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in a new issue