1 /*
2  * Copyright 2014, General Dynamics C4 Systems
3  *
4  * SPDX-License-Identifier: GPL-2.0-only
5  */
6 
7 #include <types.h>
8 #include <api/failures.h>
9 #include <machine/registerset.h>
10 #include <object/structures.h>
11 #include <arch/object/tcb.h>
12 #include <arch/machine.h>
13 
Arch_decodeTransfer(word_t flags)14 word_t CONST Arch_decodeTransfer(word_t flags)
15 {
16     return 0;
17 }
18 
Arch_performTransfer(word_t arch,tcb_t * tcb_src,tcb_t * tcb_dest)19 exception_t CONST Arch_performTransfer(word_t arch, tcb_t *tcb_src, tcb_t *tcb_dest)
20 {
21     return EXCEPTION_NONE;
22 }
23 
24 #ifdef CONFIG_VTX
Arch_leaveVMAsyncTransfer(tcb_t * tcb)25 void Arch_leaveVMAsyncTransfer(tcb_t *tcb)
26 {
27     vcpu_sysvmenter_reply_to_user(tcb);
28 }
29 
performSetEPTRoot(tcb_t * tcb,cap_t cap,cte_t * slot)30 static exception_t performSetEPTRoot(tcb_t *tcb, cap_t cap, cte_t *slot)
31 {
32     cte_t *rootSlot;
33     exception_t e;
34 
35     rootSlot = TCB_PTR_CTE_PTR(tcb, tcbArchEPTRoot);
36     e = cteDelete(rootSlot, true);
37     if (e != EXCEPTION_NONE) {
38         return e;
39     }
40 
41     cteInsert(cap, slot, rootSlot);
42 
43     setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
44     return EXCEPTION_NONE;
45 }
46 
decodeSetEPTRoot(cap_t cap)47 exception_t decodeSetEPTRoot(cap_t cap)
48 {
49     cap_t rootCap;
50     cte_t *rootSlot;
51     deriveCap_ret_t dc_ret;
52 
53     rootSlot = current_extra_caps.excaprefs[0];
54 
55     if (rootSlot == NULL) {
56         userError("TCB SetEPTRoot: Truncated message.");
57         current_syscall_error.type = seL4_TruncatedMessage;
58         return EXCEPTION_SYSCALL_ERROR;
59     }
60 
61     rootCap = rootSlot->cap;
62 
63     if (cap_get_capType(rootCap) != cap_ept_pml4_cap) {
64         userError("TCB SetEPTRoot: EPT PDPT is invalid.");
65         current_syscall_error.type = seL4_IllegalOperation;
66         return EXCEPTION_SYSCALL_ERROR;
67     }
68 
69     dc_ret = deriveCap(rootSlot, rootCap);
70     if (dc_ret.status != EXCEPTION_NONE) {
71         return dc_ret.status;
72     }
73 
74     if (!cap_ept_pml4_cap_get_capPML4IsMapped(dc_ret.cap)) {
75         userError("decodeSetEPTRoot: Invalid EPT cap.");
76         current_syscall_error.type = seL4_IllegalOperation;
77         return EXCEPTION_SYSCALL_ERROR;
78     }
79 
80     return performSetEPTRoot(TCB_PTR(cap_thread_cap_get_capTCBPtr(cap)), dc_ret.cap, rootSlot);
81 }
82 #endif
83 
84 #ifdef ENABLE_SMP_SUPPORT
Arch_migrateTCB(tcb_t * thread)85 void Arch_migrateTCB(tcb_t *thread)
86 {
87 #ifdef CONFIG_KERNEL_MCS
88     assert(thread->tcbSchedContext != NULL);
89 #endif
90 
91     /* check if thread own its current core FPU */
92     if (nativeThreadUsingFPU(thread)) {
93         switchFpuOwner(NULL, thread->tcbAffinity);
94     }
95 }
96 #endif /* ENABLE_SMP_SUPPORT */
97