* Changed the meaning of the {KERNEL,USER}_STACK_SIZE macros to not
include the guard pages. Adjusted the kernel and boot loader code accordingly -- the guard pages size is added/not removed respectively. The stack size passed to _kern_spawn_thread() is now the actually usable size, and it is no longer possible to specify a size smaller than or equal to the guard pages size. * vm_create_anonymous_area(): Precommit two pages maximum -- a stack with only one page usable size obviously doesn't need two pages. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26819 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -27,12 +27,13 @@
|
|||||||
// At least, you then know that the stack overflows in this case :)
|
// At least, you then know that the stack overflows in this case :)
|
||||||
|
|
||||||
/** Size of the kernel stack */
|
/** Size of the kernel stack */
|
||||||
#ifndef DEBUG_KERNEL_STACKS
|
#define KERNEL_STACK_SIZE (B_PAGE_SIZE * 3) // 12 kB
|
||||||
# define KERNEL_STACK_SIZE (B_PAGE_SIZE * 3) // 12 kB
|
|
||||||
|
#ifdef DEBUG_KERNEL_STACKS
|
||||||
|
# define KERNEL_STACK_GUARD_PAGES 1
|
||||||
#else
|
#else
|
||||||
# define KERNEL_STACK_SIZE (B_PAGE_SIZE * 4) // 12 kB + one guard page
|
# define KERNEL_STACK_GUARD_PAGES 0
|
||||||
#endif
|
#endif
|
||||||
#define KERNEL_STACK_GUARD_PAGES 1
|
|
||||||
|
|
||||||
/** Size of the environmental variables space for a process */
|
/** Size of the environmental variables space for a process */
|
||||||
#define ENV_SIZE (B_PAGE_SIZE * 8)
|
#define ENV_SIZE (B_PAGE_SIZE * 8)
|
||||||
|
|||||||
@@ -14,11 +14,14 @@
|
|||||||
#define THREAD_CONTINUED 0x4
|
#define THREAD_CONTINUED 0x4
|
||||||
|
|
||||||
/** Size of the stack given to teams in user space */
|
/** Size of the stack given to teams in user space */
|
||||||
#define USER_MAIN_THREAD_STACK_SIZE (16 * 1024 * 1024) // 16 MB
|
#define USER_STACK_GUARD_PAGES 4 // 16 kB
|
||||||
#define USER_STACK_SIZE (256 * 1024) // 256 kB
|
#define USER_MAIN_THREAD_STACK_SIZE (16 * 1024 * 1024 \
|
||||||
#define MIN_USER_STACK_SIZE (4 * 1024) // 4 KB
|
- USER_STACK_GUARD_PAGES * B_PAGE_SIZE) // 16 MB
|
||||||
#define MAX_USER_STACK_SIZE (16 * 1024 * 1024) // 16 MB
|
#define USER_STACK_SIZE (256 * 1024 \
|
||||||
#define USER_STACK_GUARD_PAGES 4 // 16 kB
|
- USER_STACK_GUARD_PAGES * B_PAGE_SIZE) // 256 kB
|
||||||
|
#define MIN_USER_STACK_SIZE (4 * 1024) // 4 KB
|
||||||
|
#define MAX_USER_STACK_SIZE (16 * 1024 * 1024 \
|
||||||
|
- USER_STACK_GUARD_PAGES * B_PAGE_SIZE) // 16 MB
|
||||||
|
|
||||||
|
|
||||||
struct thread_creation_attributes {
|
struct thread_creation_attributes {
|
||||||
|
|||||||
@@ -57,12 +57,12 @@
|
|||||||
* 0xdNNNNN video buffer usually there, as per v_bas_ad
|
* 0xdNNNNN video buffer usually there, as per v_bas_ad
|
||||||
* (=Logbase() but Physbase() is better)
|
* (=Logbase() but Physbase() is better)
|
||||||
*
|
*
|
||||||
* The first 32 MB (2) are identity mapped (0x0 - 0x1000000); paging
|
* The first 32 MB (2) are identity mapped (0x0 - 0x1000000); paging
|
||||||
* is turned on. The kernel is mapped at 0x80000000, all other stuff
|
* is turned on. The kernel is mapped at 0x80000000, all other stuff
|
||||||
* mapped by the loader (kernel args, modules, driver settings, ...)
|
* mapped by the loader (kernel args, modules, driver settings, ...)
|
||||||
* comes after 0x81000000 which means that there is currently only
|
* comes after 0x81000000 which means that there is currently only
|
||||||
* 1 MB reserved for the kernel itself (see kMaxKernelSize).
|
* 1 MB reserved for the kernel itself (see kMaxKernelSize).
|
||||||
*
|
*
|
||||||
* (1) no need for user stack, we are already in supervisor mode in the
|
* (1) no need for user stack, we are already in supervisor mode in the
|
||||||
* loader.
|
* loader.
|
||||||
* (2) maps the whole regular ST space; transparent translation registers
|
* (2) maps the whole regular ST space; transparent translation registers
|
||||||
@@ -143,9 +143,9 @@ extern "C" addr_t
|
|||||||
mmu_get_next_page_tables()
|
mmu_get_next_page_tables()
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
TRACE(("mmu_get_next_page_tables, sNextPageTableAddress %p, kPageTableRegionEnd %p\n",
|
TRACE(("mmu_get_next_page_tables, sNextPageTableAddress %p, kPageTableRegionEnd %p\n",
|
||||||
sNextPageTableAddress, kPageTableRegionEnd));
|
sNextPageTableAddress, kPageTableRegionEnd));
|
||||||
|
|
||||||
addr_t address = sNextPageTableAddress;
|
addr_t address = sNextPageTableAddress;
|
||||||
if (address >= kPageTableRegionEnd)
|
if (address >= kPageTableRegionEnd)
|
||||||
return (uint32 *)get_next_physical_page();
|
return (uint32 *)get_next_physical_page();
|
||||||
@@ -492,7 +492,7 @@ mmu_init_for_kernel(void)
|
|||||||
// seg 0x10 - kernel 4GB data
|
// seg 0x10 - kernel 4GB data
|
||||||
set_segment_descriptor(&virtualGDT[2], 0, 0xffffffff, DT_DATA_WRITEABLE,
|
set_segment_descriptor(&virtualGDT[2], 0, 0xffffffff, DT_DATA_WRITEABLE,
|
||||||
DPL_KERNEL);
|
DPL_KERNEL);
|
||||||
|
|
||||||
// seg 0x1b - ring 3 user 4GB code
|
// seg 0x1b - ring 3 user 4GB code
|
||||||
set_segment_descriptor(&virtualGDT[3], 0, 0xffffffff, DT_CODE_READABLE,
|
set_segment_descriptor(&virtualGDT[3], 0, 0xffffffff, DT_CODE_READABLE,
|
||||||
DPL_USER);
|
DPL_USER);
|
||||||
@@ -613,10 +613,12 @@ mmu_init(void)
|
|||||||
// set virtual addr for interrupt vector table
|
// set virtual addr for interrupt vector table
|
||||||
gKernelArgs.arch_args.vir_vbr = gKernelArgs.arch_args.vir_pgroot
|
gKernelArgs.arch_args.vir_vbr = gKernelArgs.arch_args.vir_pgroot
|
||||||
+ VBR_PAGE_OFFSET;
|
+ VBR_PAGE_OFFSET;
|
||||||
|
|
||||||
// map in a kernel stack
|
// map in a kernel stack
|
||||||
gKernelArgs.cpu_kstack[0].start = (addr_t)mmu_allocate(NULL, KERNEL_STACK_SIZE);
|
gKernelArgs.cpu_kstack[0].start = (addr_t)mmu_allocate(NULL,
|
||||||
gKernelArgs.cpu_kstack[0].size = KERNEL_STACK_SIZE;
|
KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE);
|
||||||
|
gKernelArgs.cpu_kstack[0].size = KERNEL_STACK_SIZE
|
||||||
|
+ KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE;
|
||||||
|
|
||||||
TRACE(("kernel stack at 0x%lx to 0x%lx\n", gKernelArgs.cpu_kstack[0].start,
|
TRACE(("kernel stack at 0x%lx to 0x%lx\n", gKernelArgs.cpu_kstack[0].start,
|
||||||
gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size));
|
gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size));
|
||||||
@@ -633,9 +635,9 @@ mmu_init(void)
|
|||||||
gKernelArgs.physical_memory_range[1].size =
|
gKernelArgs.physical_memory_range[1].size =
|
||||||
fastram_top - ATARI_FASTRAM_BASE;
|
fastram_top - ATARI_FASTRAM_BASE;
|
||||||
gKernelArgs.num_physical_memory_ranges++;
|
gKernelArgs.num_physical_memory_ranges++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// mark the video area allocated
|
// mark the video area allocated
|
||||||
addr_t video_base = *TOSVAR_memtop;
|
addr_t video_base = *TOSVAR_memtop;
|
||||||
video_base &= ~(B_PAGE_SIZE-1);
|
video_base &= ~(B_PAGE_SIZE-1);
|
||||||
|
|||||||
@@ -302,7 +302,7 @@ get_memory_map(extended_memory **_extendedMemory)
|
|||||||
dprintf("extended memory info (from 0xe820):\n");
|
dprintf("extended memory info (from 0xe820):\n");
|
||||||
for (uint32 i = 0; i < count; i++) {
|
for (uint32 i = 0; i < count; i++) {
|
||||||
dprintf(" base 0x%08Lx, len 0x%08Lx, type %lu (%s)\n",
|
dprintf(" base 0x%08Lx, len 0x%08Lx, type %lu (%s)\n",
|
||||||
block[i].base_addr, block[i].length,
|
block[i].base_addr, block[i].length,
|
||||||
block[i].type, e820_memory_type(block[i].type));
|
block[i].type, e820_memory_type(block[i].type));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -606,8 +606,9 @@ mmu_init(void)
|
|||||||
|
|
||||||
// map in a kernel stack
|
// map in a kernel stack
|
||||||
gKernelArgs.cpu_kstack[0].start = (addr_t)mmu_allocate(NULL,
|
gKernelArgs.cpu_kstack[0].start = (addr_t)mmu_allocate(NULL,
|
||||||
KERNEL_STACK_SIZE);
|
KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE);
|
||||||
gKernelArgs.cpu_kstack[0].size = KERNEL_STACK_SIZE;
|
gKernelArgs.cpu_kstack[0].size = KERNEL_STACK_SIZE
|
||||||
|
+ KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE;
|
||||||
|
|
||||||
TRACE(("kernel stack at 0x%lx to 0x%lx\n", gKernelArgs.cpu_kstack[0].start,
|
TRACE(("kernel stack at 0x%lx to 0x%lx\n", gKernelArgs.cpu_kstack[0].start,
|
||||||
gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size));
|
gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size));
|
||||||
|
|||||||
@@ -396,8 +396,10 @@ smp_init_other_cpus(void)
|
|||||||
|
|
||||||
for (uint32 i = 1; i < gKernelArgs.num_cpus; i++) {
|
for (uint32 i = 1; i < gKernelArgs.num_cpus; i++) {
|
||||||
// create a final stack the trampoline code will put the ap processor on
|
// create a final stack the trampoline code will put the ap processor on
|
||||||
gKernelArgs.cpu_kstack[i].start = (addr_t)mmu_allocate(NULL, KERNEL_STACK_SIZE);
|
gKernelArgs.cpu_kstack[i].start = (addr_t)mmu_allocate(NULL,
|
||||||
gKernelArgs.cpu_kstack[i].size = KERNEL_STACK_SIZE;
|
KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE);
|
||||||
|
gKernelArgs.cpu_kstack[i].size = KERNEL_STACK_SIZE
|
||||||
|
+ KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,14 +440,18 @@ smp_boot_other_cpus(void)
|
|||||||
|
|
||||||
// set this stack up
|
// set this stack up
|
||||||
finalStack = (uint32 *)gKernelArgs.cpu_kstack[i].start;
|
finalStack = (uint32 *)gKernelArgs.cpu_kstack[i].start;
|
||||||
memset(finalStack, 0, KERNEL_STACK_SIZE);
|
memset((uint8*)finalStack + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE, 0,
|
||||||
tempStack = (finalStack + KERNEL_STACK_SIZE / sizeof(uint32)) - 1;
|
KERNEL_STACK_SIZE);
|
||||||
|
tempStack = (finalStack
|
||||||
|
+ (KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE)
|
||||||
|
/ sizeof(uint32)) - 1;
|
||||||
*tempStack = (uint32)&smp_cpu_ready;
|
*tempStack = (uint32)&smp_cpu_ready;
|
||||||
|
|
||||||
// set the trampoline stack up
|
// set the trampoline stack up
|
||||||
tempStack = (uint32 *)(trampolineStack + B_PAGE_SIZE - 4);
|
tempStack = (uint32 *)(trampolineStack + B_PAGE_SIZE - 4);
|
||||||
// final location of the stack
|
// final location of the stack
|
||||||
*tempStack = ((uint32)finalStack) + KERNEL_STACK_SIZE - sizeof(uint32);
|
*tempStack = ((uint32)finalStack) + KERNEL_STACK_SIZE
|
||||||
|
+ KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE - sizeof(uint32);
|
||||||
tempStack--;
|
tempStack--;
|
||||||
// page dir
|
// page dir
|
||||||
*tempStack = gKernelArgs.arch_args.phys_pgdir;
|
*tempStack = gKernelArgs.arch_args.phys_pgdir;
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ boot_arch_cpu_init(void)
|
|||||||
gKernelArgs.arch_args.cpu_frequency = clockFrequency;
|
gKernelArgs.arch_args.cpu_frequency = clockFrequency;
|
||||||
gKernelArgs.arch_args.bus_frequency = busFrequency;
|
gKernelArgs.arch_args.bus_frequency = busFrequency;
|
||||||
gKernelArgs.arch_args.time_base_frequency = timeBaseFrequency;
|
gKernelArgs.arch_args.time_base_frequency = timeBaseFrequency;
|
||||||
|
|
||||||
TRACE((" CPU clock frequency: %ld\n", clockFrequency));
|
TRACE((" CPU clock frequency: %ld\n", clockFrequency));
|
||||||
TRACE((" bus clock frequency: %ld\n", busFrequency));
|
TRACE((" bus clock frequency: %ld\n", busFrequency));
|
||||||
TRACE((" time base frequency: %ld\n", timeBaseFrequency));
|
TRACE((" time base frequency: %ld\n", timeBaseFrequency));
|
||||||
@@ -84,7 +84,7 @@ boot_arch_cpu_init(void)
|
|||||||
|
|
||||||
cpuCount++;
|
cpuCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cpuCount == 0) {
|
if (cpuCount == 0) {
|
||||||
printf("boot_arch_cpu_init(): Found no CPUs!\n");
|
printf("boot_arch_cpu_init(): Found no CPUs!\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -95,7 +95,8 @@ boot_arch_cpu_init(void)
|
|||||||
// allocate the kernel stacks (the memory stuff is already initialized
|
// allocate the kernel stacks (the memory stuff is already initialized
|
||||||
// at this point)
|
// at this point)
|
||||||
addr_t stack = (addr_t)arch_mmu_allocate((void*)0x80000000,
|
addr_t stack = (addr_t)arch_mmu_allocate((void*)0x80000000,
|
||||||
cpuCount * KERNEL_STACK_SIZE, B_READ_AREA | B_WRITE_AREA, false);
|
cpuCount * (KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE),
|
||||||
|
B_READ_AREA | B_WRITE_AREA, false);
|
||||||
if (!stack) {
|
if (!stack) {
|
||||||
printf("boot_arch_cpu_init(): Failed to allocate kernel stack(s)!\n");
|
printf("boot_arch_cpu_init(): Failed to allocate kernel stack(s)!\n");
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
@@ -103,8 +104,9 @@ boot_arch_cpu_init(void)
|
|||||||
|
|
||||||
for (int i = 0; i < cpuCount; i++) {
|
for (int i = 0; i < cpuCount; i++) {
|
||||||
gKernelArgs.cpu_kstack[i].start = stack;
|
gKernelArgs.cpu_kstack[i].start = stack;
|
||||||
gKernelArgs.cpu_kstack[i].size = KERNEL_STACK_SIZE;
|
gKernelArgs.cpu_kstack[i].size = KERNEL_STACK_SIZE
|
||||||
stack += KERNEL_STACK_SIZE;
|
+ KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE;
|
||||||
|
stack += KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ return 0;
|
|||||||
|
|
||||||
kprintf(" kernel stack: %p to %p\n",
|
kprintf(" kernel stack: %p to %p\n",
|
||||||
(void *)thread->kernel_stack_base,
|
(void *)thread->kernel_stack_base,
|
||||||
(void *)(thread->kernel_stack_base + KERNEL_STACK_SIZE));
|
(void *)(thread->kernel_stack_top));
|
||||||
if (thread->user_stack_base != 0) {
|
if (thread->user_stack_base != 0) {
|
||||||
kprintf(" user stack: %p to %p\n",
|
kprintf(" user stack: %p to %p\n",
|
||||||
(void *)thread->user_stack_base,
|
(void *)thread->user_stack_base,
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ m68k_next_page_directory(struct thread *from, struct thread *to)
|
|||||||
// the one we're switching to is kernel space
|
// the one we're switching to is kernel space
|
||||||
return m68k_translation_map_get_pgdir(&vm_kernel_address_space()->translation_map);
|
return m68k_translation_map_get_pgdir(&vm_kernel_address_space()->translation_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
return m68k_translation_map_get_pgdir(&to->team->address_space->translation_map);
|
return m68k_translation_map_get_pgdir(&to->team->address_space->translation_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,15 +150,15 @@ arch_thread_init_kthread_stack(struct thread *t, int (*start_func)(void),
|
|||||||
void (*entry_func)(void), void (*exit_func)(void))
|
void (*entry_func)(void), void (*exit_func)(void))
|
||||||
{
|
{
|
||||||
addr_t *kstack = (addr_t *)t->kernel_stack_base;
|
addr_t *kstack = (addr_t *)t->kernel_stack_base;
|
||||||
addr_t *kstackTop = kstack + KERNEL_STACK_SIZE / sizeof(addr_t);
|
addr_t *kstackTop = (addr_t *)t->kernel_stack_base;
|
||||||
|
|
||||||
// clear the kernel stack
|
// clear the kernel stack
|
||||||
#ifdef DEBUG_KERNEL_STACKS
|
#ifdef DEBUG_KERNEL_STACKS
|
||||||
# ifdef STACK_GROWS_DOWNWARDS
|
# ifdef STACK_GROWS_DOWNWARDS
|
||||||
memset((void *)((addr_t)kstack + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE), 0,
|
memset((void *)((addr_t)kstack + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE), 0,
|
||||||
KERNEL_STACK_SIZE - KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE);
|
KERNEL_STACK_SIZE);
|
||||||
# else
|
# else
|
||||||
memset(kstack, 0, KERNEL_STACK_SIZE - KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE);
|
memset(kstack, 0, KERNEL_STACK_SIZE);
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
memset(kstack, 0, KERNEL_STACK_SIZE);
|
memset(kstack, 0, KERNEL_STACK_SIZE);
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ return 0;
|
|||||||
|
|
||||||
kprintf(" kernel stack: %p to %p\n",
|
kprintf(" kernel stack: %p to %p\n",
|
||||||
(void *)thread->kernel_stack_base,
|
(void *)thread->kernel_stack_base,
|
||||||
(void *)(thread->kernel_stack_base + KERNEL_STACK_SIZE));
|
(void *)(thread->kernel_stack_top));
|
||||||
if (thread->user_stack_base != 0) {
|
if (thread->user_stack_base != 0) {
|
||||||
kprintf(" user stack: %p to %p\n",
|
kprintf(" user stack: %p to %p\n",
|
||||||
(void *)thread->user_stack_base,
|
(void *)thread->user_stack_base,
|
||||||
|
|||||||
@@ -122,15 +122,15 @@ arch_thread_init_kthread_stack(struct thread *t, int (*start_func)(void),
|
|||||||
void (*entry_func)(void), void (*exit_func)(void))
|
void (*entry_func)(void), void (*exit_func)(void))
|
||||||
{
|
{
|
||||||
addr_t *kstack = (addr_t *)t->kernel_stack_base;
|
addr_t *kstack = (addr_t *)t->kernel_stack_base;
|
||||||
addr_t *kstackTop = kstack + KERNEL_STACK_SIZE / sizeof(addr_t);
|
addr_t *kstackTop = (addr_t *)t->kernel_stack_top;
|
||||||
|
|
||||||
// clear the kernel stack
|
// clear the kernel stack
|
||||||
#ifdef DEBUG_KERNEL_STACKS
|
#ifdef DEBUG_KERNEL_STACKS
|
||||||
# ifdef STACK_GROWS_DOWNWARDS
|
# ifdef STACK_GROWS_DOWNWARDS
|
||||||
memset((void *)((addr_t)kstack + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE), 0,
|
memset((void *)((addr_t)kstack + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE), 0,
|
||||||
KERNEL_STACK_SIZE - KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE);
|
KERNEL_STACK_SIZE);
|
||||||
# else
|
# else
|
||||||
memset(kstack, 0, KERNEL_STACK_SIZE - KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE);
|
memset(kstack, 0, KERNEL_STACK_SIZE);
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
memset(kstack, 0, KERNEL_STACK_SIZE);
|
memset(kstack, 0, KERNEL_STACK_SIZE);
|
||||||
@@ -180,9 +180,9 @@ void
|
|||||||
arch_thread_context_switch(struct thread *t_from, struct thread *t_to)
|
arch_thread_context_switch(struct thread *t_from, struct thread *t_to)
|
||||||
{
|
{
|
||||||
// set the new kernel stack in the EAR register.
|
// set the new kernel stack in the EAR register.
|
||||||
// this is used in the exception handler code to decide what kernel stack to
|
// this is used in the exception handler code to decide what kernel stack to
|
||||||
// switch to if the exception had happened when the processor was in user mode
|
// switch to if the exception had happened when the processor was in user mode
|
||||||
asm("mtear %0" :: "g"(t_to->kernel_stack_base + KERNEL_STACK_SIZE - 8));
|
asm("mtear %0" :: "g"(t_to->kernel_stack_top - 8));
|
||||||
|
|
||||||
// switch the asids if we need to
|
// switch the asids if we need to
|
||||||
if (t_to->team->address_space != NULL) {
|
if (t_to->team->address_space != NULL) {
|
||||||
|
|||||||
@@ -261,9 +261,9 @@ arch_thread_init_kthread_stack(struct thread *t, int (*start_func)(void),
|
|||||||
#ifdef DEBUG_KERNEL_STACKS
|
#ifdef DEBUG_KERNEL_STACKS
|
||||||
# ifdef STACK_GROWS_DOWNWARDS
|
# ifdef STACK_GROWS_DOWNWARDS
|
||||||
memset((void *)((addr_t)kstack + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE), 0,
|
memset((void *)((addr_t)kstack + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE), 0,
|
||||||
KERNEL_STACK_SIZE - KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE);
|
KERNEL_STACK_SIZE);
|
||||||
# else
|
# else
|
||||||
memset(kstack, 0, KERNEL_STACK_SIZE - KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE);
|
memset(kstack, 0, KERNEL_STACK_SIZE);
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
memset(kstack, 0, KERNEL_STACK_SIZE);
|
memset(kstack, 0, KERNEL_STACK_SIZE);
|
||||||
|
|||||||
@@ -985,10 +985,12 @@ team_create_thread_start(void *args)
|
|||||||
// ToDo: ENV_SIZE is a) limited, and b) not used after libroot copied it to the heap
|
// ToDo: ENV_SIZE is a) limited, and b) not used after libroot copied it to the heap
|
||||||
// ToDo: we could reserve the whole USER_STACK_REGION upfront...
|
// ToDo: we could reserve the whole USER_STACK_REGION upfront...
|
||||||
|
|
||||||
sizeLeft = PAGE_ALIGN(USER_MAIN_THREAD_STACK_SIZE + TLS_SIZE
|
sizeLeft = PAGE_ALIGN(USER_MAIN_THREAD_STACK_SIZE
|
||||||
|
+ USER_STACK_GUARD_PAGES * B_PAGE_SIZE + TLS_SIZE
|
||||||
+ sizeof(struct user_space_program_args) + teamArgs->flat_args_size);
|
+ sizeof(struct user_space_program_args) + teamArgs->flat_args_size);
|
||||||
t->user_stack_base = USER_STACK_REGION + USER_STACK_REGION_SIZE - sizeLeft;
|
t->user_stack_base = USER_STACK_REGION + USER_STACK_REGION_SIZE - sizeLeft;
|
||||||
t->user_stack_size = USER_MAIN_THREAD_STACK_SIZE;
|
t->user_stack_size = USER_MAIN_THREAD_STACK_SIZE
|
||||||
|
+ USER_STACK_GUARD_PAGES * B_PAGE_SIZE;
|
||||||
// the exact location at the end of the user stack area
|
// the exact location at the end of the user stack area
|
||||||
|
|
||||||
sprintf(ustack_name, "%s_main_stack", team->name);
|
sprintf(ustack_name, "%s_main_stack", team->name);
|
||||||
|
|||||||
@@ -391,7 +391,8 @@ create_thread(thread_creation_attributes& attributes, bool kernel)
|
|||||||
thread->id);
|
thread->id);
|
||||||
thread->kernel_stack_area = create_area(stack_name,
|
thread->kernel_stack_area = create_area(stack_name,
|
||||||
(void **)&thread->kernel_stack_base, B_ANY_KERNEL_ADDRESS,
|
(void **)&thread->kernel_stack_base, B_ANY_KERNEL_ADDRESS,
|
||||||
KERNEL_STACK_SIZE, B_FULL_LOCK,
|
KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE,
|
||||||
|
B_FULL_LOCK,
|
||||||
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_KERNEL_STACK_AREA);
|
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_KERNEL_STACK_AREA);
|
||||||
|
|
||||||
if (thread->kernel_stack_area < 0) {
|
if (thread->kernel_stack_area < 0) {
|
||||||
@@ -405,7 +406,8 @@ create_thread(thread_creation_attributes& attributes, bool kernel)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread->kernel_stack_top = thread->kernel_stack_base + KERNEL_STACK_SIZE;
|
thread->kernel_stack_top = thread->kernel_stack_base + KERNEL_STACK_SIZE
|
||||||
|
+ KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE;
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_THREAD_LOCK();
|
GRAB_THREAD_LOCK();
|
||||||
@@ -499,6 +501,7 @@ create_thread(thread_creation_attributes& attributes, bool kernel)
|
|||||||
thread->user_stack_size = USER_STACK_SIZE;
|
thread->user_stack_size = USER_STACK_SIZE;
|
||||||
else
|
else
|
||||||
thread->user_stack_size = PAGE_ALIGN(attributes.stack_size);
|
thread->user_stack_size = PAGE_ALIGN(attributes.stack_size);
|
||||||
|
thread->user_stack_size += USER_STACK_GUARD_PAGES * B_PAGE_SIZE;
|
||||||
|
|
||||||
snprintf(stack_name, B_OS_NAME_LENGTH, "%s_%ld_stack",
|
snprintf(stack_name, B_OS_NAME_LENGTH, "%s_%ld_stack",
|
||||||
attributes.name, thread->id);
|
attributes.name, thread->id);
|
||||||
|
|||||||
@@ -1576,6 +1576,7 @@ vm_create_anonymous_area(team_id team, const char *name, void **address,
|
|||||||
vm_cache *cache;
|
vm_cache *cache;
|
||||||
vm_page *page = NULL;
|
vm_page *page = NULL;
|
||||||
bool isStack = (protection & B_STACK_AREA) != 0;
|
bool isStack = (protection & B_STACK_AREA) != 0;
|
||||||
|
page_num_t guardPages;
|
||||||
bool canOvercommit = false;
|
bool canOvercommit = false;
|
||||||
addr_t physicalBase = 0;
|
addr_t physicalBase = 0;
|
||||||
|
|
||||||
@@ -1693,10 +1694,10 @@ vm_create_anonymous_area(team_id team, const char *name, void **address,
|
|||||||
|
|
||||||
// create an anonymous cache
|
// create an anonymous cache
|
||||||
// if it's a stack, make sure that two pages are available at least
|
// if it's a stack, make sure that two pages are available at least
|
||||||
status = VMCacheFactory::CreateAnonymousCache(cache,
|
guardPages = isStack ? ((protection & B_USER_PROTECTION) != 0
|
||||||
canOvercommit, isStack ? 2 : 0,
|
? USER_STACK_GUARD_PAGES : KERNEL_STACK_GUARD_PAGES) : 0;
|
||||||
isStack ? ((protection & B_USER_PROTECTION) != 0 ?
|
status = VMCacheFactory::CreateAnonymousCache(cache, canOvercommit,
|
||||||
USER_STACK_GUARD_PAGES : KERNEL_STACK_GUARD_PAGES) : 0,
|
isStack ? (min_c(2, size / B_PAGE_SIZE - guardPages)) : 0, guardPages,
|
||||||
wiring == B_NO_LOCK);
|
wiring == B_NO_LOCK);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
goto err1;
|
goto err1;
|
||||||
|
|||||||
Reference in New Issue
Block a user