1 /*
2 * Copyright 2009-2017 Citrix Ltd and other contributors
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; version 2.1 only. with the special
7 * exception on linking described in file LICENSE.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 */
14
15 #include <ctype.h>
16 #include <inttypes.h>
17 #include <stdlib.h>
18 #include <unistd.h>
19
20 #include <libxl.h>
21 #include <libxl_utils.h>
22 #include <libxlutil.h>
23
24 #include "xl.h"
25 #include "xl_utils.h"
26 #include "xl_parse.h"
27
psr_cmt_hwinfo(void)28 static int psr_cmt_hwinfo(void)
29 {
30 int rc;
31 int enabled;
32 uint32_t total_rmid;
33
34 printf("Cache Monitoring Technology (CMT):\n");
35
36 enabled = libxl_psr_cmt_enabled(ctx);
37 printf("%-16s: %s\n", "Enabled", enabled ? "1" : "0");
38 if (!enabled)
39 return 0;
40
41 rc = libxl_psr_cmt_get_total_rmid(ctx, &total_rmid);
42 if (rc) {
43 fprintf(stderr, "Failed to get max RMID value\n");
44 return rc;
45 }
46 printf("%-16s: %u\n", "Total RMID", total_rmid);
47
48 printf("Supported monitor types:\n");
49 if (libxl_psr_cmt_type_supported(ctx, LIBXL_PSR_CMT_TYPE_CACHE_OCCUPANCY))
50 printf("cache-occupancy\n");
51 if (libxl_psr_cmt_type_supported(ctx, LIBXL_PSR_CMT_TYPE_TOTAL_MEM_COUNT))
52 printf("total-mem-bandwidth\n");
53 if (libxl_psr_cmt_type_supported(ctx, LIBXL_PSR_CMT_TYPE_LOCAL_MEM_COUNT))
54 printf("local-mem-bandwidth\n");
55
56 return rc;
57 }
58
59 #define MBM_SAMPLE_RETRY_MAX 4
psr_cmt_get_mem_bandwidth(uint32_t domid,libxl_psr_cmt_type type,uint32_t socketid,uint64_t * bandwidth_r)60 static int psr_cmt_get_mem_bandwidth(uint32_t domid,
61 libxl_psr_cmt_type type,
62 uint32_t socketid,
63 uint64_t *bandwidth_r)
64 {
65 uint64_t sample1, sample2;
66 uint64_t tsc1, tsc2;
67 int retry_attempts = 0;
68 int rc;
69
70 while (1) {
71 rc = libxl_psr_cmt_get_sample(ctx, domid, type, socketid,
72 &sample1, &tsc1);
73 if (rc < 0)
74 return rc;
75
76 usleep(10000);
77
78 rc = libxl_psr_cmt_get_sample(ctx, domid, type, socketid,
79 &sample2, &tsc2);
80 if (rc < 0)
81 return rc;
82
83 if (tsc2 <= tsc1)
84 return -1;
85
86 /*
87 * Hardware guarantees at most 1 overflow can happen if the duration
88 * between two samples is less than 1 second. Note that tsc returned
89 * from hypervisor is already-scaled time(ns).
90 */
91 if (tsc2 - tsc1 < 1000000000 && sample2 >= sample1)
92 break;
93
94 if (retry_attempts < MBM_SAMPLE_RETRY_MAX) {
95 retry_attempts++;
96 } else {
97 fprintf(stderr, "event counter overflowed\n");
98 return -1;
99 }
100 }
101
102 *bandwidth_r = (sample2 - sample1) * 1000000000 / (tsc2 - tsc1) / 1024;
103 return 0;
104 }
105
psr_cmt_print_domain_info(libxl_dominfo * dominfo,libxl_psr_cmt_type type,libxl_bitmap * socketmap)106 static void psr_cmt_print_domain_info(libxl_dominfo *dominfo,
107 libxl_psr_cmt_type type,
108 libxl_bitmap *socketmap)
109 {
110 char *domain_name;
111 uint32_t socketid;
112 uint64_t monitor_data;
113
114 if (!libxl_psr_cmt_domain_attached(ctx, dominfo->domid))
115 return;
116
117 domain_name = libxl_domid_to_name(ctx, dominfo->domid);
118 printf("%-40s %5d", domain_name, dominfo->domid);
119 free(domain_name);
120
121 libxl_for_each_set_bit(socketid, *socketmap) {
122 switch (type) {
123 case LIBXL_PSR_CMT_TYPE_CACHE_OCCUPANCY:
124 if (!libxl_psr_cmt_get_sample(ctx, dominfo->domid, type, socketid,
125 &monitor_data, NULL))
126 printf("%13"PRIu64" KB", monitor_data / 1024);
127 break;
128 case LIBXL_PSR_CMT_TYPE_TOTAL_MEM_COUNT:
129 case LIBXL_PSR_CMT_TYPE_LOCAL_MEM_COUNT:
130 if (!psr_cmt_get_mem_bandwidth(dominfo->domid, type, socketid,
131 &monitor_data))
132 printf("%11"PRIu64" KB/s", monitor_data);
133 break;
134 default:
135 return;
136 }
137 }
138
139 printf("\n");
140 }
141
psr_cmt_show(libxl_psr_cmt_type type,uint32_t domid)142 static int psr_cmt_show(libxl_psr_cmt_type type, uint32_t domid)
143 {
144 uint32_t i, socketid, total_rmid;
145 uint32_t l3_cache_size;
146 libxl_bitmap socketmap;
147 int rc, nr_domains;
148
149 if (!libxl_psr_cmt_enabled(ctx)) {
150 fprintf(stderr, "CMT is disabled in the system\n");
151 return -1;
152 }
153
154 if (!libxl_psr_cmt_type_supported(ctx, type)) {
155 fprintf(stderr, "Monitor type '%s' is not supported in the system\n",
156 libxl_psr_cmt_type_to_string(type));
157 return -1;
158 }
159
160 libxl_bitmap_init(&socketmap);
161 libxl_socket_bitmap_alloc(ctx, &socketmap, 0);
162 rc = libxl_get_online_socketmap(ctx, &socketmap);
163 if (rc < 0) {
164 fprintf(stderr, "Failed getting available sockets, rc: %d\n", rc);
165 goto out;
166 }
167
168 rc = libxl_psr_cmt_get_total_rmid(ctx, &total_rmid);
169 if (rc < 0) {
170 fprintf(stderr, "Failed to get max RMID value\n");
171 goto out;
172 }
173
174 printf("Total RMID: %d\n", total_rmid);
175
176 /* Header */
177 printf("%-40s %5s", "Name", "ID");
178 libxl_for_each_set_bit(socketid, socketmap)
179 printf("%14s %d", "Socket", socketid);
180 printf("\n");
181
182 if (type == LIBXL_PSR_CMT_TYPE_CACHE_OCCUPANCY) {
183 /* Total L3 cache size */
184 printf("%-46s", "Total L3 Cache Size");
185 libxl_for_each_set_bit(socketid, socketmap) {
186 rc = libxl_psr_cmt_get_l3_cache_size(ctx, socketid,
187 &l3_cache_size);
188 if (rc < 0) {
189 fprintf(stderr,
190 "Failed to get system l3 cache size for socket:%d\n",
191 socketid);
192 goto out;
193 }
194 printf("%13u KB", l3_cache_size);
195 }
196 printf("\n");
197 }
198
199 /* Each domain */
200 if (domid != INVALID_DOMID) {
201 libxl_dominfo dominfo;
202
203 libxl_dominfo_init(&dominfo);
204 if (libxl_domain_info(ctx, &dominfo, domid)) {
205 fprintf(stderr, "Failed to get domain info for %d\n", domid);
206 rc = -1;
207 goto out;
208 }
209 psr_cmt_print_domain_info(&dominfo, type, &socketmap);
210 libxl_dominfo_dispose(&dominfo);
211 }
212 else
213 {
214 libxl_dominfo *list;
215 if (!(list = libxl_list_domain(ctx, &nr_domains))) {
216 fprintf(stderr, "Failed to get domain info for domain list.\n");
217 rc = -1;
218 goto out;
219 }
220 for (i = 0; i < nr_domains; i++)
221 psr_cmt_print_domain_info(list + i, type, &socketmap);
222 libxl_dominfo_list_free(list, nr_domains);
223 }
224
225 out:
226 libxl_bitmap_dispose(&socketmap);
227 return rc;
228 }
229
main_psr_cmt_attach(int argc,char ** argv)230 int main_psr_cmt_attach(int argc, char **argv)
231 {
232 uint32_t domid;
233 int opt, ret = 0;
234
235 SWITCH_FOREACH_OPT(opt, "", NULL, "psr-cmt-attach", 1) {
236 /* No options */
237 }
238
239 domid = find_domain(argv[optind]);
240 ret = libxl_psr_cmt_attach(ctx, domid);
241
242 return ret;
243 }
244
main_psr_cmt_detach(int argc,char ** argv)245 int main_psr_cmt_detach(int argc, char **argv)
246 {
247 uint32_t domid;
248 int opt, ret = 0;
249
250 SWITCH_FOREACH_OPT(opt, "", NULL, "psr-cmt-detach", 1) {
251 /* No options */
252 }
253
254 domid = find_domain(argv[optind]);
255 ret = libxl_psr_cmt_detach(ctx, domid);
256
257 return ret;
258 }
259
main_psr_cmt_show(int argc,char ** argv)260 int main_psr_cmt_show(int argc, char **argv)
261 {
262 int opt, ret = 0;
263 uint32_t domid;
264 libxl_psr_cmt_type type;
265
266 SWITCH_FOREACH_OPT(opt, "", NULL, "psr-cmt-show", 1) {
267 /* No options */
268 }
269
270 if (!strcmp(argv[optind], "cache-occupancy"))
271 type = LIBXL_PSR_CMT_TYPE_CACHE_OCCUPANCY;
272 else if (!strcmp(argv[optind], "total-mem-bandwidth"))
273 type = LIBXL_PSR_CMT_TYPE_TOTAL_MEM_COUNT;
274 else if (!strcmp(argv[optind], "local-mem-bandwidth"))
275 type = LIBXL_PSR_CMT_TYPE_LOCAL_MEM_COUNT;
276 else {
277 help("psr-cmt-show");
278 return 2;
279 }
280
281 if (optind + 1 >= argc)
282 domid = INVALID_DOMID;
283 else if (optind + 1 == argc - 1)
284 domid = find_domain(argv[optind + 1]);
285 else {
286 help("psr-cmt-show");
287 return 2;
288 }
289
290 ret = psr_cmt_show(type, domid);
291
292 return ret;
293 }
294
psr_l3_cat_hwinfo(void)295 static int psr_l3_cat_hwinfo(void)
296 {
297 int rc;
298 unsigned int i, nr;
299 uint32_t l3_cache_size;
300 libxl_psr_cat_info *info;
301
302 rc = libxl_psr_cat_get_info(ctx, &info, &nr, 3);
303 if (rc)
304 return rc;
305
306 printf("Cache Allocation Technology (CAT):\n");
307
308 for (i = 0; i < nr; i++) {
309 rc = libxl_psr_cmt_get_l3_cache_size(ctx, info[i].id, &l3_cache_size);
310 if (rc) {
311 fprintf(stderr, "Failed to get l3 cache size for socket:%d\n",
312 info[i].id);
313 goto out;
314 }
315 printf("%-16s: %u\n", "Socket ID", info[i].id);
316 printf("%-16s: %uKB\n", "L3 Cache", l3_cache_size);
317 printf("%-16s: %s\n", "CDP Status",
318 info[i].cdp_enabled ? "Enabled" : "Disabled");
319 printf("%-16s: %u\n", "Maximum COS", info[i].cos_max);
320 printf("%-16s: %u\n", "CBM length", info[i].cbm_len);
321 printf("%-16s: %#llx\n", "Default CBM",
322 (1ull << info[i].cbm_len) - 1);
323 }
324
325 out:
326 libxl_psr_cat_info_list_free(info, nr);
327 return rc;
328 }
329
psr_print_one_domain_val_type(uint32_t domid,libxl_psr_hw_info * info,libxl_psr_type type)330 static void psr_print_one_domain_val_type(uint32_t domid,
331 libxl_psr_hw_info *info,
332 libxl_psr_type type)
333 {
334 uint64_t val;
335
336 if (!libxl_psr_get_val(ctx, domid, type, info->id, &val)) {
337 if (type == LIBXL_PSR_CBM_TYPE_MBA_THRTL && info->u.mba.linear)
338 printf("%16"PRIu64, val);
339 else
340 printf("%#16"PRIx64, val);
341 }
342 else
343 printf("%16s", "error");
344 }
345
psr_print_one_domain_val(uint32_t domid,libxl_psr_hw_info * info,libxl_psr_feat_type type,unsigned int lvl)346 static void psr_print_one_domain_val(uint32_t domid,
347 libxl_psr_hw_info *info,
348 libxl_psr_feat_type type,
349 unsigned int lvl)
350 {
351 char *domain_name;
352
353 domain_name = libxl_domid_to_name(ctx, domid);
354 printf("%5d%25s", domid, domain_name);
355 free(domain_name);
356
357 switch (type) {
358 case LIBXL_PSR_FEAT_TYPE_CAT:
359 switch (lvl) {
360 case 3:
361 if (!info->u.cat.cdp_enabled) {
362 psr_print_one_domain_val_type(domid, info,
363 LIBXL_PSR_CBM_TYPE_L3_CBM);
364 } else {
365 psr_print_one_domain_val_type(domid, info,
366 LIBXL_PSR_CBM_TYPE_L3_CBM_CODE);
367 psr_print_one_domain_val_type(domid, info,
368 LIBXL_PSR_CBM_TYPE_L3_CBM_DATA);
369 }
370 break;
371
372 case 2:
373 psr_print_one_domain_val_type(domid, info,
374 LIBXL_PSR_CBM_TYPE_L2_CBM);
375 break;
376
377 default:
378 printf("Input lvl %d is wrong!", lvl);
379 }
380 break;
381
382 case LIBXL_PSR_FEAT_TYPE_MBA:
383 psr_print_one_domain_val_type(domid, info,
384 LIBXL_PSR_CBM_TYPE_MBA_THRTL);
385 break;
386 }
387
388 printf("\n");
389 }
390
psr_print_domain_val(uint32_t domid,libxl_psr_hw_info * info,libxl_psr_feat_type type,unsigned int lvl)391 static int psr_print_domain_val(uint32_t domid,
392 libxl_psr_hw_info *info,
393 libxl_psr_feat_type type,
394 unsigned int lvl)
395 {
396 int i, nr_domains;
397 libxl_dominfo *list;
398
399 if (domid != INVALID_DOMID) {
400 psr_print_one_domain_val(domid, info, type, lvl);
401 return 0;
402 }
403
404 if (!(list = libxl_list_domain(ctx, &nr_domains))) {
405 fprintf(stderr, "Failed to get domain list for value display\n");
406 return EXIT_FAILURE;
407 }
408
409 for (i = 0; i < nr_domains; i++)
410 psr_print_one_domain_val(list[i].domid, info, type, lvl);
411 libxl_dominfo_list_free(list, nr_domains);
412
413 return 0;
414 }
415
psr_print_socket(uint32_t domid,libxl_psr_hw_info * info,libxl_psr_feat_type type,unsigned int lvl)416 static int psr_print_socket(uint32_t domid,
417 libxl_psr_hw_info *info,
418 libxl_psr_feat_type type,
419 unsigned int lvl)
420 {
421 printf("%-16s: %u\n", "Socket ID", info->id);
422
423 switch (type) {
424 case LIBXL_PSR_FEAT_TYPE_CAT:
425 {
426 int rc;
427 uint32_t l3_cache_size;
428
429 /* So far, CMT only supports L3 cache. */
430 if (lvl == 3) {
431 rc = libxl_psr_cmt_get_l3_cache_size(ctx, info->id, &l3_cache_size);
432 if (rc) {
433 fprintf(stderr, "Failed to get l3 cache size for socket:%d\n",
434 info->id);
435 return -1;
436 }
437 printf("%-16s: %uKB\n", "L3 Cache", l3_cache_size);
438 }
439
440 printf("%-16s: %#llx\n", "Default CBM",
441 (1ull << info->u.cat.cbm_len) - 1);
442 if (info->u.cat.cdp_enabled)
443 printf("%5s%25s%16s%16s\n", "ID", "NAME", "CBM (code)", "CBM (data)");
444 else
445 printf("%5s%25s%16s\n", "ID", "NAME", "CBM");
446
447 break;
448 }
449
450 case LIBXL_PSR_FEAT_TYPE_MBA:
451 printf("%-16s: %u\n", "Default THRTL", 0);
452 printf("%5s%25s%16s\n", "ID", "NAME", "THRTL");
453 break;
454
455 default:
456 fprintf(stderr, "Input feature type %d is wrong\n", type);
457 return EXIT_FAILURE;
458 }
459
460 return psr_print_domain_val(domid, info, type, lvl);
461 }
462
psr_val_show(uint32_t domid,libxl_psr_feat_type type,unsigned int lvl)463 static int psr_val_show(uint32_t domid,
464 libxl_psr_feat_type type,
465 unsigned int lvl)
466 {
467 unsigned int i, nr;
468 int rc;
469 libxl_psr_hw_info *info;
470
471 switch (type) {
472 case LIBXL_PSR_FEAT_TYPE_CAT:
473 if (lvl != 2 && lvl != 3) {
474 fprintf(stderr, "Input lvl %d is wrong\n", lvl);
475 return EXIT_FAILURE;
476 }
477 break;
478
479 case LIBXL_PSR_FEAT_TYPE_MBA:
480 if (lvl) {
481 fprintf(stderr,
482 "Unexpected lvl parameter %d for MBA feature\n", lvl);
483 return EXIT_FAILURE;
484 }
485 break;
486
487 default:
488 fprintf(stderr, "Input feature type %d is wrong\n", type);
489 return EXIT_FAILURE;
490 }
491
492 rc = libxl_psr_get_hw_info(ctx, type, lvl, &nr, &info);
493 if (rc) {
494 fprintf(stderr, "Failed to get info\n");
495 return rc;
496 }
497
498 for (i = 0; i < nr; i++) {
499 rc = psr_print_socket(domid, info + i, type, lvl);
500 if (rc)
501 goto out;
502 }
503
504 out:
505 libxl_psr_hw_info_list_free(info, nr);
506 return rc;
507 }
508
psr_l2_cat_hwinfo(void)509 static int psr_l2_cat_hwinfo(void)
510 {
511 int rc;
512 unsigned int i, nr;
513 libxl_psr_cat_info *info;
514
515 rc = libxl_psr_cat_get_info(ctx, &info, &nr, 2);
516 if (rc)
517 return rc;
518
519 printf("Cache Allocation Technology (CAT): L2\n");
520
521 for (i = 0; i < nr; i++) {
522 /* There is no CMT on L2 cache so far. */
523 printf("%-16s: %u\n", "Socket ID", info[i].id);
524 printf("%-16s: %u\n", "Maximum COS", info[i].cos_max);
525 printf("%-16s: %u\n", "CBM length", info[i].cbm_len);
526 printf("%-16s: %#llx\n", "Default CBM",
527 (1ull << info[i].cbm_len) - 1);
528 }
529
530 libxl_psr_cat_info_list_free(info, nr);
531 return rc;
532 }
533
main_psr_mba_show(int argc,char ** argv)534 int main_psr_mba_show(int argc, char **argv)
535 {
536 int opt;
537 uint32_t domid;
538
539 SWITCH_FOREACH_OPT(opt, "", NULL, "psr-mba-show", 0) {
540 /* No options */
541 }
542
543 if (optind >= argc)
544 domid = INVALID_DOMID;
545 else if (optind == argc - 1)
546 domid = find_domain(argv[optind]);
547 else {
548 help("psr-mba-show");
549 return 2;
550 }
551
552 return psr_val_show(domid, LIBXL_PSR_FEAT_TYPE_MBA, 0);
553 }
554
main_psr_mba_set(int argc,char ** argv)555 int main_psr_mba_set(int argc, char **argv)
556 {
557 uint32_t domid;
558 libxl_psr_type type;
559 uint64_t thrtl;
560 int ret, opt = 0;
561 libxl_bitmap target_map;
562 char *value;
563 libxl_string_list socket_list;
564 unsigned long start, end;
565 unsigned int i, j, len;
566
567 static const struct option opts[] = {
568 {"socket", 1, 0, 's'},
569 COMMON_LONG_OPTS
570 };
571
572 libxl_socket_bitmap_alloc(ctx, &target_map, 0);
573 libxl_bitmap_set_none(&target_map);
574
575 SWITCH_FOREACH_OPT(opt, "s:", opts, "psr-mba-set", 0) {
576 case 's':
577 trim(isspace, optarg, &value);
578 split_string_into_string_list(value, ",", &socket_list);
579 len = libxl_string_list_length(&socket_list);
580 for (i = 0; i < len; i++) {
581 parse_range(socket_list[i], &start, &end);
582 for (j = start; j <= end; j++)
583 libxl_bitmap_set(&target_map, j);
584 }
585
586 libxl_string_list_dispose(&socket_list);
587 free(value);
588 break;
589 }
590
591 type = LIBXL_PSR_CBM_TYPE_MBA_THRTL;
592
593 if (libxl_bitmap_is_empty(&target_map))
594 libxl_bitmap_set_any(&target_map);
595
596 if (argc != optind + 2) {
597 help("psr-mba-set");
598 return EXIT_FAILURE;
599 }
600
601 domid = find_domain(argv[optind]);
602 thrtl = strtoll(argv[optind + 1], NULL , 0);
603
604 ret = libxl_psr_set_val(ctx, domid, type, &target_map, thrtl);
605
606 libxl_bitmap_dispose(&target_map);
607 return ret;
608 }
609
psr_mba_hwinfo(void)610 static int psr_mba_hwinfo(void)
611 {
612 int rc;
613 unsigned int i, nr;
614 libxl_psr_hw_info *info;
615
616 rc = libxl_psr_get_hw_info(ctx, LIBXL_PSR_FEAT_TYPE_MBA, 0, &nr, &info);
617 if (rc)
618 return rc;
619
620 printf("Memory Bandwidth Allocation (MBA):\n");
621
622 for (i = 0; i < nr; i++) {
623 printf("Socket ID : %u\n", info[i].id);
624 printf("Linear Mode : %s\n",
625 info[i].u.mba.linear ? "Enabled" : "Disabled");
626 printf("Maximum COS : %u\n", info[i].u.mba.cos_max);
627 printf("Maximum Throttling Value: %u\n", info[i].u.mba.thrtl_max);
628 printf("Default Throttling Value: %u\n", 0);
629 }
630
631 libxl_psr_hw_info_list_free(info, nr);
632 return rc;
633 }
634
main_psr_cat_cbm_set(int argc,char ** argv)635 int main_psr_cat_cbm_set(int argc, char **argv)
636 {
637 uint32_t domid;
638 libxl_psr_cbm_type type;
639 uint64_t cbm;
640 int ret, opt = 0;
641 int opt_data = 0, opt_code = 0;
642 libxl_bitmap target_map;
643 char *value;
644 libxl_string_list socket_list;
645 unsigned long start, end;
646 unsigned int i, j, len;
647 unsigned int lvl = 3;
648
649 static struct option opts[] = {
650 {"socket", 1, 0, 's'},
651 {"data", 0, 0, 'd'},
652 {"code", 0, 0, 'c'},
653 {"level", 1, 0, 'l'},
654 COMMON_LONG_OPTS
655 };
656
657 libxl_socket_bitmap_alloc(ctx, &target_map, 0);
658 libxl_bitmap_set_none(&target_map);
659
660 SWITCH_FOREACH_OPT(opt, "s:l:cd", opts, "psr-cat-set", 2) {
661 case 's':
662 trim(isspace, optarg, &value);
663 split_string_into_string_list(value, ",", &socket_list);
664 len = libxl_string_list_length(&socket_list);
665 for (i = 0; i < len; i++) {
666 parse_range(socket_list[i], &start, &end);
667 for (j = start; j <= end; j++)
668 libxl_bitmap_set(&target_map, j);
669 }
670
671 libxl_string_list_dispose(&socket_list);
672 free(value);
673 break;
674 case 'd':
675 opt_data = 1;
676 break;
677 case 'c':
678 opt_code = 1;
679 break;
680 case 'l':
681 lvl = atoi(optarg);
682 break;
683 }
684
685 if (lvl == 2)
686 type = LIBXL_PSR_CBM_TYPE_L2_CBM;
687 else if (lvl == 3) {
688 if (opt_data && opt_code) {
689 fprintf(stderr, "Cannot handle -c and -d at the same time\n");
690 return EXIT_FAILURE;
691 } else if (opt_data) {
692 type = LIBXL_PSR_CBM_TYPE_L3_CBM_DATA;
693 } else if (opt_code) {
694 type = LIBXL_PSR_CBM_TYPE_L3_CBM_CODE;
695 } else {
696 type = LIBXL_PSR_CBM_TYPE_L3_CBM;
697 }
698 } else {
699 type = LIBXL_PSR_CBM_TYPE_L3_CBM;
700 fprintf(stderr, "Input lvl %d is wrong\n", lvl);
701 return EXIT_FAILURE;
702 }
703
704 if (libxl_bitmap_is_empty(&target_map))
705 libxl_bitmap_set_any(&target_map);
706
707 if (argc != optind + 2) {
708 help("psr-cat-set");
709 return 2;
710 }
711
712 domid = find_domain(argv[optind]);
713 cbm = strtoll(argv[optind + 1], NULL , 0);
714
715 ret = libxl_psr_cat_set_cbm(ctx, domid, type, &target_map, cbm);
716
717 libxl_bitmap_dispose(&target_map);
718 return ret;
719 }
720
main_psr_cat_show(int argc,char ** argv)721 int main_psr_cat_show(int argc, char **argv)
722 {
723 int opt = 0;
724 uint32_t domid;
725 unsigned int lvl = 3;
726
727 static struct option opts[] = {
728 {"level", 1, 0, 'l'},
729 COMMON_LONG_OPTS
730 };
731
732 SWITCH_FOREACH_OPT(opt, "l:", opts, "psr-cat-show", 0) {
733 case 'l':
734 lvl = atoi(optarg);
735 break;
736 }
737
738 if (optind >= argc)
739 domid = INVALID_DOMID;
740 else if (optind == argc - 1)
741 domid = find_domain(argv[optind]);
742 else {
743 help("psr-cat-show");
744 return 2;
745 }
746
747 return psr_val_show(domid, LIBXL_PSR_FEAT_TYPE_CAT, lvl);
748 }
749
main_psr_hwinfo(int argc,char ** argv)750 int main_psr_hwinfo(int argc, char **argv)
751 {
752 int opt, ret = 0;
753 bool all = true, cmt = false, cat = false, mba = false;
754 static const struct option opts[] = {
755 {"cmt", 0, 0, 'm'},
756 {"cat", 0, 0, 'a'},
757 {"mba", 0, 0, 'b'},
758 COMMON_LONG_OPTS
759 };
760
761 SWITCH_FOREACH_OPT(opt, "mab", opts, "psr-hwinfo", 0) {
762 case 'm':
763 all = false; cmt = true;
764 break;
765 case 'a':
766 all = false; cat = true;
767 break;
768 case 'b':
769 all = false; mba = true;
770 break;
771 }
772
773 if (!ret && (all || cmt))
774 ret = psr_cmt_hwinfo();
775
776 if (!ret && (all || cat))
777 ret = psr_l3_cat_hwinfo();
778
779 /* L2 CAT is independent of CMT and L3 CAT */
780 if (all || cat)
781 ret = psr_l2_cat_hwinfo();
782
783 /* MBA is independent of CMT and CAT */
784 if (all || mba)
785 ret = psr_mba_hwinfo();
786
787 return ret;
788 }
789
790 /*
791 * Local variables:
792 * mode: C
793 * c-basic-offset: 4
794 * indent-tabs-mode: nil
795 * End:
796 */
797