Commit c345344e authored by Paolo Bonzini's avatar Paolo Bonzini

Merge tag 'kvm-x86-selftests-6.12' of https://github.com/kvm-x86/linux into HEAD

KVM selftests changes for 6.12:

 - Fix a goof that caused some Hyper-V tests to be skipped when run on bare
   metal, i.e. NOT in a VM.

 - Add a regression test for KVM's handling of SHUTDOWN for an SEV-ES guest.

 - Explicitly include one-off assets in .gitignore.  Past Sean was completely
   wrong about not being able to detect missing .gitignore entries.

 - Verify userspace single-stepping works when KVM happens to handle a VM-Exit
   in its fastpath.

 - Misc cleanups
parents 41786cc5 c32e0280
...@@ -5,4 +5,7 @@ ...@@ -5,4 +5,7 @@
!*.h !*.h
!*.S !*.S
!*.sh !*.sh
!.gitignore
!config !config
!settings
!Makefile
...@@ -428,8 +428,6 @@ const char *vm_guest_mode_string(uint32_t i); ...@@ -428,8 +428,6 @@ const char *vm_guest_mode_string(uint32_t i);
void kvm_vm_free(struct kvm_vm *vmp); void kvm_vm_free(struct kvm_vm *vmp);
void kvm_vm_restart(struct kvm_vm *vmp); void kvm_vm_restart(struct kvm_vm *vmp);
void kvm_vm_release(struct kvm_vm *vmp); void kvm_vm_release(struct kvm_vm *vmp);
int kvm_memcmp_hva_gva(void *hva, struct kvm_vm *vm, const vm_vaddr_t gva,
size_t len);
void kvm_vm_elf_load(struct kvm_vm *vm, const char *filename); void kvm_vm_elf_load(struct kvm_vm *vm, const char *filename);
int kvm_memfd_alloc(size_t size, bool hugepages); int kvm_memfd_alloc(size_t size, bool hugepages);
......
...@@ -186,6 +186,18 @@ ...@@ -186,6 +186,18 @@
#define HV_X64_ENLIGHTENED_VMCS_RECOMMENDED \ #define HV_X64_ENLIGHTENED_VMCS_RECOMMENDED \
KVM_X86_CPU_FEATURE(HYPERV_CPUID_ENLIGHTMENT_INFO, 0, EAX, 14) KVM_X86_CPU_FEATURE(HYPERV_CPUID_ENLIGHTMENT_INFO, 0, EAX, 14)
/* HYPERV_CPUID_NESTED_FEATURES.EAX */
#define HV_X64_NESTED_DIRECT_FLUSH \
KVM_X86_CPU_FEATURE(HYPERV_CPUID_NESTED_FEATURES, 0, EAX, 17)
#define HV_X64_NESTED_GUEST_MAPPING_FLUSH \
KVM_X86_CPU_FEATURE(HYPERV_CPUID_NESTED_FEATURES, 0, EAX, 18)
#define HV_X64_NESTED_MSR_BITMAP \
KVM_X86_CPU_FEATURE(HYPERV_CPUID_NESTED_FEATURES, 0, EAX, 19)
/* HYPERV_CPUID_NESTED_FEATURES.EBX */
#define HV_X64_NESTED_EVMCS1_PERF_GLOBAL_CTRL \
KVM_X86_CPU_FEATURE(HYPERV_CPUID_NESTED_FEATURES, 0, EBX, 0)
/* HYPERV_CPUID_SYNDBG_PLATFORM_CAPABILITIES.EAX */ /* HYPERV_CPUID_SYNDBG_PLATFORM_CAPABILITIES.EAX */
#define HV_X64_SYNDBG_CAP_ALLOW_KERNEL_DEBUGGING \ #define HV_X64_SYNDBG_CAP_ALLOW_KERNEL_DEBUGGING \
KVM_X86_CPU_FEATURE(HYPERV_CPUID_SYNDBG_PLATFORM_CAPABILITIES, 0, EAX, 1) KVM_X86_CPU_FEATURE(HYPERV_CPUID_SYNDBG_PLATFORM_CAPABILITIES, 0, EAX, 1)
...@@ -343,4 +355,10 @@ struct hyperv_test_pages *vcpu_alloc_hyperv_test_pages(struct kvm_vm *vm, ...@@ -343,4 +355,10 @@ struct hyperv_test_pages *vcpu_alloc_hyperv_test_pages(struct kvm_vm *vm,
/* HV_X64_MSR_TSC_INVARIANT_CONTROL bits */ /* HV_X64_MSR_TSC_INVARIANT_CONTROL bits */
#define HV_INVARIANT_TSC_EXPOSED BIT_ULL(0) #define HV_INVARIANT_TSC_EXPOSED BIT_ULL(0)
const struct kvm_cpuid2 *kvm_get_supported_hv_cpuid(void);
const struct kvm_cpuid2 *vcpu_get_supported_hv_cpuid(struct kvm_vcpu *vcpu);
void vcpu_set_hv_cpuid(struct kvm_vcpu *vcpu);
bool kvm_hv_cpu_has(struct kvm_x86_cpu_feature feature);
#endif /* !SELFTEST_KVM_HYPERV_H */ #endif /* !SELFTEST_KVM_HYPERV_H */
...@@ -25,6 +25,10 @@ extern bool host_cpu_is_intel; ...@@ -25,6 +25,10 @@ extern bool host_cpu_is_intel;
extern bool host_cpu_is_amd; extern bool host_cpu_is_amd;
extern uint64_t guest_tsc_khz; extern uint64_t guest_tsc_khz;
#ifndef MAX_NR_CPUID_ENTRIES
#define MAX_NR_CPUID_ENTRIES 100
#endif
/* Forced emulation prefix, used to invoke the emulator unconditionally. */ /* Forced emulation prefix, used to invoke the emulator unconditionally. */
#define KVM_FEP "ud2; .byte 'k', 'v', 'm';" #define KVM_FEP "ud2; .byte 'k', 'v', 'm';"
...@@ -908,8 +912,6 @@ static inline void vcpu_xcrs_set(struct kvm_vcpu *vcpu, struct kvm_xcrs *xcrs) ...@@ -908,8 +912,6 @@ static inline void vcpu_xcrs_set(struct kvm_vcpu *vcpu, struct kvm_xcrs *xcrs)
const struct kvm_cpuid_entry2 *get_cpuid_entry(const struct kvm_cpuid2 *cpuid, const struct kvm_cpuid_entry2 *get_cpuid_entry(const struct kvm_cpuid2 *cpuid,
uint32_t function, uint32_t index); uint32_t function, uint32_t index);
const struct kvm_cpuid2 *kvm_get_supported_cpuid(void); const struct kvm_cpuid2 *kvm_get_supported_cpuid(void);
const struct kvm_cpuid2 *kvm_get_supported_hv_cpuid(void);
const struct kvm_cpuid2 *vcpu_get_supported_hv_cpuid(struct kvm_vcpu *vcpu);
static inline uint32_t kvm_cpu_fms(void) static inline uint32_t kvm_cpu_fms(void)
{ {
...@@ -1009,7 +1011,6 @@ static inline struct kvm_cpuid2 *allocate_kvm_cpuid2(int nr_entries) ...@@ -1009,7 +1011,6 @@ static inline struct kvm_cpuid2 *allocate_kvm_cpuid2(int nr_entries)
} }
void vcpu_init_cpuid(struct kvm_vcpu *vcpu, const struct kvm_cpuid2 *cpuid); void vcpu_init_cpuid(struct kvm_vcpu *vcpu, const struct kvm_cpuid2 *cpuid);
void vcpu_set_hv_cpuid(struct kvm_vcpu *vcpu);
static inline struct kvm_cpuid_entry2 *__vcpu_get_cpuid_entry(struct kvm_vcpu *vcpu, static inline struct kvm_cpuid_entry2 *__vcpu_get_cpuid_entry(struct kvm_vcpu *vcpu,
uint32_t function, uint32_t function,
......
...@@ -712,16 +712,13 @@ void kvm_vm_release(struct kvm_vm *vmp) ...@@ -712,16 +712,13 @@ void kvm_vm_release(struct kvm_vm *vmp)
} }
static void __vm_mem_region_delete(struct kvm_vm *vm, static void __vm_mem_region_delete(struct kvm_vm *vm,
struct userspace_mem_region *region, struct userspace_mem_region *region)
bool unlink)
{ {
int ret; int ret;
if (unlink) { rb_erase(&region->gpa_node, &vm->regions.gpa_tree);
rb_erase(&region->gpa_node, &vm->regions.gpa_tree); rb_erase(&region->hva_node, &vm->regions.hva_tree);
rb_erase(&region->hva_node, &vm->regions.hva_tree); hash_del(&region->slot_node);
hash_del(&region->slot_node);
}
region->region.memory_size = 0; region->region.memory_size = 0;
vm_ioctl(vm, KVM_SET_USER_MEMORY_REGION2, &region->region); vm_ioctl(vm, KVM_SET_USER_MEMORY_REGION2, &region->region);
...@@ -762,7 +759,7 @@ void kvm_vm_free(struct kvm_vm *vmp) ...@@ -762,7 +759,7 @@ void kvm_vm_free(struct kvm_vm *vmp)
/* Free userspace_mem_regions. */ /* Free userspace_mem_regions. */
hash_for_each_safe(vmp->regions.slot_hash, ctr, node, region, slot_node) hash_for_each_safe(vmp->regions.slot_hash, ctr, node, region, slot_node)
__vm_mem_region_delete(vmp, region, false); __vm_mem_region_delete(vmp, region);
/* Free sparsebit arrays. */ /* Free sparsebit arrays. */
sparsebit_free(&vmp->vpages_valid); sparsebit_free(&vmp->vpages_valid);
...@@ -794,76 +791,6 @@ int kvm_memfd_alloc(size_t size, bool hugepages) ...@@ -794,76 +791,6 @@ int kvm_memfd_alloc(size_t size, bool hugepages)
return fd; return fd;
} }
/*
* Memory Compare, host virtual to guest virtual
*
* Input Args:
* hva - Starting host virtual address
* vm - Virtual Machine
* gva - Starting guest virtual address
* len - number of bytes to compare
*
* Output Args: None
*
* Input/Output Args: None
*
* Return:
* Returns 0 if the bytes starting at hva for a length of len
* are equal the guest virtual bytes starting at gva. Returns
* a value < 0, if bytes at hva are less than those at gva.
* Otherwise a value > 0 is returned.
*
* Compares the bytes starting at the host virtual address hva, for
* a length of len, to the guest bytes starting at the guest virtual
* address given by gva.
*/
int kvm_memcmp_hva_gva(void *hva, struct kvm_vm *vm, vm_vaddr_t gva, size_t len)
{
size_t amt;
/*
* Compare a batch of bytes until either a match is found
* or all the bytes have been compared.
*/
for (uintptr_t offset = 0; offset < len; offset += amt) {
uintptr_t ptr1 = (uintptr_t)hva + offset;
/*
* Determine host address for guest virtual address
* at offset.
*/
uintptr_t ptr2 = (uintptr_t)addr_gva2hva(vm, gva + offset);
/*
* Determine amount to compare on this pass.
* Don't allow the comparsion to cross a page boundary.
*/
amt = len - offset;
if ((ptr1 >> vm->page_shift) != ((ptr1 + amt) >> vm->page_shift))
amt = vm->page_size - (ptr1 % vm->page_size);
if ((ptr2 >> vm->page_shift) != ((ptr2 + amt) >> vm->page_shift))
amt = vm->page_size - (ptr2 % vm->page_size);
assert((ptr1 >> vm->page_shift) == ((ptr1 + amt - 1) >> vm->page_shift));
assert((ptr2 >> vm->page_shift) == ((ptr2 + amt - 1) >> vm->page_shift));
/*
* Perform the comparison. If there is a difference
* return that result to the caller, otherwise need
* to continue on looking for a mismatch.
*/
int ret = memcmp((void *)ptr1, (void *)ptr2, amt);
if (ret != 0)
return ret;
}
/*
* No mismatch found. Let the caller know the two memory
* areas are equal.
*/
return 0;
}
static void vm_userspace_mem_region_gpa_insert(struct rb_root *gpa_tree, static void vm_userspace_mem_region_gpa_insert(struct rb_root *gpa_tree,
struct userspace_mem_region *region) struct userspace_mem_region *region)
{ {
...@@ -1270,7 +1197,7 @@ void vm_mem_region_move(struct kvm_vm *vm, uint32_t slot, uint64_t new_gpa) ...@@ -1270,7 +1197,7 @@ void vm_mem_region_move(struct kvm_vm *vm, uint32_t slot, uint64_t new_gpa)
*/ */
void vm_mem_region_delete(struct kvm_vm *vm, uint32_t slot) void vm_mem_region_delete(struct kvm_vm *vm, uint32_t slot)
{ {
__vm_mem_region_delete(vm, memslot2region(vm, slot), true); __vm_mem_region_delete(vm, memslot2region(vm, slot));
} }
void vm_guest_mem_fallocate(struct kvm_vm *vm, uint64_t base, uint64_t size, void vm_guest_mem_fallocate(struct kvm_vm *vm, uint64_t base, uint64_t size,
......
...@@ -8,6 +8,73 @@ ...@@ -8,6 +8,73 @@
#include "processor.h" #include "processor.h"
#include "hyperv.h" #include "hyperv.h"
const struct kvm_cpuid2 *kvm_get_supported_hv_cpuid(void)
{
static struct kvm_cpuid2 *cpuid;
int kvm_fd;
if (cpuid)
return cpuid;
cpuid = allocate_kvm_cpuid2(MAX_NR_CPUID_ENTRIES);
kvm_fd = open_kvm_dev_path_or_exit();
kvm_ioctl(kvm_fd, KVM_GET_SUPPORTED_HV_CPUID, cpuid);
close(kvm_fd);
return cpuid;
}
void vcpu_set_hv_cpuid(struct kvm_vcpu *vcpu)
{
static struct kvm_cpuid2 *cpuid_full;
const struct kvm_cpuid2 *cpuid_sys, *cpuid_hv;
int i, nent = 0;
if (!cpuid_full) {
cpuid_sys = kvm_get_supported_cpuid();
cpuid_hv = kvm_get_supported_hv_cpuid();
cpuid_full = allocate_kvm_cpuid2(cpuid_sys->nent + cpuid_hv->nent);
if (!cpuid_full) {
perror("malloc");
abort();
}
/* Need to skip KVM CPUID leaves 0x400000xx */
for (i = 0; i < cpuid_sys->nent; i++) {
if (cpuid_sys->entries[i].function >= 0x40000000 &&
cpuid_sys->entries[i].function < 0x40000100)
continue;
cpuid_full->entries[nent] = cpuid_sys->entries[i];
nent++;
}
memcpy(&cpuid_full->entries[nent], cpuid_hv->entries,
cpuid_hv->nent * sizeof(struct kvm_cpuid_entry2));
cpuid_full->nent = nent + cpuid_hv->nent;
}
vcpu_init_cpuid(vcpu, cpuid_full);
}
const struct kvm_cpuid2 *vcpu_get_supported_hv_cpuid(struct kvm_vcpu *vcpu)
{
struct kvm_cpuid2 *cpuid = allocate_kvm_cpuid2(MAX_NR_CPUID_ENTRIES);
vcpu_ioctl(vcpu, KVM_GET_SUPPORTED_HV_CPUID, cpuid);
return cpuid;
}
bool kvm_hv_cpu_has(struct kvm_x86_cpu_feature feature)
{
if (!kvm_has_cap(KVM_CAP_SYS_HYPERV_CPUID))
return false;
return kvm_cpuid_has(kvm_get_supported_hv_cpuid(), feature);
}
struct hyperv_test_pages *vcpu_alloc_hyperv_test_pages(struct kvm_vm *vm, struct hyperv_test_pages *vcpu_alloc_hyperv_test_pages(struct kvm_vm *vm,
vm_vaddr_t *p_hv_pages_gva) vm_vaddr_t *p_hv_pages_gva)
{ {
......
...@@ -19,8 +19,6 @@ ...@@ -19,8 +19,6 @@
#define KERNEL_DS 0x10 #define KERNEL_DS 0x10
#define KERNEL_TSS 0x18 #define KERNEL_TSS 0x18
#define MAX_NR_CPUID_ENTRIES 100
vm_vaddr_t exception_handlers; vm_vaddr_t exception_handlers;
bool host_cpu_is_amd; bool host_cpu_is_amd;
bool host_cpu_is_intel; bool host_cpu_is_intel;
...@@ -1193,65 +1191,6 @@ void xen_hypercall(uint64_t nr, uint64_t a0, void *a1) ...@@ -1193,65 +1191,6 @@ void xen_hypercall(uint64_t nr, uint64_t a0, void *a1)
GUEST_ASSERT(!__xen_hypercall(nr, a0, a1)); GUEST_ASSERT(!__xen_hypercall(nr, a0, a1));
} }
const struct kvm_cpuid2 *kvm_get_supported_hv_cpuid(void)
{
static struct kvm_cpuid2 *cpuid;
int kvm_fd;
if (cpuid)
return cpuid;
cpuid = allocate_kvm_cpuid2(MAX_NR_CPUID_ENTRIES);
kvm_fd = open_kvm_dev_path_or_exit();
kvm_ioctl(kvm_fd, KVM_GET_SUPPORTED_HV_CPUID, cpuid);
close(kvm_fd);
return cpuid;
}
void vcpu_set_hv_cpuid(struct kvm_vcpu *vcpu)
{
static struct kvm_cpuid2 *cpuid_full;
const struct kvm_cpuid2 *cpuid_sys, *cpuid_hv;
int i, nent = 0;
if (!cpuid_full) {
cpuid_sys = kvm_get_supported_cpuid();
cpuid_hv = kvm_get_supported_hv_cpuid();
cpuid_full = allocate_kvm_cpuid2(cpuid_sys->nent + cpuid_hv->nent);
if (!cpuid_full) {
perror("malloc");
abort();
}
/* Need to skip KVM CPUID leaves 0x400000xx */
for (i = 0; i < cpuid_sys->nent; i++) {
if (cpuid_sys->entries[i].function >= 0x40000000 &&
cpuid_sys->entries[i].function < 0x40000100)
continue;
cpuid_full->entries[nent] = cpuid_sys->entries[i];
nent++;
}
memcpy(&cpuid_full->entries[nent], cpuid_hv->entries,
cpuid_hv->nent * sizeof(struct kvm_cpuid_entry2));
cpuid_full->nent = nent + cpuid_hv->nent;
}
vcpu_init_cpuid(vcpu, cpuid_full);
}
const struct kvm_cpuid2 *vcpu_get_supported_hv_cpuid(struct kvm_vcpu *vcpu)
{
struct kvm_cpuid2 *cpuid = allocate_kvm_cpuid2(MAX_NR_CPUID_ENTRIES);
vcpu_ioctl(vcpu, KVM_GET_SUPPORTED_HV_CPUID, cpuid);
return cpuid;
}
unsigned long vm_compute_max_gfn(struct kvm_vm *vm) unsigned long vm_compute_max_gfn(struct kvm_vm *vm)
{ {
const unsigned long num_ht_pages = 12 << (30 - vm->page_shift); /* 12 GiB */ const unsigned long num_ht_pages = 12 << (30 - vm->page_shift); /* 12 GiB */
......
...@@ -47,15 +47,18 @@ static void guest_code(void) ...@@ -47,15 +47,18 @@ static void guest_code(void)
/* /*
* Single step test, covers 2 basic instructions and 2 emulated * Single step test, covers 2 basic instructions and 2 emulated
* *
* Enable interrupts during the single stepping to see that * Enable interrupts during the single stepping to see that pending
* pending interrupt we raised is not handled due to KVM_GUESTDBG_BLOCKIRQ * interrupt we raised is not handled due to KVM_GUESTDBG_BLOCKIRQ.
*
* Write MSR_IA32_TSC_DEADLINE to verify that KVM's fastpath handler
* exits to userspace due to single-step being enabled.
*/ */
asm volatile("ss_start: " asm volatile("ss_start: "
"sti\n\t" "sti\n\t"
"xor %%eax,%%eax\n\t" "xor %%eax,%%eax\n\t"
"cpuid\n\t" "cpuid\n\t"
"movl $0x1a0,%%ecx\n\t" "movl $" __stringify(MSR_IA32_TSC_DEADLINE) ", %%ecx\n\t"
"rdmsr\n\t" "wrmsr\n\t"
"cli\n\t" "cli\n\t"
: : : "eax", "ebx", "ecx", "edx"); : : : "eax", "ebx", "ecx", "edx");
......
...@@ -242,7 +242,7 @@ int main(int argc, char *argv[]) ...@@ -242,7 +242,7 @@ int main(int argc, char *argv[])
TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX)); TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX));
TEST_REQUIRE(kvm_has_cap(KVM_CAP_NESTED_STATE)); TEST_REQUIRE(kvm_has_cap(KVM_CAP_NESTED_STATE));
TEST_REQUIRE(kvm_has_cap(KVM_CAP_HYPERV_ENLIGHTENED_VMCS)); TEST_REQUIRE(kvm_has_cap(KVM_CAP_HYPERV_ENLIGHTENED_VMCS));
TEST_REQUIRE(kvm_has_cap(KVM_CAP_HYPERV_DIRECT_TLBFLUSH)); TEST_REQUIRE(kvm_hv_cpu_has(HV_X64_NESTED_DIRECT_FLUSH));
vm = vm_create_with_one_vcpu(&vcpu, guest_code); vm = vm_create_with_one_vcpu(&vcpu, guest_code);
......
...@@ -157,7 +157,7 @@ int main(int argc, char *argv[]) ...@@ -157,7 +157,7 @@ int main(int argc, char *argv[])
int stage; int stage;
TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SVM)); TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SVM));
TEST_REQUIRE(kvm_has_cap(KVM_CAP_HYPERV_DIRECT_TLBFLUSH)); TEST_REQUIRE(kvm_hv_cpu_has(HV_X64_NESTED_DIRECT_FLUSH));
/* Create VM */ /* Create VM */
vm = vm_create_with_one_vcpu(&vcpu, guest_code); vm = vm_create_with_one_vcpu(&vcpu, guest_code);
......
...@@ -160,6 +160,36 @@ static void test_sev(void *guest_code, uint64_t policy) ...@@ -160,6 +160,36 @@ static void test_sev(void *guest_code, uint64_t policy)
kvm_vm_free(vm); kvm_vm_free(vm);
} }
static void guest_shutdown_code(void)
{
struct desc_ptr idt;
/* Clobber the IDT so that #UD is guaranteed to trigger SHUTDOWN. */
memset(&idt, 0, sizeof(idt));
__asm__ __volatile__("lidt %0" :: "m"(idt));
__asm__ __volatile__("ud2");
}
static void test_sev_es_shutdown(void)
{
struct kvm_vcpu *vcpu;
struct kvm_vm *vm;
uint32_t type = KVM_X86_SEV_ES_VM;
vm = vm_sev_create_with_one_vcpu(type, guest_shutdown_code, &vcpu);
vm_sev_launch(vm, SEV_POLICY_ES, NULL);
vcpu_run(vcpu);
TEST_ASSERT(vcpu->run->exit_reason == KVM_EXIT_SHUTDOWN,
"Wanted SHUTDOWN, got %s",
exit_reason_str(vcpu->run->exit_reason));
kvm_vm_free(vm);
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV)); TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV));
...@@ -171,6 +201,8 @@ int main(int argc, char *argv[]) ...@@ -171,6 +201,8 @@ int main(int argc, char *argv[])
test_sev(guest_sev_es_code, SEV_POLICY_ES | SEV_POLICY_NO_DBG); test_sev(guest_sev_es_code, SEV_POLICY_ES | SEV_POLICY_NO_DBG);
test_sev(guest_sev_es_code, SEV_POLICY_ES); test_sev(guest_sev_es_code, SEV_POLICY_ES);
test_sev_es_shutdown();
if (kvm_has_cap(KVM_CAP_XCRS) && if (kvm_has_cap(KVM_CAP_XCRS) &&
(xgetbv(0) & XFEATURE_MASK_X87_AVX) == XFEATURE_MASK_X87_AVX) { (xgetbv(0) & XFEATURE_MASK_X87_AVX) == XFEATURE_MASK_X87_AVX) {
test_sync_vmsa(0); test_sync_vmsa(0);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "test_util.h" #include "test_util.h"
#include "kvm_util.h" #include "kvm_util.h"
#include "processor.h" #include "processor.h"
#include "hyperv.h"
#define HCALL_REGION_GPA 0xc0000000ULL #define HCALL_REGION_GPA 0xc0000000ULL
#define HCALL_REGION_SLOT 10 #define HCALL_REGION_SLOT 10
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment