117 static size_t segvn_incore(struct seg *seg, caddr_t addr, size_t len,
118 char *vec);
119 static int segvn_lockop(struct seg *seg, caddr_t addr, size_t len,
120 int attr, int op, ulong_t *lockmap, size_t pos);
121 static int segvn_getprot(struct seg *seg, caddr_t addr, size_t len,
122 uint_t *protv);
123 static u_offset_t segvn_getoffset(struct seg *seg, caddr_t addr);
124 static int segvn_gettype(struct seg *seg, caddr_t addr);
125 static int segvn_getvp(struct seg *seg, caddr_t addr,
126 struct vnode **vpp);
127 static int segvn_advise(struct seg *seg, caddr_t addr, size_t len,
128 uint_t behav);
129 static void segvn_dump(struct seg *seg);
130 static int segvn_pagelock(struct seg *seg, caddr_t addr, size_t len,
131 struct page ***ppp, enum lock_type type, enum seg_rw rw);
132 static int segvn_setpagesize(struct seg *seg, caddr_t addr, size_t len,
133 uint_t szc);
134 static int segvn_getmemid(struct seg *seg, caddr_t addr,
135 memid_t *memidp);
136 static lgrp_mem_policy_info_t *segvn_getpolicy(struct seg *, caddr_t);
137 static int segvn_capable(struct seg *seg, segcapability_t capable);
138 static int segvn_inherit(struct seg *, caddr_t, size_t, uint_t);
139
140 struct seg_ops segvn_ops = {
141 .dup = segvn_dup,
142 .unmap = segvn_unmap,
143 .free = segvn_free,
144 .fault = segvn_fault,
145 .faulta = segvn_faulta,
146 .setprot = segvn_setprot,
147 .checkprot = segvn_checkprot,
148 .kluster = segvn_kluster,
149 .swapout = segvn_swapout,
150 .sync = segvn_sync,
151 .incore = segvn_incore,
152 .lockop = segvn_lockop,
153 .getprot = segvn_getprot,
154 .getoffset = segvn_getoffset,
155 .gettype = segvn_gettype,
156 .getvp = segvn_getvp,
157 .advise = segvn_advise,
158 .dump = segvn_dump,
159 .pagelock = segvn_pagelock,
160 .setpagesize = segvn_setpagesize,
161 .getmemid = segvn_getmemid,
162 .getpolicy = segvn_getpolicy,
163 .capable = segvn_capable,
164 .inherit = segvn_inherit,
165 };
166
167 /*
168 * Common zfod structures, provided as a shorthand for others to use.
169 */
170 static segvn_crargs_t zfod_segvn_crargs =
171 SEGVN_ZFOD_ARGS(PROT_ZFOD, PROT_ALL);
172 static segvn_crargs_t kzfod_segvn_crargs =
173 SEGVN_ZFOD_ARGS(PROT_ZFOD & ~PROT_USER,
174 PROT_ALL & ~PROT_USER);
175 static segvn_crargs_t stack_noexec_crargs =
176 SEGVN_ZFOD_ARGS(PROT_ZFOD & ~PROT_EXEC, PROT_ALL);
177
178 caddr_t zfod_argsp = (caddr_t)&zfod_segvn_crargs; /* user zfod argsp */
179 caddr_t kzfod_argsp = (caddr_t)&kzfod_segvn_crargs; /* kernel zfod argsp */
180 caddr_t stack_exec_argsp = (caddr_t)&zfod_segvn_crargs; /* executable stack */
181 caddr_t stack_noexec_argsp = (caddr_t)&stack_noexec_crargs; /* noexec stack */
182
183 #define vpgtob(n) ((n) * sizeof (struct vpage)) /* For brevity */
9672 /*
9673 * Get policy info for private or shared memory
9674 */
9675 if (svn_data->type != MAP_SHARED) {
9676 if (svn_data->tr_state != SEGVN_TR_ON) {
9677 policy_info = &svn_data->policy_info;
9678 } else {
9679 policy_info = &svn_data->tr_policy_info;
9680 ASSERT(policy_info->mem_policy ==
9681 LGRP_MEM_POLICY_NEXT_SEG);
9682 }
9683 } else {
9684 amp = svn_data->amp;
9685 anon_index = svn_data->anon_index + seg_page(seg, addr);
9686 vp = svn_data->vp;
9687 vn_off = svn_data->offset + (uintptr_t)(addr - seg->s_base);
9688 policy_info = lgrp_shm_policy_get(amp, anon_index, vp, vn_off);
9689 }
9690
9691 return (policy_info);
9692 }
9693
9694 /*ARGSUSED*/
9695 static int
9696 segvn_capable(struct seg *seg, segcapability_t capability)
9697 {
9698 return (0);
9699 }
9700
9701 /*
9702 * Bind text vnode segment to an amp. If we bind successfully mappings will be
9703 * established to per vnode mapping per lgroup amp pages instead of to vnode
9704 * pages. There's one amp per vnode text mapping per lgroup. Many processes
9705 * may share the same text replication amp. If a suitable amp doesn't already
9706 * exist in svntr hash table create a new one. We may fail to bind to amp if
9707 * segment is not eligible for text replication. Code below first checks for
9708 * these conditions. If binding is successful segment tr_state is set to on
9709 * and svd->amp points to the amp to use. Otherwise tr_state is set to off and
9710 * svd->amp remains as NULL.
9711 */
9712 static void
9713 segvn_textrepl(struct seg *seg)
9714 {
9715 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
9716 vnode_t *vp = svd->vp;
9717 u_offset_t off = svd->offset;
9718 size_t size = seg->s_size;
|
117 static size_t segvn_incore(struct seg *seg, caddr_t addr, size_t len,
118 char *vec);
119 static int segvn_lockop(struct seg *seg, caddr_t addr, size_t len,
120 int attr, int op, ulong_t *lockmap, size_t pos);
121 static int segvn_getprot(struct seg *seg, caddr_t addr, size_t len,
122 uint_t *protv);
123 static u_offset_t segvn_getoffset(struct seg *seg, caddr_t addr);
124 static int segvn_gettype(struct seg *seg, caddr_t addr);
125 static int segvn_getvp(struct seg *seg, caddr_t addr,
126 struct vnode **vpp);
127 static int segvn_advise(struct seg *seg, caddr_t addr, size_t len,
128 uint_t behav);
129 static void segvn_dump(struct seg *seg);
130 static int segvn_pagelock(struct seg *seg, caddr_t addr, size_t len,
131 struct page ***ppp, enum lock_type type, enum seg_rw rw);
132 static int segvn_setpagesize(struct seg *seg, caddr_t addr, size_t len,
133 uint_t szc);
134 static int segvn_getmemid(struct seg *seg, caddr_t addr,
135 memid_t *memidp);
136 static lgrp_mem_policy_info_t *segvn_getpolicy(struct seg *, caddr_t);
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 .swapout = segvn_swapout,
149 .sync = segvn_sync,
150 .incore = segvn_incore,
151 .lockop = segvn_lockop,
152 .getprot = segvn_getprot,
153 .getoffset = segvn_getoffset,
154 .gettype = segvn_gettype,
155 .getvp = segvn_getvp,
156 .advise = segvn_advise,
157 .dump = segvn_dump,
158 .pagelock = segvn_pagelock,
159 .setpagesize = segvn_setpagesize,
160 .getmemid = segvn_getmemid,
161 .getpolicy = segvn_getpolicy,
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 */
9670 /*
9671 * Get policy info for private or shared memory
9672 */
9673 if (svn_data->type != MAP_SHARED) {
9674 if (svn_data->tr_state != SEGVN_TR_ON) {
9675 policy_info = &svn_data->policy_info;
9676 } else {
9677 policy_info = &svn_data->tr_policy_info;
9678 ASSERT(policy_info->mem_policy ==
9679 LGRP_MEM_POLICY_NEXT_SEG);
9680 }
9681 } else {
9682 amp = svn_data->amp;
9683 anon_index = svn_data->anon_index + seg_page(seg, addr);
9684 vp = svn_data->vp;
9685 vn_off = svn_data->offset + (uintptr_t)(addr - seg->s_base);
9686 policy_info = lgrp_shm_policy_get(amp, anon_index, vp, vn_off);
9687 }
9688
9689 return (policy_info);
9690 }
9691
9692 /*
9693 * Bind text vnode segment to an amp. If we bind successfully mappings will be
9694 * established to per vnode mapping per lgroup amp pages instead of to vnode
9695 * pages. There's one amp per vnode text mapping per lgroup. Many processes
9696 * may share the same text replication amp. If a suitable amp doesn't already
9697 * exist in svntr hash table create a new one. We may fail to bind to amp if
9698 * segment is not eligible for text replication. Code below first checks for
9699 * these conditions. If binding is successful segment tr_state is set to on
9700 * and svd->amp points to the amp to use. Otherwise tr_state is set to off and
9701 * svd->amp remains as NULL.
9702 */
9703 static void
9704 segvn_textrepl(struct seg *seg)
9705 {
9706 struct segvn_data *svd = (struct segvn_data *)seg->s_data;
9707 vnode_t *vp = svd->vp;
9708 u_offset_t off = svd->offset;
9709 size_t size = seg->s_size;
|