summaryrefslogtreecommitdiffstats
path: root/arch/um/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/kernel')
-rw-r--r--arch/um/kernel/skas/mmu.c5
-rw-r--r--arch/um/kernel/skas/process.c20
-rw-r--r--arch/um/kernel/trap.c12
3 files changed, 33 insertions, 4 deletions
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index b56fe8b67a8..6da9ab4f5a1 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -114,6 +114,11 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
to_mm->id.u.pid = copy_context_skas0(stack,
from_mm->id.u.pid);
else to_mm->id.u.pid = start_userspace(stack);
+
+ if (to_mm->id.u.pid < 0) {
+ ret = to_mm->id.u.pid;
+ goto out_free;
+ }
}
ret = init_new_ldt(to_mm, from_mm);
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index fce389c2342..2e9852c0d48 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -6,19 +6,25 @@
#include "linux/init.h"
#include "linux/sched.h"
#include "as-layout.h"
+#include "kern.h"
#include "os.h"
#include "skas.h"
int new_mm(unsigned long stack)
{
- int fd;
+ int fd, err;
fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0);
if (fd < 0)
return fd;
- if (skas_needs_stub)
- map_stub_pages(fd, STUB_CODE, STUB_DATA, stack);
+ if (skas_needs_stub) {
+ err = map_stub_pages(fd, STUB_CODE, STUB_DATA, stack);
+ if (err) {
+ os_close_file(fd);
+ return err;
+ }
+ }
return fd;
}
@@ -49,8 +55,14 @@ int __init start_uml(void)
{
stack_protections((unsigned long) &cpu0_irqstack);
set_sigstack(cpu0_irqstack, THREAD_SIZE);
- if (proc_mm)
+ if (proc_mm) {
userspace_pid[0] = start_userspace(0);
+ if (userspace_pid[0] < 0) {
+ printf("start_uml - start_userspace returned %d\n",
+ userspace_pid[0]);
+ exit(1);
+ }
+ }
init_new_thread_signals();
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index 8fd1a797c3e..44e49041949 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -129,6 +129,18 @@ static void bad_segv(struct faultinfo fi, unsigned long ip)
force_sig_info(SIGSEGV, &si, current);
}
+void fatal_sigsegv(void)
+{
+ force_sigsegv(SIGSEGV, current);
+ do_signal();
+ /*
+ * This is to tell gcc that we're not returning - do_signal
+ * can, in general, return, but in this case, it's not, since
+ * we just got a fatal SIGSEGV queued.
+ */
+ os_dump_core();
+}
+
void segv_handler(int sig, struct uml_pt_regs *regs)
{
struct faultinfo * fi = UPT_FAULTINFO(regs);