Contiki 3.x
tss-prot-domains.h
1 /*
2  * Copyright (C) 2015-2016, Intel Corporation. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  *
13  * 3. Neither the name of the copyright holder nor the names of its
14  * contributors may be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28  * OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #ifndef CPU_X86_MM_TSS_PROT_DOMAINS_H_
32 #define CPU_X86_MM_TSS_PROT_DOMAINS_H_
33 
34 #include <stdbool.h>
35 #include <stdint.h>
36 #include <stdlib.h>
37 #include "ldt-layout.h"
38 #include "segmentation.h"
39 #include "tss.h"
40 
41 struct dom_kern_data {
42  /** Task State Segment */
43  tss_t tss;
44  /** Local Descriptor Table with per-domain descriptors */
45  segment_desc_t ldt[LDT_NUM_DESC];
46 } __attribute__((packed));
47 
48 /* relies on dom_kern_data: */
49 #include "multi-segment.h"
50 
51 /* relies on ATTR_KERN_ADDR_SPACE: */
52 #include "syscalls.h"
53 
54 /**
55  * Data associated with each protection domain that is owned by clients of that
56  * domain and used to identify the domain.
57  */
58 struct dom_client_data {
59  dom_id_t dom_id;
60  /** The selector is only 16 bits, but it is padded to 32 bits. */
61  uint32_t tss_sel;
62 };
63 
64 extern uint32_t prot_domains_main_esp;
65 
66 #define SYSCALLS_STUB_MIDDLE(nm) \
67  /* If already in the callee protection domain, skip the protection */ \
68  /* domain switch and directly invoke the system call body */ \
69  " je _syscall_" #nm "\n\t" \
70  " movl $" EXP_STRINGIFY(_syscall_ent_##nm) ", prot_domains_syscall\n\t" \
71  " mov %esp, prot_domains_main_esp\n\t"
72 
73 #define SYSCALLS_STUB(nm) \
74  SYSCALLS_ALLOC_ENTRYPOINT(nm); \
75  asm ( \
76  ".text\n\t" \
77  ".global " #nm "\n\t" \
78  #nm ":\n\t" \
79  " str %ax\n\t" \
80  /* Compare current Task Register selector to selector for callee */ \
81  /* protection domain, in tss_sel field of dom_client_data */ \
82  " cmpw %ax, 8(%esp)\n\t" \
83  SYSCALLS_STUB_MIDDLE(nm) \
84  /* This will treat the dom_id field as the offset for the call, but */ \
85  /* that is ignored when performing a far call to a task */ \
86  " lcall *4(%esp)\n\t" \
87  " ret\n\t")
88 
89 #define SYSCALLS_STUB_SINGLETON(nm, dcd) \
90  SYSCALLS_ALLOC_ENTRYPOINT(nm); \
91  asm ( \
92  ".text\n\t" \
93  ".global " #nm "\n\t" \
94  #nm ":\n\t" \
95  " str %ax\n\t" \
96  /* Compare current Task Register selector to selector for callee */ \
97  /* protection domain, in tss_sel field of dom_client_data */ \
98  " cmpw %ax, %" SEG_KERN "s:(4 + " #dcd ")\n\t" \
99  SYSCALLS_STUB_MIDDLE(nm) \
100  /* This will treat the dom_id field as the offset for the call, but */ \
101  /* that is ignored when performing a far call to a task */ \
102  " lcall *%" SEG_KERN "s:" #dcd "\n\t" \
103  " ret\n\t")
104 
105 #define PROT_DOMAINS_ENTER_ISR(exc) \
106  MULTI_SEGMENT_ENTER_ISR(exc) \
107  /* It is possible that the system call dispatcher is being interrupted, */ \
108  /* and some interrupt handlers perform system calls. Thus, it is */ \
109  /* necessary to save and restore the system call dispatcher parameters */ \
110  /* (in callee-saved registers). */ \
111  "mov prot_domains_main_esp, %%esi\n\t" \
112  "mov prot_domains_syscall, %%edi\n\t" \
113  PROT_DOMAINS_ENTER_ISR_COMMON(exc)
114 #define PROT_DOMAINS_LEAVE_ISR(exc) \
115  PROT_DOMAINS_LEAVE_ISR_COMMON(exc) \
116  "mov %%edi, prot_domains_syscall\n\t" \
117  "mov %%esi, prot_domains_main_esp\n\t" \
118  MULTI_SEGMENT_LEAVE_ISR(exc)
119 
120 /* Allocate two additional GDT entries for each protection domain. Note that
121  * the particular storage allocated by this statement may actually be used for
122  * some other protection domain, depending on how the linker happens to arrange
123  * all of the GDT storage. The GDT_IDX_TSS and GDT_IDX_LDT macros in
124  * gdt-layout.h determine which storage is used for each protection domain.
125  * Thus, this storage should not be referenced directly by its variable name.
126  */
127 #define PROT_DOMAINS_ALLOC_IMPL(nm) \
128  static segment_desc_t ATTR_BSS_GDT_MID _gdt_storage_##nm[2]
129 
130 #endif /* CPU_X86_MM_TSS_PROT_DOMAINS_H_ */
#define __attribute__(nothing)
Define attribute to nothing since it isn't handled by IAR.
Definition: iar.h:194
Segment descriptor.
Definition: segmentation.h:89
uint32_t tss_sel
The selector is only 16 bits, but it is padded to 32 bits.
Task State Segment.
Definition: tss.h:45
Data associated with each protection domain that is owned by clients of that domain and used to ident...
Definition: prot-domains.h:247