1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
4 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
8 #include <linux/sched/signal.h>
9 #include <linux/slab.h>
11 #include <asm/pgalloc.h>
12 #include <asm/pgtable.h>
13 #include <asm/sections.h>
14 #include <as-layout.h>
18 static int init_stub_pte(struct mm_struct
*mm
, unsigned long proc
,
27 pgd
= pgd_offset(mm
, proc
);
29 p4d
= p4d_alloc(mm
, pgd
, proc
);
33 pud
= pud_alloc(mm
, p4d
, proc
);
37 pmd
= pmd_alloc(mm
, pud
, proc
);
41 pte
= pte_alloc_map(mm
, pmd
, proc
);
45 *pte
= mk_pte(virt_to_page(kernel
), __pgprot(_PAGE_PRESENT
));
46 *pte
= pte_mkread(*pte
);
59 int init_new_context(struct task_struct
*task
, struct mm_struct
*mm
)
61 struct mm_context
*from_mm
= NULL
;
62 struct mm_context
*to_mm
= &mm
->context
;
63 unsigned long stack
= 0;
66 stack
= get_zeroed_page(GFP_KERNEL
);
70 to_mm
->id
.stack
= stack
;
71 if (current
->mm
!= NULL
&& current
->mm
!= &init_mm
)
72 from_mm
= ¤t
->mm
->context
;
74 block_signals_trace();
76 to_mm
->id
.u
.pid
= copy_context_skas0(stack
,
78 else to_mm
->id
.u
.pid
= start_userspace(stack
);
79 unblock_signals_trace();
81 if (to_mm
->id
.u
.pid
< 0) {
82 ret
= to_mm
->id
.u
.pid
;
86 ret
= init_new_ldt(to_mm
, from_mm
);
88 printk(KERN_ERR
"init_new_context_skas - init_ldt"
89 " failed, errno = %d\n", ret
);
96 if (to_mm
->id
.stack
!= 0)
97 free_page(to_mm
->id
.stack
);
102 void uml_setup_stubs(struct mm_struct
*mm
)
106 ret
= init_stub_pte(mm
, STUB_CODE
,
107 (unsigned long) __syscall_stub_start
);
111 ret
= init_stub_pte(mm
, STUB_DATA
, mm
->context
.id
.stack
);
115 mm
->context
.stub_pages
[0] = virt_to_page(__syscall_stub_start
);
116 mm
->context
.stub_pages
[1] = virt_to_page(mm
->context
.id
.stack
);
118 /* dup_mmap already holds mmap_sem */
119 err
= install_special_mapping(mm
, STUB_START
, STUB_END
- STUB_START
,
120 VM_READ
| VM_MAYREAD
| VM_EXEC
|
121 VM_MAYEXEC
| VM_DONTCOPY
| VM_PFNMAP
,
122 mm
->context
.stub_pages
);
124 printk(KERN_ERR
"install_special_mapping returned %d\n", err
);
130 force_sigsegv(SIGSEGV
);
133 void arch_exit_mmap(struct mm_struct
*mm
)
137 pte
= virt_to_pte(mm
, STUB_CODE
);
139 pte_clear(mm
, STUB_CODE
, pte
);
141 pte
= virt_to_pte(mm
, STUB_DATA
);
145 pte_clear(mm
, STUB_DATA
, pte
);
148 void destroy_context(struct mm_struct
*mm
)
150 struct mm_context
*mmu
= &mm
->context
;
153 * If init_new_context wasn't called, this will be
154 * zero, resulting in a kill(0), which will result in the
155 * whole UML suddenly dying. Also, cover negative and
156 * 1 cases, since they shouldn't happen either.
158 if (mmu
->id
.u
.pid
< 2) {
159 printk(KERN_ERR
"corrupt mm_context - pid = %d\n",
163 os_kill_ptraced_process(mmu
->id
.u
.pid
, 1);
165 free_page(mmu
->id
.stack
);