-
From 12c4450781a2791a68007e57af88db521526aeec Mon Sep 17 00:00:00 2001
From: Hamish Morrison <hamishm53@gmail.com>
Date: Sun, 1 Apr 2012 08:37:42 +0000
Subject: [PATCH] Add support for pthread_attr_get/setguardsize()
* Added the aforementioned functions.
* create_area_etc() now takes a guard size parameter.
* The thread_info::stack_base/end range now refers to the usable range
only.
---
headers/posix/pthread.h | 9 ++---
headers/private/kernel/vm/VMCache.h | 2 +
headers/private/kernel/vm/vm.h | 4 +-
headers/private/libroot/pthread_private.h | 1 +
headers/private/system/thread_defs.h | 14 +++----
.../kernel/bus_managers/scsi/dma_buffer.cpp | 2 +-
src/add-ons/kernel/bus_managers/scsi/emulation.cpp | 2 +-
src/libs/compat/freebsd_network/compat_cpp.cpp | 2 +-
src/libs/posix_error_mapper/pthread_attr.cpp | 14 +++++++
.../arch/arm/paging/32bit/ARMPagingMethod32Bit.cpp | 2 +-
src/system/kernel/arch/x86/32/descriptors.cpp | 2 +-
src/system/kernel/arch/x86/arch_cpu.cpp | 2 +-
.../arch/x86/paging/32bit/X86PagingMethod32Bit.cpp | 2 +-
.../arch/x86/paging/pae/X86PagingMethodPAE.cpp | 2 +-
src/system/kernel/debug/debug_heap.cpp | 2 +-
src/system/kernel/debug/tracing.cpp | 8 ++--
src/system/kernel/device_manager/dma_resources.cpp | 2 +-
src/system/kernel/elf.cpp | 2 +-
src/system/kernel/sem.cpp | 2 +-
src/system/kernel/slab/MemoryManager.cpp | 2 +-
src/system/kernel/team.cpp | 2 +-
src/system/kernel/thread.cpp | 40 +++++++++++++-------
src/system/kernel/vm/VMAnonymousCache.cpp | 21 +++++-----
src/system/kernel/vm/VMAnonymousCache.h | 2 +
src/system/kernel/vm/VMAnonymousNoSwapCache.cpp | 21 +++++-----
src/system/kernel/vm/VMAnonymousNoSwapCache.h | 2 +
src/system/kernel/vm/vm.cpp | 37 +++++++++---------
src/system/libroot/posix/pthread/pthread.cpp | 4 +-
src/system/libroot/posix/pthread/pthread_attr.c | 28 ++++++++++++++
29 files changed, 148 insertions(+), 87 deletions(-)
diff --git a/headers/posix/pthread.h b/headers/posix/pthread.h
index cc5b900..ac84d62 100644
a
|
b
|
extern int pthread_attr_getschedparam(const pthread_attr_t *attr,
|
185 | 185 | extern int pthread_attr_setschedparam(pthread_attr_t *attr, |
186 | 186 | const struct sched_param *param); |
187 | 187 | |
| 188 | extern int pthread_attr_getguardsize(const pthread_attr_t *attr, |
| 189 | size_t *guardsize); |
| 190 | extern int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize); |
| 191 | |
188 | 192 | #if 0 /* Unimplemented attribute functions: */ |
189 | 193 | |
190 | 194 | /* [TPS] */ |
… |
… |
extern int pthread_attr_getschedpolicy(const pthread_attr_t *attr,
|
196 | 200 | int *policy); |
197 | 201 | extern int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy); |
198 | 202 | |
199 | | /* [XSI] */ |
200 | | extern int pthread_attr_getguardsize(const pthread_attr_t *attr, |
201 | | size_t *guardsize); |
202 | | extern int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize); |
203 | | |
204 | 203 | /* [TSA] */ |
205 | 204 | extern int pthread_attr_getstackaddr(const pthread_attr_t *attr, |
206 | 205 | void **stackaddr); |
-
diff --git a/headers/private/kernel/vm/VMCache.h b/headers/private/kernel/vm/VMCache.h
index 06bb0b9..ffa236a 100644
a
|
b
|
public:
|
117 | 117 | inline void IncrementWiredPagesCount(); |
118 | 118 | inline void DecrementWiredPagesCount(); |
119 | 119 | |
| 120 | virtual int32 GuardSize() { return 0; } |
| 121 | |
120 | 122 | void AddConsumer(VMCache* consumer); |
121 | 123 | |
122 | 124 | status_t InsertAreaLocked(VMArea* area); |
-
diff --git a/headers/private/kernel/vm/vm.h b/headers/private/kernel/vm/vm.h
index ef1b829..bd9fd16 100644
a
|
b
|
void forbid_page_faults(void);
|
77 | 77 | |
78 | 78 | // private kernel only extension (should be moved somewhere else): |
79 | 79 | area_id create_area_etc(team_id team, const char *name, uint32 size, |
80 | | uint32 lock, uint32 protection, uint32 flags, |
| 80 | uint32 lock, uint32 protection, uint32 flags, uint32 guardSize, |
81 | 81 | const virtual_address_restrictions* virtualAddressRestrictions, |
82 | 82 | const physical_address_restrictions* physicalAddressRestrictions, |
83 | 83 | void **_address); |
… |
… |
status_t vm_unreserve_address_range(team_id team, void *address, addr_t size);
|
95 | 95 | status_t vm_reserve_address_range(team_id team, void **_address, |
96 | 96 | uint32 addressSpec, addr_t size, uint32 flags); |
97 | 97 | area_id vm_create_anonymous_area(team_id team, const char* name, addr_t size, |
98 | | uint32 wiring, uint32 protection, uint32 flags, |
| 98 | uint32 wiring, uint32 protection, uint32 flags, addr_t guardSize, |
99 | 99 | const virtual_address_restrictions* virtualAddressRestrictions, |
100 | 100 | const physical_address_restrictions* physicalAddressRestrictions, |
101 | 101 | bool kernel, void** _address); |
-
diff --git a/headers/private/libroot/pthread_private.h b/headers/private/libroot/pthread_private.h
index f50bd28..1ddc00c 100644
a
|
b
|
typedef struct _pthread_attr {
|
40 | 40 | int32 detach_state; |
41 | 41 | int32 sched_priority; |
42 | 42 | size_t stack_size; |
| 43 | size_t guard_size; |
43 | 44 | } pthread_attr; |
44 | 45 | |
45 | 46 | typedef struct _pthread_rwlockattr { |
-
diff --git a/headers/private/system/thread_defs.h b/headers/private/system/thread_defs.h
index 9f1b527..2d55937 100644
a
|
b
|
|
12 | 12 | |
13 | 13 | |
14 | 14 | /** Size of the stack given to teams in user space */ |
15 | | #define USER_STACK_GUARD_PAGES 4 // 16 kB |
16 | | #define USER_MAIN_THREAD_STACK_SIZE (16 * 1024 * 1024 \ |
17 | | - USER_STACK_GUARD_PAGES * B_PAGE_SIZE) // 16 MB |
18 | | #define USER_STACK_SIZE (256 * 1024 \ |
19 | | - USER_STACK_GUARD_PAGES * B_PAGE_SIZE) // 256 kB |
20 | | #define MIN_USER_STACK_SIZE (4 * 1024) // 4 KB |
21 | | #define MAX_USER_STACK_SIZE (16 * 1024 * 1024 \ |
22 | | - USER_STACK_GUARD_PAGES * B_PAGE_SIZE) // 16 MB |
| 15 | #define USER_STACK_GUARD_SIZE (4 * B_PAGE_SIZE) // 16 kB |
| 16 | #define USER_MAIN_THREAD_STACK_SIZE (16 * 1024 * 1024) // 16 MB |
| 17 | #define USER_STACK_SIZE (256 * 1024) // 256 kB |
| 18 | #define MIN_USER_STACK_SIZE (4 * 1024) // 4 KB |
| 19 | #define MAX_USER_STACK_SIZE (16 * 1024 * 1024) // 16 MB |
23 | 20 | |
24 | 21 | |
25 | 22 | // The type of object a thread blocks on (thread::wait::type, set by |
… |
… |
struct thread_creation_attributes {
|
50 | 47 | void* args2; |
51 | 48 | void* stack_address; |
52 | 49 | size_t stack_size; |
| 50 | size_t guard_size; |
53 | 51 | pthread_t pthread; |
54 | 52 | uint32 flags; |
55 | 53 | }; |
-
diff --git a/src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp b/src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp
index 338a45f..ef54810 100644
a
|
b
|
scsi_alloc_dma_buffer(dma_buffer *buffer, dma_params *dma_params, uint32 size)
|
195 | 195 | // TODO: Use 64 bit addresses, if possible! |
196 | 196 | #endif |
197 | 197 | buffer->area = create_area_etc(B_SYSTEM_TEAM, "DMA buffer", size, |
198 | | B_CONTIGUOUS, 0, 0, &virtualRestrictions, &physicalRestrictions, |
| 198 | B_CONTIGUOUS, 0, 0, 0, &virtualRestrictions, &physicalRestrictions, |
199 | 199 | (void**)&buffer->address); |
200 | 200 | |
201 | 201 | if (buffer->area < 0) { |
-
diff --git a/src/add-ons/kernel/bus_managers/scsi/emulation.cpp b/src/add-ons/kernel/bus_managers/scsi/emulation.cpp
index 9127e24..161b273 100644
a
|
b
|
scsi_init_emulation_buffer(scsi_device_info *device, size_t buffer_size)
|
74 | 74 | physical_address_restrictions physicalRestrictions = {}; |
75 | 75 | physicalRestrictions.alignment = buffer_size; |
76 | 76 | device->buffer_area = create_area_etc(B_SYSTEM_TEAM, "ATAPI buffer", |
77 | | total_size, B_32_BIT_CONTIGUOUS, 0, 0, &virtualRestrictions, |
| 77 | total_size, B_32_BIT_CONTIGUOUS, 0, 0, 0, &virtualRestrictions, |
78 | 78 | &physicalRestrictions, &address); |
79 | 79 | // TODO: Use B_CONTIGUOUS, if possible! |
80 | 80 | |
-
diff --git a/src/libs/compat/freebsd_network/compat_cpp.cpp b/src/libs/compat/freebsd_network/compat_cpp.cpp
index 97c9243..a9ae740 100644
a
|
b
|
_kernel_contigmalloc_cpp(const char* file, int line, size_t size,
|
37 | 37 | |
38 | 38 | void* address; |
39 | 39 | area_id area = create_area_etc(B_SYSTEM_TEAM, name, size, B_CONTIGUOUS, |
40 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, creationFlags, |
| 40 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, creationFlags, 0, |
41 | 41 | &virtualRestrictions, &physicalRestrictions, &address); |
42 | 42 | if (area < 0) |
43 | 43 | return NULL; |
-
diff --git a/src/libs/posix_error_mapper/pthread_attr.cpp b/src/libs/posix_error_mapper/pthread_attr.cpp
index 163220a..2783bfd 100644
a
|
b
|
WRAPPER_FUNCTION(int, pthread_attr_getschedparam,
|
73 | 73 | return B_TO_POSITIVE_ERROR(sReal_pthread_attr_getschedparam(attr, |
74 | 74 | param)); |
75 | 75 | ) |
| 76 | |
| 77 | |
| 78 | WRAPPER_FUNCTION(int, pthread_attr_getguardsize, |
| 79 | (const pthread_attr_t *attr, size_t *guardsize), |
| 80 | return B_TO_POSITIVE_ERROR(sReal_pthread_attr_getguardsize(attr, |
| 81 | guardsize)); |
| 82 | ) |
| 83 | |
| 84 | |
| 85 | WRAPPER_FUNCTION(int, pthread_attr_setguardsize, |
| 86 | (pthread_attr_t *attr, size_t guardsize), |
| 87 | return B_TO_POSITIVE_ERROR(sReal_pthread_attr_setguardsize(attr, |
| 88 | guardsize)); |
| 89 | ) |
-
diff --git a/src/system/kernel/arch/arm/paging/32bit/ARMPagingMethod32Bit.cpp b/src/system/kernel/arch/arm/paging/32bit/ARMPagingMethod32Bit.cpp
index fe033e0..a973bb2 100644
a
|
b
|
ARMPagingMethod32Bit::PhysicalPageSlotPool::AllocatePool(
|
197 | 197 | physical_address_restrictions physicalRestrictions = {}; |
198 | 198 | area_id dataArea = create_area_etc(B_SYSTEM_TEAM, "physical page pool", |
199 | 199 | PAGE_ALIGN(areaSize), B_FULL_LOCK, |
200 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, |
| 200 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0, |
201 | 201 | &virtualRestrictions, &physicalRestrictions, &data); |
202 | 202 | if (dataArea < 0) |
203 | 203 | return dataArea; |
-
diff --git a/src/system/kernel/arch/x86/32/descriptors.cpp b/src/system/kernel/arch/x86/32/descriptors.cpp
index 2a957e3..465aab7 100644
a
|
b
|
x86_descriptors_init_post_vm(kernel_args* args)
|
552 | 552 | physical_address_restrictions physicalRestrictions = {}; |
553 | 553 | area = create_area_etc(B_SYSTEM_TEAM, "idt", areaSize, B_CONTIGUOUS, |
554 | 554 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, |
555 | | &virtualRestrictions, &physicalRestrictions, (void**)&idt); |
| 555 | 0, &virtualRestrictions, &physicalRestrictions, (void**)&idt); |
556 | 556 | if (area < 0) |
557 | 557 | return area; |
558 | 558 | |
-
diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp
index 155ed97..7438203 100644
a
|
b
|
arch_cpu_init_post_vm(kernel_args* args)
|
792 | 792 | physical_address_restrictions physicalRestrictions = {}; |
793 | 793 | create_area_etc(B_SYSTEM_TEAM, "double fault stacks", |
794 | 794 | kDoubleFaultStackSize * smp_get_num_cpus(), B_FULL_LOCK, |
795 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, |
| 795 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0, |
796 | 796 | &virtualRestrictions, &physicalRestrictions, |
797 | 797 | (void**)&sDoubleFaultStacks); |
798 | 798 | |
-
diff --git a/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp b/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp
index 987f3b4..be91ed5 100644
a
|
b
|
X86PagingMethod32Bit::PhysicalPageSlotPool::AllocatePool(
|
195 | 195 | physical_address_restrictions physicalRestrictions = {}; |
196 | 196 | area_id dataArea = create_area_etc(B_SYSTEM_TEAM, "physical page pool", |
197 | 197 | PAGE_ALIGN(areaSize), B_FULL_LOCK, |
198 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, |
| 198 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0, |
199 | 199 | &virtualRestrictions, &physicalRestrictions, &data); |
200 | 200 | if (dataArea < 0) |
201 | 201 | return dataArea; |
-
diff --git a/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp b/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp
index 3a3115f..34258f0 100644
a
|
b
|
X86PagingMethodPAE::PhysicalPageSlotPool::AllocatePool(
|
487 | 487 | physical_address_restrictions physicalRestrictions = {}; |
488 | 488 | area_id dataArea = create_area_etc(B_SYSTEM_TEAM, "physical page pool", |
489 | 489 | PAGE_ALIGN(areaSize), B_FULL_LOCK, |
490 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, |
| 490 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0, |
491 | 491 | &virtualRestrictions, &physicalRestrictions, &data); |
492 | 492 | if (dataArea < 0) |
493 | 493 | return dataArea; |
-
diff --git a/src/system/kernel/debug/debug_heap.cpp b/src/system/kernel/debug/debug_heap.cpp
index 996f521..efdd734 100644
a
|
b
|
debug_heap_init()
|
309 | 309 | physical_address_restrictions physicalRestrictions = {}; |
310 | 310 | area_id area = create_area_etc(B_SYSTEM_TEAM, "kdebug heap", KDEBUG_HEAP, |
311 | 311 | B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, |
312 | | CREATE_AREA_DONT_WAIT, &virtualRestrictions, &physicalRestrictions, |
| 312 | CREATE_AREA_DONT_WAIT, 0, &virtualRestrictions, &physicalRestrictions, |
313 | 313 | (void**)&base); |
314 | 314 | if (area < 0) |
315 | 315 | return; |
-
diff --git a/src/system/kernel/debug/tracing.cpp b/src/system/kernel/debug/tracing.cpp
index 02b55c7..e52ffb7 100644
a
|
b
|
TracingMetaData::Create(TracingMetaData*& _metaData)
|
452 | 452 | physical_address_restrictions physicalRestrictions = {}; |
453 | 453 | area = create_area_etc(B_SYSTEM_TEAM, "tracing log", |
454 | 454 | kTraceOutputBufferSize + MAX_TRACE_SIZE, B_CONTIGUOUS, |
455 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, |
| 455 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0, |
456 | 456 | &virtualRestrictions, &physicalRestrictions, |
457 | 457 | (void**)&metaData->fTraceOutputBuffer); |
458 | 458 | if (area < 0) |
… |
… |
TracingMetaData::_CreateMetaDataArea(bool findPrevious, area_id& _area,
|
503 | 503 | physicalRestrictions.high_address = metaDataAddress + B_PAGE_SIZE; |
504 | 504 | area_id area = create_area_etc(B_SYSTEM_TEAM, "tracing metadata", |
505 | 505 | B_PAGE_SIZE, B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, |
506 | | CREATE_AREA_DONT_CLEAR, &virtualRestrictions, &physicalRestrictions, |
507 | | (void**)&metaData); |
| 506 | CREATE_AREA_DONT_CLEAR, 0, &virtualRestrictions, |
| 507 | &physicalRestrictions, (void**)&metaData); |
508 | 508 | if (area < 0) |
509 | 509 | continue; |
510 | 510 | |
… |
… |
TracingMetaData::_InitPreviousTracingData()
|
567 | 567 | + ROUNDUP(kTraceOutputBufferSize + MAX_TRACE_SIZE, B_PAGE_SIZE); |
568 | 568 | area_id area = create_area_etc(B_SYSTEM_TEAM, "tracing log", |
569 | 569 | kTraceOutputBufferSize + MAX_TRACE_SIZE, B_CONTIGUOUS, |
570 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_CLEAR, |
| 570 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_CLEAR, 0, |
571 | 571 | &virtualRestrictions, &physicalRestrictions, NULL); |
572 | 572 | if (area < 0) { |
573 | 573 | dprintf("Failed to init tracing meta data: Mapping tracing log " |
-
diff --git a/src/system/kernel/device_manager/dma_resources.cpp b/src/system/kernel/device_manager/dma_resources.cpp
index 7e334f4..71753c8 100644
a
|
b
|
DMAResource::CreateBounceBuffer(DMABounceBuffer** _buffer)
|
246 | 246 | physicalRestrictions.alignment = fRestrictions.alignment; |
247 | 247 | physicalRestrictions.boundary = fRestrictions.boundary; |
248 | 248 | area = create_area_etc(B_SYSTEM_TEAM, "dma buffer", size, B_CONTIGUOUS, |
249 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, 0, &virtualRestrictions, |
| 249 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, 0, 0, &virtualRestrictions, |
250 | 250 | &physicalRestrictions, &bounceBuffer); |
251 | 251 | if (area < B_OK) |
252 | 252 | return area; |
-
diff --git a/src/system/kernel/elf.cpp b/src/system/kernel/elf.cpp
index 19d5e55..0bb496f 100644
a
|
b
|
elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
1943 | 1943 | virtualRestrictions.address_specification = B_EXACT_ADDRESS; |
1944 | 1944 | physical_address_restrictions physicalRestrictions = {}; |
1945 | 1945 | id = create_area_etc(team->id, regionName, bssSize, B_NO_LOCK, |
1946 | | B_READ_AREA | B_WRITE_AREA, 0, &virtualRestrictions, |
| 1946 | B_READ_AREA | B_WRITE_AREA, 0, 0, &virtualRestrictions, |
1947 | 1947 | &physicalRestrictions, (void**)®ionAddress); |
1948 | 1948 | if (id < B_OK) { |
1949 | 1949 | dprintf("error allocating bss area: %s!\n", strerror(id)); |
-
diff --git a/src/system/kernel/sem.cpp b/src/system/kernel/sem.cpp
index 13fe243..0b761c2 100644
a
|
b
|
haiku_sem_init(kernel_args *args)
|
432 | 432 | physical_address_restrictions physicalRestrictions = {}; |
433 | 433 | area = create_area_etc(B_SYSTEM_TEAM, "sem_table", |
434 | 434 | sizeof(struct sem_entry) * sMaxSems, B_FULL_LOCK, |
435 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, |
| 435 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0, |
436 | 436 | &virtualRestrictions, &physicalRestrictions, (void**)&sSems); |
437 | 437 | if (area < 0) |
438 | 438 | panic("unable to allocate semaphore table!\n"); |
-
diff --git a/src/system/kernel/slab/MemoryManager.cpp b/src/system/kernel/slab/MemoryManager.cpp
index 39d6d57..1dab8fb 100644
a
|
b
|
MemoryManager::AllocateRaw(size_t size, uint32 flags, void*& _pages)
|
627 | 627 | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, |
628 | 628 | ((flags & CACHE_DONT_WAIT_FOR_MEMORY) != 0 |
629 | 629 | ? CREATE_AREA_DONT_WAIT : 0) |
630 | | | CREATE_AREA_DONT_CLEAR, |
| 630 | | CREATE_AREA_DONT_CLEAR, 0, |
631 | 631 | &virtualRestrictions, &physicalRestrictions, &_pages); |
632 | 632 | |
633 | 633 | status_t result = area >= 0 ? B_OK : area; |
-
diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp
index e492bcd..381be36 100644
a
|
b
|
create_team_user_data(Team* team)
|
1333 | 1333 | virtualRestrictions.address_specification = B_BASE_ADDRESS; |
1334 | 1334 | physical_address_restrictions physicalRestrictions = {}; |
1335 | 1335 | team->user_data_area = create_area_etc(team->id, "user area", size, |
1336 | | B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA, 0, &virtualRestrictions, |
| 1336 | B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA, 0, 0, &virtualRestrictions, |
1337 | 1337 | &physicalRestrictions, &address); |
1338 | 1338 | if (team->user_data_area < 0) |
1339 | 1339 | return team->user_data_area; |
-
diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp
index e0eae26..02a574e 100644
a
|
b
|
ThreadCreationAttributes::ThreadCreationAttributes(thread_func function,
|
524 | 524 | this->args2 = NULL; |
525 | 525 | this->stack_address = NULL; |
526 | 526 | this->stack_size = 0; |
| 527 | this->guard_size = 0; |
527 | 528 | this->pthread = NULL; |
528 | 529 | this->flags = 0; |
529 | 530 | this->team = team >= 0 ? team : team_get_kernel_team()->id; |
… |
… |
init_thread_kernel_stack(Thread* thread, const void* data, size_t dataSize)
|
781 | 782 | |
782 | 783 | static status_t |
783 | 784 | create_thread_user_stack(Team* team, Thread* thread, void* _stackBase, |
784 | | size_t stackSize, size_t additionalSize, char* nameBuffer) |
| 785 | size_t stackSize, size_t additionalSize, size_t guardSize, |
| 786 | char* nameBuffer) |
785 | 787 | { |
786 | 788 | area_id stackArea = -1; |
787 | 789 | uint8* stackBase = (uint8*)_stackBase; |
788 | 790 | |
789 | 791 | if (stackBase != NULL) { |
790 | 792 | // A stack has been specified. It must be large enough to hold the |
791 | | // TLS space at least. |
| 793 | // TLS space at least. Guard pages are ignored for existing stacks. |
792 | 794 | STATIC_ASSERT(TLS_SIZE < MIN_USER_STACK_SIZE); |
793 | 795 | if (stackSize < MIN_USER_STACK_SIZE) |
794 | 796 | return B_BAD_VALUE; |
… |
… |
create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,
|
799 | 801 | // will be between USER_STACK_REGION and the main thread stack area. For |
800 | 802 | // a main thread the position is fixed. |
801 | 803 | |
| 804 | guardSize = PAGE_ALIGN(guardSize); |
| 805 | |
802 | 806 | if (stackSize == 0) { |
803 | 807 | // Use the default size (a different one for a main thread). |
804 | 808 | stackSize = thread->id == team->id |
805 | 809 | ? USER_MAIN_THREAD_STACK_SIZE : USER_STACK_SIZE; |
806 | 810 | } else { |
807 | 811 | // Verify that the given stack size is large enough. |
808 | | if (stackSize < MIN_USER_STACK_SIZE - TLS_SIZE) |
| 812 | if (stackSize < MIN_USER_STACK_SIZE) |
809 | 813 | return B_BAD_VALUE; |
810 | 814 | |
811 | 815 | stackSize = PAGE_ALIGN(stackSize); |
812 | 816 | } |
813 | | stackSize += USER_STACK_GUARD_PAGES * B_PAGE_SIZE; |
814 | 817 | |
815 | | size_t areaSize = PAGE_ALIGN(stackSize + TLS_SIZE + additionalSize); |
| 818 | size_t areaSize = PAGE_ALIGN(guardSize + stackSize + TLS_SIZE |
| 819 | + additionalSize); |
816 | 820 | |
817 | 821 | snprintf(nameBuffer, B_OS_NAME_LENGTH, "%s_%" B_PRId32 "_stack", |
818 | 822 | thread->name, thread->id); |
… |
… |
create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,
|
836 | 840 | |
837 | 841 | stackArea = create_area_etc(team->id, nameBuffer, |
838 | 842 | areaSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA | B_STACK_AREA, |
839 | | 0, &virtualRestrictions, &physicalRestrictions, |
| 843 | 0, guardSize, &virtualRestrictions, &physicalRestrictions, |
840 | 844 | (void**)&stackBase); |
841 | 845 | if (stackArea < 0) |
842 | 846 | return stackArea; |
… |
… |
create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,
|
844 | 848 | |
845 | 849 | // set the stack |
846 | 850 | ThreadLocker threadLocker(thread); |
| 851 | #ifdef STACK_GROWS_DOWNWARDS |
| 852 | thread->user_stack_base = (addr_t)stackBase + guardSize; |
| 853 | #else |
847 | 854 | thread->user_stack_base = (addr_t)stackBase; |
| 855 | #endif |
848 | 856 | thread->user_stack_size = stackSize; |
849 | 857 | thread->user_stack_area = stackArea; |
850 | 858 | |
… |
… |
thread_create_user_stack(Team* team, Thread* thread, void* stackBase,
|
858 | 866 | { |
859 | 867 | char nameBuffer[B_OS_NAME_LENGTH]; |
860 | 868 | return create_thread_user_stack(team, thread, stackBase, stackSize, |
861 | | additionalSize, nameBuffer); |
| 869 | additionalSize, USER_STACK_GUARD_SIZE, nameBuffer); |
862 | 870 | } |
863 | 871 | |
864 | 872 | |
… |
… |
thread_create_thread(const ThreadCreationAttributes& attributes, bool kernel)
|
915 | 923 | char stackName[B_OS_NAME_LENGTH]; |
916 | 924 | snprintf(stackName, B_OS_NAME_LENGTH, "%s_%" B_PRId32 "_kstack", |
917 | 925 | thread->name, thread->id); |
918 | | thread->kernel_stack_area = create_area(stackName, |
919 | | (void **)&thread->kernel_stack_base, B_ANY_KERNEL_ADDRESS, |
920 | | KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE, |
921 | | B_FULL_LOCK, |
922 | | B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_KERNEL_STACK_AREA); |
| 926 | virtual_address_restrictions virtualRestrictions = {}; |
| 927 | virtualRestrictions.address_specification = B_ANY_KERNEL_ADDRESS; |
| 928 | physical_address_restrictions physicalRestrictions = {}; |
| 929 | |
| 930 | thread->kernel_stack_area = create_area_etc(B_SYSTEM_TEAM, stackName, |
| 931 | KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE, |
| 932 | B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA |
| 933 | | B_KERNEL_STACK_AREA, 0, KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE, |
| 934 | &virtualRestrictions, &physicalRestrictions, |
| 935 | (void**)&thread->kernel_stack_base); |
923 | 936 | |
924 | 937 | if (thread->kernel_stack_area < 0) { |
925 | 938 | // we're not yet part of a team, so we can just bail out |
… |
… |
thread_create_thread(const ThreadCreationAttributes& attributes, bool kernel)
|
948 | 961 | if (thread->user_stack_base == 0) { |
949 | 962 | status = create_thread_user_stack(team, thread, |
950 | 963 | attributes.stack_address, attributes.stack_size, |
951 | | attributes.additional_stack_size, stackName); |
| 964 | attributes.additional_stack_size, attributes.guard_size, |
| 965 | stackName); |
952 | 966 | if (status != B_OK) |
953 | 967 | return status; |
954 | 968 | } |
-
diff --git a/src/system/kernel/vm/VMAnonymousCache.cpp b/src/system/kernel/vm/VMAnonymousCache.cpp
index 78925e9..8302f99 100644
a
|
b
|
VMAnonymousCache::MaxPagesPerAsyncWrite() const
|
787 | 787 | status_t |
788 | 788 | VMAnonymousCache::Fault(struct VMAddressSpace* aspace, off_t offset) |
789 | 789 | { |
790 | | if (fCanOvercommit && LookupPage(offset) == NULL && !HasPage(offset)) { |
791 | | if (fGuardedSize > 0) { |
792 | | uint32 guardOffset; |
| 790 | if (fGuardedSize > 0) { |
| 791 | uint32 guardOffset; |
793 | 792 | |
794 | 793 | #ifdef STACK_GROWS_DOWNWARDS |
795 | | guardOffset = 0; |
| 794 | guardOffset = 0; |
796 | 795 | #elif defined(STACK_GROWS_UPWARDS) |
797 | | guardOffset = virtual_size - fGuardedSize; |
| 796 | guardOffset = virtual_size - fGuardedSize; |
798 | 797 | #else |
799 | 798 | # error Stack direction has not been defined in arch_config.h |
800 | 799 | #endif |
801 | | |
802 | | // report stack fault, guard page hit! |
803 | | if (offset >= guardOffset && offset < guardOffset + fGuardedSize) { |
804 | | TRACE(("stack overflow!\n")); |
805 | | return B_BAD_ADDRESS; |
806 | | } |
| 800 | // report stack fault, guard page hit! |
| 801 | if (offset >= guardOffset && offset < guardOffset + fGuardedSize) { |
| 802 | TRACE(("stack overflow!\n")); |
| 803 | return B_BAD_ADDRESS; |
807 | 804 | } |
| 805 | } |
808 | 806 | |
| 807 | if (fCanOvercommit && LookupPage(offset) == NULL && !HasPage(offset)) { |
809 | 808 | if (fPrecommittedPages == 0) { |
810 | 809 | // never commit more than needed |
811 | 810 | if (committed_size / B_PAGE_SIZE > page_count) |
-
diff --git a/src/system/kernel/vm/VMAnonymousCache.h b/src/system/kernel/vm/VMAnonymousCache.h
index a3d51ad..065f422 100644
a
|
b
|
public:
|
45 | 45 | virtual bool HasPage(off_t offset); |
46 | 46 | virtual bool DebugHasPage(off_t offset); |
47 | 47 | |
| 48 | virtual int32 GuardSize() { return fGuardedSize; } |
| 49 | |
48 | 50 | virtual status_t Read(off_t offset, const generic_io_vec* vecs, |
49 | 51 | size_t count, uint32 flags, |
50 | 52 | generic_size_t* _numBytes); |
-
diff --git a/src/system/kernel/vm/VMAnonymousNoSwapCache.cpp b/src/system/kernel/vm/VMAnonymousNoSwapCache.cpp
index bd8ec84d..1de023a 100644
a
|
b
|
VMAnonymousNoSwapCache::Write(off_t offset, const iovec* vecs, size_t count,
|
120 | 120 | status_t |
121 | 121 | VMAnonymousNoSwapCache::Fault(struct VMAddressSpace* aspace, off_t offset) |
122 | 122 | { |
123 | | if (fCanOvercommit) { |
124 | | if (fGuardedSize > 0) { |
125 | | uint32 guardOffset; |
| 123 | if (fGuardedSize > 0) { |
| 124 | uint32 guardOffset; |
126 | 125 | |
127 | 126 | #ifdef STACK_GROWS_DOWNWARDS |
128 | | guardOffset = 0; |
| 127 | guardOffset = 0; |
129 | 128 | #elif defined(STACK_GROWS_UPWARDS) |
130 | | guardOffset = virtual_size - fGuardedSize; |
| 129 | guardOffset = virtual_size - fGuardedSize; |
131 | 130 | #else |
132 | 131 | # error Stack direction has not been defined in arch_config.h |
133 | 132 | #endif |
134 | | |
135 | | // report stack fault, guard page hit! |
136 | | if (offset >= guardOffset && offset < guardOffset + fGuardedSize) { |
137 | | TRACE(("stack overflow!\n")); |
138 | | return B_BAD_ADDRESS; |
139 | | } |
| 133 | // report stack fault, guard page hit! |
| 134 | if (offset >= guardOffset && offset < guardOffset + fGuardedSize) { |
| 135 | TRACE(("stack overflow!\n")); |
| 136 | return B_BAD_ADDRESS; |
140 | 137 | } |
| 138 | } |
141 | 139 | |
| 140 | if (fCanOvercommit) { |
142 | 141 | if (fPrecommittedPages == 0) { |
143 | 142 | // never commit more than needed |
144 | 143 | if (committed_size / B_PAGE_SIZE > page_count) |
-
diff --git a/src/system/kernel/vm/VMAnonymousNoSwapCache.h b/src/system/kernel/vm/VMAnonymousNoSwapCache.h
index c9b839e..c9250ed 100644
a
|
b
|
public:
|
25 | 25 | virtual status_t Commit(off_t size, int priority); |
26 | 26 | virtual bool HasPage(off_t offset); |
27 | 27 | |
| 28 | virtual int32 GuardSize() { return fGuardedSize; } |
| 29 | |
28 | 30 | virtual status_t Read(off_t offset, const iovec* vecs, |
29 | 31 | size_t count, uint32 flags, |
30 | 32 | size_t* _numBytes); |
-
diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp
index 1559491..6e809b6 100644
a
|
b
|
map_backing_store(VMAddressSpace* addressSpace, VMCache* cache, off_t offset,
|
817 | 817 | VMCache* newCache; |
818 | 818 | |
819 | 819 | // create an anonymous cache |
820 | | bool isStack = (protection & B_STACK_AREA) != 0; |
821 | 820 | status = VMCacheFactory::CreateAnonymousCache(newCache, |
822 | | isStack || (protection & B_OVERCOMMITTING_AREA) != 0, 0, |
823 | | isStack ? USER_STACK_GUARD_PAGES : 0, true, VM_PRIORITY_USER); |
| 821 | (protection & B_STACK_AREA) != 0 |
| 822 | || (protection & B_OVERCOMMITTING_AREA) != 0, 0, |
| 823 | cache->GuardSize() / B_PAGE_SIZE, true, VM_PRIORITY_USER); |
824 | 824 | if (status != B_OK) |
825 | 825 | goto err1; |
826 | 826 | |
… |
… |
vm_reserve_address_range(team_id team, void** _address, uint32 addressSpec,
|
1178 | 1178 | |
1179 | 1179 | area_id |
1180 | 1180 | vm_create_anonymous_area(team_id team, const char *name, addr_t size, |
1181 | | uint32 wiring, uint32 protection, uint32 flags, |
| 1181 | uint32 wiring, uint32 protection, uint32 flags, addr_t guardSize, |
1182 | 1182 | const virtual_address_restrictions* virtualAddressRestrictions, |
1183 | 1183 | const physical_address_restrictions* physicalAddressRestrictions, |
1184 | 1184 | bool kernel, void** _address) |
… |
… |
vm_create_anonymous_area(team_id team, const char *name, addr_t size,
|
1196 | 1196 | team, name, size)); |
1197 | 1197 | |
1198 | 1198 | size = PAGE_ALIGN(size); |
| 1199 | guardSize = PAGE_ALIGN(guardSize); |
| 1200 | guardPages = guardSize / B_PAGE_SIZE; |
1199 | 1201 | |
1200 | | if (size == 0) |
| 1202 | if (size == 0 || size < guardSize) |
1201 | 1203 | return B_BAD_VALUE; |
1202 | 1204 | if (!arch_vm_supports_protection(protection)) |
1203 | 1205 | return B_NOT_SUPPORTED; |
… |
… |
vm_create_anonymous_area(team_id team, const char *name, addr_t size,
|
1373 | 1375 | |
1374 | 1376 | // create an anonymous cache |
1375 | 1377 | // if it's a stack, make sure that two pages are available at least |
1376 | | guardPages = isStack ? ((protection & B_USER_PROTECTION) != 0 |
1377 | | ? USER_STACK_GUARD_PAGES : KERNEL_STACK_GUARD_PAGES) : 0; |
1378 | 1378 | status = VMCacheFactory::CreateAnonymousCache(cache, canOvercommit, |
1379 | 1379 | isStack ? (min_c(2, size / B_PAGE_SIZE - guardPages)) : 0, guardPages, |
1380 | 1380 | wiring == B_NO_LOCK, priority); |
… |
… |
_vm_map_file(team_id team, const char* name, void** _address,
|
1879 | 1879 | virtualRestrictions.address_specification = addressSpec; |
1880 | 1880 | physical_address_restrictions physicalRestrictions = {}; |
1881 | 1881 | return vm_create_anonymous_area(team, name, size, B_NO_LOCK, protection, |
1882 | | flags, &virtualRestrictions, &physicalRestrictions, kernel, |
| 1882 | flags, 0, &virtualRestrictions, &physicalRestrictions, kernel, |
1883 | 1883 | _address); |
1884 | 1884 | } |
1885 | 1885 | |
… |
… |
vm_copy_on_write_area(VMCache* lowerCache,
|
2305 | 2305 | |
2306 | 2306 | // create an anonymous cache |
2307 | 2307 | status_t status = VMCacheFactory::CreateAnonymousCache(upperCache, false, 0, |
2308 | | 0, dynamic_cast<VMAnonymousNoSwapCache*>(lowerCache) == NULL, |
| 2308 | lowerCache->GuardSize() / B_PAGE_SIZE, |
| 2309 | dynamic_cast<VMAnonymousNoSwapCache*>(lowerCache) == NULL, |
2309 | 2310 | VM_PRIORITY_USER); |
2310 | 2311 | if (status != B_OK) |
2311 | 2312 | return status; |
… |
… |
vm_init(kernel_args* args)
|
3893 | 3894 | create_area_etc(VMAddressSpace::KernelID(), "cache info table", |
3894 | 3895 | ROUNDUP(kCacheInfoTableCount * sizeof(cache_info), B_PAGE_SIZE), |
3895 | 3896 | B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, |
3896 | | CREATE_AREA_DONT_WAIT, &virtualRestrictions, &physicalRestrictions, |
3897 | | (void**)&sCacheInfoTable); |
| 3897 | CREATE_AREA_DONT_WAIT, 0, &virtualRestrictions, |
| 3898 | &physicalRestrictions, (void**)&sCacheInfoTable); |
3898 | 3899 | } |
3899 | 3900 | #endif // DEBUG_CACHE_LIST |
3900 | 3901 | |
… |
… |
clone_area(const char* name, void** _address, uint32 addressSpec,
|
5863 | 5864 | |
5864 | 5865 | area_id |
5865 | 5866 | create_area_etc(team_id team, const char* name, uint32 size, uint32 lock, |
5866 | | uint32 protection, uint32 flags, |
| 5867 | uint32 protection, uint32 flags, uint32 guardSize, |
5867 | 5868 | const virtual_address_restrictions* virtualAddressRestrictions, |
5868 | 5869 | const physical_address_restrictions* physicalAddressRestrictions, |
5869 | 5870 | void** _address) |
… |
… |
create_area_etc(team_id team, const char* name, uint32 size, uint32 lock,
|
5871 | 5872 | fix_protection(&protection); |
5872 | 5873 | |
5873 | 5874 | return vm_create_anonymous_area(team, name, size, lock, protection, flags, |
5874 | | virtualAddressRestrictions, physicalAddressRestrictions, true, |
5875 | | _address); |
| 5875 | guardSize, virtualAddressRestrictions, physicalAddressRestrictions, |
| 5876 | true, _address); |
5876 | 5877 | } |
5877 | 5878 | |
5878 | 5879 | |
… |
… |
__create_area_haiku(const char* name, void** _address, uint32 addressSpec,
|
5887 | 5888 | virtualRestrictions.address_specification = addressSpec; |
5888 | 5889 | physical_address_restrictions physicalRestrictions = {}; |
5889 | 5890 | return vm_create_anonymous_area(VMAddressSpace::KernelID(), name, size, |
5890 | | lock, protection, 0, &virtualRestrictions, &physicalRestrictions, true, |
5891 | | _address); |
| 5891 | lock, protection, 0, 0, &virtualRestrictions, &physicalRestrictions, |
| 5892 | true, _address); |
5892 | 5893 | } |
5893 | 5894 | |
5894 | 5895 | |
… |
… |
_user_create_area(const char* userName, void** userAddress, uint32 addressSpec,
|
6131 | 6132 | virtualRestrictions.address_specification = addressSpec; |
6132 | 6133 | physical_address_restrictions physicalRestrictions = {}; |
6133 | 6134 | area_id area = vm_create_anonymous_area(VMAddressSpace::CurrentID(), name, |
6134 | | size, lock, protection, 0, &virtualRestrictions, &physicalRestrictions, |
6135 | | false, &address); |
| 6135 | size, lock, protection, 0, 0, &virtualRestrictions, |
| 6136 | &physicalRestrictions, false, &address); |
6136 | 6137 | |
6137 | 6138 | if (area >= B_OK |
6138 | 6139 | && user_memcpy(userAddress, &address, sizeof(address)) < B_OK) { |
-
diff --git a/src/system/libroot/posix/pthread/pthread.cpp b/src/system/libroot/posix/pthread/pthread.cpp
index 4c5104a..15c2516 100644
a
|
b
|
|
25 | 25 | static const pthread_attr pthread_attr_default = { |
26 | 26 | PTHREAD_CREATE_JOINABLE, |
27 | 27 | B_NORMAL_PRIORITY, |
28 | | USER_STACK_SIZE |
| 28 | USER_STACK_SIZE, |
| 29 | USER_STACK_GUARD_SIZE |
29 | 30 | }; |
30 | 31 | |
31 | 32 | |
… |
… |
__pthread_init_creation_attributes(const pthread_attr_t* pthreadAttributes,
|
117 | 118 | attributes->args2 = argument2; |
118 | 119 | attributes->stack_address = NULL; |
119 | 120 | attributes->stack_size = attr->stack_size; |
| 121 | attributes->guard_size = attr->guard_size; |
120 | 122 | attributes->pthread = thread; |
121 | 123 | attributes->flags = 0; |
122 | 124 | |
-
diff --git a/src/system/libroot/posix/pthread/pthread_attr.c b/src/system/libroot/posix/pthread/pthread_attr.c
index 3054690..f6a15ff 100644
a
|
b
|
pthread_attr_init(pthread_attr_t *_attr)
|
30 | 30 | attr->detach_state = PTHREAD_CREATE_JOINABLE; |
31 | 31 | attr->sched_priority = B_NORMAL_PRIORITY; |
32 | 32 | attr->stack_size = USER_STACK_SIZE; |
| 33 | attr->guard_size = USER_STACK_GUARD_SIZE; |
33 | 34 | |
34 | 35 | *_attr = attr; |
35 | 36 | return B_OK; |
… |
… |
pthread_attr_getschedparam(const pthread_attr_t *attr,
|
162 | 163 | return 0; |
163 | 164 | } |
164 | 165 | |
| 166 | |
| 167 | int |
| 168 | pthread_attr_getguardsize(const pthread_attr_t *_attr, size_t *guardsize) |
| 169 | { |
| 170 | pthread_attr *attr; |
| 171 | |
| 172 | if (_attr == NULL || (attr = *_attr) == NULL || guardsize == NULL) |
| 173 | return B_BAD_VALUE; |
| 174 | |
| 175 | *guardsize = attr->guard_size; |
| 176 | |
| 177 | return 0; |
| 178 | } |
| 179 | |
| 180 | |
| 181 | int |
| 182 | pthread_attr_setguardsize(pthread_attr_t *_attr, size_t guardsize) |
| 183 | { |
| 184 | pthread_attr *attr; |
| 185 | |
| 186 | if (_attr == NULL || (attr = *_attr) == NULL) |
| 187 | return B_BAD_VALUE; |
| 188 | |
| 189 | attr->guard_size = guardsize; |
| 190 | |
| 191 | return 0; |
| 192 | } |