xref: /kvmtool/builtin-debug.c (revision 7070414a1131552eb8ac0b96db50a88eb939950a)
1 #include <kvm/util.h>
2 #include <kvm/kvm-cmd.h>
3 #include <kvm/builtin-debug.h>
4 #include <kvm/kvm.h>
5 #include <kvm/parse-options.h>
6 #include <kvm/kvm-ipc.h>
7 #include <kvm/read-write.h>
8 
9 #include <stdio.h>
10 #include <string.h>
11 #include <signal.h>
12 
13 #define BUFFER_SIZE 100
14 
15 static bool all;
16 static int instance;
17 static int nmi = -1;
18 static bool dump;
19 static const char *instance_name;
20 
21 static const char * const debug_usage[] = {
22 	"kvm debug [--all] [-n name] [-d] [-m vcpu]",
23 	NULL
24 };
25 
26 static const struct option debug_options[] = {
27 	OPT_GROUP("General options:"),
28 	OPT_BOOLEAN('d', "dump", &dump, "Generate a debug dump from guest"),
29 	OPT_INTEGER('m', "nmi", &nmi, "Generate NMI on VCPU"),
30 	OPT_GROUP("Instance options:"),
31 	OPT_BOOLEAN('a', "all", &all, "Debug all instances"),
32 	OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
33 	OPT_END()
34 };
35 
36 static void parse_debug_options(int argc, const char **argv)
37 {
38 	while (argc != 0) {
39 		argc = parse_options(argc, argv, debug_options, debug_usage,
40 				PARSE_OPT_STOP_AT_NON_OPTION);
41 		if (argc != 0)
42 			kvm_debug_help();
43 	}
44 }
45 
46 void kvm_debug_help(void)
47 {
48 	usage_with_options(debug_usage, debug_options);
49 }
50 
51 static int do_debug(const char *name, int sock)
52 {
53 	char buff[BUFFER_SIZE];
54 	struct debug_cmd cmd = {KVM_IPC_DEBUG, 2 * sizeof(u32)};
55 	int r;
56 
57 	if (dump)
58 		cmd.params.dbg_type |= KVM_DEBUG_CMD_TYPE_DUMP;
59 
60 	if (nmi != -1) {
61 		cmd.params.dbg_type |= KVM_DEBUG_CMD_TYPE_NMI;
62 		cmd.params.cpu = nmi;
63 	}
64 
65 	r = xwrite(sock, &cmd, sizeof(cmd));
66 	if (r < 0)
67 		return r;
68 
69 	if (!dump)
70 		return 0;
71 
72 	do {
73 		r = xread(sock, buff, BUFFER_SIZE);
74 		if (r < 0)
75 			return 0;
76 		printf("%.*s", r, buff);
77 	} while (r > 0);
78 
79 	return 0;
80 }
81 
82 int kvm_cmd_debug(int argc, const char **argv, const char *prefix)
83 {
84 	parse_debug_options(argc, argv);
85 
86 	if (all)
87 		return kvm__enumerate_instances(do_debug);
88 
89 	if (instance_name == NULL &&
90 	    instance == 0)
91 		kvm_debug_help();
92 
93 	if (instance_name)
94 		instance = kvm__get_sock_by_instance(instance_name);
95 
96 	if (instance <= 0)
97 		die("Failed locating instance");
98 
99 	return do_debug(instance_name, instance);
100 }
101