diff options
author | Nadav Har'El <nyh@il.ibm.com> | 2011-05-25 16:09:31 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-07-12 04:45:14 -0400 |
commit | bf8179a011d40e7322d34440039b5e86a0d03aed (patch) | |
tree | 1b3cc83c1787d48da7f0f0a6b5370dc0ed4d35cc /arch/x86/kvm | |
parent | a3a8ff8ebf87cbd828f54276d902c3c8ee0c4781 (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.c | 80 |
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 | ||
3436 | static 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 | |||
3444 | static 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 | |||
3461 | static 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 | ||