Re: [PATCH v2] KVM: Specify byte order for KVM_EXIT_MMIO

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 28 January 2014 01:59, Scott Wood <scottwood@xxxxxxxxxxxxx> wrote:
> On Sat, 2014-01-25 at 03:15 +0100, Alexander Graf wrote:
>> Ok, let's go through the combinations for a 32-bit write of 0x01020304 on PPC and what data[] looks like
>>
>> your proposal:
>>
>>   BE guest, BE host: { 0x01, 0x02, 0x03, 0x04 }
>>   LE guest, BE host: { 0x04, 0x03, 0x02, 0x01 }
>>   BE guest, LE host:  { 0x01, 0x02, 0x03, 0x04 }
>>   LE guest, LE host:  { 0x04, 0x03, 0x02, 0x01 }
>>
>> -> ldw_p() will give us the correct value to work with
>
> Do you mean ldl_p(), which just does a memcpy()?  How is that different
> from *(uint32_t*)data, other than complying with C99 aliasing rules?
>
> What you get from doing ldl_p() is the value as interpreted by the host
> endianness.  If the memory region endianness is different from the host
> endianness, you need to swap.  adjust_endianness() sort of does this,
> but it's using TARGET_WORDS_BIGENDIAN instead of the host endianness
> which will break if they are not the same.  It works for TCG because it
> passes the MMIO value in target endianness rather than host --
> effectively the TARGET_WORDS_BIGENDIAN usages in memory.c and
> include/exec/softmmu_template.h cancel each other.
>
>> current proposal:
>>
>>   BE guest, BE host: { 0x01, 0x02, 0x03, 0x04 }
>>   LE guest, BE host: { 0x04, 0x03, 0x02, 0x01 }
>>   BE guest, LE host:  { 0x04, 0x03, 0x02, 0x01 }
>>   LE guest, LE host:  { 0x01, 0x02, 0x03, 0x04 }
>>
>> -> *(uint32_t*)data will give us the correct value to work with
>
> *(uint32_t*)data in the "LE guest, LE host" case will get you 0x04030201
> -- how is that the correct value to work with?  Did you make this table
> with the assumption that big-endian interpretation is inherently "the
> correct value" on PPC?

So for ARM, if you put the CPU in big endian mode (by setting
CPSR.E) then the architecture defines that what happens here
is that before any access to the bus the CPU does a byte lane
swap of the data. So a register value of 0x04030201 sent
as a 32 bit store appears on the bus as 0x01020304. If the CPU
is in little endian mode no swapping happens and values in
registers go direct to the bus.

The assumption we made here is that PPC is similar except
that it does no swapping on BE, and swaps on LE. Is this wrong?
(I did look through the PPC architecture docs but couldn't find
anything that clearly stated what happened.)

> I suppose you could define one endianness as "natural" for a particular
> platform, and the other as swapped, but I don't think that's a useful
> way to look at it except for things like virtio that are defined as
> being native-endian (and I don't think KVM_EXIT_MMIO is the right layer
> to try to sort that problem out, as it just introduces confusion for
> non-virtio MMIO).

As I say above, for ARM (v7, BE8) considering one endianness as
'natural' is exactly how the architecture works. (We don't need to
care about BE32, fortunately, as it is obsolete: it used to work kind
of similarly except that it was word invariant and worked by XORing
the address with 1 or 3 when the CPU was in BE mode...)

> Unfortunately, that appears to currently be how QEMU works, so either
> QEMU needs to be fixed in a way that is compatible with currently
> working scenarios (e.g. by changing adjust_endianness() to use host
> endianness and changing the TCG path to match), or it needs to be
> explicitly defined in the API what assumptions are being made regarding
> the default endianness on each architecture.  I believe these
> assumptions are present but implicit in the current proposal (if Alex's
> intepretation of it matches what was intended).
>
>> With approach 2 you don't care about endianness at all anymore - you
>> just get a payload that the host process can read in.
>
> You always need to care about endianness -- something has to result in
> PCI registers appearing swapped compared to e500 CCSR registers.

That's the result of some bridge doing a byte lane swap, isn't it?
Obviously swapping bridges need to be modeled (and in QEMU
we currently do that rather badly, by marking the device endpoints
as having an endianness and inferring the existence of a swap)
but that's not related to the initial CPU-to-bus interface.

thanks
-- PMM
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux