
On Fri, Jul 06, 2007 at 11:06:54AM +0200, Christian Ehrhardt wrote:
Hello everyone, we currently try to use/port libvirt to run on xenppc. While doing that I found a endianess issue.
First a simple example:
Sample code: #include <stdio.h>
union u { int i; long long l; };
int main(void) { union u u; u.l = 0; u.i = ~0; printf("%016llx\n", u.l);
return 0; }
Little-endian output: 00000000ffffffff Big-endian output: ffffffff00000000
Now look at the padding in e.g. xen_v2s3_getdomaininfolistop: it doesn't work on big-endian systems. This problem is why the GUEST_HANDLE infrastructure is present in Xen. To work on big-endian systems, libvirt will need this or a similar mechanism.
--- Current Questions --- We could now add several ugly ifdefs to libvirt code to differentiate powerpc from the others and solve the issue described above, but I think thats not a good solution. The GUEST_HANDLE mechanism would provide an architecture abstraction and is already implemented/working in libxc.a
libxc is GPL, while libvirt is LGPL.
The question is, shouldn't libvirt actually use the GUEST_HANDLE mechanism like libxc does (at least for the _v2d5_ structures) or are there big arguments against it?
We can't use the structures directly because libvirt needs to compile in support for *all* hypervisor ABIs so it can automatically use the correct ABI at runtime. We don't want a build of libvirt to be tied to the HV it was built against because that creates serious pain in upgrades.
More or less everything in libvirt that would use GUEST_HANDLE in libxc: I saw the effect on a bad pointer passed down by the structure I use for my example below, but in the end it may affect all the stuff that uses the *GUEST_HANDLE* stuff in libxc which are e.g. uchar,ulong,... here an example: libxc: uint64_aligned_t max_pages; // <- arch dependent mapping of uint64_aligned_t libvirt: #define ALIGN_64 __attribute__((aligned(8))) uint64_t max_pages ALIGN_64; // <- this align is fix on all architectures
Would it be sufficient to add #ifndef PPC or some kind of conditional around the '#define ALIGN_64' definitions ?
XEN_GUEST_HANDLE usage in libvirt: - In my example where XEN_GUEST_HANDLE is in libxc libvirt currently uses a union based structure like the following: struct xen_v2s3_getdomaininfolistop { domid_t first_domain; uint32_t max_domains; union { struct xen_v2d5_getdomaininfo *v; uint64_t pad ALIGN_64; } buffer; uint32_t num_domains; }; typedef struct xen_v2s3_getdomaininfolistop xen_v2s3_getdomaininfolistop;
The union used here to add the 64 bit padding does not work on big endian powerpc because reading this two half words in 64bit receiver gives 0xFFFFFFFF00000000 (The two half words are stored in the wrong order) while on ia64 it is read as the the valid 0x00000000FFFFFFFF.
I'm fine with any suggestions for changes to the structs above to make it work correctly on big-endian, provided they don't involve copying code from libxc Regards, Dan. -- |=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=| |=- Perl modules: http://search.cpan.org/~danberr/ -=| |=- Projects: http://freshmeat.net/~danielpb/ -=| |=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|