Introduce function nested_get_vmcs12_pages() to check the valid
of nested apic access page and virtual apic page earlier.
Signed-off-by: Wanpeng Li <wanpeng...@linux.intel.com>
---
v5 -> v6:
 * replace the name apic_access_and_virtual_page_valid by 
nested_get_vmcs12_pages

 arch/x86/kvm/vmx.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 286c283..24380a9 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -7826,6 +7826,30 @@ static void vmx_inject_page_fault_nested(struct kvm_vcpu 
*vcpu,
                kvm_inject_page_fault(vcpu, fault);
 }
 
+static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu,
+                                       struct vmcs12 *vmcs12)
+{
+       struct vcpu_vmx *vmx = to_vmx(vcpu);
+
+       if (nested_cpu_has2(vmcs12, SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) {
+               if (!PAGE_ALIGNED(vmcs12->apic_access_addr))
+                       /*TODO: Also verify bits beyond physical address width 
are 0*/
+                       return false;
+
+               /*
+                * Translate L1 physical address to host physical
+                * address for vmcs02. Keep the page pinned, so this
+                * physical address remains valid. We keep a reference
+                * to it so we can release it later.
+                */
+               if (vmx->nested.apic_access_page) /* shouldn't happen */
+                       nested_release_page(vmx->nested.apic_access_page);
+               vmx->nested.apic_access_page =
+                       nested_get_page(vcpu, vmcs12->apic_access_addr);
+       }
+       return true;
+}
+
 static void vmx_start_preemption_timer(struct kvm_vcpu *vcpu)
 {
        u64 preemption_timeout = get_vmcs12(vcpu)->vmx_preemption_timer_value;
@@ -7972,16 +7996,6 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct 
vmcs12 *vmcs12)
 
                if (exec_control & SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES) {
                        /*
-                        * Translate L1 physical address to host physical
-                        * address for vmcs02. Keep the page pinned, so this
-                        * physical address remains valid. We keep a reference
-                        * to it so we can release it later.
-                        */
-                       if (vmx->nested.apic_access_page) /* shouldn't happen */
-                               
nested_release_page(vmx->nested.apic_access_page);
-                       vmx->nested.apic_access_page =
-                               nested_get_page(vcpu, vmcs12->apic_access_addr);
-                       /*
                         * If translation failed, no matter: This feature asks
                         * to exit when accessing the given address, and if it
                         * can never be accessed, this feature won't do
@@ -8187,8 +8201,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool 
launch)
                return 1;
        }
 
-       if (nested_cpu_has2(vmcs12, SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES) &&
-                       !PAGE_ALIGNED(vmcs12->apic_access_addr)) {
+       if (!nested_get_vmcs12_pages(vcpu, vmcs12)) {
                /*TODO: Also verify bits beyond physical address width are 0*/
                nested_vmx_failValid(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
                return 1;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to