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

Commit 858259cf authored by Bodo Stroesser's avatar Bodo Stroesser Committed by Linus Torvalds
Browse files

[PATCH] uml: maintain own LDT entries



Patch imlements full LDT handling in SKAS:
 * UML holds it's own LDT table, used to deliver data on
   modify_ldt(READ)
 * UML disables the default_ldt, inherited from the host (SKAS3)
   or resets LDT entries, set by host's clib and inherited in
   SKAS0
 * A new global variable skas_needs_stub is inserted, that
   can be used to decide, whether stub-pages must be supported
   or not.
 * Uses the syscall-stub to replace missing PTRACE_LDT (therefore,
   write_ldt_entry needs to be modified)

Signed-off-by: default avatarBodo Stroesser <bstroesser@fujitsu-siemens.com>
Signed-off-by: default avatarJeff Dike <jdike@addtoit.com>
Cc: Paolo Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent e763b793
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@

#include "linux/config.h"
#include "mm_id.h"
#include "asm/ldt.h"

struct mmu_context_skas {
	struct mm_id id;
@@ -15,6 +16,7 @@ struct mmu_context_skas {
#ifdef CONFIG_3_LEVEL_PGTABLES
        unsigned long last_pmd;
#endif
	uml_ldt_t ldt;
};

extern void switch_mm_skas(struct mm_id * mm_idp);
+2 −1
Original line number Diff line number Diff line
@@ -10,7 +10,8 @@
#include "sysdep/ptrace.h"

extern int userspace_pid[];
extern int proc_mm, ptrace_faultinfo;
extern int proc_mm, ptrace_faultinfo, ptrace_ldt;
extern int skas_needs_stub;

extern void switch_threads(void *me, void *next);
extern void thread_wait(void *sw, void *fb);
+1 −1
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@ unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
	*task_size_out = CONFIG_HOST_TASK_SIZE;
#else
	*host_size_out = top;
	if (proc_mm && ptrace_faultinfo)
	if (!skas_needs_stub)
		*task_size_out = top;
	else *task_size_out = CONFIG_STUB_START & PGDIR_MASK;
#endif
+27 −17
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include "asm/mmu.h"
#include "asm/pgalloc.h"
#include "asm/pgtable.h"
#include "asm/ldt.h"
#include "os.h"
#include "skas.h"

@@ -74,13 +75,12 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,

int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
{
	struct mm_struct *cur_mm = current->mm;
	struct mm_id *cur_mm_id = &cur_mm->context.skas.id;
	struct mm_id *mm_id = &mm->context.skas.id;
 	struct mmu_context_skas *from_mm = NULL;
	struct mmu_context_skas *to_mm = &mm->context.skas;
	unsigned long stack = 0;
	int from, ret = -ENOMEM;
	int from_fd, ret = -ENOMEM;

	if(!proc_mm || !ptrace_faultinfo){
	if(skas_needs_stub){
		stack = get_zeroed_page(GFP_KERNEL);
		if(stack == 0)
			goto out;
@@ -102,33 +102,43 @@ int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)

		mm->nr_ptes--;
	}
	mm_id->stack = stack;

	to_mm->id.stack = stack;
	if(current->mm != NULL && current->mm != &init_mm)
		from_mm = &current->mm->context.skas;

	if(proc_mm){
		if((cur_mm != NULL) && (cur_mm != &init_mm))
			from = cur_mm_id->u.mm_fd;
		else from = -1;
		if(from_mm)
			from_fd = from_mm->id.u.mm_fd;
		else from_fd = -1;

		ret = new_mm(from, stack);
		ret = new_mm(from_fd, stack);
		if(ret < 0){
			printk("init_new_context_skas - new_mm failed, "
			       "errno = %d\n", ret);
			goto out_free;
		}
		mm_id->u.mm_fd = ret;
		to_mm->id.u.mm_fd = ret;
	}
	else {
		if((cur_mm != NULL) && (cur_mm != &init_mm))
			mm_id->u.pid = copy_context_skas0(stack,
							  cur_mm_id->u.pid);
		else mm_id->u.pid = start_userspace(stack);
		if(from_mm)
			to_mm->id.u.pid = copy_context_skas0(stack,
							     from_mm->id.u.pid);
		else to_mm->id.u.pid = start_userspace(stack);
	}

	ret = init_new_ldt(to_mm, from_mm);
	if(ret < 0){
		printk("init_new_context_skas - init_ldt"
		       " failed, errno = %d\n", ret);
		goto out_free;
	}

	return 0;

 out_free:
	if(mm_id->stack != 0)
		free_page(mm_id->stack);
	if(to_mm->id.stack != 0)
		free_page(to_mm->id.stack);
 out:
	return ret;
}
+3 −3
Original line number Diff line number Diff line
@@ -381,9 +381,9 @@ int copy_context_skas0(unsigned long new_stack, int pid)
}

/*
 * This is used only, if proc_mm is available, while PTRACE_FAULTINFO
 * isn't. Opening /proc/mm creates a new mm_context, which lacks the stub-pages
 * Thus, we map them using /proc/mm-fd
 * This is used only, if stub pages are needed, while proc_mm is
 * availabl. Opening /proc/mm creates a new mm_context, which lacks
 * the stub-pages. Thus, we map them using /proc/mm-fd
 */
void map_stub_pages(int fd, unsigned long code,
		    unsigned long data, unsigned long stack)
Loading