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