On 04/05/2017 06:23 PM, Måns Rullgård wrote:
> Ralf Ramsauer <[email protected]> writes:
>
>> On 04/05/2017 02:48 PM, Jan Kiszka wrote:
>>> On 2017-04-05 13:43, Måns Rullgård wrote:
>>>> Ralf Ramsauer <[email protected]> writes:
>>>>
>>>>> Hi,
>>>>>
>>>>> I need spinlocks in inmates on ARM, so I simply included asm/spinlock.h.
>>>>> Taking locks in inmates on ARM somehow doesn't work at all, but that's
>>>>> not the main issue. As soon as I try to take locks, cells can not be
>>>>> destroyed any longer, the whole system freezes on cell destroy.
>>>>>
>>>>> I was able to trace this down to the 'ldrex' instruction. This minimal
>>>>> example triggers this behavior (tested on a TK1, can not test it on
>>>>> other boards):
>>>>>
>>>>> #include <inmate.h>
>>>>>
>>>>> void inmate_main(void)
>>>>> {
>>>>> unsigned int foo = 0, bar = 0;
>>>>>
>>>>> printk("Foo!\n");
>>>>> asm volatile("ldrex %0, [%1]\n\t"
>>>>> : "=&r" (foo) : "r" (bar));
>>>>>
>>>>> printk("Bar!\n");
>>>>> while(1);
>>>>> asm volatile("wfi");
>>>>> }
>>>>>
>>>>> The example code successfully finishes, I can read Foo and Bar on my
>>>>> serial console. But I am not able to destroy the cell afterwards. My
>>>>> system completely hangs on "jailhouse cell destroy".
>>>>>
>>>>> Curiously the cell can be re-loaded and started over again. Leaving out
>>>>> the ldrex instruction does not trigger the bug.
>>>>>
>>>>> - How can ldrex prevent my cell from being destroyed?
>>>>>
>>>>> Does it change some 'internal state' where jailhouse is not aware
>>>>> about?
>>>
>>> Is your inmate opting-out from the Comm Region protocol
>>> (JAILHOUSE_CELL_PASSIVE_COMMREG)?
>> Yes I'm using the Jailhouse's TK1 default config.
>>>
>>>>>
>>>>> - Why do spinlocks not work at all in inmates?
>>>>>
>>>>> spin_lock(&lock) never returns in inmates on a fresh spin lock.
>>>>> Does the ARM implementation of spinlocks require some special
>>>>> global initialisation that I don't know of?
>>>>
>>>> Spinlocks use ldrex/strex pairs, so if ldrex is broken, I wouldn't
>>>> expect spinlocks to work either.
>>>>
>>>
>>> ...and Linux use them heavily. All our ARM SMP Linux inmates would be
>>> broken then. There must be more involved.
>> Yes, true.
>>
>> I just reanimated my Orange Pi zero and cross-checked the behaviour there:
>>
>> It just prints the "Foo!", no bar, and I'm able to destroy its cell
>> afterwards. Jetson TK1 behaves different and freezes.
>
> Is that using the same compiled inmate code? Could you post a
> disassembly of the inmate_main() function? The compiler might be doing
> something unexpected.
Sure. Let me add some more detail.
The source:
void inmate_main(void)
{
unsigned int foo = 0, bar = 0;
printk("Foo!\n");
asm volatile("dsb sy\n" ::: "memory");
asm volatile(
"ldrex %0, [%1]\n\t"
// doesn't matter if I choose &bar
: "=&r" (foo) : "r" (bar)
);
asm volatile("dsb sy\n" ::: "memory");
printk("Bar!\n");
while(1)
asm volatile("wfi");
}
compiles to:
00000204 <inmate_main>:
204: e92d4010 push {r4, lr}
208: e59f0020 ldr r0, [pc, #32] ; 230 <inmate_main+0x2c>
20c: eb0000ea bl 5bc <printk>
210: f57ff04f dsb sy
214: e3a03000 mov r3, #0
218: e1932f9f ldrex r2, [r3]
21c: f57ff04f dsb sy
220: e59f000c ldr r0, [pc, #12] ; 234 <inmate_main+0x30>
224: eb0000e4 bl 5bc <printk>
228: e320f003 wfi
22c: eafffffd b 228 <inmate_main+0x24>
230: 00000d79 .word 0x00000d79
234: 00000d7f .word 0x00000d7f
The resulting binary can be used for both systems, I just have to align
some settings for the UART, which can be done per cmdline parameter.
On TK1 side, it results in:
Cell "jetson-tk1-demo" can be loaded
Started cell "jetson-tk1-demo"
Foo!
Bar!
When I try to 'jailhouse cell destroy jetson-tk1-demo' the last things I
get to see are:
[...]
Closing cell "jetson-tk1-demo"
Page pool usage after cell destruction: mem 71/16107, remap 69/131072
And that's it, Linux hung up, but *only* if the inmate executes the
ldrex instruction since the last full system reset.
The very same inmate binary on the Orange Pi Zero (sorry, UARTs are shared):
root@orange:~/jailhouse# ./tools/jailhouse cell start 1
Started cell "orangepi0-gic-demo"
Foo!
root@orange:~/jailhouse# ./tools/jailhouse disable
Closing cell "orangepi0-gic-demo"
Page pool usage after cell destruction: mem 36/2025, remap 69/131072
[ 188.867422] Destroyed Jailhouse cell "orangepi0-gic-demo"
Shutting down hypervisor
Releasing CPU 2
Releasing CPU 1
Releasing CPU 3
Releasing CPU 0
[ 188.882025] The Jailhouse was closed.
So on the Orangepi I can only see the "Foo!", and destroy the cell or
disable the hypervisor, whatever, and on the TK1 I see "Foo!\nBar!" and
the system freezes, as soon as I try to destroy the cell.
Ralf
>
--
You received this message because you are subscribed to the Google Groups
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.