1 /* $NetBSD: segments.h,v 1.38 2021/04/17 20:12:55 rillig Exp $ */ 2 3 /* 4 * Copyright (c) 1990 The Regents of the University of California. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * William Jolitz. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * @(#)segments.h 7.1 (Berkeley) 5/9/91 35 */ 36 37 /* 38 * Copyright (c) 1995, 1997 39 * Charles M. Hannum. All rights reserved. 40 * Copyright (c) 1989, 1990 William F. Jolitz 41 * 42 * This code is derived from software contributed to Berkeley by 43 * William Jolitz. 44 * 45 * Redistribution and use in source and binary forms, with or without 46 * modification, are permitted provided that the following conditions 47 * are met: 48 * 1. Redistributions of source code must retain the above copyright 49 * notice, this list of conditions and the following disclaimer. 50 * 2. Redistributions in binary form must reproduce the above copyright 51 * notice, this list of conditions and the following disclaimer in the 52 * documentation and/or other materials provided with the distribution. 53 * 3. All advertising materials mentioning features or use of this software 54 * must display the following acknowledgement: 55 * This product includes software developed by the University of 56 * California, Berkeley and its contributors. 57 * 4. Neither the name of the University nor the names of its contributors 58 * may be used to endorse or promote products derived from this software 59 * without specific prior written permission. 60 * 61 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 62 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 63 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 64 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 65 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 66 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 67 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 68 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 69 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 70 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 71 * SUCH DAMAGE. 72 * 73 * @(#)segments.h 7.1 (Berkeley) 5/9/91 74 */ 75 76 /* 77 * Adapted for NetBSD/amd64 by fvdl@wasabisystems.com. 78 */ 79 80 /* 81 * 386 Segmentation Data Structures and definitions 82 * William F. Jolitz (william@ernie.berkeley.edu) 6/20/1989 83 */ 84 85 #ifndef _AMD64_SEGMENTS_H_ 86 #define _AMD64_SEGMENTS_H_ 87 88 #ifdef __x86_64__ 89 90 #ifdef _KERNEL_OPT 91 #include "opt_xen.h" 92 #endif 93 94 /* 95 * Selectors 96 */ 97 98 #define ISPL(s) ((s) & SEL_RPL) /* what is the priority level of a selector */ 99 #ifdef XENPV 100 #define SEL_KPL 3 /* kernel privilege level */ 101 #define SEL_XPL 0 /* Xen Hypervisor privilege level */ 102 #else 103 #define SEL_KPL 0 /* kernel privilege level */ 104 #endif 105 #define SEL_UPL 3 /* user privilege level */ 106 #define SEL_RPL 3 /* requester's privilege level mask */ 107 #define ISLDT(s) ((s) & SEL_LDT) /* is it local or global */ 108 #define SEL_LDT 4 /* local descriptor table */ 109 110 #ifdef XENPV 111 #define IOPL_KPL 1 112 #else 113 #define IOPL_KPL SEL_KPL 114 #endif 115 116 /* Dynamically allocated TSSs and LDTs start (byte offset) */ 117 #define SYSSEL_START (NGDT_MEM << 3) 118 #define DYNSEL_START (SYSSEL_START + (NGDT_SYS << 4)) 119 120 /* 121 * These define the index not from the start of the GDT, but from 122 * the part of the GDT that they're allocated from. 123 * First NGDT_MEM entries are 8-byte descriptors for CS and DS. 124 * Next NGDT_SYS entries are 16-byte descriptors defining LDTs. 125 * 126 * The rest is 16-byte descriptors for TSS and LDT. 127 */ 128 129 #define IDXSEL(s) (((s) >> 3) & 0x1fff) 130 #define IDXDYNSEL(s) ((((s) & ~SEL_RPL) - DYNSEL_START) >> 4) 131 132 #define GSEL(s,r) (((s) << 3) | r) 133 #define GSYSSEL(s,r) ((((s) << 4) + SYSSEL_START) | r) 134 #define GDYNSEL(s,r) ((((s) << 4) + DYNSEL_START) | r | SEL_KPL) 135 136 #define LSEL(s,r) ((s) | r | SEL_LDT) 137 138 #define USERMODE(c) (ISPL(c) == SEL_UPL) 139 #ifdef XENPV 140 /* 141 * As KPL == UPL, Xen emulate interrupt in kernel context by pushing 142 * a fake CS with XPL privilege 143 */ 144 #define KERNELMODE(c) (ISPL(c) == SEL_XPL) 145 #else 146 #define KERNELMODE(c) (ISPL(c) == SEL_KPL) 147 #endif 148 149 #ifndef _LOCORE 150 151 /* 152 * Memory and System segment descriptors 153 */ 154 155 /* 156 * System segment descriptor (16 bytes): used for TSS and LDT. 157 */ 158 struct sys_segment_descriptor { 159 uint64_t sd_lolimit:16; /* segment extent (lsb) */ 160 uint64_t sd_lobase:24; /* segment base address (lsb) */ 161 uint64_t sd_type:5; /* segment type */ 162 uint64_t sd_dpl:2; /* segment descriptor priority level */ 163 uint64_t sd_p:1; /* segment descriptor present */ 164 uint64_t sd_hilimit:4; /* segment extent (msb) */ 165 uint64_t sd_xx1:3; /* avl, long and def32 (not used) */ 166 uint64_t sd_gran:1; /* limit granularity (byte/page) */ 167 uint64_t sd_hibase:40; /* segment base address (msb) */ 168 uint64_t sd_xx2:8; /* reserved */ 169 uint64_t sd_zero:5; /* must be zero */ 170 uint64_t sd_xx3:19; /* reserved */ 171 } __packed; 172 173 /* 174 * Memory segment descriptor (8 bytes): used for cs, ds, etc. 175 */ 176 struct mem_segment_descriptor { 177 unsigned sd_lolimit:16; /* segment extent (lsb) */ 178 unsigned sd_lobase:24; /* segment base address (lsb) */ 179 unsigned sd_type:5; /* segment type */ 180 unsigned sd_dpl:2; /* segment descriptor priority level */ 181 unsigned sd_p:1; /* segment descriptor present */ 182 unsigned sd_hilimit:4; /* segment extent (msb) */ 183 unsigned sd_avl:1; /* available */ 184 unsigned sd_long:1; /* long mode */ 185 unsigned sd_def32:1; /* default 32 vs 16 bit size */ 186 unsigned sd_gran:1; /* limit granularity (byte/page) */ 187 unsigned sd_hibase:8; /* segment base address (msb) */ 188 } __packed; 189 190 /* 191 * Common part of the above structures. Used to walk descriptor tables. 192 */ 193 struct common_segment_descriptor { 194 unsigned sdc_lolimit:16; 195 unsigned sdc_lobase:24; 196 unsigned sdc_type:5; 197 unsigned sdc_other:19; 198 } __packed; 199 200 /* 201 * Gate descriptors (16 bytes). 202 */ 203 struct gate_descriptor { 204 uint64_t gd_looffset:16;/* gate offset (lsb) */ 205 uint64_t gd_selector:16;/* gate segment selector */ 206 uint64_t gd_ist:3; /* IST select */ 207 uint64_t gd_xx1:5; /* reserved */ 208 uint64_t gd_type:5; /* segment type */ 209 uint64_t gd_dpl:2; /* segment descriptor priority level */ 210 uint64_t gd_p:1; /* segment descriptor present */ 211 uint64_t gd_hioffset:48;/* gate offset (msb) */ 212 uint64_t gd_xx2:8; /* reserved */ 213 uint64_t gd_zero:5; /* must be zero */ 214 uint64_t gd_xx3:19; /* reserved */ 215 } __packed; 216 217 /* 218 * Generic descriptor (8 bytes). Note: it does not include system segment 219 * descriptors and gate descriptors, since these are 16-byte-long. 220 */ 221 union descriptor { 222 struct mem_segment_descriptor sd; 223 uint32_t raw[2]; 224 uint64_t raw64; 225 } __packed; 226 227 /* 228 * Region descriptors, used to load gdt/idt tables before segments yet exist. 229 */ 230 struct region_descriptor { 231 uint16_t rd_limit; /* segment extent */ 232 uint64_t rd_base; /* base address */ 233 } __packed; 234 235 #ifdef _KERNEL 236 #ifdef XENPV 237 typedef struct trap_info idt_descriptor_t; 238 #else 239 typedef struct gate_descriptor idt_descriptor_t; 240 #endif /* XENPV */ 241 extern char *gdtstore; 242 extern char *ldtstore; 243 244 void setgate(struct gate_descriptor *, void *, int, int, int, int); 245 void unsetgate(struct gate_descriptor *); 246 void set_idtgate(idt_descriptor_t *, void *, int, int, int, int); 247 void unset_idtgate(idt_descriptor_t *); 248 void setregion(struct region_descriptor *, void *, uint16_t); 249 void set_sys_segment(struct sys_segment_descriptor *, void *, size_t, 250 int, int, int); 251 void set_mem_segment(struct mem_segment_descriptor *, void *, size_t, 252 int, int, int, int, int); 253 void update_descriptor(void *, void *); 254 255 struct idt_vec; 256 void idt_vec_reserve(struct idt_vec *, int); 257 int idt_vec_alloc(struct idt_vec *, int, int); 258 void idt_vec_set(struct idt_vec *, int, void (*)(void)); 259 void idt_vec_free(struct idt_vec *, int); 260 void idt_vec_init_cpu_md(struct idt_vec *, cpuid_t); 261 bool idt_vec_is_pcpu(void); 262 struct idt_vec * idt_vec_ref(struct idt_vec *); 263 264 265 struct lwp; 266 void cpu_segregs64_zero(struct lwp *); 267 void cpu_segregs32_zero(struct lwp *); 268 void cpu_fsgs_reload(struct lwp *, int, int); 269 270 #endif /* _KERNEL */ 271 272 #endif /* !_LOCORE */ 273 274 /* system segments and gate types */ 275 #define SDT_SYSNULL 0 /* system null */ 276 #define SDT_SYS286TSS 1 /* system 286 TSS available */ 277 #define SDT_SYSLDT 2 /* system local descriptor table */ 278 #define SDT_SYS286BSY 3 /* system 286 TSS busy */ 279 #define SDT_SYS286CGT 4 /* system 286 call gate */ 280 #define SDT_SYSTASKGT 5 /* system task gate */ 281 #define SDT_SYS286IGT 6 /* system 286 interrupt gate */ 282 #define SDT_SYS286TGT 7 /* system 286 trap gate */ 283 #define SDT_SYSNULL2 8 /* system null again */ 284 #define SDT_SYS386TSS 9 /* system 386 TSS available */ 285 #define SDT_SYSNULL3 10 /* system null again */ 286 #define SDT_SYS386BSY 11 /* system 386 TSS busy */ 287 #define SDT_SYS386CGT 12 /* system 386 call gate */ 288 #define SDT_SYSNULL4 13 /* system null again */ 289 #define SDT_SYS386IGT 14 /* system 386 interrupt gate */ 290 #define SDT_SYS386TGT 15 /* system 386 trap gate */ 291 292 /* memory segment types */ 293 #define SDT_MEMRO 16 /* memory read only */ 294 #define SDT_MEMROA 17 /* memory read only accessed */ 295 #define SDT_MEMRW 18 /* memory read write */ 296 #define SDT_MEMRWA 19 /* memory read write accessed */ 297 #define SDT_MEMROD 20 /* memory read only expand dwn limit */ 298 #define SDT_MEMRODA 21 /* memory read only expand dwn limit accessed */ 299 #define SDT_MEMRWD 22 /* memory read write expand dwn limit */ 300 #define SDT_MEMRWDA 23 /* memory read write expand dwn limit accessed */ 301 #define SDT_MEME 24 /* memory execute only */ 302 #define SDT_MEMEA 25 /* memory execute only accessed */ 303 #define SDT_MEMER 26 /* memory execute read */ 304 #define SDT_MEMERA 27 /* memory execute read accessed */ 305 #define SDT_MEMEC 28 /* memory execute only conforming */ 306 #define SDT_MEMEAC 29 /* memory execute only accessed conforming */ 307 #define SDT_MEMERC 30 /* memory execute read conforming */ 308 #define SDT_MEMERAC 31 /* memory execute read accessed conforming */ 309 310 /* 311 * Segment Protection Exception code bits 312 */ 313 #define SEGEX_EXT 0x01 /* recursive or externally induced */ 314 #define SEGEX_IDT 0x02 /* interrupt descriptor table */ 315 #define SEGEX_TI 0x04 /* local descriptor table */ 316 317 /* 318 * Entries in the Interrupt Descriptor Table (IDT) 319 */ 320 #define NIDT 256 321 #define NCPUIDT 32 /* reserved entries for CPU exceptions */ 322 323 /* 324 * Entries in the Global Descriptor Table (GDT) 325 * The code and data descriptors must come first. There 326 * are NGDT_MEM of them. 327 * 328 * Then come the predefined LDT (and possibly TSS) descriptors. 329 * There are NGDT_SYS of them. 330 */ 331 #define GNULL_SEL 0 /* Null descriptor */ 332 #define GCODE_SEL 1 /* Kernel code descriptor */ 333 #define GDATA_SEL 2 /* Kernel data descriptor */ 334 #define GUCODE_SEL 3 /* User code descriptor */ 335 #define GUDATA_SEL 4 /* User data descriptor */ 336 #define GAPM32CODE_SEL 5 337 #define GAPM16CODE_SEL 6 338 #define GAPMDATA_SEL 7 339 #define GBIOSCODE_SEL 8 340 #define GBIOSDATA_SEL 9 341 #define GPNPBIOSCODE_SEL 10 342 #define GPNPBIOSDATA_SEL 11 343 #define GPNPBIOSSCRATCH_SEL 12 344 #define GPNPBIOSTRAMP_SEL 13 345 #define GUCODE32_SEL 14 346 #define GUDATA32_SEL 15 347 #define GUFS_SEL 16 /* 32-bit Per-thread %fs */ 348 #define GUGS_SEL 17 /* 32-bit Per-thread %gs */ 349 #define NGDT_MEM 18 350 351 #define GLDT_SEL 0 /* Default LDT descriptor */ 352 #define NGDT_SYS 1 353 354 #define GDT_ADDR_MEM(s,i) \ 355 ((struct mem_segment_descriptor *)((s) + ((i) << 3))) 356 #define GDT_ADDR_SYS(s,i) \ 357 ((struct sys_segment_descriptor *)((s) + (((i) << 4) + SYSSEL_START))) 358 359 /* 360 * Byte offsets in the Local Descriptor Table (LDT) 361 * Strange order because of syscall/sysret insns 362 */ 363 #define LUCODE32_SEL 48 /* 32 bit user code descriptor */ 364 #define LUDATA_SEL 56 /* User data descriptor */ 365 #define LUCODE_SEL 64 /* User code descriptor */ 366 #define LUDATA32_SEL 72 /* 32 bit user data descriptor (needed?)*/ 367 368 #define LDT_SIZE 80 369 370 #define LSYSRETBASE_SEL LUCODE32_SEL 371 372 /* 373 * Checks for valid user selectors. 374 */ 375 #define VALID_USER_DSEL32(s) \ 376 (((s) & 0xffff) == GSEL(GUDATA32_SEL, SEL_UPL) || \ 377 ((s) & 0xffff) == LSEL(LUDATA32_SEL, SEL_UPL)) 378 #define VALID_USER_CSEL32(s) \ 379 ((s) == GSEL(GUCODE32_SEL, SEL_UPL) || (s) == LSEL(LUCODE32_SEL, SEL_UPL)) 380 #define VALID_USER_FSEL32(s) \ 381 (((s) & 0xffff) == GSEL(GUFS_SEL, SEL_UPL)) 382 #define VALID_USER_GSEL32(s) \ 383 (((s) & 0xffff) == GSEL(GUGS_SEL, SEL_UPL)) 384 385 #define VALID_USER_CSEL(s) \ 386 ((s) == GSEL(GUCODE_SEL, SEL_UPL) || (s) == LSEL(LUCODE_SEL, SEL_UPL)) 387 #define VALID_USER_DSEL(s) \ 388 ((s) == GSEL(GUDATA_SEL, SEL_UPL) || (s) == LSEL(LUDATA_SEL, SEL_UPL)) 389 390 #else /* __x86_64__ */ 391 392 #include <i386/segments.h> 393 394 #endif /* __x86_64__ */ 395 396 #endif /* _AMD64_SEGMENTS_H_ */ 397