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 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * Copyright 2018 Joyent, Inc. 25 */ 26 27 #ifndef _VM_SEG_SPT_H 28 #define _VM_SEG_SPT_H 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 #ifndef _ASM 35 36 #include <sys/types.h> 37 #include <sys/t_lock.h> 38 #include <sys/lgrp.h> 39 40 /* 41 * Passed data when creating spt segment. 42 */ 43 struct segspt_crargs { 44 struct seg *seg_spt; 45 struct anon_map *amp; 46 uint_t prot; 47 uint_t flags; 48 uint_t szc; 49 }; 50 51 typedef struct spt_data { 52 struct vnode *spt_vp; 53 struct anon_map *spt_amp; 54 size_t spt_realsize; 55 struct page **spt_ppa; 56 ushort_t *spt_ppa_lckcnt; 57 uint_t spt_prot; 58 kmutex_t spt_lock; 59 size_t spt_pcachecnt; /* # of times in pcache */ 60 uint_t spt_flags; /* Dynamic ISM or regular ISM */ 61 kcondvar_t spt_cv; 62 ushort_t spt_gen; /* only updated for DISM */ 63 /* 64 * Initial memory allocation policy 65 * used during pre-allocation done in shmat() 66 */ 67 lgrp_mem_policy_info_t spt_policy_info; 68 } spt_data_t; 69 70 /* 71 * Private data for spt_shm segment. 72 */ 73 typedef struct shm_data { 74 struct as *shm_sptas; 75 struct anon_map *shm_amp; 76 spgcnt_t shm_softlockcnt; /* # outstanding lock operations */ 77 struct seg *shm_sptseg; /* pointer to spt segment */ 78 char *shm_vpage; /* indicating locked pages */ 79 spgcnt_t shm_lckpgs; /* # of locked pages per attached seg */ 80 /* 81 * Memory allocation policy after shmat() 82 */ 83 lgrp_mem_policy_info_t shm_policy_info; 84 kmutex_t shm_segfree_syncmtx; /* barrier lock for segspt_shmfree() */ 85 } shm_data_t; 86 87 #define DISM_PG_LOCKED 0x1 /* DISM page is locked */ 88 #define DISM_PPA_CHANGED 0x2 /* DISM new lock, need to rebuild ppa */ 89 90 #define DISM_LOCK_MAX 0xfffe /* max number of locks per DISM page */ 91 #endif 92 93 #ifdef _KERNEL 94 95 #ifndef _ASM 96 97 /* 98 * Functions used in shm.c to call ISM. 99 */ 100 int sptcreate(size_t size, struct seg **sptseg, struct anon_map *amp, 101 uint_t prot, uint_t flags, uint_t szc); 102 void sptdestroy(struct as *, struct anon_map *); 103 int segspt_shmattach(struct seg **, void *); 104 105 #define isspt(sp) ((sp)->shm_sptinfo ? (sp)->shm_sptinfo->sptas : NULL) 106 #define spt_locked(a) ((a) & SHM_SHARE_MMU) 107 #define spt_pageable(a) ((a) & SHM_PAGEABLE) 108 #define spt_invalid(a) (spt_locked((a)) && spt_pageable((a))) 109 110 /* 111 * This can be applied to a segment with seg->s_ops == &segspt_shmops 112 * to determine the real size of the ISM segment. 113 */ 114 #define spt_realsize(seg) (((struct spt_data *)(((struct shm_data *)\ 115 ((seg)->s_data))->shm_sptseg->s_data))->spt_realsize) 116 117 /* 118 * This can be applied to a segment with seg->s_ops == &segspt_ops 119 * to determine the flags of the {D}ISM segment. 120 */ 121 #define spt_flags(seg) (((struct spt_data *)((seg)->s_data))->spt_flags) 122 123 /* 124 * For large page support 125 */ 126 extern int segvn_anypgsz; 127 128 #endif 129 130 /* 131 * In a 64-bit address space, we'll try to put ISM segments between 132 * PREDISM_BASE and PREDISM_BOUND. The HAT may use these constants to 133 * predict that a VA is contained by an ISM segment, which may optimize 134 * translation. The range must _only_ be treated as advisory; ISM segments 135 * may fall outside of the range, and non-ISM segments may be contained 136 * within the range. 137 * In order to avoid collision between ISM/DISM addresses with e.g. 138 * process heap addresses we will try to put ISM/DISM segments above 139 * PREDISM_1T_BASESHIFT (1T). 140 * The HAT is still expecting that any VA larger than PREDISM_BASESHIFT 141 * may belong to ISM/DISM (so on tlb miss it will probe first for 4M 142 * translation) 143 */ 144 #define PREDISM_BASESHIFT 33 145 #define PREDISM_1T_BASESHIFT 40 146 #define PREDISM_BASE ((uintptr_t)1 << PREDISM_BASESHIFT) 147 #define PREDISM_1T_BASE ((uintptr_t)1 << PREDISM_1T_BASESHIFT) 148 #define PREDISM_BOUND ((uintptr_t)1 << 63) 149 150 #endif /* _KERNEL */ 151 152 #ifdef __cplusplus 153 } 154 #endif 155 156 #endif /* _VM_SEG_SPT_H */ 157