1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (C) 2021 SUSE LLC <mdoucha@suse.cz> 4f08c3bdfSopenharmony_ci * 5f08c3bdfSopenharmony_ci * KVM host library for setting up and running virtual machine tests. 6f08c3bdfSopenharmony_ci */ 7f08c3bdfSopenharmony_ci 8f08c3bdfSopenharmony_ci#include <stdlib.h> 9f08c3bdfSopenharmony_ci#include <errno.h> 10f08c3bdfSopenharmony_ci 11f08c3bdfSopenharmony_ci#define TST_NO_DEFAULT_MAIN 12f08c3bdfSopenharmony_ci#include "tst_test.h" 13f08c3bdfSopenharmony_ci#include "tst_clocks.h" 14f08c3bdfSopenharmony_ci#include "tst_timer.h" 15f08c3bdfSopenharmony_ci#include "kvm_host.h" 16f08c3bdfSopenharmony_ci 17f08c3bdfSopenharmony_cistatic struct tst_kvm_instance test_vm = { .vm_fd = -1 }; 18f08c3bdfSopenharmony_ci 19f08c3bdfSopenharmony_ciconst unsigned char tst_kvm_reset_code[VM_RESET_CODE_SIZE] = { 20f08c3bdfSopenharmony_ci 0xea, 0x00, 0x10, 0x00, 0x00 /* JMP 0x1000 */ 21f08c3bdfSopenharmony_ci}; 22f08c3bdfSopenharmony_ci 23f08c3bdfSopenharmony_civoid tst_kvm_validate_result(int value) 24f08c3bdfSopenharmony_ci{ 25f08c3bdfSopenharmony_ci int ttype, valid_result[] = {TPASS, TFAIL, TBROK, TWARN, TINFO, TCONF}; 26f08c3bdfSopenharmony_ci size_t i; 27f08c3bdfSopenharmony_ci 28f08c3bdfSopenharmony_ci if (value == KVM_TNONE) 29f08c3bdfSopenharmony_ci tst_brk(TBROK, "KVM test did not return any result"); 30f08c3bdfSopenharmony_ci 31f08c3bdfSopenharmony_ci ttype = TTYPE_RESULT(value); 32f08c3bdfSopenharmony_ci 33f08c3bdfSopenharmony_ci for (i = 0; i < ARRAY_SIZE(valid_result); i++) { 34f08c3bdfSopenharmony_ci if (ttype == valid_result[i]) 35f08c3bdfSopenharmony_ci return; 36f08c3bdfSopenharmony_ci } 37f08c3bdfSopenharmony_ci 38f08c3bdfSopenharmony_ci tst_brk(TBROK, "KVM test returned invalid result value %d", value); 39f08c3bdfSopenharmony_ci} 40f08c3bdfSopenharmony_ci 41f08c3bdfSopenharmony_ciuint64_t tst_kvm_get_phys_address(const struct tst_kvm_instance *inst, 42f08c3bdfSopenharmony_ci uint64_t addr) 43f08c3bdfSopenharmony_ci{ 44f08c3bdfSopenharmony_ci struct kvm_translation trans = { .linear_address = addr }; 45f08c3bdfSopenharmony_ci 46f08c3bdfSopenharmony_ci TEST(ioctl(inst->vcpu_fd, KVM_TRANSLATE, &trans)); 47f08c3bdfSopenharmony_ci 48f08c3bdfSopenharmony_ci /* ioctl(KVM_TRANSLATE) is not implemented for this arch */ 49f08c3bdfSopenharmony_ci if (TST_RET == -1 && TST_ERR == EINVAL) 50f08c3bdfSopenharmony_ci return addr; 51f08c3bdfSopenharmony_ci 52f08c3bdfSopenharmony_ci if (TST_RET == -1) 53f08c3bdfSopenharmony_ci tst_brk(TBROK | TTERRNO, "ioctl(KVM_TRANSLATE) failed"); 54f08c3bdfSopenharmony_ci 55f08c3bdfSopenharmony_ci if (TST_RET) { 56f08c3bdfSopenharmony_ci tst_brk(TBROK | TTERRNO, 57f08c3bdfSopenharmony_ci "Invalid ioctl(KVM_TRANSLATE) return value"); 58f08c3bdfSopenharmony_ci } 59f08c3bdfSopenharmony_ci 60f08c3bdfSopenharmony_ci return trans.valid ? trans.physical_address : 0; 61f08c3bdfSopenharmony_ci} 62f08c3bdfSopenharmony_ci 63f08c3bdfSopenharmony_ciint tst_kvm_find_phys_memslot(const struct tst_kvm_instance *inst, 64f08c3bdfSopenharmony_ci uint64_t paddr) 65f08c3bdfSopenharmony_ci{ 66f08c3bdfSopenharmony_ci int i; 67f08c3bdfSopenharmony_ci uint64_t base; 68f08c3bdfSopenharmony_ci 69f08c3bdfSopenharmony_ci for (i = 0; i < MAX_KVM_MEMSLOTS; i++) { 70f08c3bdfSopenharmony_ci if (!inst->ram[i].userspace_addr) 71f08c3bdfSopenharmony_ci continue; 72f08c3bdfSopenharmony_ci 73f08c3bdfSopenharmony_ci base = inst->ram[i].guest_phys_addr; 74f08c3bdfSopenharmony_ci 75f08c3bdfSopenharmony_ci if (paddr >= base && paddr - base < inst->ram[i].memory_size) 76f08c3bdfSopenharmony_ci return i; 77f08c3bdfSopenharmony_ci } 78f08c3bdfSopenharmony_ci 79f08c3bdfSopenharmony_ci return -1; 80f08c3bdfSopenharmony_ci} 81f08c3bdfSopenharmony_ci 82f08c3bdfSopenharmony_ciint tst_kvm_find_memslot(const struct tst_kvm_instance *inst, uint64_t addr) 83f08c3bdfSopenharmony_ci{ 84f08c3bdfSopenharmony_ci addr = tst_kvm_get_phys_address(inst, addr); 85f08c3bdfSopenharmony_ci 86f08c3bdfSopenharmony_ci if (!addr) 87f08c3bdfSopenharmony_ci return -1; 88f08c3bdfSopenharmony_ci 89f08c3bdfSopenharmony_ci return tst_kvm_find_phys_memslot(inst, addr); 90f08c3bdfSopenharmony_ci} 91f08c3bdfSopenharmony_ci 92f08c3bdfSopenharmony_civoid *tst_kvm_get_memptr(const struct tst_kvm_instance *inst, uint64_t addr) 93f08c3bdfSopenharmony_ci{ 94f08c3bdfSopenharmony_ci int slot; 95f08c3bdfSopenharmony_ci char *ret; 96f08c3bdfSopenharmony_ci 97f08c3bdfSopenharmony_ci addr = tst_kvm_get_phys_address(inst, addr); 98f08c3bdfSopenharmony_ci 99f08c3bdfSopenharmony_ci if (!addr) 100f08c3bdfSopenharmony_ci return NULL; 101f08c3bdfSopenharmony_ci 102f08c3bdfSopenharmony_ci slot = tst_kvm_find_phys_memslot(inst, addr); 103f08c3bdfSopenharmony_ci 104f08c3bdfSopenharmony_ci if (slot < 0) 105f08c3bdfSopenharmony_ci return NULL; 106f08c3bdfSopenharmony_ci 107f08c3bdfSopenharmony_ci ret = (char *)(uintptr_t)inst->ram[slot].userspace_addr; 108f08c3bdfSopenharmony_ci return ret + (addr - inst->ram[slot].guest_phys_addr); 109f08c3bdfSopenharmony_ci} 110f08c3bdfSopenharmony_ci 111f08c3bdfSopenharmony_civoid tst_kvm_print_result(const struct tst_kvm_instance *inst) 112f08c3bdfSopenharmony_ci{ 113f08c3bdfSopenharmony_ci int ttype; 114f08c3bdfSopenharmony_ci const struct tst_kvm_result *result = inst->result; 115f08c3bdfSopenharmony_ci const char *file; 116f08c3bdfSopenharmony_ci 117f08c3bdfSopenharmony_ci tst_kvm_validate_result(result->result); 118f08c3bdfSopenharmony_ci ttype = TTYPE_RESULT(result->result); 119f08c3bdfSopenharmony_ci file = tst_kvm_get_memptr(inst, result->file_addr); 120f08c3bdfSopenharmony_ci 121f08c3bdfSopenharmony_ci if (ttype == TBROK) 122f08c3bdfSopenharmony_ci tst_brk_(file, result->lineno, ttype, "%s", result->message); 123f08c3bdfSopenharmony_ci else 124f08c3bdfSopenharmony_ci tst_res_(file, result->lineno, ttype, "%s", result->message); 125f08c3bdfSopenharmony_ci} 126f08c3bdfSopenharmony_ci 127f08c3bdfSopenharmony_civoid *tst_kvm_alloc_memory(struct tst_kvm_instance *inst, unsigned int slot, 128f08c3bdfSopenharmony_ci uint64_t baseaddr, size_t size, unsigned int flags) 129f08c3bdfSopenharmony_ci{ 130f08c3bdfSopenharmony_ci size_t pagesize, offset; 131f08c3bdfSopenharmony_ci char *ret; 132f08c3bdfSopenharmony_ci struct kvm_userspace_memory_region memslot = { 133f08c3bdfSopenharmony_ci .slot = slot, 134f08c3bdfSopenharmony_ci .flags = flags 135f08c3bdfSopenharmony_ci }; 136f08c3bdfSopenharmony_ci 137f08c3bdfSopenharmony_ci if (slot >= MAX_KVM_MEMSLOTS) 138f08c3bdfSopenharmony_ci tst_brk(TBROK, "Invalid KVM memory slot %u", slot); 139f08c3bdfSopenharmony_ci 140f08c3bdfSopenharmony_ci pagesize = SAFE_SYSCONF(_SC_PAGESIZE); 141f08c3bdfSopenharmony_ci offset = baseaddr % pagesize; 142f08c3bdfSopenharmony_ci size = LTP_ALIGN(size + offset, pagesize); 143f08c3bdfSopenharmony_ci ret = tst_alloc(size); 144f08c3bdfSopenharmony_ci 145f08c3bdfSopenharmony_ci memslot.guest_phys_addr = baseaddr - offset; 146f08c3bdfSopenharmony_ci memslot.memory_size = size; 147f08c3bdfSopenharmony_ci memslot.userspace_addr = (uintptr_t)ret; 148f08c3bdfSopenharmony_ci SAFE_IOCTL(inst->vm_fd, KVM_SET_USER_MEMORY_REGION, &memslot); 149f08c3bdfSopenharmony_ci inst->ram[slot] = memslot; 150f08c3bdfSopenharmony_ci return ret; 151f08c3bdfSopenharmony_ci} 152f08c3bdfSopenharmony_ci 153f08c3bdfSopenharmony_cistruct kvm_cpuid2 *tst_kvm_get_cpuid(int sysfd) 154f08c3bdfSopenharmony_ci{ 155f08c3bdfSopenharmony_ci unsigned int count; 156f08c3bdfSopenharmony_ci int result; 157f08c3bdfSopenharmony_ci struct kvm_cpuid2 *ret; 158f08c3bdfSopenharmony_ci 159f08c3bdfSopenharmony_ci if (!SAFE_IOCTL(sysfd, KVM_CHECK_EXTENSION, KVM_CAP_EXT_CPUID)) 160f08c3bdfSopenharmony_ci return NULL; 161f08c3bdfSopenharmony_ci 162f08c3bdfSopenharmony_ci for (count = 8; count < 1 << 30; count *= 2) { 163f08c3bdfSopenharmony_ci ret = SAFE_MALLOC(sizeof(struct kvm_cpuid2) + 164f08c3bdfSopenharmony_ci count * sizeof(struct kvm_cpuid_entry2)); 165f08c3bdfSopenharmony_ci ret->nent = count; 166f08c3bdfSopenharmony_ci errno = 0; 167f08c3bdfSopenharmony_ci result = ioctl(sysfd, KVM_GET_SUPPORTED_CPUID, ret); 168f08c3bdfSopenharmony_ci 169f08c3bdfSopenharmony_ci if (!result) 170f08c3bdfSopenharmony_ci return ret; 171f08c3bdfSopenharmony_ci 172f08c3bdfSopenharmony_ci free(ret); 173f08c3bdfSopenharmony_ci 174f08c3bdfSopenharmony_ci if (errno != E2BIG) 175f08c3bdfSopenharmony_ci break; 176f08c3bdfSopenharmony_ci } 177f08c3bdfSopenharmony_ci 178f08c3bdfSopenharmony_ci tst_brk(TBROK | TERRNO, "ioctl(KVM_GET_SUPPORTED_CPUID) failed"); 179f08c3bdfSopenharmony_ci return NULL; 180f08c3bdfSopenharmony_ci} 181f08c3bdfSopenharmony_ci 182f08c3bdfSopenharmony_civoid tst_kvm_create_instance(struct tst_kvm_instance *inst, size_t ram_size) 183f08c3bdfSopenharmony_ci{ 184f08c3bdfSopenharmony_ci int sys_fd; 185f08c3bdfSopenharmony_ci size_t pagesize, result_pageaddr = KVM_RESULT_BASEADDR; 186f08c3bdfSopenharmony_ci char *buf, *reset_ptr; 187f08c3bdfSopenharmony_ci struct kvm_cpuid2 *cpuid_data; 188f08c3bdfSopenharmony_ci const size_t payload_size = kvm_payload_end - kvm_payload_start; 189f08c3bdfSopenharmony_ci 190f08c3bdfSopenharmony_ci memset(inst, 0, sizeof(struct tst_kvm_instance)); 191f08c3bdfSopenharmony_ci inst->vm_fd = -1; 192f08c3bdfSopenharmony_ci inst->vcpu_fd = -1; 193f08c3bdfSopenharmony_ci inst->vcpu_info = MAP_FAILED; 194f08c3bdfSopenharmony_ci 195f08c3bdfSopenharmony_ci pagesize = SAFE_SYSCONF(_SC_PAGESIZE); 196f08c3bdfSopenharmony_ci result_pageaddr -= result_pageaddr % pagesize; 197f08c3bdfSopenharmony_ci 198f08c3bdfSopenharmony_ci if (payload_size + MIN_FREE_RAM > ram_size - VM_KERNEL_BASEADDR) { 199f08c3bdfSopenharmony_ci ram_size = payload_size + MIN_FREE_RAM + VM_KERNEL_BASEADDR; 200f08c3bdfSopenharmony_ci ram_size = LTP_ALIGN(ram_size, 1024 * 1024); 201f08c3bdfSopenharmony_ci tst_res(TWARN, "RAM size increased to %zu bytes", ram_size); 202f08c3bdfSopenharmony_ci } 203f08c3bdfSopenharmony_ci 204f08c3bdfSopenharmony_ci if (ram_size > result_pageaddr) { 205f08c3bdfSopenharmony_ci ram_size = result_pageaddr; 206f08c3bdfSopenharmony_ci tst_res(TWARN, "RAM size truncated to %zu bytes", ram_size); 207f08c3bdfSopenharmony_ci } 208f08c3bdfSopenharmony_ci 209f08c3bdfSopenharmony_ci sys_fd = SAFE_OPEN("/dev/kvm", O_RDWR); 210f08c3bdfSopenharmony_ci inst->vcpu_info_size = SAFE_IOCTL(sys_fd, KVM_GET_VCPU_MMAP_SIZE, 0); 211f08c3bdfSopenharmony_ci inst->vm_fd = SAFE_IOCTL(sys_fd, KVM_CREATE_VM, 0); 212f08c3bdfSopenharmony_ci cpuid_data = tst_kvm_get_cpuid(sys_fd); 213f08c3bdfSopenharmony_ci SAFE_CLOSE(sys_fd); 214f08c3bdfSopenharmony_ci 215f08c3bdfSopenharmony_ci inst->vcpu_fd = SAFE_IOCTL(inst->vm_fd, KVM_CREATE_VCPU, 0); 216f08c3bdfSopenharmony_ci 217f08c3bdfSopenharmony_ci if (cpuid_data) { 218f08c3bdfSopenharmony_ci SAFE_IOCTL(inst->vcpu_fd, KVM_SET_CPUID2, cpuid_data); 219f08c3bdfSopenharmony_ci free(cpuid_data); 220f08c3bdfSopenharmony_ci } 221f08c3bdfSopenharmony_ci 222f08c3bdfSopenharmony_ci inst->vcpu_info = SAFE_MMAP(NULL, inst->vcpu_info_size, 223f08c3bdfSopenharmony_ci PROT_READ | PROT_WRITE, MAP_SHARED, inst->vcpu_fd, 0); 224f08c3bdfSopenharmony_ci 225f08c3bdfSopenharmony_ci buf = tst_kvm_alloc_memory(inst, 0, 0, ram_size, 0); 226f08c3bdfSopenharmony_ci memcpy(buf + VM_KERNEL_BASEADDR, kvm_payload_start, payload_size); 227f08c3bdfSopenharmony_ci buf = tst_kvm_alloc_memory(inst, 1, KVM_RESULT_BASEADDR, 228f08c3bdfSopenharmony_ci KVM_RESULT_SIZE, 0); 229f08c3bdfSopenharmony_ci memset(buf, 0, KVM_RESULT_SIZE); 230f08c3bdfSopenharmony_ci 231f08c3bdfSopenharmony_ci reset_ptr = buf + (VM_RESET_BASEADDR % pagesize); 232f08c3bdfSopenharmony_ci memcpy(reset_ptr, tst_kvm_reset_code, sizeof(tst_kvm_reset_code)); 233f08c3bdfSopenharmony_ci inst->result = (struct tst_kvm_result *)(buf + 234f08c3bdfSopenharmony_ci (KVM_RESULT_BASEADDR % pagesize)); 235f08c3bdfSopenharmony_ci inst->result->result = KVM_TNONE; 236f08c3bdfSopenharmony_ci inst->result->message[0] = '\0'; 237f08c3bdfSopenharmony_ci} 238f08c3bdfSopenharmony_ci 239f08c3bdfSopenharmony_ciint tst_kvm_run_instance(struct tst_kvm_instance *inst, int exp_errno) 240f08c3bdfSopenharmony_ci{ 241f08c3bdfSopenharmony_ci struct kvm_regs regs; 242f08c3bdfSopenharmony_ci int ret; 243f08c3bdfSopenharmony_ci 244f08c3bdfSopenharmony_ci while (1) { 245f08c3bdfSopenharmony_ci inst->result->result = KVM_TNONE; 246f08c3bdfSopenharmony_ci inst->result->message[0] = '\0'; 247f08c3bdfSopenharmony_ci errno = 0; 248f08c3bdfSopenharmony_ci ret = ioctl(inst->vcpu_fd, KVM_RUN, 0); 249f08c3bdfSopenharmony_ci 250f08c3bdfSopenharmony_ci if (ret == -1) { 251f08c3bdfSopenharmony_ci if (errno == exp_errno) 252f08c3bdfSopenharmony_ci return ret; 253f08c3bdfSopenharmony_ci 254f08c3bdfSopenharmony_ci tst_brk(TBROK | TERRNO, "ioctl(KVM_RUN) failed"); 255f08c3bdfSopenharmony_ci } 256f08c3bdfSopenharmony_ci 257f08c3bdfSopenharmony_ci if (ret < 0) { 258f08c3bdfSopenharmony_ci tst_brk(TBROK | TERRNO, 259f08c3bdfSopenharmony_ci "Invalid ioctl(KVM_RUN) return value %d", ret); 260f08c3bdfSopenharmony_ci } 261f08c3bdfSopenharmony_ci 262f08c3bdfSopenharmony_ci if (inst->vcpu_info->exit_reason != KVM_EXIT_HLT) { 263f08c3bdfSopenharmony_ci SAFE_IOCTL(inst->vcpu_fd, KVM_GET_REGS, ®s); 264f08c3bdfSopenharmony_ci tst_brk(TBROK, 265f08c3bdfSopenharmony_ci "Unexpected VM exit, RIP=0x%llx, reason=%u", 266f08c3bdfSopenharmony_ci regs.rip, inst->vcpu_info->exit_reason); 267f08c3bdfSopenharmony_ci } 268f08c3bdfSopenharmony_ci 269f08c3bdfSopenharmony_ci if (inst->result->result == KVM_TEXIT) 270f08c3bdfSopenharmony_ci break; 271f08c3bdfSopenharmony_ci 272f08c3bdfSopenharmony_ci tst_kvm_print_result(inst); 273f08c3bdfSopenharmony_ci } 274f08c3bdfSopenharmony_ci 275f08c3bdfSopenharmony_ci return ret; 276f08c3bdfSopenharmony_ci} 277f08c3bdfSopenharmony_ci 278f08c3bdfSopenharmony_civoid tst_kvm_destroy_instance(struct tst_kvm_instance *inst) 279f08c3bdfSopenharmony_ci{ 280f08c3bdfSopenharmony_ci if (inst->vm_fd < 0) 281f08c3bdfSopenharmony_ci return; 282f08c3bdfSopenharmony_ci 283f08c3bdfSopenharmony_ci if (inst->vcpu_info != MAP_FAILED) 284f08c3bdfSopenharmony_ci SAFE_MUNMAP(inst->vcpu_info, inst->vcpu_info_size); 285f08c3bdfSopenharmony_ci 286f08c3bdfSopenharmony_ci if (inst->vcpu_fd >= 0) 287f08c3bdfSopenharmony_ci SAFE_CLOSE(inst->vcpu_fd); 288f08c3bdfSopenharmony_ci 289f08c3bdfSopenharmony_ci SAFE_CLOSE(inst->vm_fd); 290f08c3bdfSopenharmony_ci memset(inst->ram, 0, sizeof(inst->ram)); 291f08c3bdfSopenharmony_ci} 292f08c3bdfSopenharmony_ci 293f08c3bdfSopenharmony_ciint tst_kvm_wait_guest(struct tst_kvm_instance *inst, int timeout_ms) 294f08c3bdfSopenharmony_ci{ 295f08c3bdfSopenharmony_ci volatile struct tst_kvm_result *result = inst->result; 296f08c3bdfSopenharmony_ci int32_t res; 297f08c3bdfSopenharmony_ci struct timespec start, now; 298f08c3bdfSopenharmony_ci 299f08c3bdfSopenharmony_ci if (timeout_ms >= 0) 300f08c3bdfSopenharmony_ci tst_clock_gettime(CLOCK_MONOTONIC, &start); 301f08c3bdfSopenharmony_ci 302f08c3bdfSopenharmony_ci while ((res = result->result) != KVM_TSYNC) { 303f08c3bdfSopenharmony_ci if (res == KVM_TEXIT) 304f08c3bdfSopenharmony_ci return res; 305f08c3bdfSopenharmony_ci 306f08c3bdfSopenharmony_ci if (timeout_ms >= 0) { 307f08c3bdfSopenharmony_ci tst_clock_gettime(CLOCK_MONOTONIC, &now); 308f08c3bdfSopenharmony_ci 309f08c3bdfSopenharmony_ci if (tst_timespec_diff_ms(now, start) >= timeout_ms) 310f08c3bdfSopenharmony_ci return -1; 311f08c3bdfSopenharmony_ci } 312f08c3bdfSopenharmony_ci 313f08c3bdfSopenharmony_ci usleep(1000); 314f08c3bdfSopenharmony_ci } 315f08c3bdfSopenharmony_ci 316f08c3bdfSopenharmony_ci return 0; 317f08c3bdfSopenharmony_ci} 318f08c3bdfSopenharmony_ci 319f08c3bdfSopenharmony_civoid tst_kvm_clear_guest_signal(struct tst_kvm_instance *inst) 320f08c3bdfSopenharmony_ci{ 321f08c3bdfSopenharmony_ci inst->result->result = KVM_TNONE; 322f08c3bdfSopenharmony_ci} 323f08c3bdfSopenharmony_ci 324f08c3bdfSopenharmony_civoid tst_kvm_setup(void) 325f08c3bdfSopenharmony_ci{ 326f08c3bdfSopenharmony_ci 327f08c3bdfSopenharmony_ci} 328f08c3bdfSopenharmony_ci 329f08c3bdfSopenharmony_civoid tst_kvm_run(void) 330f08c3bdfSopenharmony_ci{ 331f08c3bdfSopenharmony_ci tst_kvm_create_instance(&test_vm, DEFAULT_RAM_SIZE); 332f08c3bdfSopenharmony_ci tst_kvm_run_instance(&test_vm, 0); 333f08c3bdfSopenharmony_ci tst_kvm_destroy_instance(&test_vm); 334f08c3bdfSopenharmony_ci tst_free_all(); 335f08c3bdfSopenharmony_ci} 336f08c3bdfSopenharmony_ci 337f08c3bdfSopenharmony_civoid tst_kvm_cleanup(void) 338f08c3bdfSopenharmony_ci{ 339f08c3bdfSopenharmony_ci tst_kvm_destroy_instance(&test_vm); 340f08c3bdfSopenharmony_ci} 341