xref: /illumos-gate/usr/src/test/bhyve-tests/tests/vmm/maxcpu.c (revision b934d23b0fe0a56a5b0d2880f2c3d602f15b5cf2)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2023 Oxide Computer Company
14  */
15 
16 #include <stdio.h>
17 #include <unistd.h>
18 #include <stdlib.h>
19 #include <fcntl.h>
20 #include <libgen.h>
21 #include <sys/stat.h>
22 #include <errno.h>
23 #include <err.h>
24 #include <assert.h>
25 #include <sys/sysmacros.h>
26 #include <stdbool.h>
27 
28 #include <sys/vmm.h>
29 #include <sys/vmm_dev.h>
30 #include <sys/vmm_data.h>
31 #include <vmmapi.h>
32 
33 #include "common.h"
34 
35 int
36 main(int argc, char *argv[])
37 {
38 	const char *suite_name = basename(argv[0]);
39 	struct vmctx *ctx;
40 
41 	ctx = create_test_vm(suite_name);
42 	if (ctx == NULL) {
43 		errx(EXIT_FAILURE, "could not open test VM");
44 	}
45 
46 	/* Query VM_MAXCPU equivalent via VM topology */
47 	uint16_t sockets, cores, threads, maxcpus;
48 	if (vm_get_topology(ctx, &sockets, &cores, &threads, &maxcpus) != 0) {
49 		err(EXIT_FAILURE,
50 		    "cound not query maxcpu via vm_get_topology()");
51 	}
52 
53 	/* Check that all valid vCPUs can be activated... */
54 	for (int i = 0; i < maxcpus; i++) {
55 		if (vm_activate_cpu(ctx, i) != 0) {
56 			err(EXIT_FAILURE, "could not activate vcpu %d", i);
57 		}
58 	}
59 
60 	/* ... And that we can do something basic (like read a register) */
61 	for (int i = 0; i < maxcpus; i++) {
62 		uint64_t val = 0;
63 
64 		if (vm_get_register(ctx, i, VM_REG_GUEST_RAX, &val) != 0) {
65 			err(EXIT_FAILURE, "could not read %%rax on vcpu %d", i);
66 		}
67 	}
68 
69 	/* Check some bogus inputs as well */
70 	const int bad_inputs[] = {-1, maxcpus, maxcpus + 1};
71 	for (uint_t i = 0; i < ARRAY_SIZE(bad_inputs); i++) {
72 		const int vcpu = bad_inputs[i];
73 		uint64_t val = 0;
74 
75 		if (vm_activate_cpu(ctx, vcpu) == 0) {
76 			errx(EXIT_FAILURE,
77 			    "unexpected activation for invalid vcpu %d");
78 		}
79 		if (vm_get_register(ctx, vcpu, VM_REG_GUEST_RAX, &val) == 0) {
80 			errx(EXIT_FAILURE,
81 			    "unexpected get_register for invalid vcpu %d");
82 		}
83 	}
84 
85 	vm_destroy(ctx);
86 	(void) printf("%s\tPASS\n", suite_name);
87 	return (EXIT_SUCCESS);
88 }
89