On Sat, Aug 22, 2020 at 9:19 AM Utkarsh Rai <utkarsh.ra...@gmail.com> wrote: > > For the design details of the stack sharing mechanism please refer to the > following post - > https://gsoc2020memoryprotection.blogspot.com/2020/08/high-level-design-and-implementation-of.html > --- > cpukit/posix/src/mmap.c | 39 ++++- > cpukit/posix/src/shmopen.c | 62 +------- > .../samples/thread_stack_sharing/init.c | 136 ++++++++++++++++++ > 3 files changed, 173 insertions(+), 64 deletions(-) > create mode 100644 testsuites/samples/thread_stack_sharing/init.c > > diff --git a/cpukit/posix/src/mmap.c b/cpukit/posix/src/mmap.c > index 176c6e4fe8..1d4b65cea6 100644 > --- a/cpukit/posix/src/mmap.c > +++ b/cpukit/posix/src/mmap.c > @@ -28,7 +28,27 @@ > > #include <rtems/posix/mmanimpl.h> > #include <rtems/posix/shmimpl.h> > +#include <rtems/score/stackprotection.h> > +#include <rtems/score/memoryprotection.h> > > +static uint32_t mmap_flag_translate(int prot) > +{ > + int prot_read; > + int prot_write; > + int memory_flag; > + > + prot_read = (prot_read & PROT_READ) == PROT_READ; > + prot_write = (prot_write & PROT_WRITE) == PROT_WRITE; > + > + if(prot_read){ ws
> + memory_flag |= ( RTEMS_READ_ONLY| RTEMS_MEMORY_CACHED ); > + } > + if(prot_write) { > + memory_flag |= ( RTEMS_READ_WRITE | RTEMS_MEMORY_CACHED ); > + } > + > + return memory_flag; > +} > > /** > * mmap chain of mappings. > @@ -50,6 +70,9 @@ void *mmap( > bool map_private; > bool is_shared_shm; > int err; > + uint32_t memory_flags; > + uintptr_t shared_stack_address; > + int status; > > map_fixed = (flags & MAP_FIXED) == MAP_FIXED; > map_anonymous = (flags & MAP_ANON) == MAP_ANON; > @@ -67,7 +90,10 @@ void *mmap( > > /* > * We can provide read, write and execute because the memory in RTEMS does > - * not normally have protections but we cannot hide access to memory. > + * not normally have protections but we cannot hide access to memory. For > + * thread-stack protection we can provide no-access option, but stacks are > + * implicitly isolated and it makes no sense to specify no-access option > for > + * already isolated stacks. > */ > if ( prot == PROT_NONE ) { > errno = ENOTSUP; > @@ -292,9 +318,16 @@ void *mmap( > free( mapping ); > return MAP_FAILED; > } > + /** > + * We share thread-stacks only when we have a shared memory object and map > + * shared flag set > + */ > + memory_flags = mmap_flag_translate( prot ); > + status = _Stackprotection_Share_stack( mapping->addr, addr, > len,memory_flags ); ws This function doesn't exist. This patch won't compile. Normally I would stop reviewing here. The _Stack_protection_Share_stack() function returns 0 or -1. It doesn't return a status code. > + } > + if(status == RTEMS_INVALID_ADDRESS ) { > + rtems_chain_append_unprotected( &mmap_mappings, &mapping->node ); > } > - > - rtems_chain_append_unprotected( &mmap_mappings, &mapping->node ); > > mmap_mappings_lock_release( ); > > diff --git a/cpukit/posix/src/shmopen.c b/cpukit/posix/src/shmopen.c > index 1e7fda66f8..b439592fd7 100644 > --- a/cpukit/posix/src/shmopen.c > +++ b/cpukit/posix/src/shmopen.c > @@ -19,13 +19,11 @@ > #include <unistd.h> > #include <fcntl.h> > #include <sys/stat.h> > -#include <string.h> > > #include <rtems/libio_.h> > #include <rtems/seterr.h> > > #include <rtems/posix/shmimpl.h> > -#include <rtems/posix/pthread.h> > #include <rtems/score/wkspace.h> > #include <rtems/sysinit.h> > > @@ -93,61 +91,6 @@ static int shm_ftruncate( rtems_libio_t *iop, off_t length > ) > return 0; > } > > -static int shm_stack_ftruncate ( rtems_libio_t *iop, off_t length ) > -{ > - int err; > - Objects_Id id; > - Objects_Name_or_id_lookup_errors obj_err; > - Thread_Control *Control; > - ISR_lock_Context lock_context; > - size_t size; > - char *name; > - POSIX_Shm_Control *shm = iop_to_shm ( iop ); > - > - name = shm->Object.name.name_p; > - > - /** We assign fixed pattern of naming for thread-stacks, and treat them > - * accordingly. > - */ > - if( strncmp( name, "/taskfs/", 8) == 0 ) { > - /** > - * Obtain the object id of the thread and then get the thread control > block > - * corresponding to that id. > - */ > - obj_err = _Objects_Name_to_id_u32( > - &_POSIX_Threads_Information.Objects, > - _Objects_Build_name( name[8], name[9], name[10], name[11]), > - RTEMS_LOCAL, > - &id > - ); > - Control = _Thread_Get( id, &lock_context ); > - if( Control != NULL ) { > - shm->shm_object.handle = Control->Start.Initial_stack.area; > - if( length != Control->Start.Initial_stack.size) { > - return ENOMEM; > - } > - } else { > - return ENOMEM; > - } > - }else{ > - > - _Objects_Allocator_lock(); > - > - err = (*shm->shm_object.ops->object_resize)( &shm->shm_object, length ); > - > - if ( err != 0 ) { > - _Objects_Allocator_unlock(); > - rtems_set_errno_and_return_minus_one( err ); > - } > - > - _POSIX_Shm_Update_mtime_ctime( shm ); > - > - _Objects_Allocator_unlock(); > - return 0; > - } > - > -} > - Why are you removing this code? > static int shm_close( rtems_libio_t *iop ) > { > POSIX_Shm_Control *shm = iop_to_shm( iop ); > @@ -363,11 +306,7 @@ static const rtems_filesystem_file_handlers_r > shm_handlers = { > .ioctl_h = rtems_filesystem_default_ioctl, > .lseek_h = rtems_filesystem_default_lseek, > .fstat_h = shm_fstat, > - #if defined ( RTEMS_THREAD_STACK_PROTECTION ) > - .ftruncate_h = shm_stack_ftruncate, > - #else > .ftruncate_h = shm_ftruncate, > - #endif > .fsync_h = rtems_filesystem_default_fsync_or_fdatasync, > .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, > .fcntl_h = rtems_filesystem_default_fcntl, > @@ -388,3 +327,4 @@ RTEMS_SYSINIT_ITEM( > RTEMS_SYSINIT_POSIX_SHM, > RTEMS_SYSINIT_ORDER_MIDDLE > ); > + > diff --git a/testsuites/samples/thread_stack_sharing/init.c > b/testsuites/samples/thread_stack_sharing/init.c > new file mode 100644 > index 0000000000..5bb7d01418 > --- /dev/null > +++ b/testsuites/samples/thread_stack_sharing/init.c > @@ -0,0 +1,136 @@ > +#ifdef HAVE_CONFIG_H > +#include "config.h" > +#endif > + > +#include <rtems.h> > +#include <tmacros.h> > +#include <pthread.h> > +#include <sys/mman.h> > +#include <sys/fcntl.h> > +#include <rtems/score/memoryprotection.h> > + > +const char rtems_test_name[] = " THREAD STACK SHARING "; > + > +void* Test_routine( void* arg ) > +{ > + > +} > + > +void *POSIX_Init( void *argument ) > +{ > + void *stack_addr1; > + void *stack_addr2; > + void* addr; > + size_t stack_size1; > + size_t stack_size2; > + pthread_t id1; > + pthread_t id2; > + pthread_attr_t attr1; > + pthread_attr_t attr2; > + int fd; > + char name[4] = "0x01"; > + char thread_name[13] = "/taskfs/0x01"; > + > + TEST_BEGIN(); > + > + /* > + * We set the stack size as 8Kb. > + */ > + stack_size1 = 8192; > + stack_size2 = 8192; > + > + /* > + * We allocate page-aligned memory of the stack from the application. > + */ > + posix_memalign(&stack_addr1, sysconf( _SC_PAGESIZE ), stack_size1 ); > + posix_memalign(&stack_addr2, sysconf( _SC_PAGESIZE ), stack_size2 ); > + > + pthread_attr_init( &attr1 ); > + pthread_attr_init( &attr2 ); > + > + /* > + * We set the stack size and address of the thread from the application > itself > + */ > + pthread_attr_setstack( &attr1, stack_addr1, stack_size1 ); > + pthread_attr_setstack( &attr2, stack_addr2, stack_size2 ); > + > + pthread_create( &id1, &attr1, Test_routine, NULL ); > + > + /* > + * We set the memory attributes of the stack from the application. > + */ > + _Memory_protection_Set_entries( stack_addr1, stack_size1, RTEMS_READ_ONLY > | RTEMS_MEMORY_CACHED ); > + > + pthread_create( &id2, &attr2, Test_routine, NULL ); > + _Memory_protection_Set_entries( stack_addr2, stack_size2, RTEMS_READ_ONLY > | RTEMS_MEMORY_CACHED ); > + > + /* > + * Add leading "/taskfs/" to denote thread-stack name. > + */ > + strlcat( thread_name, name, 4); > + > + /* > + * Set the name of the thread object same as that of the shared memory > object name > + */ > + rtems_object_set_name( id1, name); > + > + /* > + * Create a shared memory object of the stack we want to share with > + * appropraite permissions. We share the stack with read and write > permission > + */ > + fd = shm_open( thread_name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR ); > + > + /* > + * Truncate the size of the file to the size of the stack. > + */ > + ftruncate( fd, stack_size1 ); > + > + /* > + * For sharing the stack we specify the address of the > + * thread-stack we want to share with, the size of the shared stack, > + * protection and access flags, file descriptor of the shared memory objcet > + */ > + addr = mmap( stack_addr2, stack_size1, PROT_READ | PROT_WRITE, O_RDWR, fd, > 0 ); > + rtems_test_assert( addr != NULL ); > + > + pthread_join( id1, NULL ); > + /* > + * Write to the stack address of thread1 after it has been switched out. > + */ > + memset( stack_addr1, 0, stack_size1 ); > + > + pthread_join( id2, NULL ); > + /* > + * Write to the stack address of thread2 after it has been switched out. > + */ > + memset( stack_addr2, 0, stack_size2 ); > + > + > + TEST_END(); > + rtems_test_exit( 0 ); > +} > + > +/* configuration information */ > + > +#define CONFIGURE_INIT > + > +#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER > +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER > + > +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION > + > +#define CONFIGURE_MAXIMUM_POSIX_THREADS 4 > + > +#define CONFIGURE_MAXIMUM_POSIX_SHMS 2 > + > +#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 10 > + > +#define CONFIGURE_POSIX_INIT_THREAD_TABLE > + > +#define CONFIGURE_TASK_STACK_ALLOCATOR_INIT bsp_stack_allocate_init > +#define CONFIGURE_TASK_STACK_ALLOCATOR bsp_stack_allocate > +#define CONFIGURE_TASK_STACK_DEALLOCATOR bsp_stack_free > + > +#include <bsp/stackalloc.h> > +#define CONFIGURE_INIT > +#include <rtems/confdefs.h> > \ No newline at end of file > -- > 2.17.1 > _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel