diff options
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-rw-r--r-- | arch/x86/kvm/vmx.c | 71 |
1 files changed, 52 insertions, 19 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 1320e0f8e611..138ceffc6377 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -503,7 +503,7 @@ static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu) | |||
503 | [number##_HIGH] = VMCS12_OFFSET(name)+4 | 503 | [number##_HIGH] = VMCS12_OFFSET(name)+4 |
504 | 504 | ||
505 | 505 | ||
506 | static const unsigned long shadow_read_only_fields[] = { | 506 | static unsigned long shadow_read_only_fields[] = { |
507 | /* | 507 | /* |
508 | * We do NOT shadow fields that are modified when L0 | 508 | * We do NOT shadow fields that are modified when L0 |
509 | * traps and emulates any vmx instruction (e.g. VMPTRLD, | 509 | * traps and emulates any vmx instruction (e.g. VMPTRLD, |
@@ -526,10 +526,10 @@ static const unsigned long shadow_read_only_fields[] = { | |||
526 | GUEST_LINEAR_ADDRESS, | 526 | GUEST_LINEAR_ADDRESS, |
527 | GUEST_PHYSICAL_ADDRESS | 527 | GUEST_PHYSICAL_ADDRESS |
528 | }; | 528 | }; |
529 | static const int max_shadow_read_only_fields = | 529 | static int max_shadow_read_only_fields = |
530 | ARRAY_SIZE(shadow_read_only_fields); | 530 | ARRAY_SIZE(shadow_read_only_fields); |
531 | 531 | ||
532 | static const unsigned long shadow_read_write_fields[] = { | 532 | static unsigned long shadow_read_write_fields[] = { |
533 | GUEST_RIP, | 533 | GUEST_RIP, |
534 | GUEST_RSP, | 534 | GUEST_RSP, |
535 | GUEST_CR0, | 535 | GUEST_CR0, |
@@ -558,7 +558,7 @@ static const unsigned long shadow_read_write_fields[] = { | |||
558 | HOST_FS_SELECTOR, | 558 | HOST_FS_SELECTOR, |
559 | HOST_GS_SELECTOR | 559 | HOST_GS_SELECTOR |
560 | }; | 560 | }; |
561 | static const int max_shadow_read_write_fields = | 561 | static int max_shadow_read_write_fields = |
562 | ARRAY_SIZE(shadow_read_write_fields); | 562 | ARRAY_SIZE(shadow_read_write_fields); |
563 | 563 | ||
564 | static const unsigned short vmcs_field_to_offset_table[] = { | 564 | static const unsigned short vmcs_field_to_offset_table[] = { |
@@ -3009,6 +3009,41 @@ static void free_kvm_area(void) | |||
3009 | } | 3009 | } |
3010 | } | 3010 | } |
3011 | 3011 | ||
3012 | static void init_vmcs_shadow_fields(void) | ||
3013 | { | ||
3014 | int i, j; | ||
3015 | |||
3016 | /* No checks for read only fields yet */ | ||
3017 | |||
3018 | for (i = j = 0; i < max_shadow_read_write_fields; i++) { | ||
3019 | switch (shadow_read_write_fields[i]) { | ||
3020 | case GUEST_BNDCFGS: | ||
3021 | if (!vmx_mpx_supported()) | ||
3022 | continue; | ||
3023 | break; | ||
3024 | default: | ||
3025 | break; | ||
3026 | } | ||
3027 | |||
3028 | if (j < i) | ||
3029 | shadow_read_write_fields[j] = | ||
3030 | shadow_read_write_fields[i]; | ||
3031 | j++; | ||
3032 | } | ||
3033 | max_shadow_read_write_fields = j; | ||
3034 | |||
3035 | /* shadowed fields guest access without vmexit */ | ||
3036 | for (i = 0; i < max_shadow_read_write_fields; i++) { | ||
3037 | clear_bit(shadow_read_write_fields[i], | ||
3038 | vmx_vmwrite_bitmap); | ||
3039 | clear_bit(shadow_read_write_fields[i], | ||
3040 | vmx_vmread_bitmap); | ||
3041 | } | ||
3042 | for (i = 0; i < max_shadow_read_only_fields; i++) | ||
3043 | clear_bit(shadow_read_only_fields[i], | ||
3044 | vmx_vmread_bitmap); | ||
3045 | } | ||
3046 | |||
3012 | static __init int alloc_kvm_area(void) | 3047 | static __init int alloc_kvm_area(void) |
3013 | { | 3048 | { |
3014 | int cpu; | 3049 | int cpu; |
@@ -3039,6 +3074,8 @@ static __init int hardware_setup(void) | |||
3039 | enable_vpid = 0; | 3074 | enable_vpid = 0; |
3040 | if (!cpu_has_vmx_shadow_vmcs()) | 3075 | if (!cpu_has_vmx_shadow_vmcs()) |
3041 | enable_shadow_vmcs = 0; | 3076 | enable_shadow_vmcs = 0; |
3077 | if (enable_shadow_vmcs) | ||
3078 | init_vmcs_shadow_fields(); | ||
3042 | 3079 | ||
3043 | if (!cpu_has_vmx_ept() || | 3080 | if (!cpu_has_vmx_ept() || |
3044 | !cpu_has_vmx_ept_4levels()) { | 3081 | !cpu_has_vmx_ept_4levels()) { |
@@ -3484,13 +3521,14 @@ static int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) | |||
3484 | hw_cr4 &= ~X86_CR4_PAE; | 3521 | hw_cr4 &= ~X86_CR4_PAE; |
3485 | hw_cr4 |= X86_CR4_PSE; | 3522 | hw_cr4 |= X86_CR4_PSE; |
3486 | /* | 3523 | /* |
3487 | * SMEP is disabled if CPU is in non-paging mode in | 3524 | * SMEP/SMAP is disabled if CPU is in non-paging mode |
3488 | * hardware. However KVM always uses paging mode to | 3525 | * in hardware. However KVM always uses paging mode to |
3489 | * emulate guest non-paging mode with TDP. | 3526 | * emulate guest non-paging mode with TDP. |
3490 | * To emulate this behavior, SMEP needs to be manually | 3527 | * To emulate this behavior, SMEP/SMAP needs to be |
3491 | * disabled when guest switches to non-paging mode. | 3528 | * manually disabled when guest switches to non-paging |
3529 | * mode. | ||
3492 | */ | 3530 | */ |
3493 | hw_cr4 &= ~X86_CR4_SMEP; | 3531 | hw_cr4 &= ~(X86_CR4_SMEP | X86_CR4_SMAP); |
3494 | } else if (!(cr4 & X86_CR4_PAE)) { | 3532 | } else if (!(cr4 & X86_CR4_PAE)) { |
3495 | hw_cr4 &= ~X86_CR4_PAE; | 3533 | hw_cr4 &= ~X86_CR4_PAE; |
3496 | } | 3534 | } |
@@ -7740,7 +7778,8 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) | |||
7740 | 7778 | ||
7741 | exec_control = vmcs12->pin_based_vm_exec_control; | 7779 | exec_control = vmcs12->pin_based_vm_exec_control; |
7742 | exec_control |= vmcs_config.pin_based_exec_ctrl; | 7780 | exec_control |= vmcs_config.pin_based_exec_ctrl; |
7743 | exec_control &= ~PIN_BASED_VMX_PREEMPTION_TIMER; | 7781 | exec_control &= ~(PIN_BASED_VMX_PREEMPTION_TIMER | |
7782 | PIN_BASED_POSTED_INTR); | ||
7744 | vmcs_write32(PIN_BASED_VM_EXEC_CONTROL, exec_control); | 7783 | vmcs_write32(PIN_BASED_VM_EXEC_CONTROL, exec_control); |
7745 | 7784 | ||
7746 | vmx->nested.preemption_timer_expired = false; | 7785 | vmx->nested.preemption_timer_expired = false; |
@@ -7777,7 +7816,9 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) | |||
7777 | if (!vmx->rdtscp_enabled) | 7816 | if (!vmx->rdtscp_enabled) |
7778 | exec_control &= ~SECONDARY_EXEC_RDTSCP; | 7817 | exec_control &= ~SECONDARY_EXEC_RDTSCP; |
7779 | /* Take the following fields only from vmcs12 */ | 7818 | /* Take the following fields only from vmcs12 */ |
7780 | exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES; | 7819 | exec_control &= ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | |
7820 | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | | ||
7821 | SECONDARY_EXEC_APIC_REGISTER_VIRT); | ||
7781 | if (nested_cpu_has(vmcs12, | 7822 | if (nested_cpu_has(vmcs12, |
7782 | CPU_BASED_ACTIVATE_SECONDARY_CONTROLS)) | 7823 | CPU_BASED_ACTIVATE_SECONDARY_CONTROLS)) |
7783 | exec_control |= vmcs12->secondary_vm_exec_control; | 7824 | exec_control |= vmcs12->secondary_vm_exec_control; |
@@ -8802,14 +8843,6 @@ static int __init vmx_init(void) | |||
8802 | 8843 | ||
8803 | memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE); | 8844 | memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE); |
8804 | memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE); | 8845 | memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE); |
8805 | /* shadowed read/write fields */ | ||
8806 | for (i = 0; i < max_shadow_read_write_fields; i++) { | ||
8807 | clear_bit(shadow_read_write_fields[i], vmx_vmwrite_bitmap); | ||
8808 | clear_bit(shadow_read_write_fields[i], vmx_vmread_bitmap); | ||
8809 | } | ||
8810 | /* shadowed read only fields */ | ||
8811 | for (i = 0; i < max_shadow_read_only_fields; i++) | ||
8812 | clear_bit(shadow_read_only_fields[i], vmx_vmread_bitmap); | ||
8813 | 8846 | ||
8814 | /* | 8847 | /* |
8815 | * Allow direct access to the PC debug port (it is often used for I/O | 8848 | * Allow direct access to the PC debug port (it is often used for I/O |