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 nmi = -1;
17 static bool dump;
18 static const char *instance_name;
19 static const char *sysrq;
20
21 static const char * const debug_usage[] = {
22 "lkvm 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_STRING('s', "sysrq", &sysrq, "sysrq", "Inject a sysrq"),
31 OPT_GROUP("Instance options:"),
32 OPT_BOOLEAN('a', "all", &all, "Debug all instances"),
33 OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
34 OPT_END()
35 };
36
parse_debug_options(int argc,const char ** argv)37 static void parse_debug_options(int argc, const char **argv)
38 {
39 while (argc != 0) {
40 argc = parse_options(argc, argv, debug_options, debug_usage,
41 PARSE_OPT_STOP_AT_NON_OPTION);
42 if (argc != 0)
43 kvm_debug_help();
44 }
45 }
46
kvm_debug_help(void)47 void kvm_debug_help(void)
48 {
49 usage_with_options(debug_usage, debug_options);
50 }
51
do_debug(const char * name,int sock)52 static int do_debug(const char *name, int sock)
53 {
54 char buff[BUFFER_SIZE];
55 struct debug_cmd_params cmd = {.dbg_type = 0};
56 int r;
57
58 if (dump)
59 cmd.dbg_type |= KVM_DEBUG_CMD_TYPE_DUMP;
60
61 if (nmi != -1) {
62 cmd.dbg_type |= KVM_DEBUG_CMD_TYPE_NMI;
63 cmd.cpu = nmi;
64 }
65
66 if (sysrq) {
67 cmd.dbg_type |= KVM_DEBUG_CMD_TYPE_SYSRQ;
68 cmd.sysrq = sysrq[0];
69 }
70
71 r = kvm_ipc__send_msg(sock, KVM_IPC_DEBUG, sizeof(cmd), (u8 *)&cmd);
72 if (r < 0)
73 return r;
74
75 if (!dump)
76 return 0;
77
78 do {
79 r = xread(sock, buff, BUFFER_SIZE);
80 if (r < 0)
81 return 0;
82 printf("%.*s", r, buff);
83 } while (r > 0);
84
85 return 0;
86 }
87
kvm_cmd_debug(int argc,const char ** argv,const char * prefix)88 int kvm_cmd_debug(int argc, const char **argv, const char *prefix)
89 {
90 parse_debug_options(argc, argv);
91 int instance;
92 int r;
93
94 if (all)
95 return kvm__enumerate_instances(do_debug);
96
97 if (instance_name == NULL)
98 kvm_debug_help();
99
100 instance = kvm__get_sock_by_instance(instance_name);
101
102 if (instance <= 0)
103 die("Failed locating instance");
104
105 r = do_debug(instance_name, instance);
106
107 close(instance);
108
109 return r;
110 }
111