Commit be82f706 authored by Jeff Dike's avatar Jeff Dike

Merge

parents 55014c58 1a4d78ad
...@@ -164,6 +164,14 @@ config KERNEL_HALF_GIGS ...@@ -164,6 +164,14 @@ config KERNEL_HALF_GIGS
config HIGHMEM config HIGHMEM
bool "Highmem support" bool "Highmem support"
config KERNEL_STACK_ORDER
int "Kernel stack size order"
default 2
help
This option determines the size of UML kernel stacks. They will
be 1 << order pages. The default is OK unless you're running Valgrind
on UML, in which case, set this to 3.
endmenu endmenu
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* Licensed under the GPL * Licensed under the GPL
*/ */
#include "linux/config.h"
#include "linux/mm.h" #include "linux/mm.h"
#include "linux/sched.h" #include "linux/sched.h"
#include "linux/init_task.h" #include "linux/init_task.h"
...@@ -37,17 +38,16 @@ union thread_union init_thread_union ...@@ -37,17 +38,16 @@ union thread_union init_thread_union
__attribute__((__section__(".data.init_task"))) = __attribute__((__section__(".data.init_task"))) =
{ INIT_THREAD_INFO(init_task) }; { INIT_THREAD_INFO(init_task) };
struct task_struct *alloc_task_struct(void){ struct task_struct *alloc_task_struct(void)
struct task_struct *task; {
return((struct task_struct *)
task = (struct task_struct *) __get_free_pages(GFP_KERNEL, 2); __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
if(task == NULL) return(NULL);
return(task);
} }
void unprotect_stack(unsigned long stack) void unprotect_stack(unsigned long stack)
{ {
protect_memory(stack, 4 * PAGE_SIZE, 1, 1, 0, 1); protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE,
1, 1, 0, 1);
} }
void free_task_struct(struct task_struct *task) void free_task_struct(struct task_struct *task)
...@@ -55,7 +55,7 @@ void free_task_struct(struct task_struct *task) ...@@ -55,7 +55,7 @@ void free_task_struct(struct task_struct *task)
/* free_pages decrements the page counter and only actually frees /* free_pages decrements the page counter and only actually frees
* the pages if they are now not accessed by anything. * the pages if they are now not accessed by anything.
*/ */
free_pages((unsigned long) task, 2); free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
} }
/* /*
......
...@@ -38,16 +38,17 @@ ...@@ -38,16 +38,17 @@
#include "choose-mode.h" #include "choose-mode.h"
#include "mode.h" #include "mode.h"
#ifdef CONFIG_MODE_SKAS #ifdef CONFIG_MODE_SKAS
#include "skas_ptrace.h"
#include "skas.h" #include "skas.h"
#include "skas_ptrace.h"
#endif #endif
void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)) void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
{ {
int flags = 0; int flags = 0, pages;
if(sig_stack != NULL){ if(sig_stack != NULL){
set_sigstack(sig_stack, 2 * page_size()); pages = (1 << CONFIG_KERNEL_STACK_ORDER) - 2;
set_sigstack(sig_stack, pages * page_size());
flags = SA_ONSTACK; flags = SA_ONSTACK;
} }
if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1); if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1);
......
...@@ -306,7 +306,11 @@ EXPORT_SYMBOL(not_implemented); ...@@ -306,7 +306,11 @@ EXPORT_SYMBOL(not_implemented);
int user_context(unsigned long sp) int user_context(unsigned long sp)
{ {
return((sp & (PAGE_MASK << 1)) != current->thread.kernel_stack); unsigned long stack;
stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER);
stack += 2 * PAGE_SIZE;
return(stack != current->thread.kernel_stack);
} }
extern void remove_umid_dir(void); extern void remove_umid_dir(void);
......
...@@ -367,11 +367,14 @@ __uml_setup("jail", jail_setup, ...@@ -367,11 +367,14 @@ __uml_setup("jail", jail_setup,
static void mprotect_kernel_mem(int w) static void mprotect_kernel_mem(int w)
{ {
unsigned long start, end; unsigned long start, end;
int pages;
if(!jail || (current == &init_task)) return; if(!jail || (current == &init_task)) return;
pages = (1 << CONFIG_KERNEL_STACK_ORDER);
start = (unsigned long) current->thread_info + PAGE_SIZE; start = (unsigned long) current->thread_info + PAGE_SIZE;
end = (unsigned long) current->thread_info + PAGE_SIZE * 4; end = (unsigned long) current + PAGE_SIZE * pages;
protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1); protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1);
protect_memory(end, high_physmem - end, 1, w, 1, 1); protect_memory(end, high_physmem - end, 1, w, 1, 1);
...@@ -470,8 +473,10 @@ void clear_singlestep(void *t) ...@@ -470,8 +473,10 @@ void clear_singlestep(void *t)
int start_uml_tt(void) int start_uml_tt(void)
{ {
void *sp; void *sp;
int pages;
sp = (void *) init_task.thread.kernel_stack + 2 * PAGE_SIZE - pages = (1 << CONFIG_KERNEL_STACK_ORDER) - 2;
sp = (void *) init_task.thread.kernel_stack + pages * PAGE_SIZE -
sizeof(unsigned long); sizeof(unsigned long);
return(tracer(start_kernel_proc, sp)); return(tracer(start_kernel_proc, sp));
} }
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "mem_user.h" #include "mem_user.h"
#include "init.h" #include "init.h"
#include "helper.h" #include "helper.h"
#include "uml-config.h"
#define COMMAND_LINE_SIZE _POSIX_ARG_MAX #define COMMAND_LINE_SIZE _POSIX_ARG_MAX
...@@ -88,12 +89,15 @@ void task_protections(unsigned long address) ...@@ -88,12 +89,15 @@ void task_protections(unsigned long address)
{ {
unsigned long guard = address + page_size(); unsigned long guard = address + page_size();
unsigned long stack = guard + page_size(); unsigned long stack = guard + page_size();
int prot = 0; int prot = 0, pages;
#ifdef notdef
if(mprotect((void *) stack, page_size(), prot) < 0) if(mprotect((void *) stack, page_size(), prot) < 0)
panic("protecting guard page failed, errno = %d", errno); panic("protecting guard page failed, errno = %d", errno);
#endif
pages = (1 << CONFIG_KERNEL_STACK_ORDER) - 2;
prot = PROT_READ | PROT_WRITE | PROT_EXEC; prot = PROT_READ | PROT_WRITE | PROT_EXEC;
if(mprotect((void *) stack, 2 * page_size(), prot) < 0) if(mprotect((void *) stack, pages * page_size(), prot) < 0)
panic("protecting stack failed, errno = %d", errno); panic("protecting stack failed, errno = %d", errno);
} }
......
...@@ -13,7 +13,8 @@ struct thread_info; ...@@ -13,7 +13,8 @@ struct thread_info;
#include "linux/config.h" #include "linux/config.h"
#include "asm/page.h" #include "asm/page.h"
#define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & (PAGE_MASK << 2)) #define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & \
(PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
#define current ({ int dummy; \ #define current ({ int dummy; \
((struct thread_info *) CURRENT_THREAD(dummy))->task; }) ((struct thread_info *) CURRENT_THREAD(dummy))->task; })
......
...@@ -80,21 +80,21 @@ struct thread_struct { ...@@ -80,21 +80,21 @@ struct thread_struct {
#define INIT_THREAD \ #define INIT_THREAD \
{ \ { \
forking: 0, \ .forking = 0, \
kernel_stack: 0, \ .kernel_stack = 0, \
nsyscalls: 0, \ .nsyscalls = 0, \
regs: EMPTY_REGS, \ .regs = EMPTY_REGS, \
cr2: 0, \ .cr2 = 0, \
err: 0, \ .err = 0, \
fault_addr: NULL, \ .fault_addr = NULL, \
prev_sched: NULL, \ .prev_sched = NULL, \
temp_stack: 0, \ .temp_stack = 0, \
exec_buf: NULL, \ .exec_buf = NULL, \
arch: INIT_ARCH_THREAD, \ .arch = INIT_ARCH_THREAD, \
request: { 0 } \ .request = { 0 } \
} }
#define INIT_THREAD_SIZE (4 * PAGE_SIZE) #define INIT_THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
typedef struct { typedef struct {
unsigned long seg; unsigned long seg;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment