Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * Hypervisor Software File: res_mau.c | |
5 | * | |
6 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
7 | * | |
8 | * - Do no alter or remove copyright notices | |
9 | * | |
10 | * - Redistribution and use of this software in source and binary forms, with | |
11 | * or without modification, are permitted provided that the following | |
12 | * conditions are met: | |
13 | * | |
14 | * - Redistribution of source code must retain the above copyright notice, | |
15 | * this list of conditions and the following disclaimer. | |
16 | * | |
17 | * - Redistribution in binary form must reproduce the above copyright notice, | |
18 | * this list of conditions and the following disclaimer in the | |
19 | * documentation and/or other materials provided with the distribution. | |
20 | * | |
21 | * Neither the name of Sun Microsystems, Inc. or the names of contributors | |
22 | * may be used to endorse or promote products derived from this software | |
23 | * without specific prior written permission. | |
24 | * | |
25 | * This software is provided "AS IS," without a warranty of any kind. | |
26 | * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, | |
27 | * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A | |
28 | * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN | |
29 | * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR | |
30 | * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
31 | * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN | |
32 | * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR | |
33 | * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE | |
34 | * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, | |
35 | * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF | |
36 | * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
37 | * | |
38 | * You acknowledge that this software is not designed, licensed or | |
39 | * intended for use in the design, construction, operation or maintenance of | |
40 | * any nuclear facility. | |
41 | * | |
42 | * ========== Copyright Header End ============================================ | |
43 | */ | |
44 | /* | |
45 | * Copyright 2007 Sun Microsystems, Inc. All rights reserved. | |
46 | * Use is subject to license terms. | |
47 | */ | |
48 | ||
49 | #pragma ident "@(#)res_mau.c 1.7 07/06/07 SMI" | |
50 | ||
51 | #ifdef CONFIG_CRYPTO /* Compiled in if the CRYPTO option selected */ | |
52 | ||
53 | #include <stdarg.h> | |
54 | ||
55 | #include <sys/htypes.h> | |
56 | #include <traps.h> | |
57 | #include <cache.h> | |
58 | #include <mmu.h> | |
59 | #include <sun4v/asi.h> | |
60 | #include <vdev_intr.h> | |
61 | #include <ncs.h> | |
62 | #include <cyclic.h> | |
63 | #include <support.h> | |
64 | #include <strand.h> | |
65 | #include <vcpu.h> | |
66 | #include <guest.h> | |
67 | #include <pcie.h> | |
68 | #include <vdev_ops.h> | |
69 | #include <fpga.h> | |
70 | #include <ldc.h> | |
71 | #include <config.h> | |
72 | #include <offsets.h> | |
73 | #include <hvctl.h> | |
74 | #include <md.h> | |
75 | #include <abort.h> | |
76 | #include <hypervisor.h> | |
77 | #include <proto.h> | |
78 | ||
79 | /* | |
80 | * (re)-configuration code to handle HV MAU resources | |
81 | */ | |
82 | ||
83 | /* | |
84 | * resource processing support | |
85 | */ | |
86 | ||
87 | extern void c_unconfig_mau(vcpu_t *, guest_t *); | |
88 | extern void c_setup_mau(vcpu_t *, uint64_t, config_t *); | |
89 | ||
90 | static void res_mau_commit_config(mau_t *maup); | |
91 | static void res_mau_commit_unconfig(mau_t *maup); | |
92 | static void res_mau_commit_modify(mau_t *maup); | |
93 | ||
94 | static hvctl_status_t res_mau_parse_1(bin_md_t *mdp, md_element_t *maunodep, | |
95 | hvctl_res_error_t *fail_codep, int *fail_res_idp); | |
96 | ||
97 | static void setup_a_mau(vcpu_t *vcpup, mau_t *maup, uint64_t ino); | |
98 | ||
99 | /* | |
100 | * mau support functions. | |
101 | */ | |
102 | void | |
103 | res_mau_prep() | |
104 | { | |
105 | mau_t *mp; | |
106 | int i; | |
107 | ||
108 | mp = config.config_m.maus; | |
109 | ||
110 | for (i = 0; i < NMAUS; i++, mp++) { | |
111 | mp->pip.res.flags = (mp->state == MAU_STATE_UNCONFIGURED) ? | |
112 | RESF_Noop : RESF_Unconfig; | |
113 | mp->pip.cpuset = 0; | |
114 | } | |
115 | } | |
116 | ||
117 | ||
118 | hvctl_status_t | |
119 | res_mau_parse(bin_md_t *mdp, hvctl_res_error_t *fail_codep, | |
120 | md_element_t **failnodepp, int *fail_res_idp) | |
121 | { | |
122 | md_element_t *mdep; | |
123 | uint64_t arc_token; | |
124 | uint64_t node_token; | |
125 | md_element_t *maunodep; | |
126 | ||
127 | mdp = (bin_md_t *)config.parse_hvmd; | |
128 | ||
129 | mdep = md_find_node(mdp, NULL, MDNAME(maus)); | |
130 | if (mdep == NULL) { | |
131 | DBG_MAU(c_printf("Missing maus node in HVMD\n")); | |
132 | *failnodepp = NULL; | |
133 | *fail_res_idp = 0; | |
134 | return (HVctl_st_badmd); | |
135 | } | |
136 | ||
137 | arc_token = MDARC(MDNAME(fwd)); | |
138 | node_token = MDNODE(MDNAME(mau)); | |
139 | ||
140 | while (NULL != (mdep = md_find_node_by_arc(mdp, mdep, | |
141 | arc_token, node_token, &maunodep))) { | |
142 | hvctl_status_t status; | |
143 | status = res_mau_parse_1(mdp, maunodep, fail_codep, | |
144 | fail_res_idp); | |
145 | if (status != HVctl_st_ok) { | |
146 | *failnodepp = maunodep; | |
147 | return (status); | |
148 | } | |
149 | } | |
150 | return (HVctl_st_ok); | |
151 | } | |
152 | ||
153 | hvctl_status_t | |
154 | res_mau_parse_1(bin_md_t *mdp, md_element_t *maunodep, | |
155 | hvctl_res_error_t *fail_codep, int *fail_res_idp) | |
156 | { | |
157 | uint64_t strand_id, thread_id, mau_id, gid, ino; | |
158 | mau_t *maup = NULL; | |
159 | md_element_t *guestnodep, *cpunodep, *mdep; | |
160 | ||
161 | DBG_MAU(md_dump_node(mdp, maunodep)); | |
162 | ||
163 | mdep = maunodep; | |
164 | ||
165 | while (NULL != (mdep = md_find_node_by_arc(mdp, mdep, | |
166 | MDARC(MDNAME(back)), MDNODE(MDNAME(cpu)), &cpunodep))) { | |
167 | ||
168 | if (!md_node_get_val(mdp, cpunodep, MDNAME(pid), &strand_id)) { | |
169 | DBG_MAU(c_printf("Missing PID in cpu node\n")); | |
170 | *fail_codep = HVctl_e_mau_missing_strandid; | |
171 | goto fail; | |
172 | } | |
173 | ||
174 | if (strand_id >= NSTRANDS) { | |
175 | DBG_MAU(c_printf("Invalid PID in cpu node\n")); | |
176 | *fail_codep = HVctl_e_mau_invalid_strandid; | |
177 | goto fail; | |
178 | } | |
179 | ||
180 | if (maup == NULL) { | |
181 | mau_id = strand_id >> STRANDID_2_COREID_SHIFT; | |
182 | ASSERT(mau_id < NMAUS); | |
183 | maup = config.config_m.maus; | |
184 | maup = &(maup[mau_id]); | |
185 | maup->pip.cpuset = 0; | |
186 | *fail_res_idp = mau_id; | |
187 | DBG_MAU(c_printf("res_mau_parse_1(0x%x)\n", mau_id)); | |
188 | } | |
189 | ||
190 | thread_id = strand_id & NSTRANDS_PER_CORE_MASK; | |
191 | ||
192 | maup->pip.cpuset |= (1 << thread_id); | |
193 | ||
194 | if (NULL == md_find_node_by_arc(mdp, cpunodep, | |
195 | MDARC(MDNAME(back)), MDNODE(MDNAME(guest)), | |
196 | &guestnodep)) { | |
197 | DBG_MAU(c_printf("Missing back arc to guest node in " | |
198 | "cpu node\n")); | |
199 | *fail_codep = HVctl_e_mau_missing_guest; | |
200 | goto fail; | |
201 | } | |
202 | ||
203 | if (!md_node_get_val(mdp, guestnodep, MDNAME(resource_id), | |
204 | &gid)) { | |
205 | DBG_MAU(c_printf( | |
206 | "Missing resource_id in guest node\n")); | |
207 | *fail_codep = HVctl_e_guest_missing_id; | |
208 | goto fail; | |
209 | } | |
210 | if (gid >= NGUESTS) { | |
211 | DBG_MAU(c_printf( | |
212 | "Invalid resource_id in guest node\n")); | |
213 | *fail_codep = HVctl_e_guest_invalid_id; | |
214 | goto fail; | |
215 | } | |
216 | /* FIXME: check that all cpus belong to same guest */ | |
217 | maup->pip.guestid = gid; | |
218 | } | |
219 | ||
220 | /* Get ino value for this mau */ | |
221 | if (!md_node_get_val(mdp, maunodep, MDNAME(ino), &ino)) { | |
222 | DBG_MAU(c_printf("WARNING: Missing ino in mau node\n")); | |
223 | *fail_codep = HVctl_e_mau_missing_ino; | |
224 | goto fail; | |
225 | } | |
226 | ||
227 | DBG_MAU(c_printf("Virtual mau 0x%x in guest 0x%x ino 0x%x\n", | |
228 | mau_id, gid, ino)); | |
229 | ||
230 | ||
231 | /* | |
232 | * Now determine the delta - if relevent... | |
233 | */ | |
234 | maup->pip.pid = mau_id; | |
235 | maup->pip.ino = ino; | |
236 | ||
237 | /* | |
238 | * We can configure an unconfigured MAU. | |
239 | * Cannot (yet) support the dynamic re-binding of | |
240 | * a configured / running mau, except to modify the | |
241 | * set of vcpus bound to it, which is handled as part of unconfig | |
242 | * or config. | |
243 | */ | |
244 | DBG_MAU(c_printf("\t\tCurrent mau status = 0x%x\n", maup->state)); | |
245 | ||
246 | if (maup->state == MAU_STATE_UNCONFIGURED) { | |
247 | DBG_MAU(c_printf("\t\tElected to config mau\n")); | |
248 | maup->pip.res.flags = RESF_Config; | |
249 | } else { | |
250 | if (maup->pid == maup->pip.pid && | |
251 | maup->guest->guestid == gid && | |
252 | maup->ino == ino && | |
253 | maup->cpuset != maup->pip.cpuset) { | |
254 | DBG_MAU(c_printf("\t\tElected to modify mau\n")); | |
255 | maup->pip.res.flags = RESF_Modify; | |
256 | } else if (maup->pid == maup->pip.pid && | |
257 | maup->guest->guestid == gid && | |
258 | maup->ino == ino) { | |
259 | DBG_MAU(c_printf("\t\tElected to ignore mau\n")); | |
260 | maup->pip.res.flags = RESF_Noop; | |
261 | } else { | |
262 | DBG_MAU(c_printf("\t\tFailed MD update - no " | |
263 | "rebind live\n")); | |
264 | *fail_codep = HVctl_e_mau_rebind_na; | |
265 | goto fail; | |
266 | } | |
267 | } | |
268 | ||
269 | return (HVctl_st_ok); | |
270 | fail:; | |
271 | return (HVctl_st_badmd); | |
272 | } | |
273 | ||
274 | hvctl_status_t | |
275 | res_mau_postparse(hvctl_res_error_t *res_error, int *fail_res_id) | |
276 | { | |
277 | return (HVctl_st_ok); | |
278 | } | |
279 | ||
280 | void | |
281 | res_mau_commit(int flag) | |
282 | { | |
283 | mau_t *mp; | |
284 | int i; | |
285 | ||
286 | mp = config.config_m.maus; | |
287 | ||
288 | for (i = 0; i < NMAUS; i++, mp++) { | |
289 | /* if not this ops turn move on */ | |
290 | DBG_MAU(c_printf("res_mau_commit: mauid 0x%x : state 0x%x : " | |
291 | "flags 0x%x - opflag 0x%x\n", | |
292 | mp->pid, mp->state, mp->pip.res.flags, flag)); | |
293 | ||
294 | if (mp->pip.res.flags != flag) | |
295 | continue; | |
296 | ||
297 | switch (mp->pip.res.flags) { | |
298 | case RESF_Noop: | |
299 | DBG_MAU(c_printf("mau 0x%x : noop\n", i)); | |
300 | break; | |
301 | case RESF_Unconfig: | |
302 | DBG_MAU(c_printf("mau 0x%x : unconfig\n", i)); | |
303 | res_mau_commit_unconfig(mp); | |
304 | break; | |
305 | case RESF_Config: | |
306 | DBG_MAU(c_printf("mau 0x%x : config\n", i)); | |
307 | res_mau_commit_config(mp); | |
308 | break; | |
309 | case RESF_Rebind: | |
310 | DBG_MAU(c_printf("mau 0x%x : rebind\n", i)); | |
311 | ASSERT(0); /* not supported */ | |
312 | break; | |
313 | case RESF_Modify: | |
314 | DBG_MAU(c_printf("mau 0x%x : modify\n", i)); | |
315 | res_mau_commit_modify(mp); | |
316 | break; | |
317 | default: | |
318 | ASSERT(0); | |
319 | } | |
320 | ||
321 | mp->pip.res.flags = RESF_Noop; /* cleanup */ | |
322 | } | |
323 | } | |
324 | ||
325 | bool_t | |
326 | strand_in_vcpu_list(uint64_t strand_id, vcpu_t *vcpu_list, uint64_t *found_idx) | |
327 | { | |
328 | int i; | |
329 | ||
330 | for (i = 0; i < NVCPUS; ++i) { | |
331 | if (vcpu_list[i].strand && vcpu_list[i].strand->id == | |
332 | strand_id) { | |
333 | if (found_idx != NULL) | |
334 | *found_idx = i; | |
335 | return (true); | |
336 | } | |
337 | } | |
338 | return (false); | |
339 | } | |
340 | ||
341 | void | |
342 | res_mau_commit_config(mau_t *maup) | |
343 | { | |
344 | guest_t *guestp; | |
345 | vcpu_t *cpup; | |
346 | uint64_t strand_num, vcpu_num; | |
347 | int i; | |
348 | ||
349 | DBG_MAU(c_printf("res_mau_commit_config\n")); | |
350 | ||
351 | /* | |
352 | * Assign the mau its bound vcpu. | |
353 | * Note: this does not schedule the mau. | |
354 | */ | |
355 | maup->pid = maup->pip.pid; | |
356 | ||
357 | guestp = config.guests; | |
358 | guestp = &(guestp[maup->pip.guestid]); | |
359 | ASSERT(guestp->guestid == maup->pip.guestid); | |
360 | ASSERT(guestp->maus[maup->pid] == NULL); | |
361 | guestp->maus[maup->pid] = maup; | |
362 | ||
363 | /* | |
364 | * Initialise the remainder of the mau struct. Need to do this | |
365 | * once for each cpu bound to this mau. | |
366 | */ | |
367 | ||
368 | /* | |
369 | * Loop through the cpus attached to this mau. | |
370 | * FIXME: make independent of cpu arch | |
371 | */ | |
372 | strand_num = maup->pid << STRANDID_2_COREID_SHIFT; | |
373 | for (i = 0; i < NSTRANDS_PER_CORE; ++i, ++strand_num) { | |
374 | /* Skip cpus not being bound to this mau */ | |
375 | if ((maup->pip.cpuset & (1 << i)) == 0) { | |
376 | DBG_MAU(c_printf("Skipping thread id %d for mau %d " | |
377 | "(pip.cpuset 0x%x)\n", | |
378 | i, maup->pid, maup->pip.cpuset)); | |
379 | continue; | |
380 | } | |
381 | cpup = config.vcpus; | |
382 | ||
383 | /* Convert strand to vid */ | |
384 | if (strand_in_vcpu_list(strand_num, cpup, &vcpu_num)) { | |
385 | cpup = &(cpup[vcpu_num]); | |
386 | } else { | |
387 | DBG_MAU(c_printf( | |
388 | "strand 0x%x not found!\n", strand_num)); | |
389 | c_hvabort(); | |
390 | } | |
391 | ||
392 | cpup->maup = maup; | |
393 | ||
394 | DBG_MAU(c_printf("\tBinding mau (pid = 0x%x) to vcpu 0x%x on " | |
395 | "strand 0x%x in guest 0x%x\n", | |
396 | maup->pid, vcpu_num, strand_num, maup->pip.guestid)); | |
397 | ||
398 | setup_a_mau(cpup, maup, maup->pip.ino); | |
399 | config_a_guest_device_vino(maup->guest, maup->pip.ino, | |
400 | DEVOPS_VDEV); | |
401 | } | |
402 | } | |
403 | ||
404 | void | |
405 | init_mau(mau_t *maup) | |
406 | { | |
407 | #ifdef ERRATA_192 | |
408 | maup->store_in_progr = 0; | |
409 | maup->enable_cwq = 0; | |
410 | #endif | |
411 | maup->queue.mq_base_ra = 0; | |
412 | maup->queue.mq_base = 0; | |
413 | maup->queue.mq_end = 0; | |
414 | maup->queue.mq_head = 0; | |
415 | maup->queue.mq_tail = 0; | |
416 | maup->queue.mq_nentries = 0; | |
417 | maup->queue.mq_busy = 0; | |
418 | } | |
419 | ||
420 | void | |
421 | unconfig_strand_from_mau(mau_t *maup, uint64_t strand_num) | |
422 | { | |
423 | int thread_id; | |
424 | ||
425 | /* | |
426 | * Check if already unconfigured! | |
427 | */ | |
428 | ASSERT(maup->guest->maus[maup->pid] != NULL); | |
429 | ASSERT(maup->state != MAU_STATE_UNCONFIGURED); | |
430 | ||
431 | thread_id = strand_num & NSTRANDS_PER_CORE_MASK; | |
432 | ||
433 | /* | |
434 | * Force the cpu_active entry to 0. | |
435 | * It is possible to come through the unconfig sequence | |
436 | * without having gone through stop_mau. However, we | |
437 | * assured that when we come into unconfig_mau that the | |
438 | * respective cpu is stopped. | |
439 | */ | |
440 | maup->cpu_active[thread_id] = 0; | |
441 | ||
442 | /* | |
443 | * Remove cpu from MAU's cpuset and if this | |
444 | * is the last one, then clear the queue structure. | |
445 | */ | |
446 | DBG_MAU(c_printf( | |
447 | "\tunconfig_strand_from_mau: mau %d thread %d (strand %d) guest %d\n", | |
448 | maup->pid, thread_id, strand_num, maup->guest->guestid)); | |
449 | ||
450 | maup->cpuset &= ~(1 << thread_id); | |
451 | ||
452 | DBG_MAU(c_printf("\tnew cpuset: %d\n", maup->cpuset)); | |
453 | ||
454 | if (maup->cpuset == 0) { | |
455 | init_mau(maup); | |
456 | maup->state = MAU_STATE_UNCONFIGURED; | |
457 | maup->guest->maus[maup->pid] = NULL; | |
458 | maup->guest = NULL; | |
459 | } | |
460 | } | |
461 | ||
462 | void | |
463 | res_mau_commit_unconfig(mau_t *maup) | |
464 | { | |
465 | vcpu_t *cpup; | |
466 | uint64_t strand_num, vcpu_num; | |
467 | int i; | |
468 | ||
469 | ASSERT(maup->state == MAU_STATE_RUNNING || | |
470 | maup->state == MAU_STATE_ERROR); | |
471 | ||
472 | ASSERT(maup->guest != NULL); | |
473 | ||
474 | strand_num = maup->pid << STRANDID_2_COREID_SHIFT; | |
475 | for (i = 0; i < NSTRANDS_PER_CORE; ++i, ++strand_num) { | |
476 | /* Skip cpus not bound to this mau */ | |
477 | if ((maup->cpuset & (1 << i)) == 0) { | |
478 | DBG_MAU(c_printf( | |
479 | "Skipping thread id %d (strand 0x%x) for " | |
480 | "mau %d (cpuset 0x%x)\n", | |
481 | i, strand_num, maup->pid, maup->cpuset)); | |
482 | continue; | |
483 | } | |
484 | ||
485 | cpup = config.vcpus; | |
486 | ||
487 | /* Convert strand to vid */ | |
488 | DBG_MAU(c_printf( | |
489 | "\tUnconfig mau (pid = 0x%x) from strand 0x%x in " | |
490 | "guest 0x%x\n", maup->pid, strand_num, | |
491 | maup->guest->guestid)); | |
492 | ||
493 | if (strand_in_vcpu_list(strand_num, cpup, &vcpu_num)) { | |
494 | cpup = &(cpup[vcpu_num]); | |
495 | DBG_MAU(c_printf("\tstrand 0x%x is vcpu 0x%x\n", | |
496 | strand_num, vcpu_num)); | |
497 | } else { | |
498 | DBG_MAU(c_printf( | |
499 | "strand 0x%x not found!\n", strand_num)); | |
500 | c_hvabort(); | |
501 | } | |
502 | ||
503 | unconfig_a_guest_device_vino(maup->guest, maup->ino, | |
504 | DEVOPS_VDEV); | |
505 | unconfig_strand_from_mau(maup, strand_num); | |
506 | } | |
507 | } | |
508 | ||
509 | vcpu_t * | |
510 | mau_to_vcpu(mau_t *maup, int strand_id) | |
511 | { | |
512 | vcpu_t *cpup; | |
513 | int i; | |
514 | ||
515 | /* | |
516 | * Walk all vcpus bound to guest which owns mau, and find | |
517 | * one with strand_id passed in. | |
518 | */ | |
519 | for (i = 0; i < NVCPUS; ++i) { | |
520 | cpup = maup->guest->vcpus[i]; | |
521 | ||
522 | /* Is vcpu mapped to guest? */ | |
523 | if (cpup == NULL) | |
524 | continue; | |
525 | ||
526 | ASSERT(cpup->strand != NULL); | |
527 | if (cpup->strand->id == strand_id) { | |
528 | DBG_MAU(c_printf( | |
529 | "\tmau_to_vcpu: mau %d strand %d is vcpu %d\n", | |
530 | maup->pid, strand_id, cpup->vid)); | |
531 | return (cpup); | |
532 | } | |
533 | } | |
534 | ||
535 | return (NULL); | |
536 | } | |
537 | ||
538 | /* | |
539 | * The only allowed modification on a mau is the list of vcpus which | |
540 | * are bound to it. | |
541 | */ | |
542 | void | |
543 | res_mau_commit_modify(mau_t *maup) | |
544 | { | |
545 | uint64_t strand_id, thread_id; | |
546 | ||
547 | ASSERT(maup->state == MAU_STATE_RUNNING || | |
548 | maup->state == MAU_STATE_ERROR); | |
549 | ASSERT(maup->guest != NULL); | |
550 | ||
551 | /* | |
552 | * Compare old & new cpusets, configuring or unconfiguring | |
553 | * cpu->mau bindings as appropriate. | |
554 | */ | |
555 | /* | |
556 | * We can't determine which cpu->mau bindings to unconfigure | |
557 | * by walking the available vcpus, as they've already been | |
558 | * unconfigured, so we find them by comparing the old & new | |
559 | * cpuset mask values. | |
560 | */ | |
561 | strand_id = maup->pid << STRANDID_2_COREID_SHIFT; | |
562 | for (thread_id = 0; thread_id < NSTRANDS_PER_CORE; | |
563 | ++thread_id, ++strand_id) { | |
564 | uint64_t mask = 1LL << thread_id; | |
565 | ||
566 | if ((maup->cpuset & mask) == (maup->pip.cpuset & mask)) { | |
567 | DBG_MAU(c_printf( | |
568 | "\tIgnoring mau (pid = 0x%x) on strand " | |
569 | "0x%x in guest 0x%x\n", | |
570 | maup->pid, strand_id, maup->pip.guestid)); | |
571 | continue; | |
572 | } | |
573 | /* Configure? */ | |
574 | if ((maup->pip.cpuset & mask) != 0) { | |
575 | vcpu_t *cpup; | |
576 | ||
577 | cpup = mau_to_vcpu(maup, strand_id); | |
578 | ASSERT(cpup != NULL); | |
579 | cpup->maup = maup; | |
580 | ||
581 | DBG_MAU(c_printf("\tBinding mau (pid = 0x%x) to strand " | |
582 | "0x%x in guest 0x%x\n", | |
583 | maup->pid, strand_id, maup->pip.guestid)); | |
584 | ||
585 | setup_a_mau(cpup, maup, maup->pip.ino); | |
586 | } else { | |
587 | /* Unconfigure */ | |
588 | DBG_MAU(c_printf("\tUnbinding mau %d from strand 0x%x " | |
589 | "in guest 0x%x\n", | |
590 | maup->pid, strand_id, maup->guest->guestid)); | |
591 | unconfig_strand_from_mau(maup, strand_id); | |
592 | } | |
593 | } | |
594 | } | |
595 | ||
596 | /* | |
597 | * Setup an MAU ... | |
598 | * | |
599 | * FIXME: bunch of wierd stuff here .. check this is done right. | |
600 | * This is a copy of config_a_mau in reconf.c. The reconf.c version | |
601 | * will go away when we handle delayed reconfig. | |
602 | */ | |
603 | static void | |
604 | setup_a_mau(vcpu_t *vcpup, mau_t *maup, uint64_t ino) | |
605 | { | |
606 | c_setup_mau(vcpup, ino, &config); | |
607 | maup->guest = vcpup->guest; | |
608 | } | |
609 | ||
610 | /* | |
611 | * Initialise MAUs | |
612 | */ | |
613 | void | |
614 | init_mau_crypto_units() | |
615 | { | |
616 | mau_t *maup; | |
617 | int i, j; | |
618 | ||
619 | config.config_m.maus = &maus[0]; | |
620 | ||
621 | maup = (mau_t *)config.config_m.maus; | |
622 | for (i = 0; i < NMAUS; i++) { | |
623 | maup[i].handle = 0LL; | |
624 | #ifdef ERRATA_192 | |
625 | maup[i].store_in_progr = 0LL; | |
626 | maup[i].enable_cwq = 0LL; | |
627 | #endif | |
628 | maup[i].res_id = i; | |
629 | maup[i].cpuset = 0LL; | |
630 | for (j = 0; j < NSTRANDS_PER_CORE; j++) { | |
631 | maup[i].cpu_active[j] = 0; | |
632 | } | |
633 | maup[i].state = MAU_STATE_UNCONFIGURED; | |
634 | } | |
635 | } | |
636 | ||
637 | #endif |