aboutsummaryrefslogtreecommitdiffstats
path: root/exec.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-01-10 01:35:11 +0000
committerAlexander Graf <agraf@suse.de>2012-01-21 05:17:01 +0100
commit82afa58641b0e67abbaf4da6c325ebd7c2513262 (patch)
tree9e0f2e91ce9e53518b9aecc7e214594ba6d806ed /exec.c
parent34ba1dc8739196c771281b0ba38c2ccd32c6d1fe (diff)
virtio-pci: Fix endianness of virtio config
The virtio config area in PIO space is a bit special. The initial header is little endian but the rest (device specific) is guest native endian. The PIO accessors for PCI on machines that don't have native IO ports assume that all PIO is little endian, which works fine for everything except the above. A complicated way to fix it would be to split the BAR into two memory regions with different endianess settings, but this isn't practical to do, besides, the PIO code doesn't honor region endianness anyway (I have a patch for that too but it isn't necessary at this stage). So I decided to go for the quick fix instead which consists of reverting the swap in virtio-pci in selected places, hoping that when we eventually do a "v2" of the virtio protocols, we sort that out once and for all using a fixed endian setting for everything. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Alexander Graf <agraf@suse.de> [agraf: keep virtio in libhw and determine endianness through a helper function in exec.c] Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'exec.c')
-rw-r--r--exec.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/exec.c b/exec.c
index 7f9f73025..5b9eb9aa1 100644
--- a/exec.c
+++ b/exec.c
@@ -4390,6 +4390,20 @@ tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong addr)
return qemu_ram_addr_from_host_nofail(p);
}
+/*
+ * A helper function for the _utterly broken_ virtio device model to find out if
+ * it's running on a big endian machine. Don't do this at home kids!
+ */
+bool virtio_is_big_endian(void);
+bool virtio_is_big_endian(void)
+{
+#if defined(TARGET_WORDS_BIGENDIAN)
+ return true;
+#else
+ return false;
+#endif
+}
+
#define MMUSUFFIX _cmmu
#undef GETPC
#define GETPC() NULL