All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/9] kvmtool: handle guests of a different endianness
@ 2014-05-08  9:32 Marc Zyngier
  2014-05-08  9:32 ` [PATCH v4 1/9] kvmtool: pass trapped vcpu to MMIO accessors Marc Zyngier
                   ` (8 more replies)
  0 siblings, 9 replies; 13+ messages in thread
From: Marc Zyngier @ 2014-05-08  9:32 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: Pekka Enberg, Will Deacon

This patch series adds some infrastructure to kvmtool to allow a BE
guest to use virtio-mmio on a LE host, provided that the architecture
actually supports such madness.

Not all the backend have been converted, only those I actually cared
about. Converting them is pretty easy though, and will be done if the
method is deemed acceptable.

This has been tested on both arm and arm64 (I use this on a daily
basis to test BE code). The corresponding kernel changes have all been
merged.

Also available at:
git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git kvm-arm64/kvmtool-be-on-le

>From v3:
- Only patch 9/9 changed:
  * Handle access comming from EL0 in AArch64 mode
  * Added comment about SETEND in AArch32 mode
  * Fixed commit message

>From v2 (never posted):
- Fixed tons of bugs (config space)
- Fixed TAP networking

>From v1:
- Gave up on the virtio extension after the push back from the PPC
  guys. Instead, we snapshot the endianness of the vcpu  when it
  tries to reset the device. A bit ugly, but doesn't require any
  change on the kernel side.

Marc Zyngier (9):
  kvmtool: pass trapped vcpu to MMIO accessors
  kvmtool: virt_queue configuration based on endianness
  kvmtool: sample CPU endianness on virtio-mmio device reset
  kvmtool: add queue endianness initializer
  kvmtool: convert console backend to support bi-endianness
  kvmtool: convert 9p backend to support bi-endianness
  kvmtool: convert blk backend to support bi-endianness
  kvmtool: convert net backend to support bi-endianness
  kvmtool: virtio: enable arm/arm64 support for bi-endianness

 tools/kvm/arm/aarch32/kvm-cpu.c                  | 14 ++++
 tools/kvm/arm/aarch64/include/kvm/kvm-cpu-arch.h |  2 +
 tools/kvm/arm/aarch64/kvm-cpu.c                  | 43 +++++++++++++
 tools/kvm/arm/include/arm-common/kvm-arch.h      |  2 +
 tools/kvm/arm/include/arm-common/kvm-cpu-arch.h  |  4 +-
 tools/kvm/arm/kvm-cpu.c                          | 10 +--
 tools/kvm/hw/pci-shmem.c                         |  2 +-
 tools/kvm/include/kvm/kvm-cpu.h                  |  1 +
 tools/kvm/include/kvm/kvm.h                      |  4 +-
 tools/kvm/include/kvm/virtio.h                   | 82 +++++++++++++++++++++++-
 tools/kvm/kvm-cpu.c                              | 10 ++-
 tools/kvm/mmio.c                                 | 11 ++--
 tools/kvm/pci.c                                  |  3 +-
 tools/kvm/powerpc/include/kvm/kvm-cpu-arch.h     |  2 +-
 tools/kvm/powerpc/kvm-cpu.c                      |  4 +-
 tools/kvm/powerpc/spapr_pci.h                    |  6 +-
 tools/kvm/virtio/9p.c                            |  3 +
 tools/kvm/virtio/blk.c                           | 31 +++++++--
 tools/kvm/virtio/console.c                       |  8 ++-
 tools/kvm/virtio/core.c                          | 59 +++++++++--------
 tools/kvm/virtio/mmio.c                          | 21 ++++--
 tools/kvm/virtio/net.c                           | 45 +++++++++++--
 tools/kvm/virtio/pci.c                           |  6 +-
 tools/kvm/x86/include/kvm/kvm-cpu-arch.h         |  4 +-
 24 files changed, 302 insertions(+), 75 deletions(-)

-- 
1.8.3.4


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v4 1/9] kvmtool: pass trapped vcpu to MMIO accessors
  2014-05-08  9:32 [PATCH v4 0/9] kvmtool: handle guests of a different endianness Marc Zyngier
@ 2014-05-08  9:32 ` Marc Zyngier
  2014-05-08  9:32 ` [PATCH v4 2/9] kvmtool: virt_queue configuration based on endianness Marc Zyngier
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Marc Zyngier @ 2014-05-08  9:32 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: Pekka Enberg, Will Deacon

In order to be able to find out about the endianness of a virtual
CPU, it is necessary to pass a pointer to the kvm_cpu structure
down to the MMIO accessors.

This patch just pushes such pointer as far as required for the
MMIO accessors to have a play with the vcpu.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 tools/kvm/arm/include/arm-common/kvm-cpu-arch.h |  4 ++--
 tools/kvm/arm/kvm-cpu.c                         | 10 +++++-----
 tools/kvm/hw/pci-shmem.c                        |  2 +-
 tools/kvm/include/kvm/kvm.h                     |  4 ++--
 tools/kvm/kvm-cpu.c                             |  4 ++--
 tools/kvm/mmio.c                                | 11 ++++++-----
 tools/kvm/pci.c                                 |  3 ++-
 tools/kvm/powerpc/include/kvm/kvm-cpu-arch.h    |  2 +-
 tools/kvm/powerpc/kvm-cpu.c                     |  4 ++--
 tools/kvm/powerpc/spapr_pci.h                   |  6 +++---
 tools/kvm/virtio/mmio.c                         | 18 +++++++++++-------
 tools/kvm/virtio/pci.c                          |  6 ++++--
 tools/kvm/x86/include/kvm/kvm-cpu-arch.h        |  4 ++--
 13 files changed, 43 insertions(+), 35 deletions(-)

diff --git a/tools/kvm/arm/include/arm-common/kvm-cpu-arch.h b/tools/kvm/arm/include/arm-common/kvm-cpu-arch.h
index bef1761..355a02d 100644
--- a/tools/kvm/arm/include/arm-common/kvm-cpu-arch.h
+++ b/tools/kvm/arm/include/arm-common/kvm-cpu-arch.h
@@ -42,8 +42,8 @@ static inline bool kvm_cpu__emulate_io(struct kvm *kvm, u16 port, void *data,
 	return false;
 }
 
-bool kvm_cpu__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len,
-			   u8 is_write);
+bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data,
+			   u32 len, u8 is_write);
 
 unsigned long kvm_cpu__get_vcpu_mpidr(struct kvm_cpu *vcpu);
 
diff --git a/tools/kvm/arm/kvm-cpu.c b/tools/kvm/arm/kvm-cpu.c
index 9c9616f..53afa35 100644
--- a/tools/kvm/arm/kvm-cpu.c
+++ b/tools/kvm/arm/kvm-cpu.c
@@ -98,17 +98,17 @@ bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
 	return false;
 }
 
-bool kvm_cpu__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len,
-			   u8 is_write)
+bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data,
+			   u32 len, u8 is_write)
 {
 	if (arm_addr_in_virtio_mmio_region(phys_addr)) {
-		return kvm__emulate_mmio(kvm, phys_addr, data, len, is_write);
+		return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
 	} else if (arm_addr_in_ioport_region(phys_addr)) {
 		int direction = is_write ? KVM_EXIT_IO_OUT : KVM_EXIT_IO_IN;
 		u16 port = (phys_addr - KVM_IOPORT_AREA) & USHRT_MAX;
-		return kvm__emulate_io(kvm, port, data, direction, len, 1);
+		return kvm__emulate_io(vcpu->kvm, port, data, direction, len, 1);
 	} else if (arm_addr_in_pci_region(phys_addr)) {
-		return kvm__emulate_mmio(kvm, phys_addr, data, len, is_write);
+		return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
 	}
 
 	return false;
diff --git a/tools/kvm/hw/pci-shmem.c b/tools/kvm/hw/pci-shmem.c
index 34de747..4b837eb 100644
--- a/tools/kvm/hw/pci-shmem.c
+++ b/tools/kvm/hw/pci-shmem.c
@@ -105,7 +105,7 @@ static struct ioport_operations shmem_pci__io_ops = {
 	.io_out	= shmem_pci__io_out,
 };
 
-static void callback_mmio_msix(u64 addr, u8 *data, u32 len, u8 is_write, void *ptr)
+static void callback_mmio_msix(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, u8 is_write, void *ptr)
 {
 	void *mem;
 
diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
index d05b936..f1b71a0 100644
--- a/tools/kvm/include/kvm/kvm.h
+++ b/tools/kvm/include/kvm/kvm.h
@@ -84,10 +84,10 @@ int kvm_timer__exit(struct kvm *kvm);
 void kvm__irq_line(struct kvm *kvm, int irq, int level);
 void kvm__irq_trigger(struct kvm *kvm, int irq);
 bool kvm__emulate_io(struct kvm *kvm, u16 port, void *data, int direction, int size, u32 count);
-bool kvm__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, u8 is_write);
+bool kvm__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u8 is_write);
 int kvm__register_mem(struct kvm *kvm, u64 guest_phys, u64 size, void *userspace_addr);
 int kvm__register_mmio(struct kvm *kvm, u64 phys_addr, u64 phys_addr_len, bool coalesce,
-			void (*mmio_fn)(u64 addr, u8 *data, u32 len, u8 is_write, void *ptr),
+		       void (*mmio_fn)(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, u8 is_write, void *ptr),
 			void *ptr);
 bool kvm__deregister_mmio(struct kvm *kvm, u64 phys_addr);
 void kvm__pause(struct kvm *kvm);
diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
index be05c49..5c70b00 100644
--- a/tools/kvm/kvm-cpu.c
+++ b/tools/kvm/kvm-cpu.c
@@ -54,7 +54,7 @@ static void kvm_cpu__handle_coalesced_mmio(struct kvm_cpu *cpu)
 		while (cpu->ring->first != cpu->ring->last) {
 			struct kvm_coalesced_mmio *m;
 			m = &cpu->ring->coalesced_mmio[cpu->ring->first];
-			kvm_cpu__emulate_mmio(cpu->kvm,
+			kvm_cpu__emulate_mmio(cpu,
 					      m->phys_addr,
 					      m->data,
 					      m->len,
@@ -138,7 +138,7 @@ int kvm_cpu__start(struct kvm_cpu *cpu)
 			 */
 			kvm_cpu__handle_coalesced_mmio(cpu);
 
-			ret = kvm_cpu__emulate_mmio(cpu->kvm,
+			ret = kvm_cpu__emulate_mmio(cpu,
 						    cpu->kvm_run->mmio.phys_addr,
 						    cpu->kvm_run->mmio.data,
 						    cpu->kvm_run->mmio.len,
diff --git a/tools/kvm/mmio.c b/tools/kvm/mmio.c
index 5d65d28..705ce27f 100644
--- a/tools/kvm/mmio.c
+++ b/tools/kvm/mmio.c
@@ -1,4 +1,5 @@
 #include "kvm/kvm.h"
+#include "kvm/kvm-cpu.h"
 #include "kvm/rbtree-interval.h"
 #include "kvm/brlock.h"
 
@@ -16,7 +17,7 @@
 
 struct mmio_mapping {
 	struct rb_int_node	node;
-	void			(*mmio_fn)(u64 addr, u8 *data, u32 len, u8 is_write, void *ptr);
+	void			(*mmio_fn)(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, u8 is_write, void *ptr);
 	void			*ptr;
 };
 
@@ -59,7 +60,7 @@ static const char *to_direction(u8 is_write)
 }
 
 int kvm__register_mmio(struct kvm *kvm, u64 phys_addr, u64 phys_addr_len, bool coalesce,
-			void (*mmio_fn)(u64 addr, u8 *data, u32 len, u8 is_write, void *ptr),
+		       void (*mmio_fn)(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, u8 is_write, void *ptr),
 			void *ptr)
 {
 	struct mmio_mapping *mmio;
@@ -119,7 +120,7 @@ bool kvm__deregister_mmio(struct kvm *kvm, u64 phys_addr)
 	return true;
 }
 
-bool kvm__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, u8 is_write)
+bool kvm__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u8 is_write)
 {
 	struct mmio_mapping *mmio;
 
@@ -127,9 +128,9 @@ bool kvm__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, u8 is_
 	mmio = mmio_search(&mmio_tree, phys_addr, len);
 
 	if (mmio)
-		mmio->mmio_fn(phys_addr, data, len, is_write, mmio->ptr);
+		mmio->mmio_fn(vcpu, phys_addr, data, len, is_write, mmio->ptr);
 	else {
-		if (kvm->cfg.mmio_debug)
+		if (vcpu->kvm->cfg.mmio_debug)
 			fprintf(stderr, "Warning: Ignoring MMIO %s at %016llx (length %u)\n",
 				to_direction(is_write), phys_addr, len);
 	}
diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c
index c2da152..5d60585 100644
--- a/tools/kvm/pci.c
+++ b/tools/kvm/pci.c
@@ -179,7 +179,8 @@ void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data,
 	}
 }
 
-static void pci_config_mmio_access(u64 addr, u8 *data, u32 len, u8 is_write, void *kvm)
+static void pci_config_mmio_access(struct kvm_cpu *vcpu, u64 addr, u8 *data,
+				   u32 len, u8 is_write, void *kvm)
 {
 	union pci_config_address cfg_addr;
 
diff --git a/tools/kvm/powerpc/include/kvm/kvm-cpu-arch.h b/tools/kvm/powerpc/include/kvm/kvm-cpu-arch.h
index 7520c04..82cb5987 100644
--- a/tools/kvm/powerpc/include/kvm/kvm-cpu-arch.h
+++ b/tools/kvm/powerpc/include/kvm/kvm-cpu-arch.h
@@ -71,6 +71,6 @@ static inline bool kvm_cpu__emulate_io(struct kvm *kvm, u16 port, void *data, in
 	return false;
 }
 
-bool kvm_cpu__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, u8 is_write);
+bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u8 is_write);
 
 #endif /* KVM__KVM_CPU_ARCH_H */
diff --git a/tools/kvm/powerpc/kvm-cpu.c b/tools/kvm/powerpc/kvm-cpu.c
index 8f825bd..2f5cfc6 100644
--- a/tools/kvm/powerpc/kvm-cpu.c
+++ b/tools/kvm/powerpc/kvm-cpu.c
@@ -193,7 +193,7 @@ bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
 	return ret;
 }
 
-bool kvm_cpu__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, u8 is_write)
+bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u8 is_write)
 {
 	/*
 	 * FIXME: This function will need to be split in order to support
@@ -204,7 +204,7 @@ bool kvm_cpu__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, u8
 
 	if ((phys_addr >= SPAPR_PCI_WIN_START) &&
 	    (phys_addr < SPAPR_PCI_WIN_END)) {
-		ret = spapr_phb_mmio(kvm, phys_addr, data, len, is_write);
+		ret = spapr_phb_mmio(vcpu, phys_addr, data, len, is_write);
 	} else {
 		pr_warning("MMIO %s unknown address %llx (size %d)!\n",
 			   is_write ? "write to" : "read from",
diff --git a/tools/kvm/powerpc/spapr_pci.h b/tools/kvm/powerpc/spapr_pci.h
index 48b221c..f9cb42f 100644
--- a/tools/kvm/powerpc/spapr_pci.h
+++ b/tools/kvm/powerpc/spapr_pci.h
@@ -36,19 +36,19 @@ int spapr_populate_pci_devices(struct kvm *kvm,
                                uint32_t xics_phandle,
                                void *fdt);
 
-static inline bool spapr_phb_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, u8 is_write)
+static inline bool spapr_phb_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u8 is_write)
 {
 	if ((phys_addr >= SPAPR_PCI_IO_WIN_ADDR) &&
 	    (phys_addr < SPAPR_PCI_IO_WIN_ADDR +
 	     SPAPR_PCI_IO_WIN_SIZE)) {
-		return kvm__emulate_io(kvm, phys_addr - SPAPR_PCI_IO_WIN_ADDR,
+		return kvm__emulate_io(vcpu->kvm, phys_addr - SPAPR_PCI_IO_WIN_ADDR,
 				       data, is_write ? KVM_EXIT_IO_OUT :
 				       KVM_EXIT_IO_IN,
 				       len, 1);
 	} else if ((phys_addr >= SPAPR_PCI_MEM_WIN_ADDR) &&
 		   (phys_addr < SPAPR_PCI_MEM_WIN_ADDR +
 		    SPAPR_PCI_MEM_WIN_SIZE)) {
-		return kvm__emulate_mmio(kvm, phys_addr - SPAPR_PCI_MEM_WIN_ADDR,
+		return kvm__emulate_mmio(vcpu, phys_addr - SPAPR_PCI_MEM_WIN_ADDR,
 					 data, len, is_write);
 	}
 	return false;
diff --git a/tools/kvm/virtio/mmio.c b/tools/kvm/virtio/mmio.c
index e1fca2b..9d385e2 100644
--- a/tools/kvm/virtio/mmio.c
+++ b/tools/kvm/virtio/mmio.c
@@ -88,7 +88,8 @@ int virtio_mmio_signal_config(struct kvm *kvm, struct virtio_device *vdev)
 	return 0;
 }
 
-static void virtio_mmio_device_specific(u64 addr, u8 *data, u32 len,
+static void virtio_mmio_device_specific(struct kvm_cpu *vcpu,
+					u64 addr, u8 *data, u32 len,
 					u8 is_write, struct virtio_device *vdev)
 {
 	struct virtio_mmio *vmmio = vdev->virtio;
@@ -104,7 +105,8 @@ static void virtio_mmio_device_specific(u64 addr, u8 *data, u32 len,
 	}
 }
 
-static void virtio_mmio_config_in(u64 addr, void *data, u32 len,
+static void virtio_mmio_config_in(struct kvm_cpu *vcpu,
+				  u64 addr, void *data, u32 len,
 				  struct virtio_device *vdev)
 {
 	struct virtio_mmio *vmmio = vdev->virtio;
@@ -140,7 +142,8 @@ static void virtio_mmio_config_in(u64 addr, void *data, u32 len,
 	}
 }
 
-static void virtio_mmio_config_out(u64 addr, void *data, u32 len,
+static void virtio_mmio_config_out(struct kvm_cpu *vcpu,
+				   u64 addr, void *data, u32 len,
 				   struct virtio_device *vdev)
 {
 	struct virtio_mmio *vmmio = vdev->virtio;
@@ -202,7 +205,8 @@ static void virtio_mmio_config_out(u64 addr, void *data, u32 len,
 	};
 }
 
-static void virtio_mmio_mmio_callback(u64 addr, u8 *data, u32 len,
+static void virtio_mmio_mmio_callback(struct kvm_cpu *vcpu,
+				      u64 addr, u8 *data, u32 len,
 				      u8 is_write, void *ptr)
 {
 	struct virtio_device *vdev = ptr;
@@ -211,14 +215,14 @@ static void virtio_mmio_mmio_callback(u64 addr, u8 *data, u32 len,
 
 	if (offset >= VIRTIO_MMIO_CONFIG) {
 		offset -= VIRTIO_MMIO_CONFIG;
-		virtio_mmio_device_specific(offset, data, len, is_write, ptr);
+		virtio_mmio_device_specific(vcpu, offset, data, len, is_write, ptr);
 		return;
 	}
 
 	if (is_write)
-		virtio_mmio_config_out(offset, data, len, ptr);
+		virtio_mmio_config_out(vcpu, offset, data, len, ptr);
 	else
-		virtio_mmio_config_in(offset, data, len, ptr);
+		virtio_mmio_config_in(vcpu, offset, data, len, ptr);
 }
 
 #ifdef CONFIG_HAS_LIBFDT
diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c
index 665d492..57ccde6 100644
--- a/tools/kvm/virtio/pci.c
+++ b/tools/kvm/virtio/pci.c
@@ -240,7 +240,8 @@ static struct ioport_operations virtio_pci__io_ops = {
 	.io_out	= virtio_pci__io_out,
 };
 
-static void virtio_pci__msix_mmio_callback(u64 addr, u8 *data, u32 len,
+static void virtio_pci__msix_mmio_callback(struct kvm_cpu *vcpu,
+					   u64 addr, u8 *data, u32 len,
 					   u8 is_write, void *ptr)
 {
 	struct virtio_pci *vpci = ptr;
@@ -321,7 +322,8 @@ int virtio_pci__signal_config(struct kvm *kvm, struct virtio_device *vdev)
 	return 0;
 }
 
-static void virtio_pci__io_mmio_callback(u64 addr, u8 *data, u32 len,
+static void virtio_pci__io_mmio_callback(struct kvm_cpu *vcpu,
+					 u64 addr, u8 *data, u32 len,
 					 u8 is_write, void *ptr)
 {
 	struct virtio_pci *vpci = ptr;
diff --git a/tools/kvm/x86/include/kvm/kvm-cpu-arch.h b/tools/kvm/x86/include/kvm/kvm-cpu-arch.h
index 198efe6..fd86b4d 100644
--- a/tools/kvm/x86/include/kvm/kvm-cpu-arch.h
+++ b/tools/kvm/x86/include/kvm/kvm-cpu-arch.h
@@ -41,9 +41,9 @@ static inline bool kvm_cpu__emulate_io(struct kvm *kvm, u16 port, void *data, in
 	return kvm__emulate_io(kvm, port, data, direction, size, count);
 }
 
-static inline bool kvm_cpu__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, u8 is_write)
+static inline bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u8 is_write)
 {
-	return kvm__emulate_mmio(kvm, phys_addr, data, len, is_write);
+	return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
 }
 
 #endif /* KVM__KVM_CPU_ARCH_H */
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 2/9] kvmtool: virt_queue configuration based on endianness
  2014-05-08  9:32 [PATCH v4 0/9] kvmtool: handle guests of a different endianness Marc Zyngier
  2014-05-08  9:32 ` [PATCH v4 1/9] kvmtool: pass trapped vcpu to MMIO accessors Marc Zyngier
@ 2014-05-08  9:32 ` Marc Zyngier
  2014-05-08  9:32 ` [PATCH v4 3/9] kvmtool: sample CPU endianness on virtio-mmio device reset Marc Zyngier
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Marc Zyngier @ 2014-05-08  9:32 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: Pekka Enberg, Will Deacon

Define a simple infrastructure to configure a virt_queue
depending on the guest endianness, as reported by the feature
flags. At this stage, the endianness is always the host's.

Wrap all accesses to virt_queue data structures shared between
host and guest with byte swapping helpers.

Should the architecture only support one endianness, these helpers
are reduced to the identity function.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 tools/kvm/include/kvm/virtio.h | 74 ++++++++++++++++++++++++++++++++++++++++--
 tools/kvm/virtio/core.c        | 59 +++++++++++++++++++--------------
 2 files changed, 105 insertions(+), 28 deletions(-)

diff --git a/tools/kvm/include/kvm/virtio.h b/tools/kvm/include/kvm/virtio.h
index 820b94a..f6bddd9 100644
--- a/tools/kvm/include/kvm/virtio.h
+++ b/tools/kvm/include/kvm/virtio.h
@@ -1,6 +1,8 @@
 #ifndef KVM__VIRTIO_H
 #define KVM__VIRTIO_H
 
+#include <endian.h>
+
 #include <linux/virtio_ring.h>
 #include <linux/virtio_pci.h>
 
@@ -15,6 +17,10 @@
 #define VIRTIO_PCI_O_CONFIG	0
 #define VIRTIO_PCI_O_MSIX	1
 
+#define VIRTIO_ENDIAN_HOST	0
+#define VIRTIO_ENDIAN_LE	(1 << 0)
+#define VIRTIO_ENDIAN_BE	(1 << 1)
+
 struct virt_queue {
 	struct vring	vring;
 	u32		pfn;
@@ -24,9 +30,71 @@ struct virt_queue {
 	u16		last_used_signalled;
 };
 
+/*
+ * The default policy is not to cope with the guest endianness.
+ * It also helps not breaking archs that do not care about supporting
+ * such a configuration.
+ */
+#ifndef VIRTIO_RING_ENDIAN
+#define VIRTIO_RING_ENDIAN VIRTIO_ENDIAN_HOST
+#endif
+
+#if (VIRTIO_RING_ENDIAN & (VIRTIO_ENDIAN_LE | VIRTIO_ENDIAN_BE))
+
+static inline __u16 __virtio_g2h_u16(u16 endian, __u16 val)
+{
+	return (endian == VIRTIO_ENDIAN_LE) ? le16toh(val) : be16toh(val);
+}
+
+static inline __u16 __virtio_h2g_u16(u16 endian, __u16 val)
+{
+	return (endian == VIRTIO_ENDIAN_LE) ? htole16(val) : htobe16(val);
+}
+
+static inline __u32 __virtio_g2h_u32(u16 endian, __u32 val)
+{
+	return (endian == VIRTIO_ENDIAN_LE) ? le32toh(val) : be32toh(val);
+}
+
+static inline __u32 __virtio_h2g_u32(u16 endian, __u32 val)
+{
+	return (endian == VIRTIO_ENDIAN_LE) ? htole32(val) : htobe32(val);
+}
+
+static inline __u64 __virtio_g2h_u64(u16 endian, __u64 val)
+{
+	return (endian == VIRTIO_ENDIAN_LE) ? le64toh(val) : be64toh(val);
+}
+
+static inline __u64 __virtio_h2g_u64(u16 endian, __u64 val)
+{
+	return (endian == VIRTIO_ENDIAN_LE) ? htole64(val) : htobe64(val);
+}
+
+#define virtio_guest_to_host_u16(x, v)	__virtio_g2h_u16((x)->endian, (v))
+#define virtio_host_to_guest_u16(x, v)	__virtio_h2g_u16((x)->endian, (v))
+#define virtio_guest_to_host_u32(x, v)	__virtio_g2h_u32((x)->endian, (v))
+#define virtio_host_to_guest_u32(x, v)	__virtio_h2g_u32((x)->endian, (v))
+#define virtio_guest_to_host_u64(x, v)	__virtio_g2h_u64((x)->endian, (v))
+#define virtio_host_to_guest_u64(x, v)	__virtio_h2g_u64((x)->endian, (v))
+
+#else
+
+#define virtio_guest_to_host_u16(x, v)	(v)
+#define virtio_host_to_guest_u16(x, v)	(v)
+#define virtio_guest_to_host_u32(x, v)	(v)
+#define virtio_host_to_guest_u32(x, v)	(v)
+#define virtio_guest_to_host_u64(x, v)	(v)
+#define virtio_host_to_guest_u64(x, v)	(v)
+
+#endif
+
 static inline u16 virt_queue__pop(struct virt_queue *queue)
 {
-	return queue->vring.avail->ring[queue->last_avail_idx++ % queue->vring.num];
+	__u16 guest_idx;
+
+	guest_idx = queue->vring.avail->ring[queue->last_avail_idx++ % queue->vring.num];
+	return virtio_guest_to_host_u16(queue, guest_idx);
 }
 
 static inline struct vring_desc *virt_queue__get_desc(struct virt_queue *queue, u16 desc_ndx)
@@ -39,8 +107,8 @@ static inline bool virt_queue__available(struct virt_queue *vq)
 	if (!vq->vring.avail)
 		return 0;
 
-	vring_avail_event(&vq->vring) = vq->last_avail_idx;
-	return vq->vring.avail->idx !=  vq->last_avail_idx;
+	vring_avail_event(&vq->vring) = virtio_host_to_guest_u16(vq, vq->last_avail_idx);
+	return virtio_guest_to_host_u16(vq, vq->vring.avail->idx) != vq->last_avail_idx;
 }
 
 struct vring_used_elem *virt_queue__set_used_elem(struct virt_queue *queue, u32 head, u32 len);
diff --git a/tools/kvm/virtio/core.c b/tools/kvm/virtio/core.c
index 2dfb828..9ae7887 100644
--- a/tools/kvm/virtio/core.c
+++ b/tools/kvm/virtio/core.c
@@ -15,10 +15,11 @@
 struct vring_used_elem *virt_queue__set_used_elem(struct virt_queue *queue, u32 head, u32 len)
 {
 	struct vring_used_elem *used_elem;
+	u16 idx = virtio_guest_to_host_u16(queue, queue->vring.used->idx);
 
-	used_elem	= &queue->vring.used->ring[queue->vring.used->idx % queue->vring.num];
-	used_elem->id	= head;
-	used_elem->len	= len;
+	used_elem	= &queue->vring.used->ring[idx % queue->vring.num];
+	used_elem->id	= virtio_host_to_guest_u32(queue, head);
+	used_elem->len	= virtio_host_to_guest_u32(queue, len);
 
 	/*
 	 * Use wmb to assure that used elem was updated with head and len.
@@ -26,7 +27,8 @@ struct vring_used_elem *virt_queue__set_used_elem(struct virt_queue *queue, u32
 	 * to pass the used element to the guest.
 	 */
 	wmb();
-	queue->vring.used->idx++;
+	idx++;
+	queue->vring.used->idx = virtio_host_to_guest_u16(queue, idx);
 
 	/*
 	 * Use wmb to assure used idx has been increased before we signal the guest.
@@ -38,22 +40,28 @@ struct vring_used_elem *virt_queue__set_used_elem(struct virt_queue *queue, u32
 	return used_elem;
 }
 
+static inline bool virt_desc__test_flag(struct virt_queue *vq,
+					struct vring_desc *desc, u16 flag)
+{
+	return !!(virtio_guest_to_host_u16(vq, desc->flags) & flag);
+}
+
 /*
  * Each buffer in the virtqueues is actually a chain of descriptors.  This
  * function returns the next descriptor in the chain, or vq->vring.num if we're
  * at the end.
  */
-static unsigned next_desc(struct vring_desc *desc,
+static unsigned next_desc(struct virt_queue *vq, struct vring_desc *desc,
 			  unsigned int i, unsigned int max)
 {
 	unsigned int next;
 
 	/* If this descriptor says it doesn't chain, we're done. */
-	if (!(desc[i].flags & VRING_DESC_F_NEXT))
+	if (!virt_desc__test_flag(vq, &desc[i], VRING_DESC_F_NEXT))
 		return max;
 
 	/* Check they're not leading us off end of descriptors. */
-	next = desc[i].next;
+	next = virtio_guest_to_host_u16(vq, desc[i].next);
 	/* Make sure compiler knows to grab that: we don't want it changing! */
 	wmb();
 
@@ -71,22 +79,23 @@ u16 virt_queue__get_head_iov(struct virt_queue *vq, struct iovec iov[], u16 *out
 	max = vq->vring.num;
 	desc = vq->vring.desc;
 
-	if (desc[idx].flags & VRING_DESC_F_INDIRECT) {
-		max = desc[idx].len / sizeof(struct vring_desc);
-		desc = guest_flat_to_host(kvm, desc[idx].addr);
+	if (virt_desc__test_flag(vq, &desc[idx], VRING_DESC_F_INDIRECT)) {
+		max = virtio_guest_to_host_u32(vq, desc[idx].len) / sizeof(struct vring_desc);
+		desc = guest_flat_to_host(kvm, virtio_guest_to_host_u64(vq, desc[idx].addr));
 		idx = 0;
 	}
 
 	do {
 		/* Grab the first descriptor, and check it's OK. */
-		iov[*out + *in].iov_len = desc[idx].len;
-		iov[*out + *in].iov_base = guest_flat_to_host(kvm, desc[idx].addr);
+		iov[*out + *in].iov_len = virtio_guest_to_host_u32(vq, desc[idx].len);
+		iov[*out + *in].iov_base = guest_flat_to_host(kvm,
+							      virtio_guest_to_host_u64(vq, desc[idx].addr));
 		/* If this is an input descriptor, increment that count. */
-		if (desc[idx].flags & VRING_DESC_F_WRITE)
+		if (virt_desc__test_flag(vq, &desc[idx], VRING_DESC_F_WRITE))
 			(*in)++;
 		else
 			(*out)++;
-	} while ((idx = next_desc(desc, idx, max)) != max);
+	} while ((idx = next_desc(vq, desc, idx, max)) != max);
 
 	return head;
 }
@@ -111,20 +120,20 @@ u16 virt_queue__get_inout_iov(struct kvm *kvm, struct virt_queue *queue,
 	idx = head = virt_queue__pop(queue);
 	*out = *in = 0;
 	do {
+		u64 addr;
 		desc = virt_queue__get_desc(queue, idx);
-		if (desc->flags & VRING_DESC_F_WRITE) {
-			in_iov[*in].iov_base = guest_flat_to_host(kvm,
-								  desc->addr);
-			in_iov[*in].iov_len = desc->len;
+		addr = virtio_guest_to_host_u64(queue, desc->addr);
+		if (virt_desc__test_flag(queue, desc, VRING_DESC_F_WRITE)) {
+			in_iov[*in].iov_base = guest_flat_to_host(kvm, addr);
+			in_iov[*in].iov_len = virtio_guest_to_host_u32(queue, desc->len);
 			(*in)++;
 		} else {
-			out_iov[*out].iov_base = guest_flat_to_host(kvm,
-								    desc->addr);
-			out_iov[*out].iov_len = desc->len;
+			out_iov[*out].iov_base = guest_flat_to_host(kvm, addr);
+			out_iov[*out].iov_len = virtio_guest_to_host_u32(queue, desc->len);
 			(*out)++;
 		}
-		if (desc->flags & VRING_DESC_F_NEXT)
-			idx = desc->next;
+		if (virt_desc__test_flag(queue, desc, VRING_DESC_F_NEXT))
+			idx = virtio_guest_to_host_u16(queue, desc->next);
 		else
 			break;
 	} while (1);
@@ -151,8 +160,8 @@ bool virtio_queue__should_signal(struct virt_queue *vq)
 	u16 old_idx, new_idx, event_idx;
 
 	old_idx		= vq->last_used_signalled;
-	new_idx		= vq->vring.used->idx;
-	event_idx	= vring_used_event(&vq->vring);
+	new_idx		= virtio_guest_to_host_u16(vq, vq->vring.used->idx);
+	event_idx	= virtio_guest_to_host_u16(vq, vring_used_event(&vq->vring));
 
 	if (vring_need_event(event_idx, new_idx, old_idx)) {
 		vq->last_used_signalled = new_idx;
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 3/9] kvmtool: sample CPU endianness on virtio-mmio device reset
  2014-05-08  9:32 [PATCH v4 0/9] kvmtool: handle guests of a different endianness Marc Zyngier
  2014-05-08  9:32 ` [PATCH v4 1/9] kvmtool: pass trapped vcpu to MMIO accessors Marc Zyngier
  2014-05-08  9:32 ` [PATCH v4 2/9] kvmtool: virt_queue configuration based on endianness Marc Zyngier
@ 2014-05-08  9:32 ` Marc Zyngier
  2014-05-08  9:32 ` [PATCH v4 4/9] kvmtool: add queue endianness initializer Marc Zyngier
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Marc Zyngier @ 2014-05-08  9:32 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: Pekka Enberg, Will Deacon

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(+)

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


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 4/9] kvmtool: add queue endianness initializer
  2014-05-08  9:32 [PATCH v4 0/9] kvmtool: handle guests of a different endianness Marc Zyngier
                   ` (2 preceding siblings ...)
  2014-05-08  9:32 ` [PATCH v4 3/9] kvmtool: sample CPU endianness on virtio-mmio device reset Marc Zyngier
@ 2014-05-08  9:32 ` Marc Zyngier
  2014-05-08  9:32 ` [PATCH v4 5/9] kvmtool: convert console backend to support bi-endianness Marc Zyngier
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Marc Zyngier @ 2014-05-08  9:32 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: Pekka Enberg, Will Deacon

Add a utility function that transfers the endianness sampled
at device reset time to a queue being set up.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 tools/kvm/include/kvm/virtio.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/tools/kvm/include/kvm/virtio.h b/tools/kvm/include/kvm/virtio.h
index 1180a3e..8a9eab5 100644
--- a/tools/kvm/include/kvm/virtio.h
+++ b/tools/kvm/include/kvm/virtio.h
@@ -28,6 +28,7 @@ struct virt_queue {
 	   It's where we assume the next request index is at.  */
 	u16		last_avail_idx;
 	u16		last_used_signalled;
+	u16		endian;
 };
 
 /*
@@ -165,4 +166,10 @@ static inline void *virtio_get_vq(struct kvm *kvm, u32 pfn, u32 page_size)
 	return guest_flat_to_host(kvm, (u64)pfn * page_size);
 }
 
+static inline void virtio_init_device_vq(struct virtio_device *vdev,
+					 struct virt_queue *vq)
+{
+	vq->endian = vdev->endian;
+}
+
 #endif /* KVM__VIRTIO_H */
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 5/9] kvmtool: convert console backend to support bi-endianness
  2014-05-08  9:32 [PATCH v4 0/9] kvmtool: handle guests of a different endianness Marc Zyngier
                   ` (3 preceding siblings ...)
  2014-05-08  9:32 ` [PATCH v4 4/9] kvmtool: add queue endianness initializer Marc Zyngier
@ 2014-05-08  9:32 ` Marc Zyngier
  2014-05-08  9:32 ` [PATCH v4 6/9] kvmtool: convert 9p " Marc Zyngier
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Marc Zyngier @ 2014-05-08  9:32 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: Pekka Enberg, Will Deacon

Configure the queues to follow the guest endianness, and make sure
the configuration space is doing the same.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 tools/kvm/virtio/console.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/tools/kvm/virtio/console.c b/tools/kvm/virtio/console.c
index 0474e2b..384eac1 100644
--- a/tools/kvm/virtio/console.c
+++ b/tools/kvm/virtio/console.c
@@ -131,7 +131,12 @@ static u32 get_host_features(struct kvm *kvm, void *dev)
 
 static void set_guest_features(struct kvm *kvm, void *dev, u32 features)
 {
-	/* Unused */
+	struct con_dev *cdev = dev;
+	struct virtio_console_config *conf = &cdev->config;
+
+	conf->cols = virtio_host_to_guest_u16(&cdev->vdev, conf->cols);
+	conf->rows = virtio_host_to_guest_u16(&cdev->vdev, conf->rows);
+	conf->max_nr_ports = virtio_host_to_guest_u32(&cdev->vdev, conf->max_nr_ports);
 }
 
 static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
@@ -149,6 +154,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
 	p		= virtio_get_vq(kvm, queue->pfn, page_size);
 
 	vring_init(&queue->vring, VIRTIO_CONSOLE_QUEUE_SIZE, p, align);
+	virtio_init_device_vq(&cdev.vdev, queue);
 
 	if (vq == VIRTIO_CONSOLE_TX_QUEUE) {
 		thread_pool__init_job(&cdev.jobs[vq], kvm, virtio_console_handle_callback, queue);
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 6/9] kvmtool: convert 9p backend to support bi-endianness
  2014-05-08  9:32 [PATCH v4 0/9] kvmtool: handle guests of a different endianness Marc Zyngier
                   ` (4 preceding siblings ...)
  2014-05-08  9:32 ` [PATCH v4 5/9] kvmtool: convert console backend to support bi-endianness Marc Zyngier
@ 2014-05-08  9:32 ` Marc Zyngier
  2014-05-08  9:32 ` [PATCH v4 7/9] kvmtool: convert blk " Marc Zyngier
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Marc Zyngier @ 2014-05-08  9:32 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: Pekka Enberg, Will Deacon

Configure the queues to follow the guest endianness, and make sure
the configuration space is doing the same.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 tools/kvm/virtio/9p.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/kvm/virtio/9p.c b/tools/kvm/virtio/9p.c
index 847eddb..9073a1e 100644
--- a/tools/kvm/virtio/9p.c
+++ b/tools/kvm/virtio/9p.c
@@ -1252,8 +1252,10 @@ static u32 get_host_features(struct kvm *kvm, void *dev)
 static void set_guest_features(struct kvm *kvm, void *dev, u32 features)
 {
 	struct p9_dev *p9dev = dev;
+	struct virtio_9p_config *conf = p9dev->config;
 
 	p9dev->features = features;
+	conf->tag_len = virtio_host_to_guest_u16(&p9dev->vdev, conf->tag_len);
 }
 
 static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
@@ -1272,6 +1274,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
 	job		= &p9dev->jobs[vq];
 
 	vring_init(&queue->vring, VIRTQUEUE_NUM, p, align);
+	virtio_init_device_vq(&p9dev->vdev, queue);
 
 	*job		= (struct p9_dev_job) {
 		.vq		= queue,
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 7/9] kvmtool: convert blk backend to support bi-endianness
  2014-05-08  9:32 [PATCH v4 0/9] kvmtool: handle guests of a different endianness Marc Zyngier
                   ` (5 preceding siblings ...)
  2014-05-08  9:32 ` [PATCH v4 6/9] kvmtool: convert 9p " Marc Zyngier
@ 2014-05-08  9:32 ` Marc Zyngier
  2014-05-08  9:32 ` [PATCH v4 8/9] kvmtool: convert net " Marc Zyngier
  2014-05-08  9:32 ` [PATCH v4 9/9] kvmtool: virtio: enable arm/arm64 support for bi-endianness Marc Zyngier
  8 siblings, 0 replies; 13+ messages in thread
From: Marc Zyngier @ 2014-05-08  9:32 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: Pekka Enberg, Will Deacon

Configure the queues to follow the guest endianness, and make sure
the configuration space is doing the same.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 tools/kvm/virtio/blk.c | 31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/tools/kvm/virtio/blk.c b/tools/kvm/virtio/blk.c
index 4bed3a9..edfa8e6 100644
--- a/tools/kvm/virtio/blk.c
+++ b/tools/kvm/virtio/blk.c
@@ -77,13 +77,15 @@ void virtio_blk_complete(void *param, long len)
 		bdev->vdev.ops->signal_vq(req->kvm, &bdev->vdev, queueid);
 }
 
-static void virtio_blk_do_io_request(struct kvm *kvm, struct blk_dev_req *req)
+static void virtio_blk_do_io_request(struct kvm *kvm, struct virt_queue *vq, struct blk_dev_req *req)
 {
 	struct virtio_blk_outhdr *req_hdr;
 	ssize_t block_cnt;
 	struct blk_dev *bdev;
 	struct iovec *iov;
 	u16 out, in;
+	u32 type;
+	u64 sector;
 
 	block_cnt	= -1;
 	bdev		= req->bdev;
@@ -92,13 +94,16 @@ static void virtio_blk_do_io_request(struct kvm *kvm, struct blk_dev_req *req)
 	in		= req->in;
 	req_hdr		= iov[0].iov_base;
 
-	switch (req_hdr->type) {
+	type = virtio_guest_to_host_u32(vq, req_hdr->type);
+	sector = virtio_guest_to_host_u64(vq, req_hdr->sector);
+
+	switch (type) {
 	case VIRTIO_BLK_T_IN:
-		block_cnt = disk_image__read(bdev->disk, req_hdr->sector,
+		block_cnt = disk_image__read(bdev->disk, sector,
 				iov + 1, in + out - 2, req);
 		break;
 	case VIRTIO_BLK_T_OUT:
-		block_cnt = disk_image__write(bdev->disk, req_hdr->sector,
+		block_cnt = disk_image__write(bdev->disk, sector,
 				iov + 1, in + out - 2, req);
 		break;
 	case VIRTIO_BLK_T_FLUSH:
@@ -112,7 +117,7 @@ static void virtio_blk_do_io_request(struct kvm *kvm, struct blk_dev_req *req)
 		virtio_blk_complete(req, block_cnt);
 		break;
 	default:
-		pr_warning("request type %d", req_hdr->type);
+		pr_warning("request type %d", type);
 		block_cnt	= -1;
 		break;
 	}
@@ -130,7 +135,7 @@ static void virtio_blk_do_io(struct kvm *kvm, struct virt_queue *vq, struct blk_
 					&req->in, head, kvm);
 		req->vq		= vq;
 
-		virtio_blk_do_io_request(kvm, req);
+		virtio_blk_do_io_request(kvm, vq, req);
 	}
 }
 
@@ -152,8 +157,21 @@ static u32 get_host_features(struct kvm *kvm, void *dev)
 static void set_guest_features(struct kvm *kvm, void *dev, u32 features)
 {
 	struct blk_dev *bdev = dev;
+	struct virtio_blk_config *conf = &bdev->blk_config;
+	struct virtio_blk_geometry *geo = &conf->geometry;
 
 	bdev->features = features;
+
+	conf->capacity = virtio_host_to_guest_u64(&bdev->vdev, conf->capacity);
+	conf->size_max = virtio_host_to_guest_u32(&bdev->vdev, conf->size_max);
+	conf->seg_max = virtio_host_to_guest_u32(&bdev->vdev, conf->seg_max);
+
+	/* Geometry */
+	geo->cylinders = virtio_host_to_guest_u16(&bdev->vdev, geo->cylinders);
+
+	conf->blk_size = virtio_host_to_guest_u32(&bdev->vdev, conf->blk_size);
+	conf->min_io_size = virtio_host_to_guest_u16(&bdev->vdev, conf->min_io_size);
+	conf->opt_io_size = virtio_host_to_guest_u32(&bdev->vdev, conf->opt_io_size);
 }
 
 static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
@@ -170,6 +188,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
 	p		= virtio_get_vq(kvm, queue->pfn, page_size);
 
 	vring_init(&queue->vring, VIRTIO_BLK_QUEUE_SIZE, p, align);
+	virtio_init_device_vq(&bdev->vdev, queue);
 
 	return 0;
 }
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 8/9] kvmtool: convert net backend to support bi-endianness
  2014-05-08  9:32 [PATCH v4 0/9] kvmtool: handle guests of a different endianness Marc Zyngier
                   ` (6 preceding siblings ...)
  2014-05-08  9:32 ` [PATCH v4 7/9] kvmtool: convert blk " Marc Zyngier
@ 2014-05-08  9:32 ` Marc Zyngier
  2014-05-08  9:32 ` [PATCH v4 9/9] kvmtool: virtio: enable arm/arm64 support for bi-endianness Marc Zyngier
  8 siblings, 0 replies; 13+ messages in thread
From: Marc Zyngier @ 2014-05-08  9:32 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: Pekka Enberg, Will Deacon

Configure the queues to follow the guest endianness, and make sure
the configuration space is doing the same.

Extra care is taken for the handling of the virtio_net_hdr structures
on both the TX and RX ends.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 tools/kvm/virtio/net.c | 45 ++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 40 insertions(+), 5 deletions(-)

diff --git a/tools/kvm/virtio/net.c b/tools/kvm/virtio/net.c
index 82dbb88..c8af3859 100644
--- a/tools/kvm/virtio/net.c
+++ b/tools/kvm/virtio/net.c
@@ -73,6 +73,24 @@ static bool has_virtio_feature(struct net_dev *ndev, u32 feature)
 	return ndev->features & (1 << feature);
 }
 
+static void virtio_net_fix_tx_hdr(struct virtio_net_hdr *hdr, struct net_dev *ndev)
+{
+	hdr->hdr_len		= virtio_guest_to_host_u16(&ndev->vdev, hdr->hdr_len);
+	hdr->gso_size		= virtio_guest_to_host_u16(&ndev->vdev, hdr->gso_size);
+	hdr->csum_start		= virtio_guest_to_host_u16(&ndev->vdev, hdr->csum_start);
+	hdr->csum_offset	= virtio_guest_to_host_u16(&ndev->vdev, hdr->csum_offset);
+}
+
+static void virtio_net_fix_rx_hdr(struct virtio_net_hdr_mrg_rxbuf *hdr, struct net_dev *ndev)
+{
+	hdr->hdr.hdr_len	= virtio_host_to_guest_u16(&ndev->vdev, hdr->hdr.hdr_len);
+	hdr->hdr.gso_size	= virtio_host_to_guest_u16(&ndev->vdev, hdr->hdr.gso_size);
+	hdr->hdr.csum_start	= virtio_host_to_guest_u16(&ndev->vdev, hdr->hdr.csum_start);
+	hdr->hdr.csum_offset	= virtio_host_to_guest_u16(&ndev->vdev, hdr->hdr.csum_offset);
+	if (has_virtio_feature(ndev, VIRTIO_NET_F_MRG_RXBUF))
+		hdr->num_buffers	= virtio_host_to_guest_u16(&ndev->vdev, hdr->num_buffers);
+}
+
 static void *virtio_net_rx_thread(void *p)
 {
 	struct iovec iov[VIRTIO_NET_QUEUE_SIZE];
@@ -106,6 +124,7 @@ static void *virtio_net_rx_thread(void *p)
 				.iov_len  = sizeof(buffer),
 			};
 			struct virtio_net_hdr_mrg_rxbuf *hdr;
+			int i;
 
 			len = ndev->ops->rx(&dummy_iov, 1, ndev);
 			if (len < 0) {
@@ -114,16 +133,20 @@ static void *virtio_net_rx_thread(void *p)
 				goto out_err;
 			}
 
-			copied = 0;
+			copied = i = 0;
 			head = virt_queue__get_iov(vq, iov, &out, &in, kvm);
-			hdr = (void *)iov[0].iov_base;
+			hdr = iov[0].iov_base;
 			while (copied < len) {
 				size_t iovsize = min_t(size_t, len - copied, iov_size(iov, in));
 
 				memcpy_toiovec(iov, buffer + copied, iovsize);
 				copied += iovsize;
-				if (has_virtio_feature(ndev, VIRTIO_NET_F_MRG_RXBUF))
-					hdr->num_buffers++;
+				if (i++ == 0)
+					virtio_net_fix_rx_hdr(hdr, ndev);
+				if (has_virtio_feature(ndev, VIRTIO_NET_F_MRG_RXBUF)) {
+					u16 num_buffers = virtio_guest_to_host_u16(vq, hdr->num_buffers);
+					hdr->num_buffers = virtio_host_to_guest_u16(vq, num_buffers + 1);
+				}
 				virt_queue__set_used_elem(vq, head, iovsize);
 				if (copied == len)
 					break;
@@ -170,11 +193,14 @@ static void *virtio_net_tx_thread(void *p)
 		mutex_unlock(&ndev->io_lock[id]);
 
 		while (virt_queue__available(vq)) {
+			struct virtio_net_hdr *hdr;
 			head = virt_queue__get_iov(vq, iov, &out, &in, kvm);
+			hdr = iov[0].iov_base;
+			virtio_net_fix_tx_hdr(hdr, ndev);
 			len = ndev->ops->tx(iov, out, ndev);
 			if (len < 0) {
 				pr_warning("%s: tx on vq %u failed (%d)\n",
-						__func__, id, len);
+						__func__, id, errno);
 				goto out_err;
 			}
 
@@ -420,9 +446,14 @@ static int virtio_net__vhost_set_features(struct net_dev *ndev)
 static void set_guest_features(struct kvm *kvm, void *dev, u32 features)
 {
 	struct net_dev *ndev = dev;
+	struct virtio_net_config *conf = &ndev->config;
 
 	ndev->features = features;
 
+	conf->status = virtio_host_to_guest_u16(&ndev->vdev, conf->status);
+	conf->max_virtqueue_pairs = virtio_host_to_guest_u16(&ndev->vdev,
+							     conf->max_virtqueue_pairs);
+
 	if (ndev->mode == NET_MODE_TAP) {
 		if (!virtio_net__tap_init(ndev))
 			die_perror("You have requested a TAP device, but creation of one has failed because");
@@ -459,6 +490,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
 	p		= virtio_get_vq(kvm, queue->pfn, page_size);
 
 	vring_init(&queue->vring, VIRTIO_NET_QUEUE_SIZE, p, align);
+	virtio_init_device_vq(&ndev->vdev, queue);
 
 	mutex_init(&ndev->io_lock[vq]);
 	pthread_cond_init(&ndev->io_cond[vq], NULL);
@@ -475,6 +507,9 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
 		return 0;
 	}
 
+	if (queue->endian != VIRTIO_ENDIAN_HOST)
+		die_perror("VHOST requires VIRTIO_ENDIAN_HOST");
+
 	state.num = queue->vring.num;
 	r = ioctl(ndev->vhost_fd, VHOST_SET_VRING_NUM, &state);
 	if (r < 0)
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v4 9/9] kvmtool: virtio: enable arm/arm64 support for bi-endianness
  2014-05-08  9:32 [PATCH v4 0/9] kvmtool: handle guests of a different endianness Marc Zyngier
                   ` (7 preceding siblings ...)
  2014-05-08  9:32 ` [PATCH v4 8/9] kvmtool: convert net " Marc Zyngier
@ 2014-05-08  9:32 ` Marc Zyngier
  2014-05-08 10:06   ` Peter Maydell
  2014-05-08 10:43   ` Will Deacon
  8 siblings, 2 replies; 13+ messages in thread
From: Marc Zyngier @ 2014-05-08  9:32 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: Pekka Enberg, Will Deacon

Implement the kvm_cpu__get_endianness call for both AArch32 and
AArch64, and advertise the bi-endianness support.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 tools/kvm/arm/aarch32/kvm-cpu.c                  | 14 ++++++++
 tools/kvm/arm/aarch64/include/kvm/kvm-cpu-arch.h |  2 ++
 tools/kvm/arm/aarch64/kvm-cpu.c                  | 43 ++++++++++++++++++++++++
 tools/kvm/arm/include/arm-common/kvm-arch.h      |  2 ++
 4 files changed, 61 insertions(+)

diff --git a/tools/kvm/arm/aarch32/kvm-cpu.c b/tools/kvm/arm/aarch32/kvm-cpu.c
index bd71037..464b473 100644
--- a/tools/kvm/arm/aarch32/kvm-cpu.c
+++ b/tools/kvm/arm/aarch32/kvm-cpu.c
@@ -1,5 +1,6 @@
 #include "kvm/kvm-cpu.h"
 #include "kvm/kvm.h"
+#include "kvm/virtio.h"
 
 #include <asm/ptrace.h>
 
@@ -76,6 +77,19 @@ void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu)
 		die_perror("KVM_SET_ONE_REG failed (pc)");
 }
 
+int kvm_cpu__get_endianness(struct kvm_cpu *vcpu)
+{
+	struct kvm_one_reg reg;
+	u32 data;
+
+	reg.id = ARM_CORE_REG(usr_regs.ARM_cpsr);
+	reg.addr = (u64)(unsigned long)&data;
+	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
+		die("KVM_GET_ONE_REG failed (cpsr)");
+
+	return (data & PSR_E_BIT) ? VIRTIO_ENDIAN_BE : VIRTIO_ENDIAN_LE;
+}
+
 void kvm_cpu__show_code(struct kvm_cpu *vcpu)
 {
 	struct kvm_one_reg reg;
diff --git a/tools/kvm/arm/aarch64/include/kvm/kvm-cpu-arch.h b/tools/kvm/arm/aarch64/include/kvm/kvm-cpu-arch.h
index 7d70c3b..2ffa7ad 100644
--- a/tools/kvm/arm/aarch64/include/kvm/kvm-cpu-arch.h
+++ b/tools/kvm/arm/aarch64/include/kvm/kvm-cpu-arch.h
@@ -13,5 +13,7 @@
 #define ARM_MPIDR_HWID_BITMASK	0xFF00FFFFFFUL
 #define ARM_CPU_ID		3, 0, 0, 0
 #define ARM_CPU_ID_MPIDR	5
+#define ARM_CPU_CTRL		3, 0, 1, 0
+#define ARM_CPU_CTRL_SCTLR_EL1	0
 
 #endif /* KVM__KVM_CPU_ARCH_H */
diff --git a/tools/kvm/arm/aarch64/kvm-cpu.c b/tools/kvm/arm/aarch64/kvm-cpu.c
index 059e42c..71a2a3a 100644
--- a/tools/kvm/arm/aarch64/kvm-cpu.c
+++ b/tools/kvm/arm/aarch64/kvm-cpu.c
@@ -1,12 +1,17 @@
 #include "kvm/kvm-cpu.h"
 #include "kvm/kvm.h"
+#include "kvm/virtio.h"
 
 #include <asm/ptrace.h>
 
 #define COMPAT_PSR_F_BIT	0x00000040
 #define COMPAT_PSR_I_BIT	0x00000080
+#define COMPAT_PSR_E_BIT	0x00000200
 #define COMPAT_PSR_MODE_SVC	0x00000013
 
+#define SCTLR_EL1_E0E_MASK	(1 << 24)
+#define SCTLR_EL1_EE_MASK	(1 << 25)
+
 #define ARM64_CORE_REG(x)	(KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
 				 KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
 
@@ -133,6 +138,44 @@ void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu)
 		return reset_vcpu_aarch64(vcpu);
 }
 
+int kvm_cpu__get_endianness(struct kvm_cpu *vcpu)
+{
+	struct kvm_one_reg reg;
+	u64 psr;
+	u64 sctlr;
+
+	/*
+	 * Quoting the definition given by Peter Maydell:
+	 *
+	 * "Endianness of the CPU which does the virtio reset at the
+	 * point when it does that reset"
+	 *
+	 * We first check for an AArch32 guest: its endianness can
+	 * change when using SETEND, which affects the CPSR.E bit.
+	 *
+	 * If we're AArch64, use SCTLR_EL1.E0E if access comes from
+	 * EL0, and SCTLR_EL1.EE if access comes from EL1.
+	 */
+	reg.id = ARM64_CORE_REG(regs.pstate);
+	reg.addr = (u64)&psr;
+	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
+		die("KVM_GET_ONE_REG failed (spsr[EL1])");
+
+	if (psr & PSR_MODE32_BIT)
+		return (psr & COMPAT_PSR_E_BIT) ? VIRTIO_ENDIAN_BE : VIRTIO_ENDIAN_LE;
+
+	reg.id = ARM64_SYS_REG(ARM_CPU_CTRL, ARM_CPU_CTRL_SCTLR_EL1);
+	reg.addr = (u64)&sctlr;
+	if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, &reg) < 0)
+		die("KVM_GET_ONE_REG failed (SCTLR_EL1)");
+
+	if ((psr & PSR_MODE_MASK) == PSR_MODE_EL0t)
+		sctlr &= SCTLR_EL1_E0E_MASK;
+	else
+		sctlr &= SCTLR_EL1_EE_MASK;
+	return sctlr ? VIRTIO_ENDIAN_BE : VIRTIO_ENDIAN_LE;
+}
+
 void kvm_cpu__show_code(struct kvm_cpu *vcpu)
 {
 	struct kvm_one_reg reg;
diff --git a/tools/kvm/arm/include/arm-common/kvm-arch.h b/tools/kvm/arm/include/arm-common/kvm-arch.h
index b6c4bf8..5d2fab2 100644
--- a/tools/kvm/arm/include/arm-common/kvm-arch.h
+++ b/tools/kvm/arm/include/arm-common/kvm-arch.h
@@ -35,6 +35,8 @@
 #define VIRTIO_DEFAULT_TRANS(kvm)	\
 	((kvm)->cfg.arch.virtio_trans_pci ? VIRTIO_PCI : VIRTIO_MMIO)
 
+#define VIRTIO_RING_ENDIAN	(VIRTIO_ENDIAN_LE | VIRTIO_ENDIAN_BE)
+
 static inline bool arm_addr_in_ioport_region(u64 phys_addr)
 {
 	u64 limit = KVM_IOPORT_AREA + ARM_IOPORT_SIZE;
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 9/9] kvmtool: virtio: enable arm/arm64 support for bi-endianness
  2014-05-08  9:32 ` [PATCH v4 9/9] kvmtool: virtio: enable arm/arm64 support for bi-endianness Marc Zyngier
@ 2014-05-08 10:06   ` Peter Maydell
  2014-05-08 10:15     ` Marc Zyngier
  2014-05-08 10:43   ` Will Deacon
  1 sibling, 1 reply; 13+ messages in thread
From: Peter Maydell @ 2014-05-08 10:06 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: kvmarm@lists.cs.columbia.edu, kvm-devel, Pekka Enberg,
	Will Deacon

On 8 May 2014 10:32, Marc Zyngier <marc.zyngier@arm.com> wrote:
> +int kvm_cpu__get_endianness(struct kvm_cpu *vcpu)
> +{
> +       struct kvm_one_reg reg;
> +       u64 psr;
> +       u64 sctlr;
> +
> +       /*
> +        * Quoting the definition given by Peter Maydell:
> +        *
> +        * "Endianness of the CPU which does the virtio reset at the
> +        * point when it does that reset"
> +        *
> +        * We first check for an AArch32 guest: its endianness can
> +        * change when using SETEND, which affects the CPSR.E bit.
> +        *
> +        * If we're AArch64, use SCTLR_EL1.E0E if access comes from
> +        * EL0, and SCTLR_EL1.EE if access comes from EL1.
> +        */

I note that the set of checks described here match the logic
of the ARM ARM BigEndian() pseudocode function, which is
a good sign.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 9/9] kvmtool: virtio: enable arm/arm64 support for bi-endianness
  2014-05-08 10:06   ` Peter Maydell
@ 2014-05-08 10:15     ` Marc Zyngier
  0 siblings, 0 replies; 13+ messages in thread
From: Marc Zyngier @ 2014-05-08 10:15 UTC (permalink / raw)
  To: Peter Maydell
  Cc: kvmarm@lists.cs.columbia.edu, kvm-devel, Pekka Enberg,
	Will Deacon

On 08/05/14 11:06, Peter Maydell wrote:
> On 8 May 2014 10:32, Marc Zyngier <marc.zyngier@arm.com> wrote:
>> +int kvm_cpu__get_endianness(struct kvm_cpu *vcpu)
>> +{
>> +       struct kvm_one_reg reg;
>> +       u64 psr;
>> +       u64 sctlr;
>> +
>> +       /*
>> +        * Quoting the definition given by Peter Maydell:
>> +        *
>> +        * "Endianness of the CPU which does the virtio reset at the
>> +        * point when it does that reset"
>> +        *
>> +        * We first check for an AArch32 guest: its endianness can
>> +        * change when using SETEND, which affects the CPSR.E bit.
>> +        *
>> +        * If we're AArch64, use SCTLR_EL1.E0E if access comes from
>> +        * EL0, and SCTLR_EL1.EE if access comes from EL1.
>> +        */
> 
> I note that the set of checks described here match the logic
> of the ARM ARM BigEndian() pseudocode function, which is
> a good sign.

Pure luck. Or maybe I'm now going slightly mad. Either way, consistency
is good... ;-)

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 9/9] kvmtool: virtio: enable arm/arm64 support for bi-endianness
  2014-05-08  9:32 ` [PATCH v4 9/9] kvmtool: virtio: enable arm/arm64 support for bi-endianness Marc Zyngier
  2014-05-08 10:06   ` Peter Maydell
@ 2014-05-08 10:43   ` Will Deacon
  1 sibling, 0 replies; 13+ messages in thread
From: Will Deacon @ 2014-05-08 10:43 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, Pekka Enberg

On Thu, May 08, 2014 at 10:32:48AM +0100, Marc Zyngier wrote:
> Implement the kvm_cpu__get_endianness call for both AArch32 and
> AArch64, and advertise the bi-endianness support.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

  Acked-by: Will Deacon <will.deacon@arm.com>

Will

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2014-05-08 10:44 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-08  9:32 [PATCH v4 0/9] kvmtool: handle guests of a different endianness Marc Zyngier
2014-05-08  9:32 ` [PATCH v4 1/9] kvmtool: pass trapped vcpu to MMIO accessors Marc Zyngier
2014-05-08  9:32 ` [PATCH v4 2/9] kvmtool: virt_queue configuration based on endianness Marc Zyngier
2014-05-08  9:32 ` [PATCH v4 3/9] kvmtool: sample CPU endianness on virtio-mmio device reset Marc Zyngier
2014-05-08  9:32 ` [PATCH v4 4/9] kvmtool: add queue endianness initializer Marc Zyngier
2014-05-08  9:32 ` [PATCH v4 5/9] kvmtool: convert console backend to support bi-endianness Marc Zyngier
2014-05-08  9:32 ` [PATCH v4 6/9] kvmtool: convert 9p " Marc Zyngier
2014-05-08  9:32 ` [PATCH v4 7/9] kvmtool: convert blk " Marc Zyngier
2014-05-08  9:32 ` [PATCH v4 8/9] kvmtool: convert net " Marc Zyngier
2014-05-08  9:32 ` [PATCH v4 9/9] kvmtool: virtio: enable arm/arm64 support for bi-endianness Marc Zyngier
2014-05-08 10:06   ` Peter Maydell
2014-05-08 10:15     ` Marc Zyngier
2014-05-08 10:43   ` Will Deacon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.