diff mbox

[RFC,ARM,8/8] Added support for ARMV8-M Security Extension cmse_nonsecure_caller intrinsic

Message ID 001d01d13f80$fe623db0$fb26b910$@foss.arm.com
State New
Headers show

Commit Message

Thomas Preudhomme Dec. 26, 2015, 1:59 a.m. UTC
[Sending on behalf of Andre Vieira]

Hello,

This patch adds support ARMv8-M's Security Extension's cmse_nonsecure_caller intrinsic. This intrinsic is used to check whether an entry function was called from a non-secure state. 
See Section 5.4.3 of ARM®v8-M Security Extensions: Requirements on Development Tools (http://infocenter.arm.com/help/topic/com.arm.doc.ecm0359818/index.html) for further details.

*** gcc/ChangeLog ***
2015-10-27  Andre Vieira        <andre.simoesdiasvieira@arm.com>
            Thomas Preud'homme  <thomas.preudhomme@arm.com>

        * gcc/config/arm/arm-builtins.c (arm_builtins): Define
          ARM_BUILTIN_CMSE_NONSECURE_CALLER.
          (bdesc_2arg): Add line for cmse_nonsecure_caller.
          (arm_init_builtins): Init for cmse_nonsecure_caller.
          (arm_expand_builtin): Handle cmse_nonsecure_caller.
        * gcc/config/arm/arm_cmse.h (cmse_nonsecure_caller): New.

*** gcc/testsuite/ChangeLog ***
2015-10-27  Andre Vieira        <andre.simoesdiasvieira@arm.com>
            Thomas Preud'homme  <thomas.preudhomme@arm.com>

        * gcc.target/arm/cmse/cmse-1.c: Added test for 
          cmse_nonsecure_caller.




We welcome any comment.

Cheers,

Andre

Comments

Andre Vieira (lists) Jan. 29, 2016, 5:08 p.m. UTC | #1
On 26/12/15 01:59, Thomas Preud'homme wrote:
> [Sending on behalf of Andre Vieira]
>
> Hello,
>
> This patch adds support ARMv8-M's Security Extension's cmse_nonsecure_caller intrinsic. This intrinsic is used to check whether an entry function was called from a non-secure state.
> See Section 5.4.3 of ARM®v8-M Security Extensions: Requirements on Development Tools (http://infocenter.arm.com/help/topic/com.arm.doc.ecm0359818/index.html) for further details.
>
> *** gcc/ChangeLog ***
> 2015-10-27  Andre Vieira        <andre.simoesdiasvieira@arm.com>
>              Thomas Preud'homme  <thomas.preudhomme@arm.com>
>
>          * gcc/config/arm/arm-builtins.c (arm_builtins): Define
>            ARM_BUILTIN_CMSE_NONSECURE_CALLER.
>            (bdesc_2arg): Add line for cmse_nonsecure_caller.
>            (arm_init_builtins): Init for cmse_nonsecure_caller.
>            (arm_expand_builtin): Handle cmse_nonsecure_caller.
>          * gcc/config/arm/arm_cmse.h (cmse_nonsecure_caller): New.
>
> *** gcc/testsuite/ChangeLog ***
> 2015-10-27  Andre Vieira        <andre.simoesdiasvieira@arm.com>
>              Thomas Preud'homme  <thomas.preudhomme@arm.com>
>
>          * gcc.target/arm/cmse/cmse-1.c: Added test for
>            cmse_nonsecure_caller.
>
>
> diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
> index 11cd17d0b8f3c29ccbe16cb463a17d55ba0fa1e3..7934cf1d4d96c40255d3e93dc9902b4568014984 100644
> --- a/gcc/config/arm/arm-builtins.c
> +++ b/gcc/config/arm/arm-builtins.c
> @@ -515,6 +515,8 @@ enum arm_builtins
>     ARM_BUILTIN_GET_FPSCR,
>     ARM_BUILTIN_SET_FPSCR,
>
> +  ARM_BUILTIN_CMSE_NONSECURE_CALLER,
> +
>   #undef CRYPTO1
>   #undef CRYPTO2
>   #undef CRYPTO3
> @@ -1263,6 +1265,10 @@ static const struct builtin_description bdesc_2arg[] =
>     FP_BUILTIN (set_fpscr, SET_FPSCR)
>   #undef FP_BUILTIN
>
> +  {ARM_FSET_MAKE_CPU2 (FL2_CMSE), CODE_FOR_andsi3,
> +   "__builtin_arm_cmse_nonsecure_caller", ARM_BUILTIN_CMSE_NONSECURE_CALLER,
> +   UNKNOWN, 0},
> +
>   #define CRC32_BUILTIN(L, U) \
>     {ARM_FSET_EMPTY, CODE_FOR_##L, "__builtin_arm_"#L, \
>      ARM_BUILTIN_##U, UNKNOWN, 0},
> @@ -1797,6 +1803,17 @@ arm_init_builtins (void)
>   	= add_builtin_function ("__builtin_arm_stfscr", ftype_set_fpscr,
>   				ARM_BUILTIN_SET_FPSCR, BUILT_IN_MD, NULL, NULL_TREE);
>       }
> +
> +  if (arm_arch_cmse)
> +    {
> +      tree ftype_cmse_nonsecure_caller
> +	= build_function_type_list (unsigned_type_node, NULL);
> +      arm_builtin_decls[ARM_BUILTIN_CMSE_NONSECURE_CALLER]
> +	= add_builtin_function ("__builtin_arm_cmse_nonsecure_caller",
> +				ftype_cmse_nonsecure_caller,
> +				ARM_BUILTIN_CMSE_NONSECURE_CALLER, BUILT_IN_MD,
> +				NULL, NULL_TREE);
> +    }
>   }
>
>   /* Return the ARM builtin for CODE.  */
> @@ -2356,6 +2373,14 @@ arm_expand_builtin (tree exp,
>         emit_insn (pat);
>         return target;
>
> +    case ARM_BUILTIN_CMSE_NONSECURE_CALLER:
> +      icode = CODE_FOR_andsi3;
> +      target = gen_reg_rtx (SImode);
> +      op0 = arm_return_addr (0, NULL_RTX);
> +      pat = GEN_FCN (icode) (target, op0, const1_rtx);
> +      emit_insn (pat);
> +      return target;
> +
>       case ARM_BUILTIN_TEXTRMSB:
>       case ARM_BUILTIN_TEXTRMUB:
>       case ARM_BUILTIN_TEXTRMSH:
> diff --git a/gcc/config/arm/arm_cmse.h b/gcc/config/arm/arm_cmse.h
> index ab20a3ec46025f268a1e9bed895d27da9af7aab6..0bdff668d03d54e1acf2bdd3b5ff1bfb2b463bd8 100644
> --- a/gcc/config/arm/arm_cmse.h
> +++ b/gcc/config/arm/arm_cmse.h
> @@ -163,6 +163,13 @@ __attribute__ ((__always_inline__))
>   cmse_TTAT (void *p)
>   CMSE_TT_ASM (at)
>
> +//TODO: diagnose use outside cmse_nonsecure_entry functions
> +__extension__ static __inline int __attribute__ ((__always_inline__))
> +cmse_nonsecure_caller (void)
> +{
> +  return __builtin_arm_cmse_nonsecure_caller ();
> +}
> +
>   #define CMSE_AU_NONSECURE	2
>   #define CMSE_MPU_NONSECURE	16
>   #define CMSE_NONSECURE		18
> diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c b/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c
> index 1c3d4e9e934f4b1166d4d98383cf4ae8c3515117..ccecf396d3cda76536537b4d146bbb5f70589fd5 100644
> --- a/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c
> +++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c
> @@ -66,3 +66,32 @@ int foo (char * p)
>   /* { dg-final { scan-assembler-times "ttat " 2 } } */
>   /* { dg-final { scan-assembler-times "bl.cmse_check_address_range" 7 } } */
>   /* { dg-final { scan-assembler-not "cmse_check_pointed_object" } } */
> +
> +typedef int (*int_ret_funcptr_t) (void);
> +typedef int __attribute__ ((cmse_nonsecure_call)) (*int_ret_nsfuncptr_t) (void);
> +
> +int __attribute__ ((cmse_nonsecure_entry))
> +baz (void)
> +{
> +  return cmse_nonsecure_caller ();
> +}
> +
> +int __attribute__ ((cmse_nonsecure_entry))
> +qux (int_ret_funcptr_t int_ret_funcptr)
> +{
> +  int_ret_nsfuncptr_t int_ret_nsfunc_ptr;
> +
> +  if (cmse_is_nsfptr (int_ret_funcptr))
> +    {
> +      int_ret_nsfunc_ptr = cmse_nsfptr_create (int_ret_funcptr);
> +      return int_ret_nsfunc_ptr ();
> +    }
> +  return 0;
> +}
> +/* { dg-final { scan-assembler "baz:" } } */
> +/* { dg-final { scan-assembler "__acle_se_baz:" } } */
> +/* { dg-final { scan-assembler-not "\tcmse_nonsecure_caller" } } */
> +/* { dg-final { scan-rtl-dump "and.*reg.*const_int 1" expand } } */
> +/* { dg-final { scan-assembler "bic" } } */
> +/* { dg-final { scan-assembler "push\t\{r4, r5, r6" } } */
> +/* { dg-final { scan-assembler "msr\tAPSR_nzcvq" } } */
>
>
> We welcome any comment.
>
> Cheers,
>
> Andre
>
Ping.
diff mbox

Patch

diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
index 11cd17d0b8f3c29ccbe16cb463a17d55ba0fa1e3..7934cf1d4d96c40255d3e93dc9902b4568014984 100644
--- a/gcc/config/arm/arm-builtins.c
+++ b/gcc/config/arm/arm-builtins.c
@@ -515,6 +515,8 @@  enum arm_builtins
   ARM_BUILTIN_GET_FPSCR,
   ARM_BUILTIN_SET_FPSCR,
 
+  ARM_BUILTIN_CMSE_NONSECURE_CALLER,
+
 #undef CRYPTO1
 #undef CRYPTO2
 #undef CRYPTO3
@@ -1263,6 +1265,10 @@  static const struct builtin_description bdesc_2arg[] =
   FP_BUILTIN (set_fpscr, SET_FPSCR)
 #undef FP_BUILTIN
 
+  {ARM_FSET_MAKE_CPU2 (FL2_CMSE), CODE_FOR_andsi3,
+   "__builtin_arm_cmse_nonsecure_caller", ARM_BUILTIN_CMSE_NONSECURE_CALLER,
+   UNKNOWN, 0},
+
 #define CRC32_BUILTIN(L, U) \
   {ARM_FSET_EMPTY, CODE_FOR_##L, "__builtin_arm_"#L, \
    ARM_BUILTIN_##U, UNKNOWN, 0},
@@ -1797,6 +1803,17 @@  arm_init_builtins (void)
 	= add_builtin_function ("__builtin_arm_stfscr", ftype_set_fpscr,
 				ARM_BUILTIN_SET_FPSCR, BUILT_IN_MD, NULL, NULL_TREE);
     }
+
+  if (arm_arch_cmse)
+    {
+      tree ftype_cmse_nonsecure_caller
+	= build_function_type_list (unsigned_type_node, NULL);
+      arm_builtin_decls[ARM_BUILTIN_CMSE_NONSECURE_CALLER]
+	= add_builtin_function ("__builtin_arm_cmse_nonsecure_caller",
+				ftype_cmse_nonsecure_caller,
+				ARM_BUILTIN_CMSE_NONSECURE_CALLER, BUILT_IN_MD,
+				NULL, NULL_TREE);
+    }
 }
 
 /* Return the ARM builtin for CODE.  */
@@ -2356,6 +2373,14 @@  arm_expand_builtin (tree exp,
       emit_insn (pat);
       return target;
 
+    case ARM_BUILTIN_CMSE_NONSECURE_CALLER:
+      icode = CODE_FOR_andsi3;
+      target = gen_reg_rtx (SImode);
+      op0 = arm_return_addr (0, NULL_RTX);
+      pat = GEN_FCN (icode) (target, op0, const1_rtx);
+      emit_insn (pat);
+      return target;
+
     case ARM_BUILTIN_TEXTRMSB:
     case ARM_BUILTIN_TEXTRMUB:
     case ARM_BUILTIN_TEXTRMSH:
diff --git a/gcc/config/arm/arm_cmse.h b/gcc/config/arm/arm_cmse.h
index ab20a3ec46025f268a1e9bed895d27da9af7aab6..0bdff668d03d54e1acf2bdd3b5ff1bfb2b463bd8 100644
--- a/gcc/config/arm/arm_cmse.h
+++ b/gcc/config/arm/arm_cmse.h
@@ -163,6 +163,13 @@  __attribute__ ((__always_inline__))
 cmse_TTAT (void *p)
 CMSE_TT_ASM (at)
 
+//TODO: diagnose use outside cmse_nonsecure_entry functions
+__extension__ static __inline int __attribute__ ((__always_inline__))
+cmse_nonsecure_caller (void)
+{
+  return __builtin_arm_cmse_nonsecure_caller ();
+}
+
 #define CMSE_AU_NONSECURE	2
 #define CMSE_MPU_NONSECURE	16
 #define CMSE_NONSECURE		18
diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c b/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c
index 1c3d4e9e934f4b1166d4d98383cf4ae8c3515117..ccecf396d3cda76536537b4d146bbb5f70589fd5 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c
@@ -66,3 +66,32 @@  int foo (char * p)
 /* { dg-final { scan-assembler-times "ttat " 2 } } */
 /* { dg-final { scan-assembler-times "bl.cmse_check_address_range" 7 } } */
 /* { dg-final { scan-assembler-not "cmse_check_pointed_object" } } */
+
+typedef int (*int_ret_funcptr_t) (void);
+typedef int __attribute__ ((cmse_nonsecure_call)) (*int_ret_nsfuncptr_t) (void);
+
+int __attribute__ ((cmse_nonsecure_entry))
+baz (void)
+{
+  return cmse_nonsecure_caller ();
+}
+
+int __attribute__ ((cmse_nonsecure_entry))
+qux (int_ret_funcptr_t int_ret_funcptr)
+{
+  int_ret_nsfuncptr_t int_ret_nsfunc_ptr;
+
+  if (cmse_is_nsfptr (int_ret_funcptr))
+    {
+      int_ret_nsfunc_ptr = cmse_nsfptr_create (int_ret_funcptr);
+      return int_ret_nsfunc_ptr ();
+    }
+  return 0;
+}
+/* { dg-final { scan-assembler "baz:" } } */
+/* { dg-final { scan-assembler "__acle_se_baz:" } } */
+/* { dg-final { scan-assembler-not "\tcmse_nonsecure_caller" } } */
+/* { dg-final { scan-rtl-dump "and.*reg.*const_int 1" expand } } */
+/* { dg-final { scan-assembler "bic" } } */
+/* { dg-final { scan-assembler "push\t\{r4, r5, r6" } } */
+/* { dg-final { scan-assembler "msr\tAPSR_nzcvq" } } */