Save the CPU endianness when the device is reset. It is widely
assumed that the guest won't change its endianness after, or at
least not without reseting the device first.

A default implementation of the endianness sampling just returns
the default "host endianness" value so that unsuspecting architectures
are not affected.

Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
---
 tools/kvm/include/kvm/kvm-cpu.h | 1 +
 tools/kvm/include/kvm/virtio.h  | 1 +
 tools/kvm/kvm-cpu.c             | 6 ++++++
 tools/kvm/virtio/mmio.c         | 3 +++
 4 files changed, 11 insertions(+)

diff --git a/tools/kvm/include/kvm/kvm-cpu.h b/tools/kvm/include/kvm/kvm-cpu.h
index 0ece28c..aa0cb54 100644
--- a/tools/kvm/include/kvm/kvm-cpu.h
+++ b/tools/kvm/include/kvm/kvm-cpu.h
@@ -15,6 +15,7 @@ void kvm_cpu__run(struct kvm_cpu *vcpu);
 void kvm_cpu__reboot(struct kvm *kvm);
 int kvm_cpu__start(struct kvm_cpu *cpu);
 bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu);
+int kvm_cpu__get_endianness(struct kvm_cpu *vcpu);
 
 int kvm_cpu__get_debug_fd(void);
 void kvm_cpu__set_debug_fd(int fd);
diff --git a/tools/kvm/include/kvm/virtio.h b/tools/kvm/include/kvm/virtio.h
index f6bddd9..1180a3e 100644
--- a/tools/kvm/include/kvm/virtio.h
+++ b/tools/kvm/include/kvm/virtio.h
@@ -132,6 +132,7 @@ struct virtio_device {
        bool                    use_vhost;
        void                    *virtio;
        struct virtio_ops       *ops;
+       u16                     endian;
 };
 
 struct virtio_ops {
diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
index 5c70b00..9575b32 100644
--- a/tools/kvm/kvm-cpu.c
+++ b/tools/kvm/kvm-cpu.c
@@ -3,6 +3,7 @@
 #include "kvm/symbol.h"
 #include "kvm/util.h"
 #include "kvm/kvm.h"
+#include "kvm/virtio.h"
 
 #include <sys/ioctl.h>
 #include <sys/mman.h>
@@ -14,6 +15,11 @@
 
 extern __thread struct kvm_cpu *current_kvm_cpu;
 
+int __attribute__((weak)) kvm_cpu__get_endianness(struct kvm_cpu *vcpu)
+{
+       return VIRTIO_ENDIAN_HOST;
+}
+
 void kvm_cpu__enable_singlestep(struct kvm_cpu *vcpu)
 {
        struct kvm_guest_debug debug = {
diff --git a/tools/kvm/virtio/mmio.c b/tools/kvm/virtio/mmio.c
index 9d385e2..3a2bd62 100644
--- a/tools/kvm/virtio/mmio.c
+++ b/tools/kvm/virtio/mmio.c
@@ -4,6 +4,7 @@
 #include "kvm/ioport.h"
 #include "kvm/virtio.h"
 #include "kvm/kvm.h"
+#include "kvm/kvm-cpu.h"
 #include "kvm/irq.h"
 #include "kvm/fdt.h"
 
@@ -159,6 +160,8 @@ static void virtio_mmio_config_out(struct kvm_cpu *vcpu,
                break;
        case VIRTIO_MMIO_STATUS:
                vmmio->hdr.status = ioport__read32(data);
+               if (!vmmio->hdr.status) /* Sample endianness on reset */
+                       vdev->endian = kvm_cpu__get_endianness(vcpu);
                if (vdev->ops->notify_status)
                        vdev->ops->notify_status(kvm, vmmio->dev, 
vmmio->hdr.status);
                break;
-- 
1.8.3.4

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

Reply via email to