diff options
author | Wincy Van <fanwenyi0529@gmail.com> | 2015-02-03 10:56:30 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-02-03 11:06:51 -0500 |
commit | b9c237bb1db61f107b5d7cee5008e4a6b96ff800 (patch) | |
tree | 406fc00264bc06cfc32c34dd5b093c6bd0411f82 | |
parent | f2b93280edee5c7e95eecba48707a4e4a19b17c8 (diff) |
KVM: nVMX: Make nested control MSRs per-cpu
To enable nested apicv support, we need per-cpu vmx
control MSRs:
1. If in-kernel irqchip is enabled, we can enable nested
posted interrupt, we should set posted intr bit in
the nested_vmx_pinbased_ctls_high.
2. If in-kernel irqchip is disabled, we can not enable
nested posted interrupt, the posted intr bit
in the nested_vmx_pinbased_ctls_high will be cleared.
Since there would be different settings about in-kernel
irqchip between VMs, different nested control MSRs
are needed.
Signed-off-by: Wincy Van <fanwenyi0529@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | arch/x86/kvm/vmx.c | 215 |
1 files changed, 129 insertions, 86 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 25984e7e8a4d..a17bbb862f91 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -411,6 +411,23 @@ struct nested_vmx { | |||
411 | 411 | ||
412 | /* to migrate it to L2 if VM_ENTRY_LOAD_DEBUG_CONTROLS is off */ | 412 | /* to migrate it to L2 if VM_ENTRY_LOAD_DEBUG_CONTROLS is off */ |
413 | u64 vmcs01_debugctl; | 413 | u64 vmcs01_debugctl; |
414 | |||
415 | u32 nested_vmx_procbased_ctls_low; | ||
416 | u32 nested_vmx_procbased_ctls_high; | ||
417 | u32 nested_vmx_true_procbased_ctls_low; | ||
418 | u32 nested_vmx_secondary_ctls_low; | ||
419 | u32 nested_vmx_secondary_ctls_high; | ||
420 | u32 nested_vmx_pinbased_ctls_low; | ||
421 | u32 nested_vmx_pinbased_ctls_high; | ||
422 | u32 nested_vmx_exit_ctls_low; | ||
423 | u32 nested_vmx_exit_ctls_high; | ||
424 | u32 nested_vmx_true_exit_ctls_low; | ||
425 | u32 nested_vmx_entry_ctls_low; | ||
426 | u32 nested_vmx_entry_ctls_high; | ||
427 | u32 nested_vmx_true_entry_ctls_low; | ||
428 | u32 nested_vmx_misc_low; | ||
429 | u32 nested_vmx_misc_high; | ||
430 | u32 nested_vmx_ept_caps; | ||
414 | }; | 431 | }; |
415 | 432 | ||
416 | #define POSTED_INTR_ON 0 | 433 | #define POSTED_INTR_ON 0 |
@@ -2292,20 +2309,8 @@ static inline bool nested_vmx_allowed(struct kvm_vcpu *vcpu) | |||
2292 | * if the corresponding bit in the (32-bit) control field *must* be on, and a | 2309 | * if the corresponding bit in the (32-bit) control field *must* be on, and a |
2293 | * bit in the high half is on if the corresponding bit in the control field | 2310 | * bit in the high half is on if the corresponding bit in the control field |
2294 | * may be on. See also vmx_control_verify(). | 2311 | * may be on. See also vmx_control_verify(). |
2295 | * TODO: allow these variables to be modified (downgraded) by module options | ||
2296 | * or other means. | ||
2297 | */ | 2312 | */ |
2298 | static u32 nested_vmx_procbased_ctls_low, nested_vmx_procbased_ctls_high; | 2313 | static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx) |
2299 | static u32 nested_vmx_true_procbased_ctls_low; | ||
2300 | static u32 nested_vmx_secondary_ctls_low, nested_vmx_secondary_ctls_high; | ||
2301 | static u32 nested_vmx_pinbased_ctls_low, nested_vmx_pinbased_ctls_high; | ||
2302 | static u32 nested_vmx_exit_ctls_low, nested_vmx_exit_ctls_high; | ||
2303 | static u32 nested_vmx_true_exit_ctls_low; | ||
2304 | static u32 nested_vmx_entry_ctls_low, nested_vmx_entry_ctls_high; | ||
2305 | static u32 nested_vmx_true_entry_ctls_low; | ||
2306 | static u32 nested_vmx_misc_low, nested_vmx_misc_high; | ||
2307 | static u32 nested_vmx_ept_caps; | ||
2308 | static __init void nested_vmx_setup_ctls_msrs(void) | ||
2309 | { | 2314 | { |
2310 | /* | 2315 | /* |
2311 | * Note that as a general rule, the high half of the MSRs (bits in | 2316 | * Note that as a general rule, the high half of the MSRs (bits in |
@@ -2324,57 +2329,71 @@ static __init void nested_vmx_setup_ctls_msrs(void) | |||
2324 | 2329 | ||
2325 | /* pin-based controls */ | 2330 | /* pin-based controls */ |
2326 | rdmsr(MSR_IA32_VMX_PINBASED_CTLS, | 2331 | rdmsr(MSR_IA32_VMX_PINBASED_CTLS, |
2327 | nested_vmx_pinbased_ctls_low, nested_vmx_pinbased_ctls_high); | 2332 | vmx->nested.nested_vmx_pinbased_ctls_low, |
2328 | nested_vmx_pinbased_ctls_low |= PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR; | 2333 | vmx->nested.nested_vmx_pinbased_ctls_high); |
2329 | nested_vmx_pinbased_ctls_high &= PIN_BASED_EXT_INTR_MASK | | 2334 | vmx->nested.nested_vmx_pinbased_ctls_low |= |
2330 | PIN_BASED_NMI_EXITING | PIN_BASED_VIRTUAL_NMIS; | 2335 | PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR; |
2331 | nested_vmx_pinbased_ctls_high |= PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR | | 2336 | vmx->nested.nested_vmx_pinbased_ctls_high &= |
2337 | PIN_BASED_EXT_INTR_MASK | | ||
2338 | PIN_BASED_NMI_EXITING | | ||
2339 | PIN_BASED_VIRTUAL_NMIS; | ||
2340 | vmx->nested.nested_vmx_pinbased_ctls_high |= | ||
2341 | PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR | | ||
2332 | PIN_BASED_VMX_PREEMPTION_TIMER; | 2342 | PIN_BASED_VMX_PREEMPTION_TIMER; |
2333 | 2343 | ||
2334 | /* exit controls */ | 2344 | /* exit controls */ |
2335 | rdmsr(MSR_IA32_VMX_EXIT_CTLS, | 2345 | rdmsr(MSR_IA32_VMX_EXIT_CTLS, |
2336 | nested_vmx_exit_ctls_low, nested_vmx_exit_ctls_high); | 2346 | vmx->nested.nested_vmx_exit_ctls_low, |
2337 | nested_vmx_exit_ctls_low = VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR; | 2347 | vmx->nested.nested_vmx_exit_ctls_high); |
2348 | vmx->nested.nested_vmx_exit_ctls_low = | ||
2349 | VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR; | ||
2338 | 2350 | ||
2339 | nested_vmx_exit_ctls_high &= | 2351 | vmx->nested.nested_vmx_exit_ctls_high &= |
2340 | #ifdef CONFIG_X86_64 | 2352 | #ifdef CONFIG_X86_64 |
2341 | VM_EXIT_HOST_ADDR_SPACE_SIZE | | 2353 | VM_EXIT_HOST_ADDR_SPACE_SIZE | |
2342 | #endif | 2354 | #endif |
2343 | VM_EXIT_LOAD_IA32_PAT | VM_EXIT_SAVE_IA32_PAT; | 2355 | VM_EXIT_LOAD_IA32_PAT | VM_EXIT_SAVE_IA32_PAT; |
2344 | nested_vmx_exit_ctls_high |= VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR | | 2356 | vmx->nested.nested_vmx_exit_ctls_high |= |
2357 | VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR | | ||
2345 | VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER | | 2358 | VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER | |
2346 | VM_EXIT_SAVE_VMX_PREEMPTION_TIMER | VM_EXIT_ACK_INTR_ON_EXIT; | 2359 | VM_EXIT_SAVE_VMX_PREEMPTION_TIMER | VM_EXIT_ACK_INTR_ON_EXIT; |
2347 | 2360 | ||
2348 | if (vmx_mpx_supported()) | 2361 | if (vmx_mpx_supported()) |
2349 | nested_vmx_exit_ctls_high |= VM_EXIT_CLEAR_BNDCFGS; | 2362 | vmx->nested.nested_vmx_exit_ctls_high |= VM_EXIT_CLEAR_BNDCFGS; |
2350 | 2363 | ||
2351 | /* We support free control of debug control saving. */ | 2364 | /* We support free control of debug control saving. */ |
2352 | nested_vmx_true_exit_ctls_low = nested_vmx_exit_ctls_low & | 2365 | vmx->nested.nested_vmx_true_exit_ctls_low = |
2366 | vmx->nested.nested_vmx_exit_ctls_low & | ||
2353 | ~VM_EXIT_SAVE_DEBUG_CONTROLS; | 2367 | ~VM_EXIT_SAVE_DEBUG_CONTROLS; |
2354 | 2368 | ||
2355 | /* entry controls */ | 2369 | /* entry controls */ |
2356 | rdmsr(MSR_IA32_VMX_ENTRY_CTLS, | 2370 | rdmsr(MSR_IA32_VMX_ENTRY_CTLS, |
2357 | nested_vmx_entry_ctls_low, nested_vmx_entry_ctls_high); | 2371 | vmx->nested.nested_vmx_entry_ctls_low, |
2358 | nested_vmx_entry_ctls_low = VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR; | 2372 | vmx->nested.nested_vmx_entry_ctls_high); |
2359 | nested_vmx_entry_ctls_high &= | 2373 | vmx->nested.nested_vmx_entry_ctls_low = |
2374 | VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR; | ||
2375 | vmx->nested.nested_vmx_entry_ctls_high &= | ||
2360 | #ifdef CONFIG_X86_64 | 2376 | #ifdef CONFIG_X86_64 |
2361 | VM_ENTRY_IA32E_MODE | | 2377 | VM_ENTRY_IA32E_MODE | |
2362 | #endif | 2378 | #endif |
2363 | VM_ENTRY_LOAD_IA32_PAT; | 2379 | VM_ENTRY_LOAD_IA32_PAT; |
2364 | nested_vmx_entry_ctls_high |= (VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | | 2380 | vmx->nested.nested_vmx_entry_ctls_high |= |
2365 | VM_ENTRY_LOAD_IA32_EFER); | 2381 | (VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | VM_ENTRY_LOAD_IA32_EFER); |
2366 | if (vmx_mpx_supported()) | 2382 | if (vmx_mpx_supported()) |
2367 | nested_vmx_entry_ctls_high |= VM_ENTRY_LOAD_BNDCFGS; | 2383 | vmx->nested.nested_vmx_entry_ctls_high |= VM_ENTRY_LOAD_BNDCFGS; |
2368 | 2384 | ||
2369 | /* We support free control of debug control loading. */ | 2385 | /* We support free control of debug control loading. */ |
2370 | nested_vmx_true_entry_ctls_low = nested_vmx_entry_ctls_low & | 2386 | vmx->nested.nested_vmx_true_entry_ctls_low = |
2387 | vmx->nested.nested_vmx_entry_ctls_low & | ||
2371 | ~VM_ENTRY_LOAD_DEBUG_CONTROLS; | 2388 | ~VM_ENTRY_LOAD_DEBUG_CONTROLS; |
2372 | 2389 | ||
2373 | /* cpu-based controls */ | 2390 | /* cpu-based controls */ |
2374 | rdmsr(MSR_IA32_VMX_PROCBASED_CTLS, | 2391 | rdmsr(MSR_IA32_VMX_PROCBASED_CTLS, |
2375 | nested_vmx_procbased_ctls_low, nested_vmx_procbased_ctls_high); | 2392 | vmx->nested.nested_vmx_procbased_ctls_low, |
2376 | nested_vmx_procbased_ctls_low = CPU_BASED_ALWAYSON_WITHOUT_TRUE_MSR; | 2393 | vmx->nested.nested_vmx_procbased_ctls_high); |
2377 | nested_vmx_procbased_ctls_high &= | 2394 | vmx->nested.nested_vmx_procbased_ctls_low = |
2395 | CPU_BASED_ALWAYSON_WITHOUT_TRUE_MSR; | ||
2396 | vmx->nested.nested_vmx_procbased_ctls_high &= | ||
2378 | CPU_BASED_VIRTUAL_INTR_PENDING | | 2397 | CPU_BASED_VIRTUAL_INTR_PENDING | |
2379 | CPU_BASED_VIRTUAL_NMI_PENDING | CPU_BASED_USE_TSC_OFFSETING | | 2398 | CPU_BASED_VIRTUAL_NMI_PENDING | CPU_BASED_USE_TSC_OFFSETING | |
2380 | CPU_BASED_HLT_EXITING | CPU_BASED_INVLPG_EXITING | | 2399 | CPU_BASED_HLT_EXITING | CPU_BASED_INVLPG_EXITING | |
@@ -2394,18 +2413,21 @@ static __init void nested_vmx_setup_ctls_msrs(void) | |||
2394 | * can use it to avoid exits to L1 - even when L0 runs L2 | 2413 | * can use it to avoid exits to L1 - even when L0 runs L2 |
2395 | * without MSR bitmaps. | 2414 | * without MSR bitmaps. |
2396 | */ | 2415 | */ |
2397 | nested_vmx_procbased_ctls_high |= CPU_BASED_ALWAYSON_WITHOUT_TRUE_MSR | | 2416 | vmx->nested.nested_vmx_procbased_ctls_high |= |
2417 | CPU_BASED_ALWAYSON_WITHOUT_TRUE_MSR | | ||
2398 | CPU_BASED_USE_MSR_BITMAPS; | 2418 | CPU_BASED_USE_MSR_BITMAPS; |
2399 | 2419 | ||
2400 | /* We support free control of CR3 access interception. */ | 2420 | /* We support free control of CR3 access interception. */ |
2401 | nested_vmx_true_procbased_ctls_low = nested_vmx_procbased_ctls_low & | 2421 | vmx->nested.nested_vmx_true_procbased_ctls_low = |
2422 | vmx->nested.nested_vmx_procbased_ctls_low & | ||
2402 | ~(CPU_BASED_CR3_LOAD_EXITING | CPU_BASED_CR3_STORE_EXITING); | 2423 | ~(CPU_BASED_CR3_LOAD_EXITING | CPU_BASED_CR3_STORE_EXITING); |
2403 | 2424 | ||
2404 | /* secondary cpu-based controls */ | 2425 | /* secondary cpu-based controls */ |
2405 | rdmsr(MSR_IA32_VMX_PROCBASED_CTLS2, | 2426 | rdmsr(MSR_IA32_VMX_PROCBASED_CTLS2, |
2406 | nested_vmx_secondary_ctls_low, nested_vmx_secondary_ctls_high); | 2427 | vmx->nested.nested_vmx_secondary_ctls_low, |
2407 | nested_vmx_secondary_ctls_low = 0; | 2428 | vmx->nested.nested_vmx_secondary_ctls_high); |
2408 | nested_vmx_secondary_ctls_high &= | 2429 | vmx->nested.nested_vmx_secondary_ctls_low = 0; |
2430 | vmx->nested.nested_vmx_secondary_ctls_high &= | ||
2409 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | | 2431 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | |
2410 | SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | | 2432 | SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | |
2411 | SECONDARY_EXEC_WBINVD_EXITING | | 2433 | SECONDARY_EXEC_WBINVD_EXITING | |
@@ -2413,27 +2435,31 @@ static __init void nested_vmx_setup_ctls_msrs(void) | |||
2413 | 2435 | ||
2414 | if (enable_ept) { | 2436 | if (enable_ept) { |
2415 | /* nested EPT: emulate EPT also to L1 */ | 2437 | /* nested EPT: emulate EPT also to L1 */ |
2416 | nested_vmx_secondary_ctls_high |= SECONDARY_EXEC_ENABLE_EPT | | 2438 | vmx->nested.nested_vmx_secondary_ctls_high |= |
2439 | SECONDARY_EXEC_ENABLE_EPT | | ||
2417 | SECONDARY_EXEC_UNRESTRICTED_GUEST; | 2440 | SECONDARY_EXEC_UNRESTRICTED_GUEST; |
2418 | nested_vmx_ept_caps = VMX_EPT_PAGE_WALK_4_BIT | | 2441 | vmx->nested.nested_vmx_ept_caps = VMX_EPT_PAGE_WALK_4_BIT | |
2419 | VMX_EPTP_WB_BIT | VMX_EPT_2MB_PAGE_BIT | | 2442 | VMX_EPTP_WB_BIT | VMX_EPT_2MB_PAGE_BIT | |
2420 | VMX_EPT_INVEPT_BIT; | 2443 | VMX_EPT_INVEPT_BIT; |
2421 | nested_vmx_ept_caps &= vmx_capability.ept; | 2444 | vmx->nested.nested_vmx_ept_caps &= vmx_capability.ept; |
2422 | /* | 2445 | /* |
2423 | * For nested guests, we don't do anything specific | 2446 | * For nested guests, we don't do anything specific |
2424 | * for single context invalidation. Hence, only advertise | 2447 | * for single context invalidation. Hence, only advertise |
2425 | * support for global context invalidation. | 2448 | * support for global context invalidation. |
2426 | */ | 2449 | */ |
2427 | nested_vmx_ept_caps |= VMX_EPT_EXTENT_GLOBAL_BIT; | 2450 | vmx->nested.nested_vmx_ept_caps |= VMX_EPT_EXTENT_GLOBAL_BIT; |
2428 | } else | 2451 | } else |
2429 | nested_vmx_ept_caps = 0; | 2452 | vmx->nested.nested_vmx_ept_caps = 0; |
2430 | 2453 | ||
2431 | /* miscellaneous data */ | 2454 | /* miscellaneous data */ |
2432 | rdmsr(MSR_IA32_VMX_MISC, nested_vmx_misc_low, nested_vmx_misc_high); | 2455 | rdmsr(MSR_IA32_VMX_MISC, |
2433 | nested_vmx_misc_low &= VMX_MISC_SAVE_EFER_LMA; | 2456 | vmx->nested.nested_vmx_misc_low, |
2434 | nested_vmx_misc_low |= VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE | | 2457 | vmx->nested.nested_vmx_misc_high); |
2458 | vmx->nested.nested_vmx_misc_low &= VMX_MISC_SAVE_EFER_LMA; | ||
2459 | vmx->nested.nested_vmx_misc_low |= | ||
2460 | VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE | | ||
2435 | VMX_MISC_ACTIVITY_HLT; | 2461 | VMX_MISC_ACTIVITY_HLT; |
2436 | nested_vmx_misc_high = 0; | 2462 | vmx->nested.nested_vmx_misc_high = 0; |
2437 | } | 2463 | } |
2438 | 2464 | ||
2439 | static inline bool vmx_control_verify(u32 control, u32 low, u32 high) | 2465 | static inline bool vmx_control_verify(u32 control, u32 low, u32 high) |
@@ -2452,6 +2478,8 @@ static inline u64 vmx_control_msr(u32 low, u32 high) | |||
2452 | /* Returns 0 on success, non-0 otherwise. */ | 2478 | /* Returns 0 on success, non-0 otherwise. */ |
2453 | static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) | 2479 | static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) |
2454 | { | 2480 | { |
2481 | struct vcpu_vmx *vmx = to_vmx(vcpu); | ||
2482 | |||
2455 | switch (msr_index) { | 2483 | switch (msr_index) { |
2456 | case MSR_IA32_VMX_BASIC: | 2484 | case MSR_IA32_VMX_BASIC: |
2457 | /* | 2485 | /* |
@@ -2466,36 +2494,44 @@ static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) | |||
2466 | break; | 2494 | break; |
2467 | case MSR_IA32_VMX_TRUE_PINBASED_CTLS: | 2495 | case MSR_IA32_VMX_TRUE_PINBASED_CTLS: |
2468 | case MSR_IA32_VMX_PINBASED_CTLS: | 2496 | case MSR_IA32_VMX_PINBASED_CTLS: |
2469 | *pdata = vmx_control_msr(nested_vmx_pinbased_ctls_low, | 2497 | *pdata = vmx_control_msr( |
2470 | nested_vmx_pinbased_ctls_high); | 2498 | vmx->nested.nested_vmx_pinbased_ctls_low, |
2499 | vmx->nested.nested_vmx_pinbased_ctls_high); | ||
2471 | break; | 2500 | break; |
2472 | case MSR_IA32_VMX_TRUE_PROCBASED_CTLS: | 2501 | case MSR_IA32_VMX_TRUE_PROCBASED_CTLS: |
2473 | *pdata = vmx_control_msr(nested_vmx_true_procbased_ctls_low, | 2502 | *pdata = vmx_control_msr( |
2474 | nested_vmx_procbased_ctls_high); | 2503 | vmx->nested.nested_vmx_true_procbased_ctls_low, |
2504 | vmx->nested.nested_vmx_procbased_ctls_high); | ||
2475 | break; | 2505 | break; |
2476 | case MSR_IA32_VMX_PROCBASED_CTLS: | 2506 | case MSR_IA32_VMX_PROCBASED_CTLS: |
2477 | *pdata = vmx_control_msr(nested_vmx_procbased_ctls_low, | 2507 | *pdata = vmx_control_msr( |
2478 | nested_vmx_procbased_ctls_high); | 2508 | vmx->nested.nested_vmx_procbased_ctls_low, |
2509 | vmx->nested.nested_vmx_procbased_ctls_high); | ||
2479 | break; | 2510 | break; |
2480 | case MSR_IA32_VMX_TRUE_EXIT_CTLS: | 2511 | case MSR_IA32_VMX_TRUE_EXIT_CTLS: |
2481 | *pdata = vmx_control_msr(nested_vmx_true_exit_ctls_low, | 2512 | *pdata = vmx_control_msr( |
2482 | nested_vmx_exit_ctls_high); | 2513 | vmx->nested.nested_vmx_true_exit_ctls_low, |
2514 | vmx->nested.nested_vmx_exit_ctls_high); | ||
2483 | break; | 2515 | break; |
2484 | case MSR_IA32_VMX_EXIT_CTLS: | 2516 | case MSR_IA32_VMX_EXIT_CTLS: |
2485 | *pdata = vmx_control_msr(nested_vmx_exit_ctls_low, | 2517 | *pdata = vmx_control_msr( |
2486 | nested_vmx_exit_ctls_high); | 2518 | vmx->nested.nested_vmx_exit_ctls_low, |
2519 | vmx->nested.nested_vmx_exit_ctls_high); | ||
2487 | break; | 2520 | break; |
2488 | case MSR_IA32_VMX_TRUE_ENTRY_CTLS: | 2521 | case MSR_IA32_VMX_TRUE_ENTRY_CTLS: |
2489 | *pdata = vmx_control_msr(nested_vmx_true_entry_ctls_low, | 2522 | *pdata = vmx_control_msr( |
2490 | nested_vmx_entry_ctls_high); | 2523 | vmx->nested.nested_vmx_true_entry_ctls_low, |
2524 | vmx->nested.nested_vmx_entry_ctls_high); | ||
2491 | break; | 2525 | break; |
2492 | case MSR_IA32_VMX_ENTRY_CTLS: | 2526 | case MSR_IA32_VMX_ENTRY_CTLS: |
2493 | *pdata = vmx_control_msr(nested_vmx_entry_ctls_low, | 2527 | *pdata = vmx_control_msr( |
2494 | nested_vmx_entry_ctls_high); | 2528 | vmx->nested.nested_vmx_entry_ctls_low, |
2529 | vmx->nested.nested_vmx_entry_ctls_high); | ||
2495 | break; | 2530 | break; |
2496 | case MSR_IA32_VMX_MISC: | 2531 | case MSR_IA32_VMX_MISC: |
2497 | *pdata = vmx_control_msr(nested_vmx_misc_low, | 2532 | *pdata = vmx_control_msr( |
2498 | nested_vmx_misc_high); | 2533 | vmx->nested.nested_vmx_misc_low, |
2534 | vmx->nested.nested_vmx_misc_high); | ||
2499 | break; | 2535 | break; |
2500 | /* | 2536 | /* |
2501 | * These MSRs specify bits which the guest must keep fixed (on or off) | 2537 | * These MSRs specify bits which the guest must keep fixed (on or off) |
@@ -2520,12 +2556,13 @@ static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) | |||
2520 | *pdata = 0x2e; /* highest index: VMX_PREEMPTION_TIMER_VALUE */ | 2556 | *pdata = 0x2e; /* highest index: VMX_PREEMPTION_TIMER_VALUE */ |
2521 | break; | 2557 | break; |
2522 | case MSR_IA32_VMX_PROCBASED_CTLS2: | 2558 | case MSR_IA32_VMX_PROCBASED_CTLS2: |
2523 | *pdata = vmx_control_msr(nested_vmx_secondary_ctls_low, | 2559 | *pdata = vmx_control_msr( |
2524 | nested_vmx_secondary_ctls_high); | 2560 | vmx->nested.nested_vmx_secondary_ctls_low, |
2561 | vmx->nested.nested_vmx_secondary_ctls_high); | ||
2525 | break; | 2562 | break; |
2526 | case MSR_IA32_VMX_EPT_VPID_CAP: | 2563 | case MSR_IA32_VMX_EPT_VPID_CAP: |
2527 | /* Currently, no nested vpid support */ | 2564 | /* Currently, no nested vpid support */ |
2528 | *pdata = nested_vmx_ept_caps; | 2565 | *pdata = vmx->nested.nested_vmx_ept_caps; |
2529 | break; | 2566 | break; |
2530 | default: | 2567 | default: |
2531 | return 1; | 2568 | return 1; |
@@ -5045,11 +5082,12 @@ vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall) | |||
5045 | hypercall[2] = 0xc1; | 5082 | hypercall[2] = 0xc1; |
5046 | } | 5083 | } |
5047 | 5084 | ||
5048 | static bool nested_cr0_valid(struct vmcs12 *vmcs12, unsigned long val) | 5085 | static bool nested_cr0_valid(struct kvm_vcpu *vcpu, unsigned long val) |
5049 | { | 5086 | { |
5050 | unsigned long always_on = VMXON_CR0_ALWAYSON; | 5087 | unsigned long always_on = VMXON_CR0_ALWAYSON; |
5088 | struct vmcs12 *vmcs12 = get_vmcs12(vcpu); | ||
5051 | 5089 | ||
5052 | if (nested_vmx_secondary_ctls_high & | 5090 | if (to_vmx(vcpu)->nested.nested_vmx_secondary_ctls_high & |
5053 | SECONDARY_EXEC_UNRESTRICTED_GUEST && | 5091 | SECONDARY_EXEC_UNRESTRICTED_GUEST && |
5054 | nested_cpu_has2(vmcs12, SECONDARY_EXEC_UNRESTRICTED_GUEST)) | 5092 | nested_cpu_has2(vmcs12, SECONDARY_EXEC_UNRESTRICTED_GUEST)) |
5055 | always_on &= ~(X86_CR0_PE | X86_CR0_PG); | 5093 | always_on &= ~(X86_CR0_PE | X86_CR0_PG); |
@@ -5074,7 +5112,7 @@ static int handle_set_cr0(struct kvm_vcpu *vcpu, unsigned long val) | |||
5074 | val = (val & ~vmcs12->cr0_guest_host_mask) | | 5112 | val = (val & ~vmcs12->cr0_guest_host_mask) | |
5075 | (vmcs12->guest_cr0 & vmcs12->cr0_guest_host_mask); | 5113 | (vmcs12->guest_cr0 & vmcs12->cr0_guest_host_mask); |
5076 | 5114 | ||
5077 | if (!nested_cr0_valid(vmcs12, val)) | 5115 | if (!nested_cr0_valid(vcpu, val)) |
5078 | return 1; | 5116 | return 1; |
5079 | 5117 | ||
5080 | if (kvm_set_cr0(vcpu, val)) | 5118 | if (kvm_set_cr0(vcpu, val)) |
@@ -5969,9 +6007,6 @@ static __init int hardware_setup(void) | |||
5969 | kvm_x86_ops->sync_pir_to_irr = vmx_sync_pir_to_irr_dummy; | 6007 | kvm_x86_ops->sync_pir_to_irr = vmx_sync_pir_to_irr_dummy; |
5970 | } | 6008 | } |
5971 | 6009 | ||
5972 | if (nested) | ||
5973 | nested_vmx_setup_ctls_msrs(); | ||
5974 | |||
5975 | vmx_disable_intercept_for_msr(MSR_FS_BASE, false); | 6010 | vmx_disable_intercept_for_msr(MSR_FS_BASE, false); |
5976 | vmx_disable_intercept_for_msr(MSR_GS_BASE, false); | 6011 | vmx_disable_intercept_for_msr(MSR_GS_BASE, false); |
5977 | vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true); | 6012 | vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true); |
@@ -6989,6 +7024,7 @@ static int handle_vmptrst(struct kvm_vcpu *vcpu) | |||
6989 | /* Emulate the INVEPT instruction */ | 7024 | /* Emulate the INVEPT instruction */ |
6990 | static int handle_invept(struct kvm_vcpu *vcpu) | 7025 | static int handle_invept(struct kvm_vcpu *vcpu) |
6991 | { | 7026 | { |
7027 | struct vcpu_vmx *vmx = to_vmx(vcpu); | ||
6992 | u32 vmx_instruction_info, types; | 7028 | u32 vmx_instruction_info, types; |
6993 | unsigned long type; | 7029 | unsigned long type; |
6994 | gva_t gva; | 7030 | gva_t gva; |
@@ -6997,8 +7033,9 @@ static int handle_invept(struct kvm_vcpu *vcpu) | |||
6997 | u64 eptp, gpa; | 7033 | u64 eptp, gpa; |
6998 | } operand; | 7034 | } operand; |
6999 | 7035 | ||
7000 | if (!(nested_vmx_secondary_ctls_high & SECONDARY_EXEC_ENABLE_EPT) || | 7036 | if (!(vmx->nested.nested_vmx_secondary_ctls_high & |
7001 | !(nested_vmx_ept_caps & VMX_EPT_INVEPT_BIT)) { | 7037 | SECONDARY_EXEC_ENABLE_EPT) || |
7038 | !(vmx->nested.nested_vmx_ept_caps & VMX_EPT_INVEPT_BIT)) { | ||
7002 | kvm_queue_exception(vcpu, UD_VECTOR); | 7039 | kvm_queue_exception(vcpu, UD_VECTOR); |
7003 | return 1; | 7040 | return 1; |
7004 | } | 7041 | } |
@@ -7014,7 +7051,7 @@ static int handle_invept(struct kvm_vcpu *vcpu) | |||
7014 | vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO); | 7051 | vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO); |
7015 | type = kvm_register_readl(vcpu, (vmx_instruction_info >> 28) & 0xf); | 7052 | type = kvm_register_readl(vcpu, (vmx_instruction_info >> 28) & 0xf); |
7016 | 7053 | ||
7017 | types = (nested_vmx_ept_caps >> VMX_EPT_EXTENT_SHIFT) & 6; | 7054 | types = (vmx->nested.nested_vmx_ept_caps >> VMX_EPT_EXTENT_SHIFT) & 6; |
7018 | 7055 | ||
7019 | if (!(types & (1UL << type))) { | 7056 | if (!(types & (1UL << type))) { |
7020 | nested_vmx_failValid(vcpu, | 7057 | nested_vmx_failValid(vcpu, |
@@ -8254,6 +8291,9 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) | |||
8254 | goto free_vmcs; | 8291 | goto free_vmcs; |
8255 | } | 8292 | } |
8256 | 8293 | ||
8294 | if (nested) | ||
8295 | nested_vmx_setup_ctls_msrs(vmx); | ||
8296 | |||
8257 | vmx->nested.current_vmptr = -1ull; | 8297 | vmx->nested.current_vmptr = -1ull; |
8258 | vmx->nested.current_vmcs12 = NULL; | 8298 | vmx->nested.current_vmcs12 = NULL; |
8259 | 8299 | ||
@@ -8412,7 +8452,8 @@ static void nested_ept_init_mmu_context(struct kvm_vcpu *vcpu) | |||
8412 | { | 8452 | { |
8413 | WARN_ON(mmu_is_nested(vcpu)); | 8453 | WARN_ON(mmu_is_nested(vcpu)); |
8414 | kvm_init_shadow_ept_mmu(vcpu, | 8454 | kvm_init_shadow_ept_mmu(vcpu, |
8415 | nested_vmx_ept_caps & VMX_EPT_EXECUTE_ONLY_BIT); | 8455 | to_vmx(vcpu)->nested.nested_vmx_ept_caps & |
8456 | VMX_EPT_EXECUTE_ONLY_BIT); | ||
8416 | vcpu->arch.mmu.set_cr3 = vmx_set_cr3; | 8457 | vcpu->arch.mmu.set_cr3 = vmx_set_cr3; |
8417 | vcpu->arch.mmu.get_cr3 = nested_ept_get_cr3; | 8458 | vcpu->arch.mmu.get_cr3 = nested_ept_get_cr3; |
8418 | vcpu->arch.mmu.inject_page_fault = nested_ept_inject_page_fault; | 8459 | vcpu->arch.mmu.inject_page_fault = nested_ept_inject_page_fault; |
@@ -9123,18 +9164,20 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) | |||
9123 | } | 9164 | } |
9124 | 9165 | ||
9125 | if (!vmx_control_verify(vmcs12->cpu_based_vm_exec_control, | 9166 | if (!vmx_control_verify(vmcs12->cpu_based_vm_exec_control, |
9126 | nested_vmx_true_procbased_ctls_low, | 9167 | vmx->nested.nested_vmx_true_procbased_ctls_low, |
9127 | nested_vmx_procbased_ctls_high) || | 9168 | vmx->nested.nested_vmx_procbased_ctls_high) || |
9128 | !vmx_control_verify(vmcs12->secondary_vm_exec_control, | 9169 | !vmx_control_verify(vmcs12->secondary_vm_exec_control, |
9129 | nested_vmx_secondary_ctls_low, nested_vmx_secondary_ctls_high) || | 9170 | vmx->nested.nested_vmx_secondary_ctls_low, |
9171 | vmx->nested.nested_vmx_secondary_ctls_high) || | ||
9130 | !vmx_control_verify(vmcs12->pin_based_vm_exec_control, | 9172 | !vmx_control_verify(vmcs12->pin_based_vm_exec_control, |
9131 | nested_vmx_pinbased_ctls_low, nested_vmx_pinbased_ctls_high) || | 9173 | vmx->nested.nested_vmx_pinbased_ctls_low, |
9174 | vmx->nested.nested_vmx_pinbased_ctls_high) || | ||
9132 | !vmx_control_verify(vmcs12->vm_exit_controls, | 9175 | !vmx_control_verify(vmcs12->vm_exit_controls, |
9133 | nested_vmx_true_exit_ctls_low, | 9176 | vmx->nested.nested_vmx_true_exit_ctls_low, |
9134 | nested_vmx_exit_ctls_high) || | 9177 | vmx->nested.nested_vmx_exit_ctls_high) || |
9135 | !vmx_control_verify(vmcs12->vm_entry_controls, | 9178 | !vmx_control_verify(vmcs12->vm_entry_controls, |
9136 | nested_vmx_true_entry_ctls_low, | 9179 | vmx->nested.nested_vmx_true_entry_ctls_low, |
9137 | nested_vmx_entry_ctls_high)) | 9180 | vmx->nested.nested_vmx_entry_ctls_high)) |
9138 | { | 9181 | { |
9139 | nested_vmx_failValid(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD); | 9182 | nested_vmx_failValid(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD); |
9140 | return 1; | 9183 | return 1; |
@@ -9147,7 +9190,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) | |||
9147 | return 1; | 9190 | return 1; |
9148 | } | 9191 | } |
9149 | 9192 | ||
9150 | if (!nested_cr0_valid(vmcs12, vmcs12->guest_cr0) || | 9193 | if (!nested_cr0_valid(vcpu, vmcs12->guest_cr0) || |
9151 | ((vmcs12->guest_cr4 & VMXON_CR4_ALWAYSON) != VMXON_CR4_ALWAYSON)) { | 9194 | ((vmcs12->guest_cr4 & VMXON_CR4_ALWAYSON) != VMXON_CR4_ALWAYSON)) { |
9152 | nested_vmx_entry_failure(vcpu, vmcs12, | 9195 | nested_vmx_entry_failure(vcpu, vmcs12, |
9153 | EXIT_REASON_INVALID_STATE, ENTRY_FAIL_DEFAULT); | 9196 | EXIT_REASON_INVALID_STATE, ENTRY_FAIL_DEFAULT); |