KVM: Fix unused but set warnings
[linux-2.6.git] / arch / x86 / kvm / paging_tmpl.h
index 22f1379..9308be2 100644 (file)
@@ -7,6 +7,7 @@
  * MMU support
  *
  * Copyright (C) 2006 Qumranet, Inc.
+ * Copyright 2010 Red Hat, Inc. and/or its affilates.
  *
  * Authors:
  *   Yaniv Kamay  <yaniv@qumranet.com>
@@ -338,10 +339,13 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
                        direct = 1;
                        if (!is_dirty_gpte(gw->ptes[level - delta]))
                                access &= ~ACC_WRITE_MASK;
-                       table_gfn = gpte_to_gfn(gw->ptes[level - delta]);
-                       /* advance table_gfn when emulating 1gb pages with 4k */
-                       if (delta == 0)
-                               table_gfn += PT_INDEX(addr, level);
+                       /*
+                        * It is a large guest pages backed by small host pages,
+                        * So we set @direct(@shadow_page->role.direct)=1, and
+                        * set @table_gfn(@shadow_page->gfn)=the base page frame
+                        * for linear translations.
+                        */
+                       table_gfn = gw->gfn & ~(KVM_PAGES_PER_HPAGE(level) - 1);
                        access &= gw->pte_access;
                } else {
                        direct = 0;
@@ -440,6 +444,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
        kvm_mmu_free_some_pages(vcpu);
        sptep = FNAME(fetch)(vcpu, addr, &walker, user_fault, write_fault,
                             level, &write_pt, pfn);
+       (void)sptep;
        pgprintk("%s: shadow pte %p %llx ptwrite %d\n", __func__,
                 sptep, *sptep, write_pt);
 
@@ -461,6 +466,7 @@ out_unlock:
 static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
 {
        struct kvm_shadow_walk_iterator iterator;
+       struct kvm_mmu_page *sp;
        gpa_t pte_gpa = -1;
        int level;
        u64 *sptep;
@@ -472,10 +478,13 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
                level = iterator.level;
                sptep = iterator.sptep;
 
+               sp = page_header(__pa(sptep));
                if (is_last_spte(*sptep, level)) {
-                       struct kvm_mmu_page *sp = page_header(__pa(sptep));
                        int offset, shift;
 
+                       if (!sp->unsync)
+                               break;
+
                        shift = PAGE_SHIFT -
                                  (PT_LEVEL_BITS - PT64_LEVEL_BITS) * level;
                        offset = sp->role.quadrant << shift;
@@ -493,7 +502,7 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
                        break;
                }
 
-               if (!is_shadow_present_pte(*sptep))
+               if (!is_shadow_present_pte(*sptep) || !sp->unsync_children)
                        break;
        }
 
@@ -577,6 +586,9 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
 
        offset = nr_present = 0;
 
+       /* direct kvm_mmu_page can not be unsync. */
+       BUG_ON(sp->role.direct);
+
        if (PTTYPE == 32)
                offset = sp->role.quadrant << PT64_LEVEL_BITS;