Re: KVM and variable-endianness guest CPUs

Peter Maydell
2014-01-23T10:23:52Z

On 23 January 2014 00:22, Victor Kamensky <victor.kamensky@linaro.org> wrote:
> Peter, could I please ask you a favor. Could you please
> stop deleting pieces of your and my previous responses
> when you reply.

No, sorry. It produces excessively long and totally unreadable
emails for everybody else if people don't trim for context.
This is standard mailing list practice.

>>> Consider above big endian case (setend be) example,
>>> but now running in BE KVM host. 0x4 is LSB of CPU
>>> core register in this case.
>>
>> Yes. In this case if we are using the "mmio.data is host
>> kernel endianness" definition then mmio.data[0] should be
>> 0x01 (the MSB of the 32 bit data value).
>
> If mmio.data[0] is 0x1, mmio.data[] = {0x1, 0x2, 0x3, 0x4},
> and now KVM host and emulator running in BE mode.
> But that contradicts to what you said before.

Sorry, I misread the example here (and assumed we were
writing the same word in both cases, when actually the BE
code example is writing a different value). mmio.data[0] should
be 0x4, because:
* BE ARM guest, so KVM must byte-swap the register value
(giving 0x04030201)
* BE host, so it writes the uint32_t in host order (giving
0x4 in mmio.data[0])

>>> I believe, but I need to check, that PPC BE setup actually
>>> acts as the second case in above example If we have PPC
>>> BE guest executing the following instructions:
>>>
>>> lis r1,0x102
>>> ori r1,r1,0x304
>>> stw r1,0(r0)
>>>
>>> after first two instructions r1 would contain 0x01020304.
>>> IMHO It exactly corresponds to above my ARM second case -
>>> BE guest when it runs under ARM BE KVM host. I believe
>>> that mmio.data[] in PPC BE case would be {0x1, 0x2, 0x3, 0x4}.
>>
>> Yes, assuming a BE PPC host kernel (which is the usual
>> arrangement).
>
> OK, that confirms my understanding how PPC mmio
> should work.
>
>>> But according to you data[0] must be 0x4 in BE host case
>>
>> Er, no. The data here is 0x01020304, so for a BE host
>> data[0] is the big end, ie 0x1. It would only be 0x4 if
>> mmio.data[] were LE always (or if you were running
>> your BE PPC guest on an LE PPC host, which I don't
>> think is supported currently).
>
> So do you agree that for all three code snippets cited in this
> email, we always will have mmio.data[] = {0x1, 0x2,
> 0x3, 0x4}, for ARM LE qemu/host, for ARM BE qemu/host
> and for ppc code snippet in PPC BE qemu/host.

No. Also your ARM and PPC examples are not usefully
comparable, because:

> setend le
> mov r1, #0x04030201
> str r1, [r0]

This is an LE guest writing 0x04030201, and that is the
value that will go out on the bus.

> and
>
> setend be
> mov r1, #0x01020304
> str r1, [r0]

This is a BE guest writing 0x01020304; as far as the
code running on the CPU is concerned; the value on the
bus will be byteswapped.

> lis r1,0x102
> ori r1,r1,0x304
> stw r1,0(r0)

This is also a BE guest writing 0x01020304. I'm pretty
sure that the PPC approach is that for BE guests writing
a word that word goes out to the bus as is; for LE guests
(or if the page table is set up to say "this page is LE") the
CPU swaps it before putting it on the bus. In this regard
it is the opposite way round to ARM.

So the value you start with in the CPU register is not
the same in all three cases, and what the hardware
does is not the same either.

thanks
-- PMM