@@ -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);
@@ -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;
@@ -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;
@@ -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);
@@ -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,
@@ -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);
}
@@ -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;
@@ -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 */
@@ -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",
@@ -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;
@@ -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
@@ -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;
@@ -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 */
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(-)