Discussion:
Query regarding extracting instruction which caused a data-abort exception
Abhishek Kumar
2017-06-13 09:17:02 UTC
Permalink
Hello
I am trying to modify genode trustzone. I want to read the instruction
which lead to data abort exception in normal world, in the `dump` function
in tz_vmm. I have value of all the registers through `_state` register. We
tried with `_state->ip`. On converting 16 bits stored at the address
pointed by _state->ip, we got ARM Thumb instruction:

STRH R0, [R0, #6]
But the value (R0) + 6, doesn't match dfar. We're not sure if _state->ip is
the register to go with. We tried with _state->mode[2].lr which is lr_abt
register. But the address stored in lr_abt, lr_abt-16, lr_abt-32 all have
0s.

Which is right register to get the address of the instruction which caused
the data-abort exception?

Thanks
Abhishek
Stefan Kalkowski
2017-06-14 12:24:41 UTC
Permalink
Hello,
Post by Abhishek Kumar
Hello
I am trying to modify genode trustzone. I want to read the instruction
which lead to data abort exception in normal world, in the `dump`
function in tz_vmm. I have value of all the registers through `_state`
register. We tried with `_state->ip`. On converting 16 bits stored at
STRH R0, [R0, #6]
But the value (R0) + 6, doesn't match dfar. We're not sure if _state->ip
is the register to go with. We tried with _state->mode[2].lr which is
lr_abt register. But the address stored in lr_abt, lr_abt-16, lr_abt-32
all have 0s.
Which is right register to get the address of the instruction which
caused the data-abort exception?
As long as you get an synchronous data-abort from the normal world,
reading the current instruction pointer of the 'state' structure is
perfectly fine. The mode-specific lr register is useful for the handling
of MMU faults within the "normal" world itself. They are not modified,
as long as the "normal" world MMU can resolve an access, but some bus
resp. CSU is answering that the access is not allowed. This will not
change the "normal" world register set.

On the other hand, in general a bus fault triggered by unallowed access
of the "normal" world does not necessarily mean a synchronous
data-abort, although on i.MX53 I only observed those. In general, it can
also provoke an asynchronous external data-abort, which means that the
instruction pointer is not necessarily pointing to the instruction that
triggered the fault.

Moreover, looking at the "normal" world's memory from the secure side is
troublesome. Because the normal and secure world's memory view is not
cache-coherent. Cache entries are always tagged by the NS bit. That
means you have to take care to flush caches yourself. If you want to
debug instructions, you should instead look at the Linux binary itself
and not into the memory on the secure side. To me it looks strange that
you identify a Thumb instruction in the kernel here.

Btw. these kind of TrustZone/i.MX53 questions were asked repeatedly in
the past, and are mostly answered in our TrustZone report:

https://genode.org/documentation/articles/trustzone

and in the discussions of our mailing list:

https://sourceforge.net/p/genode/mailman/search/?q=trustzone

Regards
Stefan
Post by Abhishek Kumar
Thanks
Abhishek
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs

https://github.com/skalk · http://genode.org/
r***@mpi-sws.org
2017-06-14 12:40:49 UTC
Permalink
Thanks Stefan!

We are actually trying to do device emulation in the secure world genode,
for peripherals marked as secure (UART or ESDHC) in csu_config.h. We got
encouraged by the following discussion at
http://genode.org/documentation/articles/trustzone

==========================================================================
The basic idea of emulating device access is to let the hypervisor pass
control to the VMM as soon as the non-secure OS accesses an address
outside the permitted physical address ranges. The VMM can then inspect
the address in question and the program counter of the non-secure OS that
raised the access violation. Given the program counter value, the VMM can
fetch and decode the faulting instruction and emulate it in software.
Because ARM is a RISC architecture, the instruction decoding is rather
simple. The instruction in question can only be a load or a store
instruction. No other instruction would raise an access fault. For read
operations, the VMM would provide the result of the operation by changing
the corresponding entry of the VM state structure.

That said, we found that the trap-and-execute emulation model is not
possible to implement with the TrustZone protection mechanisms in general.
Dependent on the concrete platform, the CPU will not immediately enter the
hypervisor when the fault occurs but attempts to perform the bus
transaction. This transaction will trigger an external data abort. This
abort is similar to a device interrupt. It principally raises an exception
(so the violation can be detected) but not always immediately. Therefore,
there is no way to uniquely reconstruct what happened in between the
invalid access and the reception of the external abort exception in the
hypervisor. Neither can the hypervisor recover the non-secure world to a
useful state.

A noteworthy advantage of the CSU compared to the ARM TZ protection
controller within the ARM Cortex A9 reference board is the way of how
access violations are handled. As stated in Device emulation, the ARM TZ
protection controller responds to invalid accesses with an asynchronous
external abort exception, similar to a device interrupt. Upon the
execution of an offending instruction, the TZ protection controller
detects the violation, yet the CPU would continue the execution of further
instructions until the flagged violation eventually reaches the CPU,
triggering an external abort exception. This scheme effectively rules out
any attempt to emulate device accesses. In contrast, the i.MX CSU responds
to access violations by synchronously yielding control to the exception
handler. So when such an exception occurs, the offending instruction can
be determined and emulated in software. However, even though device
emulation using the CSU is principally possible, we haven't investigated
this opportunity further.
===========================================================================

We want to read the instruction faulting in NW linux in tz_vmm,
disassemble it, emulate it in genode code and restart the VM at the next
instruction of the normal world. Do you think this is feasible, or your
comments about "synchronous data abort in IMX53 vs. asynchronous aborts in
Versatile Express" don't hold always?

Thanks!
Riju
Post by Stefan Kalkowski
Hello,
Post by Abhishek Kumar
Hello
I am trying to modify genode trustzone. I want to read the instruction
which lead to data abort exception in normal world, in the `dump`
function in tz_vmm. I have value of all the registers through `_state`
register. We tried with `_state->ip`. On converting 16 bits stored at
STRH R0, [R0, #6]
But the value (R0) + 6, doesn't match dfar. We're not sure if _state->ip
is the register to go with. We tried with _state->mode[2].lr which is
lr_abt register. But the address stored in lr_abt, lr_abt-16, lr_abt-32
all have 0s.
Which is right register to get the address of the instruction which
caused the data-abort exception?
As long as you get an synchronous data-abort from the normal world,
reading the current instruction pointer of the 'state' structure is
perfectly fine. The mode-specific lr register is useful for the handling
of MMU faults within the "normal" world itself. They are not modified,
as long as the "normal" world MMU can resolve an access, but some bus
resp. CSU is answering that the access is not allowed. This will not
change the "normal" world register set.
On the other hand, in general a bus fault triggered by unallowed access
of the "normal" world does not necessarily mean a synchronous
data-abort, although on i.MX53 I only observed those. In general, it can
also provoke an asynchronous external data-abort, which means that the
instruction pointer is not necessarily pointing to the instruction that
triggered the fault.
Moreover, looking at the "normal" world's memory from the secure side is
troublesome. Because the normal and secure world's memory view is not
cache-coherent. Cache entries are always tagged by the NS bit. That
means you have to take care to flush caches yourself. If you want to
debug instructions, you should instead look at the Linux binary itself
and not into the memory on the secure side. To me it looks strange that
you identify a Thumb instruction in the kernel here.
Btw. these kind of TrustZone/i.MX53 questions were asked repeatedly in
https://genode.org/documentation/articles/trustzone
https://sourceforge.net/p/genode/mailman/search/?q=trustzone
Regards
Stefan
Post by Abhishek Kumar
Thanks
Abhishek
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs
https://github.com/skalk · http://genode.org/
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
r***@mpi-sws.org
2017-06-14 12:48:18 UTC
Permalink
Interestingly, the DFAR contains an UART address when UART is made secure
in csu_config.h and an eSDHC address when eSDHC is made secure in
csu_config.h. But this might still be a case of asynchronous abort, only
that DFAR is still pointing to the correct address where the instruction
faulted (not more data aborts have occurred since then), but the other
registers have changed because of the asynchronous nature of the abort.

How can we know if the abort is asynchronous vs. synchronous? Is an lr_abt
with all 0's already a clear indication that this is asynchronous, and
there is no hope for device emulation?

Thanks!
Riju
Post by r***@mpi-sws.org
Thanks Stefan!
We are actually trying to do device emulation in the secure world genode,
for peripherals marked as secure (UART or ESDHC) in csu_config.h. We got
encouraged by the following discussion at
http://genode.org/documentation/articles/trustzone
==========================================================================
The basic idea of emulating device access is to let the hypervisor pass
control to the VMM as soon as the non-secure OS accesses an address
outside the permitted physical address ranges. The VMM can then inspect
the address in question and the program counter of the non-secure OS that
raised the access violation. Given the program counter value, the VMM can
fetch and decode the faulting instruction and emulate it in software.
Because ARM is a RISC architecture, the instruction decoding is rather
simple. The instruction in question can only be a load or a store
instruction. No other instruction would raise an access fault. For read
operations, the VMM would provide the result of the operation by changing
the corresponding entry of the VM state structure.
That said, we found that the trap-and-execute emulation model is not
possible to implement with the TrustZone protection mechanisms in general.
Dependent on the concrete platform, the CPU will not immediately enter the
hypervisor when the fault occurs but attempts to perform the bus
transaction. This transaction will trigger an external data abort. This
abort is similar to a device interrupt. It principally raises an exception
(so the violation can be detected) but not always immediately. Therefore,
there is no way to uniquely reconstruct what happened in between the
invalid access and the reception of the external abort exception in the
hypervisor. Neither can the hypervisor recover the non-secure world to a
useful state.
A noteworthy advantage of the CSU compared to the ARM TZ protection
controller within the ARM Cortex A9 reference board is the way of how
access violations are handled. As stated in Device emulation, the ARM TZ
protection controller responds to invalid accesses with an asynchronous
external abort exception, similar to a device interrupt. Upon the
execution of an offending instruction, the TZ protection controller
detects the violation, yet the CPU would continue the execution of further
instructions until the flagged violation eventually reaches the CPU,
triggering an external abort exception. This scheme effectively rules out
any attempt to emulate device accesses. In contrast, the i.MX CSU responds
to access violations by synchronously yielding control to the exception
handler. So when such an exception occurs, the offending instruction can
be determined and emulated in software. However, even though device
emulation using the CSU is principally possible, we haven't investigated
this opportunity further.
===========================================================================
We want to read the instruction faulting in NW linux in tz_vmm,
disassemble it, emulate it in genode code and restart the VM at the next
instruction of the normal world. Do you think this is feasible, or your
comments about "synchronous data abort in IMX53 vs. asynchronous aborts in
Versatile Express" don't hold always?
Thanks!
Riju
Post by Stefan Kalkowski
Hello,
Post by Abhishek Kumar
Hello
I am trying to modify genode trustzone. I want to read the instruction
which lead to data abort exception in normal world, in the `dump`
function in tz_vmm. I have value of all the registers through `_state`
register. We tried with `_state->ip`. On converting 16 bits stored at
STRH R0, [R0, #6]
But the value (R0) + 6, doesn't match dfar. We're not sure if _state->ip
is the register to go with. We tried with _state->mode[2].lr which is
lr_abt register. But the address stored in lr_abt, lr_abt-16, lr_abt-32
all have 0s.
Which is right register to get the address of the instruction which
caused the data-abort exception?
As long as you get an synchronous data-abort from the normal world,
reading the current instruction pointer of the 'state' structure is
perfectly fine. The mode-specific lr register is useful for the handling
of MMU faults within the "normal" world itself. They are not modified,
as long as the "normal" world MMU can resolve an access, but some bus
resp. CSU is answering that the access is not allowed. This will not
change the "normal" world register set.
On the other hand, in general a bus fault triggered by unallowed access
of the "normal" world does not necessarily mean a synchronous
data-abort, although on i.MX53 I only observed those. In general, it can
also provoke an asynchronous external data-abort, which means that the
instruction pointer is not necessarily pointing to the instruction that
triggered the fault.
Moreover, looking at the "normal" world's memory from the secure side is
troublesome. Because the normal and secure world's memory view is not
cache-coherent. Cache entries are always tagged by the NS bit. That
means you have to take care to flush caches yourself. If you want to
debug instructions, you should instead look at the Linux binary itself
and not into the memory on the secure side. To me it looks strange that
you identify a Thumb instruction in the kernel here.
Btw. these kind of TrustZone/i.MX53 questions were asked repeatedly in
https://genode.org/documentation/articles/trustzone
https://sourceforge.net/p/genode/mailman/search/?q=trustzone
Regards
Stefan
Post by Abhishek Kumar
Thanks
Abhishek
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs
https://github.com/skalk · http://genode.org/
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
Stefan Kalkowski
2017-06-14 13:12:17 UTC
Permalink
Hi,
Post by r***@mpi-sws.org
Interestingly, the DFAR contains an UART address when UART is made secure
in csu_config.h and an eSDHC address when eSDHC is made secure in
csu_config.h. But this might still be a case of asynchronous abort, only
that DFAR is still pointing to the correct address where the instruction
faulted (not more data aborts have occurred since then), but the other
registers have changed because of the asynchronous nature of the abort.
How can we know if the abort is asynchronous vs. synchronous? Is an lr_abt
with all 0's already a clear indication that this is asynchronous, and
there is no hope for device emulation?
I would not generalize or depend on anything related to the "exception"
case, because TrustZone is not meant as a virtualization solution.
Normally, you should just turn off the device or reboot in emergency case.

Having said this: Obviously, in case of the i.MX53 the secure world's
DFAR is updated to the faulting address if the "normal" world provokes a
security violation "on the bus". Therefore, I could imagine the DFSR
register is updated too. Normally, this register contains information
about the type of data-fault. Have a look at:

repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc

where the DFAR is read and set to the VM state structure, and you could
print it, or write it to an arbitrary register for debugging purposes.

Regards
Stefan
Post by r***@mpi-sws.org
Thanks!
Riju
Post by r***@mpi-sws.org
Thanks Stefan!
We are actually trying to do device emulation in the secure world genode,
for peripherals marked as secure (UART or ESDHC) in csu_config.h. We got
encouraged by the following discussion at
http://genode.org/documentation/articles/trustzone
==========================================================================
The basic idea of emulating device access is to let the hypervisor pass
control to the VMM as soon as the non-secure OS accesses an address
outside the permitted physical address ranges. The VMM can then inspect
the address in question and the program counter of the non-secure OS that
raised the access violation. Given the program counter value, the VMM can
fetch and decode the faulting instruction and emulate it in software.
Because ARM is a RISC architecture, the instruction decoding is rather
simple. The instruction in question can only be a load or a store
instruction. No other instruction would raise an access fault. For read
operations, the VMM would provide the result of the operation by changing
the corresponding entry of the VM state structure.
That said, we found that the trap-and-execute emulation model is not
possible to implement with the TrustZone protection mechanisms in general.
Dependent on the concrete platform, the CPU will not immediately enter the
hypervisor when the fault occurs but attempts to perform the bus
transaction. This transaction will trigger an external data abort. This
abort is similar to a device interrupt. It principally raises an exception
(so the violation can be detected) but not always immediately. Therefore,
there is no way to uniquely reconstruct what happened in between the
invalid access and the reception of the external abort exception in the
hypervisor. Neither can the hypervisor recover the non-secure world to a
useful state.
A noteworthy advantage of the CSU compared to the ARM TZ protection
controller within the ARM Cortex A9 reference board is the way of how
access violations are handled. As stated in Device emulation, the ARM TZ
protection controller responds to invalid accesses with an asynchronous
external abort exception, similar to a device interrupt. Upon the
execution of an offending instruction, the TZ protection controller
detects the violation, yet the CPU would continue the execution of further
instructions until the flagged violation eventually reaches the CPU,
triggering an external abort exception. This scheme effectively rules out
any attempt to emulate device accesses. In contrast, the i.MX CSU responds
to access violations by synchronously yielding control to the exception
handler. So when such an exception occurs, the offending instruction can
be determined and emulated in software. However, even though device
emulation using the CSU is principally possible, we haven't investigated
this opportunity further.
===========================================================================
We want to read the instruction faulting in NW linux in tz_vmm,
disassemble it, emulate it in genode code and restart the VM at the next
instruction of the normal world. Do you think this is feasible, or your
comments about "synchronous data abort in IMX53 vs. asynchronous aborts in
Versatile Express" don't hold always?
Thanks!
Riju
Post by Stefan Kalkowski
Hello,
Post by Abhishek Kumar
Hello
I am trying to modify genode trustzone. I want to read the instruction
which lead to data abort exception in normal world, in the `dump`
function in tz_vmm. I have value of all the registers through `_state`
register. We tried with `_state->ip`. On converting 16 bits stored at
STRH R0, [R0, #6]
But the value (R0) + 6, doesn't match dfar. We're not sure if _state->ip
is the register to go with. We tried with _state->mode[2].lr which is
lr_abt register. But the address stored in lr_abt, lr_abt-16, lr_abt-32
all have 0s.
Which is right register to get the address of the instruction which
caused the data-abort exception?
As long as you get an synchronous data-abort from the normal world,
reading the current instruction pointer of the 'state' structure is
perfectly fine. The mode-specific lr register is useful for the handling
of MMU faults within the "normal" world itself. They are not modified,
as long as the "normal" world MMU can resolve an access, but some bus
resp. CSU is answering that the access is not allowed. This will not
change the "normal" world register set.
On the other hand, in general a bus fault triggered by unallowed access
of the "normal" world does not necessarily mean a synchronous
data-abort, although on i.MX53 I only observed those. In general, it can
also provoke an asynchronous external data-abort, which means that the
instruction pointer is not necessarily pointing to the instruction that
triggered the fault.
Moreover, looking at the "normal" world's memory from the secure side is
troublesome. Because the normal and secure world's memory view is not
cache-coherent. Cache entries are always tagged by the NS bit. That
means you have to take care to flush caches yourself. If you want to
debug instructions, you should instead look at the Linux binary itself
and not into the memory on the secure side. To me it looks strange that
you identify a Thumb instruction in the kernel here.
Btw. these kind of TrustZone/i.MX53 questions were asked repeatedly in
https://genode.org/documentation/articles/trustzone
https://sourceforge.net/p/genode/mailman/search/?q=trustzone
Regards
Stefan
Post by Abhishek Kumar
Thanks
Abhishek
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs
https://github.com/skalk · http://genode.org/
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs

https://github.com/skalk · http://genode.org/
Stefan Kalkowski
2017-06-14 12:55:05 UTC
Permalink
Hi,
Post by r***@mpi-sws.org
We want to read the instruction faulting in NW linux in tz_vmm,
disassemble it, emulate it in genode code and restart the VM at the next
instruction of the normal world. Do you think this is feasible, or your
comments about "synchronous data abort in IMX53 vs. asynchronous aborts in
Versatile Express" don't hold always?
As I said in my previous mail: I only observed synchronous data-abort on
i.MX53. So I think this is not the show-stopper.

Anyway please read my whole mail especially the section regarding the
caching issues. Being in your position, I would first correlate the
instruction pointer values with your Linux binary, e.g. using objdump,
before you start to do instruction decoding on cache-incoherent memory.

Regards
Stefan
Post by r***@mpi-sws.org
Thanks!
Riju
Post by Stefan Kalkowski
Hello,
Post by Abhishek Kumar
Hello
I am trying to modify genode trustzone. I want to read the instruction
which lead to data abort exception in normal world, in the `dump`
function in tz_vmm. I have value of all the registers through `_state`
register. We tried with `_state->ip`. On converting 16 bits stored at
STRH R0, [R0, #6]
But the value (R0) + 6, doesn't match dfar. We're not sure if _state->ip
is the register to go with. We tried with _state->mode[2].lr which is
lr_abt register. But the address stored in lr_abt, lr_abt-16, lr_abt-32
all have 0s.
Which is right register to get the address of the instruction which
caused the data-abort exception?
As long as you get an synchronous data-abort from the normal world,
reading the current instruction pointer of the 'state' structure is
perfectly fine. The mode-specific lr register is useful for the handling
of MMU faults within the "normal" world itself. They are not modified,
as long as the "normal" world MMU can resolve an access, but some bus
resp. CSU is answering that the access is not allowed. This will not
change the "normal" world register set.
On the other hand, in general a bus fault triggered by unallowed access
of the "normal" world does not necessarily mean a synchronous
data-abort, although on i.MX53 I only observed those. In general, it can
also provoke an asynchronous external data-abort, which means that the
instruction pointer is not necessarily pointing to the instruction that
triggered the fault.
Moreover, looking at the "normal" world's memory from the secure side is
troublesome. Because the normal and secure world's memory view is not
cache-coherent. Cache entries are always tagged by the NS bit. That
means you have to take care to flush caches yourself. If you want to
debug instructions, you should instead look at the Linux binary itself
and not into the memory on the secure side. To me it looks strange that
you identify a Thumb instruction in the kernel here.
Btw. these kind of TrustZone/i.MX53 questions were asked repeatedly in
https://genode.org/documentation/articles/trustzone
https://sourceforge.net/p/genode/mailman/search/?q=trustzone
Regards
Stefan
Post by Abhishek Kumar
Thanks
Abhishek
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs
https://github.com/skalk · http://genode.org/
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs

https://github.com/skalk · http://genode.org/
r***@mpi-sws.org
2017-06-14 12:58:01 UTC
Permalink
Thanks a lot Stefan, Will correlate with the linux binary.

Riju
Post by Stefan Kalkowski
Hi,
Post by r***@mpi-sws.org
We want to read the instruction faulting in NW linux in tz_vmm,
disassemble it, emulate it in genode code and restart the VM at the next
instruction of the normal world. Do you think this is feasible, or your
comments about "synchronous data abort in IMX53 vs. asynchronous aborts in
Versatile Express" don't hold always?
As I said in my previous mail: I only observed synchronous data-abort on
i.MX53. So I think this is not the show-stopper.
Anyway please read my whole mail especially the section regarding the
caching issues. Being in your position, I would first correlate the
instruction pointer values with your Linux binary, e.g. using objdump,
before you start to do instruction decoding on cache-incoherent memory.
Regards
Stefan
Post by r***@mpi-sws.org
Thanks!
Riju
Post by Stefan Kalkowski
Hello,
Post by Abhishek Kumar
Hello
I am trying to modify genode trustzone. I want to read the instruction
which lead to data abort exception in normal world, in the `dump`
function in tz_vmm. I have value of all the registers through `_state`
register. We tried with `_state->ip`. On converting 16 bits stored at
STRH R0, [R0, #6]
But the value (R0) + 6, doesn't match dfar. We're not sure if _state->ip
is the register to go with. We tried with _state->mode[2].lr which is
lr_abt register. But the address stored in lr_abt, lr_abt-16, lr_abt-32
all have 0s.
Which is right register to get the address of the instruction which
caused the data-abort exception?
As long as you get an synchronous data-abort from the normal world,
reading the current instruction pointer of the 'state' structure is
perfectly fine. The mode-specific lr register is useful for the handling
of MMU faults within the "normal" world itself. They are not modified,
as long as the "normal" world MMU can resolve an access, but some bus
resp. CSU is answering that the access is not allowed. This will not
change the "normal" world register set.
On the other hand, in general a bus fault triggered by unallowed access
of the "normal" world does not necessarily mean a synchronous
data-abort, although on i.MX53 I only observed those. In general, it can
also provoke an asynchronous external data-abort, which means that the
instruction pointer is not necessarily pointing to the instruction that
triggered the fault.
Moreover, looking at the "normal" world's memory from the secure side is
troublesome. Because the normal and secure world's memory view is not
cache-coherent. Cache entries are always tagged by the NS bit. That
means you have to take care to flush caches yourself. If you want to
debug instructions, you should instead look at the Linux binary itself
and not into the memory on the secure side. To me it looks strange that
you identify a Thumb instruction in the kernel here.
Btw. these kind of TrustZone/i.MX53 questions were asked repeatedly in
https://genode.org/documentation/articles/trustzone
https://sourceforge.net/p/genode/mailman/search/?q=trustzone
Regards
Stefan
Post by Abhishek Kumar
Thanks
Abhishek
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs
https://github.com/skalk · http://genode.org/
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs
https://github.com/skalk · http://genode.org/
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
Abhishek Kumar
2017-06-14 13:15:01 UTC
Permalink
Hello Stefan
Thanks for your reply. I have a quick clarification to ask for. As you
mentioned about problems with cache-incoherent memory. What we are trying
to read is in code segment, I don't see how it can be changed. Since it is
not changing cache coherency should not be an issue, this is my
understanding. Can you please help me see where I might be wrong?

Thanks
Abhishek
Post by r***@mpi-sws.org
Thanks a lot Stefan, Will correlate with the linux binary.
Riju
Post by Stefan Kalkowski
Hi,
Post by r***@mpi-sws.org
We want to read the instruction faulting in NW linux in tz_vmm,
disassemble it, emulate it in genode code and restart the VM at the next
instruction of the normal world. Do you think this is feasible, or your
comments about "synchronous data abort in IMX53 vs. asynchronous aborts in
Versatile Express" don't hold always?
As I said in my previous mail: I only observed synchronous data-abort on
i.MX53. So I think this is not the show-stopper.
Anyway please read my whole mail especially the section regarding the
caching issues. Being in your position, I would first correlate the
instruction pointer values with your Linux binary, e.g. using objdump,
before you start to do instruction decoding on cache-incoherent memory.
Regards
Stefan
Post by r***@mpi-sws.org
Thanks!
Riju
Post by Stefan Kalkowski
Hello,
Post by Abhishek Kumar
Hello
I am trying to modify genode trustzone. I want to read the instruction
which lead to data abort exception in normal world, in the `dump`
function in tz_vmm. I have value of all the registers through `_state`
register. We tried with `_state->ip`. On converting 16 bits stored at
STRH R0, [R0, #6]
But the value (R0) + 6, doesn't match dfar. We're not sure if _state->ip
is the register to go with. We tried with _state->mode[2].lr which is
lr_abt register. But the address stored in lr_abt, lr_abt-16, lr_abt-32
all have 0s.
Which is right register to get the address of the instruction which
caused the data-abort exception?
As long as you get an synchronous data-abort from the normal world,
reading the current instruction pointer of the 'state' structure is
perfectly fine. The mode-specific lr register is useful for the handling
of MMU faults within the "normal" world itself. They are not modified,
as long as the "normal" world MMU can resolve an access, but some bus
resp. CSU is answering that the access is not allowed. This will not
change the "normal" world register set.
On the other hand, in general a bus fault triggered by unallowed access
of the "normal" world does not necessarily mean a synchronous
data-abort, although on i.MX53 I only observed those. In general, it can
also provoke an asynchronous external data-abort, which means that the
instruction pointer is not necessarily pointing to the instruction that
triggered the fault.
Moreover, looking at the "normal" world's memory from the secure side is
troublesome. Because the normal and secure world's memory view is not
cache-coherent. Cache entries are always tagged by the NS bit. That
means you have to take care to flush caches yourself. If you want to
debug instructions, you should instead look at the Linux binary itself
and not into the memory on the secure side. To me it looks strange that
you identify a Thumb instruction in the kernel here.
Btw. these kind of TrustZone/i.MX53 questions were asked repeatedly in
https://genode.org/documentation/articles/trustzone
https://sourceforge.net/p/genode/mailman/search/?q=trustzone
Regards
Stefan
Post by Abhishek Kumar
Thanks
Abhishek
------------------------------------------------------------
------------------
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Post by Abhishek Kumar
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs
https://github.com/skalk · http://genode.org/
------------------------------------------------------------
------------------
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
------------------------------------------------------------
------------------
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs
https://github.com/skalk · http://genode.org/
------------------------------------------------------------
------------------
Post by Stefan Kalkowski
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
------------------------------------------------------------
------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
r***@mpi-sws.org
2017-06-14 13:36:24 UTC
Permalink
Follow up question:

At https://sourceforge.net/p/genode/mailman/message/34685275/, you said
========================================================================
In the tz_vmm, the whole non-secure RAM is mapped as IOMEM [4], which is
- using ARM-speak - tagged as "Device Memory" and thus non-cached. So,
yes, the tz_vmm must not flush caches as it should always use these
non-cached mappings.
========================================================================

So this particular physical address used by linux UART code is non-cached
in genode? So why should cache-incoherence be an issue in tz_vmm?

Thanks!
Riju
Post by Abhishek Kumar
Hello Stefan
Thanks for your reply. I have a quick clarification to ask for. As you
mentioned about problems with cache-incoherent memory. What we are trying
to read is in code segment, I don't see how it can be changed. Since it is
not changing cache coherency should not be an issue, this is my
understanding. Can you please help me see where I might be wrong?
Thanks
Abhishek
Post by r***@mpi-sws.org
Thanks a lot Stefan, Will correlate with the linux binary.
Riju
Post by Stefan Kalkowski
Hi,
Post by r***@mpi-sws.org
We want to read the instruction faulting in NW linux in tz_vmm,
disassemble it, emulate it in genode code and restart the VM at the
next
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
instruction of the normal world. Do you think this is feasible, or
your
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
comments about "synchronous data abort in IMX53 vs. asynchronous
aborts
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
in
Versatile Express" don't hold always?
As I said in my previous mail: I only observed synchronous data-abort
on
Post by Stefan Kalkowski
i.MX53. So I think this is not the show-stopper.
Anyway please read my whole mail especially the section regarding the
caching issues. Being in your position, I would first correlate the
instruction pointer values with your Linux binary, e.g. using objdump,
before you start to do instruction decoding on cache-incoherent
memory.
Post by Stefan Kalkowski
Regards
Stefan
Post by r***@mpi-sws.org
Thanks!
Riju
Post by Stefan Kalkowski
Hello,
Post by Abhishek Kumar
Hello
I am trying to modify genode trustzone. I want to read the
instruction
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Post by Abhishek Kumar
which lead to data abort exception in normal world, in the `dump`
function in tz_vmm. I have value of all the registers through
`_state`
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Post by Abhishek Kumar
register. We tried with `_state->ip`. On converting 16 bits stored
at
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Post by Abhishek Kumar
STRH R0, [R0, #6]
But the value (R0) + 6, doesn't match dfar. We're not sure if _state->ip
is the register to go with. We tried with _state->mode[2].lr which
is
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Post by Abhishek Kumar
lr_abt register. But the address stored in lr_abt, lr_abt-16, lr_abt-32
all have 0s.
Which is right register to get the address of the instruction which
caused the data-abort exception?
As long as you get an synchronous data-abort from the normal world,
reading the current instruction pointer of the 'state' structure is
perfectly fine. The mode-specific lr register is useful for the handling
of MMU faults within the "normal" world itself. They are not
modified,
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
as long as the "normal" world MMU can resolve an access, but some
bus
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
resp. CSU is answering that the access is not allowed. This will not
change the "normal" world register set.
On the other hand, in general a bus fault triggered by unallowed
access
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
of the "normal" world does not necessarily mean a synchronous
data-abort, although on i.MX53 I only observed those. In general, it can
also provoke an asynchronous external data-abort, which means that
the
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
instruction pointer is not necessarily pointing to the instruction
that
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
triggered the fault.
Moreover, looking at the "normal" world's memory from the secure
side
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
is
troublesome. Because the normal and secure world's memory view is
not
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
cache-coherent. Cache entries are always tagged by the NS bit. That
means you have to take care to flush caches yourself. If you want to
debug instructions, you should instead look at the Linux binary
itself
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
and not into the memory on the secure side. To me it looks strange
that
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
you identify a Thumb instruction in the kernel here.
Btw. these kind of TrustZone/i.MX53 questions were asked repeatedly
in
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
https://genode.org/documentation/articles/trustzone
https://sourceforge.net/p/genode/mailman/search/?q=trustzone
Regards
Stefan
Post by Abhishek Kumar
Thanks
Abhishek
------------------------------------------------------------
------------------
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Post by Abhishek Kumar
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs
https://github.com/skalk · http://genode.org/
------------------------------------------------------------
------------------
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
------------------------------------------------------------
------------------
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs
https://github.com/skalk · http://genode.org/
------------------------------------------------------------
------------------
Post by Stefan Kalkowski
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
------------------------------------------------------------
------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org!
http://sdm.link/slashdot_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
Stefan Kalkowski
2017-06-15 06:19:07 UTC
Permalink
Post by r***@mpi-sws.org
At https://sourceforge.net/p/genode/mailman/message/34685275/, you said
========================================================================
In the tz_vmm, the whole non-secure RAM is mapped as IOMEM [4], which is
- using ARM-speak - tagged as "Device Memory" and thus non-cached. So,
yes, the tz_vmm must not flush caches as it should always use these
non-cached mappings.
========================================================================
So this particular physical address used by linux UART code is non-cached
in genode? So why should cache-incoherence be an issue in tz_vmm?
As long as it is mapped uncached in the secure world *and* the normal
world, cache-coherency is not an issue. As far as I understood you
correctly, you tried to decode instructions within the Linux kernel's
text segment? I bet the Linux kernel maps it as cached memory.

Regards
Stefan
Post by r***@mpi-sws.org
Thanks!
Riju
Post by Abhishek Kumar
Hello Stefan
Thanks for your reply. I have a quick clarification to ask for. As you
mentioned about problems with cache-incoherent memory. What we are trying
to read is in code segment, I don't see how it can be changed. Since it is
not changing cache coherency should not be an issue, this is my
understanding. Can you please help me see where I might be wrong?
Thanks
Abhishek
Post by r***@mpi-sws.org
Thanks a lot Stefan, Will correlate with the linux binary.
Riju
Post by Stefan Kalkowski
Hi,
Post by r***@mpi-sws.org
We want to read the instruction faulting in NW linux in tz_vmm,
disassemble it, emulate it in genode code and restart the VM at the
next
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
instruction of the normal world. Do you think this is feasible, or
your
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
comments about "synchronous data abort in IMX53 vs. asynchronous
aborts
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
in
Versatile Express" don't hold always?
As I said in my previous mail: I only observed synchronous data-abort
on
Post by Stefan Kalkowski
i.MX53. So I think this is not the show-stopper.
Anyway please read my whole mail especially the section regarding the
caching issues. Being in your position, I would first correlate the
instruction pointer values with your Linux binary, e.g. using objdump,
before you start to do instruction decoding on cache-incoherent
memory.
Post by Stefan Kalkowski
Regards
Stefan
Post by r***@mpi-sws.org
Thanks!
Riju
Post by Stefan Kalkowski
Hello,
Post by Abhishek Kumar
Hello
I am trying to modify genode trustzone. I want to read the
instruction
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Post by Abhishek Kumar
which lead to data abort exception in normal world, in the `dump`
function in tz_vmm. I have value of all the registers through
`_state`
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Post by Abhishek Kumar
register. We tried with `_state->ip`. On converting 16 bits stored
at
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Post by Abhishek Kumar
STRH R0, [R0, #6]
But the value (R0) + 6, doesn't match dfar. We're not sure if _state->ip
is the register to go with. We tried with _state->mode[2].lr which
is
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Post by Abhishek Kumar
lr_abt register. But the address stored in lr_abt, lr_abt-16, lr_abt-32
all have 0s.
Which is right register to get the address of the instruction which
caused the data-abort exception?
As long as you get an synchronous data-abort from the normal world,
reading the current instruction pointer of the 'state' structure is
perfectly fine. The mode-specific lr register is useful for the handling
of MMU faults within the "normal" world itself. They are not
modified,
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
as long as the "normal" world MMU can resolve an access, but some
bus
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
resp. CSU is answering that the access is not allowed. This will not
change the "normal" world register set.
On the other hand, in general a bus fault triggered by unallowed
access
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
of the "normal" world does not necessarily mean a synchronous
data-abort, although on i.MX53 I only observed those. In general, it can
also provoke an asynchronous external data-abort, which means that
the
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
instruction pointer is not necessarily pointing to the instruction
that
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
triggered the fault.
Moreover, looking at the "normal" world's memory from the secure
side
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
is
troublesome. Because the normal and secure world's memory view is
not
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
cache-coherent. Cache entries are always tagged by the NS bit. That
means you have to take care to flush caches yourself. If you want to
debug instructions, you should instead look at the Linux binary
itself
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
and not into the memory on the secure side. To me it looks strange
that
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
you identify a Thumb instruction in the kernel here.
Btw. these kind of TrustZone/i.MX53 questions were asked repeatedly
in
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
https://genode.org/documentation/articles/trustzone
https://sourceforge.net/p/genode/mailman/search/?q=trustzone
Regards
Stefan
Post by Abhishek Kumar
Thanks
Abhishek
------------------------------------------------------------
------------------
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Post by Abhishek Kumar
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs
https://github.com/skalk · http://genode.org/
------------------------------------------------------------
------------------
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
------------------------------------------------------------
------------------
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs
https://github.com/skalk · http://genode.org/
------------------------------------------------------------
------------------
Post by Stefan Kalkowski
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
------------------------------------------------------------
------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org!
http://sdm.link/slashdot_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs

https://github.com/skalk · http://genode.org/
r***@mpi-sws.org
2017-06-20 12:12:50 UTC
Permalink
We read the dfsr value with changes in
base-hw/include/spec/imx53/vm_state.h,
base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc, and
os/src/server/tz_vmm/include/vm_base.h dump() function.

We got dfsr = 00001008, which gives b101000 for the status bits, matching
"bx01000 precise external abort, nontranslation" with "x=1=AXI Slave error
caused the abort" (according to
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344k/Bgbiaghh.html).

Got dfar = 53fbc080 physical address, which is in the UART range, and we
have made UART secure in csu_config.h, so makes sense that we get an AXI
slave error.

Basic questions:
(1) In base-hw/src/core/include/spec/arm/cpu_support.h, we see Cpu structs
Dfsr and Dfar and the read functions, which read from the cp15 registers.
This is what we explicitly read on a data abort and assign to _state
variables. How do the other _state variables r0-r12, ip, lr, etc. defined
in base/include/spec/arm/cpu/cpu_state.h get populated? In
os/src/server/tz_vmm/include/vm_base.h, constructor has this
initialization for _state:

_state((Genode::Vm_state*)Genode::env()->rm_session()->attach(_vm_con.cpu_state()))

What does this do? When we read or write from _state->ip or _state->r5,
are we accessing an actual register or a memory location? Where does the
memory read/write get translated to an actual register read/write? Like
dfar and dfsr, do we need explicit assignment of the other _state
variables in the data abort handler, so that in dump() function we get the
correct _state->ip?

(2) For precise data aborts,
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344f/Beiibjca.html
says the following.

After dealing with the cause of the abort, the handler executes the
following return instruction, irrespective of the processor operating
state at the point of entry:
SUBS PC,R14_abt,#8
This restores both the PC and the CPSR, and retries the aborted instruction.

But as we discussed above in this thread, we need to see _state->ip and
not _state->abt.lr, because this is an external abort on the AXI bus, and
not an mmu based internal abort. Is this behavior (lr_abt not updated and
ip needs to be read) something genode specific, or ARM specific? We see
cpsr=0x93, which makes EA=0. So external aborts are not programmed to trap
to monitor mode. So what is the flow when an imprecise external abort
occurs in the normal world? Does it go to the normal world exception
handler or comes to genode exception handler? What code can I look at to
understand this flow?
r***@mpi-sws.org
2017-06-20 14:42:53 UTC
Permalink
Analyzed the following files:
(a) base-hw/src/core/spec/arm/kernel/cpu.cc (calls init trustzone)
(b) base-hw/src/core/spec/imx53/trustzone/platform_support.cc (defines
init trustzone where monitor exception entry is assigned with
_mon_kernel_entry)
(c) base-hw/src/core/spec/arm_v7/trustzone/mode_transition.s defines
_mon_kernel_entry, which is the exception vector table in monitor mode.
The exception handlers call "_nonsecure_to_secure exception_type,
pc_adjust", which sets the appropriate pc based on lr values.
(d) base-hw/src/core/include/spec/arm_v7/macros_support.s has the register
bank save and restore macros.

For my doubt (1) above, does each precise external abort go through this
monitor exception handler function? How does that explain _state->ip is
the correct variable (since pc is already adjusted based on lr)?

For my doubt (2) above, are the _state variables mapped to the memory
addresses where the normal world registers are restored from? Is that how
any change made by vmm is reflected in the normal world registers?

Thanks!
Riju
Stefan Kalkowski
2017-06-22 14:57:20 UTC
Permalink
Post by r***@mpi-sws.org
(a) base-hw/src/core/spec/arm/kernel/cpu.cc (calls init trustzone)
(b) base-hw/src/core/spec/imx53/trustzone/platform_support.cc (defines
init trustzone where monitor exception entry is assigned with
_mon_kernel_entry)
(c) base-hw/src/core/spec/arm_v7/trustzone/mode_transition.s defines
_mon_kernel_entry, which is the exception vector table in monitor mode.
The exception handlers call "_nonsecure_to_secure exception_type,
pc_adjust", which sets the appropriate pc based on lr values.
(d) base-hw/src/core/include/spec/arm_v7/macros_support.s has the register
bank save and restore macros.
For my doubt (1) above, does each precise external abort go through this
monitor exception handler function? How does that explain _state->ip is
the correct variable (since pc is already adjusted based on lr)?
As previously said, its hard to reason about this, because the whole
peripheral connection and behaviour is largely board/vendor specific.
Probably almost all external data-aborts are taken to monitor mode, but
I can also imagine that some access (e.g. misaligned access on a device
granted to the normal world) might trigger an appropriated data-abort to
the normal world.

When a data-abort is taken by the monitor mode, it goes through that
exception handler.
Post by r***@mpi-sws.org
For my doubt (2) above, are the _state variables mapped to the memory
addresses where the normal world registers are restored from?
Yes.
Post by r***@mpi-sws.org
Is that how
any change made by vmm is reflected in the normal world registers?
Yes.

Regards
Stefan
Post by r***@mpi-sws.org
Thanks!
Riju
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs

https://github.com/skalk · http://genode.org/
r***@mpi-sws.org
2017-06-22 17:02:22 UTC
Permalink
Thanks a lot Stefan! base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc
and base-hw/src/core/spec/arm_v7/trustzone/mode_transition.s makes the
memory sharing and register read/write between vmm and vm clearer.

Further doubts:
(1)We put three print statements:
(a) In os/src/server/tz_vmm/spec/imx53/main.cc,
printf1
Signal s = _sig_rcv.wait_for_signal()
printf3

(b) In base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc,
printf2
mtc()->switch_to(reinterpret_cast<Cpu::Context*>(_state), cpu,
(addr_t)&_mt_nonsecure_entry_pic,
(addr_t)&_tz_client_context);

printf1 prints once. printf2 prints multiple times, followed by printf3
(we make uart secure in csu_config.h, so we hit printf3 followed by the
register dumps). Why do we switch from secure to normal world so many
times (indicated by multiple printf2), while _sig_rcv.wait_for_signal()?
What causes a switch back from normal to secure, before the UART related
abort?

(2) Every time we switch from secure to normal world, .macro
_secure_to_nonsecure does
mov lr, #13
mcr p15, 0, lr, c1, c1, 0 /* enable EA, FIQ, and NS bit in SCTRL */
So a csu based uart abort in normal world is expected to trap to monitor?
Are you saying this behavior is something peripheral/vendor specific?

(3) We suspect that the csu based uart abort doesn't trap to monitor
handler. If it came to the handler with a DABT excpetion, DFAR would be
copied to r3 and saved in the memory shared with _state at
.macro _nonsecure_to_secure
In that case _state->dfar would give the same value, with and without the
explicit read in base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc
case Genode::Cpu_state::DATA_ABORT:
state->dfar = Cpu::Dfar::read();
But we see without this read, _state->dfar prints all zeros, and with this
read it gives a uart address. So dfar is not saved in the monitor handler,
and therefore no other register would be saved. Is this understanding
correct?

(4) What does Signal s = _sig_rcv.wait_for_signal(); do in
os/src/server/tz_vmm/spec/imx53/main.cc? If the uart abort doesn't trap to
the monitor, what raises the signal so that we come to this main.cc and
execute the subsequent code like _handle_vm() that calls _vm->dump()? Is
vmm doing some sort of polling to check cpu exception states in normal
world?

(5) If abort doesn't trap to monitor, then only dfar and dfsr will hold
the normal world relevant values, as that was the last abort? The other
registers will be over-written, as normal world continued to execute,
until vmm polled it? So emulating the abort causing instruction in secure
world looks infeasible?

(6) Is there a way to print something from
base-hw/src/core/spec/arm_v7/trustzone/mode_transition.s? Most of the
actions happen here, but we are not able to trace when those macros are
executed.

Thanks for your constant assistance.

Riju
Stefan Kalkowski
2017-06-23 08:43:07 UTC
Permalink
Hi,
Post by r***@mpi-sws.org
Thanks a lot Stefan! base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc
and base-hw/src/core/spec/arm_v7/trustzone/mode_transition.s makes the
memory sharing and register read/write between vmm and vm clearer.
(a) In os/src/server/tz_vmm/spec/imx53/main.cc,
printf1
Signal s = _sig_rcv.wait_for_signal()
printf3
(b) In base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc,
printf2
mtc()->switch_to(reinterpret_cast<Cpu::Context*>(_state), cpu,
(addr_t)&_mt_nonsecure_entry_pic,
(addr_t)&_tz_client_context);
printf1 prints once. printf2 prints multiple times, followed by printf3
(we make uart secure in csu_config.h, so we hit printf3 followed by the
register dumps). Why do we switch from secure to normal world so many
times (indicated by multiple printf2), while _sig_rcv.wait_for_signal()?
What causes a switch back from normal to secure, before the UART related
abort?
Secure interrupts. Please keep in mind that in your scenario there is
more than the VMM component and the VM. The kernel schedules different
entities, thereby it uses its schedule clock. Probably you also have a
user-land timer for all other components, and maybe additional drivers,
which can use secure interrupts. Each secure interrupt hits the
fast-interrupt exception vector of the monitor mode, and thereby
initiates a world-switch.
Post by r***@mpi-sws.org
(2) Every time we switch from secure to normal world, .macro
_secure_to_nonsecure does
mov lr, #13
mcr p15, 0, lr, c1, c1, 0 /* enable EA, FIQ, and NS bit in SCTRL */
So a csu based uart abort in normal world is expected to trap to monitor?
correct.
Post by r***@mpi-sws.org
Are you saying this behavior is something peripheral/vendor specific?
No, I don't meant that whether an external data abort hits the monitor
mode is peripheral/vendor specific, like it is configured above. What I
meant is how a peripheral (e.g.: the CSU) signals a security violation
or error condition is not necessarily determined, and might differ from
peripheral to peripheral. I also said the update of the DFAR and DFSR
register is nothing I would count on. I only observed in my experiments
that DFAR was set to the correct value when the CSU signaled a
data-abort. Therefore, the kernel saved that register to the VM state,
and the VMM dumped it for debugging purposes.
Post by r***@mpi-sws.org
(3) We suspect that the csu based uart abort doesn't trap to monitor
handler. If it came to the handler with a DABT excpetion, DFAR would be
copied to r3 and saved in the memory shared with _state at
.macro _nonsecure_to_secure
In that case _state->dfar would give the same value, with and without the
explicit read in base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc
state->dfar = Cpu::Dfar::read();
But we see without this read, _state->dfar prints all zeros, and with this
read it gives a uart address. So dfar is not saved in the monitor handler,
and therefore no other register would be saved. Is this understanding
correct?
No. The DFAR register simply is not saved within the assembler path, but
at a later point using the "read" you refered to. All other relevant
registers are already saved in the assembler path. As I said, reading
out the DFAR was done for debugging purposes only, and enabled at a
later point in time. There was no need to read its value within the
assembler path.
Post by r***@mpi-sws.org
(4) What does Signal s = _sig_rcv.wait_for_signal(); do in
os/src/server/tz_vmm/spec/imx53/main.cc? If the uart abort doesn't trap to
the monitor, what raises the signal so that we come to this main.cc and
execute the subsequent code like _handle_vm() that calls _vm->dump()? Is
vmm doing some sort of polling to check cpu exception states in normal
world?
It waits for all signals registered at the signal receiver. It does not
poll at all. It blocks until a signal arrives. The VM session's signal
context is definitely connected to that signal receiver, so that
whenever the VM produced an exception, e.g. an abort, or smc call, the
VMM gets unblocked. But the signal receiver can be attached to other
signal sources too, e.g.: para-virtual driver backends like a block
session. So in general the VMM can also be woken up by another signal
source, as long as you use para-virtual devices in your scenario, which
is probably not the case if you use the tz_vmm example for the
Quickstart board.
Post by r***@mpi-sws.org
(5) If abort doesn't trap to monitor, then only dfar and dfsr will hold
the normal world relevant values, as that was the last abort? The other
registers will be over-written, as normal world continued to execute,
until vmm polled it? So emulating the abort causing instruction in secure
world looks infeasible?
as being said, just do not uncomment DFAR saving, and it will work again.
Post by r***@mpi-sws.org
(6) Is there a way to print something from
base-hw/src/core/spec/arm_v7/trustzone/mode_transition.s? Most of the
actions happen here, but we are not able to trace when those macros are
executed.
Not easily, you can write your own assembler macro that writes to the
UART directly. But changing anything there is very much error-prone. If
you have a JTAG adapter you should use that instead.

Regards
Stefan
Post by r***@mpi-sws.org
Thanks for your constant assistance.
Riju
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs

https://github.com/skalk · http://genode.org/
r***@mpi-sws.org
2017-06-23 09:10:20 UTC
Permalink
Why do you say you do not save DFAR in the assembler path? Isn't DFAR
saved in lines 15. and 27. below, while other registers are saved in line
3. in base-hw/src/core/spec/arm_v7/trustzone/mode_transition.s? This is
where control will come for csu abort with
_mon_dab_entry: _nonsecure_to_secure DAB_TYPE, 8, right?

1. .macro _nonsecure_to_secure exception_type, pc_adjust
2. ldr sp, _tz_client_context /* load context pointer*/
3. stmia sp, {r0-lr}^ /* save user regs r0-r12,sp,lr*/
4. add r0, sp, #15*4
5. .if \pc_adjust != 0 /* adjust pc if necessary*/
6. sub lr, lr, #\pc_adjust
7. .endif
8. stmia r0!, {lr} /* save pc*/
9. mrs r1, spsr /* spsr to r0*/
10. mov r2, #\exception_type /* exception reason to r1*/
11. b _nonsecure_kernel_entry
12. .endm /* _non_to_secure */

13. _nonsecure_kernel_entry:
14. stmia r0!, {r1-r2} /* save spsr, and exception reason */
15. mrc p15, 0, r3, c6, c0, 0 /* move DFAR to r3 */
16. mrc p15, 0, r4, c2, c0, 0 /* move TTBR0 to r4 */
17. mrc p15, 0, r5, c2, c0, 1 /* move TTBR1 to r5 */
18. mrc p15, 0, r6, c2, c0, 2 /* move TTBRC to r6 */
19. mov r1, #0
20. mcr p15, 0, r1, c1, c1, 0 /* disable non-secure bit */
21. _save_bank 27 /* save undefined banks */
22. _save_bank 19 /* save supervisor banks */
23. _save_bank 23 /* save abort banks */
24. _save_bank 18 /* save irq banks */
25. _save_bank 17 /* save fiq banks */
26. stmia r0!, {r8-r12} /* save fiq r8-r12 */
27. stmia r0!, {r3-r6} /* save MMU registers */
28. cps #SVC_MODE
29. adr r0, _tz_master_context
30. _restore_kernel_sp r0, r1, r2 /* apply kernel sp */
31. add r1, r0, #LR_OFFSET
32. ldm r1, {lr, pc}

Also, is there a tutorial how to use jtag to debug genode assembly? WE
have never used jtag, but have an olimex arm-usb-ocd-h.

Thanks!
Riju
Stefan Kalkowski
2017-06-23 09:42:56 UTC
Permalink
Hi,
Post by r***@mpi-sws.org
Why do you say you do not save DFAR in the assembler path? Isn't DFAR
saved in lines 15. and 27. below, while other registers are saved in line
3. in base-hw/src/core/spec/arm_v7/trustzone/mode_transition.s? This is
where control will come for csu abort with
_mon_dab_entry: _nonsecure_to_secure DAB_TYPE, 8, right?
1. .macro _nonsecure_to_secure exception_type, pc_adjust
2. ldr sp, _tz_client_context /* load context pointer*/
3. stmia sp, {r0-lr}^ /* save user regs r0-r12,sp,lr*/
4. add r0, sp, #15*4
5. .if \pc_adjust != 0 /* adjust pc if necessary*/
6. sub lr, lr, #\pc_adjust
7. .endif
8. stmia r0!, {lr} /* save pc*/
9. mrs r1, spsr /* spsr to r0*/
10. mov r2, #\exception_type /* exception reason to r1*/
11. b _nonsecure_kernel_entry
12. .endm /* _non_to_secure */
14. stmia r0!, {r1-r2} /* save spsr, and exception reason */
15. mrc p15, 0, r3, c6, c0, 0 /* move DFAR to r3 */
16. mrc p15, 0, r4, c2, c0, 0 /* move TTBR0 to r4 */
17. mrc p15, 0, r5, c2, c0, 1 /* move TTBR1 to r5 */
18. mrc p15, 0, r6, c2, c0, 2 /* move TTBRC to r6 */
19. mov r1, #0
20. mcr p15, 0, r1, c1, c1, 0 /* disable non-secure bit */
21. _save_bank 27 /* save undefined banks */
22. _save_bank 19 /* save supervisor banks */
23. _save_bank 23 /* save abort banks */
24. _save_bank 18 /* save irq banks */
25. _save_bank 17 /* save fiq banks */
26. stmia r0!, {r8-r12} /* save fiq r8-r12 */
27. stmia r0!, {r3-r6} /* save MMU registers */
28. cps #SVC_MODE
29. adr r0, _tz_master_context
30. _restore_kernel_sp r0, r1, r2 /* apply kernel sp */
31. add r1, r0, #LR_OFFSET
32. ldm r1, {lr, pc}
Ok sorry, I was not aware anymore that we save *normal world* DFAR in
the assembly path. Anyway, what you are interested in when receiving a
data-abort in monitor mode is the *secure world* DFAR register as it
contains the security violation address. Therefore, you cannot uncomment
the overwriting of the VM state's DFAR register in the high-level C++
code, because it saves a different register. Or you add another register
value to the end of the VM state and differentiate in between secure and
normal world DFAR register.
Post by r***@mpi-sws.org
Also, is there a tutorial how to use jtag to debug genode assembly? WE
have never used jtag, but have an olimex arm-usb-ocd-h.
No. There is nothing special about JTAG debugging Genode in contrast to
debugging any other software target, but I'm afraid debugging with
Olimex some specific ARM hardware is out of scope of this mailing list.
I have to admit that I primarily used Lauterbach, which is more
expensive but quite convenient (advertisement ends here).

Regards
Stefan
Post by r***@mpi-sws.org
Thanks!
Riju
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs

https://github.com/skalk · http://genode.org/
r***@mpi-sws.org
2017-06-23 13:02:47 UTC
Permalink
Thanks Stefan! We completely missed DFAR and DFSR are **banked** across
secure and non-secure worlds and the assembler path and the ::read are
seeing two separate copies of these registers.

We verified that we hit .macro _nonsecure_to_secure in monitor handler
with the csu abort exception. We wrote values to registers in the macro,
when the exception was DAB_TYPE. _state dump printed those specific
values. Though this macro is hit multiple times, the prior hits are
through fiq exception, and so these specific values must have been set on
the csu abort. So now we are confident that the flow after UART abort is
as expected, through the monitor handler.

(1) dfar (secure world) = 53fbc080 physical address, which is in the UART
range, and we have made UART secure in csu_config.h
(2) dfsr (secure world) = 00001008, which gives b101000 for the status
bits, matching "bx01000 precise external abort, nontranslation" with
"x=1=AXI Slave error caused the abort" (according to
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344k/Bgbiaghh.html)
(3) monitor handler gets the abort, so all normal world registers would be
appropriately saved. Especially, _state->ip will be lr-8, address holding
the normal world instruction that caused the abort.

This is good.

_state->ip holds a normal world virtual address VA_nw, which we convert to
physical address PA with va_to_pa function in
os/src/server/tz_vmm/include/vm_base.h. We take PA as secure world virtual
address VA_sw (based on a linear mapping we see at
repos/os/src/server/tz_vmm/include/ram.h. *(VA_sw) gives the normal world
instruction at _state->ip. The problem is the address in that instruction
doesn't match the address in dfar (secure).

Possible issues:
(a) The VA_nw->PA->VA_sw is wrong and we are reading the wrong memory.
(seems unlikely)
(b) We decode the instruction wrong, thumb vs. arm (we will verify this)
(c) normal world cached this address and didn't write it to RAM, so secure
world is reading a stale value (you suggested this sometime back).

For (c), we need to flush the normal world cache from secure world. Does
genode have any functions for this? I can see some cache/invalidate
related code for arm or arm_v7 or cortex_a8 in the following files:

Defining cache invalidate instructions:
base-hw/src/core/include/spec/cortex_a8/cpu.h,
base-hw/src/core/spec/cortex_a8/cpu.cc,
base-hw/src/core/include/spec/arm_v7/cpu_support.h,
base-hw/src/core/spec/arm_v7/cpu.cc,
base-hw/src/core/include/spec/arm/cpu_support.h,

Using those cache invalidate instructions:
base-hw/src/core/spec/arm/kernel/pd.cc,
base-hw/src/core/spec/arm/kernel/thread.cc,
base-hw/src/core/spec/arm/kernel/thread_update_pd.cc

Will see what these do and ask more specific questions if needed.

Thanks a lot for your patience and help.

Riju
r***@mpi-sws.org
2017-06-26 11:35:54 UTC
Permalink
We get the correct instruction from *(unsigned
int*)(va_to_pa(_state->ip))=e5930080.

The issue was wrong instruction decoding at
http://armconverter.com/hextoarm/. e5930080 gave
(1) in ARMv7 ARM mode
ANDHI SB, R0, R5, ROR #7 , and
(2) in ARMv7 Thumb mode
0xE5930080: STR R3, [SP, #0x394]
0xE5930082: STRH R0, [R0]

Decoding by hand using encoding rules at "ARM® Architecture Reference
Manual - ARMv7-A and ARMv7-R edition" gives
ldr r0, [r3,#128] in ARMv7 ARM mode.

This should be the mode as va_to_pa(_state->ip) is an even address.
r3(53fbc000)+128 exactly matches the DFAR(53fbc080) and ldr matches the
dfsr error that "read" gave "AXI Slave error" causing "precise external
abort, nontranslation".

https://github.com/jbremer/darm gives the correct decoding. We have ported
this to genode, to have inline decoding of faulting instruction and are
able to emulate the decoded instruction.

Thanks Stefan for your patient and constant help.

Riju

Stefan Kalkowski
2017-06-22 14:49:17 UTC
Permalink
Hi,
Post by r***@mpi-sws.org
We read the dfsr value with changes in
base-hw/include/spec/imx53/vm_state.h,
base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc, and
os/src/server/tz_vmm/include/vm_base.h dump() function.
We got dfsr = 00001008, which gives b101000 for the status bits, matching
"bx01000 precise external abort, nontranslation" with "x=1=AXI Slave error
caused the abort" (according to
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344k/Bgbiaghh.html).
Got dfar = 53fbc080 physical address, which is in the UART range, and we
have made UART secure in csu_config.h, so makes sense that we get an AXI
slave error.
(1) In base-hw/src/core/include/spec/arm/cpu_support.h, we see Cpu structs
Dfsr and Dfar and the read functions, which read from the cp15 registers.
This is what we explicitly read on a data abort and assign to _state
variables. How do the other _state variables r0-r12, ip, lr, etc. defined
in base/include/spec/arm/cpu/cpu_state.h get populated?
They are saved within the assembler path when switching from normal to
secure mode within monitor mode. Have a look at file:

repos/base-hw/src/core/spec/arm_v7/trustzone/mode_transition.s
Post by r***@mpi-sws.org
In
os/src/server/tz_vmm/include/vm_base.h, constructor has this
_state((Genode::Vm_state*)Genode::env()->rm_session()->attach(_vm_con.cpu_state()))
What does this do?
It initializes the pointer to the memory holding the normal world's
register set. That memory is a dataspace returned by the VM service
provided by core. The component attaches this dataspace to its region
map (virtual memory), and assigns the resulting address to the _state
pointer.
Post by r***@mpi-sws.org
When we read or write from _state->ip or _state->r5,
are we accessing an actual register or a memory location? Where does the
memory read/write get translated to an actual register read/write?
When the kernel/core schedules the normal world after the VMM marked it
to be runnable via run() of the VM service, the register state within
the VM's dataspace is restored to the actual registers.
Post by r***@mpi-sws.org
Like
dfar and dfsr, do we need explicit assignment of the other _state
variables in the data abort handler, so that in dump() function we get the
correct _state->ip?
No.
Post by r***@mpi-sws.org
(2) For precise data aborts,
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344f/Beiibjca.html
says the following.
After dealing with the cause of the abort, the handler executes the
following return instruction, irrespective of the processor operating
SUBS PC,R14_abt,#8
This restores both the PC and the CPSR, and retries the aborted instruction.
But as we discussed above in this thread, we need to see _state->ip and
not _state->abt.lr, because this is an external abort on the AXI bus, and
not an mmu based internal abort. Is this behavior (lr_abt not updated and
ip needs to be read) something genode specific, or ARM specific? We see
cpsr=0x93, which makes EA=0. So external aborts are not programmed to trap
to monitor mode. So what is the flow when an imprecise external abort
occurs in the normal world? Does it go to the normal world exception
handler or comes to genode exception handler? What code can I look at to
understand this flow?
The "_state" register set in memory is the information that our
hypervisor (kernel/core) provides to the VMM component. It is typically
the register state *before* the exception occurred resp. the instruction
that triggered the exception. For instance in your case the kernel saves
the lr register of the monitor mode to _state.ip. Therefore, you should
have a look at that register. The _state->abt.lr value shows the last
instruction pointer when the normal world's exception vector was hit by
a data-abort exception. It has nothing to do with your observed
exception. When the normal world's MMU/TLB can correctly translate a
data access, but the bus or peripheral answers with an error due to a
security violation, control is directly given to the monitor mode _not_
the normal world's exception vector. This is independent from the abort
flag in the CPSR register, which is useful in this context only within
the normal world (and its exception vector).

I hope this answers your questions.

Regards
Stefan
Post by r***@mpi-sws.org
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs

https://github.com/skalk · http://genode.org/
Stefan Kalkowski
2017-06-15 06:16:23 UTC
Permalink
Post by Abhishek Kumar
Hello Stefan
Thanks for your reply. I have a quick clarification to ask for. As you
mentioned about problems with cache-incoherent memory. What we are
trying to read is in code segment, I don't see how it can be changed.
Since it is not changing cache coherency should not be an issue, this is
my understanding. Can you please help me see where I might be wrong?
The Linux image typically in compressed (zImage) and gets uncompressed
by early assembler code within the Linux kernel itself. With other
words, it gets changed after you load it.

Regards
Stefan
Post by Abhishek Kumar
Thanks
Abhishek
Thanks a lot Stefan, Will correlate with the linux binary.
Riju
Post by Stefan Kalkowski
Hi,
Post by r***@mpi-sws.org
We want to read the instruction faulting in NW linux in tz_vmm,
disassemble it, emulate it in genode code and restart the VM at
the next
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
instruction of the normal world. Do you think this is feasible,
or your
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
comments about "synchronous data abort in IMX53 vs. asynchronous
aborts
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
in
Versatile Express" don't hold always?
As I said in my previous mail: I only observed synchronous
data-abort on
Post by Stefan Kalkowski
i.MX53. So I think this is not the show-stopper.
Anyway please read my whole mail especially the section regarding the
caching issues. Being in your position, I would first correlate the
instruction pointer values with your Linux binary, e.g. using objdump,
before you start to do instruction decoding on cache-incoherent
memory.
Post by Stefan Kalkowski
Regards
Stefan
Post by r***@mpi-sws.org
Thanks!
Riju
Post by Stefan Kalkowski
Hello,
Post by Abhishek Kumar
Hello
I am trying to modify genode trustzone. I want to read the
instruction
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Post by Abhishek Kumar
which lead to data abort exception in normal world, in the `dump`
function in tz_vmm. I have value of all the registers through
`_state`
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Post by Abhishek Kumar
register. We tried with `_state->ip`. On converting 16 bits
stored at
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Post by Abhishek Kumar
STRH R0, [R0, #6]
But the value (R0) + 6, doesn't match dfar. We're not sure if _state->ip
is the register to go with. We tried with _state->mode[2].lr
which is
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Post by Abhishek Kumar
lr_abt register. But the address stored in lr_abt, lr_abt-16, lr_abt-32
all have 0s.
Which is right register to get the address of the instruction which
caused the data-abort exception?
As long as you get an synchronous data-abort from the normal world,
reading the current instruction pointer of the 'state' structure is
perfectly fine. The mode-specific lr register is useful for the handling
of MMU faults within the "normal" world itself. They are not
modified,
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
as long as the "normal" world MMU can resolve an access, but
some bus
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
resp. CSU is answering that the access is not allowed. This will not
change the "normal" world register set.
On the other hand, in general a bus fault triggered by unallowed
access
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
of the "normal" world does not necessarily mean a synchronous
data-abort, although on i.MX53 I only observed those. In general, it can
also provoke an asynchronous external data-abort, which means
that the
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
instruction pointer is not necessarily pointing to the
instruction that
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
triggered the fault.
Moreover, looking at the "normal" world's memory from the secure
side
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
is
troublesome. Because the normal and secure world's memory view
is not
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
cache-coherent. Cache entries are always tagged by the NS bit. That
means you have to take care to flush caches yourself. If you want to
debug instructions, you should instead look at the Linux binary
itself
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
and not into the memory on the secure side. To me it looks
strange that
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
you identify a Thumb instruction in the kernel here.
Btw. these kind of TrustZone/i.MX53 questions were asked
repeatedly in
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
https://genode.org/documentation/articles/trustzone
<https://genode.org/documentation/articles/trustzone>
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
https://sourceforge.net/p/genode/mailman/search/?q=trustzone
<https://sourceforge.net/p/genode/mailman/search/?q=trustzone>
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Regards
Stefan
Post by Abhishek Kumar
Thanks
Abhishek
------------------------------------------------------------------------------
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Post by Abhishek Kumar
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
<https://lists.sourceforge.net/lists/listinfo/genode-main>
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
--
Stefan Kalkowski
Genode Labs
https://github.com/skalk · http://genode.org/
------------------------------------------------------------------------------
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Post by Stefan Kalkowski
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
<https://lists.sourceforge.net/lists/listinfo/genode-main>
------------------------------------------------------------------------------
Post by Stefan Kalkowski
Post by r***@mpi-sws.org
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
<https://lists.sourceforge.net/lists/listinfo/genode-main>
Post by Stefan Kalkowski
--
Stefan Kalkowski
Genode Labs
https://github.com/skalk · http://genode.org/
------------------------------------------------------------------------------
Post by Stefan Kalkowski
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
<https://lists.sourceforge.net/lists/listinfo/genode-main>
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
<https://lists.sourceforge.net/lists/listinfo/genode-main>
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
--
Stefan Kalkowski
Genode Labs

https://github.com/skalk · http://genode.org/
Loading...