@@ -36,7 +36,7 @@ struct kvm_arm_target {
int kvm_cpu__register_kvm_arm_target(struct kvm_arm_target *target);
-static inline bool kvm_cpu__emulate_io(struct kvm *kvm, u16 port, void *data,
+static inline bool kvm_cpu__emulate_io(struct kvm_cpu *vcpu, u16 port, void *data,
int direction, int size, u32 count)
{
return false;
@@ -106,7 +106,7 @@ bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data,
} 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(vcpu->kvm, port, data, direction, len, 1);
+ return kvm__emulate_io(vcpu, port, data, direction, len, 1);
} else if (arm_addr_in_pci_region(phys_addr)) {
return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
}
@@ -295,7 +295,7 @@ static void kbd_reset(void)
/*
* Called when the OS has written to one of the keyboard's ports (0x60 or 0x64)
*/
-static bool kbd_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool kbd_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
switch (port) {
case I8042_COMMAND_REG: {
@@ -319,12 +319,12 @@ static bool kbd_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data,
return true;
}
-static bool kbd_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool kbd_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
switch (port) {
case I8042_COMMAND_REG: {
u8 value = ioport__read8(data);
- kbd_write_command(kvm, value);
+ kbd_write_command(vcpu->kvm, value);
break;
}
case I8042_DATA_REG: {
@@ -63,7 +63,7 @@ int pci_shmem__register_mem(struct shmem_info *si)
return 0;
}
-static bool shmem_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool shmem_pci__io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
u16 offset = port - ivshmem_registers;
@@ -82,7 +82,7 @@ static bool shmem_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port, v
return true;
}
-static bool shmem_pci__io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool shmem_pci__io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
u16 offset = port - ivshmem_registers;
@@ -37,7 +37,7 @@ static inline unsigned char bin2bcd(unsigned val)
return ((val / 10) << 4) + val % 10;
}
-static bool cmos_ram_data_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool cmos_ram_data_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
struct tm *tm;
time_t ti;
@@ -91,7 +91,7 @@ static bool cmos_ram_data_in(struct ioport *ioport, struct kvm *kvm, u16 port, v
return true;
}
-static bool cmos_ram_data_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool cmos_ram_data_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
switch (rtc.cmos_idx) {
case RTC_REG_C:
@@ -111,11 +111,11 @@ static struct ioport_operations cmos_ram_data_ioport_ops = {
.io_in = cmos_ram_data_in,
};
-static bool cmos_ram_index_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool cmos_ram_index_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
u8 value = ioport__read8(data);
- kvm->nmi_disabled = value & (1UL << 7);
+ vcpu->kvm->nmi_disabled = value & (1UL << 7);
rtc.cmos_idx = value & ~(1UL << 7);
return true;
@@ -218,7 +218,7 @@ void serial8250__inject_sysrq(struct kvm *kvm, char sysrq)
sysrq_pending = sysrq;
}
-static bool serial8250_out(struct ioport *ioport, struct kvm *kvm, u16 port,
+static bool serial8250_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port,
void *data, int size)
{
struct serial8250_device *dev = ioport->priv;
@@ -251,7 +251,7 @@ static bool serial8250_out(struct ioport *ioport, struct kvm *kvm, u16 port,
dev->lsr &= ~UART_LSR_TEMT;
if (dev->txcnt == FIFO_LEN / 2)
dev->lsr &= ~UART_LSR_THRE;
- serial8250_flush_tx(kvm, dev);
+ serial8250_flush_tx(vcpu->kvm, dev);
} else {
/* Should never happpen */
dev->lsr &= ~(UART_LSR_TEMT | UART_LSR_THRE);
@@ -286,7 +286,7 @@ static bool serial8250_out(struct ioport *ioport, struct kvm *kvm, u16 port,
break;
}
- serial8250_update_irq(kvm, dev);
+ serial8250_update_irq(vcpu->kvm, dev);
mutex_unlock(&dev->mutex);
@@ -312,7 +312,7 @@ static void serial8250_rx(struct serial8250_device *dev, void *data)
}
}
-static bool serial8250_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool serial8250_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
struct serial8250_device *dev = ioport->priv;
u16 offset;
@@ -358,7 +358,7 @@ static bool serial8250_in(struct ioport *ioport, struct kvm *kvm, u16 port, void
break;
}
- serial8250_update_irq(kvm, dev);
+ serial8250_update_irq(vcpu->kvm, dev);
mutex_unlock(&dev->mutex);
@@ -18,12 +18,12 @@
#include <inttypes.h>
#include <unistd.h>
-static bool vesa_pci_io_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool vesa_pci_io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
return true;
}
-static bool vesa_pci_io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool vesa_pci_io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
return true;
}
@@ -2,6 +2,7 @@
#define KVM__IOPORT_H
#include "kvm/devices.h"
+#include "kvm/kvm-cpu.h"
#include "kvm/rbtree-interval.h"
#include <stdbool.h>
@@ -27,8 +28,8 @@ struct ioport {
};
struct ioport_operations {
- bool (*io_in)(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size);
- bool (*io_out)(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size);
+ bool (*io_in)(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size);
+ bool (*io_out)(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size);
void (*generate_fdt_node)(struct ioport *ioport, void *fdt,
void (*generate_irq_prop)(void *fdt, u8 irq));
};
@@ -83,7 +83,7 @@ int kvm_timer__init(struct kvm *kvm);
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_io(struct kvm_cpu *vcpu, u16 port, void *data, int direction, int size, u32 count);
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,
@@ -172,12 +172,13 @@ static void ioport_error(u16 port, void *data, int direction, int size, u32 coun
fprintf(stderr, "IO error: %s port=%x, size=%d, count=%u\n", to_direction(direction), port, size, count);
}
-bool kvm__emulate_io(struct kvm *kvm, u16 port, void *data, int direction, int size, u32 count)
+bool kvm__emulate_io(struct kvm_cpu *vcpu, u16 port, void *data, int direction, int size, u32 count)
{
struct ioport_operations *ops;
bool ret = false;
struct ioport *entry;
void *ptr = data;
+ struct kvm *kvm = vcpu->kvm;
br_read_lock();
entry = ioport_search(&ioport_tree, port);
@@ -188,9 +189,9 @@ bool kvm__emulate_io(struct kvm *kvm, u16 port, void *data, int direction, int s
while (count--) {
if (direction == KVM_EXIT_IO_IN && ops->io_in)
- ret = ops->io_in(entry, kvm, port, ptr, size);
+ ret = ops->io_in(entry, vcpu, port, ptr, size);
else if (ops->io_out)
- ret = ops->io_out(entry, kvm, port, ptr, size);
+ ret = ops->io_out(entry, vcpu, port, ptr, size);
ptr += size;
}
@@ -123,7 +123,7 @@ int kvm_cpu__start(struct kvm_cpu *cpu)
case KVM_EXIT_IO: {
bool ret;
- ret = kvm_cpu__emulate_io(cpu->kvm,
+ ret = kvm_cpu__emulate_io(cpu,
cpu->kvm_run->io.port,
(u8 *)cpu->kvm_run +
cpu->kvm_run->io.data_offset,
@@ -52,7 +52,7 @@ static void *pci_config_address_ptr(u16 port)
return base + offset;
}
-static bool pci_config_address_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool pci_config_address_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
void *p = pci_config_address_ptr(port);
@@ -61,7 +61,7 @@ static bool pci_config_address_out(struct ioport *ioport, struct kvm *kvm, u16 p
return true;
}
-static bool pci_config_address_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool pci_config_address_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
void *p = pci_config_address_ptr(port);
@@ -86,7 +86,7 @@ static bool pci_device_exists(u8 bus_number, u8 device_number, u8 function_numbe
return !IS_ERR_OR_NULL(device__find_dev(DEVICE_BUS_PCI, device_number));
}
-static bool pci_config_data_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool pci_config_data_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
/*
* If someone accesses PCI configuration space offsets that are not
@@ -94,12 +94,12 @@ static bool pci_config_data_out(struct ioport *ioport, struct kvm *kvm, u16 port
*/
pci_config_address.reg_offset = port - PCI_CONFIG_DATA;
- pci__config_wr(kvm, pci_config_address, data, size);
+ pci__config_wr(vcpu->kvm, pci_config_address, data, size);
return true;
}
-static bool pci_config_data_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool pci_config_data_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
/*
* If someone accesses PCI configuration space offsets that are not
@@ -107,7 +107,7 @@ static bool pci_config_data_in(struct ioport *ioport, struct kvm *kvm, u16 port,
*/
pci_config_address.reg_offset = port - PCI_CONFIG_DATA;
- pci__config_rd(kvm, pci_config_address, data, size);
+ pci__config_rd(vcpu->kvm, pci_config_address, data, size);
return true;
}
@@ -66,7 +66,7 @@ struct kvm_cpu {
void kvm_cpu__irq(struct kvm_cpu *vcpu, int pin, int level);
/* This is never actually called on PPC. */
-static inline bool kvm_cpu__emulate_io(struct kvm *kvm, u16 port, void *data, int direction, int size, u32 count)
+static inline bool kvm_cpu__emulate_io(struct kvm_cpu *vcpu, u16 port, void *data, int direction, int size, u32 count)
{
return false;
}
@@ -41,7 +41,7 @@ static inline bool spapr_phb_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data,
if ((phys_addr >= SPAPR_PCI_IO_WIN_ADDR) &&
(phys_addr < SPAPR_PCI_IO_WIN_ADDR +
SPAPR_PCI_IO_WIN_SIZE)) {
- return kvm__emulate_io(vcpu->kvm, phys_addr - SPAPR_PCI_IO_WIN_ADDR,
+ return kvm__emulate_io(vcpu, phys_addr - SPAPR_PCI_IO_WIN_ADDR,
data, is_write ? KVM_EXIT_IO_OUT :
KVM_EXIT_IO_IN,
len, 1);
@@ -2,6 +2,7 @@
#include "kvm/ioport.h"
#include "kvm/kvm.h"
+#include "kvm/kvm-cpu.h"
#include "kvm/virtio-pci-dev.h"
#include "kvm/irq.h"
#include "kvm/virtio.h"
@@ -108,14 +109,16 @@ static bool virtio_pci__specific_io_in(struct kvm *kvm, struct virtio_device *vd
return false;
}
-static bool virtio_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool virtio_pci__io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
unsigned long offset;
bool ret = true;
struct virtio_device *vdev;
struct virtio_pci *vpci;
+ struct kvm *kvm;
u32 val;
+ kvm = vcpu->kvm;
vdev = ioport->priv;
vpci = vdev->virtio;
offset = port - vpci->port_addr;
@@ -191,14 +194,16 @@ static bool virtio_pci__specific_io_out(struct kvm *kvm, struct virtio_device *v
return false;
}
-static bool virtio_pci__io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool virtio_pci__io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
unsigned long offset;
bool ret = true;
struct virtio_device *vdev;
struct virtio_pci *vpci;
+ struct kvm *kvm;
u32 val;
+ kvm = vcpu->kvm;
vdev = ioport->priv;
vpci = vdev->virtio;
offset = port - vpci->port_addr;
@@ -224,6 +229,8 @@ static bool virtio_pci__io_out(struct ioport *ioport, struct kvm *kvm, u16 port,
break;
case VIRTIO_PCI_STATUS:
vpci->status = ioport__read8(data);
+ if (!vpci->status) /* Sample endianness on reset */
+ vdev->endian = kvm_cpu__get_endianness(vcpu);
if (vdev->ops->notify_status)
vdev->ops->notify_status(kvm, vpci->dev, vpci->status);
break;
@@ -330,7 +337,7 @@ static void virtio_pci__io_mmio_callback(struct kvm_cpu *vcpu,
int direction = is_write ? KVM_EXIT_IO_OUT : KVM_EXIT_IO_IN;
u16 port = vpci->port_addr + (addr & (IOPORT_SIZE - 1));
- kvm__emulate_io(vpci->kvm, port, data, direction, len, 1);
+ kvm__emulate_io(vcpu, port, data, direction, len, 1);
}
int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
@@ -36,9 +36,9 @@ struct kvm_cpu {
* As these are such simple wrappers, let's have them in the header so they'll
* be cheaper to call:
*/
-static inline bool kvm_cpu__emulate_io(struct kvm *kvm, u16 port, void *data, int direction, int size, u32 count)
+static inline bool kvm_cpu__emulate_io(struct kvm_cpu *vcpu, u16 port, void *data, int direction, int size, u32 count)
{
- return kvm__emulate_io(kvm, port, data, direction, size, count);
+ return kvm__emulate_io(vcpu, port, data, direction, size, count);
}
static inline bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u8 is_write)
@@ -3,7 +3,7 @@
#include <stdlib.h>
#include <stdio.h>
-static bool debug_io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool debug_io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
return 0;
}
@@ -12,7 +12,7 @@ static struct ioport_operations debug_ops = {
.io_out = debug_io_out,
};
-static bool seabios_debug_io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool seabios_debug_io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
char ch;
@@ -27,12 +27,12 @@ static struct ioport_operations seabios_debug_ops = {
.io_out = seabios_debug_io_out,
};
-static bool dummy_io_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool dummy_io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
return true;
}
-static bool dummy_io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool dummy_io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
return true;
}
@@ -50,7 +50,7 @@ static struct ioport_operations dummy_write_only_ioport_ops = {
* The "fast A20 gate"
*/
-static bool ps2_control_a_io_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+static bool ps2_control_a_io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size)
{
/*
* A20 is always enabled.