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

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/i86pc/vm/kboot_mmu.c
          +++ new/usr/src/uts/i86pc/vm/kboot_mmu.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
       25 + *
       26 + * Copyright 2018 Joyent, Inc.
  25   27   */
  26   28  
  27   29  #include <sys/types.h>
  28   30  #include <sys/systm.h>
  29   31  #include <sys/archsystm.h>
  30   32  #include <sys/debug.h>
  31   33  #include <sys/bootconf.h>
  32   34  #include <sys/bootsvcs.h>
  33   35  #include <sys/bootinfo.h>
  34   36  #include <sys/mman.h>
↓ open down ↓ 103 lines elided ↑ open up ↑
 138  140          if (!writeable)
 139  141                  pt_bits &= ~PT_WRITABLE;
 140  142          if (HYPERVISOR_update_va_mapping((uintptr_t)window,
 141  143              pa_to_ma(physaddr) | pt_bits, UVMF_INVLPG | UVMF_LOCAL) < 0)
 142  144                  bop_panic("HYPERVISOR_update_va_mapping() failed");
 143  145  #else
 144  146          if (kbm_pae_support)
 145  147                  *((x86pte_t *)pte_to_window) = physaddr | pt_bits;
 146  148          else
 147  149                  *((x86pte32_t *)pte_to_window) = physaddr | pt_bits;
 148      -        mmu_tlbflush_entry(window);
      150 +        mmu_invlpg(window);
 149  151  #endif
 150  152          DBG(window);
 151  153          return (window);
 152  154  }
 153  155  
 154  156  /*
 155  157   * Add a mapping for the physical page at the given virtual address.
 156  158   */
 157  159  void
 158  160  kbm_map(uintptr_t va, paddr_t pa, uint_t level, uint_t is_kernel)
↓ open down ↓ 29 lines elided ↑ open up ↑
 188  190                  bop_panic("kbm_map: find_pte returned NULL");
 189  191  
 190  192  #ifdef __xpv
 191  193          if (HYPERVISOR_update_va_mapping(va, pteval, UVMF_INVLPG | UVMF_LOCAL))
 192  194                  bop_panic("HYPERVISOR_update_va_mapping() failed");
 193  195  #else
 194  196          if (kbm_pae_support)
 195  197                  *ptep = pteval;
 196  198          else
 197  199                  *((x86pte32_t *)ptep) = pteval;
 198      -        mmu_tlbflush_entry((caddr_t)va);
      200 +        mmu_invlpg((caddr_t)va);
 199  201  #endif
 200  202  }
 201  203  
 202  204  #ifdef __xpv
 203  205  
 204  206  /*
 205  207   * Add a mapping for the machine page at the given virtual address.
 206  208   */
 207  209  void
 208  210  kbm_map_ma(maddr_t ma, uintptr_t va, uint_t level)
↓ open down ↓ 133 lines elided ↑ open up ↑
 342  344                  uint_t  probe_only = 1;
 343  345  
 344  346                  ptep = find_pte(va, NULL, level, probe_only);
 345  347                  if (ptep == NULL)
 346  348                          return;
 347  349  
 348  350                  if (kbm_pae_support)
 349  351                          *ptep = 0;
 350  352                  else
 351  353                          *((x86pte32_t *)ptep) = 0;
 352      -                mmu_tlbflush_entry((caddr_t)va);
      354 +                mmu_invlpg((caddr_t)va);
 353  355  #endif
 354  356          }
 355  357  }
 356  358  
 357  359  
 358  360  /*
 359  361   * Change a boot loader page table 4K mapping.
 360  362   * Returns the pfn of the old mapping.
 361  363   */
 362  364  pfn_t
↓ open down ↓ 18 lines elided ↑ open up ↑
 381  383                  old_pte = *((x86pte32_t *)ptep);
 382  384  
 383  385  #ifdef __xpv
 384  386          if (HYPERVISOR_update_va_mapping(va, pte_val, UVMF_INVLPG | UVMF_LOCAL))
 385  387                  bop_panic("HYPERVISOR_update_va_mapping() failed");
 386  388  #else
 387  389          if (kbm_pae_support)
 388  390                  *((x86pte_t *)ptep) = pte_val;
 389  391          else
 390  392                  *((x86pte32_t *)ptep) = pte_val;
 391      -        mmu_tlbflush_entry((caddr_t)va);
      393 +        mmu_invlpg((caddr_t)va);
 392  394  #endif
 393  395  
 394  396          if (!(old_pte & PT_VALID) || ma_to_pa(old_pte) == -1)
 395  397                  return (PFN_INVALID);
 396  398          return (mmu_btop(ma_to_pa(old_pte)));
 397  399  }
 398  400  
 399  401  
 400  402  /*
 401  403   * Change a boot loader page table 4K mapping to read only.
↓ open down ↓ 12 lines elided ↑ open up ↑
 414  416          level_t level = 0;
 415  417  
 416  418          ptep = find_pte(va, NULL, level, 0);
 417  419          if (ptep == NULL)
 418  420                  bop_panic("kbm_read_only: find_pte returned NULL");
 419  421  
 420  422          if (kbm_pae_support)
 421  423                  *ptep = pte_val;
 422  424          else
 423  425                  *((x86pte32_t *)ptep) = pte_val;
 424      -        mmu_tlbflush_entry((caddr_t)va);
      426 +        mmu_invlpg((caddr_t)va);
 425  427  #endif
 426  428  }
 427  429  
 428  430  /*
 429  431   * interfaces for kernel debugger to access physical memory
 430  432   */
 431  433  static x86pte_t save_pte;
 432  434  
 433  435  void *
 434  436  kbm_push(paddr_t pa)
↓ open down ↓ 17 lines elided ↑ open up ↑
 452  454  {
 453  455  #ifdef __xpv
 454  456          if (HYPERVISOR_update_va_mapping((uintptr_t)window, save_pte,
 455  457              UVMF_INVLPG | UVMF_LOCAL) < 0)
 456  458                  bop_panic("HYPERVISOR_update_va_mapping() failed");
 457  459  #else
 458  460          if (kbm_pae_support)
 459  461                  *((x86pte_t *)pte_to_window) = save_pte;
 460  462          else
 461  463                  *((x86pte32_t *)pte_to_window) = save_pte;
 462      -        mmu_tlbflush_entry(window);
      464 +        mmu_invlpg(window);
 463  465  #endif
 464  466  }
 465  467  
 466  468  x86pte_t
 467  469  get_pteval(paddr_t table, uint_t index)
 468  470  {
 469  471          void *table_ptr = kbm_remap_window(table, 0);
 470  472  
 471  473          if (kbm_pae_support)
 472  474                  return (((x86pte_t *)table_ptr)[index]);
↓ open down ↓ 46 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX