| From 478258bb62e9eed8632db2c602ef0e7c3f48a433 Mon Sep 17 00:00:00 2001 |
| From: Oliver Upton <oupton@google.com> |
| Date: Tue, 4 Feb 2020 15:26:30 -0800 |
| Subject: [PATCH] KVM: nVMX: Refactor IO bitmap checks into helper function |
| |
| commit e71237d3ff1abf9f3388337cfebf53b96df2020d upstream. |
| |
| Checks against the IO bitmap are useful for both instruction emulation |
| and VM-exit reflection. Refactor the IO bitmap checks into a helper |
| function. |
| |
| Signed-off-by: Oliver Upton <oupton@google.com> |
| Reviewed-by: Vitaly Kuznetsov <vkuznets@redhat.com> |
| Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c |
| index 5811a0bba0d7..95ab9d7b1960 100644 |
| --- a/arch/x86/kvm/vmx/nested.c |
| +++ b/arch/x86/kvm/vmx/nested.c |
| @@ -4894,24 +4894,17 @@ static int handle_vmfunc(struct kvm_vcpu *vcpu) |
| return 1; |
| } |
| |
| - |
| -static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu, |
| - struct vmcs12 *vmcs12) |
| +/* |
| + * Return true if an IO instruction with the specified port and size should cause |
| + * a VM-exit into L1. |
| + */ |
| +bool nested_vmx_check_io_bitmaps(struct kvm_vcpu *vcpu, unsigned int port, |
| + int size) |
| { |
| - unsigned long exit_qualification; |
| + struct vmcs12 *vmcs12 = get_vmcs12(vcpu); |
| gpa_t bitmap, last_bitmap; |
| - unsigned int port; |
| - int size; |
| u8 b; |
| |
| - if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS)) |
| - return nested_cpu_has(vmcs12, CPU_BASED_UNCOND_IO_EXITING); |
| - |
| - exit_qualification = vmcs_readl(EXIT_QUALIFICATION); |
| - |
| - port = exit_qualification >> 16; |
| - size = (exit_qualification & 7) + 1; |
| - |
| last_bitmap = (gpa_t)-1; |
| b = -1; |
| |
| @@ -4938,6 +4931,24 @@ static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu, |
| return false; |
| } |
| |
| +static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu, |
| + struct vmcs12 *vmcs12) |
| +{ |
| + unsigned long exit_qualification; |
| + unsigned int port; |
| + int size; |
| + |
| + if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS)) |
| + return nested_cpu_has(vmcs12, CPU_BASED_UNCOND_IO_EXITING); |
| + |
| + exit_qualification = vmcs_readl(EXIT_QUALIFICATION); |
| + |
| + port = exit_qualification >> 16; |
| + size = (exit_qualification & 7) + 1; |
| + |
| + return nested_vmx_check_io_bitmaps(vcpu, port, size); |
| +} |
| + |
| /* |
| * Return 1 if we should exit from L2 to L1 to handle an MSR access access, |
| * rather than handle it ourselves in L0. I.e., check whether L1 expressed |
| diff --git a/arch/x86/kvm/vmx/nested.h b/arch/x86/kvm/vmx/nested.h |
| index 29d205bb4e4f..bbec76bb4f1a 100644 |
| --- a/arch/x86/kvm/vmx/nested.h |
| +++ b/arch/x86/kvm/vmx/nested.h |
| @@ -22,6 +22,8 @@ int vmx_set_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data); |
| int vmx_get_vmx_msr(struct nested_vmx_msrs *msrs, u32 msr_index, u64 *pdata); |
| int get_vmx_mem_address(struct kvm_vcpu *vcpu, unsigned long exit_qualification, |
| u32 vmx_instruction_info, bool wr, int len, gva_t *ret); |
| +bool nested_vmx_check_io_bitmaps(struct kvm_vcpu *vcpu, unsigned int port, |
| + int size); |
| |
| static inline struct vmcs12 *get_vmcs12(struct kvm_vcpu *vcpu) |
| { |
| -- |
| 2.7.4 |
| |