From mboxrd@z Thu Jan 1 00:00:00 1970 From: Izik Eidus Subject: [RFC][PATCH 1/5] rmap: add new exported function: page_wrprotect() Date: Mon, 21 Jan 2008 18:09:29 +0200 Message-ID: <4794C3B9.7060506@qumranet.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------070206020703090900080506" To: kvm-devel , andrea-atKUWr5tajBWk0Htik3J/w@public.gmane.org, avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org, dor.laor-atKUWr5tajBWk0Htik3J/w@public.gmane.org, linux-mm-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org, yaniv-atKUWr5tajBWk0Htik3J/w@public.gmane.org Return-path: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: kvm-devel-bounces-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org Errors-To: kvm-devel-bounces-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org List-Id: kvm.vger.kernel.org This is a multi-part message in MIME format. --------------070206020703090900080506 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit --------------070206020703090900080506 Content-Type: text/x-patch; name="0004-rmap-add-new-exported-function-page_wrprotect.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename*0="0004-rmap-add-new-exported-function-page_wrprotect.patch" >>From 45e5a255b004e0d578007576304a6b1e272fcb67 Mon Sep 17 00:00:00 2001 From: Izik Eidus Date: Mon, 21 Jan 2008 16:59:35 +0200 Subject: [PATCH] rmap: add new exported function: page_wrprotect(), page_wrprotect() make the page as read only by setting the ptes point to it as read only. Signed-off-by: Izik Eidus --- include/linux/rmap.h | 7 ++++ mm/rmap.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 0 deletions(-) diff --git a/include/linux/rmap.h b/include/linux/rmap.h index 97347f2..dac41af 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -108,6 +108,8 @@ unsigned long page_address_in_vma(struct page *, struct vm_area_struct *); */ int page_mkclean(struct page *); +int page_wrprotect(struct page *page); + #else /* !CONFIG_MMU */ #define anon_vma_init() do {} while (0) @@ -122,6 +124,11 @@ static inline int page_mkclean(struct page *page) return 0; } +static inline int page_wrprotect(struct page *page) +{ + return 0; +} + #endif /* CONFIG_MMU */ diff --git a/mm/rmap.c b/mm/rmap.c index dbc2ca2..462b7c9 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -484,6 +484,97 @@ int page_mkclean(struct page *page) } EXPORT_SYMBOL_GPL(page_mkclean); +static int page_wrprotect_one(struct page *page, struct vm_area_struct *vma) +{ + struct mm_struct *mm = vma->vm_mm; + unsigned long address; + pte_t *pte; + spinlock_t *ptl; + int ret = 0; + + address = vma_address(page, vma); + if (address == -EFAULT) + goto out; + + pte = page_check_address(page, mm, address, &ptl); + if (!pte) + goto out; + + if (pte_write(*pte)) { + pte_t entry; + + flush_cache_page(vma, address, pte_pfn(*pte)); + entry = ptep_clear_flush(vma, address, pte); + entry = pte_wrprotect(entry); + set_pte_at(mm, address, pte, entry); + } + ret = 1; + + pte_unmap_unlock(pte, ptl); +out: + return ret; +} + +static int page_wrprotect_file(struct page *page) +{ + struct address_space *mapping; + struct prio_tree_iter iter; + struct vm_area_struct *vma; + pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); + int ret = 0; + + mapping = page_mapping(page); + if (!mapping) + return ret; + + spin_lock(&mapping->i_mmap_lock); + + vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) + ret += page_wrprotect_one(page, vma); + + spin_unlock(&mapping->i_mmap_lock); + + return ret; +} + +static int page_wrprotect_anon(struct page *page) +{ + struct vm_area_struct *vma; + struct anon_vma *anon_vma; + int ret = 0; + + anon_vma = page_lock_anon_vma(page); + if (!anon_vma) + return ret; + + list_for_each_entry(vma, &anon_vma->head, anon_vma_node) + ret += page_wrprotect_one(page, vma); + + page_unlock_anon_vma(anon_vma); + + return ret; +} + +/** + * set all the ptes pointed to a page as read only + * return the number of ptes that were set as read only + * (ptes that were read only before this was called are counted as well) + */ +int page_wrprotect(struct page *page) +{ + int ret = 0; + + BUG_ON(!PageLocked(page)); + + if (PageAnon(page)) + ret = page_wrprotect_anon(page); + else + ret = page_wrprotect_file(page); + + return ret; +} +EXPORT_SYMBOL(page_wrprotect); + /** * page_set_anon_rmap - setup new anonymous rmap * @page: the page to add the mapping to -- 1.5.3.6 --------------070206020703090900080506 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ --------------070206020703090900080506 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ kvm-devel mailing list kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org https://lists.sourceforge.net/lists/listinfo/kvm-devel --------------070206020703090900080506--