Hi,
I've successfully run Linux in the non-secure world on top of an experimental kernel running on the i.MX53. For the first steps, I've configured the CSU (Central Security Unit) to enable secure and non-secure world to access all peripherals (using CSL registers). Moreover, I've configured the TZIC to route most interrupts as normal interrupts (non FIQ) to the non-secure world. Given that, the Linux guest successfully boots until I can enter a console via serial line.
After that, I've taken away all peripheral access rights from Linux. Step by step, I gave access rights for certain devices to Linux, or emulate others, Linux shouldn't access directly, by using hypervisor calls from the non-secure side. First, everything worked as expected. Reads from registers, Linux isn't allowed to access, result in a data-abort caught by the hypervisor. But now I detected some strange behaviour: When the non-secure Linux tries to write to e.g. the CCM registers, which it isn't allowed to access at all, no data-abort gets raised. A read leads to a data-abort, a write doesn't. The write has no effect on the CCM registers. Its value doesn't get changed. But it also doesn't trigger an exception nor alarm. I've even configured the CSU to forbid access to the CCM at all, whether it is secure or not. Then, when writing from the secure side to the CCM registers I get a data-abort. When doing it from the non-secure side nothing happens. To me this seems to be an odd behaviour, which isn't intended, or is it? Is there any other way I can detect violations of the CSL configuration in the CSU?
Regards
Stefan Kalkowski
已解决! 转到解答。
Hello Stefan,
I cannot tell if the observed behavior is expected or not, but I suggest you to look into the configuration of the AIPSTZ.
That bridge between masters (ARM core, SDMA,...) and slaves (CCM, UART, GPT,...) allows to set the read/write permissions depending on the master that does the request and its access mode (user, supervisor, trusted...).
Regards,
Florent
Hi stefankalkowski,
Did you find a solution to this issue? We are also seeing reads trapping and writes silently failing for all our peripherals marked secure in csu. We would like the writes to trap as well. We are using an IMX53 QSB.
Thanks!
Riju
Hi Rijurekha,
no I did not further investigate. As I already mentioned in other contexts I do not think that using ARM TrustZone / i.MX53 CSU is a good foundation to implement a trap-emulate device virtualization approach. Anyway, did you try to use the interrupts of the CSU? Maybe, they are triggered instead to indicate security violations.
Regards
Stefan
Thanks for your response!
We could finally get a synchronous external abort in secure world for STR
in normal world. The thing is memory type = "device memory" doesn't
guarantee the absence of write buffer, we need "strongly ordered" memory
type.
From ARMv7 architecture manual (page 151-152 in
https://www.dropbox.com/s/ze4r66c4024jkog/DEN0013D_cortex_a_series_PG.pdf?dl=0)
The only difference between Device and Strongly-ordered memory is that:
• A write to Strongly-ordered memory can complete only when it reaches the
peripheral or memory component accessed by the write.
• A write to Device memory is permitted to complete before it reaches the
peripheral or memory component accessed by the write.
Changing pte flags to L_PTE_MT_UNCACHED from L_PTE_MT_DEV_SHARED for the
necessary memory
(http://elixir.free-electrons.com/linux/latest/source/arch/arm/include/asm/pgtable-2level.h),
did the trick.
Thanks!
Riju
Hi,
I can add: if a data barrier (dsm & dsb instruction) is inserted in the code at the point before the write to the device register, a data abort is raised. The curious thing: without the data barrier no data abort gets raised at all. I would understand if the abort is triggered at a later point in time, but it never occurs instead. Can you enlighten me with regard to this behaviour?
Regards
Stefan Kalkowski
Hello Stefan,
I cannot tell if the observed behavior is expected or not, but I suggest you to look into the configuration of the AIPSTZ.
That bridge between masters (ARM core, SDMA,...) and slaves (CCM, UART, GPT,...) allows to set the read/write permissions depending on the master that does the request and its access mode (user, supervisor, trusted...).
Regards,
Florent