forked from Imagelibrary/seL4
Add seL4_TCB_SetFlags Syscall
Add flags to tcb_t and the seL4_TCBFlag_fpuDisabled flag. Enums are signed, make TCB flags word_t to make it unsigned. Signed-off-by: Indan Zupancic <indan@nul.nu> Signed-off-by: Corey Lewis <corey.lewis@proofcraft.systems>
This commit is contained in:
committed by
Gerwin Klein
parent
8f8776a541
commit
1415cac443
@@ -242,7 +242,6 @@ typedef struct sched_context sched_context_t;
|
|||||||
typedef struct reply reply_t;
|
typedef struct reply reply_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* TCB: size >= 18 words + sizeof(arch_tcb_t) + 1 word on MCS (aligned to nearest power of 2) */
|
|
||||||
struct tcb {
|
struct tcb {
|
||||||
/* arch specific tcb state (including context)*/
|
/* arch specific tcb state (including context)*/
|
||||||
arch_tcb_t tcbArch;
|
arch_tcb_t tcbArch;
|
||||||
@@ -250,6 +249,9 @@ struct tcb {
|
|||||||
/* Thread state, 3 words */
|
/* Thread state, 3 words */
|
||||||
thread_state_t tcbState;
|
thread_state_t tcbState;
|
||||||
|
|
||||||
|
/* Currently only used for seL4_TCBFlag_fpuDisabled */
|
||||||
|
word_t tcbFlags; /* seL4_TCBFlag */
|
||||||
|
|
||||||
/* Notification that this TCB is bound to. If this is set, when this TCB waits on
|
/* Notification that this TCB is bound to. If this is set, when this TCB waits on
|
||||||
* any sync endpoint, it may receive a signal from a Notification object.
|
* any sync endpoint, it may receive a signal from a Notification object.
|
||||||
* 1 word*/
|
* 1 word*/
|
||||||
|
|||||||
@@ -825,6 +825,28 @@
|
|||||||
</error>
|
</error>
|
||||||
</method>
|
</method>
|
||||||
|
|
||||||
|
<method id="TCBSetFlags" name="SetFlags" manual_name="Set Feature Flags" manual_label="tcb_setflags">
|
||||||
|
<brief>
|
||||||
|
Set or clear <texttt text="seL4_TCBFlag"/> feature flags of the target TCB.
|
||||||
|
</brief>
|
||||||
|
<description>
|
||||||
|
A newly created TCB has all flags cleared.
|
||||||
|
Currently the only flag supported is <texttt text="seL4_TCBFlag_fpuDisabled"/>.
|
||||||
|
The flags are cleared and set in the given order, i.e. when a flag is both cleared and set, it will be set.
|
||||||
|
Unknown flags are ignored. Use zero for both clear and set to retrieve the current flags value.
|
||||||
|
</description>
|
||||||
|
<return>
|
||||||
|
The resulting TCB flags value is returned in the first message register.
|
||||||
|
</return>
|
||||||
|
<param dir="in" name="clear" type="seL4_Word" description="Bitwise OR'd set of seL4_TCBFlag to clear."/>
|
||||||
|
<param dir="in" name="set" type="seL4_Word" description="Bitwise OR'd set of seL4_TCBFlag to set."/>
|
||||||
|
<param dir="out" name="flags" type="seL4_Word" description="Returned value of the TCB flags"/>
|
||||||
|
<error name="seL4_InvalidCapability">
|
||||||
|
<description>
|
||||||
|
The <texttt text="_service"/> is a CPtr to a capability of the wrong type.
|
||||||
|
</description>
|
||||||
|
</error>
|
||||||
|
</method>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
<interface name="seL4_CNode" manual_name="CNode">
|
<interface name="seL4_CNode" manual_name="CNode">
|
||||||
|
|||||||
@@ -68,6 +68,19 @@ typedef enum {
|
|||||||
seL4_GuardMismatch,
|
seL4_GuardMismatch,
|
||||||
SEL4_FORCE_LONG_ENUM(seL4_LookupFailureType),
|
SEL4_FORCE_LONG_ENUM(seL4_LookupFailureType),
|
||||||
} seL4_LookupFailureType;
|
} seL4_LookupFailureType;
|
||||||
|
|
||||||
|
/* Flags to be used with seL4_TCB_Set_Flags */
|
||||||
|
typedef enum {
|
||||||
|
seL4_TCBFlag_NoFlag = 0x0,
|
||||||
|
seL4_TCBFlag_fpuDisabled = 0x1,
|
||||||
|
|
||||||
|
SEL4_FORCE_LONG_ENUM(seL4_TCBFlag),
|
||||||
|
seL4_TCBFlag_MASK = seL4_TCBFlag_NoFlag
|
||||||
|
#ifdef CONFIG_HAVE_FPU
|
||||||
|
| seL4_TCBFlag_fpuDisabled
|
||||||
|
#endif
|
||||||
|
} seL4_TCBFlag;
|
||||||
|
|
||||||
#endif /* !__ASSEMBLER__ */
|
#endif /* !__ASSEMBLER__ */
|
||||||
|
|
||||||
#ifdef CONFIG_KERNEL_MCS
|
#ifdef CONFIG_KERNEL_MCS
|
||||||
|
|||||||
@@ -74,6 +74,14 @@ automatically suspended when the last capability to their \obj{TCB} is
|
|||||||
deleted.
|
deleted.
|
||||||
% an example of which is demonstrated in \nameref{ex:second_thread}.
|
% an example of which is demonstrated in \nameref{ex:second_thread}.
|
||||||
|
|
||||||
|
\subsection{Thread Feature Flags}
|
||||||
|
\label{sec:thread_flags}
|
||||||
|
Specific features can be enabled or disabled on a per TCB basis with
|
||||||
|
\apifunc{seL4\_TCB\_SetFlags}{tcb_setflags}.
|
||||||
|
|
||||||
|
If access to the Floating Point Unit is not needed, it can be disabled
|
||||||
|
for individual threads to maximise context switching speed.
|
||||||
|
|
||||||
\subsection{Affinity}
|
\subsection{Affinity}
|
||||||
\label{sec:thread_affinity}
|
\label{sec:thread_affinity}
|
||||||
|
|
||||||
|
|||||||
@@ -792,6 +792,49 @@ static exception_t decodeSetTLSBase(cap_t cap, word_t length, word_t *buffer)
|
|||||||
return invokeSetTLSBase(TCB_PTR(cap_thread_cap_get_capTCBPtr(cap)), tls_base);
|
return invokeSetTLSBase(TCB_PTR(cap_thread_cap_get_capTCBPtr(cap)), tls_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void invokeSetFlags(tcb_t *thread, word_t clear, word_t set, bool_t call)
|
||||||
|
{
|
||||||
|
tcb_t *cur_thread = NODE_STATE(ksCurThread);
|
||||||
|
word_t flags = thread->tcbFlags;
|
||||||
|
|
||||||
|
flags &= ~clear;
|
||||||
|
flags |= set & seL4_TCBFlag_MASK;
|
||||||
|
thread->tcbFlags = flags;
|
||||||
|
|
||||||
|
#ifdef CONFIG_HAVE_FPU
|
||||||
|
/* Save current FPU state before disabling FPU: */
|
||||||
|
if (flags & seL4_TCBFlag_fpuDisabled) {
|
||||||
|
fpuThreadDelete(thread);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (call) {
|
||||||
|
word_t *ipcBuffer = lookupIPCBuffer(true, cur_thread);
|
||||||
|
setRegister(cur_thread, badgeRegister, 0);
|
||||||
|
unsigned int length = setMR(cur_thread, ipcBuffer, 0, flags);
|
||||||
|
setRegister(cur_thread, msgInfoRegister, wordFromMessageInfo(
|
||||||
|
seL4_MessageInfo_new(0, 0, 0, length)));
|
||||||
|
}
|
||||||
|
setThreadState(cur_thread, ThreadState_Running);
|
||||||
|
}
|
||||||
|
|
||||||
|
static exception_t decodeSetFlags(cap_t cap, word_t length, bool_t call, word_t *buffer)
|
||||||
|
{
|
||||||
|
tcb_t *thread = TCB_PTR(cap_thread_cap_get_capTCBPtr(cap));
|
||||||
|
|
||||||
|
if (length < 2) {
|
||||||
|
userError("TCB SetFlags: Truncated message.");
|
||||||
|
current_syscall_error.type = seL4_TruncatedMessage;
|
||||||
|
return EXCEPTION_SYSCALL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
word_t clear = getSyscallArg(0, buffer);
|
||||||
|
word_t set = getSyscallArg(1, buffer);
|
||||||
|
|
||||||
|
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
||||||
|
invokeSetFlags(thread, clear, set, call);
|
||||||
|
return EXCEPTION_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/* The following functions sit in the syscall error monad, but include the
|
/* The following functions sit in the syscall error monad, but include the
|
||||||
* exception cases for the preemptible bottom end, as they call the invoke
|
* exception cases for the preemptible bottom end, as they call the invoke
|
||||||
* functions directly. This is a significant deviation from the Haskell
|
* functions directly. This is a significant deviation from the Haskell
|
||||||
@@ -885,6 +928,9 @@ exception_t decodeTCBInvocation(word_t invLabel, word_t length, cap_t cap,
|
|||||||
case TCBSetTLSBase:
|
case TCBSetTLSBase:
|
||||||
return decodeSetTLSBase(cap, length, buffer);
|
return decodeSetTLSBase(cap, length, buffer);
|
||||||
|
|
||||||
|
case TCBSetFlags:
|
||||||
|
return decodeSetFlags(cap, length, call, buffer);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Haskell: "throw IllegalOperation" */
|
/* Haskell: "throw IllegalOperation" */
|
||||||
userError("TCB: Illegal operation.");
|
userError("TCB: Illegal operation.");
|
||||||
|
|||||||
Reference in New Issue
Block a user