| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: nvmm_x86_svm.c,v 1.46 2019/05/11 07:31:56 maxv Exp $ */ | | 1 | /* $NetBSD: nvmm_x86_svm.c,v 1.46.4.1 2019/10/06 11:04:55 martin Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2018 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2018 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Maxime Villard. | | 8 | * by Maxime Villard. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -20,27 +20,27 @@ | | | @@ -20,27 +20,27 @@ |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. | | 29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | #include <sys/cdefs.h> | | 32 | #include <sys/cdefs.h> |
33 | __KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.46 2019/05/11 07:31:56 maxv Exp $"); | | 33 | __KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.46.4.1 2019/10/06 11:04:55 martin Exp $"); |
34 | | | 34 | |
35 | #include <sys/param.h> | | 35 | #include <sys/param.h> |
36 | #include <sys/systm.h> | | 36 | #include <sys/systm.h> |
37 | #include <sys/kernel.h> | | 37 | #include <sys/kernel.h> |
38 | #include <sys/kmem.h> | | 38 | #include <sys/kmem.h> |
39 | #include <sys/cpu.h> | | 39 | #include <sys/cpu.h> |
40 | #include <sys/xcall.h> | | 40 | #include <sys/xcall.h> |
41 | #include <sys/mman.h> | | 41 | #include <sys/mman.h> |
42 | | | 42 | |
43 | #include <uvm/uvm.h> | | 43 | #include <uvm/uvm.h> |
44 | #include <uvm/uvm_page.h> | | 44 | #include <uvm/uvm_page.h> |
45 | | | 45 | |
46 | #include <x86/cputypes.h> | | 46 | #include <x86/cputypes.h> |
| @@ -192,43 +192,45 @@ int svm_vmrun(paddr_t, uint64_t *); | | | @@ -192,43 +192,45 @@ int svm_vmrun(paddr_t, uint64_t *); |
192 | #define VMCB_EXITCODE_VMMCALL 0x0081 | | 192 | #define VMCB_EXITCODE_VMMCALL 0x0081 |
193 | #define VMCB_EXITCODE_VMLOAD 0x0082 | | 193 | #define VMCB_EXITCODE_VMLOAD 0x0082 |
194 | #define VMCB_EXITCODE_VMSAVE 0x0083 | | 194 | #define VMCB_EXITCODE_VMSAVE 0x0083 |
195 | #define VMCB_EXITCODE_STGI 0x0084 | | 195 | #define VMCB_EXITCODE_STGI 0x0084 |
196 | #define VMCB_EXITCODE_CLGI 0x0085 | | 196 | #define VMCB_EXITCODE_CLGI 0x0085 |
197 | #define VMCB_EXITCODE_SKINIT 0x0086 | | 197 | #define VMCB_EXITCODE_SKINIT 0x0086 |
198 | #define VMCB_EXITCODE_RDTSCP 0x0087 | | 198 | #define VMCB_EXITCODE_RDTSCP 0x0087 |
199 | #define VMCB_EXITCODE_ICEBP 0x0088 | | 199 | #define VMCB_EXITCODE_ICEBP 0x0088 |
200 | #define VMCB_EXITCODE_WBINVD 0x0089 | | 200 | #define VMCB_EXITCODE_WBINVD 0x0089 |
201 | #define VMCB_EXITCODE_MONITOR 0x008A | | 201 | #define VMCB_EXITCODE_MONITOR 0x008A |
202 | #define VMCB_EXITCODE_MWAIT 0x008B | | 202 | #define VMCB_EXITCODE_MWAIT 0x008B |
203 | #define VMCB_EXITCODE_MWAIT_CONDITIONAL 0x008C | | 203 | #define VMCB_EXITCODE_MWAIT_CONDITIONAL 0x008C |
204 | #define VMCB_EXITCODE_XSETBV 0x008D | | 204 | #define VMCB_EXITCODE_XSETBV 0x008D |
| | | 205 | #define VMCB_EXITCODE_RDPRU 0x008E |
205 | #define VMCB_EXITCODE_EFER_WRITE_TRAP 0x008F | | 206 | #define VMCB_EXITCODE_EFER_WRITE_TRAP 0x008F |
206 | #define VMCB_EXITCODE_CR0_WRITE_TRAP 0x0090 | | 207 | #define VMCB_EXITCODE_CR0_WRITE_TRAP 0x0090 |
207 | #define VMCB_EXITCODE_CR1_WRITE_TRAP 0x0091 | | 208 | #define VMCB_EXITCODE_CR1_WRITE_TRAP 0x0091 |
208 | #define VMCB_EXITCODE_CR2_WRITE_TRAP 0x0092 | | 209 | #define VMCB_EXITCODE_CR2_WRITE_TRAP 0x0092 |
209 | #define VMCB_EXITCODE_CR3_WRITE_TRAP 0x0093 | | 210 | #define VMCB_EXITCODE_CR3_WRITE_TRAP 0x0093 |
210 | #define VMCB_EXITCODE_CR4_WRITE_TRAP 0x0094 | | 211 | #define VMCB_EXITCODE_CR4_WRITE_TRAP 0x0094 |
211 | #define VMCB_EXITCODE_CR5_WRITE_TRAP 0x0095 | | 212 | #define VMCB_EXITCODE_CR5_WRITE_TRAP 0x0095 |
212 | #define VMCB_EXITCODE_CR6_WRITE_TRAP 0x0096 | | 213 | #define VMCB_EXITCODE_CR6_WRITE_TRAP 0x0096 |
213 | #define VMCB_EXITCODE_CR7_WRITE_TRAP 0x0097 | | 214 | #define VMCB_EXITCODE_CR7_WRITE_TRAP 0x0097 |
214 | #define VMCB_EXITCODE_CR8_WRITE_TRAP 0x0098 | | 215 | #define VMCB_EXITCODE_CR8_WRITE_TRAP 0x0098 |
215 | #define VMCB_EXITCODE_CR9_WRITE_TRAP 0x0099 | | 216 | #define VMCB_EXITCODE_CR9_WRITE_TRAP 0x0099 |
216 | #define VMCB_EXITCODE_CR10_WRITE_TRAP 0x009A | | 217 | #define VMCB_EXITCODE_CR10_WRITE_TRAP 0x009A |
217 | #define VMCB_EXITCODE_CR11_WRITE_TRAP 0x009B | | 218 | #define VMCB_EXITCODE_CR11_WRITE_TRAP 0x009B |
218 | #define VMCB_EXITCODE_CR12_WRITE_TRAP 0x009C | | 219 | #define VMCB_EXITCODE_CR12_WRITE_TRAP 0x009C |
219 | #define VMCB_EXITCODE_CR13_WRITE_TRAP 0x009D | | 220 | #define VMCB_EXITCODE_CR13_WRITE_TRAP 0x009D |
220 | #define VMCB_EXITCODE_CR14_WRITE_TRAP 0x009E | | 221 | #define VMCB_EXITCODE_CR14_WRITE_TRAP 0x009E |
221 | #define VMCB_EXITCODE_CR15_WRITE_TRAP 0x009F | | 222 | #define VMCB_EXITCODE_CR15_WRITE_TRAP 0x009F |
| | | 223 | #define VMCB_EXITCODE_MCOMMIT 0x00A3 |
222 | #define VMCB_EXITCODE_NPF 0x0400 | | 224 | #define VMCB_EXITCODE_NPF 0x0400 |
223 | #define VMCB_EXITCODE_AVIC_INCOMP_IPI 0x0401 | | 225 | #define VMCB_EXITCODE_AVIC_INCOMP_IPI 0x0401 |
224 | #define VMCB_EXITCODE_AVIC_NOACCEL 0x0402 | | 226 | #define VMCB_EXITCODE_AVIC_NOACCEL 0x0402 |
225 | #define VMCB_EXITCODE_VMGEXIT 0x0403 | | 227 | #define VMCB_EXITCODE_VMGEXIT 0x0403 |
226 | #define VMCB_EXITCODE_INVALID -1 | | 228 | #define VMCB_EXITCODE_INVALID -1 |
227 | | | 229 | |
228 | /* -------------------------------------------------------------------------- */ | | 230 | /* -------------------------------------------------------------------------- */ |
229 | | | 231 | |
230 | struct vmcb_ctrl { | | 232 | struct vmcb_ctrl { |
231 | uint32_t intercept_cr; | | 233 | uint32_t intercept_cr; |
232 | #define VMCB_CTRL_INTERCEPT_RCR(x) __BIT( 0 + x) | | 234 | #define VMCB_CTRL_INTERCEPT_RCR(x) __BIT( 0 + x) |
233 | #define VMCB_CTRL_INTERCEPT_WCR(x) __BIT(16 + x) | | 235 | #define VMCB_CTRL_INTERCEPT_WCR(x) __BIT(16 + x) |
234 | | | 236 | |
| @@ -275,32 +277,37 @@ struct vmcb_ctrl { | | | @@ -275,32 +277,37 @@ struct vmcb_ctrl { |
275 | | | 277 | |
276 | uint32_t intercept_misc2; | | 278 | uint32_t intercept_misc2; |
277 | #define VMCB_CTRL_INTERCEPT_VMRUN __BIT(0) | | 279 | #define VMCB_CTRL_INTERCEPT_VMRUN __BIT(0) |
278 | #define VMCB_CTRL_INTERCEPT_VMMCALL __BIT(1) | | 280 | #define VMCB_CTRL_INTERCEPT_VMMCALL __BIT(1) |
279 | #define VMCB_CTRL_INTERCEPT_VMLOAD __BIT(2) | | 281 | #define VMCB_CTRL_INTERCEPT_VMLOAD __BIT(2) |
280 | #define VMCB_CTRL_INTERCEPT_VMSAVE __BIT(3) | | 282 | #define VMCB_CTRL_INTERCEPT_VMSAVE __BIT(3) |
281 | #define VMCB_CTRL_INTERCEPT_STGI __BIT(4) | | 283 | #define VMCB_CTRL_INTERCEPT_STGI __BIT(4) |
282 | #define VMCB_CTRL_INTERCEPT_CLGI __BIT(5) | | 284 | #define VMCB_CTRL_INTERCEPT_CLGI __BIT(5) |
283 | #define VMCB_CTRL_INTERCEPT_SKINIT __BIT(6) | | 285 | #define VMCB_CTRL_INTERCEPT_SKINIT __BIT(6) |
284 | #define VMCB_CTRL_INTERCEPT_RDTSCP __BIT(7) | | 286 | #define VMCB_CTRL_INTERCEPT_RDTSCP __BIT(7) |
285 | #define VMCB_CTRL_INTERCEPT_ICEBP __BIT(8) | | 287 | #define VMCB_CTRL_INTERCEPT_ICEBP __BIT(8) |
286 | #define VMCB_CTRL_INTERCEPT_WBINVD __BIT(9) | | 288 | #define VMCB_CTRL_INTERCEPT_WBINVD __BIT(9) |
287 | #define VMCB_CTRL_INTERCEPT_MONITOR __BIT(10) | | 289 | #define VMCB_CTRL_INTERCEPT_MONITOR __BIT(10) |
288 | #define VMCB_CTRL_INTERCEPT_MWAIT __BIT(12) | | 290 | #define VMCB_CTRL_INTERCEPT_MWAIT __BIT(11) |
| | | 291 | #define VMCB_CTRL_INTERCEPT_MWAIT_ARMED __BIT(12) |
289 | #define VMCB_CTRL_INTERCEPT_XSETBV __BIT(13) | | 292 | #define VMCB_CTRL_INTERCEPT_XSETBV __BIT(13) |
| | | 293 | #define VMCB_CTRL_INTERCEPT_RDPRU __BIT(14) |
290 | #define VMCB_CTRL_INTERCEPT_EFER_SPEC __BIT(15) | | 294 | #define VMCB_CTRL_INTERCEPT_EFER_SPEC __BIT(15) |
291 | #define VMCB_CTRL_INTERCEPT_WCR_SPEC(x) __BIT(16 + x) | | 295 | #define VMCB_CTRL_INTERCEPT_WCR_SPEC(x) __BIT(16 + x) |
292 | | | 296 | |
293 | uint8_t rsvd1[40]; | | 297 | uint32_t intercept_misc3; |
| | | 298 | #define VMCB_CTRL_INTERCEPT_MCOMMIT __BIT(3) |
| | | 299 | |
| | | 300 | uint8_t rsvd1[36]; |
294 | uint16_t pause_filt_thresh; | | 301 | uint16_t pause_filt_thresh; |
295 | uint16_t pause_filt_cnt; | | 302 | uint16_t pause_filt_cnt; |
296 | uint64_t iopm_base_pa; | | 303 | uint64_t iopm_base_pa; |
297 | uint64_t msrpm_base_pa; | | 304 | uint64_t msrpm_base_pa; |
298 | uint64_t tsc_offset; | | 305 | uint64_t tsc_offset; |
299 | uint32_t guest_asid; | | 306 | uint32_t guest_asid; |
300 | | | 307 | |
301 | uint32_t tlb_ctrl; | | 308 | uint32_t tlb_ctrl; |
302 | #define VMCB_CTRL_TLB_CTRL_FLUSH_ALL 0x01 | | 309 | #define VMCB_CTRL_TLB_CTRL_FLUSH_ALL 0x01 |
303 | #define VMCB_CTRL_TLB_CTRL_FLUSH_GUEST 0x03 | | 310 | #define VMCB_CTRL_TLB_CTRL_FLUSH_GUEST 0x03 |
304 | #define VMCB_CTRL_TLB_CTRL_FLUSH_GUEST_NONGLOBAL 0x07 | | 311 | #define VMCB_CTRL_TLB_CTRL_FLUSH_GUEST_NONGLOBAL 0x07 |
305 | | | 312 | |
306 | uint64_t v; | | 313 | uint64_t v; |
| @@ -322,26 +329,28 @@ struct vmcb_ctrl { | | | @@ -322,26 +329,28 @@ struct vmcb_ctrl { |
322 | uint64_t exitinfo2; | | 329 | uint64_t exitinfo2; |
323 | | | 330 | |
324 | uint64_t exitintinfo; | | 331 | uint64_t exitintinfo; |
325 | #define VMCB_CTRL_EXITINTINFO_VECTOR __BITS(7,0) | | 332 | #define VMCB_CTRL_EXITINTINFO_VECTOR __BITS(7,0) |
326 | #define VMCB_CTRL_EXITINTINFO_TYPE __BITS(10,8) | | 333 | #define VMCB_CTRL_EXITINTINFO_TYPE __BITS(10,8) |
327 | #define VMCB_CTRL_EXITINTINFO_EV __BIT(11) | | 334 | #define VMCB_CTRL_EXITINTINFO_EV __BIT(11) |
328 | #define VMCB_CTRL_EXITINTINFO_V __BIT(31) | | 335 | #define VMCB_CTRL_EXITINTINFO_V __BIT(31) |
329 | #define VMCB_CTRL_EXITINTINFO_ERRORCODE __BITS(63,32) | | 336 | #define VMCB_CTRL_EXITINTINFO_ERRORCODE __BITS(63,32) |
330 | | | 337 | |
331 | uint64_t enable1; | | 338 | uint64_t enable1; |
332 | #define VMCB_CTRL_ENABLE_NP __BIT(0) | | 339 | #define VMCB_CTRL_ENABLE_NP __BIT(0) |
333 | #define VMCB_CTRL_ENABLE_SEV __BIT(1) | | 340 | #define VMCB_CTRL_ENABLE_SEV __BIT(1) |
334 | #define VMCB_CTRL_ENABLE_ES_SEV __BIT(2) | | 341 | #define VMCB_CTRL_ENABLE_ES_SEV __BIT(2) |
| | | 342 | #define VMCB_CTRL_ENABLE_GMET __BIT(3) |
| | | 343 | #define VMCB_CTRL_ENABLE_VTE __BIT(5) |
335 | | | 344 | |
336 | uint64_t avic; | | 345 | uint64_t avic; |
337 | #define VMCB_CTRL_AVIC_APIC_BAR __BITS(51,0) | | 346 | #define VMCB_CTRL_AVIC_APIC_BAR __BITS(51,0) |
338 | | | 347 | |
339 | uint64_t ghcb; | | 348 | uint64_t ghcb; |
340 | | | 349 | |
341 | uint64_t eventinj; | | 350 | uint64_t eventinj; |
342 | #define VMCB_CTRL_EVENTINJ_VECTOR __BITS(7,0) | | 351 | #define VMCB_CTRL_EVENTINJ_VECTOR __BITS(7,0) |
343 | #define VMCB_CTRL_EVENTINJ_TYPE __BITS(10,8) | | 352 | #define VMCB_CTRL_EVENTINJ_TYPE __BITS(10,8) |
344 | #define VMCB_CTRL_EVENTINJ_EV __BIT(11) | | 353 | #define VMCB_CTRL_EVENTINJ_EV __BIT(11) |
345 | #define VMCB_CTRL_EVENTINJ_V __BIT(31) | | 354 | #define VMCB_CTRL_EVENTINJ_V __BIT(31) |
346 | #define VMCB_CTRL_EVENTINJ_ERRORCODE __BITS(63,32) | | 355 | #define VMCB_CTRL_EVENTINJ_ERRORCODE __BITS(63,32) |
347 | | | 356 | |
| @@ -2112,27 +2121,27 @@ svm_vcpu_destroy(struct nvmm_machine *ma | | | @@ -2112,27 +2121,27 @@ svm_vcpu_destroy(struct nvmm_machine *ma |
2112 | } | | 2121 | } |
2113 | | | 2122 | |
2114 | /* -------------------------------------------------------------------------- */ | | 2123 | /* -------------------------------------------------------------------------- */ |
2115 | | | 2124 | |
2116 | static void | | 2125 | static void |
2117 | svm_tlb_flush(struct pmap *pm) | | 2126 | svm_tlb_flush(struct pmap *pm) |
2118 | { | | 2127 | { |
2119 | struct nvmm_machine *mach = pm->pm_data; | | 2128 | struct nvmm_machine *mach = pm->pm_data; |
2120 | struct svm_machdata *machdata = mach->machdata; | | 2129 | struct svm_machdata *machdata = mach->machdata; |
2121 | | | 2130 | |
2122 | atomic_inc_64(&machdata->mach_htlb_gen); | | 2131 | atomic_inc_64(&machdata->mach_htlb_gen); |
2123 | | | 2132 | |
2124 | /* Generates IPIs, which cause #VMEXITs. */ | | 2133 | /* Generates IPIs, which cause #VMEXITs. */ |
2125 | pmap_tlb_shootdown(pmap_kernel(), -1, PG_G, TLBSHOOT_UPDATE); | | 2134 | pmap_tlb_shootdown(pmap_kernel(), -1, PTE_G, TLBSHOOT_UPDATE); |
2126 | } | | 2135 | } |
2127 | | | 2136 | |
2128 | static void | | 2137 | static void |
2129 | svm_machine_create(struct nvmm_machine *mach) | | 2138 | svm_machine_create(struct nvmm_machine *mach) |
2130 | { | | 2139 | { |
2131 | struct svm_machdata *machdata; | | 2140 | struct svm_machdata *machdata; |
2132 | | | 2141 | |
2133 | /* Fill in pmap info. */ | | 2142 | /* Fill in pmap info. */ |
2134 | mach->vm->vm_map.pmap->pm_data = (void *)mach; | | 2143 | mach->vm->vm_map.pmap->pm_data = (void *)mach; |
2135 | mach->vm->vm_map.pmap->pm_tlb_flush = svm_tlb_flush; | | 2144 | mach->vm->vm_map.pmap->pm_tlb_flush = svm_tlb_flush; |
2136 | | | 2145 | |
2137 | machdata = kmem_zalloc(sizeof(struct svm_machdata), KM_SLEEP); | | 2146 | machdata = kmem_zalloc(sizeof(struct svm_machdata), KM_SLEEP); |
2138 | mach->machdata = machdata; | | 2147 | mach->machdata = machdata; |