diff options
-rw-r--r-- | arch/um/kernel/skas/uaccess.c | 56 | ||||
-rw-r--r-- | include/asm-um/pgtable.h | 3 |
2 files changed, 26 insertions, 33 deletions
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c index d145565b5f4b..05b41dbc1dd9 100644 --- a/arch/um/kernel/skas/uaccess.c +++ b/arch/um/kernel/skas/uaccess.c | |||
@@ -13,70 +13,60 @@ | |||
13 | #include "kern_util.h" | 13 | #include "kern_util.h" |
14 | #include "os.h" | 14 | #include "os.h" |
15 | 15 | ||
16 | static void *um_virt_to_phys(struct task_struct *task, unsigned long addr, | 16 | pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr) |
17 | pte_t *pte_out) | ||
18 | { | 17 | { |
19 | pgd_t *pgd; | 18 | pgd_t *pgd; |
20 | pud_t *pud; | 19 | pud_t *pud; |
21 | pmd_t *pmd; | 20 | pmd_t *pmd; |
22 | pte_t *pte; | ||
23 | pte_t ptent; | ||
24 | 21 | ||
25 | if (task->mm == NULL) | 22 | if (mm == NULL) |
26 | return ERR_PTR(-EINVAL); | 23 | return NULL; |
27 | pgd = pgd_offset(task->mm, addr); | 24 | |
25 | pgd = pgd_offset(mm, addr); | ||
28 | if (!pgd_present(*pgd)) | 26 | if (!pgd_present(*pgd)) |
29 | return ERR_PTR(-EINVAL); | 27 | return NULL; |
30 | 28 | ||
31 | pud = pud_offset(pgd, addr); | 29 | pud = pud_offset(pgd, addr); |
32 | if (!pud_present(*pud)) | 30 | if (!pud_present(*pud)) |
33 | return ERR_PTR(-EINVAL); | 31 | return NULL; |
34 | 32 | ||
35 | pmd = pmd_offset(pud, addr); | 33 | pmd = pmd_offset(pud, addr); |
36 | if (!pmd_present(*pmd)) | 34 | if (!pmd_present(*pmd)) |
37 | return ERR_PTR(-EINVAL); | 35 | return NULL; |
38 | |||
39 | pte = pte_offset_kernel(pmd, addr); | ||
40 | ptent = *pte; | ||
41 | if (!pte_present(ptent)) | ||
42 | return ERR_PTR(-EINVAL); | ||
43 | 36 | ||
44 | if (pte_out != NULL) | 37 | return pte_offset_kernel(pmd, addr); |
45 | *pte_out = ptent; | ||
46 | return (void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK); | ||
47 | } | 38 | } |
48 | 39 | ||
49 | static unsigned long maybe_map(unsigned long virt, int is_write) | 40 | static pte_t *maybe_map(unsigned long virt, int is_write) |
50 | { | 41 | { |
51 | pte_t pte; | 42 | pte_t *pte = virt_to_pte(current->mm, virt); |
52 | int err; | 43 | int err, dummy_code; |
53 | 44 | ||
54 | void *phys = um_virt_to_phys(current, virt, &pte); | 45 | if ((pte == NULL) || !pte_present(*pte) || |
55 | int dummy_code; | 46 | (is_write && !pte_write(*pte))) { |
56 | |||
57 | if (IS_ERR(phys) || (is_write && !pte_write(pte))) { | ||
58 | err = handle_page_fault(virt, 0, is_write, 1, &dummy_code); | 47 | err = handle_page_fault(virt, 0, is_write, 1, &dummy_code); |
59 | if (err) | 48 | if (err) |
60 | return -1UL; | 49 | return NULL; |
61 | phys = um_virt_to_phys(current, virt, NULL); | 50 | pte = virt_to_pte(current->mm, virt); |
62 | } | 51 | } |
63 | if (IS_ERR(phys)) | 52 | if (!pte_present(*pte)) |
64 | phys = (void *) -1; | 53 | pte = NULL; |
65 | 54 | ||
66 | return (unsigned long) phys; | 55 | return pte; |
67 | } | 56 | } |
68 | 57 | ||
69 | static int do_op_one_page(unsigned long addr, int len, int is_write, | 58 | static int do_op_one_page(unsigned long addr, int len, int is_write, |
70 | int (*op)(unsigned long addr, int len, void *arg), void *arg) | 59 | int (*op)(unsigned long addr, int len, void *arg), void *arg) |
71 | { | 60 | { |
72 | struct page *page; | 61 | struct page *page; |
62 | pte_t *pte; | ||
73 | int n; | 63 | int n; |
74 | 64 | ||
75 | addr = maybe_map(addr, is_write); | 65 | pte = maybe_map(addr, is_write); |
76 | if (addr == -1UL) | 66 | if (pte == NULL) |
77 | return -1; | 67 | return -1; |
78 | 68 | ||
79 | page = phys_to_page(addr); | 69 | page = pte_page(*pte); |
80 | addr = (unsigned long) kmap_atomic(page, KM_UML_USERCOPY) + | 70 | addr = (unsigned long) kmap_atomic(page, KM_UML_USERCOPY) + |
81 | (addr & ~PAGE_MASK); | 71 | (addr & ~PAGE_MASK); |
82 | 72 | ||
diff --git a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h index 62ab94a4f1b6..fb477774a2e9 100644 --- a/include/asm-um/pgtable.h +++ b/include/asm-um/pgtable.h | |||
@@ -323,6 +323,9 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | |||
323 | #define pte_unmap(pte) do { } while (0) | 323 | #define pte_unmap(pte) do { } while (0) |
324 | #define pte_unmap_nested(pte) do { } while (0) | 324 | #define pte_unmap_nested(pte) do { } while (0) |
325 | 325 | ||
326 | struct mm_struct; | ||
327 | extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr); | ||
328 | |||
326 | #define update_mmu_cache(vma,address,pte) do ; while (0) | 329 | #define update_mmu_cache(vma,address,pte) do ; while (0) |
327 | 330 | ||
328 | /* Encode and de-code a swap entry */ | 331 | /* Encode and de-code a swap entry */ |