1 | /* |
2 | * QEMU Hypervisor.framework (HVF) support |
3 | * |
4 | * Copyright Google Inc., 2017 |
5 | * |
6 | * This work is licensed under the terms of the GNU GPL, version 2 or later. |
7 | * See the COPYING file in the top-level directory. |
8 | * |
9 | */ |
10 | |
11 | /* header to be included in non-HVF-specific code */ |
12 | |
13 | #ifndef HVF_H |
14 | #define HVF_H |
15 | |
16 | #include "cpu.h" |
17 | #include "qemu/bitops.h" |
18 | #include "exec/memory.h" |
19 | #include "sysemu/accel.h" |
20 | |
21 | extern bool hvf_allowed; |
22 | #ifdef CONFIG_HVF |
23 | #include <Hypervisor/hv.h> |
24 | #include <Hypervisor/hv_vmx.h> |
25 | #include <Hypervisor/hv_error.h> |
26 | #include "target/i386/cpu.h" |
27 | uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx, |
28 | int reg); |
29 | #define hvf_enabled() (hvf_allowed) |
30 | #else |
31 | #define hvf_enabled() 0 |
32 | #define hvf_get_supported_cpuid(func, idx, reg) 0 |
33 | #endif |
34 | |
35 | /* hvf_slot flags */ |
36 | #define HVF_SLOT_LOG (1 << 0) |
37 | |
38 | typedef struct hvf_slot { |
39 | uint64_t start; |
40 | uint64_t size; |
41 | uint8_t *mem; |
42 | int slot_id; |
43 | uint32_t flags; |
44 | MemoryRegion *region; |
45 | } hvf_slot; |
46 | |
47 | typedef struct hvf_vcpu_caps { |
48 | uint64_t vmx_cap_pinbased; |
49 | uint64_t vmx_cap_procbased; |
50 | uint64_t vmx_cap_procbased2; |
51 | uint64_t vmx_cap_entry; |
52 | uint64_t vmx_cap_exit; |
53 | uint64_t vmx_cap_preemption_timer; |
54 | } hvf_vcpu_caps; |
55 | |
56 | typedef struct HVFState { |
57 | AccelState parent; |
58 | hvf_slot slots[32]; |
59 | int num_slots; |
60 | |
61 | hvf_vcpu_caps *hvf_caps; |
62 | } HVFState; |
63 | extern HVFState *hvf_state; |
64 | |
65 | void hvf_set_phys_mem(MemoryRegionSection *, bool); |
66 | void hvf_handle_io(CPUArchState *, uint16_t, void *, |
67 | int, int, int); |
68 | hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t); |
69 | |
70 | /* Disable HVF if |disable| is 1, otherwise, enable it iff it is supported by |
71 | * the host CPU. Use hvf_enabled() after this to get the result. */ |
72 | void hvf_disable(int disable); |
73 | |
74 | /* Returns non-0 if the host CPU supports the VMX "unrestricted guest" feature |
75 | * which allows the virtual CPU to directly run in "real mode". If true, this |
76 | * allows QEMU to run several vCPU threads in parallel (see cpus.c). Otherwise, |
77 | * only a a single TCG thread can run, and it will call HVF to run the current |
78 | * instructions, except in case of "real mode" (paging disabled, typically at |
79 | * boot time), or MMIO operations. */ |
80 | |
81 | int hvf_sync_vcpus(void); |
82 | |
83 | int hvf_init_vcpu(CPUState *); |
84 | int hvf_vcpu_exec(CPUState *); |
85 | int hvf_smp_cpu_exec(CPUState *); |
86 | void hvf_cpu_synchronize_state(CPUState *); |
87 | void hvf_cpu_synchronize_post_reset(CPUState *); |
88 | void hvf_cpu_synchronize_post_init(CPUState *); |
89 | void _hvf_cpu_synchronize_post_init(CPUState *, run_on_cpu_data); |
90 | |
91 | void hvf_vcpu_destroy(CPUState *); |
92 | void hvf_raise_event(CPUState *); |
93 | /* void hvf_reset_vcpu_state(void *opaque); */ |
94 | void hvf_reset_vcpu(CPUState *); |
95 | void vmx_update_tpr(CPUState *); |
96 | void update_apic_tpr(CPUState *); |
97 | int hvf_put_registers(CPUState *); |
98 | void vmx_clear_int_window_exiting(CPUState *cpu); |
99 | |
100 | #define TYPE_HVF_ACCEL ACCEL_CLASS_NAME("hvf") |
101 | |
102 | #define HVF_STATE(obj) \ |
103 | OBJECT_CHECK(HVFState, (obj), TYPE_HVF_ACCEL) |
104 | |
105 | #endif |
106 | |