[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: Bodo Stroesser <bstroesser@fujitsu-siemens.com> Signed-off-by: Jeff Dike <jdike@addtoit.com> Cc: Paolo Giarrusso <blaisorblade@yahoo.it> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:

committed by
Linus Torvalds

parent
e763b793f7
commit
858259cf7d
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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 = ¤t->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;
|
||||
}
|
||||
|
@@ -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)
|
||||
|
@@ -145,7 +145,7 @@ int new_mm(int from, unsigned long stack)
|
||||
"err = %d\n", -n);
|
||||
}
|
||||
|
||||
if(!ptrace_faultinfo)
|
||||
if(skas_needs_stub)
|
||||
map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack);
|
||||
|
||||
return(fd);
|
||||
|
Reference in New Issue
Block a user