Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e4aa402e authored by Martin Schwidefsky's avatar Martin Schwidefsky
Browse files

[S390] Introduce follow_table in uaccess_pt.c



Define and use follow_table inline in uaccess_pt.c to simplify
the code.

Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 6f3fa3f0
Loading
Loading
Loading
Loading
+22 −63
Original line number Diff line number Diff line
@@ -15,6 +15,22 @@
#include <asm/futex.h>
#include "uaccess.h"

static inline pte_t *follow_table(struct mm_struct *mm, unsigned long addr)
{
	pgd_t *pgd;
	pmd_t *pmd;

	pgd = pgd_offset(mm, addr);
	if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
		return NULL;

	pmd = pmd_offset(pgd, addr);
	if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
		return NULL;

	return pte_offset_map(pmd, addr);
}

static int __handle_fault(struct mm_struct *mm, unsigned long address,
			  int write_access)
{
@@ -85,8 +101,6 @@ static size_t __user_copy_pt(unsigned long uaddr, void *kptr,
{
	struct mm_struct *mm = current->mm;
	unsigned long offset, pfn, done, size;
	pgd_t *pgd;
	pmd_t *pmd;
	pte_t *pte;
	void *from, *to;

@@ -94,15 +108,7 @@ static size_t __user_copy_pt(unsigned long uaddr, void *kptr,
retry:
	spin_lock(&mm->page_table_lock);
	do {
		pgd = pgd_offset(mm, uaddr);
		if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
			goto fault;

		pmd = pmd_offset(pgd, uaddr);
		if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
			goto fault;

		pte = pte_offset_map(pmd, uaddr);
		pte = follow_table(mm, uaddr);
		if (!pte || !pte_present(*pte) ||
		    (write_user && !pte_write(*pte)))
			goto fault;
@@ -142,22 +148,12 @@ static unsigned long __dat_user_addr(unsigned long uaddr)
{
	struct mm_struct *mm = current->mm;
	unsigned long pfn, ret;
	pgd_t *pgd;
	pmd_t *pmd;
	pte_t *pte;
	int rc;

	ret = 0;
retry:
	pgd = pgd_offset(mm, uaddr);
	if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
		goto fault;

	pmd = pmd_offset(pgd, uaddr);
	if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
		goto fault;

	pte = pte_offset_map(pmd, uaddr);
	pte = follow_table(mm, uaddr);
	if (!pte || !pte_present(*pte))
		goto fault;

@@ -229,8 +225,6 @@ static size_t strnlen_user_pt(size_t count, const char __user *src)
	unsigned long uaddr = (unsigned long) src;
	struct mm_struct *mm = current->mm;
	unsigned long offset, pfn, done, len;
	pgd_t *pgd;
	pmd_t *pmd;
	pte_t *pte;
	size_t len_str;

@@ -240,15 +234,7 @@ static size_t strnlen_user_pt(size_t count, const char __user *src)
retry:
	spin_lock(&mm->page_table_lock);
	do {
		pgd = pgd_offset(mm, uaddr);
		if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
			goto fault;

		pmd = pmd_offset(pgd, uaddr);
		if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
			goto fault;

		pte = pte_offset_map(pmd, uaddr);
		pte = follow_table(mm, uaddr);
		if (!pte || !pte_present(*pte))
			goto fault;

@@ -308,8 +294,6 @@ static size_t copy_in_user_pt(size_t n, void __user *to,
		      uaddr, done, size;
	unsigned long uaddr_from = (unsigned long) from;
	unsigned long uaddr_to = (unsigned long) to;
	pgd_t *pgd_from, *pgd_to;
	pmd_t *pmd_from, *pmd_to;
	pte_t *pte_from, *pte_to;
	int write_user;

@@ -317,39 +301,14 @@ static size_t copy_in_user_pt(size_t n, void __user *to,
retry:
	spin_lock(&mm->page_table_lock);
	do {
		pgd_from = pgd_offset(mm, uaddr_from);
		if (pgd_none(*pgd_from) || unlikely(pgd_bad(*pgd_from))) {
			uaddr = uaddr_from;
			write_user = 0;
			goto fault;
		}
		pgd_to = pgd_offset(mm, uaddr_to);
		if (pgd_none(*pgd_to) || unlikely(pgd_bad(*pgd_to))) {
			uaddr = uaddr_to;
			write_user = 1;
			goto fault;
		}

		pmd_from = pmd_offset(pgd_from, uaddr_from);
		if (pmd_none(*pmd_from) || unlikely(pmd_bad(*pmd_from))) {
			uaddr = uaddr_from;
			write_user = 0;
			goto fault;
		}
		pmd_to = pmd_offset(pgd_to, uaddr_to);
		if (pmd_none(*pmd_to) || unlikely(pmd_bad(*pmd_to))) {
			uaddr = uaddr_to;
			write_user = 1;
			goto fault;
		}

		pte_from = pte_offset_map(pmd_from, uaddr_from);
		pte_from = follow_table(mm, uaddr_from);
		if (!pte_from || !pte_present(*pte_from)) {
			uaddr = uaddr_from;
			write_user = 0;
			goto fault;
		}
		pte_to = pte_offset_map(pmd_to, uaddr_to);

		pte_to = follow_table(mm, uaddr_to);
		if (!pte_to || !pte_present(*pte_to) || !pte_write(*pte_to)) {
			uaddr = uaddr_to;
			write_user = 1;