|
12 | 12 | #include <sys/stat.h> |
13 | 13 | #include <sys/types.h> |
14 | 14 |
|
15 | | -static int kvm, vmfd; |
16 | | -static struct kvm_run *run; |
17 | | -static struct kvm_regs regs; |
18 | | -static struct kvm_sregs sregs; |
19 | | -static int vcpufd; |
| 15 | +static int kvm = -1; |
| 16 | +static __thread int vcpufd = -1; |
| 17 | +static __thread struct kvm_run *run; |
| 18 | +static int mmap_size = -1; |
20 | 19 |
|
21 | 20 | int |
22 | | -vmm_create(void) |
| 21 | +vmm_create(vmm_vmid_t *vm) |
23 | 22 | { |
24 | 23 | int ret; |
25 | 24 |
|
26 | | - if ((kvm = open("/dev/kvm", O_RDWR | O_CLOEXEC)) < 0) |
27 | | - return VMM_ENOTSUP; |
| 25 | + if (kvm < 0) { |
| 26 | + if ((kvm = open("/dev/kvm", O_RDWR | O_CLOEXEC)) < 0) { |
| 27 | + return VMM_ENOTSUP; |
| 28 | + } |
| 29 | + } |
28 | 30 |
|
29 | 31 | /* check API version */ |
30 | 32 | if ((ret = ioctl(kvm, KVM_GET_API_VERSION, NULL)) < 0) |
31 | 33 | return VMM_ERROR; |
32 | 34 | if (ret != 12) |
33 | 35 | return VMM_ENOTSUP; |
34 | 36 |
|
35 | | - if ((vmfd = ioctl(kvm, KVM_CREATE_VM, 0UL)) < 0) |
| 37 | + if ((*vm = ioctl(kvm, KVM_CREATE_VM, 0UL)) < 0) |
36 | 38 | return VMM_ERROR; |
37 | 39 |
|
38 | 40 | return 0; |
39 | 41 | } |
40 | 42 |
|
41 | 43 | int |
42 | | -vmm_destroy(void) |
| 44 | +vmm_destroy(vmm_vmid_t vm) |
43 | 45 | { |
44 | | - close(vmfd); |
45 | | - close(kvm); |
| 46 | + close(vm); |
46 | 47 | return 0; |
47 | 48 | } |
48 | 49 |
|
49 | 50 | int |
50 | | -vmm_memory_map(vmm_uvaddr_t uva, vmm_gpaddr_t gpa, size_t size, vmm_memory_flags_t flags) |
| 51 | +vmm_memory_map(vmm_vmid_t vm, vmm_uvaddr_t uva, vmm_gpaddr_t gpa, size_t size, vmm_memory_flags_t flags) |
51 | 52 | { |
52 | 53 | struct kvm_userspace_memory_region region = { |
53 | 54 | .slot = 0, |
| 55 | + .flags = 0, |
54 | 56 | .guest_phys_addr = gpa, |
55 | 57 | .memory_size = size, |
56 | 58 | .userspace_addr = (uint64_t)uva, |
57 | 59 | }; |
58 | 60 | int ret; |
59 | 61 |
|
60 | | - if ((ret = ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, ®ion)) < 0) |
| 62 | + if ((ret = ioctl(vm, KVM_SET_USER_MEMORY_REGION, ®ion)) < 0) |
61 | 63 | return VMM_ERROR; |
62 | 64 |
|
63 | 65 | return 0; |
64 | 66 | } |
65 | 67 |
|
66 | 68 | int |
67 | | -vmm_cpu_create(void) |
| 69 | +vmm_cpu_create(vmm_vmid_t vm, vmm_cpuid_t *cpu) |
68 | 70 | { |
69 | | - int mmap_size; |
70 | | - |
71 | | - if ((vcpufd = ioctl(vmfd, KVM_CREATE_VCPU, 0UL)) < 0) |
| 71 | + if ((vcpufd = ioctl(vm, KVM_CREATE_VCPU, 0UL)) < 0) |
72 | 72 | return VMM_ERROR; |
73 | 73 |
|
| 74 | + *cpu = vcpufd; |
| 75 | + |
74 | 76 | /* Map the shared kvm_run structure and following data. */ |
75 | | - if ((mmap_size = ioctl(kvm, KVM_GET_VCPU_MMAP_SIZE, NULL)) < 0) |
76 | | - return VMM_ERROR; |
77 | | - if ((run = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, vcpufd, 0)) == 0) |
| 77 | + if (mmap_size < 0) { |
| 78 | + if ((mmap_size = ioctl(kvm, KVM_GET_VCPU_MMAP_SIZE, NULL)) < 0) |
| 79 | + return VMM_ERROR; |
| 80 | + } |
| 81 | + if ((run = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, vcpufd, 0)) == MAP_FAILED) |
78 | 82 | return VMM_ERROR; |
79 | | - |
| 83 | + assert(run != 0); |
80 | 84 | return 0; |
81 | 85 | } |
82 | 86 |
|
83 | 87 | int |
84 | | -vmm_cpu_destroy(void) |
| 88 | +vmm_cpu_destroy(vmm_vmid_t vm) |
85 | 89 | { |
86 | | - close(vcpufd); |
| 90 | + if (munmap(run, mmap_size) < 0) |
| 91 | + return -VMM_ERROR; |
87 | 92 | run = NULL; |
| 93 | + close(vcpufd); |
88 | 94 | return 0; |
89 | 95 | } |
90 | 96 |
|
91 | 97 | int |
92 | | -vmm_cpu_run(void) |
| 98 | +vmm_cpu_run(vmm_vmid_t vm) |
93 | 99 | { |
94 | 100 | if (ioctl(vcpufd, KVM_RUN, NULL) < 0) |
95 | 101 | return VMM_ERROR; |
@@ -135,11 +141,14 @@ struct kvm_sregs { |
135 | 141 | */ |
136 | 142 |
|
137 | 143 | int |
138 | | -vmm_cpu_write_register(vmm_x64_reg_t reg, uint64_t value) |
| 144 | +vmm_cpu_set_register(vmm_vmid_t vm, vmm_cpuid_t cpu, vmm_x64_reg_t reg, uint64_t value) |
139 | 145 | { |
140 | | - if (ioctl(vcpufd, KVM_GET_REGS, ®s) < 0) |
| 146 | + static struct kvm_regs regs; |
| 147 | + static struct kvm_sregs sregs; |
| 148 | + |
| 149 | + if (ioctl(cpu, KVM_GET_REGS, ®s) < 0) |
141 | 150 | return VMM_ERROR; |
142 | | - if (ioctl(vcpufd, KVM_GET_SREGS, &sregs) < 0) |
| 151 | + if (ioctl(cpu, KVM_GET_SREGS, &sregs) < 0) |
143 | 152 | return VMM_ERROR; |
144 | 153 |
|
145 | 154 | switch (reg) { |
@@ -199,20 +208,23 @@ vmm_cpu_write_register(vmm_x64_reg_t reg, uint64_t value) |
199 | 208 | assert(false); |
200 | 209 | } |
201 | 210 |
|
202 | | - if (ioctl(vcpufd, KVM_SET_REGS, ®s) < 0) |
| 211 | + if (ioctl(cpu, KVM_SET_REGS, ®s) < 0) |
203 | 212 | return VMM_ERROR; |
204 | | - if (ioctl(vcpufd, KVM_SET_SREGS, &sregs) < 0) |
| 213 | + if (ioctl(cpu, KVM_SET_SREGS, &sregs) < 0) |
205 | 214 | return VMM_ERROR; |
206 | 215 |
|
207 | 216 | return 0; |
208 | 217 | } |
209 | 218 |
|
210 | 219 | int |
211 | | -vmm_cpu_read_register(vmm_x64_reg_t reg, uint64_t *value) |
| 220 | +vmm_cpu_get_register(vmm_vmid_t vm, vmm_cpuid_t cpu, vmm_x64_reg_t reg, uint64_t *value) |
212 | 221 | { |
213 | | - if (ioctl(vcpufd, KVM_GET_REGS, ®s) < 0) |
| 222 | + static struct kvm_regs regs; |
| 223 | + static struct kvm_sregs sregs; |
| 224 | + |
| 225 | + if (ioctl(cpu, KVM_GET_REGS, ®s) < 0) |
214 | 226 | return VMM_ERROR; |
215 | | - if (ioctl(vcpufd, KVM_GET_SREGS, &sregs) < 0) |
| 227 | + if (ioctl(cpu, KVM_GET_SREGS, &sregs) < 0) |
216 | 228 | return VMM_ERROR; |
217 | 229 |
|
218 | 230 | switch (reg) { |
@@ -274,7 +286,7 @@ vmm_cpu_read_register(vmm_x64_reg_t reg, uint64_t *value) |
274 | 286 | } |
275 | 287 |
|
276 | 288 | int |
277 | | -vmm_get(int id, uint64_t *value) |
| 289 | +vmm_get(vmm_vmid_t vm, int id, uint64_t *value) |
278 | 290 | { |
279 | 291 | assert(id == VMM_CTRL_EXIT_REASON); |
280 | 292 |
|
|
0 commit comments