1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*
  27  * Copyright 2011 Joyent, Inc. All rights reserved.
  28  */
  29 
  30 /*
  31  * Copyright (c) 1992 Terrence R. Lambert.
  32  * Copyright (c) 1990 The Regents of the University of California.
  33  * All rights reserved.
  34  *
  35  * This code is derived from software contributed to Berkeley by
  36  * William Jolitz.
  37  *
  38  * Redistribution and use in source and binary forms, with or without
  39  * modification, are permitted provided that the following conditions
  40  * are met:
  41  * 1. Redistributions of source code must retain the above copyright
  42  *    notice, this list of conditions and the following disclaimer.
  43  * 2. Redistributions in binary form must reproduce the above copyright
  44  *    notice, this list of conditions and the following disclaimer in the
  45  *    documentation and/or other materials provided with the distribution.
  46  * 3. All advertising materials mentioning features or use of this software
  47  *    must display the following acknowledgement:
  48  *      This product includes software developed by the University of
  49  *      California, Berkeley and its contributors.
  50  * 4. Neither the name of the University nor the names of its contributors
  51  *    may be used to endorse or promote products derived from this software
  52  *    without specific prior written permission.
  53  *
  54  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  55  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  56  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  57  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  58  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  59  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  60  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  61  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  62  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  63  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  64  * SUCH DAMAGE.
  65  *
  66  *      from: @(#)machdep.c     7.4 (Berkeley) 6/3/91
  67  */
  68 
  69 #include <sys/types.h>
  70 #include <sys/sysmacros.h>
  71 #include <sys/tss.h>
  72 #include <sys/segments.h>
  73 #include <sys/trap.h>
  74 #include <sys/cpuvar.h>
  75 #include <sys/bootconf.h>
  76 #include <sys/x86_archext.h>
  77 #include <sys/controlregs.h>
  78 #include <sys/archsystm.h>
  79 #include <sys/machsystm.h>
  80 #include <sys/kobj.h>
  81 #include <sys/cmn_err.h>
  82 #include <sys/reboot.h>
  83 #include <sys/kdi.h>
  84 #include <sys/mach_mmu.h>
  85 #include <sys/systm.h>
  86 
  87 #ifdef __xpv
  88 #include <sys/hypervisor.h>
  89 #include <vm/as.h>
  90 #endif
  91 
  92 #include <sys/promif.h>
  93 #include <sys/bootinfo.h>
  94 #include <vm/kboot_mmu.h>
  95 #include <vm/hat_pte.h>
  96 
  97 /*
  98  * cpu0 and default tables and structures.
  99  */
 100 user_desc_t     *gdt0;
 101 #if !defined(__xpv)
 102 desctbr_t       gdt0_default_r;
 103 #endif
 104 
 105 gate_desc_t     *idt0;          /* interrupt descriptor table */
 106 #if defined(__i386)
 107 desctbr_t       idt0_default_r;         /* describes idt0 in IDTR format */
 108 #endif
 109 
 110 tss_t           *ktss0;                 /* kernel task state structure */
 111 
 112 #if defined(__i386)
 113 tss_t           *dftss0;                /* #DF double-fault exception */
 114 #endif  /* __i386 */
 115 
 116 user_desc_t     zero_udesc;             /* base zero user desc native procs */
 117 user_desc_t     null_udesc;             /* null user descriptor */
 118 system_desc_t   null_sdesc;             /* null system descriptor */
 119 
 120 #if defined(__amd64)
 121 user_desc_t     zero_u32desc;           /* 32-bit compatibility procs */
 122 #endif  /* __amd64 */
 123 
 124 #if defined(__amd64)
 125 user_desc_t     ucs_on;
 126 user_desc_t     ucs_off;
 127 user_desc_t     ucs32_on;
 128 user_desc_t     ucs32_off;
 129 #endif  /* __amd64 */
 130 
 131 #pragma align   16(dblfault_stack0)
 132 char            dblfault_stack0[DEFAULTSTKSZ];
 133 
 134 extern void     fast_null(void);
 135 extern hrtime_t get_hrtime(void);
 136 extern hrtime_t gethrvtime(void);
 137 extern hrtime_t get_hrestime(void);
 138 extern uint64_t getlgrp(void);
 139 
 140 void (*(fasttable[]))(void) = {
 141         fast_null,                      /* T_FNULL routine */
 142         fast_null,                      /* T_FGETFP routine (initially null) */
 143         fast_null,                      /* T_FSETFP routine (initially null) */
 144         (void (*)())get_hrtime,         /* T_GETHRTIME */
 145         (void (*)())gethrvtime,         /* T_GETHRVTIME */
 146         (void (*)())get_hrestime,       /* T_GETHRESTIME */
 147         (void (*)())getlgrp             /* T_GETLGRP */
 148 };
 149 
 150 /*
 151  * Structure containing pre-computed descriptors to allow us to temporarily
 152  * interpose on a standard handler.
 153  */
 154 struct interposing_handler {
 155         int ih_inum;
 156         gate_desc_t ih_interp_desc;
 157         gate_desc_t ih_default_desc;
 158 };
 159 
 160 /*
 161  * The brand infrastructure interposes on two handlers, and we use one as a
 162  * NULL signpost.
 163  */
 164 static struct interposing_handler brand_tbl[2];
 165 
 166 /*
 167  * software prototypes for default local descriptor table
 168  */
 169 
 170 /*
 171  * Routines for loading segment descriptors in format the hardware
 172  * can understand.
 173  */
 174 
 175 #if defined(__amd64)
 176 
 177 /*
 178  * In long mode we have the new L or long mode attribute bit
 179  * for code segments. Only the conforming bit in type is used along
 180  * with descriptor priority and present bits. Default operand size must
 181  * be zero when in long mode. In 32-bit compatibility mode all fields
 182  * are treated as in legacy mode. For data segments while in long mode
 183  * only the present bit is loaded.
 184  */
 185 void
 186 set_usegd(user_desc_t *dp, uint_t lmode, void *base, size_t size,
 187     uint_t type, uint_t dpl, uint_t gran, uint_t defopsz)
 188 {
 189         ASSERT(lmode == SDP_SHORT || lmode == SDP_LONG);
 190 
 191         /*
 192          * 64-bit long mode.
 193          */
 194         if (lmode == SDP_LONG)
 195                 dp->usd_def32 = 0;           /* 32-bit operands only */
 196         else
 197                 /*
 198                  * 32-bit compatibility mode.
 199                  */
 200                 dp->usd_def32 = defopsz;     /* 0 = 16, 1 = 32-bit ops */
 201 
 202         dp->usd_long = lmode;        /* 64-bit mode */
 203         dp->usd_type = type;
 204         dp->usd_dpl = dpl;
 205         dp->usd_p = 1;
 206         dp->usd_gran = gran;         /* 0 = bytes, 1 = pages */
 207 
 208         dp->usd_lobase = (uintptr_t)base;
 209         dp->usd_midbase = (uintptr_t)base >> 16;
 210         dp->usd_hibase = (uintptr_t)base >> (16 + 8);
 211         dp->usd_lolimit = size;
 212         dp->usd_hilimit = (uintptr_t)size >> 16;
 213 }
 214 
 215 #elif defined(__i386)
 216 
 217 /*
 218  * Install user segment descriptor for code and data.
 219  */
 220 void
 221 set_usegd(user_desc_t *dp, void *base, size_t size, uint_t type,
 222     uint_t dpl, uint_t gran, uint_t defopsz)
 223 {
 224         dp->usd_lolimit = size;
 225         dp->usd_hilimit = (uintptr_t)size >> 16;
 226 
 227         dp->usd_lobase = (uintptr_t)base;
 228         dp->usd_midbase = (uintptr_t)base >> 16;
 229         dp->usd_hibase = (uintptr_t)base >> (16 + 8);
 230 
 231         dp->usd_type = type;
 232         dp->usd_dpl = dpl;
 233         dp->usd_p = 1;
 234         dp->usd_def32 = defopsz;     /* 0 = 16, 1 = 32 bit operands */
 235         dp->usd_gran = gran;         /* 0 = bytes, 1 = pages */
 236 }
 237 
 238 #endif  /* __i386 */
 239 
 240 /*
 241  * Install system segment descriptor for LDT and TSS segments.
 242  */
 243 
 244 #if defined(__amd64)
 245 
 246 void
 247 set_syssegd(system_desc_t *dp, void *base, size_t size, uint_t type,
 248     uint_t dpl)
 249 {
 250         dp->ssd_lolimit = size;
 251         dp->ssd_hilimit = (uintptr_t)size >> 16;
 252 
 253         dp->ssd_lobase = (uintptr_t)base;
 254         dp->ssd_midbase = (uintptr_t)base >> 16;
 255         dp->ssd_hibase = (uintptr_t)base >> (16 + 8);
 256         dp->ssd_hi64base = (uintptr_t)base >> (16 + 8 + 8);
 257 
 258         dp->ssd_type = type;
 259         dp->ssd_zero1 = 0;   /* must be zero */
 260         dp->ssd_zero2 = 0;
 261         dp->ssd_dpl = dpl;
 262         dp->ssd_p = 1;
 263         dp->ssd_gran = 0;    /* force byte units */
 264 }
 265 
 266 void *
 267 get_ssd_base(system_desc_t *dp)
 268 {
 269         uintptr_t       base;
 270 
 271         base = (uintptr_t)dp->ssd_lobase |
 272             (uintptr_t)dp->ssd_midbase << 16 |
 273             (uintptr_t)dp->ssd_hibase << (16 + 8) |
 274             (uintptr_t)dp->ssd_hi64base << (16 + 8 + 8);
 275         return ((void *)base);
 276 }
 277 
 278 #elif defined(__i386)
 279 
 280 void
 281 set_syssegd(system_desc_t *dp, void *base, size_t size, uint_t type,
 282     uint_t dpl)
 283 {
 284         dp->ssd_lolimit = size;
 285         dp->ssd_hilimit = (uintptr_t)size >> 16;
 286 
 287         dp->ssd_lobase = (uintptr_t)base;
 288         dp->ssd_midbase = (uintptr_t)base >> 16;
 289         dp->ssd_hibase = (uintptr_t)base >> (16 + 8);
 290 
 291         dp->ssd_type = type;
 292         dp->ssd_zero = 0;    /* must be zero */
 293         dp->ssd_dpl = dpl;
 294         dp->ssd_p = 1;
 295         dp->ssd_gran = 0;    /* force byte units */
 296 }
 297 
 298 void *
 299 get_ssd_base(system_desc_t *dp)
 300 {
 301         uintptr_t       base;
 302 
 303         base = (uintptr_t)dp->ssd_lobase |
 304             (uintptr_t)dp->ssd_midbase << 16 |
 305             (uintptr_t)dp->ssd_hibase << (16 + 8);
 306         return ((void *)base);
 307 }
 308 
 309 #endif  /* __i386 */
 310 
 311 /*
 312  * Install gate segment descriptor for interrupt, trap, call and task gates.
 313  */
 314 
 315 #if defined(__amd64)
 316 
 317 /*ARGSUSED*/
 318 void
 319 set_gatesegd(gate_desc_t *dp, void (*func)(void), selector_t sel,
 320     uint_t type, uint_t dpl, uint_t vector)
 321 {
 322         dp->sgd_looffset = (uintptr_t)func;
 323         dp->sgd_hioffset = (uintptr_t)func >> 16;
 324         dp->sgd_hi64offset = (uintptr_t)func >> (16 + 16);
 325 
 326         dp->sgd_selector =  (uint16_t)sel;
 327 
 328         /*
 329          * For 64 bit native we use the IST stack mechanism
 330          * for double faults. All other traps use the CPL = 0
 331          * (tss_rsp0) stack.
 332          */
 333 #if !defined(__xpv)
 334         if (vector == T_DBLFLT)
 335                 dp->sgd_ist = 1;
 336         else
 337 #endif
 338                 dp->sgd_ist = 0;
 339 
 340         dp->sgd_type = type;
 341         dp->sgd_dpl = dpl;
 342         dp->sgd_p = 1;
 343 }
 344 
 345 #elif defined(__i386)
 346 
 347 /*ARGSUSED*/
 348 void
 349 set_gatesegd(gate_desc_t *dp, void (*func)(void), selector_t sel,
 350     uint_t type, uint_t dpl, uint_t unused)
 351 {
 352         dp->sgd_looffset = (uintptr_t)func;
 353         dp->sgd_hioffset = (uintptr_t)func >> 16;
 354 
 355         dp->sgd_selector =  (uint16_t)sel;
 356         dp->sgd_stkcpy = 0;  /* always zero bytes */
 357         dp->sgd_type = type;
 358         dp->sgd_dpl = dpl;
 359         dp->sgd_p = 1;
 360 }
 361 
 362 #endif  /* __i386 */
 363 
 364 /*
 365  * Updates a single user descriptor in the the GDT of the current cpu.
 366  * Caller is responsible for preventing cpu migration.
 367  */
 368 
 369 void
 370 gdt_update_usegd(uint_t sidx, user_desc_t *udp)
 371 {
 372 #if defined(__xpv)
 373 
 374         uint64_t dpa = CPU->cpu_m.mcpu_gdtpa + sizeof (*udp) * sidx;
 375 
 376         if (HYPERVISOR_update_descriptor(pa_to_ma(dpa), *(uint64_t *)udp))
 377                 panic("gdt_update_usegd: HYPERVISOR_update_descriptor");
 378 
 379 #else   /* __xpv */
 380 
 381         CPU->cpu_gdt[sidx] = *udp;
 382 
 383 #endif  /* __xpv */
 384 }
 385 
 386 /*
 387  * Writes single descriptor pointed to by udp into a processes
 388  * LDT entry pointed to by ldp.
 389  */
 390 int
 391 ldt_update_segd(user_desc_t *ldp, user_desc_t *udp)
 392 {
 393 #if defined(__xpv)
 394 
 395         uint64_t dpa;
 396 
 397         dpa = mmu_ptob(hat_getpfnum(kas.a_hat, (caddr_t)ldp)) |
 398             ((uintptr_t)ldp & PAGEOFFSET);
 399 
 400         /*
 401          * The hypervisor is a little more restrictive about what it
 402          * supports in the LDT.
 403          */
 404         if (HYPERVISOR_update_descriptor(pa_to_ma(dpa), *(uint64_t *)udp) != 0)
 405                 return (EINVAL);
 406 
 407 #else   /* __xpv */
 408 
 409         *ldp = *udp;
 410 
 411 #endif  /* __xpv */
 412         return (0);
 413 }
 414 
 415 #if defined(__xpv)
 416 
 417 /*
 418  * Converts hw format gate descriptor into pseudo-IDT format for the hypervisor.
 419  * Returns true if a valid entry was written.
 420  */
 421 int
 422 xen_idt_to_trap_info(uint_t vec, gate_desc_t *sgd, void *ti_arg)
 423 {
 424         trap_info_t *ti = ti_arg;       /* XXPV Aargh - segments.h comment */
 425 
 426         /*
 427          * skip holes in the IDT
 428          */
 429         if (GATESEG_GETOFFSET(sgd) == 0)
 430                 return (0);
 431 
 432         ASSERT(sgd->sgd_type == SDT_SYSIGT);
 433         ti->vector = vec;
 434         TI_SET_DPL(ti, sgd->sgd_dpl);
 435 
 436         /*
 437          * Is this an interrupt gate?
 438          */
 439         if (sgd->sgd_type == SDT_SYSIGT) {
 440                 /* LINTED */
 441                 TI_SET_IF(ti, 1);
 442         }
 443         ti->cs = sgd->sgd_selector;
 444 #if defined(__amd64)
 445         ti->cs |= SEL_KPL;   /* force into ring 3. see KCS_SEL  */
 446 #endif
 447         ti->address = GATESEG_GETOFFSET(sgd);
 448         return (1);
 449 }
 450 
 451 /*
 452  * Convert a single hw format gate descriptor and write it into our virtual IDT.
 453  */
 454 void
 455 xen_idt_write(gate_desc_t *sgd, uint_t vec)
 456 {
 457         trap_info_t trapinfo[2];
 458 
 459         bzero(trapinfo, sizeof (trapinfo));
 460         if (xen_idt_to_trap_info(vec, sgd, &trapinfo[0]) == 0)
 461                 return;
 462         if (xen_set_trap_table(trapinfo) != 0)
 463                 panic("xen_idt_write: xen_set_trap_table() failed");
 464 }
 465 
 466 #endif  /* __xpv */
 467 
 468 #if defined(__amd64)
 469 
 470 /*
 471  * Build kernel GDT.
 472  */
 473 
 474 static void
 475 init_gdt_common(user_desc_t *gdt)
 476 {
 477         int i;
 478 
 479         /*
 480          * 64-bit kernel code segment.
 481          */
 482         set_usegd(&gdt[GDT_KCODE], SDP_LONG, NULL, 0, SDT_MEMERA, SEL_KPL,
 483             SDP_PAGES, SDP_OP32);
 484 
 485         /*
 486          * 64-bit kernel data segment. The limit attribute is ignored in 64-bit
 487          * mode, but we set it here to 0xFFFF so that we can use the SYSRET
 488          * instruction to return from system calls back to 32-bit applications.
 489          * SYSRET doesn't update the base, limit, or attributes of %ss or %ds
 490          * descriptors. We therefore must ensure that the kernel uses something,
 491          * though it will be ignored by hardware, that is compatible with 32-bit
 492          * apps. For the same reason we must set the default op size of this
 493          * descriptor to 32-bit operands.
 494          */
 495         set_usegd(&gdt[GDT_KDATA], SDP_LONG, NULL, -1, SDT_MEMRWA,
 496             SEL_KPL, SDP_PAGES, SDP_OP32);
 497         gdt[GDT_KDATA].usd_def32 = 1;
 498 
 499         /*
 500          * 64-bit user code segment.
 501          */
 502         set_usegd(&gdt[GDT_UCODE], SDP_LONG, NULL, 0, SDT_MEMERA, SEL_UPL,
 503             SDP_PAGES, SDP_OP32);
 504 
 505         /*
 506          * 32-bit user code segment.
 507          */
 508         set_usegd(&gdt[GDT_U32CODE], SDP_SHORT, NULL, -1, SDT_MEMERA,
 509             SEL_UPL, SDP_PAGES, SDP_OP32);
 510 
 511         /*
 512          * See gdt_ucode32() and gdt_ucode_native().
 513          */
 514         ucs_on = ucs_off = gdt[GDT_UCODE];
 515         ucs_off.usd_p = 0;      /* forces #np fault */
 516 
 517         ucs32_on = ucs32_off = gdt[GDT_U32CODE];
 518         ucs32_off.usd_p = 0;    /* forces #np fault */
 519 
 520         /*
 521          * 32 and 64 bit data segments can actually share the same descriptor.
 522          * In long mode only the present bit is checked but all other fields
 523          * are loaded. But in compatibility mode all fields are interpreted
 524          * as in legacy mode so they must be set correctly for a 32-bit data
 525          * segment.
 526          */
 527         set_usegd(&gdt[GDT_UDATA], SDP_SHORT, NULL, -1, SDT_MEMRWA, SEL_UPL,
 528             SDP_PAGES, SDP_OP32);
 529 
 530 #if !defined(__xpv)
 531 
 532         /*
 533          * The 64-bit kernel has no default LDT. By default, the LDT descriptor
 534          * in the GDT is 0.
 535          */
 536 
 537         /*
 538          * Kernel TSS
 539          */
 540         set_syssegd((system_desc_t *)&gdt[GDT_KTSS], ktss0,
 541             sizeof (*ktss0) - 1, SDT_SYSTSS, SEL_KPL);
 542 
 543 #endif  /* !__xpv */
 544 
 545         /*
 546          * Initialize fs and gs descriptors for 32 bit processes.
 547          * Only attributes and limits are initialized, the effective
 548          * base address is programmed via fsbase/gsbase.
 549          */
 550         set_usegd(&gdt[GDT_LWPFS], SDP_SHORT, NULL, -1, SDT_MEMRWA,
 551             SEL_UPL, SDP_PAGES, SDP_OP32);
 552         set_usegd(&gdt[GDT_LWPGS], SDP_SHORT, NULL, -1, SDT_MEMRWA,
 553             SEL_UPL, SDP_PAGES, SDP_OP32);
 554 
 555         /*
 556          * Initialize the descriptors set aside for brand usage.
 557          * Only attributes and limits are initialized.
 558          */
 559         for (i = GDT_BRANDMIN; i <= GDT_BRANDMAX; i++)
 560                 set_usegd(&gdt0[i], SDP_SHORT, NULL, -1, SDT_MEMRWA,
 561                     SEL_UPL, SDP_PAGES, SDP_OP32);
 562 
 563         /*
 564          * Initialize convenient zero base user descriptors for clearing
 565          * lwp private %fs and %gs descriptors in GDT. See setregs() for
 566          * an example.
 567          */
 568         set_usegd(&zero_udesc, SDP_LONG, 0, 0, SDT_MEMRWA, SEL_UPL,
 569             SDP_BYTES, SDP_OP32);
 570         set_usegd(&zero_u32desc, SDP_SHORT, 0, -1, SDT_MEMRWA, SEL_UPL,
 571             SDP_PAGES, SDP_OP32);
 572 }
 573 
 574 #if defined(__xpv)
 575 
 576 static user_desc_t *
 577 init_gdt(void)
 578 {
 579         uint64_t gdtpa;
 580         ulong_t ma[1];          /* XXPV should be a memory_t */
 581         ulong_t addr;
 582 
 583 #if !defined(__lint)
 584         /*
 585          * Our gdt is never larger than a single page.
 586          */
 587         ASSERT((sizeof (*gdt0) * NGDT) <= PAGESIZE);
 588 #endif
 589         gdt0 = (user_desc_t *)BOP_ALLOC(bootops, (caddr_t)GDT_VA,
 590             PAGESIZE, PAGESIZE);
 591         bzero(gdt0, PAGESIZE);
 592 
 593         init_gdt_common(gdt0);
 594 
 595         /*
 596          * XXX Since we never invoke kmdb until after the kernel takes
 597          * over the descriptor tables why not have it use the kernel's
 598          * selectors?
 599          */
 600         if (boothowto & RB_DEBUG) {
 601                 set_usegd(&gdt0[GDT_B32DATA], SDP_LONG, NULL, -1, SDT_MEMRWA,
 602                     SEL_KPL, SDP_PAGES, SDP_OP32);
 603                 set_usegd(&gdt0[GDT_B64CODE], SDP_LONG, NULL, -1, SDT_MEMERA,
 604                     SEL_KPL, SDP_PAGES, SDP_OP32);
 605         }
 606 
 607         /*
 608          * Clear write permission for page containing the gdt and install it.
 609          */
 610         gdtpa = pfn_to_pa(va_to_pfn(gdt0));
 611         ma[0] = (ulong_t)(pa_to_ma(gdtpa) >> PAGESHIFT);
 612         kbm_read_only((uintptr_t)gdt0, gdtpa);
 613         xen_set_gdt(ma, NGDT);
 614 
 615         /*
 616          * Reload the segment registers to use the new GDT.
 617          * On 64-bit, fixup KCS_SEL to be in ring 3.
 618          * See KCS_SEL in segments.h.
 619          */
 620         load_segment_registers((KCS_SEL | SEL_KPL), KFS_SEL, KGS_SEL, KDS_SEL);
 621 
 622         /*
 623          *  setup %gs for kernel
 624          */
 625         xen_set_segment_base(SEGBASE_GS_KERNEL, (ulong_t)&cpus[0]);
 626 
 627         /*
 628          * XX64 We should never dereference off "other gsbase" or
 629          * "fsbase".  So, we should arrange to point FSBASE and
 630          * KGSBASE somewhere truly awful e.g. point it at the last
 631          * valid address below the hole so that any attempts to index
 632          * off them cause an exception.
 633          *
 634          * For now, point it at 8G -- at least it should be unmapped
 635          * until some 64-bit processes run.
 636          */
 637         addr = 0x200000000ul;
 638         xen_set_segment_base(SEGBASE_FS, addr);
 639         xen_set_segment_base(SEGBASE_GS_USER, addr);
 640         xen_set_segment_base(SEGBASE_GS_USER_SEL, 0);
 641 
 642         return (gdt0);
 643 }
 644 
 645 #else   /* __xpv */
 646 
 647 static user_desc_t *
 648 init_gdt(void)
 649 {
 650         desctbr_t       r_bgdt, r_gdt;
 651         user_desc_t     *bgdt;
 652 
 653 #if !defined(__lint)
 654         /*
 655          * Our gdt is never larger than a single page.
 656          */
 657         ASSERT((sizeof (*gdt0) * NGDT) <= PAGESIZE);
 658 #endif
 659         gdt0 = (user_desc_t *)BOP_ALLOC(bootops, (caddr_t)GDT_VA,
 660             PAGESIZE, PAGESIZE);
 661         bzero(gdt0, PAGESIZE);
 662 
 663         init_gdt_common(gdt0);
 664 
 665         /*
 666          * Copy in from boot's gdt to our gdt.
 667          * Entry 0 is the null descriptor by definition.
 668          */
 669         rd_gdtr(&r_bgdt);
 670         bgdt = (user_desc_t *)r_bgdt.dtr_base;
 671         if (bgdt == NULL)
 672                 panic("null boot gdt");
 673 
 674         gdt0[GDT_B32DATA] = bgdt[GDT_B32DATA];
 675         gdt0[GDT_B32CODE] = bgdt[GDT_B32CODE];
 676         gdt0[GDT_B16CODE] = bgdt[GDT_B16CODE];
 677         gdt0[GDT_B16DATA] = bgdt[GDT_B16DATA];
 678         gdt0[GDT_B64CODE] = bgdt[GDT_B64CODE];
 679 
 680         /*
 681          * Install our new GDT
 682          */
 683         r_gdt.dtr_limit = (sizeof (*gdt0) * NGDT) - 1;
 684         r_gdt.dtr_base = (uintptr_t)gdt0;
 685         wr_gdtr(&r_gdt);
 686 
 687         /*
 688          * Reload the segment registers to use the new GDT
 689          */
 690         load_segment_registers(KCS_SEL, KFS_SEL, KGS_SEL, KDS_SEL);
 691 
 692         /*
 693          *  setup %gs for kernel
 694          */
 695         wrmsr(MSR_AMD_GSBASE, (uint64_t)&cpus[0]);
 696 
 697         /*
 698          * XX64 We should never dereference off "other gsbase" or
 699          * "fsbase".  So, we should arrange to point FSBASE and
 700          * KGSBASE somewhere truly awful e.g. point it at the last
 701          * valid address below the hole so that any attempts to index
 702          * off them cause an exception.
 703          *
 704          * For now, point it at 8G -- at least it should be unmapped
 705          * until some 64-bit processes run.
 706          */
 707         wrmsr(MSR_AMD_FSBASE, 0x200000000ul);
 708         wrmsr(MSR_AMD_KGSBASE, 0x200000000ul);
 709         return (gdt0);
 710 }
 711 
 712 #endif  /* __xpv */
 713 
 714 #elif defined(__i386)
 715 
 716 static void
 717 init_gdt_common(user_desc_t *gdt)
 718 {
 719         int i;
 720 
 721         /*
 722          * Text and data for both kernel and user span entire 32 bit
 723          * address space.
 724          */
 725 
 726         /*
 727          * kernel code segment.
 728          */
 729         set_usegd(&gdt[GDT_KCODE], NULL, -1, SDT_MEMERA, SEL_KPL, SDP_PAGES,
 730             SDP_OP32);
 731 
 732         /*
 733          * kernel data segment.
 734          */
 735         set_usegd(&gdt[GDT_KDATA], NULL, -1, SDT_MEMRWA, SEL_KPL, SDP_PAGES,
 736             SDP_OP32);
 737 
 738         /*
 739          * user code segment.
 740          */
 741         set_usegd(&gdt[GDT_UCODE], NULL, -1, SDT_MEMERA, SEL_UPL, SDP_PAGES,
 742             SDP_OP32);
 743 
 744         /*
 745          * user data segment.
 746          */
 747         set_usegd(&gdt[GDT_UDATA], NULL, -1, SDT_MEMRWA, SEL_UPL, SDP_PAGES,
 748             SDP_OP32);
 749 
 750 #if !defined(__xpv)
 751 
 752         /*
 753          * TSS for T_DBLFLT (double fault) handler
 754          */
 755         set_syssegd((system_desc_t *)&gdt[GDT_DBFLT], dftss0,
 756             sizeof (*dftss0) - 1, SDT_SYSTSS, SEL_KPL);
 757 
 758         /*
 759          * TSS for kernel
 760          */
 761         set_syssegd((system_desc_t *)&gdt[GDT_KTSS], ktss0,
 762             sizeof (*ktss0) - 1, SDT_SYSTSS, SEL_KPL);
 763 
 764 #endif  /* !__xpv */
 765 
 766         /*
 767          * %gs selector for kernel
 768          */
 769         set_usegd(&gdt[GDT_GS], &cpus[0], sizeof (struct cpu) -1, SDT_MEMRWA,
 770             SEL_KPL, SDP_BYTES, SDP_OP32);
 771 
 772         /*
 773          * Initialize lwp private descriptors.
 774          * Only attributes and limits are initialized, the effective
 775          * base address is programmed via fsbase/gsbase.
 776          */
 777         set_usegd(&gdt[GDT_LWPFS], NULL, (size_t)-1, SDT_MEMRWA, SEL_UPL,
 778             SDP_PAGES, SDP_OP32);
 779         set_usegd(&gdt[GDT_LWPGS], NULL, (size_t)-1, SDT_MEMRWA, SEL_UPL,
 780             SDP_PAGES, SDP_OP32);
 781 
 782         /*
 783          * Initialize the descriptors set aside for brand usage.
 784          * Only attributes and limits are initialized.
 785          */
 786         for (i = GDT_BRANDMIN; i <= GDT_BRANDMAX; i++)
 787                 set_usegd(&gdt0[i], NULL, (size_t)-1, SDT_MEMRWA, SEL_UPL,
 788                     SDP_PAGES, SDP_OP32);
 789         /*
 790          * Initialize convenient zero base user descriptor for clearing
 791          * lwp  private %fs and %gs descriptors in GDT. See setregs() for
 792          * an example.
 793          */
 794         set_usegd(&zero_udesc, NULL, -1, SDT_MEMRWA, SEL_UPL,
 795             SDP_BYTES, SDP_OP32);
 796 }
 797 
 798 #if defined(__xpv)
 799 
 800 static user_desc_t *
 801 init_gdt(void)
 802 {
 803         uint64_t gdtpa;
 804         ulong_t ma[1];          /* XXPV should be a memory_t */
 805 
 806 #if !defined(__lint)
 807         /*
 808          * Our gdt is never larger than a single page.
 809          */
 810         ASSERT((sizeof (*gdt0) * NGDT) <= PAGESIZE);
 811 #endif
 812         gdt0 = (user_desc_t *)BOP_ALLOC(bootops, (caddr_t)GDT_VA,
 813             PAGESIZE, PAGESIZE);
 814         bzero(gdt0, PAGESIZE);
 815 
 816         init_gdt_common(gdt0);
 817         gdtpa = pfn_to_pa(va_to_pfn(gdt0));
 818 
 819         /*
 820          * XXX Since we never invoke kmdb until after the kernel takes
 821          * over the descriptor tables why not have it use the kernel's
 822          * selectors?
 823          */
 824         if (boothowto & RB_DEBUG) {
 825                 set_usegd(&gdt0[GDT_B32DATA], NULL, -1, SDT_MEMRWA, SEL_KPL,
 826                     SDP_PAGES, SDP_OP32);
 827                 set_usegd(&gdt0[GDT_B32CODE], NULL, -1, SDT_MEMERA, SEL_KPL,
 828                     SDP_PAGES, SDP_OP32);
 829         }
 830 
 831         /*
 832          * Clear write permission for page containing the gdt and install it.
 833          */
 834         ma[0] = (ulong_t)(pa_to_ma(gdtpa) >> PAGESHIFT);
 835         kbm_read_only((uintptr_t)gdt0, gdtpa);
 836         xen_set_gdt(ma, NGDT);
 837 
 838         /*
 839          * Reload the segment registers to use the new GDT
 840          */
 841         load_segment_registers(
 842             KCS_SEL, KDS_SEL, KDS_SEL, KFS_SEL, KGS_SEL, KDS_SEL);
 843 
 844         return (gdt0);
 845 }
 846 
 847 #else   /* __xpv */
 848 
 849 static user_desc_t *
 850 init_gdt(void)
 851 {
 852         desctbr_t       r_bgdt, r_gdt;
 853         user_desc_t     *bgdt;
 854 
 855 #if !defined(__lint)
 856         /*
 857          * Our gdt is never larger than a single page.
 858          */
 859         ASSERT((sizeof (*gdt0) * NGDT) <= PAGESIZE);
 860 #endif
 861         /*
 862          * XXX this allocation belongs in our caller, not here.
 863          */
 864         gdt0 = (user_desc_t *)BOP_ALLOC(bootops, (caddr_t)GDT_VA,
 865             PAGESIZE, PAGESIZE);
 866         bzero(gdt0, PAGESIZE);
 867 
 868         init_gdt_common(gdt0);
 869 
 870         /*
 871          * Copy in from boot's gdt to our gdt entries.
 872          * Entry 0 is null descriptor by definition.
 873          */
 874         rd_gdtr(&r_bgdt);
 875         bgdt = (user_desc_t *)r_bgdt.dtr_base;
 876         if (bgdt == NULL)
 877                 panic("null boot gdt");
 878 
 879         gdt0[GDT_B32DATA] = bgdt[GDT_B32DATA];
 880         gdt0[GDT_B32CODE] = bgdt[GDT_B32CODE];
 881         gdt0[GDT_B16CODE] = bgdt[GDT_B16CODE];
 882         gdt0[GDT_B16DATA] = bgdt[GDT_B16DATA];
 883 
 884         /*
 885          * Install our new GDT
 886          */
 887         r_gdt.dtr_limit = (sizeof (*gdt0) * NGDT) - 1;
 888         r_gdt.dtr_base = (uintptr_t)gdt0;
 889         wr_gdtr(&r_gdt);
 890 
 891         /*
 892          * Reload the segment registers to use the new GDT
 893          */
 894         load_segment_registers(
 895             KCS_SEL, KDS_SEL, KDS_SEL, KFS_SEL, KGS_SEL, KDS_SEL);
 896 
 897         return (gdt0);
 898 }
 899 
 900 #endif  /* __xpv */
 901 #endif  /* __i386 */
 902 
 903 /*
 904  * Build kernel IDT.
 905  *
 906  * Note that for amd64 we pretty much require every gate to be an interrupt
 907  * gate which blocks interrupts atomically on entry; that's because of our
 908  * dependency on using 'swapgs' every time we come into the kernel to find
 909  * the cpu structure. If we get interrupted just before doing that, %cs could
 910  * be in kernel mode (so that the trap prolog doesn't do a swapgs), but
 911  * %gsbase is really still pointing at something in userland. Bad things will
 912  * ensue. We also use interrupt gates for i386 as well even though this is not
 913  * required for some traps.
 914  *
 915  * Perhaps they should have invented a trap gate that does an atomic swapgs?
 916  */
 917 static void
 918 init_idt_common(gate_desc_t *idt)
 919 {
 920         set_gatesegd(&idt[T_ZERODIV], &div0trap, KCS_SEL, SDT_SYSIGT, TRP_KPL,
 921             0);
 922         set_gatesegd(&idt[T_SGLSTP], &dbgtrap, KCS_SEL, SDT_SYSIGT, TRP_KPL,
 923             0);
 924         set_gatesegd(&idt[T_NMIFLT], &nmiint, KCS_SEL, SDT_SYSIGT, TRP_KPL,
 925             0);
 926         set_gatesegd(&idt[T_BPTFLT], &brktrap, KCS_SEL, SDT_SYSIGT, TRP_UPL,
 927             0);
 928         set_gatesegd(&idt[T_OVFLW], &ovflotrap, KCS_SEL, SDT_SYSIGT, TRP_UPL,
 929             0);
 930         set_gatesegd(&idt[T_BOUNDFLT], &boundstrap, KCS_SEL, SDT_SYSIGT,
 931             TRP_KPL, 0);
 932         set_gatesegd(&idt[T_ILLINST], &invoptrap, KCS_SEL, SDT_SYSIGT, TRP_KPL,
 933             0);
 934         set_gatesegd(&idt[T_NOEXTFLT], &ndptrap,  KCS_SEL, SDT_SYSIGT, TRP_KPL,
 935             0);
 936 
 937         /*
 938          * double fault handler.
 939          *
 940          * Note that on the hypervisor a guest does not receive #df faults.
 941          * Instead a failsafe event is injected into the guest if its selectors
 942          * and/or stack is in a broken state. See xen_failsafe_callback.
 943          */
 944 #if !defined(__xpv)
 945 #if defined(__amd64)
 946 
 947         set_gatesegd(&idt[T_DBLFLT], &syserrtrap, KCS_SEL, SDT_SYSIGT, TRP_KPL,
 948             T_DBLFLT);
 949 
 950 #elif defined(__i386)
 951 
 952         /*
 953          * task gate required.
 954          */
 955         set_gatesegd(&idt[T_DBLFLT], NULL, DFTSS_SEL, SDT_SYSTASKGT, TRP_KPL,
 956             0);
 957 
 958 #endif  /* __i386 */
 959 #endif  /* !__xpv */
 960 
 961         /*
 962          * T_EXTOVRFLT coprocessor-segment-overrun not supported.
 963          */
 964 
 965         set_gatesegd(&idt[T_TSSFLT], &invtsstrap, KCS_SEL, SDT_SYSIGT, TRP_KPL,
 966             0);
 967         set_gatesegd(&idt[T_SEGFLT], &segnptrap, KCS_SEL, SDT_SYSIGT, TRP_KPL,
 968             0);
 969         set_gatesegd(&idt[T_STKFLT], &stktrap, KCS_SEL, SDT_SYSIGT, TRP_KPL, 0);
 970         set_gatesegd(&idt[T_GPFLT], &gptrap, KCS_SEL, SDT_SYSIGT, TRP_KPL, 0);
 971         set_gatesegd(&idt[T_PGFLT], &pftrap, KCS_SEL, SDT_SYSIGT, TRP_KPL, 0);
 972         set_gatesegd(&idt[T_EXTERRFLT], &ndperr, KCS_SEL, SDT_SYSIGT, TRP_KPL,
 973             0);
 974         set_gatesegd(&idt[T_ALIGNMENT], &achktrap, KCS_SEL, SDT_SYSIGT,
 975             TRP_KPL, 0);
 976         set_gatesegd(&idt[T_MCE], &mcetrap, KCS_SEL, SDT_SYSIGT, TRP_KPL, 0);
 977         set_gatesegd(&idt[T_SIMDFPE], &xmtrap, KCS_SEL, SDT_SYSIGT, TRP_KPL, 0);
 978 
 979         /*
 980          * install fast trap handler at 210.
 981          */
 982         set_gatesegd(&idt[T_FASTTRAP], &fasttrap, KCS_SEL, SDT_SYSIGT, TRP_UPL,
 983             0);
 984 
 985         /*
 986          * System call handler.
 987          */
 988 #if defined(__amd64)
 989         set_gatesegd(&idt[T_SYSCALLINT], &sys_syscall_int, KCS_SEL, SDT_SYSIGT,
 990             TRP_UPL, 0);
 991 
 992 #elif defined(__i386)
 993         set_gatesegd(&idt[T_SYSCALLINT], &sys_call, KCS_SEL, SDT_SYSIGT,
 994             TRP_UPL, 0);
 995 #endif  /* __i386 */
 996 
 997         /*
 998          * Install the DTrace interrupt handler for the pid provider.
 999          */
1000         set_gatesegd(&idt[T_DTRACE_RET], &dtrace_ret, KCS_SEL,
1001             SDT_SYSIGT, TRP_UPL, 0);
1002 
1003         /*
1004          * Prepare interposing descriptor for the syscall handler
1005          * and cache copy of the default descriptor.
1006          */
1007         brand_tbl[0].ih_inum = T_SYSCALLINT;
1008         brand_tbl[0].ih_default_desc = idt0[T_SYSCALLINT];
1009 
1010 #if defined(__amd64)
1011         set_gatesegd(&(brand_tbl[0].ih_interp_desc), &brand_sys_syscall_int,
1012             KCS_SEL, SDT_SYSIGT, TRP_UPL, 0);
1013 #elif defined(__i386)
1014         set_gatesegd(&(brand_tbl[0].ih_interp_desc), &brand_sys_call,
1015             KCS_SEL, SDT_SYSIGT, TRP_UPL, 0);
1016 #endif  /* __i386 */
1017 
1018         brand_tbl[1].ih_inum = 0;
1019 }
1020 
1021 #if defined(__xpv)
1022 
1023 static void
1024 init_idt(gate_desc_t *idt)
1025 {
1026         init_idt_common(idt);
1027 }
1028 
1029 #else   /* __xpv */
1030 
1031 static void
1032 init_idt(gate_desc_t *idt)
1033 {
1034         char    ivctname[80];
1035         void    (*ivctptr)(void);
1036         int     i;
1037 
1038         /*
1039          * Initialize entire table with 'reserved' trap and then overwrite
1040          * specific entries. T_EXTOVRFLT (9) is unsupported and reserved
1041          * since it can only be generated on a 386 processor. 15 is also
1042          * unsupported and reserved.
1043          */
1044         for (i = 0; i < NIDT; i++)
1045                 set_gatesegd(&idt[i], &resvtrap, KCS_SEL, SDT_SYSIGT, TRP_KPL,
1046                     0);
1047 
1048         /*
1049          * 20-31 reserved
1050          */
1051         for (i = 20; i < 32; i++)
1052                 set_gatesegd(&idt[i], &invaltrap, KCS_SEL, SDT_SYSIGT, TRP_KPL,
1053                     0);
1054 
1055         /*
1056          * interrupts 32 - 255
1057          */
1058         for (i = 32; i < 256; i++) {
1059                 (void) snprintf(ivctname, sizeof (ivctname), "ivct%d", i);
1060                 ivctptr = (void (*)(void))kobj_getsymvalue(ivctname, 0);
1061                 if (ivctptr == NULL)
1062                         panic("kobj_getsymvalue(%s) failed", ivctname);
1063 
1064                 set_gatesegd(&idt[i], ivctptr, KCS_SEL, SDT_SYSIGT, TRP_KPL, 0);
1065         }
1066 
1067         /*
1068          * Now install the common ones. Note that it will overlay some
1069          * entries installed above like T_SYSCALLINT, T_FASTTRAP etc.
1070          */
1071         init_idt_common(idt);
1072 }
1073 
1074 #endif  /* __xpv */
1075 
1076 /*
1077  * The kernel does not deal with LDTs unless a user explicitly creates
1078  * one. Under normal circumstances, the LDTR contains 0. Any process attempting
1079  * to reference the LDT will therefore cause a #gp. System calls made via the
1080  * obsolete lcall mechanism are emulated by the #gp fault handler.
1081  */
1082 static void
1083 init_ldt(void)
1084 {
1085 #if defined(__xpv)
1086         xen_set_ldt(NULL, 0);
1087 #else
1088         wr_ldtr(0);
1089 #endif
1090 }
1091 
1092 #if !defined(__xpv)
1093 #if defined(__amd64)
1094 
1095 static void
1096 init_tss(void)
1097 {
1098         /*
1099          * tss_rsp0 is dynamically filled in by resume() on each context switch.
1100          * All exceptions but #DF will run on the thread stack.
1101          * Set up the double fault stack here.
1102          */
1103         ktss0->tss_ist1 =
1104             (uint64_t)&dblfault_stack0[sizeof (dblfault_stack0)];
1105 
1106         /*
1107          * Set I/O bit map offset equal to size of TSS segment limit
1108          * for no I/O permission map. This will force all user I/O
1109          * instructions to generate #gp fault.
1110          */
1111         ktss0->tss_bitmapbase = sizeof (*ktss0);
1112 
1113         /*
1114          * Point %tr to descriptor for ktss0 in gdt.
1115          */
1116         wr_tsr(KTSS_SEL);
1117 }
1118 
1119 #elif defined(__i386)
1120 
1121 static void
1122 init_tss(void)
1123 {
1124         /*
1125          * ktss0->tss_esp dynamically filled in by resume() on each
1126          * context switch.
1127          */
1128         ktss0->tss_ss0       = KDS_SEL;
1129         ktss0->tss_eip       = (uint32_t)_start;
1130         ktss0->tss_ds        = ktss0->tss_es = ktss0->tss_ss = KDS_SEL;
1131         ktss0->tss_cs        = KCS_SEL;
1132         ktss0->tss_fs        = KFS_SEL;
1133         ktss0->tss_gs        = KGS_SEL;
1134         ktss0->tss_ldt       = ULDT_SEL;
1135 
1136         /*
1137          * Initialize double fault tss.
1138          */
1139         dftss0->tss_esp0 = (uint32_t)&dblfault_stack0[sizeof (dblfault_stack0)];
1140         dftss0->tss_ss0      = KDS_SEL;
1141 
1142         /*
1143          * tss_cr3 will get initialized in hat_kern_setup() once our page
1144          * tables have been setup.
1145          */
1146         dftss0->tss_eip      = (uint32_t)syserrtrap;
1147         dftss0->tss_esp      = (uint32_t)&dblfault_stack0[sizeof (dblfault_stack0)];
1148         dftss0->tss_cs       = KCS_SEL;
1149         dftss0->tss_ds       = KDS_SEL;
1150         dftss0->tss_es       = KDS_SEL;
1151         dftss0->tss_ss       = KDS_SEL;
1152         dftss0->tss_fs       = KFS_SEL;
1153         dftss0->tss_gs       = KGS_SEL;
1154 
1155         /*
1156          * Set I/O bit map offset equal to size of TSS segment limit
1157          * for no I/O permission map. This will force all user I/O
1158          * instructions to generate #gp fault.
1159          */
1160         ktss0->tss_bitmapbase = sizeof (*ktss0);
1161 
1162         /*
1163          * Point %tr to descriptor for ktss0 in gdt.
1164          */
1165         wr_tsr(KTSS_SEL);
1166 }
1167 
1168 #endif  /* __i386 */
1169 #endif  /* !__xpv */
1170 
1171 #if defined(__xpv)
1172 
1173 void
1174 init_desctbls(void)
1175 {
1176         uint_t vec;
1177         user_desc_t *gdt;
1178 
1179         /*
1180          * Setup and install our GDT.
1181          */
1182         gdt = init_gdt();
1183 
1184         /*
1185          * Store static pa of gdt to speed up pa_to_ma() translations
1186          * on lwp context switches.
1187          */
1188         ASSERT(IS_P2ALIGNED((uintptr_t)gdt, PAGESIZE));
1189         CPU->cpu_gdt = gdt;
1190         CPU->cpu_m.mcpu_gdtpa = pfn_to_pa(va_to_pfn(gdt));
1191 
1192         /*
1193          * Setup and install our IDT.
1194          */
1195 #if !defined(__lint)
1196         ASSERT(NIDT * sizeof (*idt0) <= PAGESIZE);
1197 #endif
1198         idt0 = (gate_desc_t *)BOP_ALLOC(bootops, (caddr_t)IDT_VA,
1199             PAGESIZE, PAGESIZE);
1200         bzero(idt0, PAGESIZE);
1201         init_idt(idt0);
1202         for (vec = 0; vec < NIDT; vec++)
1203                 xen_idt_write(&idt0[vec], vec);
1204 
1205         CPU->cpu_idt = idt0;
1206 
1207         /*
1208          * set default kernel stack
1209          */
1210         xen_stack_switch(KDS_SEL,
1211             (ulong_t)&dblfault_stack0[sizeof (dblfault_stack0)]);
1212 
1213         xen_init_callbacks();
1214 
1215         init_ldt();
1216 }
1217 
1218 #else   /* __xpv */
1219 
1220 void
1221 init_desctbls(void)
1222 {
1223         user_desc_t *gdt;
1224         desctbr_t idtr;
1225 
1226         /*
1227          * Allocate IDT and TSS structures on unique pages for better
1228          * performance in virtual machines.
1229          */
1230 #if !defined(__lint)
1231         ASSERT(NIDT * sizeof (*idt0) <= PAGESIZE);
1232 #endif
1233         idt0 = (gate_desc_t *)BOP_ALLOC(bootops, (caddr_t)IDT_VA,
1234             PAGESIZE, PAGESIZE);
1235         bzero(idt0, PAGESIZE);
1236 #if !defined(__lint)
1237         ASSERT(sizeof (*ktss0) <= PAGESIZE);
1238 #endif
1239         ktss0 = (tss_t *)BOP_ALLOC(bootops, (caddr_t)KTSS_VA,
1240             PAGESIZE, PAGESIZE);
1241         bzero(ktss0, PAGESIZE);
1242 
1243 #if defined(__i386)
1244 #if !defined(__lint)
1245         ASSERT(sizeof (*dftss0) <= PAGESIZE);
1246 #endif
1247         dftss0 = (tss_t *)BOP_ALLOC(bootops, (caddr_t)DFTSS_VA,
1248             PAGESIZE, PAGESIZE);
1249         bzero(dftss0, PAGESIZE);
1250 #endif
1251 
1252         /*
1253          * Setup and install our GDT.
1254          */
1255         gdt = init_gdt();
1256         ASSERT(IS_P2ALIGNED((uintptr_t)gdt, PAGESIZE));
1257         CPU->cpu_gdt = gdt;
1258 
1259         /*
1260          * Setup and install our IDT.
1261          */
1262         init_idt(idt0);
1263 
1264         idtr.dtr_base = (uintptr_t)idt0;
1265         idtr.dtr_limit = (NIDT * sizeof (*idt0)) - 1;
1266         wr_idtr(&idtr);
1267         CPU->cpu_idt = idt0;
1268 
1269 #if defined(__i386)
1270         /*
1271          * We maintain a description of idt0 in convenient IDTR format
1272          * for #pf's on some older pentium processors. See pentium_pftrap().
1273          */
1274         idt0_default_r = idtr;
1275 #endif  /* __i386 */
1276 
1277         init_tss();
1278         CPU->cpu_tss = ktss0;
1279         init_ldt();
1280 }
1281 
1282 #endif  /* __xpv */
1283 
1284 /*
1285  * In the early kernel, we need to set up a simple GDT to run on.
1286  *
1287  * XXPV Can dboot use this too?  See dboot_gdt.s
1288  */
1289 void
1290 init_boot_gdt(user_desc_t *bgdt)
1291 {
1292 #if defined(__amd64)
1293         set_usegd(&bgdt[GDT_B32DATA], SDP_LONG, NULL, -1, SDT_MEMRWA, SEL_KPL,
1294             SDP_PAGES, SDP_OP32);
1295         set_usegd(&bgdt[GDT_B64CODE], SDP_LONG, NULL, -1, SDT_MEMERA, SEL_KPL,
1296             SDP_PAGES, SDP_OP32);
1297 #elif defined(__i386)
1298         set_usegd(&bgdt[GDT_B32DATA], NULL, -1, SDT_MEMRWA, SEL_KPL,
1299             SDP_PAGES, SDP_OP32);
1300         set_usegd(&bgdt[GDT_B32CODE], NULL, -1, SDT_MEMERA, SEL_KPL,
1301             SDP_PAGES, SDP_OP32);
1302 #endif  /* __i386 */
1303 }
1304 
1305 /*
1306  * Enable interpositioning on the system call path by rewriting the
1307  * sys{call|enter} MSRs and the syscall-related entries in the IDT to use
1308  * the branded entry points.
1309  */
1310 void
1311 brand_interpositioning_enable(void)
1312 {
1313         gate_desc_t     *idt = CPU->cpu_idt;
1314         int             i;
1315 
1316         ASSERT(curthread->t_preempt != 0 || getpil() >= DISP_LEVEL);
1317 
1318         for (i = 0; brand_tbl[i].ih_inum; i++) {
1319                 idt[brand_tbl[i].ih_inum] = brand_tbl[i].ih_interp_desc;
1320 #if defined(__xpv)
1321                 xen_idt_write(&idt[brand_tbl[i].ih_inum],
1322                     brand_tbl[i].ih_inum);
1323 #endif
1324         }
1325 
1326 #if defined(__amd64)
1327 #if defined(__xpv)
1328 
1329         /*
1330          * Currently the hypervisor only supports 64-bit syscalls via
1331          * syscall instruction. The 32-bit syscalls are handled by
1332          * interrupt gate above.
1333          */
1334         xen_set_callback(brand_sys_syscall, CALLBACKTYPE_syscall,
1335             CALLBACKF_mask_events);
1336 
1337 #else
1338 
1339         if (is_x86_feature(x86_featureset, X86FSET_ASYSC)) {
1340                 wrmsr(MSR_AMD_LSTAR, (uintptr_t)brand_sys_syscall);
1341                 wrmsr(MSR_AMD_CSTAR, (uintptr_t)brand_sys_syscall32);
1342         }
1343 
1344 #endif
1345 #endif  /* __amd64 */
1346 
1347         if (is_x86_feature(x86_featureset, X86FSET_SEP))
1348                 wrmsr(MSR_INTC_SEP_EIP, (uintptr_t)brand_sys_sysenter);
1349 }
1350 
1351 /*
1352  * Disable interpositioning on the system call path by rewriting the
1353  * sys{call|enter} MSRs and the syscall-related entries in the IDT to use
1354  * the standard entry points, which bypass the interpositioning hooks.
1355  */
1356 void
1357 brand_interpositioning_disable(void)
1358 {
1359         gate_desc_t     *idt = CPU->cpu_idt;
1360         int i;
1361 
1362         ASSERT(curthread->t_preempt != 0 || getpil() >= DISP_LEVEL);
1363 
1364         for (i = 0; brand_tbl[i].ih_inum; i++) {
1365                 idt[brand_tbl[i].ih_inum] = brand_tbl[i].ih_default_desc;
1366 #if defined(__xpv)
1367                 xen_idt_write(&idt[brand_tbl[i].ih_inum],
1368                     brand_tbl[i].ih_inum);
1369 #endif
1370         }
1371 
1372 #if defined(__amd64)
1373 #if defined(__xpv)
1374 
1375         /*
1376          * See comment above in brand_interpositioning_enable.
1377          */
1378         xen_set_callback(sys_syscall, CALLBACKTYPE_syscall,
1379             CALLBACKF_mask_events);
1380 
1381 #else
1382 
1383         if (is_x86_feature(x86_featureset, X86FSET_ASYSC)) {
1384                 wrmsr(MSR_AMD_LSTAR, (uintptr_t)sys_syscall);
1385                 wrmsr(MSR_AMD_CSTAR, (uintptr_t)sys_syscall32);
1386         }
1387 
1388 #endif
1389 #endif  /* __amd64 */
1390 
1391         if (is_x86_feature(x86_featureset, X86FSET_SEP))
1392                 wrmsr(MSR_INTC_SEP_EIP, (uintptr_t)sys_sysenter);
1393 }