#include <asm/mtrr.h>
 #include <asm/msr-index.h>
 #include <asm/asm.h>
+#include <asm/kvm_page_track.h>
 
 #define KVM_MAX_VCPUS 255
 #define KVM_SOFT_MAX_VCPUS 160
        void *objects[KVM_NR_MEM_OBJS];
 };
 
+/*
+ * the pages used as guest page table on soft mmu are tracked by
+ * kvm_memory_slot.arch.gfn_track which is 16 bits, so the role bits used
+ * by indirect shadow page can not be more than 15 bits.
+ *
+ * Currently, we used 14 bits that are @level, @cr4_pae, @quadrant, @access,
+ * @nxe, @cr0_wp, @smep_andnot_wp and @smap_andnot_wp.
+ */
 union kvm_mmu_page_role {
        unsigned word;
        struct {
 struct kvm_arch_memory_slot {
        struct kvm_rmap_head *rmap[KVM_NR_PAGE_SIZES];
        struct kvm_lpage_info *lpage_info[KVM_NR_PAGE_SIZES - 1];
+       unsigned short *gfn_track[KVM_PAGE_TRACK_MAX];
 };
 
 /*
 
--- /dev/null
+#ifndef _ASM_X86_KVM_PAGE_TRACK_H
+#define _ASM_X86_KVM_PAGE_TRACK_H
+
+enum kvm_page_track_mode {
+       KVM_PAGE_TRACK_WRITE,
+       KVM_PAGE_TRACK_MAX,
+};
+
+void kvm_page_track_free_memslot(struct kvm_memory_slot *free,
+                                struct kvm_memory_slot *dont);
+int kvm_page_track_create_memslot(struct kvm_memory_slot *slot,
+                                 unsigned long npages);
+#endif
 
 
 kvm-y                  += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \
                           i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o \
-                          hyperv.o
+                          hyperv.o page_track.o
 
 kvm-$(CONFIG_KVM_DEVICE_ASSIGNMENT)    += assigned-dev.o iommu.o
+
 kvm-intel-y            += vmx.o pmu_intel.o
 kvm-amd-y              += svm.o pmu_amd.o
 
 
--- /dev/null
+/*
+ * Support KVM gust page tracking
+ *
+ * This feature allows us to track page access in guest. Currently, only
+ * write access is tracked.
+ *
+ * Copyright(C) 2015 Intel Corporation.
+ *
+ * Author:
+ *   Xiao Guangrong <guangrong.xiao@linux.intel.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include <linux/kvm_host.h>
+#include <asm/kvm_host.h>
+#include <asm/kvm_page_track.h>
+
+#include "mmu.h"
+
+void kvm_page_track_free_memslot(struct kvm_memory_slot *free,
+                                struct kvm_memory_slot *dont)
+{
+       int i;
+
+       for (i = 0; i < KVM_PAGE_TRACK_MAX; i++)
+               if (!dont || free->arch.gfn_track[i] !=
+                     dont->arch.gfn_track[i]) {
+                       kvfree(free->arch.gfn_track[i]);
+                       free->arch.gfn_track[i] = NULL;
+               }
+}
+
+int kvm_page_track_create_memslot(struct kvm_memory_slot *slot,
+                                 unsigned long npages)
+{
+       int  i;
+
+       for (i = 0; i < KVM_PAGE_TRACK_MAX; i++) {
+               slot->arch.gfn_track[i] = kvm_kvzalloc(npages *
+                                           sizeof(*slot->arch.gfn_track[i]));
+               if (!slot->arch.gfn_track[i])
+                       goto track_free;
+       }
+
+       return 0;
+
+track_free:
+       kvm_page_track_free_memslot(slot, NULL);
+       return -ENOMEM;
+}
 
                        free->arch.lpage_info[i - 1] = NULL;
                }
        }
+
+       kvm_page_track_free_memslot(free, dont);
 }
 
 int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot,
                }
        }
 
+       if (kvm_page_track_create_memslot(slot, npages))
+               goto out_free;
+
        return 0;
 
 out_free: