aboutsummaryrefslogtreecommitdiff
path: root/arch/um/kernel/skas/uaccess.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/kernel/skas/uaccess.c')
-rw-r--r--arch/um/kernel/skas/uaccess.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index 1d8b119f2d0..302425b03d4 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -12,8 +12,38 @@
#include "kern_util.h"
#include "os.h"
-extern void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
- pte_t *pte_out);
+static void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
+ pte_t *pte_out)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+ pte_t ptent;
+
+ if (task->mm == NULL)
+ return ERR_PTR(-EINVAL);
+ pgd = pgd_offset(task->mm, addr);
+ if (!pgd_present(*pgd))
+ return ERR_PTR(-EINVAL);
+
+ pud = pud_offset(pgd, addr);
+ if (!pud_present(*pud))
+ return ERR_PTR(-EINVAL);
+
+ pmd = pmd_offset(pud, addr);
+ if (!pmd_present(*pmd))
+ return ERR_PTR(-EINVAL);
+
+ pte = pte_offset_kernel(pmd, addr);
+ ptent = *pte;
+ if (!pte_present(ptent))
+ return ERR_PTR(-EINVAL);
+
+ if (pte_out != NULL)
+ *pte_out = ptent;
+ return (void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK);
+}
static unsigned long maybe_map(unsigned long virt, int is_write)
{