Ticket #8233: 0001-Add-support-for-pthread_attr_get-setguardsize.patch

File 0001-Add-support-for-pthread_attr_get-setguardsize.patch, 34.8 KB (added by hamish, 12 years ago)
  • headers/posix/pthread.h

    From 3c09cb1afb168200c7fa0889c3eb4f1628a47973 Mon Sep 17 00:00:00 2001
    From: Hamish Morrison <hamish@lavabit.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/arch_cpu.cpp            |    2 +-
     src/system/kernel/arch/x86/arch_int.cpp            |    2 +-
     .../arch/x86/paging/32bit/X86PagingMethod32Bit.cpp |    2 +-
     .../arch/x86/paging/pae/X86PagingMethodPAE.cpp     |    2 +-
     src/system/kernel/arch/x86/vm86.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 ++++++++++++++
     30 files changed, 149 insertions(+), 88 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,  
    185185extern int pthread_attr_setschedparam(pthread_attr_t *attr,
    186186    const struct sched_param *param);
    187187
     188extern int pthread_attr_getguardsize(const pthread_attr_t *attr,
     189    size_t *guardsize);
     190extern int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
     191
    188192#if 0   /* Unimplemented attribute functions: */
    189193
    190194/* [TPS] */
    extern int pthread_attr_getschedpolicy(const pthread_attr_t *attr,  
    196200    int *policy);
    197201extern int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
    198202
    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 
    204203/* [TSA] */
    205204extern int pthread_attr_getstackaddr(const pthread_attr_t *attr,
    206205    void **stackaddr);
  • headers/private/kernel/vm/VMCache.h

    diff --git a/headers/private/kernel/vm/VMCache.h b/headers/private/kernel/vm/VMCache.h
    index 06bb0b9..ffa236a 100644
    a b public:  
    117117    inline  void                IncrementWiredPagesCount();
    118118    inline  void                DecrementWiredPagesCount();
    119119
     120    virtual int32               GuardSize() { return 0; }
     121
    120122            void                AddConsumer(VMCache* consumer);
    121123
    122124            status_t            InsertAreaLocked(VMArea* area);
  • headers/private/kernel/vm/vm.h

    diff --git a/headers/private/kernel/vm/vm.h b/headers/private/kernel/vm/vm.h
    index 9163e3b..7bdcee1 100644
    a b void forbid_page_faults(void);  
    7777
    7878// private kernel only extension (should be moved somewhere else):
    7979area_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,
    8181            const virtual_address_restrictions* virtualAddressRestrictions,
    8282            const physical_address_restrictions* physicalAddressRestrictions,
    8383            void **_address);
    status_t vm_unreserve_address_range(team_id team, void *address, addr_t size);  
    9595status_t vm_reserve_address_range(team_id team, void **_address,
    9696            uint32 addressSpec, addr_t size, uint32 flags);
    9797area_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,
    9999            const virtual_address_restrictions* virtualAddressRestrictions,
    100100            const physical_address_restrictions* physicalAddressRestrictions,
    101101            bool kernel, void** _address);
  • headers/private/libroot/pthread_private.h

    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 {  
    4040    int32       detach_state;
    4141    int32       sched_priority;
    4242    size_t      stack_size;
     43    size_t      guard_size;
    4344} pthread_attr;
    4445
    4546typedef struct _pthread_rwlockattr {
  • headers/private/system/thread_defs.h

    diff --git a/headers/private/system/thread_defs.h b/headers/private/system/thread_defs.h
    index 9f1b527..2d55937 100644
    a b  
    1212
    1313
    1414/** 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
    2320
    2421
    2522// The type of object a thread blocks on (thread::wait::type, set by
    struct thread_creation_attributes {  
    5047    void*       args2;
    5148    void*       stack_address;
    5249    size_t      stack_size;
     50    size_t      guard_size;
    5351    pthread_t   pthread;
    5452    uint32      flags;
    5553};
  • src/add-ons/kernel/bus_managers/scsi/dma_buffer.cpp

    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 9da56a5..1b32a1d 100644
    a b scsi_alloc_dma_buffer(dma_buffer *buffer, dma_params *dma_params, uint32 size)  
    195195            // TODO: Use 64 bit addresses, if possible!
    196196#endif
    197197        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,
    199199            (void**)&buffer->address);
    200200
    201201        if (buffer->area < 0) {
  • src/add-ons/kernel/bus_managers/scsi/emulation.cpp

    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)  
    7474    physical_address_restrictions physicalRestrictions = {};
    7575    physicalRestrictions.alignment = buffer_size;
    7676    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,
    7878        &physicalRestrictions, &address);
    7979        // TODO: Use B_CONTIGUOUS, if possible!
    8080
  • src/libs/compat/freebsd_network/compat_cpp.cpp

    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,  
    3737
    3838    void* address;
    3939    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,
    4141        &virtualRestrictions, &physicalRestrictions, &address);
    4242    if (area < 0)
    4343        return NULL;
  • src/libs/posix_error_mapper/pthread_attr.cpp

    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,  
    7373    return B_TO_POSITIVE_ERROR(sReal_pthread_attr_getschedparam(attr,
    7474        param));
    7575)
     76
     77
     78WRAPPER_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
     85WRAPPER_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)
  • src/system/kernel/arch/arm/paging/32bit/ARMPagingMethod32Bit.cpp

    diff --git a/src/system/kernel/arch/arm/paging/32bit/ARMPagingMethod32Bit.cpp b/src/system/kernel/arch/arm/paging/32bit/ARMPagingMethod32Bit.cpp
    index 9214286..b2d218f 100644
    a b ARMPagingMethod32Bit::PhysicalPageSlotPool::AllocatePool(  
    197197    physical_address_restrictions physicalRestrictions = {};
    198198    area_id dataArea = create_area_etc(B_SYSTEM_TEAM, "physical page pool",
    199199        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,
    201201        &virtualRestrictions, &physicalRestrictions, &data);
    202202    if (dataArea < 0)
    203203        return dataArea;
  • src/system/kernel/arch/x86/arch_cpu.cpp

    diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp
    index c199afc..313a68b 100644
    a b arch_cpu_init_post_vm(kernel_args *args)  
    765765    physical_address_restrictions physicalRestrictions = {};
    766766    create_area_etc(B_SYSTEM_TEAM, "double fault stacks",
    767767        kDoubleFaultStackSize * smp_get_num_cpus(), B_FULL_LOCK,
    768         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
     768        B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
    769769        &virtualRestrictions, &physicalRestrictions,
    770770        (void**)&sDoubleFaultStacks);
    771771
  • src/system/kernel/arch/x86/arch_int.cpp

    diff --git a/src/system/kernel/arch/x86/arch_int.cpp b/src/system/kernel/arch/x86/arch_int.cpp
    index 123f575..a0dc35b 100644
    a b arch_int_init_post_vm(struct kernel_args *args)  
    873873        virtualRestrictions.address_specification = B_ANY_KERNEL_ADDRESS;
    874874        physical_address_restrictions physicalRestrictions = {};
    875875        area = create_area_etc(B_SYSTEM_TEAM, "idt", areaSize, B_CONTIGUOUS,
    876             B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
     876            B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
    877877            &virtualRestrictions, &physicalRestrictions, (void**)&idt);
    878878        if (area < 0)
    879879            return area;
  • src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp

    diff --git a/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp b/src/system/kernel/arch/x86/paging/32bit/X86PagingMethod32Bit.cpp
    index 9f84057..58cab87 100644
    a b X86PagingMethod32Bit::PhysicalPageSlotPool::AllocatePool(  
    195195    physical_address_restrictions physicalRestrictions = {};
    196196    area_id dataArea = create_area_etc(B_SYSTEM_TEAM, "physical page pool",
    197197        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,
    199199        &virtualRestrictions, &physicalRestrictions, &data);
    200200    if (dataArea < 0)
    201201        return dataArea;
  • src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp

    diff --git a/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp b/src/system/kernel/arch/x86/paging/pae/X86PagingMethodPAE.cpp
    index e7001bb..5136e77 100644
    a b X86PagingMethodPAE::PhysicalPageSlotPool::AllocatePool(  
    486486    physical_address_restrictions physicalRestrictions = {};
    487487    area_id dataArea = create_area_etc(B_SYSTEM_TEAM, "physical page pool",
    488488        PAGE_ALIGN(areaSize), B_FULL_LOCK,
    489         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
     489        B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
    490490        &virtualRestrictions, &physicalRestrictions, &data);
    491491    if (dataArea < 0)
    492492        return dataArea;
  • src/system/kernel/arch/x86/vm86.cpp

    diff --git a/src/system/kernel/arch/x86/vm86.cpp b/src/system/kernel/arch/x86/vm86.cpp
    index ebfce51..39adf38 100644
    a b vm86_prepare(struct vm86_state *state, unsigned int ramSize)  
    552552    virtualRestrictions.address_specification = B_EXACT_ADDRESS;
    553553    physical_address_restrictions physicalRestrictions = {};
    554554    state->ram_area = create_area_etc(team->id, "dos", ramSize, B_NO_LOCK,
    555         B_READ_AREA | B_WRITE_AREA, 0, &virtualRestrictions,
     555        B_READ_AREA | B_WRITE_AREA, 0, 0, &virtualRestrictions,
    556556        &physicalRestrictions, &address);
    557557    if (state->ram_area < B_OK) {
    558558        ret = state->ram_area;
  • src/system/kernel/debug/debug_heap.cpp

    diff --git a/src/system/kernel/debug/debug_heap.cpp b/src/system/kernel/debug/debug_heap.cpp
    index 069e97d..326d865 100644
    a b debug_heap_init()  
    296296    physical_address_restrictions physicalRestrictions = {};
    297297    area_id area = create_area_etc(B_SYSTEM_TEAM, "kdebug heap", KDEBUG_HEAP,
    298298        B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
    299         CREATE_AREA_DONT_WAIT, &virtualRestrictions, &physicalRestrictions,
     299        CREATE_AREA_DONT_WAIT, 0, &virtualRestrictions, &physicalRestrictions,
    300300        (void**)&base);
    301301    if (area < 0)
    302302        return;
  • src/system/kernel/debug/tracing.cpp

    diff --git a/src/system/kernel/debug/tracing.cpp b/src/system/kernel/debug/tracing.cpp
    index 72cbb95..5ae6d22 100644
    a b TracingMetaData::Create(TracingMetaData*& _metaData)  
    435435    physical_address_restrictions physicalRestrictions = {};
    436436    area = create_area_etc(B_SYSTEM_TEAM, "tracing log",
    437437        kTraceOutputBufferSize + MAX_TRACE_SIZE, B_CONTIGUOUS,
    438         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
     438        B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
    439439        &virtualRestrictions, &physicalRestrictions,
    440440        (void**)&metaData->fTraceOutputBuffer);
    441441    if (area < 0)
    TracingMetaData::_CreateMetaDataArea(bool findPrevious, area_id& _area,  
    486486        physicalRestrictions.high_address = metaDataAddress + B_PAGE_SIZE;
    487487        area_id area = create_area_etc(B_SYSTEM_TEAM, "tracing metadata",
    488488            B_PAGE_SIZE, B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
    489             CREATE_AREA_DONT_CLEAR, &virtualRestrictions, &physicalRestrictions,
    490             (void**)&metaData);
     489            CREATE_AREA_DONT_CLEAR, 0, &virtualRestrictions,
     490            &physicalRestrictions, (void**)&metaData);
    491491        if (area < 0)
    492492            continue;
    493493
    TracingMetaData::_InitPreviousTracingData()  
    550550        + ROUNDUP(kTraceOutputBufferSize + MAX_TRACE_SIZE, B_PAGE_SIZE);
    551551    area_id area = create_area_etc(B_SYSTEM_TEAM, "tracing log",
    552552        kTraceOutputBufferSize + MAX_TRACE_SIZE, B_CONTIGUOUS,
    553         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_CLEAR,
     553        B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_CLEAR, 0,
    554554        &virtualRestrictions, &physicalRestrictions, NULL);
    555555    if (area < 0) {
    556556        dprintf("Failed to init tracing meta data: Mapping tracing log "
  • src/system/kernel/device_manager/dma_resources.cpp

    diff --git a/src/system/kernel/device_manager/dma_resources.cpp b/src/system/kernel/device_manager/dma_resources.cpp
    index 5c4b3de..190c952 100644
    a b DMAResource::CreateBounceBuffer(DMABounceBuffer** _buffer)  
    246246    physicalRestrictions.alignment = fRestrictions.alignment;
    247247    physicalRestrictions.boundary = fRestrictions.boundary;
    248248    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,
    250250        &physicalRestrictions, &bounceBuffer);
    251251    if (area < B_OK)
    252252        return area;
  • src/system/kernel/elf.cpp

    diff --git a/src/system/kernel/elf.cpp b/src/system/kernel/elf.cpp
    index ad3c291..bdbf3fe 100644
    a b elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)  
    19311931                virtualRestrictions.address_specification = B_EXACT_ADDRESS;
    19321932                physical_address_restrictions physicalRestrictions = {};
    19331933                id = create_area_etc(team->id, regionName, bssSize, B_NO_LOCK,
    1934                     B_READ_AREA | B_WRITE_AREA, 0, &virtualRestrictions,
     1934                    B_READ_AREA | B_WRITE_AREA, 0, 0, &virtualRestrictions,
    19351935                    &physicalRestrictions, (void**)&regionAddress);
    19361936                if (id < B_OK) {
    19371937                    dprintf("error allocating bss area: %s!\n", strerror(id));
  • src/system/kernel/sem.cpp

    diff --git a/src/system/kernel/sem.cpp b/src/system/kernel/sem.cpp
    index ad32ddd..3803a6d 100644
    a b haiku_sem_init(kernel_args *args)  
    431431    physical_address_restrictions physicalRestrictions = {};
    432432    area = create_area_etc(B_SYSTEM_TEAM, "sem_table",
    433433        sizeof(struct sem_entry) * sMaxSems, B_FULL_LOCK,
    434         B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT,
     434        B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, CREATE_AREA_DONT_WAIT, 0,
    435435        &virtualRestrictions, &physicalRestrictions, (void**)&sSems);
    436436    if (area < 0)
    437437        panic("unable to allocate semaphore table!\n");
  • src/system/kernel/slab/MemoryManager.cpp

    diff --git a/src/system/kernel/slab/MemoryManager.cpp b/src/system/kernel/slab/MemoryManager.cpp
    index 3a6ac26..54523f9 100644
    a b MemoryManager::AllocateRaw(size_t size, uint32 flags, void*& _pages)  
    628628            B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
    629629            ((flags & CACHE_DONT_WAIT_FOR_MEMORY) != 0
    630630                    ? CREATE_AREA_DONT_WAIT : 0)
    631                 | CREATE_AREA_DONT_CLEAR,
     631                | CREATE_AREA_DONT_CLEAR, 0,
    632632            &virtualRestrictions, &physicalRestrictions, &_pages);
    633633
    634634        status_t result = area >= 0 ? B_OK : area;
  • src/system/kernel/team.cpp

    diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp
    index b794b07..346ae61 100644
    a b create_team_user_data(Team* team)  
    13311331    virtualRestrictions.address_specification = B_BASE_ADDRESS;
    13321332    physical_address_restrictions physicalRestrictions = {};
    13331333    team->user_data_area = create_area_etc(team->id, "user area", size,
    1334         B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA, 0, &virtualRestrictions,
     1334        B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA, 0, 0, &virtualRestrictions,
    13351335        &physicalRestrictions, &address);
    13361336    if (team->user_data_area < 0)
    13371337        return team->user_data_area;
  • src/system/kernel/thread.cpp

    diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp
    index 6c95268..bb14658 100644
    a b ThreadCreationAttributes::ThreadCreationAttributes(thread_func function,  
    524524    this->args2 = NULL;
    525525    this->stack_address = NULL;
    526526    this->stack_size = 0;
     527    this->guard_size = 0;
    527528    this->pthread = NULL;
    528529    this->flags = 0;
    529530    this->team = team >= 0 ? team : team_get_kernel_team()->id;
    init_thread_kernel_stack(Thread* thread, const void* data, size_t dataSize)  
    781782
    782783static status_t
    783784create_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)
    785787{
    786788    area_id stackArea = -1;
    787789    uint8* stackBase = (uint8*)_stackBase;
    788790
    789791    if (stackBase != NULL) {
    790792        // 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.
    792794        STATIC_ASSERT(TLS_SIZE < MIN_USER_STACK_SIZE);
    793795        if (stackSize < MIN_USER_STACK_SIZE)
    794796            return B_BAD_VALUE;
    create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,  
    799801        // will be between USER_STACK_REGION and the main thread stack area. For
    800802        // a main thread the position is fixed.
    801803
     804        guardSize = PAGE_ALIGN(guardSize);
     805
    802806        if (stackSize == 0) {
    803807            // Use the default size (a different one for a main thread).
    804808            stackSize = thread->id == team->id
    805809                ? USER_MAIN_THREAD_STACK_SIZE : USER_STACK_SIZE;
    806810        } else {
    807811            // 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)
    809813                return B_BAD_VALUE;
    810814
    811815            stackSize = PAGE_ALIGN(stackSize);
    812816        }
    813         stackSize += USER_STACK_GUARD_PAGES * B_PAGE_SIZE;
    814817
    815         size_t areaSize = PAGE_ALIGN(stackSize + TLS_SIZE + additionalSize);
     818        size_t areaSize = PAGE_ALIGN(guardSize + stackSize + TLS_SIZE
     819            + additionalSize);
    816820
    817821        snprintf(nameBuffer, B_OS_NAME_LENGTH, "%s_%ld_stack", thread->name,
    818822            thread->id);
    create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,  
    836840
    837841        stackArea = create_area_etc(team->id, nameBuffer,
    838842            areaSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA | B_STACK_AREA,
    839             0, &virtualRestrictions, &physicalRestrictions,
     843            0, guardSize, &virtualRestrictions, &physicalRestrictions,
    840844            (void**)&stackBase);
    841845        if (stackArea < 0)
    842846            return stackArea;
    create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,  
    844848
    845849    // set the stack
    846850    ThreadLocker threadLocker(thread);
     851#ifdef STACK_GROWS_DOWNWARDS
     852    thread->user_stack_base = (addr_t)stackBase + guardSize;
     853#else
    847854    thread->user_stack_base = (addr_t)stackBase;
     855#endif
    848856    thread->user_stack_size = stackSize;
    849857    thread->user_stack_area = stackArea;
    850858
    thread_create_user_stack(Team* team, Thread* thread, void* stackBase,  
    858866{
    859867    char nameBuffer[B_OS_NAME_LENGTH];
    860868    return create_thread_user_stack(team, thread, stackBase, stackSize,
    861         additionalSize, nameBuffer);
     869        additionalSize, USER_STACK_GUARD_SIZE, nameBuffer);
    862870}
    863871
    864872
    thread_create_thread(const ThreadCreationAttributes& attributes, bool kernel)  
    915923    char stackName[B_OS_NAME_LENGTH];
    916924    snprintf(stackName, B_OS_NAME_LENGTH, "%s_%ld_kstack", thread->name,
    917925        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);
    923936
    924937    if (thread->kernel_stack_area < 0) {
    925938        // we're not yet part of a team, so we can just bail out
    thread_create_thread(const ThreadCreationAttributes& attributes, bool kernel)  
    948961        if (thread->user_stack_base == 0) {
    949962            status = create_thread_user_stack(team, thread,
    950963                attributes.stack_address, attributes.stack_size,
    951                 attributes.additional_stack_size, stackName);
     964                attributes.additional_stack_size, attributes.guard_size,
     965                stackName);
    952966            if (status != B_OK)
    953967                return status;
    954968        }
  • src/system/kernel/vm/VMAnonymousCache.cpp

    diff --git a/src/system/kernel/vm/VMAnonymousCache.cpp b/src/system/kernel/vm/VMAnonymousCache.cpp
    index d9047df..8afaa74 100644
    a b VMAnonymousCache::MaxPagesPerAsyncWrite() const  
    767767status_t
    768768VMAnonymousCache::Fault(struct VMAddressSpace* aspace, off_t offset)
    769769{
    770     if (fCanOvercommit && LookupPage(offset) == NULL && !HasPage(offset)) {
    771         if (fGuardedSize > 0) {
    772             uint32 guardOffset;
     770    if (fGuardedSize > 0) {
     771        uint32 guardOffset;
    773772
    774773#ifdef STACK_GROWS_DOWNWARDS
    775             guardOffset = 0;
     774        guardOffset = 0;
    776775#elif defined(STACK_GROWS_UPWARDS)
    777             guardOffset = virtual_size - fGuardedSize;
     776        guardOffset = virtual_size - fGuardedSize;
    778777#else
    779778#   error Stack direction has not been defined in arch_config.h
    780779#endif
    781 
    782             // report stack fault, guard page hit!
    783             if (offset >= guardOffset && offset < guardOffset + fGuardedSize) {
    784                 TRACE(("stack overflow!\n"));
    785                 return B_BAD_ADDRESS;
    786             }
     780        // report stack fault, guard page hit!
     781        if (offset >= guardOffset && offset < guardOffset + fGuardedSize) {
     782            TRACE(("stack overflow!\n"));
     783            return B_BAD_ADDRESS;
    787784        }
     785    }
    788786
     787    if (fCanOvercommit && LookupPage(offset) == NULL && !HasPage(offset)) {
    789788        if (fPrecommittedPages == 0) {
    790789            // never commit more than needed
    791790            if (committed_size / B_PAGE_SIZE > page_count)
  • src/system/kernel/vm/VMAnonymousCache.h

    diff --git a/src/system/kernel/vm/VMAnonymousCache.h b/src/system/kernel/vm/VMAnonymousCache.h
    index a3d51ad..065f422 100644
    a b public:  
    4545    virtual bool                HasPage(off_t offset);
    4646    virtual bool                DebugHasPage(off_t offset);
    4747
     48    virtual int32               GuardSize() { return fGuardedSize; }
     49
    4850    virtual status_t            Read(off_t offset, const generic_io_vec* vecs,
    4951                                    size_t count, uint32 flags,
    5052                                    generic_size_t* _numBytes);
  • src/system/kernel/vm/VMAnonymousNoSwapCache.cpp

    diff --git a/src/system/kernel/vm/VMAnonymousNoSwapCache.cpp b/src/system/kernel/vm/VMAnonymousNoSwapCache.cpp
    index bd8ec84..1de023a 100644
    a b VMAnonymousNoSwapCache::Write(off_t offset, const iovec* vecs, size_t count,  
    120120status_t
    121121VMAnonymousNoSwapCache::Fault(struct VMAddressSpace* aspace, off_t offset)
    122122{
    123     if (fCanOvercommit) {
    124         if (fGuardedSize > 0) {
    125             uint32 guardOffset;
     123    if (fGuardedSize > 0) {
     124        uint32 guardOffset;
    126125
    127126#ifdef STACK_GROWS_DOWNWARDS
    128             guardOffset = 0;
     127        guardOffset = 0;
    129128#elif defined(STACK_GROWS_UPWARDS)
    130             guardOffset = virtual_size - fGuardedSize;
     129        guardOffset = virtual_size - fGuardedSize;
    131130#else
    132131#   error Stack direction has not been defined in arch_config.h
    133132#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;
    140137        }
     138    }
    141139
     140    if (fCanOvercommit) {
    142141        if (fPrecommittedPages == 0) {
    143142            // never commit more than needed
    144143            if (committed_size / B_PAGE_SIZE > page_count)
  • src/system/kernel/vm/VMAnonymousNoSwapCache.h

    diff --git a/src/system/kernel/vm/VMAnonymousNoSwapCache.h b/src/system/kernel/vm/VMAnonymousNoSwapCache.h
    index c9b839e..c9250ed 100644
    a b public:  
    2525    virtual status_t            Commit(off_t size, int priority);
    2626    virtual bool                HasPage(off_t offset);
    2727
     28    virtual int32               GuardSize() { return fGuardedSize; }
     29
    2830    virtual status_t            Read(off_t offset, const iovec* vecs,
    2931                                    size_t count, uint32 flags,
    3032                                    size_t* _numBytes);
  • src/system/kernel/vm/vm.cpp

    diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp
    index 857bf22..af971a7 100644
    a b map_backing_store(VMAddressSpace* addressSpace, VMCache* cache, off_t offset,  
    816816        VMCache* newCache;
    817817
    818818        // create an anonymous cache
    819         bool isStack = (protection & B_STACK_AREA) != 0;
    820819        status = VMCacheFactory::CreateAnonymousCache(newCache,
    821             isStack || (protection & B_OVERCOMMITTING_AREA) != 0, 0,
    822             isStack ? USER_STACK_GUARD_PAGES : 0, true, VM_PRIORITY_USER);
     820            (protection & B_STACK_AREA) != 0
     821                || (protection & B_OVERCOMMITTING_AREA) != 0, 0,
     822            cache->GuardSize() / B_PAGE_SIZE, true, VM_PRIORITY_USER);
    823823        if (status != B_OK)
    824824            goto err1;
    825825
    vm_reserve_address_range(team_id team, void** _address, uint32 addressSpec,  
    11771177
    11781178area_id
    11791179vm_create_anonymous_area(team_id team, const char *name, addr_t size,
    1180     uint32 wiring, uint32 protection, uint32 flags,
     1180    uint32 wiring, uint32 protection, uint32 flags, addr_t guardSize,
    11811181    const virtual_address_restrictions* virtualAddressRestrictions,
    11821182    const physical_address_restrictions* physicalAddressRestrictions,
    11831183    bool kernel, void** _address)
    vm_create_anonymous_area(team_id team, const char *name, addr_t size,  
    11941194    TRACE(("create_anonymous_area [%ld] %s: size 0x%lx\n", team, name, size));
    11951195
    11961196    size = PAGE_ALIGN(size);
     1197    guardSize = PAGE_ALIGN(guardSize);
     1198    guardPages = guardSize / B_PAGE_SIZE;
    11971199
    1198     if (size == 0)
     1200    if (size == 0 || size < guardSize)
    11991201        return B_BAD_VALUE;
    12001202    if (!arch_vm_supports_protection(protection))
    12011203        return B_NOT_SUPPORTED;
    vm_create_anonymous_area(team_id team, const char *name, addr_t size,  
    13711373
    13721374    // create an anonymous cache
    13731375    // if it's a stack, make sure that two pages are available at least
    1374     guardPages = isStack ? ((protection & B_USER_PROTECTION) != 0
    1375         ? USER_STACK_GUARD_PAGES : KERNEL_STACK_GUARD_PAGES) : 0;
    13761376    status = VMCacheFactory::CreateAnonymousCache(cache, canOvercommit,
    13771377        isStack ? (min_c(2, size / B_PAGE_SIZE - guardPages)) : 0, guardPages,
    13781378        wiring == B_NO_LOCK, priority);
    _vm_map_file(team_id team, const char* name, void** _address,  
    18771877        virtualRestrictions.address_specification = addressSpec;
    18781878        physical_address_restrictions physicalRestrictions = {};
    18791879        return vm_create_anonymous_area(team, name, size, B_NO_LOCK, protection,
    1880             flags, &virtualRestrictions, &physicalRestrictions, kernel,
     1880            flags, 0, &virtualRestrictions, &physicalRestrictions, kernel,
    18811881            _address);
    18821882    }
    18831883
    vm_copy_on_write_area(VMCache* lowerCache,  
    23022302
    23032303    // create an anonymous cache
    23042304    status_t status = VMCacheFactory::CreateAnonymousCache(upperCache, false, 0,
    2305         0, dynamic_cast<VMAnonymousNoSwapCache*>(lowerCache) == NULL,
     2305        lowerCache->GuardSize() / B_PAGE_SIZE,
     2306        dynamic_cast<VMAnonymousNoSwapCache*>(lowerCache) == NULL,
    23062307        VM_PRIORITY_USER);
    23072308    if (status != B_OK)
    23082309        return status;
    vm_init(kernel_args* args)  
    38873888        create_area_etc(VMAddressSpace::KernelID(), "cache info table",
    38883889            ROUNDUP(kCacheInfoTableCount * sizeof(cache_info), B_PAGE_SIZE),
    38893890            B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
    3890             CREATE_AREA_DONT_WAIT, &virtualRestrictions, &physicalRestrictions,
    3891             (void**)&sCacheInfoTable);
     3891            CREATE_AREA_DONT_WAIT, 0, &virtualRestrictions,
     3892            &physicalRestrictions, (void**)&sCacheInfoTable);
    38923893    }
    38933894#endif  // DEBUG_CACHE_LIST
    38943895
    clone_area(const char* name, void** _address, uint32 addressSpec,  
    58555856
    58565857area_id
    58575858create_area_etc(team_id team, const char* name, uint32 size, uint32 lock,
    5858     uint32 protection, uint32 flags,
     5859    uint32 protection, uint32 flags, uint32 guardSize,
    58595860    const virtual_address_restrictions* virtualAddressRestrictions,
    58605861    const physical_address_restrictions* physicalAddressRestrictions,
    58615862    void** _address)
    create_area_etc(team_id team, const char* name, uint32 size, uint32 lock,  
    58635864    fix_protection(&protection);
    58645865
    58655866    return vm_create_anonymous_area(team, name, size, lock, protection, flags,
    5866         virtualAddressRestrictions, physicalAddressRestrictions, true,
    5867         _address);
     5867        guardSize, virtualAddressRestrictions, physicalAddressRestrictions,
     5868        true, _address);
    58685869}
    58695870
    58705871
    __create_area_haiku(const char* name, void** _address, uint32 addressSpec,  
    58795880    virtualRestrictions.address_specification = addressSpec;
    58805881    physical_address_restrictions physicalRestrictions = {};
    58815882    return vm_create_anonymous_area(VMAddressSpace::KernelID(), name, size,
    5882         lock, protection, 0, &virtualRestrictions, &physicalRestrictions, true,
    5883         _address);
     5883        lock, protection, 0, 0, &virtualRestrictions, &physicalRestrictions,
     5884        true, _address);
    58845885}
    58855886
    58865887
    _user_create_area(const char* userName, void** userAddress, uint32 addressSpec,  
    61236124    virtualRestrictions.address_specification = addressSpec;
    61246125    physical_address_restrictions physicalRestrictions = {};
    61256126    area_id area = vm_create_anonymous_area(VMAddressSpace::CurrentID(), name,
    6126         size, lock, protection, 0, &virtualRestrictions, &physicalRestrictions,
    6127         false, &address);
     6127        size, lock, protection, 0, 0, &virtualRestrictions,
     6128        &physicalRestrictions, false, &address);
    61286129
    61296130    if (area >= B_OK
    61306131        && user_memcpy(userAddress, &address, sizeof(address)) < B_OK) {
  • src/system/libroot/posix/pthread/pthread.cpp

    diff --git a/src/system/libroot/posix/pthread/pthread.cpp b/src/system/libroot/posix/pthread/pthread.cpp
    index 4c5104a..15c2516 100644
    a b  
    2525static const pthread_attr pthread_attr_default = {
    2626    PTHREAD_CREATE_JOINABLE,
    2727    B_NORMAL_PRIORITY,
    28     USER_STACK_SIZE
     28    USER_STACK_SIZE,
     29    USER_STACK_GUARD_SIZE
    2930};
    3031
    3132
    __pthread_init_creation_attributes(const pthread_attr_t* pthreadAttributes,  
    117118    attributes->args2 = argument2;
    118119    attributes->stack_address = NULL;
    119120    attributes->stack_size = attr->stack_size;
     121    attributes->guard_size = attr->guard_size;
    120122    attributes->pthread = thread;
    121123    attributes->flags = 0;
    122124
  • src/system/libroot/posix/pthread/pthread_attr.c

    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)  
    3030    attr->detach_state = PTHREAD_CREATE_JOINABLE;
    3131    attr->sched_priority = B_NORMAL_PRIORITY;
    3232    attr->stack_size = USER_STACK_SIZE;
     33    attr->guard_size = USER_STACK_GUARD_SIZE;
    3334
    3435    *_attr = attr;
    3536    return B_OK;
    pthread_attr_getschedparam(const pthread_attr_t *attr,  
    162163    return 0;
    163164}
    164165
     166
     167int
     168pthread_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
     181int
     182pthread_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}