116 static size_t segvn_incore(struct seg *seg, caddr_t addr, size_t len,
117 char *vec);
118 static int segvn_lockop(struct seg *seg, caddr_t addr, size_t len,
119 int attr, int op, ulong_t *lockmap, size_t pos);
120 static int segvn_getprot(struct seg *seg, caddr_t addr, size_t len,
121 uint_t *protv);
122 static u_offset_t segvn_getoffset(struct seg *seg, caddr_t addr);
123 static int segvn_gettype(struct seg *seg, caddr_t addr);
124 static int segvn_getvp(struct seg *seg, caddr_t addr,
125 struct vnode **vpp);
126 static int segvn_advise(struct seg *seg, caddr_t addr, size_t len,
127 uint_t behav);
128 static void segvn_dump(struct seg *seg);
129 static int segvn_pagelock(struct seg *seg, caddr_t addr, size_t len,
130 struct page ***ppp, enum lock_type type, enum seg_rw rw);
131 static int segvn_setpagesize(struct seg *seg, caddr_t addr, size_t len,
132 uint_t szc);
133 static int segvn_getmemid(struct seg *seg, caddr_t addr,
134 memid_t *memidp);
135 static lgrp_mem_policy_info_t *segvn_getpolicy(struct seg *, caddr_t);
136 static int segvn_capable(struct seg *seg, segcapability_t capable);
137 static int segvn_inherit(struct seg *, caddr_t, size_t, uint_t);
138
139 struct seg_ops segvn_ops = {
140 .dup = segvn_dup,
141 .unmap = segvn_unmap,
142 .free = segvn_free,
143 .fault = segvn_fault,
144 .faulta = segvn_faulta,
145 .setprot = segvn_setprot,
146 .checkprot = segvn_checkprot,
147 .kluster = segvn_kluster,
148 .sync = segvn_sync,
149 .incore = segvn_incore,
150 .lockop = segvn_lockop,
151 .getprot = segvn_getprot,
152 .getoffset = segvn_getoffset,
153 .gettype = segvn_gettype,
154 .getvp = segvn_getvp,
155 .advise = segvn_advise,
156 .dump = segvn_dump,
157 .pagelock = segvn_pagelock,
158 .setpagesize = segvn_setpagesize,
159 .getmemid = segvn_getmemid,
160 .getpolicy = segvn_getpolicy,
161 .capable = segvn_capable,
162 .inherit = segvn_inherit,
163 };
164
165 /*
166 * Common zfod structures, provided as a shorthand for others to use.
167 */
168 static segvn_crargs_t zfod_segvn_crargs =
169 SEGVN_ZFOD_ARGS(PROT_ZFOD, PROT_ALL);
170 static segvn_crargs_t kzfod_segvn_crargs =
171 SEGVN_ZFOD_ARGS(PROT_ZFOD & ~PROT_USER,
172 PROT_ALL & ~PROT_USER);
173 static segvn_crargs_t stack_noexec_crargs =
174 SEGVN_ZFOD_ARGS(PROT_ZFOD & ~PROT_EXEC, PROT_ALL);
175
176 caddr_t zfod_argsp = (caddr_t)&zfod_segvn_crargs; /* user zfod argsp */
177 caddr_t kzfod_argsp = (caddr_t)&kzfod_segvn_crargs; /* kernel zfod argsp */
178 caddr_t stack_exec_argsp = (caddr_t)&zfod_segvn_crargs; /* executable stack */
179 caddr_t stack_noexec_argsp = (caddr_t)&stack_noexec_crargs; /* noexec stack */
180
181 #define vpgtob(n) ((n) * sizeof (struct vpage)) /* For brevity */
9466 /*
9467 * Get policy info for private or shared memory
9468 */
9469 if (svn_data->type != MAP_SHARED) {
9470 if (svn_data->tr_state != SEGVN_TR_ON) {
9471 policy_info = &svn_data->policy_info;
9472 } else {
9473 policy_info = &svn_data->tr_policy_info;
9474 ASSERT(policy_info->mem_policy ==
9475 LGRP_MEM_POLICY_NEXT_SEG);
9476 }
9477 } else {
9478 amp = svn_data->amp;
9479 anon_index = svn_data->anon_index + seg_page(seg, addr);
9480 vp = svn_data->vp;
9481 vn_off = svn_data->offset + (uintptr_t)(addr - seg->s_base);
9482 policy_info = lgrp_shm_policy_get(amp, anon_index, vp, vn_off);
9483 }
9484
9485 return (policy_info);
9486 }
9487
9488 /*ARGSUSED*/
9489 static int
9490 segvn_capable(struct seg *seg, segcapability_t capability)
9491 {
9492 return (0);
9493 }
9494
9495 /*
9496 * Bind text vnode segment to an amp. If we bind successfully mappings will be
9497 * established to per vnode mapping per lgroup amp pages instead of to vnode
9498 * pages. There's one amp per vnode text mapping per lgroup. Many processes
9499 * may share the same text replication amp. If a suitable amp doesn't already
9500 * exist in svntr hash table create a new one. We may fail to bind to amp if
9501 * segment is not eligible for text replication. Code below first checks for
9502 * these conditions. If binding is successful segment tr_state is set to on
9503 * and svd->amp points to the amp to use. Otherwise tr_state is set to off and
9504 * svd->amp remains as NULL.
9505 */
9506 static void
9507 segvn_textrepl(struct seg *seg)
9508 {
9509 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
9510 vnode_t *vp = svd->vp;
9511 u_offset_t off = svd->offset;
9512 size_t size = seg->s_size;
|
116 static size_t segvn_incore(struct seg *seg, caddr_t addr, size_t len,
117 char *vec);
118 static int segvn_lockop(struct seg *seg, caddr_t addr, size_t len,
119 int attr, int op, ulong_t *lockmap, size_t pos);
120 static int segvn_getprot(struct seg *seg, caddr_t addr, size_t len,
121 uint_t *protv);
122 static u_offset_t segvn_getoffset(struct seg *seg, caddr_t addr);
123 static int segvn_gettype(struct seg *seg, caddr_t addr);
124 static int segvn_getvp(struct seg *seg, caddr_t addr,
125 struct vnode **vpp);
126 static int segvn_advise(struct seg *seg, caddr_t addr, size_t len,
127 uint_t behav);
128 static void segvn_dump(struct seg *seg);
129 static int segvn_pagelock(struct seg *seg, caddr_t addr, size_t len,
130 struct page ***ppp, enum lock_type type, enum seg_rw rw);
131 static int segvn_setpagesize(struct seg *seg, caddr_t addr, size_t len,
132 uint_t szc);
133 static int segvn_getmemid(struct seg *seg, caddr_t addr,
134 memid_t *memidp);
135 static lgrp_mem_policy_info_t *segvn_getpolicy(struct seg *, caddr_t);
136 static int segvn_inherit(struct seg *, caddr_t, size_t, uint_t);
137
138 struct seg_ops segvn_ops = {
139 .dup = segvn_dup,
140 .unmap = segvn_unmap,
141 .free = segvn_free,
142 .fault = segvn_fault,
143 .faulta = segvn_faulta,
144 .setprot = segvn_setprot,
145 .checkprot = segvn_checkprot,
146 .kluster = segvn_kluster,
147 .sync = segvn_sync,
148 .incore = segvn_incore,
149 .lockop = segvn_lockop,
150 .getprot = segvn_getprot,
151 .getoffset = segvn_getoffset,
152 .gettype = segvn_gettype,
153 .getvp = segvn_getvp,
154 .advise = segvn_advise,
155 .dump = segvn_dump,
156 .pagelock = segvn_pagelock,
157 .setpagesize = segvn_setpagesize,
158 .getmemid = segvn_getmemid,
159 .getpolicy = segvn_getpolicy,
160 .inherit = segvn_inherit,
161 };
162
163 /*
164 * Common zfod structures, provided as a shorthand for others to use.
165 */
166 static segvn_crargs_t zfod_segvn_crargs =
167 SEGVN_ZFOD_ARGS(PROT_ZFOD, PROT_ALL);
168 static segvn_crargs_t kzfod_segvn_crargs =
169 SEGVN_ZFOD_ARGS(PROT_ZFOD & ~PROT_USER,
170 PROT_ALL & ~PROT_USER);
171 static segvn_crargs_t stack_noexec_crargs =
172 SEGVN_ZFOD_ARGS(PROT_ZFOD & ~PROT_EXEC, PROT_ALL);
173
174 caddr_t zfod_argsp = (caddr_t)&zfod_segvn_crargs; /* user zfod argsp */
175 caddr_t kzfod_argsp = (caddr_t)&kzfod_segvn_crargs; /* kernel zfod argsp */
176 caddr_t stack_exec_argsp = (caddr_t)&zfod_segvn_crargs; /* executable stack */
177 caddr_t stack_noexec_argsp = (caddr_t)&stack_noexec_crargs; /* noexec stack */
178
179 #define vpgtob(n) ((n) * sizeof (struct vpage)) /* For brevity */
9464 /*
9465 * Get policy info for private or shared memory
9466 */
9467 if (svn_data->type != MAP_SHARED) {
9468 if (svn_data->tr_state != SEGVN_TR_ON) {
9469 policy_info = &svn_data->policy_info;
9470 } else {
9471 policy_info = &svn_data->tr_policy_info;
9472 ASSERT(policy_info->mem_policy ==
9473 LGRP_MEM_POLICY_NEXT_SEG);
9474 }
9475 } else {
9476 amp = svn_data->amp;
9477 anon_index = svn_data->anon_index + seg_page(seg, addr);
9478 vp = svn_data->vp;
9479 vn_off = svn_data->offset + (uintptr_t)(addr - seg->s_base);
9480 policy_info = lgrp_shm_policy_get(amp, anon_index, vp, vn_off);
9481 }
9482
9483 return (policy_info);
9484 }
9485
9486 /*
9487 * Bind text vnode segment to an amp. If we bind successfully mappings will be
9488 * established to per vnode mapping per lgroup amp pages instead of to vnode
9489 * pages. There's one amp per vnode text mapping per lgroup. Many processes
9490 * may share the same text replication amp. If a suitable amp doesn't already
9491 * exist in svntr hash table create a new one. We may fail to bind to amp if
9492 * segment is not eligible for text replication. Code below first checks for
9493 * these conditions. If binding is successful segment tr_state is set to on
9494 * and svd->amp points to the amp to use. Otherwise tr_state is set to off and
9495 * svd->amp remains as NULL.
9496 */
9497 static void
9498 segvn_textrepl(struct seg *seg)
9499 {
9500 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
9501 vnode_t *vp = svd->vp;
9502 u_offset_t off = svd->offset;
9503 size_t size = seg->s_size;
|