diff options
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-rw-r--r-- | arch/x86/kvm/vmx.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 14c1a18d206a..ae4f6d35d19c 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -2168,7 +2168,10 @@ static void vmx_set_msr_bitmap(struct kvm_vcpu *vcpu) | |||
2168 | { | 2168 | { |
2169 | unsigned long *msr_bitmap; | 2169 | unsigned long *msr_bitmap; |
2170 | 2170 | ||
2171 | if (irqchip_in_kernel(vcpu->kvm) && apic_x2apic_mode(vcpu->arch.apic)) { | 2171 | if (is_guest_mode(vcpu)) |
2172 | msr_bitmap = vmx_msr_bitmap_nested; | ||
2173 | else if (irqchip_in_kernel(vcpu->kvm) && | ||
2174 | apic_x2apic_mode(vcpu->arch.apic)) { | ||
2172 | if (is_long_mode(vcpu)) | 2175 | if (is_long_mode(vcpu)) |
2173 | msr_bitmap = vmx_msr_bitmap_longmode_x2apic; | 2176 | msr_bitmap = vmx_msr_bitmap_longmode_x2apic; |
2174 | else | 2177 | else |
@@ -2476,8 +2479,7 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx) | |||
2476 | if (enable_ept) { | 2479 | if (enable_ept) { |
2477 | /* nested EPT: emulate EPT also to L1 */ | 2480 | /* nested EPT: emulate EPT also to L1 */ |
2478 | vmx->nested.nested_vmx_secondary_ctls_high |= | 2481 | vmx->nested.nested_vmx_secondary_ctls_high |= |
2479 | SECONDARY_EXEC_ENABLE_EPT | | 2482 | SECONDARY_EXEC_ENABLE_EPT; |
2480 | SECONDARY_EXEC_UNRESTRICTED_GUEST; | ||
2481 | vmx->nested.nested_vmx_ept_caps = VMX_EPT_PAGE_WALK_4_BIT | | 2483 | vmx->nested.nested_vmx_ept_caps = VMX_EPT_PAGE_WALK_4_BIT | |
2482 | VMX_EPTP_WB_BIT | VMX_EPT_2MB_PAGE_BIT | | 2484 | VMX_EPTP_WB_BIT | VMX_EPT_2MB_PAGE_BIT | |
2483 | VMX_EPT_INVEPT_BIT; | 2485 | VMX_EPT_INVEPT_BIT; |
@@ -2491,6 +2493,10 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx) | |||
2491 | } else | 2493 | } else |
2492 | vmx->nested.nested_vmx_ept_caps = 0; | 2494 | vmx->nested.nested_vmx_ept_caps = 0; |
2493 | 2495 | ||
2496 | if (enable_unrestricted_guest) | ||
2497 | vmx->nested.nested_vmx_secondary_ctls_high |= | ||
2498 | SECONDARY_EXEC_UNRESTRICTED_GUEST; | ||
2499 | |||
2494 | /* miscellaneous data */ | 2500 | /* miscellaneous data */ |
2495 | rdmsr(MSR_IA32_VMX_MISC, | 2501 | rdmsr(MSR_IA32_VMX_MISC, |
2496 | vmx->nested.nested_vmx_misc_low, | 2502 | vmx->nested.nested_vmx_misc_low, |
@@ -4367,6 +4373,18 @@ static int vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu) | |||
4367 | return 0; | 4373 | return 0; |
4368 | } | 4374 | } |
4369 | 4375 | ||
4376 | static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu) | ||
4377 | { | ||
4378 | #ifdef CONFIG_SMP | ||
4379 | if (vcpu->mode == IN_GUEST_MODE) { | ||
4380 | apic->send_IPI_mask(get_cpu_mask(vcpu->cpu), | ||
4381 | POSTED_INTR_VECTOR); | ||
4382 | return true; | ||
4383 | } | ||
4384 | #endif | ||
4385 | return false; | ||
4386 | } | ||
4387 | |||
4370 | static int vmx_deliver_nested_posted_interrupt(struct kvm_vcpu *vcpu, | 4388 | static int vmx_deliver_nested_posted_interrupt(struct kvm_vcpu *vcpu, |
4371 | int vector) | 4389 | int vector) |
4372 | { | 4390 | { |
@@ -4375,9 +4393,7 @@ static int vmx_deliver_nested_posted_interrupt(struct kvm_vcpu *vcpu, | |||
4375 | if (is_guest_mode(vcpu) && | 4393 | if (is_guest_mode(vcpu) && |
4376 | vector == vmx->nested.posted_intr_nv) { | 4394 | vector == vmx->nested.posted_intr_nv) { |
4377 | /* the PIR and ON have been set by L1. */ | 4395 | /* the PIR and ON have been set by L1. */ |
4378 | if (vcpu->mode == IN_GUEST_MODE) | 4396 | kvm_vcpu_trigger_posted_interrupt(vcpu); |
4379 | apic->send_IPI_mask(get_cpu_mask(vcpu->cpu), | ||
4380 | POSTED_INTR_VECTOR); | ||
4381 | /* | 4397 | /* |
4382 | * If a posted intr is not recognized by hardware, | 4398 | * If a posted intr is not recognized by hardware, |
4383 | * we will accomplish it in the next vmentry. | 4399 | * we will accomplish it in the next vmentry. |
@@ -4409,12 +4425,7 @@ static void vmx_deliver_posted_interrupt(struct kvm_vcpu *vcpu, int vector) | |||
4409 | 4425 | ||
4410 | r = pi_test_and_set_on(&vmx->pi_desc); | 4426 | r = pi_test_and_set_on(&vmx->pi_desc); |
4411 | kvm_make_request(KVM_REQ_EVENT, vcpu); | 4427 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
4412 | #ifdef CONFIG_SMP | 4428 | if (r || !kvm_vcpu_trigger_posted_interrupt(vcpu)) |
4413 | if (!r && (vcpu->mode == IN_GUEST_MODE)) | ||
4414 | apic->send_IPI_mask(get_cpu_mask(vcpu->cpu), | ||
4415 | POSTED_INTR_VECTOR); | ||
4416 | else | ||
4417 | #endif | ||
4418 | kvm_vcpu_kick(vcpu); | 4429 | kvm_vcpu_kick(vcpu); |
4419 | } | 4430 | } |
4420 | 4431 | ||
@@ -9213,9 +9224,9 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) | |||
9213 | } | 9224 | } |
9214 | 9225 | ||
9215 | if (cpu_has_vmx_msr_bitmap() && | 9226 | if (cpu_has_vmx_msr_bitmap() && |
9216 | exec_control & CPU_BASED_USE_MSR_BITMAPS && | 9227 | exec_control & CPU_BASED_USE_MSR_BITMAPS) { |
9217 | nested_vmx_merge_msr_bitmap(vcpu, vmcs12)) { | 9228 | nested_vmx_merge_msr_bitmap(vcpu, vmcs12); |
9218 | vmcs_write64(MSR_BITMAP, __pa(vmx_msr_bitmap_nested)); | 9229 | /* MSR_BITMAP will be set by following vmx_set_efer. */ |
9219 | } else | 9230 | } else |
9220 | exec_control &= ~CPU_BASED_USE_MSR_BITMAPS; | 9231 | exec_control &= ~CPU_BASED_USE_MSR_BITMAPS; |
9221 | 9232 | ||