From: Adalbert Lazar <alazar@bitdefender.com>
To: kvm@vger.kernel.org
Cc: "Paolo Bonzini" <pbonzini@redhat.com>,
"Radim Krčmář" <rkrcmar@redhat.com>,
alazar@bitdefender.com, mdontu@bitdefender.com
Subject: [RFC PATCH 03/19] mm: Add vm_replace_page()
Date: Fri, 16 Jun 2017 16:43:32 +0300 [thread overview]
Message-ID: <20170616134348.17725-4-alazar@bitdefender.com> (raw)
In-Reply-To: <20170616134348.17725-1-alazar@bitdefender.com>
From: Mihai Dontu <mdontu@bitdefender.com>
This function is used to get two processes to share a page. It's inspired
by replace_page() from KSM.
Signed-off-by: Mihai Dontu <mdontu@bitdefender.com>
---
include/linux/mm.h | 1 +
mm/memory.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 70 insertions(+)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index b892e95d4929..9cd088ef9d0c 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2296,6 +2296,7 @@ int vm_insert_pfn_prot(struct vm_area_struct *vma, unsigned long addr,
unsigned long pfn, pgprot_t pgprot);
int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr,
pfn_t pfn);
+int vm_replace_page(struct vm_area_struct *vma, struct page *page);
int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long len);
diff --git a/mm/memory.c b/mm/memory.c
index 2e65df1831d9..ae7716ffe6e9 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1776,6 +1776,75 @@ int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr,
}
EXPORT_SYMBOL(vm_insert_mixed);
+/**
+ * vm_replace_page - given a page-sized VMA, drop the currently
+ * referenced page and place the specified one
+ * in its stead
+ * @vma: the remote user VMA in which the replace takes place
+ * @page: the page with which we make the replacement
+ */
+int vm_replace_page(struct vm_area_struct *vma, struct page *page)
+{
+ unsigned long mmun_start;
+ unsigned long mmun_end;
+ struct mm_struct *mm = vma->vm_mm;
+ pmd_t *pmd;
+ struct page *old_page;
+ pte_t *ptep;
+ spinlock_t *ptl;
+
+ /* Make sure the area is page aligned */
+ if (vma->vm_start % PAGE_SIZE)
+ return -EINVAL;
+
+ /* Make sure the area is page-sized */
+ if ((vma->vm_end - vma->vm_start) != PAGE_SIZE)
+ return -EINVAL;
+
+ old_page = follow_page(vma, vma->vm_start, 0);
+ if (IS_ERR_OR_NULL(old_page))
+ return old_page ? PTR_ERR(old_page) : -ENOENT;
+
+ pmd = mm_find_pmd(mm, vma->vm_start);
+ if (!pmd)
+ return -ENOENT;
+
+ mmun_start = vma->vm_start;
+ mmun_end = mmun_start + PAGE_SIZE;
+ mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
+
+ ptep = pte_offset_map_lock(mm, pmd, vma->vm_start, &ptl);
+
+ get_page(page);
+ page_add_anon_rmap(page, vma, vma->vm_start, false);
+
+ flush_cache_page(vma, vma->vm_start, pte_pfn(*ptep));
+ ptep_clear_flush_notify(vma, vma->vm_start, ptep);
+
+ /*
+ * TODO: Find why we can't do:
+ * set_pte_at_notify(mm, vma->vm_start, ptep,
+ * mk_pte(page, vma->vm_page_prot))
+ */
+ set_pte_at_notify(mm, vma->vm_start, ptep,
+ mk_pte(page,
+ __pgprot(_PAGE_PRESENT | _PAGE_RW |
+ _PAGE_BIT_NX)));
+
+ /* Drop the old page */
+ page_remove_rmap(old_page, false);
+ if (!page_mapped(old_page))
+ try_to_free_swap(old_page);
+ put_page(old_page);
+
+ pte_unmap_unlock(ptep, ptl);
+
+ mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(vm_replace_page);
+
/*
* maps a range of physical memory into the requested pages. the old
* mappings are removed. any references to nonexistent pages results
--
2.12.2
next prev parent reply other threads:[~2017-06-16 13:42 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-16 13:43 [RFC PATCH 00/19] Guest introspection Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 01/19] kvm: x86: mmu: Add kvm_mmu_get_spte() and kvm_mmu_set_spte() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 02/19] kvm: x86: Add kvm_arch_vcpu_set_regs() Adalbert Lazar
2017-06-16 13:43 ` Adalbert Lazar [this message]
2017-06-16 13:43 ` [RFC PATCH 04/19] kvm: Add kvm_enum() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 05/19] kvm: Add uuid member in struct kvm + support for KVM_CAP_VM_UUID Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 06/19] kvm: Add kvm_vm_shutdown() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 07/19] kvm: x86: Add kvm_arch_msr_intercept() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 08/19] kvm: Add the introspection subsystem Adalbert Lazar
2017-06-21 11:54 ` Paolo Bonzini
2017-06-21 12:36 ` Mihai Donțu
2017-06-21 12:57 ` Paolo Bonzini
2017-06-16 13:43 ` [RFC PATCH 09/19] kvm: Hook in kvmi on VM on/off events Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 10/19] kvm: vmx: Hook in kvmi_page_fault() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 11/19] kvm: x86: Hook in kvmi_breakpoint_event() Adalbert Lazar
2017-06-21 11:48 ` Paolo Bonzini
2017-06-21 12:37 ` Mihai Donțu
2017-06-16 13:43 ` [RFC PATCH 12/19] kvm: x86: Hook in kvmi_trap_event() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 13/19] kvm: x86: Hook in kvmi_cr_event() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 14/19] kvm: x86: Hook in kvmi_xsetbv_event() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 15/19] kvm: x86: Hook in kvmi_msr_event() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 16/19] kvm: x86: Change the emulation context Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 17/19] kvm: x86: Hook in kvmi_vmcall_event() Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 18/19] kvm: x86: Set the new spte flags before entering the guest Adalbert Lazar
2017-06-16 13:43 ` [RFC PATCH 19/19] kvm: x86: Handle KVM_REQ_INTROSPECTION Adalbert Lazar
2017-06-16 14:45 ` [RFC PATCH 00/19] Guest introspection Jan Kiszka
2017-06-16 15:18 ` Mihai Donțu
2017-06-16 15:34 ` Jan Kiszka
2017-06-16 15:59 ` Mihai Donțu
2017-06-19 9:39 ` Stefan Hajnoczi
2017-06-20 14:58 ` alazar
2017-06-20 15:03 ` Jan Kiszka
2017-06-21 11:04 ` Stefan Hajnoczi
2017-06-21 13:25 ` Paolo Bonzini
2017-06-27 16:12 ` Mihai Donțu
2017-06-27 16:23 ` Paolo Bonzini
2017-06-16 17:05 ` Paolo Bonzini
2017-06-16 17:27 ` Jan Kiszka
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170616134348.17725-4-alazar@bitdefender.com \
--to=alazar@bitdefender.com \
--cc=kvm@vger.kernel.org \
--cc=mdontu@bitdefender.com \
--cc=pbonzini@redhat.com \
--cc=rkrcmar@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox