@@ -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);
@@ -132,6 +132,7 @@ struct virtio_device {
bool use_vhost;
void *virtio;
struct virtio_ops *ops;
+ u16 endian;
};
struct virtio_ops {
@@ -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 = {
@@ -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;
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.zyngier@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(+)