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/hat_kdi.c
          +++ new/usr/src/uts/i86pc/vm/hat_kdi.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 2007 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  /*
  28   30   * HAT interfaces used by the kernel debugger to interact with the VM system.
  29   31   * These interfaces are invoked when the world is stopped.  As such, no blocking
  30   32   * operations may be performed.
  31   33   */
  32   34  
  33   35  #include <sys/cpuvar.h>
  34   36  #include <sys/kdi_impl.h>
↓ open down ↓ 135 lines elided ↑ open up ↑
 170  172                  return (0);
 171  173          }
 172  174  
 173  175          /*
 174  176           * We can't go through normal hat routines, so we'll use
 175  177           * kdi_pread() to walk the page tables
 176  178           */
 177  179  #if defined(__xpv)
 178  180          *pap = pfn_to_pa(CPU->cpu_current_hat->hat_htable->ht_pfn);
 179  181  #else
 180      -        *pap = getcr3() & MMU_PAGEMASK;
      182 +        *pap = getcr3_pa();
 181  183  #endif
 182  184          for (level = mmu.max_level; ; --level) {
 183  185                  index = (va >> LEVEL_SHIFT(level)) & (mmu.ptes_per_table - 1);
 184  186                  *pap += index << mmu.pte_size_shift;
 185  187                  pte = 0;
 186  188                  if (kdi_pread((caddr_t)&pte, mmu.pte_size, *pap, &len) != 0)
 187  189                          return (ENOENT);
 188  190                  if (pte == 0)
 189  191                          return (ENOENT);
 190  192                  if (level > 0 && level <= mmu.max_page_level &&
↓ open down ↓ 51 lines elided ↑ open up ↑
 242  244                          (void) kbm_push(pa);
 243  245  #if defined(__xpv)
 244  246                  else
 245  247                          (void) HYPERVISOR_update_va_mapping(
 246  248                              (uintptr_t)va, pte, UVMF_INVLPG);
 247  249  #else
 248  250                  else if (hat_kdi_use_pae)
 249  251                          *hat_kdi_pte = pte;
 250  252                  else
 251  253                          *(x86pte32_t *)hat_kdi_pte = pte;
 252      -                mmu_tlbflush_entry((caddr_t)hat_kdi_page);
      254 +                mmu_flush_tlb_kpage(hat_kdi_page);
 253  255  #endif
 254  256  
 255  257                  bcopy(from, to, sz);
 256  258  
 257  259                  /*
 258  260                   * erase the mapping
 259  261                   */
 260  262                  if (use_kbm)
 261  263                          kbm_pop();
 262  264  #if defined(__xpv)
 263  265                  else
 264  266                          (void) HYPERVISOR_update_va_mapping(
 265  267                              (uintptr_t)va, 0, UVMF_INVLPG);
 266  268  #else
 267  269                  else if (hat_kdi_use_pae)
 268  270                          *hat_kdi_pte = 0;
 269  271                  else
 270  272                          *(x86pte32_t *)hat_kdi_pte = 0;
 271      -                mmu_tlbflush_entry((caddr_t)hat_kdi_page);
      273 +                mmu_flush_tlb_kpage(hat_kdi_page);
 272  274  #endif
 273  275  
 274  276                  buf += sz;
 275  277                  pa += sz;
 276  278                  nbytes -= sz;
 277  279                  ncopied += sz;
 278  280          }
 279  281  
 280  282          if (ncopied == 0)
 281  283                  return (ENOENT);
↓ open down ↓ 7 lines elided ↑ open up ↑
 289  291  {
 290  292          return (kdi_prw(buf, nbytes, addr, ncopiedp, 1));
 291  293  }
 292  294  
 293  295  int
 294  296  kdi_pwrite(caddr_t buf, size_t nbytes, uint64_t addr, size_t *ncopiedp)
 295  297  {
 296  298          return (kdi_prw(buf, nbytes, addr, ncopiedp, 0));
 297  299  }
 298  300  
      301 +#if !defined(__xpv)
      302 +/*
      303 + * This gets used for flushing the TLB on all the slaves just prior to doing a
      304 + * kdi_prw().  It's unclear why this was originally done, since kdi_prw() itself
      305 + * will flush any lingering hat_kdi_page mappings, but let's presume it was a
      306 + * good idea.
      307 + */
      308 +void
      309 +kdi_flush_caches(void)
      310 +{
      311 +        mmu_flush_tlb(FLUSH_TLB_ALL, NULL);
      312 +}
      313 +#endif
 299  314  
 300  315  /*
 301  316   * Return the number of bytes, relative to the beginning of a given range, that
 302  317   * are non-toxic (can be read from and written to with relative impunity).
 303  318   */
 304  319  /*ARGSUSED*/
 305  320  size_t
 306  321  kdi_range_is_nontoxic(uintptr_t va, size_t sz, int write)
 307  322  {
 308  323  #if defined(__amd64)
↓ open down ↓ 33 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX