Print this page
8956 Implement KPTI
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>

*** 21,31 **** /* * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. * Copyright 2017 Nexenta Systems, Inc. ! * Copyright 2015 Joyent, Inc. * Copyright (c) 2015 by Delphix. All rights reserved. */ /* * Copyright (c) 2010, Intel Corporation. * All rights reserved. --- 21,31 ---- /* * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. * Copyright 2017 Nexenta Systems, Inc. ! * Copyright (c) 2018 Joyent, Inc. * Copyright (c) 2015 by Delphix. All rights reserved. */ /* * Copyright (c) 2010, Intel Corporation. * All rights reserved.
*** 444,455 **** * +-----------------------+ * | Kernel Data | * 0xFFFFFFFF.FBC00000 |-----------------------| * | Kernel Text | * 0xFFFFFFFF.FB800000 |-----------------------|- KERNEL_TEXT - * |--- GDT ---|- GDT page (GDT_VA) * |--- debug info ---|- debug info (DEBUG_INFO_VA) * | | * | Core heap | (used for loadable modules) * 0xFFFFFFFF.C0000000 |-----------------------|- core_base / ekernelheap * | Kernel | * | heap | --- 444,457 ---- * +-----------------------+ * | Kernel Data | * 0xFFFFFFFF.FBC00000 |-----------------------| * | Kernel Text | * 0xFFFFFFFF.FB800000 |-----------------------|- KERNEL_TEXT * |--- debug info ---|- debug info (DEBUG_INFO_VA) + * |--- GDT ---|- GDT page (GDT_VA) + * |--- IDT ---|- IDT page (IDT_VA) + * |--- LDT ---|- LDT pages (LDT_VA) * | | * | Core heap | (used for loadable modules) * 0xFFFFFFFF.C0000000 |-----------------------|- core_base / ekernelheap * | Kernel | * | heap |
*** 949,958 **** --- 951,971 ---- if (segkpm_create(segkpm, (caddr_t)&b) != 0) panic("segkpm_create segkpm"); rw_exit(&kas.a_lock); + + kpm_enable = 1; + + /* + * As the KPM was disabled while setting up the system, go back and fix + * CPU zero's access to its user page table. This is a bit gross, but + * we have a chicken and egg problem otherwise. + */ + ASSERT(CPU->cpu_hat_info->hci_user_l3ptes == NULL); + CPU->cpu_hat_info->hci_user_l3ptes = + (x86pte_t *)hat_kpm_mapin_pfn(CPU->cpu_hat_info->hci_user_l3pfn); } /* * The debug info page provides enough information to allow external * inspectors (e.g. when running under a hypervisor) to bootstrap
*** 1412,1421 **** --- 1425,1437 ---- */ static void startup_kmem(void) { extern void page_set_colorequiv_arr(void); + #if !defined(__xpv) + extern uint64_t kpti_kbase; + #endif PRM_POINT("startup_kmem() starting..."); #if defined(__amd64) if (eprom_kernelbase && eprom_kernelbase != KERNELBASE)
*** 1474,1490 **** --- 1490,1512 ---- *(uintptr_t *)&_kernelbase = kernelbase; *(uintptr_t *)&_userlimit = kernelbase; #if defined(__amd64) *(uintptr_t *)&_userlimit -= KERNELBASE - USERLIMIT; + #if !defined(__xpv) + kpti_kbase = kernelbase; + #endif #else *(uintptr_t *)&_userlimit32 = _userlimit; #endif PRM_DEBUG(_kernelbase); PRM_DEBUG(_userlimit); PRM_DEBUG(_userlimit32); + /* We have to re-do this now that we've modified _userlimit. */ + mmu_calc_user_slots(); + layout_kernel_va(); #if defined(__i386) /* * If segmap is too large we can push the bottom of the kernel heap
*** 2119,2154 **** * it, tell the debugger. */ if (boothowto & RB_DEBUG) kdi_dvec_memavail(); - /* - * The following code installs a special page fault handler (#pf) - * to work around a pentium bug. - */ - #if !defined(__amd64) && !defined(__xpv) - if (x86_type == X86_TYPE_P5) { - desctbr_t idtr; - gate_desc_t *newidt; - - if ((newidt = kmem_zalloc(MMU_PAGESIZE, KM_NOSLEEP)) == NULL) - panic("failed to install pentium_pftrap"); - - bcopy(idt0, newidt, NIDT * sizeof (*idt0)); - set_gatesegd(&newidt[T_PGFLT], &pentium_pftrap, - KCS_SEL, SDT_SYSIGT, TRP_KPL, 0); - - (void) as_setprot(&kas, (caddr_t)newidt, MMU_PAGESIZE, - PROT_READ | PROT_EXEC); - - CPU->cpu_idt = newidt; - idtr.dtr_base = (uintptr_t)CPU->cpu_idt; - idtr.dtr_limit = (NIDT * sizeof (*idt0)) - 1; - wr_idtr(&idtr); - } - #endif /* !__amd64 */ - #if !defined(__xpv) /* * Map page pfn=0 for drivers, such as kd, that need to pick up * parameters left there by controllers/BIOS. */ --- 2141,2150 ----
*** 2207,2220 **** /* * kpm segment */ segmap_kpm = 0; ! if (kpm_desired) { kpm_init(); - kpm_enable = 1; - } /* * Now create segmap segment. */ rw_enter(&kas.a_lock, RW_WRITER); --- 2203,2214 ---- /* * kpm segment */ segmap_kpm = 0; ! if (kpm_desired) kpm_init(); /* * Now create segmap segment. */ rw_enter(&kas.a_lock, RW_WRITER);
*** 2333,2348 **** #if defined(__xpv) ec_init_debug_irq(); xs_domu_init(); #endif ! #if defined(__amd64) && !defined(__xpv) /* * Intel IOMMU has been setup/initialized in ddi_impl.c * Start it up now. */ immu_startup(); #endif PRM_POINT("Enabling interrupts"); (*picinitf)(); sti(); --- 2327,2348 ---- #if defined(__xpv) ec_init_debug_irq(); xs_domu_init(); #endif ! #if !defined(__xpv) /* * Intel IOMMU has been setup/initialized in ddi_impl.c * Start it up now. */ immu_startup(); + + /* + * Now that we're no longer going to drop into real mode for a BIOS call + * via bootops, we can enable PCID (which requires CR0.PG). + */ + enable_pcid(); #endif PRM_POINT("Enabling interrupts"); (*picinitf)(); sti();