debug: add get thread affinity syscall

This is useful for sel4test et al for testing that a certain
PD has been succesfully migrated between cores, or that it
is running on a particular core.

Signed-off-by: Julia Vassiliki <julia.vassiliki@unsw.edu.au>
This commit is contained in:
Julia Vassiliki 2026-05-12 10:44:34 +10:00 committed by Julia
parent 4ee903cf50
commit 90b5159800
8 changed files with 104 additions and 5 deletions

View file

@ -28,6 +28,9 @@ description indicates whether it is SOURCE-COMPATIBLE, BINARY-COMPATIBLE, or BRE
### Changes ### Changes
* Add `seL4_DebugGetThreadAffinity()` syscall to return the current affinity of a thread
in SMP configurations.
### Platforms ### Platforms
* Add support for the stm32mp2 SoC family * Add support for the stm32mp2 SoC family

View file

@ -645,6 +645,21 @@ LIBSEL4_INLINE_FUNC void seL4_DebugNameThread(seL4_CPtr tcb, const char *name)
} }
#if CONFIG_ENABLE_SMP_SUPPORT #if CONFIG_ENABLE_SMP_SUPPORT
LIBSEL4_INLINE_FUNC seL4_Word seL4_DebugGetThreadAffinity(seL4_CPtr tcb)
{
seL4_Word unused0 = 0;
seL4_Word unused1 = 0;
seL4_Word unused2 = 0;
seL4_Word unused3 = 0;
seL4_Word unused4 = 0;
seL4_Word affinity = 0;
arm_sys_send_recv(seL4_SysDebugGetThreadAffinity, tcb, &affinity, 0,
&unused0, &unused1, &unused2, &unused3, &unused4, 0);
return affinity;
}
LIBSEL4_INLINE_FUNC void seL4_DebugSendIPI(seL4_Uint8 target, unsigned irq) LIBSEL4_INLINE_FUNC void seL4_DebugSendIPI(seL4_Uint8 target, unsigned irq)
{ {
arm_sys_send(seL4_SysDebugSendIPI, target, irq, 0, 0, 0, 0); arm_sys_send(seL4_SysDebugSendIPI, target, irq, 0, 0, 0, 0);

View file

@ -849,7 +849,24 @@ LIBSEL4_INLINE_FUNC void seL4_DebugNameThread(seL4_CPtr tcb, const char *name)
riscv_sys_send_recv(seL4_SysDebugNameThread, tcb, &unused0, 0, &unused1, &unused2, &unused3, riscv_sys_send_recv(seL4_SysDebugNameThread, tcb, &unused0, 0, &unused1, &unused2, &unused3,
&unused4, &unused5, 0); &unused4, &unused5, 0);
} }
#endif
#if CONFIG_ENABLE_SMP_SUPPORT
LIBSEL4_INLINE_FUNC seL4_Word seL4_DebugGetThreadAffinity(seL4_CPtr tcb)
{
seL4_Word unused0 = 0;
seL4_Word unused1 = 0;
seL4_Word unused2 = 0;
seL4_Word unused3 = 0;
seL4_Word unused4 = 0;
seL4_Word affinity = 0;
riscv_sys_send_recv(seL4_SysDebugGetThreadAffinity, tcb, &affinity, 0,
&unused0, &unused1, &unused2, &unused3, &unused4, 0);
return affinity;
}
#endif /* CONFIG_ENABLE_SMP_SUPPORT */
#endif /* CONFIG_DEBUG_BUILD */
#ifdef CONFIG_DANGEROUS_CODE_INJECTION #ifdef CONFIG_DANGEROUS_CODE_INJECTION
LIBSEL4_INLINE_FUNC void seL4_DebugRun(void (* userfn)(void *), void *userarg) LIBSEL4_INLINE_FUNC void seL4_DebugRun(void (* userfn)(void *), void *userarg)

View file

@ -57,6 +57,7 @@
</and> </and>
</condition> </condition>
<syscall name="DebugSendIPI"/> <syscall name="DebugSendIPI"/>
<syscall name="DebugGetThreadAffinity"/>
</config> </config>
<config> <config>
<condition><config var="CONFIG_DANGEROUS_CODE_INJECTION"/></condition> <condition><config var="CONFIG_DANGEROUS_CODE_INJECTION"/></condition>

View file

@ -118,7 +118,22 @@ seL4_DebugCapIdentify(seL4_CPtr cap);
*/ */
LIBSEL4_INLINE_FUNC void LIBSEL4_INLINE_FUNC void
seL4_DebugNameThread(seL4_CPtr tcb, const char *name); seL4_DebugNameThread(seL4_CPtr tcb, const char *name);
#if defined(CONFIG_ENABLE_SMP_SUPPORT) && defined(CONFIG_ARCH_ARM) #if defined(CONFIG_ENABLE_SMP_SUPPORT)
/**
* @xmlonly <manual name="Get thread affinity" label="sel4_debugthreadgetaffinity"/> @endxmlonly
* @brief Get the current affinity of a thread.
*
* This gets the value of the kernel's tcb_t->tcbAffinity field, which corresponds
* to the core (affinity) of the thread. If the thread is not running (e.g. blocked)
* this is the last core it ran on.
*
* @param tcb A capability to the tcb object for the thread to query.
*
*/
LIBSEL4_INLINE_FUNC seL4_Word
seL4_DebugGetThreadAffinity(seL4_CPtr tcb);
#if defined(CONFIG_ARCH_ARM)
/** /**
* @xmlonly <manual name="Send SGI 0-15" label="sel4_debugsendipi"/> @endxmlonly * @xmlonly <manual name="Send SGI 0-15" label="sel4_debugsendipi"/> @endxmlonly
* @brief Sends arbitrary SGI. * @brief Sends arbitrary SGI.
@ -131,8 +146,9 @@ seL4_DebugNameThread(seL4_CPtr tcb, const char *name);
*/ */
LIBSEL4_INLINE_FUNC void LIBSEL4_INLINE_FUNC void
seL4_DebugSendIPI(seL4_Uint8 target, unsigned irq); seL4_DebugSendIPI(seL4_Uint8 target, unsigned irq);
#endif #endif /* CONFIG_ARCH_ARM */
#endif #endif /* CONFIG_ENABLE_SMP_SUPPORT */
#endif /* CONFIG_DEBUG_BUILD */
#ifdef CONFIG_DANGEROUS_CODE_INJECTION #ifdef CONFIG_DANGEROUS_CODE_INJECTION
/** /**

View file

@ -874,6 +874,23 @@ LIBSEL4_INLINE_FUNC void seL4_DebugNameThread(seL4_CPtr tcb, const char *name)
x86_sys_send_recv(seL4_SysDebugNameThread, tcb, &unused0, 0, &unused1, &unused2, MCS_COND(0, &unused3)); x86_sys_send_recv(seL4_SysDebugNameThread, tcb, &unused0, 0, &unused1, &unused2, MCS_COND(0, &unused3));
} }
#if CONFIG_ENABLE_SMP_SUPPORT
LIBSEL4_INLINE_FUNC seL4_Word seL4_DebugGetThreadAffinity(seL4_CPtr tcb)
{
seL4_Word unused0 = 0;
seL4_Word unused1 = 0;
seL4_Word unused2 = 0;
seL4_Word unused3 = 0;
seL4_Word unused4 = 0;
seL4_Word affinity = 0;
x86_sys_send_recv(seL4_SysDebugGetThreadAffinity, tcb, &affinity, 0,
&unused0, &unused1, MCS_COND(0, &unused2));
return affinity;
}
#endif /* CONFIG_ENABLE_SMP_SUPPORT */
#endif #endif
#if defined(CONFIG_DANGEROUS_CODE_INJECTION) #if defined(CONFIG_DANGEROUS_CODE_INJECTION)

View file

@ -673,7 +673,24 @@ LIBSEL4_INLINE_FUNC void seL4_DebugNameThread(seL4_CPtr tcb, const char *name)
x64_sys_send_recv(seL4_SysDebugNameThread, tcb, &unused0, 0, &unused1, &unused2, &unused3, &unused4, &unused5, 0); x64_sys_send_recv(seL4_SysDebugNameThread, tcb, &unused0, 0, &unused1, &unused2, &unused3, &unused4, &unused5, 0);
} }
#endif
#if CONFIG_ENABLE_SMP_SUPPORT
LIBSEL4_INLINE_FUNC seL4_Word seL4_DebugGetThreadAffinity(seL4_CPtr tcb)
{
seL4_Word unused0 = 0;
seL4_Word unused1 = 0;
seL4_Word unused2 = 0;
seL4_Word unused3 = 0;
seL4_Word unused4 = 0;
seL4_Word affinity = 0;
x64_sys_send_recv(seL4_SysDebugGetThreadAffinity, tcb, &affinity, 0,
&unused0, &unused1, &unused3, &unused4, &unused5, 0);
return affinity;
}
#endif /* CONFIG_ENABLE_SMP_SUPPORT */
#endif /* CONFIG_DEBUG_BUILD */
#if defined(CONFIG_DANGEROUS_CODE_INJECTION) #if defined(CONFIG_DANGEROUS_CODE_INJECTION)
LIBSEL4_INLINE_FUNC void seL4_DebugRun(void (*userfn)(void *), void *userarg) LIBSEL4_INLINE_FUNC void seL4_DebugRun(void (*userfn)(void *), void *userarg)

View file

@ -158,6 +158,19 @@ exception_t handleUnknownSyscall(word_t w)
return EXCEPTION_NONE; return EXCEPTION_NONE;
} }
#ifdef ENABLE_SMP_SUPPORT #ifdef ENABLE_SMP_SUPPORT
if (w == SysDebugGetThreadAffinity) {
word_t cptr = getRegister(NODE_STATE(ksCurThread), capRegister);
lookupCapAndSlot_ret_t lu_ret = lookupCapAndSlot(NODE_STATE(ksCurThread), cptr);
/* ensure we got a TCB cap */
word_t cap_type = cap_get_capType(lu_ret.cap);
if (cap_type != cap_thread_cap) {
userError("SysDebugGetThreadAffinity: cap is not a TCB, halting");
halt();
}
word_t affinity = TCB_PTR(cap_thread_cap_get_capTCBPtr(lu_ret.cap))->tcbAffinity;
setRegister(NODE_STATE(ksCurThread), capRegister, affinity);
return EXCEPTION_NONE;
}
if (w == SysDebugSendIPI) { if (w == SysDebugSendIPI) {
return handle_SysDebugSendIPI(); return handle_SysDebugSendIPI();
} }