On Fri, Nov 03, 2017 at 04:30:08PM -0400, nilal@xxxxxxxxxx wrote: > From: Nitesh Narayan Lal <nilal@xxxxxxxxxx> > > This patch includes the following: > 1. Basic skeleton for the support > 2. Enablement of x86 platform to use the same > > Signed-off-by: Nitesh Narayan Lal <nilal@xxxxxxxxxx> > --- > arch/x86/Kbuild | 2 +- > arch/x86/kvm/Makefile | 2 ++ > include/linux/gfp.h | 7 +++++++ > virt/kvm/Kconfig | 4 ++++ > virt/kvm/page_hinting.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ > 5 files changed, 60 insertions(+), 1 deletion(-) > create mode 100644 virt/kvm/page_hinting.c > > diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild > index 0038a2d..7d39d7d 100644 > --- a/arch/x86/Kbuild > +++ b/arch/x86/Kbuild > @@ -2,7 +2,7 @@ obj-y += entry/ > > obj-$(CONFIG_PERF_EVENTS) += events/ > > -obj-$(CONFIG_KVM) += kvm/ > +obj-$(subst m,y,$(CONFIG_KVM)) += kvm/ > > # Xen paravirtualization support > obj-$(CONFIG_XEN) += xen/ > diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile > index 09d4b17..d8a3800 100644 > --- a/arch/x86/kvm/Makefile > +++ b/arch/x86/kvm/Makefile > @@ -15,6 +15,8 @@ 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 page_track.o debugfs.o > > +obj-$(CONFIG_KVM_FREE_PAGE_HINTING) += $(KVM)/page_hinting.o > + > kvm-intel-y += vmx.o pmu_intel.o > kvm-amd-y += svm.o pmu_amd.o > > diff --git a/include/linux/gfp.h b/include/linux/gfp.h > index f780718..a74371f 100644 > --- a/include/linux/gfp.h > +++ b/include/linux/gfp.h > @@ -452,6 +452,13 @@ static inline struct zonelist *node_zonelist(int nid, gfp_t flags) > return NODE_DATA(nid)->node_zonelists + gfp_zonelist(flags); > } > > +#ifdef CONFIG_KVM_FREE_PAGE_HINTING > +#define HAVE_ARCH_ALLOC_PAGE > +#define HAVE_ARCH_FREE_PAGE > +void arch_free_page(struct page *page, int order); > +void arch_alloc_page(struct page *page, int order); > +#endif > + > #ifndef HAVE_ARCH_FREE_PAGE > static inline void arch_free_page(struct page *page, int order) { } > #endif So the idea is to send pages to host in arch_free_page? However, I notice: arch_free_page(page, order); kernel_poison_pages(page, 1 << order, 0); Thus pages are immediately written to after they are freed. > diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig > index b0cc1a3..936c71d 100644 > --- a/virt/kvm/Kconfig > +++ b/virt/kvm/Kconfig > @@ -50,3 +50,7 @@ config KVM_COMPAT > > config HAVE_KVM_IRQ_BYPASS > bool > + > +config KVM_FREE_PAGE_HINTING > + def_bool y > + depends on KVM > diff --git a/virt/kvm/page_hinting.c b/virt/kvm/page_hinting.c > new file mode 100644 > index 0000000..39d2b1d > --- /dev/null > +++ b/virt/kvm/page_hinting.c > @@ -0,0 +1,46 @@ > +#include <linux/gfp.h> > +#include <linux/mm.h> > +#include <linux/page_ref.h> > +#include <linux/kvm_host.h> > +#include <linux/sort.h> > + > +#include <trace/events/kvm.h> > + > +#define MAX_FGPT_ENTRIES 1000 > +#define HYPERLIST_THRESHOLD 500 > +/* > + * struct kvm_free_pages - Tracks the pages which are freed by the guest. > + * @pfn - page frame number for the page which is to be freed > + * @pages - number of pages which are supposed to be freed. > + * A global array object is used to hold the list of pfn and number of pages > + * which are freed by the guest. This list may also have fragmentated pages so > + * defragmentation is a must prior to the hypercall. > + */ > +struct kvm_free_pages { > + unsigned long pfn; > + unsigned int pages; > +}; > + > +/* > + * hypervisor_pages - It is a dummy structure passed with the hypercall. > + * @pfn - page frame number for the page which is to be freed. > + * @pages - number of pages which are supposed to be freed. > + * A global array object is used to to hold the list of pfn and pages and is > + * passed as part of the hypercall. > + */ > +struct hypervisor_pages { > + unsigned long pfn; > + unsigned int pages; > +}; > + > +DEFINE_PER_CPU(struct kvm_free_pages [MAX_FGPT_ENTRIES], kvm_pt); > +DEFINE_PER_CPU(int, kvm_pt_idx); > +struct hypervisor_pages hypervisor_pagelist[MAX_FGPT_ENTRIES]; > + > +void arch_alloc_page(struct page *page, int order) > +{ > +} > + > +void arch_free_page(struct page *page, int order) > +{ > +} > -- > 2.9.4