lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 5 Feb 2013 15:03:39 +0800
From:	Huang Shijie <b32955@...escale.com>
To:	<akpm@...ux-foundation.org>
CC:	<linux-mm@...ck.org>, <linux-kernel@...r.kernel.org>,
	Huang Shijie <b32955@...escale.com>
Subject: [PATCH] mm: introduce __linear_page_index()

There are many places we should get the offset(in PAGE_SIZE unit) of
an address within a non-hugetlb vma.

In order to simplify the code, add a new helper __linear_page_index()
to do the work.

Signed-off-by: Huang Shijie <b32955@...escale.com>
---

This patch is based on linux-next tree.

---
 arch/arm/mm/fault-armv.c            |    2 +-
 arch/powerpc/kvm/book3s_64_mmu_hv.c |    5 ++---
 arch/x86/mm/hugetlbpage.c           |    3 +--
 include/linux/pagemap.h             |   16 ++++++++++++----
 ipc/shm.c                           |    7 ++-----
 mm/hugetlb.c                        |    3 +--
 mm/madvise.c                        |    8 ++++----
 mm/memory.c                         |   10 +++-------
 mm/mempolicy.c                      |    6 ++----
 mm/mlock.c                          |    2 +-
 mm/mprotect.c                       |    2 +-
 mm/mremap.c                         |   14 +++++---------
 mm/shmem.c                          |    5 ++---
 virt/kvm/kvm_main.c                 |    3 +--
 14 files changed, 38 insertions(+), 48 deletions(-)

diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 2a5907b..f50df8a 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -138,7 +138,7 @@ make_coherent(struct address_space *mapping, struct vm_area_struct *vma,
 	pgoff_t pgoff;
 	int aliases = 0;
 
-	pgoff = vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT);
+	pgoff = __linear_page_index(vma, addr);
 
 	/*
 	 * If we have any shared mappings that are in the same mm
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index 8cc18ab..a4a893b 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -310,7 +310,7 @@ static long kvmppc_get_guest_page(struct kvm *kvm, unsigned long gfn,
 		    !(vma->vm_flags & VM_PFNMAP))
 			goto up_err;
 		is_io = hpte_cache_bits(pgprot_val(vma->vm_page_prot));
-		pfn = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
+		pfn = __linear_page_index(vma, start);
 		/* check alignment of pfn vs. requested page size */
 		if (psize > PAGE_SIZE && (pfn & ((psize >> PAGE_SHIFT) - 1)))
 			goto up_err;
@@ -658,8 +658,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
 		vma = find_vma(current->mm, hva);
 		if (vma && vma->vm_start <= hva && hva + psize <= vma->vm_end &&
 		    (vma->vm_flags & VM_PFNMAP)) {
-			pfn = vma->vm_pgoff +
-				((hva - vma->vm_start) >> PAGE_SHIFT);
+			pfn = __linear_page_index(vma, hva);
 			pte_size = psize;
 			is_io = hpte_cache_bits(pgprot_val(vma->vm_page_prot));
 			write_ok = vma->vm_flags & VM_WRITE;
diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
index ae1aa71..5dfcd5b 100644
--- a/arch/x86/mm/hugetlbpage.c
+++ b/arch/x86/mm/hugetlbpage.c
@@ -69,8 +69,7 @@ huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud)
 {
 	struct vm_area_struct *vma = find_vma(mm, addr);
 	struct address_space *mapping = vma->vm_file->f_mapping;
-	pgoff_t idx = ((addr - vma->vm_start) >> PAGE_SHIFT) +
-			vma->vm_pgoff;
+	pgoff_t idx = __linear_page_index(vma, addr);
 	struct vm_area_struct *svma;
 	unsigned long saddr;
 	pte_t *spte = NULL;
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 0e38e13..03e442a 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -310,15 +310,23 @@ static inline loff_t page_file_offset(struct page *page)
 extern pgoff_t linear_hugepage_index(struct vm_area_struct *vma,
 				     unsigned long address);
 
-static inline pgoff_t linear_page_index(struct vm_area_struct *vma,
+/* The offset for an address within a non-hugetlb vma, in PAGE_SIZE unit. */
+static inline pgoff_t __linear_page_index(struct vm_area_struct *vma,
 					unsigned long address)
 {
 	pgoff_t pgoff;
+
+	pgoff = (address - vma->vm_start) >> PAGE_SHIFT;
+	return pgoff + vma->vm_pgoff;
+}
+
+static inline pgoff_t linear_page_index(struct vm_area_struct *vma,
+					unsigned long address)
+{
 	if (unlikely(is_vm_hugetlb_page(vma)))
 		return linear_hugepage_index(vma, address);
-	pgoff = (address - vma->vm_start) >> PAGE_SHIFT;
-	pgoff += vma->vm_pgoff;
-	return pgoff >> (PAGE_CACHE_SHIFT - PAGE_SHIFT);
+	return __linear_page_index(vma, address) >>
+				(PAGE_CACHE_SHIFT - PAGE_SHIFT);
 }
 
 extern void __lock_page(struct page *page);
diff --git a/ipc/shm.c b/ipc/shm.c
index be3ec9a..77b7d02 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -1172,9 +1172,7 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr)
 		 * otherwise it starts at this address with no hassles.
 		 */
 		if ((vma->vm_ops == &shm_vm_ops) &&
-			(vma->vm_start - addr)/PAGE_SIZE == vma->vm_pgoff) {
-
-
+			0 == __linear_page_index(vma, addr)) {
 			size = vma->vm_file->f_path.dentry->d_inode->i_size;
 			do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start);
 			/*
@@ -1201,8 +1199,7 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr)
 
 		/* finding a matching vma now does not alter retval */
 		if ((vma->vm_ops == &shm_vm_ops) &&
-			(vma->vm_start - addr)/PAGE_SIZE == vma->vm_pgoff)
-
+			0 == __linear_page_index(vma, addr))
 			do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start);
 		vma = next;
 	}
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index e14a8c7..756bf6e 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -2477,8 +2477,7 @@ static int unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma,
 	 * from page cache lookup which is in HPAGE_SIZE units.
 	 */
 	address = address & huge_page_mask(h);
-	pgoff = ((address - vma->vm_start) >> PAGE_SHIFT) +
-			vma->vm_pgoff;
+	pgoff = __linear_page_index(vma, address);
 	mapping = vma->vm_file->f_dentry->d_inode->i_mapping;
 
 	/*
diff --git a/mm/madvise.c b/mm/madvise.c
index c58c94b..51bfaf2 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -100,7 +100,7 @@ static long madvise_behavior(struct vm_area_struct * vma,
 		goto out;
 	}
 
-	pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
+	pgoff = __linear_page_index(vma, start);
 	*prev = vma_merge(mm, *prev, start, end, new_flags, vma->anon_vma,
 				vma->vm_file, pgoff, vma_policy(vma));
 	if (*prev) {
@@ -193,7 +193,7 @@ static void force_shm_swapin_readahead(struct vm_area_struct *vma,
 	swp_entry_t swap;
 
 	for (; start < end; start += PAGE_SIZE) {
-		index = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
+		index = __linear_page_index(vma, start);
 
 		page = find_get_page(mapping, index);
 		if (!radix_tree_exceptional_entry(page)) {
@@ -242,10 +242,10 @@ static long madvise_willneed(struct vm_area_struct * vma,
 	}
 
 	*prev = vma;
-	start = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
+	start = __linear_page_index(vma, start);
 	if (end > vma->vm_end)
 		end = vma->vm_end;
-	end = ((end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
+	end = __linear_page_index(vma, end);
 
 	force_page_cache_readahead(file->f_mapping, file, start, end - start);
 	return 0;
diff --git a/mm/memory.c b/mm/memory.c
index c04078b..b7e4f04 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -798,9 +798,7 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
 				return NULL;
 			goto out;
 		} else {
-			unsigned long off;
-			off = (addr - vma->vm_start) >> PAGE_SHIFT;
-			if (pfn == vma->vm_pgoff + off)
+			if (pfn == __linear_page_index(vma, addr))
 				return NULL;
 			if (!is_cow_mapping(vma->vm_flags))
 				return NULL;
@@ -3404,11 +3402,9 @@ static int do_linear_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 		unsigned long address, pte_t *page_table, pmd_t *pmd,
 		unsigned int flags, pte_t orig_pte)
 {
-	pgoff_t pgoff = (((address & PAGE_MASK)
-			- vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
-
 	pte_unmap(page_table);
-	return __do_fault(mm, vma, address, pmd, pgoff, flags, orig_pte);
+	return __do_fault(mm, vma, address, pmd,
+			__linear_page_index(vma, address), flags, orig_pte);
 }
 
 /*
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 6f7979c..870f40a 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -725,8 +725,7 @@ static int mbind_range(struct mm_struct *mm, unsigned long start,
 		if (mpol_equal(vma_policy(vma), new_pol))
 			continue;
 
-		pgoff = vma->vm_pgoff +
-			((vmstart - vma->vm_start) >> PAGE_SHIFT);
+		pgoff = __linear_page_index(vma, vmstart);
 		prev = vma_merge(mm, prev, vmstart, vmend, vma->vm_flags,
 				  vma->anon_vma, vma->vm_file, pgoff,
 				  new_pol);
@@ -2257,8 +2256,7 @@ int mpol_misplaced(struct page *page, struct vm_area_struct *vma, unsigned long
 		BUG_ON(addr >= vma->vm_end);
 		BUG_ON(addr < vma->vm_start);
 
-		pgoff = vma->vm_pgoff;
-		pgoff += (addr - vma->vm_start) >> PAGE_SHIFT;
+		pgoff = __linear_page_index(vma, addr);
 		polnid = offset_il_node(pol, vma, pgoff);
 		break;
 
diff --git a/mm/mlock.c b/mm/mlock.c
index b1647fb..fb62a2e 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -269,7 +269,7 @@ static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
 	    is_vm_hugetlb_page(vma) || vma == get_gate_vma(current->mm))
 		goto out;	/* don't set VM_LOCKED,  don't count */
 
-	pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
+	pgoff = __linear_page_index(vma, start);
 	*prev = vma_merge(mm, *prev, start, end, newflags, vma->anon_vma,
 			  vma->vm_file, pgoff, vma_policy(vma));
 	if (*prev) {
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 94722a4..c9d57f0 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -269,7 +269,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
 	/*
 	 * First try to merge with previous and/or next vma.
 	 */
-	pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
+	pgoff = __linear_page_index(vma, start);
 	*pprev = vma_merge(mm, *pprev, start, end, newflags,
 			vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma));
 	if (*pprev) {
diff --git a/mm/mremap.c b/mm/mremap.c
index 38fffd8..640c616 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -240,7 +240,7 @@ static unsigned long move_vma(struct vm_area_struct *vma,
 	if (err)
 		return err;
 
-	new_pgoff = vma->vm_pgoff + ((old_addr - vma->vm_start) >> PAGE_SHIFT);
+	new_pgoff = __linear_page_index(vma, old_addr);
 	new_vma = copy_vma(&vma, new_addr, new_len, new_pgoff,
 			   &need_rmap_locks);
 	if (!new_vma)
@@ -327,8 +327,7 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr,
 
 		if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP))
 			goto Efault;
-		pgoff = (addr - vma->vm_start) >> PAGE_SHIFT;
-		pgoff += vma->vm_pgoff;
+		pgoff = __linear_page_index(vma, addr);
 		if (pgoff + (new_len >> PAGE_SHIFT) < pgoff)
 			goto Einval;
 	}
@@ -409,9 +408,8 @@ static unsigned long mremap_to(unsigned long addr, unsigned long old_len,
 	if (vma->vm_flags & VM_MAYSHARE)
 		map_flags |= MAP_SHARED;
 
-	ret = get_unmapped_area(vma->vm_file, new_addr, new_len, vma->vm_pgoff +
-				((addr - vma->vm_start) >> PAGE_SHIFT),
-				map_flags);
+	ret = get_unmapped_area(vma->vm_file, new_addr, new_len,
+				__linear_page_index(vma, addr), map_flags);
 	if (ret & ~PAGE_MASK)
 		goto out1;
 
@@ -538,9 +536,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
 			map_flags |= MAP_SHARED;
 
 		new_addr = get_unmapped_area(vma->vm_file, 0, new_len,
-					vma->vm_pgoff +
-					((addr - vma->vm_start) >> PAGE_SHIFT),
-					map_flags);
+				__linear_page_index(vma, addr), map_flags);
 		if (new_addr & ~PAGE_MASK) {
 			ret = new_addr;
 			goto out;
diff --git a/mm/shmem.c b/mm/shmem.c
index 3049cfc..50e1b38 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1322,10 +1322,9 @@ static struct mempolicy *shmem_get_policy(struct vm_area_struct *vma,
 					  unsigned long addr)
 {
 	struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
-	pgoff_t index;
 
-	index = ((addr - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
-	return mpol_shared_policy_lookup(&SHMEM_I(inode)->policy, index);
+	return mpol_shared_policy_lookup(&SHMEM_I(inode)->policy,
+			__linear_page_index(vma, addr));
 }
 #endif
 
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index c94088d..fbbfaf1 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1240,8 +1240,7 @@ static pfn_t hva_to_pfn(unsigned long addr, bool atomic, bool *async,
 	if (vma == NULL)
 		pfn = KVM_PFN_ERR_FAULT;
 	else if ((vma->vm_flags & VM_PFNMAP)) {
-		pfn = ((addr - vma->vm_start) >> PAGE_SHIFT) +
-			vma->vm_pgoff;
+		pfn = __linear_page_index(vma, addr);
 		BUG_ON(!kvm_is_mmio_pfn(pfn));
 	} else {
 		if (async && vma_is_valid(vma, write_fault))
-- 
1.7.0.4


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ