Account pages that only have global entries. Such pages need to be
synced on cr4 writes, but not cr3 writes.

Index: kvm/arch/x86/kvm/mmu.c
===================================================================
--- kvm.orig/arch/x86/kvm/mmu.c
+++ kvm/arch/x86/kvm/mmu.c
@@ -778,6 +778,7 @@ static struct kvm_mmu_page *kvm_mmu_allo
        ASSERT(is_empty_shadow_page(sp->spt));
        sp->slot_bitmap = 0;
        sp->multimapped = 0;
+       sp->flags = (1 << KVM_PG_global);
        sp->parent_pte = parent_pte;
        --vcpu->kvm->arch.n_free_mmu_pages;
        return sp;
@@ -1147,18 +1148,22 @@ struct page *gva_to_page(struct kvm_vcpu
 static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
                         unsigned pt_access, unsigned pte_access,
                         int user_fault, int write_fault, int dirty,
-                        int *ptwrite, int largepage, gfn_t gfn,
-                        pfn_t pfn, bool speculative)
+                        int global, int *ptwrite, int largepage,
+                        gfn_t gfn, pfn_t pfn, bool speculative)
 {
        u64 spte;
        int was_rmapped = 0;
        int was_writeble = is_writeble_pte(*shadow_pte);
+       struct kvm_mmu_page *sp = page_header(__pa(shadow_pte));
 
        pgprintk("%s: spte %llx access %x write_fault %d"
                 " user_fault %d gfn %lx\n",
                 __func__, *shadow_pte, pt_access,
                 write_fault, user_fault, gfn);
 
+       if (!global)
+               kvm_clear_pg_global(sp);
+
        if (is_rmap_pte(*shadow_pte)) {
                /*
                 * If we overwrite a PTE page pointer with a 2MB PMD, unlink
@@ -1285,7 +1290,7 @@ static int direct_map_entry(struct kvm_s
        if (level == PT_PAGE_TABLE_LEVEL
            || (walk->largepage && level == PT_DIRECTORY_LEVEL)) {
                mmu_set_spte(vcpu, sptep, ACC_ALL, ACC_ALL,
-                            0, walk->write, 1, &walk->pt_write,
+                            0, walk->write, 1, 0, &walk->pt_write,
                             walk->largepage, gfn, walk->pfn, false);
                ++vcpu->stat.pf_fixed;
                return 1;
Index: kvm/include/asm-x86/kvm_host.h
===================================================================
--- kvm.orig/include/asm-x86/kvm_host.h
+++ kvm/include/asm-x86/kvm_host.h
@@ -199,6 +199,7 @@ struct kvm_mmu_page {
                u64 *parent_pte;               /* !multimapped */
                struct hlist_head parent_ptes; /* multimapped, kvm_pte_chain */
        };
+       unsigned long flags;
 };
 
 struct kvm_pv_mmu_op_buffer {
@@ -757,4 +758,20 @@ asmlinkage void kvm_handle_fault_on_rebo
 int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
 int kvm_age_hva(struct kvm *kvm, unsigned long hva);
 
+enum kvm_page_flags {
+       KVM_PG_global,
+};
+
+#define KVMPGFLAG(name)                                                        
\
+static inline int kvm_page_##name(struct kvm_mmu_page *sp)             \
+       { return test_bit(KVM_PG_##name, &sp->flags); }                 \
+static inline void kvm_set_pg_##name(struct kvm_mmu_page *sp)          \
+       { set_bit(KVM_PG_##name, &sp->flags); }                         \
+static inline void kvm_clear_pg_##name(struct kvm_mmu_page *sp)                
\
+       { clear_bit(KVM_PG_##name, &sp->flags); }                       \
+static inline int kvm_test_clear_pg_##name(struct kvm_mmu_page *sp)    \
+       { return test_and_clear_bit(KVM_PG_##name, &sp->flags); }
+
+KVMPGFLAG(global);
+
 #endif
Index: kvm/arch/x86/kvm/paging_tmpl.h
===================================================================
--- kvm.orig/arch/x86/kvm/paging_tmpl.h
+++ kvm/arch/x86/kvm/paging_tmpl.h
@@ -274,8 +274,8 @@ static void FNAME(update_pte)(struct kvm
                return;
        kvm_get_pfn(pfn);
        mmu_set_spte(vcpu, spte, page->role.access, pte_access, 0, 0,
-                    gpte & PT_DIRTY_MASK, NULL, largepage, gpte_to_gfn(gpte),
-                    pfn, true);
+                    gpte & PT_DIRTY_MASK, gpte & PT_GLOBAL_MASK, NULL,
+                    largepage, gpte_to_gfn(gpte), pfn, true);
 }
 
 /*
@@ -301,6 +301,7 @@ static int FNAME(shadow_walk_entry)(stru
                mmu_set_spte(vcpu, sptep, access, gw->pte_access & access,
                             sw->user_fault, sw->write_fault,
                             gw->ptes[gw->level-1] & PT_DIRTY_MASK,
+                            gw->ptes[gw->level-1] & PT_GLOBAL_MASK,
                             sw->ptwrite, sw->largepage, gw->gfn, sw->pfn,
                             false);
                sw->sptep = sptep;

-- 

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to