Ignore:
Timestamp:
Jun 17, 2021, 1:37:55 PM (3 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
26d944c
Parents:
7e1cb79
Message:

Implemented kernel_getcpu from rseq and librseq.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/kernel/startup.cfa

    r7e1cb79 rf558b5f  
    1919// C Includes
    2020#include <errno.h>              // errno
     21#include <signal.h>
    2122#include <string.h>             // strerror
    2223#include <unistd.h>             // sysconf
     24
    2325extern "C" {
    2426      #include <limits.h>       // PTHREAD_STACK_MIN
     27        #include <unistd.h>       // syscall
    2528        #include <sys/eventfd.h>  // eventfd
    2629      #include <sys/mman.h>     // mprotect
    2730      #include <sys/resource.h> // getrlimit
     31        #include <sys/syscall.h>  // __NR_xxx
    2832}
    2933
     
    98102extern void __wake_proc(processor *);
    99103
     104#if   defined(CFA_HAVE_LINUX_LIBRSEQ)
     105        // No forward declaration needed
     106        #define __kernel_rseq_register rseq_register_current_thread
     107        #define __kernel_rseq_unregister rseq_unregister_current_thread
     108#elif defined(CFA_HAVE_LINUX_RSEQ_H)
     109        void __kernel_raw_rseq_register  (void);
     110        void __kernel_raw_rseq_unregister(void);
     111
     112        #define __kernel_rseq_register __kernel_raw_rseq_register
     113        #define __kernel_rseq_unregister __kernel_raw_rseq_unregister
     114#else
     115        // No forward declaration needed
     116        // No initialization needed
     117        static inline void noop(void) {};
     118
     119        #define __kernel_rseq_register noop
     120        #define __kernel_rseq_unregister noop
     121#endif
     122
    100123//-----------------------------------------------------------------------------
    101124// Kernel storage
     
    141164#elif defined(CFA_HAVE_LINUX_RSEQ_H)
    142165        extern "Cforall" {
    143                 // thread_local volatile struct rseq __cfaabi_rseq;
     166                __attribute__((aligned(128))) thread_local volatile struct rseq __cfaabi_rseq @= {
     167                        .cpu_id : RSEQ_CPU_ID_UNINITIALIZED,
     168                };
    144169        }
    145170#else
     
    230255
    231256        register_tls( mainProcessor );
     257
     258        __kernel_rseq_register();
    232259
    233260        //initialize the global state variables
     
    296323        mainProcessor->local_data = 0p;
    297324
     325        __kernel_rseq_unregister();
     326
    298327        unregister_tls( mainProcessor );
    299328
     
    347376        register_tls( proc );
    348377
    349         #if defined(CFA_HAVE_LINUX_LIBRSEQ)
    350                 rseq_register_current_thread();
    351         #endif
     378        __kernel_rseq_register();
    352379
    353380        // SKULLDUGGERY: We want to create a context for the processor coroutine
     
    389416
    390417        proc->local_data = 0p;
     418
     419        __kernel_rseq_unregister();
    391420
    392421        unregister_tls( proc );
     
    803832}
    804833#endif
     834
     835#if   defined(CFA_HAVE_LINUX_LIBRSEQ)
     836        // No definition needed
     837#elif defined(CFA_HAVE_LINUX_RSEQ_H)
     838
     839        #if defined( __x86_64 ) || defined( __i386 )
     840                #define RSEQ_SIG        0x53053053
     841        #elif defined( __ARM_ARCH )
     842                #ifdef __ARMEB__
     843                #define RSEQ_SIG    0xf3def5e7      /* udf    #24035    ; 0x5de3 (ARMv6+) */
     844                #else
     845                #define RSEQ_SIG    0xe7f5def3      /* udf    #24035    ; 0x5de3 */
     846                #endif
     847        #endif
     848
     849        extern void __disable_interrupts_hard();
     850        extern void __enable_interrupts_hard();
     851
     852        void __kernel_raw_rseq_register  (void) {
     853                /* paranoid */ verify( __cfaabi_rseq.cpu_id == RSEQ_CPU_ID_UNINITIALIZED );
     854
     855                // int ret = syscall(__NR_rseq, &__cfaabi_rseq, sizeof(struct rseq), 0, (sigset_t *)0p, _NSIG / 8);
     856                int ret = syscall(__NR_rseq, &__cfaabi_rseq, sizeof(struct rseq), 0, RSEQ_SIG);
     857                if(ret != 0) {
     858                        int e = errno;
     859                        switch(e) {
     860                        case EINVAL: abort("KERNEL ERROR: rseq register invalid argument");
     861                        case ENOSYS: abort("KERNEL ERROR: rseq register no supported");
     862                        case EFAULT: abort("KERNEL ERROR: rseq register with invalid argument");
     863                        case EBUSY : abort("KERNEL ERROR: rseq register already registered");
     864                        case EPERM : abort("KERNEL ERROR: rseq register sig  argument  on unregistration does not match the signature received on registration");
     865                        default: abort("KERNEL ERROR: rseq register unexpected return %d", e);
     866                        }
     867                }
     868        }
     869
     870        void __kernel_raw_rseq_unregister(void) {
     871                /* paranoid */ verify( __cfaabi_rseq.cpu_id >= 0 );
     872
     873                // int ret = syscall(__NR_rseq, &__cfaabi_rseq, sizeof(struct rseq), RSEQ_FLAG_UNREGISTER, (sigset_t *)0p, _NSIG / 8);
     874                int ret = syscall(__NR_rseq, &__cfaabi_rseq, sizeof(struct rseq), RSEQ_FLAG_UNREGISTER, RSEQ_SIG);
     875                if(ret != 0) {
     876                        int e = errno;
     877                        switch(e) {
     878                        case EINVAL: abort("KERNEL ERROR: rseq unregister invalid argument");
     879                        case ENOSYS: abort("KERNEL ERROR: rseq unregister no supported");
     880                        case EFAULT: abort("KERNEL ERROR: rseq unregister with invalid argument");
     881                        case EBUSY : abort("KERNEL ERROR: rseq unregister already registered");
     882                        case EPERM : abort("KERNEL ERROR: rseq unregister sig  argument  on unregistration does not match the signature received on registration");
     883                        default: abort("KERNEL ERROR: rseq unregisteunexpected return %d", e);
     884                        }
     885                }
     886        }
     887#else
     888        // No definition needed
     889#endif
Note: See TracChangeset for help on using the changeset viewer.