From patchwork Mon May 4 09:54:32 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Weiner X-Patchwork-Id: 21688 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n449uPVI018384 for ; Mon, 4 May 2009 09:56:27 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752863AbZEDJ4V (ORCPT ); Mon, 4 May 2009 05:56:21 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754348AbZEDJ4V (ORCPT ); Mon, 4 May 2009 05:56:21 -0400 Received: from cmpxchg.org ([85.214.51.133]:49972 "EHLO cmpxchg.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753554AbZEDJ4R (ORCPT ); Mon, 4 May 2009 05:56:17 -0400 From: Johannes Weiner To: Andrew Morton Cc: Magnus Damm , linux-media@vger.kernel.org, Hans Verkuil , Paul Mundt , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [patch 1/3] mm: introduce follow_pte() Date: Mon, 4 May 2009 11:54:32 +0200 Message-Id: <1241430874-12667-1-git-send-email-hannes@cmpxchg.org> X-Mailer: git-send-email 1.6.2.1.135.gde769 In-Reply-To: <20090501181449.GA8912@cmpxchg.org> References: <20090501181449.GA8912@cmpxchg.org> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org A generic readonly page table lookup helper to map an address space and an address from it to a pte. Signed-off-by: Johannes Weiner Acked-by: Magnus Damm --- mm/memory.c | 37 +++++++++++++++++++++++++++++++++++++ 1 files changed, 37 insertions(+), 0 deletions(-) diff --git a/mm/memory.c b/mm/memory.c index cf6873e..a621319 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -3009,6 +3009,43 @@ int in_gate_area_no_task(unsigned long addr) #endif /* __HAVE_ARCH_GATE_AREA */ +static int follow_pte(struct mm_struct *mm, unsigned long address, + pte_t **ptepp, spinlock_t **ptlp) +{ + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *ptep; + + pgd = pgd_offset(mm, address); + if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) + goto out; + + pud = pud_offset(pgd, address); + if (pud_none(*pud) || unlikely(pud_bad(*pud))) + goto out; + + pmd = pmd_offset(pud, address); + if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) + goto out; + + /* We cannot handle huge page PFN maps. Luckily they don't exist. */ + if (pmd_huge(*pmd)) + goto out; + + ptep = pte_offset_map_lock(mm, pmd, address, ptlp); + if (!ptep) + goto out; + if (!pte_present(*ptep)) + goto unlock; + *ptepp = ptep; + return 0; +unlock: + pte_unmap_unlock(ptep, *ptlp); +out: + return -EINVAL; +} + #ifdef CONFIG_HAVE_IOREMAP_PROT int follow_phys(struct vm_area_struct *vma, unsigned long address, unsigned int flags,