Print this page
    
NEX-16970 assertion failed: ht->ht_valid_cnt >= 0, file: ../../i86pc/vm/htable.c, line: 1204
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/i86pc/vm/hat_i86.h
          +++ new/usr/src/uts/i86pc/vm/hat_i86.h
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  
    | 
      ↓ open down ↓ | 
    16 lines elided | 
    
      ↑ open up ↑ | 
  
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
  25   25  /*
  26   26   * Copyright (c) 2014 by Delphix. All rights reserved.
       27 + * Copyright 2019 Nexenta Systems, Inc.
  27   28   */
  28   29  
  29   30  #ifndef _VM_HAT_I86_H
  30   31  #define _VM_HAT_I86_H
  31   32  
  32   33  
  33   34  #ifdef  __cplusplus
  34   35  extern "C" {
  35   36  #endif
  36   37  
  37   38  /*
  38   39   * VM - Hardware Address Translation management.
  39   40   *
  40   41   * This file describes the contents of the x86_64 HAT data structures.
  41   42   */
  42   43  #include <sys/types.h>
  43   44  #include <sys/t_lock.h>
  44   45  #include <sys/cpuvar.h>
  45   46  #include <sys/x_call.h>
  46   47  #include <vm/seg.h>
  47   48  #include <vm/page.h>
  48   49  #include <sys/vmparam.h>
  49   50  #include <sys/vm_machparam.h>
  50   51  #include <sys/promif.h>
  51   52  #include <vm/hat_pte.h>
  52   53  #include <vm/htable.h>
  53   54  #include <vm/hment.h>
  54   55  
  55   56  /*
  56   57   * The essential data types involved:
  57   58   *
  58   59   * htable_t     - There is one of these for each page table and it is used
  59   60   *              by the HAT to manage the page table.
  60   61   *
  61   62   * hment_t      - Links together multiple PTEs to a single page.
  62   63   */
  63   64  
  64   65  /*
  65   66   * VLP processes have a 32 bit address range, so their top level is 2 and
  66   67   * with only 4 PTEs in that table.
  67   68   */
  68   69  #define VLP_LEVEL       (2)
  69   70  #define VLP_NUM_PTES    (4)
  70   71  #define VLP_SIZE        (VLP_NUM_PTES * sizeof (x86pte_t))
  71   72  #define TOP_LEVEL(h)    (((h)->hat_flags & HAT_VLP) ? VLP_LEVEL : mmu.max_level)
  72   73  #define VLP_COPY(fromptep, toptep) { \
  73   74          toptep[0] = fromptep[0]; \
  74   75          toptep[1] = fromptep[1]; \
  75   76          toptep[2] = fromptep[2]; \
  76   77          toptep[3] = fromptep[3]; \
  77   78  }
  78   79  
  79   80  /*
  
    | 
      ↓ open down ↓ | 
    43 lines elided | 
    
      ↑ open up ↑ | 
  
  80   81   * The hat struct exists for each address space.
  81   82   */
  82   83  struct hat {
  83   84          kmutex_t        hat_mutex;
  84   85          struct as       *hat_as;
  85   86          uint_t          hat_stats;
  86   87          pgcnt_t         hat_pages_mapped[MAX_PAGE_LEVEL + 1];
  87   88          pgcnt_t         hat_ism_pgcnt;
  88   89          cpuset_t        hat_cpus;
  89   90          uint16_t        hat_flags;
       91 +        uint16_t        hat_unmaps;     /* stop hat being free'd during unmap */
  90   92          htable_t        *hat_htable;    /* top level htable */
  91   93          struct hat      *hat_next;
  92   94          struct hat      *hat_prev;
  93   95          uint_t          hat_num_hash;   /* number of htable hash buckets */
  94   96          htable_t        **hat_ht_hash;  /* htable hash buckets */
  95   97          htable_t        *hat_ht_cached; /* cached free htables */
  96   98          x86pte_t        hat_vlp_ptes[VLP_NUM_PTES];
  97   99  #if defined(__amd64) && defined(__xpv)
  98  100          pfn_t           hat_user_ptable; /* alt top ptable for user mode */
  99  101  #endif
 100  102  };
 101  103  typedef struct hat hat_t;
 102  104  
 103  105  #define PGCNT_INC(hat, level)   \
 104  106          atomic_inc_ulong(&(hat)->hat_pages_mapped[level]);
 105  107  #define PGCNT_DEC(hat, level)   \
 106  108          atomic_dec_ulong(&(hat)->hat_pages_mapped[level]);
 107  109  
 108  110  /*
 109  111   * Flags for the hat_flags field
 110  112   *
 111  113   * HAT_FREEING - set when HAT is being destroyed - mostly used to detect that
 112  114   *      demap()s can be avoided.
 113  115   *
 114  116   * HAT_VLP - indicates a 32 bit process has a virtual address range less than
 115  117   *      the hardware's physical address range. (VLP->Virtual Less-than Physical)
 116  118   *      Note - never used on the hypervisor.
 117  119   *
 118  120   * HAT_VICTIM - This is set while a hat is being examined for page table
 119  121   *      stealing and prevents it from being freed.
 120  122   *
 121  123   * HAT_SHARED - The hat has exported it's page tables via hat_share()
 122  124   *
 123  125   * HAT_PINNED - On the hypervisor, indicates the top page table has been pinned.
 124  126   */
 125  127  #define HAT_FREEING     (0x0001)
 126  128  #define HAT_VLP         (0x0002)
 127  129  #define HAT_VICTIM      (0x0004)
 128  130  #define HAT_SHARED      (0x0008)
 129  131  #define HAT_PINNED      (0x0010)
 130  132  
 131  133  /*
 132  134   * Additional platform attribute for hat_devload() to force no caching.
 133  135   */
 134  136  #define HAT_PLAT_NOCACHE        (0x100000)
 135  137  
 136  138  /*
 137  139   * Simple statistics for the HAT. These are just counters that are
 138  140   * atomically incremented. They can be reset directly from the kernel
 139  141   * debugger.
 140  142   */
 141  143  struct hatstats {
 142  144          ulong_t hs_reap_attempts;
 143  145          ulong_t hs_reaped;
 144  146          ulong_t hs_steals;
 145  147          ulong_t hs_ptable_allocs;
 146  148          ulong_t hs_ptable_frees;
 147  149          ulong_t hs_htable_rgets;        /* allocs from reserve */
 148  150          ulong_t hs_htable_rputs;        /* putbacks to reserve */
 149  151          ulong_t hs_htable_shared;       /* number of htables shared */
 150  152          ulong_t hs_htable_unshared;     /* number of htables unshared */
 151  153          ulong_t hs_hm_alloc;
 152  154          ulong_t hs_hm_free;
 153  155          ulong_t hs_hm_put_reserve;
 154  156          ulong_t hs_hm_get_reserve;
 155  157          ulong_t hs_hm_steals;
 156  158          ulong_t hs_hm_steal_exam;
 157  159          ulong_t hs_tlb_inval_delayed;
 158  160  };
 159  161  extern struct hatstats hatstat;
 160  162  #ifdef DEBUG
 161  163  #define HATSTAT_INC(x)  (++hatstat.x)
 162  164  #else
 163  165  #define HATSTAT_INC(x)  (0)
 164  166  #endif
 165  167  
 166  168  #if defined(_KERNEL)
 167  169  
 168  170  /*
 169  171   * Useful macro to align hat_XXX() address arguments to a page boundary
 170  172   */
 171  173  #define ALIGN2PAGE(a)           ((uintptr_t)(a) & MMU_PAGEMASK)
 172  174  #define IS_PAGEALIGNED(a)       (((uintptr_t)(a) & MMU_PAGEOFFSET) == 0)
 173  175  
 174  176  extern uint_t   khat_running;   /* set at end of hat_kern_setup() */
 175  177  extern cpuset_t khat_cpuset;    /* cpuset for kernal address demap Xcalls */
 176  178  extern kmutex_t hat_list_lock;
 177  179  extern kcondvar_t hat_list_cv;
 178  180  
 179  181  
 180  182  
 181  183  /*
 182  184   * Interfaces to setup a cpu private mapping (ie. preemption disabled).
 183  185   * The attr and flags arguments are the same as for hat_devload().
 184  186   * setup() must be called once, then any number of calls to remap(),
 185  187   * followed by a final call to release()
 186  188   *
 187  189   * Used by ppcopy(), page_zero(), the memscrubber, and the kernel debugger.
 188  190   */
 189  191  typedef paddr_t hat_mempte_t;                           /* phys addr of PTE */
 190  192  extern hat_mempte_t hat_mempte_setup(caddr_t addr);
 191  193  extern void hat_mempte_remap(pfn_t, caddr_t, hat_mempte_t,
 192  194          uint_t attr, uint_t flags);
 193  195  extern void hat_mempte_release(caddr_t addr, hat_mempte_t);
 194  196  
 195  197  /*
 196  198   * Interfaces to manage which thread has access to htable and hment reserves.
 197  199   * The USE_HAT_RESERVES macro should always be recomputed in full. Its value
 198  200   * (due to curthread) can change after any call into kmem/vmem.
 199  201   */
 200  202  extern uint_t can_steal_post_boot;
 201  203  extern uint_t use_boot_reserve;
 202  204  #define USE_HAT_RESERVES()                                      \
 203  205          (use_boot_reserve || curthread->t_hatdepth > 1 ||       \
 204  206          panicstr != NULL || vmem_is_populator())
 205  207  
 206  208  /*
 207  209   * initialization stuff needed by by startup, mp_startup...
 208  210   */
 209  211  extern void hat_cpu_online(struct cpu *);
 210  212  extern void hat_cpu_offline(struct cpu *);
 211  213  extern void setup_vaddr_for_ppcopy(struct cpu *);
 212  214  extern void teardown_vaddr_for_ppcopy(struct cpu *);
 213  215  extern void clear_boot_mappings(uintptr_t, uintptr_t);
 214  216  
 215  217  /*
 216  218   * magic value to indicate that all TLB entries should be demapped.
 217  219   */
 218  220  #define DEMAP_ALL_ADDR  (~(uintptr_t)0)
 219  221  
 220  222  /*
 221  223   * not in any include file???
 222  224   */
 223  225  extern void halt(char *fmt);
 224  226  
 225  227  /*
 226  228   * x86 specific routines for use online in setup or i86pc/vm files
 227  229   */
 228  230  extern void hat_kern_alloc(caddr_t segmap_base, size_t segmap_size,
 229  231          caddr_t ekernelheap);
 230  232  extern void hat_kern_setup(void);
 231  233  extern void hat_tlb_inval(struct hat *hat, uintptr_t va);
 232  234  extern void hat_pte_unmap(htable_t *ht, uint_t entry, uint_t flags,
 233  235          x86pte_t old_pte, void *pte_ptr, boolean_t tlb);
 234  236  extern void hat_init_finish(void);
 235  237  extern caddr_t hat_kpm_pfn2va(pfn_t pfn);
 236  238  extern pfn_t hat_kpm_va2pfn(caddr_t);
 237  239  extern page_t *hat_kpm_vaddr2page(caddr_t);
 238  240  extern uintptr_t hat_kernelbase(uintptr_t);
 239  241  extern void hat_kmap_init(uintptr_t base, size_t len);
 240  242  
 241  243  extern hment_t *hati_page_unmap(page_t *pp, htable_t *ht, uint_t entry);
 242  244  
 243  245  #if !defined(__xpv)
 244  246  /*
 245  247   * routines to deal with delayed TLB invalidations for idle CPUs
 246  248   */
 247  249  extern void tlb_going_idle(void);
 248  250  extern void tlb_service(void);
 249  251  #endif
 250  252  
 251  253  /*
 252  254   * Hat switch function invoked to load a new context into %cr3
 253  255   */
 254  256  extern void hat_switch(struct hat *hat);
 255  257  
 256  258  #ifdef __xpv
 257  259  /*
 258  260   * Interfaces to use around code that maps/unmaps grant table references.
 259  261   */
 260  262  extern void hat_prepare_mapping(hat_t *, caddr_t, uint64_t *);
 261  263  extern void hat_release_mapping(hat_t *, caddr_t);
 262  264  
 263  265  #define XPV_DISALLOW_MIGRATE()  xen_block_migrate()
 264  266  #define XPV_ALLOW_MIGRATE()     xen_allow_migrate()
 265  267  
 266  268  #else
 267  269  
 268  270  #define XPV_DISALLOW_MIGRATE()  /* nothing */
 269  271  #define XPV_ALLOW_MIGRATE()     /* nothing */
 270  272  
 271  273  #define pfn_is_foreign(pfn)     __lintzero
 272  274  
 273  275  #endif
 274  276  
 275  277  
 276  278  #endif  /* _KERNEL */
 277  279  
 278  280  #ifdef  __cplusplus
 279  281  }
 280  282  #endif
 281  283  
 282  284  #endif  /* _VM_HAT_I86_H */
  
    | 
      ↓ open down ↓ | 
    183 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX