aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
authorNadav Har'El <nyh@il.ibm.com>2011-05-25 16:09:31 -0400
committerAvi Kivity <avi@redhat.com>2011-07-12 04:45:14 -0400
commitbf8179a011d40e7322d34440039b5e86a0d03aed (patch)
tree1b3cc83c1787d48da7f0f0a6b5370dc0ed4d35cc /arch/x86/kvm
parenta3a8ff8ebf87cbd828f54276d902c3c8ee0c4781 (diff)
KVM: nVMX: Move control field setup to functions
Move some of the control field setup to common functions. These functions will also be needed for running L2 guests - L0's desires (expressed in these functions) will be appropriately merged with L1's desires. Signed-off-by: Nadav Har'El <nyh@il.ibm.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r--arch/x86/kvm/vmx.c80
1 files changed, 47 insertions, 33 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 4b97161b262..3134638e9e9 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -3433,6 +3433,49 @@ static void vmx_set_constant_host_state(void)
3433 } 3433 }
3434} 3434}
3435 3435
3436static void set_cr4_guest_host_mask(struct vcpu_vmx *vmx)
3437{
3438 vmx->vcpu.arch.cr4_guest_owned_bits = KVM_CR4_GUEST_OWNED_BITS;
3439 if (enable_ept)
3440 vmx->vcpu.arch.cr4_guest_owned_bits |= X86_CR4_PGE;
3441 vmcs_writel(CR4_GUEST_HOST_MASK, ~vmx->vcpu.arch.cr4_guest_owned_bits);
3442}
3443
3444static u32 vmx_exec_control(struct vcpu_vmx *vmx)
3445{
3446 u32 exec_control = vmcs_config.cpu_based_exec_ctrl;
3447 if (!vm_need_tpr_shadow(vmx->vcpu.kvm)) {
3448 exec_control &= ~CPU_BASED_TPR_SHADOW;
3449#ifdef CONFIG_X86_64
3450 exec_control |= CPU_BASED_CR8_STORE_EXITING |
3451 CPU_BASED_CR8_LOAD_EXITING;
3452#endif
3453 }
3454 if (!enable_ept)
3455 exec_control |= CPU_BASED_CR3_STORE_EXITING |
3456 CPU_BASED_CR3_LOAD_EXITING |
3457 CPU_BASED_INVLPG_EXITING;
3458 return exec_control;
3459}
3460
3461static u32 vmx_secondary_exec_control(struct vcpu_vmx *vmx)
3462{
3463 u32 exec_control = vmcs_config.cpu_based_2nd_exec_ctrl;
3464 if (!vm_need_virtualize_apic_accesses(vmx->vcpu.kvm))
3465 exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
3466 if (vmx->vpid == 0)
3467 exec_control &= ~SECONDARY_EXEC_ENABLE_VPID;
3468 if (!enable_ept) {
3469 exec_control &= ~SECONDARY_EXEC_ENABLE_EPT;
3470 enable_unrestricted_guest = 0;
3471 }
3472 if (!enable_unrestricted_guest)
3473 exec_control &= ~SECONDARY_EXEC_UNRESTRICTED_GUEST;
3474 if (!ple_gap)
3475 exec_control &= ~SECONDARY_EXEC_PAUSE_LOOP_EXITING;
3476 return exec_control;
3477}
3478
3436/* 3479/*
3437 * Sets up the vmcs for emulated real mode. 3480 * Sets up the vmcs for emulated real mode.
3438 */ 3481 */
@@ -3440,7 +3483,6 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
3440{ 3483{
3441 unsigned long a; 3484 unsigned long a;
3442 int i; 3485 int i;
3443 u32 exec_control;
3444 3486
3445 /* I/O */ 3487 /* I/O */
3446 vmcs_write64(IO_BITMAP_A, __pa(vmx_io_bitmap_a)); 3488 vmcs_write64(IO_BITMAP_A, __pa(vmx_io_bitmap_a));
@@ -3455,36 +3497,11 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
3455 vmcs_write32(PIN_BASED_VM_EXEC_CONTROL, 3497 vmcs_write32(PIN_BASED_VM_EXEC_CONTROL,
3456 vmcs_config.pin_based_exec_ctrl); 3498 vmcs_config.pin_based_exec_ctrl);
3457 3499
3458 exec_control = vmcs_config.cpu_based_exec_ctrl; 3500 vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, vmx_exec_control(vmx));
3459 if (!vm_need_tpr_shadow(vmx->vcpu.kvm)) {
3460 exec_control &= ~CPU_BASED_TPR_SHADOW;
3461#ifdef CONFIG_X86_64
3462 exec_control |= CPU_BASED_CR8_STORE_EXITING |
3463 CPU_BASED_CR8_LOAD_EXITING;
3464#endif
3465 }
3466 if (!enable_ept)
3467 exec_control |= CPU_BASED_CR3_STORE_EXITING |
3468 CPU_BASED_CR3_LOAD_EXITING |
3469 CPU_BASED_INVLPG_EXITING;
3470 vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, exec_control);
3471 3501
3472 if (cpu_has_secondary_exec_ctrls()) { 3502 if (cpu_has_secondary_exec_ctrls()) {
3473 exec_control = vmcs_config.cpu_based_2nd_exec_ctrl; 3503 vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
3474 if (!vm_need_virtualize_apic_accesses(vmx->vcpu.kvm)) 3504 vmx_secondary_exec_control(vmx));
3475 exec_control &=
3476 ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
3477 if (vmx->vpid == 0)
3478 exec_control &= ~SECONDARY_EXEC_ENABLE_VPID;
3479 if (!enable_ept) {
3480 exec_control &= ~SECONDARY_EXEC_ENABLE_EPT;
3481 enable_unrestricted_guest = 0;
3482 }
3483 if (!enable_unrestricted_guest)
3484 exec_control &= ~SECONDARY_EXEC_UNRESTRICTED_GUEST;
3485 if (!ple_gap)
3486 exec_control &= ~SECONDARY_EXEC_PAUSE_LOOP_EXITING;
3487 vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control);
3488 } 3505 }
3489 3506
3490 if (ple_gap) { 3507 if (ple_gap) {
@@ -3547,10 +3564,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
3547 vmcs_write32(VM_ENTRY_CONTROLS, vmcs_config.vmentry_ctrl); 3564 vmcs_write32(VM_ENTRY_CONTROLS, vmcs_config.vmentry_ctrl);
3548 3565
3549 vmcs_writel(CR0_GUEST_HOST_MASK, ~0UL); 3566 vmcs_writel(CR0_GUEST_HOST_MASK, ~0UL);
3550 vmx->vcpu.arch.cr4_guest_owned_bits = KVM_CR4_GUEST_OWNED_BITS; 3567 set_cr4_guest_host_mask(vmx);
3551 if (enable_ept)
3552 vmx->vcpu.arch.cr4_guest_owned_bits |= X86_CR4_PGE;
3553 vmcs_writel(CR4_GUEST_HOST_MASK, ~vmx->vcpu.arch.cr4_guest_owned_bits);
3554 3568
3555 kvm_write_tsc(&vmx->vcpu, 0); 3569 kvm_write_tsc(&vmx->vcpu, 0);
3556 3570