Thank you, now it is clear for me
The kernel differentiates between fault instruction and next instruction in some cases. Might make more sense to just explain some different cases
* If a thread is interrupted by a hardware interrupt, then it should start running again at the address of the next instruction that should be executed. In this case the fault instruction is irrelevant, all the kernel will use is the 'next instruction'. What this really means is the kernel will do nothing to signal to the arch layer that the resume address should be modified. So on architectures like arm (where we store LR) or x86 (where the hardware saves NextIP) when we unstack the user context everything is correct. From the non-arch side of the kernel the thread is always kept at ThreadState_Running, and if you look in activateThread you will see this causes the thread to be untouched when rescheduling it.
* If a thread does a syscall it is more complicated. The kernel may want to start the thread running either at the instruction after the trap instruction, if the syscall completed, or set it running back at the trap instruction if the syscall needs to get restarted. This is where the fault instruction comes in. In handleInvocation you will see if a check for 'if (unlikely(status == EXCEPTION_PREEMPTED))', which if true results in handleInvocation immediately returning. At the point it returns the thread state is set to ThreadState_Restart, and if you look back in activateThread you will see this results in setting the next instruction to 'getRestartPC', which on arm is FaultInstruction. This means that when we resume this thread it will immediately perform the trap instruction again (this is how the kernel does pre-emption for long running operations). If that check for EXCEPTION_PREEMPTED was false and all goes well with the invocation then the 'setThreadState(thread, ThreadState_Running)' at the bottom of the function gets called. This once again means that activateThread does nothing, and this thread will start running at its next instruction, which is assumed to be the instruction after the trap.
Other kinds of faults (vm faults etc) are a bit different in that it is the user level fault handler that gets to pick the next instruction.
Adrian
On Sat 15-Oct-2016 11:02 PM, Vasily A. Sartakov wrote:
we take address that causes syscall from the ksCurThread and set them back. Thus, FaultInstruction should point to something different, right?
I have add FaultInstruction in the same manner as it made in ARM platform:
sub lr, lr, #4
/* Store FaultInstruction */ str lr, [sp, #(PT_FaultInstruction - PT_LR_svc)]
I am tacking address of an instruction causes exception, subtract 4 from the value, and save it into the FauiltInstruction. Now get* and set* functions are:
word_t PURE getRestartPC(tcb_t *thread) { return getRegister(thread, FaultInstruction); }
void setNextPC(tcb_t *thread, word_t v) { setRegister(thread, CP0_EPC, v); }
Also, Faultinstruction is part of frameRegisters and «linked» with cp0_epc of seL4_UserContext (sel4arch.xml)
Now both tests are passed:
Starting test 27: TEST_RECYCLE0001 TEST_RECYCLE0001 Running test RECYCLE0001 (Basic endpoint recycle testing.) <
> < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > Test RECYCLE0001 passed Starting test 28: TEST_RECYCLE0002 TEST_RECYCLE0002 Running test RECYCLE0002 (Recycle deletes caps) < > < > < > < > < > < > < > < > < > < > <<..>
<
> < > < > < > Test RECYCLE0002 passed Can you please tell me something about the Faultinstruction context field, and, in general, what the assumptions about the behaviour of CPU you put into the design. For example, in MIPS, in a case of a trap, EPC points on instruction causes a trap, but in a case of an interrupt, PC and further EPC points on next instruction. Should I take this into the account somewhere in the kernel?
Hope that helps.
Regards, Hesham ________________________________________ From: Devel
on behalf of Vasily A.Sartakov Sent: Friday, October 14, 2016 12:33 AM To: devel@sel4.systems
Subject: [seL4] endpoint.c
Hello.
I have a problem with endpoint.c test (RECYCLE0001):
Error: seL4_MessageInfo_get_label(tag) == seL4_InvalidCapability at line 50 of file /long/path/apps/sel4test-tests/src/tests/endpoints.c
I am reading MR(0) in call_func above this check and see, that seL4_Call returns values that were sent before. For example, 100 for the first thread, 101 for the second and etc. Thus, as far I understand, cnode_recycle does not work at all. I am pretty sure that my seL4_Call syscall was implemented properly. I have looked inside the kernel, and tried to track everything related to cteRecycle and do not see anything platform specific. I know that it is a complicated question, but any ideas or hints where to look?
-- Vasily A. Sartakov sartakov@ksyslabs.org