2

I have a pretty weird thing I need to do: Access some "secure" instructions for things that don't really need to be done in a secure context. In short: I need to get in to Secure Mode, but not because I want Hardware TPM-ish functionality or anything. I just need access to certain instructions that I wouldn't otherwise have.

We're doing this on Gumstix Overo FireSTORM COMs. It is my understanding these boot securely, but then somewhere (MLO? u-boot?) they switch to non-secure mode, but I could be wrong. The point is that we're certainly doing this from nonsecure (but privileged, see below) mode.

(I authored this question, about direct access to the GHB/BTB of the A8 branch predictor, if you're curious about what I'm looking to do: Write directly to the global history buffer (GHB) or BTB in the branch predictor of a ARM Cortex A8?)

Now, all of this will be done from u-boot (we've got Overo FireSTORM COMs), so luckily I have "privileged" execution. No worries there. And I've looked at other StackOverflow questions, but there doesn't seem to be anything on how, exactly, to get to secure mode. All I really wanna do is access some CP15 registers, and then go back to non-secure mode (and potentially repeat the process).

I've looked into the SMC instruction, but I can't find any documentation on how to appropriately trap the call/where the call goes to/how to set that up, etc.

Is that information anywhere?

To recap, here's what I want to do:

FROM PRIVILEGED EXECUTION: 
Do stuff
Tweak GHB // requires secure execution
Do more stuff
Tweak GHB 
Do more stuff
...
...
...
Do stuff

Any help would CERTAINLY be appreciated!

Thanks to @artlessnoise, I found this file in the u-boot source: /u-boot/arch/arm/cpu/armv7/nonsec_virt.S.

It contains the following code:

/*
* secure monitor handler
* U-boot calls this "software interrupt" in start.S
* This is executed on a "smc" instruction, we use a "smc #0" to switch
* to non-secure state.
* We use only r0 and r1 here, due to constraints in the caller.
*/
   .align  5
_secure_monitor:
   mrc     p15, 0, r1, c1, c1, 0           @ read SCR
   bic     r1, r1, #0x4e                   @ clear IRQ, FIQ, EA, nET bits
   orr     r1, r1, #0x31                   @ enable NS, AW, FW bits

#ifdef CONFIG_ARMV7_VIRT
   mrc     p15, 0, r0, c0, c1, 1           @ read ID_PFR1
   and     r0, r0, #CPUID_ARM_VIRT_MASK    @ mask virtualization bits
   cmp     r0, #(1 << CPUID_ARM_VIRT_SHIFT)
   orreq   r1, r1, #0x100                  @ allow HVC instruction
#endif

   mcr     p15, 0, r1, c1, c1, 0           @ write SCR (with NS bit set)

#ifdef CONFIG_ARMV7_VIRT
   mrceq   p15, 0, r0, c12, c0, 1          @ get MVBAR value
   mcreq   p15, 4, r0, c12, c0, 0          @ write HVBAR
#endif

   movs    pc, lr                          @ return to non-secure SVC

Presumably if I modified the mask for the mcr p15 instruction, I could simply "turn off" the move to nonsecure mode. This will probably kill u-boot, however.

So the question is, then: How do I set the appropriate vector so when I make the SMC call, I jump back into secure mode, and am able to do my GHB/BTB tinkering?

Any other help is appreciated!

Community
  • 1
  • 1
user770901
  • 414
  • 1
  • 4
  • 15
  • 1
    Is any of your code ever in **secure** mode, or does a ROM boot loader put you in **normal** mode? You need `mcr p15, 0, r0, c12, c0, 1` which will set the *monitor vector table* to use the `smc` instruction. The *tweak GHB* can be done in the `smc` call. However, you can only access the MVBAR from secure mode. If you are never in *secure*, then you can never get there. – artless noise Sep 25 '14 at 17:48
  • 1
    Thanks for the reply, @artlessnoise! I edited the question with a little more background. We're starting from non-secure (but privileged) mode. I know the SMC call can be used to access secure mode (right?). If I'm reading your response correctly, the problem is that we can't ever set the location of where the SMC call will end up [unless we're setting it in secure mode]. Is that correct? So there's no way of doing what we're trying to do from strictly a NS mode? – user770901 Sep 25 '14 at 21:26
  • 1
    That is correct. You need to modify the *u-boot* and/or the ROM loader (MLO?) code or execution path so that you get some code in the **privileged secure world**; the `mcr` instruction to set the MVBAR is the same as the other GHB/BTB; it is only accessible in secure world. To do this from your current mode, you are asking for a TZ exploit on this platform. TZ is designed so you can't do this. – artless noise Sep 26 '14 at 15:04
  • Thanks for the tip, @artlessnoise. With your help, I've found -- I think -- where u-boot makes the jump into NS mode. I've updated the original question, so future generations can benefit. The remaining issue seems to be how to set the appropriate vector so when I make the SMC call -- much later in u-boot's execution -- I a). jump back into secure mode and b). can do my tinkering with the GHB. Any ideas there? – user770901 Sep 26 '14 at 19:50
  • I think you have the wrong file. That is for a Cortex-A15. See: *include/configs/vexpress_ca15_tc2.h*, I don't think the Cortex-A8 boots this way. – artless noise Sep 26 '14 at 20:06
  • @artlessnoise You are probably correct. It doesn't look like that file is compiled in u-boot. But I'm not sure how the file you suggest helps either. It's possible it's actually MLO that sets the machine into NS state, or maybe it is buried someplace in u-boot. Either way, I'm still having a hard time figuring out how to actually get in to the secure mode. =[ – user770901 Sep 30 '14 at 21:36

1 Answers1

1

The DM3730 on the Gumstix is a GP (general purpose) device, which means it has TrustZone disabled. There's no way you can get in to it.

See https://stackoverflow.com/a/8028948/6839

Community
  • 1
  • 1
Tom Hennen
  • 4,746
  • 7
  • 34
  • 45