1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 makeknown_:
72 procedure (a_makeknown_infop, a_segno, a_use_count, a_code);
73
74
75
76 dcl a_code fixed bin (35);
77 dcl a_makeknown_infop ptr;
78 dcl a_segno fixed bin (17);
79 dcl a_use_count fixed bin (17);
80
81
82
83 dcl code fixed bin (35);
84 dcl hash_bucket fixed bin (17);
85 dcl pkstep ptr;
86 dcl ring fixed bin (3);
87 dcl 1 sdwi aligned like sdw_info;
88 dcl segno fixed bin (17);
89 dcl valid bit (1) aligned;
90 dcl vcpu_suspend_1 fixed bin (71);
91 dcl vcpu_suspend_2 fixed bin (71);
92
93
94
95 dcl dseg$ (0:4095) fixed bin (71) external;
96 dcl error_table_$invalidsegno fixed bin (35) external static;
97 dcl error_table_$nrmkst fixed bin (35) ext static;
98 dcl error_table_$segknown fixed bin (35) external static;
99 dcl error_table_$segno_in_use fixed bin (35) external static;
100 dcl 1 pds$transparent external aligned,
101 2 tms bit (1) unaligned,
102 2 tus bit (1) unaligned,
103 2 tpd bit (1) unaligned;
104
105
106
107 dcl fim_util$fim_v_time_calc_ext entry (fixed bin (71), fixed bin (71));
108 dcl fim_util$fim_v_time_init_ext entry (fixed bin (71), fixed bin (71));
109 dcl kst_util$garbage_collect entry (fixed bin (35));
110 dcl kst_util$initialize_region entry (fixed bin);
111 dcl kst_util$unthread_kste entry (ptr);
112 dcl kstsrch entry (bit (36) aligned, fixed bin (17), ptr);
113 dcl level$get entry () returns (fixed bin (3));
114 dcl makeunknown_ entry (fixed bin, bit (36) aligned, bit (1) aligned, fixed bin (35));
115 dcl sdw_util_$construct entry (ptr, ptr);
116 dcl sdw_util_$dissect entry (ptr, ptr);
117 dcl sdw_util_$get_valid entry (ptr, bit (1) aligned);
118 dcl seg_fault$makeknown_activate entry (ptr, fixed bin (35));
119 dcl setfaults$disconnect entry (fixed bin (17));
120
121
122
123 dcl (addr, baseno, fixed, null, ptr, rel, string, unspec) builtin;
124 %page;
125 makeknown_infop = a_makeknown_infop;
126 segno = a_segno;
127 a_use_count = 0;
128 a_code = 0;
129 kstp = pds$kstp;
130 ring = level$get ();
131 call kstsrch (makeknown_info.uid, hash_bucket, kstep);
132 if kstep ^= null () then do;
133 a_code = error_table_$segknown;
134 a_segno = kste.segno;
135 if (^kste.priv_init & makeknown_info.priv_init) | (^kste.allow_write & makeknown_info.allow_write) then do;
136
137 call setfaults$disconnect ((kste.segno));
138 kste.dtbm = (36)"1"b;
139 end;
140 end;
141 else do;
142 if makeknown_info.rsw then do;
143 if segno - kst.lowseg < ring |
144 segno > kst.highseg then call abort (error_table_$invalidsegno);
145 if segno > kst.highest_used_segno then call kst_util$initialize_region (segno);
146 kstep = addr (kst.kst_entry (segno));
147 if unspec (kste.entryp) ^= "0"b then call abort (error_table_$segno_in_use);
148 if kste.fp ^= (18)"1"b then call kst_util$unthread_kste (kstep);
149 end;
150 else do;
151 if kst.free_list = "0"b
152 then if kst.highest_used_segno < kst.highseg
153 then call kst_util$initialize_region (kst.highest_used_segno + 1);
154 else do;
155 call kst_util$garbage_collect (code);
156 if code ^= 0 then call abort (code);
157 end;
158 if kst.free_list = ""b
159 then
160 call abort (error_table_$nrmkst);
161 kstep = ptr (kstp, kst.free_list);
162 kst.free_list = kste.fp;
163 a_segno = kste.segno;
164 end;
165 kste.fp = kst.uid_hash_bucket (hash_bucket);
166 kst.uid_hash_bucket (hash_bucket) = rel (kstep);
167
168 if makeknown_info.entryp ^= null () then do;
169 pkstep = addr (kst.kst_entry (fixed (baseno (makeknown_info.entryp), 17)));
170 pkstep -> kste.infcount = pkstep -> kste.infcount + 1;
171 end;
172 kste.dirsw = makeknown_info.dirsw;
173 kste.uid = makeknown_info.uid;
174 kste.dtbm = (36)"1"b;
175
176
177
178 call sdw_util_$dissect (addr (dseg$ (kste.segno)), addr (sdwi));
179
180 sdwi.r1, sdwi.r2, sdwi.r3 = "0"b;
181 string (sdwi.access) = "0"b;
182
183 call sdw_util_$construct (addr (dseg$ (kste.segno)), addr (sdwi));
184 end;
185 kste.tus = pds$transparent.tus;
186 kste.tms = pds$transparent.tms | kste.dirsw;
187 kste.tpd = pds$transparent.tpd;
188 kste.allow_write = kste.allow_write | makeknown_info.allow_write;
189 kste.priv_init = kste.priv_init | makeknown_info.priv_init;
190 kste.entryp = makeknown_info.entryp;
191 kste.audit = makeknown_info.audit;
192 if kste.usage_count (ring) ^< 0
193 then kste.usage_count (ring) = kste.usage_count (ring) + 1;
194 a_use_count = kste.usage_count (ring);
195
196 if makeknown_info.activate then do;
197 call sdw_util_$get_valid (addr (dseg$ (kste.segno)), valid);
198 if ^valid then do;
199 call fim_util$fim_v_time_init_ext (vcpu_suspend_1, vcpu_suspend_2);
200 call seg_fault$makeknown_activate (kstep, code);
201
202 if code = 0 then
203 call fim_util$fim_v_time_calc_ext (vcpu_suspend_1, vcpu_suspend_2);
204 else do;
205 a_code = code;
206 call makeunknown_ ((kste.segno), "01"b, ("0"b), code);
207
208 end;
209 end;
210 end;
211
212 return;
213
214
215 abort:
216 proc (code);
217 dcl code fixed bin (35);
218 a_code = code;
219 go to non_local_return;
220 end abort;
221
222 non_local_return:
223 return;
224 %page;
225 %include kst;
226 %page;
227 %include makeknown_info;
228 %page;
229 %include sdw_info;
230 %page;
231 %include stack_header;
232 end makeknown_;