On 09/11/16 14:53, Andre Vieira (lists) wrote:
On 27/10/16 11:01, Andre Vieira (lists) wrote:
On 25/10/16 17:30, Andre Vieira (lists) wrote:
On 24/08/16 12:01, Andre Vieira (lists) wrote:
On 25/07/16 14:26, Andre Vieira (lists) wrote:
This patch extends support for the ARMv8-M Security Extensions
'cmse_nonsecure_call' to use a new library function
'__gnu_cmse_nonsecure_call'. This library function is responsible for
(without using r0-r3 or d0-d7):
1) saving and clearing all callee-saved registers using the secure stack
2) clearing the LSB of the address passed in r4 and using blxns to
'jump' to it
3) clearing ASPR, including the 'ge bits' if DSP is enabled
4) clearing FPSCR if using non-soft float-abi
5) restoring callee-saved registers.
The decisions whether to include DSP 'ge bits' clearing and floating
point registers (single/double precision) all depends on the multilib used.
See Section 5.5 of ARM®v8-M Security Extensions
(http://infocenter.arm.com/help/topic/com.arm.doc.ecm0359818/index.html).
*** gcc/ChangeLog ***
2016-07-25 Andre Vieira <andre.simoesdiasvie...@arm.com>
Thomas Preud'homme <thomas.preudho...@arm.com>
* config/arm/arm.c (detect_cmse_nonsecure_call): New.
(cmse_nonsecure_call_clear_caller_saved): New.
(arm_reorg): Use cmse_nonsecure_call_clear_caller_saved.
* config/arm/arm-protos.h (detect_cmse_nonsecure_call): New.
* config/arm/arm.md (call): Handle cmse_nonsecure_entry.
(call_value): Likewise.
(nonsecure_call_internal): New.
(nonsecure_call_value_internal): New.
* config/arm/thumb1.md (*nonsecure_call_reg_thumb1_v5): New.
(*nonsecure_call_value_reg_thumb1_v5): New.
* config/arm/thumb2.md (*nonsecure_call_reg_thumb2): New.
(*nonsecure_call_value_reg_thumb2): New.
* config/arm/unspecs.md (UNSPEC_NONSECURE_MEM): New.
*** libgcc/ChangeLog ***
2016-07-25 Andre Vieira <andre.simoesdiasvie...@arm.com>
Thomas Preud'homme <thomas.preudho...@arm.com>
* config/arm/cmse_nonsecure_call.S: New.
* config/arm/t-arm: Compile cmse_nonsecure_call.S
*** gcc/testsuite/ChangeLog ***
2016-07-25 Andre Vieira <andre.simoesdiasvie...@arm.com>
Thomas Preud'homme <thomas.preudho...@arm.com>
* gcc.target/arm/cmse/cmse.exp: Run tests in mainline dir.
* gcc.target/arm/cmse/cmse-9.c: Added some extra tests.
* gcc.target/arm/cmse/baseline/bitfield-4.c: New.
* gcc.target/arm/cmse/baseline/bitfield-5.c: New.
* gcc.target/arm/cmse/baseline/bitfield-6.c: New.
* gcc.target/arm/cmse/baseline/bitfield-7.c: New.
* gcc.target/arm/cmse/baseline/bitfield-8.c: New.
* gcc.target/arm/cmse/baseline/bitfield-9.c: New.
* gcc.target/arm/cmse/baseline/bitfield-and-union-1.c: New.
* gcc.target/arm/cmse/baseline/cmse-11.c: New.
* gcc.target/arm/cmse/baseline/cmse-13.c: New.
* gcc.target/arm/cmse/baseline/cmse-6.c: New.
* gcc/testsuite/gcc.target/arm/cmse/baseline/union-1.c: New.
* gcc/testsuite/gcc.target/arm/cmse/baseline/union-2.c: New.
* gcc.target/arm/cmse/mainline/hard-sp/cmse-13.c: New.
* gcc.target/arm/cmse/mainline/hard-sp/cmse-7.c: New.
* gcc.target/arm/cmse/mainline/hard-sp/cmse-8.c: New.
* gcc.target/arm/cmse/mainline/hard/cmse-13.c: New.
* gcc.target/arm/cmse/mainline/hard/cmse-7.c: New.
* gcc.target/arm/cmse/mainline/hard/cmse-8.c: New.
* gcc.target/arm/cmse/mainline/soft/cmse-13.c: New.
* gcc.target/arm/cmse/mainline/soft/cmse-7.c: New.
* gcc.target/arm/cmse/mainline/soft/cmse-8.c: New.
* gcc.target/arm/cmse/mainline/softfp-sp/cmse-7.c: New.
* gcc.target/arm/cmse/mainline/softfp-sp/cmse-8.c: New.
* gcc.target/arm/cmse/mainline/softfp/cmse-13.c: New.
* gcc.target/arm/cmse/mainline/softfp/cmse-7.c: New.
* gcc.target/arm/cmse/mainline/softfp/cmse-8.c: New.
Updated this patch to correctly clear only the cumulative
exception-status (0-4,7) and the condition code bits (28-31) of the FPSCR.
----
This patch extends support for the ARMv8-M Security Extensions
'cmse_nonsecure_call' to use a new library function
'__gnu_cmse_nonsecure_call'. This library function is responsible for
(without using r0-r3 or d0-d7):
1) saving and clearing all callee-saved registers using the secure stack
2) clearing the LSB of the address passed in r4 and using blxns to
'jump' to it
3) clearing ASPR, including the 'ge bits' if DSP is enabled
4) clearing the cumulative exception-status (0-4, 7) and the condition
bits (28-31) of the FPSCR if using non-soft float-abi
5) restoring callee-saved registers.
The decisions whether to include DSP 'ge bits' clearing and floating
point registers (single/double precision) all depends on the multilib used.
See Section 5.5 of ARM®v8-M Security Extensions
(http://infocenter.arm.com/help/topic/com.arm.doc.ecm0359818/index.html).
*** gcc/ChangeLog ***
2016-07-xx Andre Vieira <andre.simoesdiasvie...@arm.com>
Thomas Preud'homme <thomas.preudho...@arm.com>
* config/arm/arm.c (detect_cmse_nonsecure_call): New.
(cmse_nonsecure_call_clear_caller_saved): New.
(arm_reorg): Use cmse_nonsecure_call_clear_caller_saved.
* config/arm/arm-protos.h (detect_cmse_nonsecure_call): New.
* config/arm/arm.md (call): Handle cmse_nonsecure_entry.
(call_value): Likewise.
(nonsecure_call_internal): New.
(nonsecure_call_value_internal): New.
* config/arm/thumb1.md (*nonsecure_call_reg_thumb1_v5): New.
(*nonsecure_call_value_reg_thumb1_v5): New.
* config/arm/thumb2.md (*nonsecure_call_reg_thumb2): New.
(*nonsecure_call_value_reg_thumb2): New.
* config/arm/unspecs.md (UNSPEC_NONSECURE_MEM): New.
*** libgcc/ChangeLog ***
2016-07-xx Andre Vieira <andre.simoesdiasvie...@arm.com>
Thomas Preud'homme <thomas.preudho...@arm.com>
* config/arm/cmse_nonsecure_call.S: New.
* config/arm/t-arm: Compile cmse_nonsecure_call.S
*** gcc/testsuite/ChangeLog ***
2016-07-xx Andre Vieira <andre.simoesdiasvie...@arm.com>
Thomas Preud'homme <thomas.preudho...@arm.com>
* gcc.target/arm/cmse/cmse.exp: Run tests in mainline dir.
* gcc.target/arm/cmse/cmse-9.c: Added some extra tests.
* gcc.target/arm/cmse/baseline/bitfield-4.c: New.
* gcc.target/arm/cmse/baseline/bitfield-5.c: New.
* gcc.target/arm/cmse/baseline/bitfield-6.c: New.
* gcc.target/arm/cmse/baseline/bitfield-7.c: New.
* gcc.target/arm/cmse/baseline/bitfield-8.c: New.
* gcc.target/arm/cmse/baseline/bitfield-9.c: New.
* gcc.target/arm/cmse/baseline/bitfield-and-union-1.c: New.
* gcc.target/arm/cmse/baseline/cmse-11.c: New.
* gcc.target/arm/cmse/baseline/cmse-13.c: New.
* gcc.target/arm/cmse/baseline/cmse-6.c: New.
* gcc/testsuite/gcc.target/arm/cmse/baseline/union-1.c: New.
* gcc/testsuite/gcc.target/arm/cmse/baseline/union-2.c: New.
* gcc.target/arm/cmse/mainline/hard-sp/cmse-13.c: New.
* gcc.target/arm/cmse/mainline/hard-sp/cmse-7.c: New.
* gcc.target/arm/cmse/mainline/hard-sp/cmse-8.c: New.
* gcc.target/arm/cmse/mainline/hard/cmse-13.c: New.
* gcc.target/arm/cmse/mainline/hard/cmse-7.c: New.
* gcc.target/arm/cmse/mainline/hard/cmse-8.c: New.
* gcc.target/arm/cmse/mainline/soft/cmse-13.c: New.
* gcc.target/arm/cmse/mainline/soft/cmse-7.c: New.
* gcc.target/arm/cmse/mainline/soft/cmse-8.c: New.
* gcc.target/arm/cmse/mainline/softfp-sp/cmse-7.c: New.
* gcc.target/arm/cmse/mainline/softfp-sp/cmse-8.c: New.
* gcc.target/arm/cmse/mainline/softfp/cmse-13.c: New.
* gcc.target/arm/cmse/mainline/softfp/cmse-7.c: New.
* gcc.target/arm/cmse/mainline/softfp/cmse-8.c: New.
Hi,
Rebased previous patch on top of trunk as requested. No changes to
ChangeLog.
Cheers,
Andre
Hi,
Reworked the testcase for compiling without -mcmse to catch the warning
added in 5/7. Also took the opportunity to improve the code in the
cmse_nonsecure_call library wrapper.
Cheers,
Andre
Hi,
Fixed an issue when returning from cmse_nonsecure_call's. The ARMv8-M
Mainline variant was missing a branch back and changed the Baseline
variant to use bx, rather than blx when returning. I also noticed a
sub-optimal sequence for thumb-1 and changed it.
Cheers,
Andre
+static void
+cmse_nonsecure_call_clear_caller_saved (void)
+{
+ basic_block bb;
+
<...>
+ FOREACH_FUNCTION_ARGS (fntype, arg_type, args_iter)
+ {
+ rtx arg_rtx;
+ machine_mode arg_mode = TYPE_MODE (arg_type);
+
+ if (VOID_TYPE_P (arg_type))
+ continue;
+
+ if (!first_param)
+ arm_function_arg_advance (args_so_far, arg_mode, arg_type,
+ true);
+
+ arg_rtx = arm_function_arg (args_so_far, arg_mode, arg_type,
+ true);
+ gcc_assert (REG_P (arg_rtx));
+ to_clear_mask &=
+ ~compute_not_to_clear_mask (arg_type, arg_rtx,
+ REGNO (arg_rtx),
+ padding_bits_to_clear_ptr);
I believe the convention in GCC is to put the "&=" on the next line.
+
+ first_param = false;
+ }
+
+ /* Clear padding bits where needed. */
+ cleared_reg = XEXP (address, 0);
+ reg = gen_rtx_REG (SImode, IP_REGNUM);
+ using_r4 = false;
+ for (regno = 0; regno < NUM_ARG_REGS; regno++)
+ {
Please use regno = R0_REGNUM.
+ if (padding_bits_to_clear[regno] == 0)
+ continue;
+
+ /* If this is a Thumb-1 target copy the address of the function
+ we are calling from 'r4' into 'ip' such that we can use r4 to
+ clear the unused bits in the arguments. */
+ if (TARGET_THUMB1 && !using_r4)
+ {
+ using_r4 = true;
+ reg = cleared_reg;
+ emit_move_insn (gen_rtx_REG (SImode, IP_REGNUM),
+ reg);
+ }
+
+ tmp = GEN_INT ((((~padding_bits_to_clear[regno]) << 16u) >> 16u));
+ emit_move_insn (reg, tmp);
+ /* Also fill the top half of the negated
+ padding_bits_to_clear. */
+ if (((~padding_bits_to_clear[regno]) >> 16) > 0)
+ {
+ tmp = GEN_INT ((~padding_bits_to_clear[regno]) >> 16);
+ emit_insn (gen_rtx_SET (gen_rtx_ZERO_EXTRACT (SImode, reg,
+ GEN_INT (16),
+ GEN_INT (16)),
+ tmp));
+ }
+
+ emit_insn (gen_andsi3 (gen_rtx_REG (SImode, regno),
+ gen_rtx_REG (SImode, regno),
+ reg));
+
+ }
+ if (using_r4)
+ emit_move_insn (cleared_reg,
+ gen_rtx_REG (SImode, IP_REGNUM));
+
+ /* We use right shift and left shift to clear the LSB of the address
+ we jump to instead of using bic, to avoid having to use an extra
+ register on Thumb-1. */
+ tmp = gen_rtx_LSHIFTRT (SImode, cleared_reg, const1_rtx);
+ emit_insn (gen_rtx_SET (cleared_reg, tmp));
+ tmp = gen_rtx_ASHIFT (SImode, cleared_reg, const1_rtx);
+ emit_insn (gen_rtx_SET (cleared_reg, tmp));
+
+ /* Clearing all registers that leak before doing a non-secure
+ call. */
+ for (regno = 0; regno <= maxregno; regno++)
Same here.
+ {
+ if (!(to_clear_mask & (1LL << regno)))
+ continue;
+
+ /* If regno is an even vfp register and its successor is also to
+ be cleared, use vmov. */
+ if (IS_VFP_REGNUM (regno))
+ {
+ if (TARGET_VFP_DOUBLE
+ && VFP_REGNO_OK_FOR_DOUBLE (regno)
+ && to_clear_mask & (1LL << (regno + 1)))
+ emit_move_insn (gen_rtx_REG (DFmode, regno++),
+ CONST1_RTX (DFmode));
+ else
+ emit_move_insn (gen_rtx_REG (SFmode, regno),
+ CONST1_RTX (SFmode));
Why are you writing 1.0 to clear the register? I think you want CONST0_RTX
(DFmode)
and CONST0_RTX (SFmode).
Also, in this function when you iterate from regno = 0 up to some number,
please use
regno = R0_REGNUM (minor nit).
Thanks,
Kyrill