Mirror of strace – the linux syscall tracer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

kvm.c 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. /*
  2. * Support for decoding of KVM_* ioctl commands.
  3. *
  4. * Copyright (c) 2017 Masatake YAMATO <yamato@redhat.com>
  5. * Copyright (c) 2017 Red Hat, Inc.
  6. * Copyright (c) 2017-2018 The strace developers.
  7. * All rights reserved.
  8. *
  9. * SPDX-License-Identifier: LGPL-2.1-or-later
  10. */
  11. #include "defs.h"
  12. #ifdef HAVE_LINUX_KVM_H
  13. # include <linux/kvm.h>
  14. # include "print_fields.h"
  15. # include "arch_kvm.c"
  16. # include "xmalloc.h"
  17. # include "mmap_cache.h"
  18. struct vcpu_info {
  19. struct vcpu_info *next;
  20. int fd;
  21. int cpuid;
  22. long mmap_addr;
  23. unsigned long mmap_len;
  24. bool resolved;
  25. };
  26. static bool dump_kvm_run_structure;
  27. static struct vcpu_info *
  28. vcpu_find(struct tcb *const tcp, int fd)
  29. {
  30. for (struct vcpu_info *vcpu_info = tcp->vcpu_info_list;
  31. vcpu_info;
  32. vcpu_info = vcpu_info->next)
  33. if (vcpu_info->fd == fd)
  34. return vcpu_info;
  35. return NULL;
  36. }
  37. static struct vcpu_info *
  38. vcpu_alloc(struct tcb *const tcp, int fd, int cpuid)
  39. {
  40. struct vcpu_info *vcpu_info = xzalloc(sizeof(*vcpu_info));
  41. vcpu_info->fd = fd;
  42. vcpu_info->cpuid = cpuid;
  43. vcpu_info->next = tcp->vcpu_info_list;
  44. tcp->vcpu_info_list = vcpu_info;
  45. return vcpu_info;
  46. }
  47. void
  48. kvm_vcpu_info_free(struct tcb *tcp)
  49. {
  50. struct vcpu_info *head, *next;
  51. for (head = tcp->vcpu_info_list; head; head = next) {
  52. next = head->next;
  53. free(head);
  54. }
  55. tcp->vcpu_info_list = NULL;
  56. }
  57. static void
  58. vcpu_register(struct tcb *const tcp, int fd, int cpuid)
  59. {
  60. if (fd < 0)
  61. return;
  62. struct vcpu_info *vcpu_info = vcpu_find(tcp, fd);
  63. if (!vcpu_info)
  64. vcpu_info = vcpu_alloc(tcp, fd, cpuid);
  65. else if (vcpu_info->cpuid != cpuid)
  66. {
  67. vcpu_info->cpuid = cpuid;
  68. vcpu_info->resolved = false;
  69. }
  70. }
  71. static bool
  72. is_map_for_file(struct mmap_cache_entry_t *map_info, void *data)
  73. {
  74. /* major version for anon inode may be given in get_anon_bdev()
  75. * in linux kernel.
  76. *
  77. * *p = MKDEV(0, dev & MINORMASK);
  78. *-----------------^
  79. */
  80. return map_info->binary_filename &&
  81. map_info->major == 0 &&
  82. strcmp(map_info->binary_filename, data) == 0;
  83. }
  84. static unsigned long
  85. map_len(struct mmap_cache_entry_t *map_info)
  86. {
  87. return map_info->start_addr < map_info->end_addr
  88. ? map_info->end_addr - map_info->start_addr
  89. : 0;
  90. }
  91. # define VCPU_DENTRY_PREFIX "anon_inode:kvm-vcpu:"
  92. static struct vcpu_info*
  93. vcpu_get_info(struct tcb *const tcp, int fd)
  94. {
  95. struct vcpu_info *vcpu_info = vcpu_find(tcp, fd);
  96. struct mmap_cache_entry_t *map_info;
  97. const char *cpuid_str;
  98. enum mmap_cache_rebuild_result mc_stat =
  99. mmap_cache_rebuild_if_invalid(tcp, __func__);
  100. if (mc_stat == MMAP_CACHE_REBUILD_NOCACHE)
  101. return NULL;
  102. if (vcpu_info && vcpu_info->resolved) {
  103. if (mc_stat == MMAP_CACHE_REBUILD_READY)
  104. return vcpu_info;
  105. else {
  106. map_info = mmap_cache_search(tcp, vcpu_info->mmap_addr);
  107. if (map_info) {
  108. cpuid_str =
  109. STR_STRIP_PREFIX(map_info->binary_filename,
  110. VCPU_DENTRY_PREFIX);
  111. if (cpuid_str != map_info->binary_filename) {
  112. int cpuid = string_to_uint(cpuid_str);
  113. if (cpuid < 0)
  114. return NULL;
  115. if (vcpu_info->cpuid == cpuid)
  116. return vcpu_info;
  117. }
  118. }
  119. /* The vcpu vma may be mremap'ed. */
  120. vcpu_info->resolved = false;
  121. }
  122. }
  123. /* Slow path: !vcpu_info || !vcpu_info->resolved */
  124. char path[PATH_MAX + 1];
  125. cpuid_str = path;
  126. if (getfdpath(tcp, fd, path, sizeof(path)) >= 0)
  127. cpuid_str = STR_STRIP_PREFIX(path, VCPU_DENTRY_PREFIX);
  128. if (cpuid_str == path)
  129. map_info = NULL;
  130. else
  131. map_info = mmap_cache_search_custom(tcp, is_map_for_file, path);
  132. if (map_info) {
  133. int cpuid = string_to_uint(cpuid_str);
  134. if (cpuid < 0)
  135. return NULL;
  136. if (!vcpu_info)
  137. vcpu_info = vcpu_alloc(tcp, fd, cpuid);
  138. else if (vcpu_info->cpuid != cpuid)
  139. vcpu_info->cpuid = cpuid;
  140. vcpu_info->mmap_addr = map_info->start_addr;
  141. vcpu_info->mmap_len = map_len(map_info);
  142. vcpu_info->resolved = true;
  143. return vcpu_info;
  144. }
  145. return NULL;
  146. }
  147. static int
  148. kvm_ioctl_create_vcpu(struct tcb *const tcp, const kernel_ulong_t arg)
  149. {
  150. uint32_t cpuid = arg;
  151. if (entering(tcp)) {
  152. tprintf(", %u", cpuid);
  153. if (dump_kvm_run_structure)
  154. return 0;
  155. } else if (!syserror(tcp)) {
  156. vcpu_register(tcp, tcp->u_rval, cpuid);
  157. }
  158. return RVAL_IOCTL_DECODED | RVAL_FD;
  159. }
  160. # ifdef HAVE_STRUCT_KVM_USERSPACE_MEMORY_REGION
  161. # include "xlat/kvm_mem_flags.h"
  162. static int
  163. kvm_ioctl_set_user_memory_region(struct tcb *const tcp, const kernel_ulong_t arg)
  164. {
  165. struct kvm_userspace_memory_region u_memory_region;
  166. tprints(", ");
  167. if (umove_or_printaddr(tcp, arg, &u_memory_region))
  168. return RVAL_IOCTL_DECODED;
  169. PRINT_FIELD_U("{", u_memory_region, slot);
  170. PRINT_FIELD_FLAGS(", ", u_memory_region, flags, kvm_mem_flags,
  171. "KVM_MEM_???");
  172. PRINT_FIELD_X(", ", u_memory_region, guest_phys_addr);
  173. PRINT_FIELD_U(", ", u_memory_region, memory_size);
  174. PRINT_FIELD_X(", ", u_memory_region, userspace_addr);
  175. tprints("}");
  176. return RVAL_IOCTL_DECODED;
  177. }
  178. # endif /* HAVE_STRUCT_KVM_USERSPACE_MEMORY_REGION */
  179. # ifdef HAVE_STRUCT_KVM_REGS
  180. static int
  181. kvm_ioctl_decode_regs(struct tcb *const tcp, const unsigned int code,
  182. const kernel_ulong_t arg)
  183. {
  184. struct kvm_regs regs;
  185. if (code == KVM_GET_REGS && entering(tcp))
  186. return 0;
  187. tprints(", ");
  188. if (!umove_or_printaddr(tcp, arg, &regs))
  189. arch_print_kvm_regs(tcp, arg, &regs);
  190. return RVAL_IOCTL_DECODED;
  191. }
  192. # endif /* HAVE_STRUCT_KVM_REGS */
  193. # ifdef HAVE_STRUCT_KVM_CPUID2
  194. # include "xlat/kvm_cpuid_flags.h"
  195. static bool
  196. print_kvm_cpuid_entry(struct tcb *const tcp,
  197. void* elem_buf, size_t elem_size, void* data)
  198. {
  199. const struct kvm_cpuid_entry2 *entry = elem_buf;
  200. PRINT_FIELD_X("{", *entry, function);
  201. PRINT_FIELD_X(", ", *entry, index);
  202. PRINT_FIELD_FLAGS(", ", *entry, flags, kvm_cpuid_flags,
  203. "KVM_CPUID_FLAG_???");
  204. PRINT_FIELD_X(", ", *entry, eax);
  205. PRINT_FIELD_X(", ", *entry, ebx);
  206. PRINT_FIELD_X(", ", *entry, ecx);
  207. PRINT_FIELD_X(", ", *entry, edx);
  208. tprints("}");
  209. return true;
  210. }
  211. static int
  212. kvm_ioctl_decode_cpuid2(struct tcb *const tcp, const unsigned int code,
  213. const kernel_ulong_t arg)
  214. {
  215. struct kvm_cpuid2 cpuid;
  216. if (entering(tcp) && (code == KVM_GET_SUPPORTED_CPUID
  217. # ifdef KVM_GET_EMULATED_CPUID
  218. || code == KVM_GET_EMULATED_CPUID
  219. # endif
  220. ))
  221. return 0;
  222. tprints(", ");
  223. if (!umove_or_printaddr(tcp, arg, &cpuid)) {
  224. PRINT_FIELD_U("{", cpuid, nent);
  225. tprints(", entries=");
  226. if (abbrev(tcp)) {
  227. tprints("[");
  228. if (cpuid.nent)
  229. tprints("...");
  230. tprints("]");
  231. } else {
  232. struct kvm_cpuid_entry2 entry;
  233. print_array(tcp, arg + sizeof(cpuid), cpuid.nent,
  234. &entry, sizeof(entry), tfetch_mem,
  235. print_kvm_cpuid_entry, NULL);
  236. }
  237. tprints("}");
  238. }
  239. return RVAL_IOCTL_DECODED;
  240. }
  241. # endif /* HAVE_STRUCT_KVM_CPUID2 */
  242. # ifdef HAVE_STRUCT_KVM_SREGS
  243. static int
  244. kvm_ioctl_decode_sregs(struct tcb *const tcp, const unsigned int code,
  245. const kernel_ulong_t arg)
  246. {
  247. struct kvm_sregs sregs;
  248. if (code == KVM_GET_SREGS && entering(tcp))
  249. return 0;
  250. tprints(", ");
  251. if (!umove_or_printaddr(tcp, arg, &sregs))
  252. arch_print_kvm_sregs(tcp, arg, &sregs);
  253. return RVAL_IOCTL_DECODED;
  254. }
  255. # endif /* HAVE_STRUCT_KVM_SREGS */
  256. # include "xlat/kvm_cap.h"
  257. static int
  258. kvm_ioctl_decode_check_extension(struct tcb *const tcp, const unsigned int code,
  259. const kernel_ulong_t arg)
  260. {
  261. tprints(", ");
  262. printxval_index(kvm_cap, arg, "KVM_CAP_???");
  263. return RVAL_IOCTL_DECODED;
  264. }
  265. # include "xlat/kvm_exit_reason.h"
  266. static void
  267. kvm_ioctl_run_attach_auxstr(struct tcb *const tcp,
  268. struct vcpu_info *info)
  269. {
  270. static struct kvm_run vcpu_run_struct;
  271. if (info->mmap_len < sizeof(vcpu_run_struct))
  272. return;
  273. if (umove(tcp, info->mmap_addr, &vcpu_run_struct) < 0)
  274. return;
  275. tcp->auxstr = xlat_idx(kvm_exit_reason, ARRAY_SIZE(kvm_exit_reason) - 1,
  276. vcpu_run_struct.exit_reason);
  277. if (!tcp->auxstr)
  278. tcp->auxstr = "KVM_EXIT_???";
  279. }
  280. static int
  281. kvm_ioctl_decode_run(struct tcb *const tcp)
  282. {
  283. if (entering(tcp))
  284. return 0;
  285. int r = RVAL_DECODED;
  286. if (syserror(tcp))
  287. return r;
  288. if (dump_kvm_run_structure) {
  289. tcp->auxstr = NULL;
  290. int fd = tcp->u_arg[0];
  291. struct vcpu_info *info = vcpu_get_info(tcp, fd);
  292. if (info) {
  293. kvm_ioctl_run_attach_auxstr(tcp, info);
  294. if (tcp->auxstr)
  295. r |= RVAL_STR;
  296. }
  297. }
  298. return r;
  299. }
  300. int
  301. kvm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg)
  302. {
  303. switch (code) {
  304. case KVM_CREATE_VCPU:
  305. return kvm_ioctl_create_vcpu(tcp, arg);
  306. # ifdef HAVE_STRUCT_KVM_USERSPACE_MEMORY_REGION
  307. case KVM_SET_USER_MEMORY_REGION:
  308. return kvm_ioctl_set_user_memory_region(tcp, arg);
  309. # endif
  310. # ifdef HAVE_STRUCT_KVM_REGS
  311. case KVM_SET_REGS:
  312. case KVM_GET_REGS:
  313. return kvm_ioctl_decode_regs(tcp, code, arg);
  314. # endif
  315. # ifdef HAVE_STRUCT_KVM_SREGS
  316. case KVM_SET_SREGS:
  317. case KVM_GET_SREGS:
  318. return kvm_ioctl_decode_sregs(tcp, code, arg);
  319. # endif
  320. # ifdef HAVE_STRUCT_KVM_CPUID2
  321. case KVM_SET_CPUID2:
  322. case KVM_GET_SUPPORTED_CPUID:
  323. # ifdef KVM_GET_EMULATED_CPUID
  324. case KVM_GET_EMULATED_CPUID:
  325. # endif
  326. return kvm_ioctl_decode_cpuid2(tcp, code, arg);
  327. # endif
  328. case KVM_CHECK_EXTENSION:
  329. return kvm_ioctl_decode_check_extension(tcp, code, arg);
  330. case KVM_CREATE_VM:
  331. return RVAL_DECODED | RVAL_FD;
  332. case KVM_RUN:
  333. return kvm_ioctl_decode_run(tcp);
  334. case KVM_GET_VCPU_MMAP_SIZE:
  335. case KVM_GET_API_VERSION:
  336. default:
  337. return RVAL_DECODED;
  338. }
  339. }
  340. void
  341. kvm_run_structure_decoder_init(void)
  342. {
  343. dump_kvm_run_structure = true;
  344. mmap_cache_enable();
  345. }
  346. #endif /* HAVE_LINUX_KVM_H */