xref: /illumos-gate/usr/src/test/bhyve-tests/tests/vmm/self_destruct.c (revision b8052df9f609edb713f6828c9eecc3d7be19dfb3)
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 2022 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 
26 #include <sys/vmm.h>
27 #include <sys/vmm_dev.h>
28 #include <vmmapi.h>
29 
30 #include "common.h"
31 
32 int
33 main(int argc, char *argv[])
34 {
35 	const char *suite_name = basename(argv[0]);
36 	struct vmctx *ctx;
37 
38 	ctx = create_test_vm(suite_name);
39 	if (ctx == NULL) {
40 		errx(EXIT_FAILURE, "could open test VM");
41 	}
42 
43 	/*
44 	 * It would be odd if we had the freshly created VM instance, but it did
45 	 * not appear to exist.
46 	 */
47 	assert(check_instance_usable(suite_name));
48 
49 	/* Ensure sure that auto-destruct is off */
50 	if (ioctl(vm_get_device_fd(ctx), VM_SET_AUTODESTRUCT, 0) != 0) {
51 		errx(EXIT_FAILURE, "could not disable auto-destruct");
52 	}
53 
54 	if (ioctl(vm_get_device_fd(ctx), VM_DESTROY_SELF, 0) != 0) {
55 		errx(EXIT_FAILURE, "ioctl(VM_DESTROY_SELF) failed");
56 	}
57 
58 	/*
59 	 * Since we still hold the instance open, we expect it to still exist in
60 	 * /dev/vmm, but be useless for further operations
61 	 */
62 	if (!check_instance_exists(suite_name)) {
63 		err(EXIT_FAILURE,
64 		    "instance missing after unfinished destroy");
65 	}
66 
67 	/* Attempt an operation on our still-open handle */
68 	uint64_t reg = 0;
69 	if (vm_get_register(ctx, 0, VM_REG_GUEST_RAX, &reg) == 0) {
70 		err(EXIT_FAILURE,
71 		    "VM_GET_REGISTER succeeded despite instance destruction");
72 	}
73 	/* Check usability via the dedicated ioctl */
74 	if (check_instance_usable(suite_name)) {
75 		err(EXIT_FAILURE,
76 		    "instance not reporting in-progress destruction");
77 	}
78 
79 
80 	vm_close(ctx);
81 	ctx = NULL;
82 
83 	/* Make doubly-sure the VM is gone after close */
84 	if (check_instance_exists(suite_name)) {
85 		err(EXIT_FAILURE, "instance still accessible after destroy");
86 	}
87 
88 	(void) printf("%s\tPASS\n", suite_name);
89 	return (EXIT_SUCCESS);
90 }
91