Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 92760499 authored by Laurent Vivier's avatar Laurent Vivier Committed by Avi Kivity
Browse files

KVM: kvm_io_device: extend in_range() to manage len and write attribute



Modify member in_range() of structure kvm_io_device to pass length and the type
of the I/O (write or read).

This modification allows to use kvm_io_device with coalesced MMIO.

Signed-off-by: default avatarLaurent Vivier <Laurent.Vivier@bull.net>
Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
parent 131d8279
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -195,11 +195,11 @@ int kvm_dev_ioctl_check_extension(long ext)
}

static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
					gpa_t addr)
					gpa_t addr, int len, int is_write)
{
	struct kvm_io_device *dev;

	dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr);
	dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr, len, is_write);

	return dev;
}
@@ -231,7 +231,7 @@ static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
	kvm_run->exit_reason = KVM_EXIT_MMIO;
	return 0;
mmio:
	mmio_dev = vcpu_find_mmio_dev(vcpu, p->addr);
	mmio_dev = vcpu_find_mmio_dev(vcpu, p->addr, p->size, !p->dir);
	if (mmio_dev) {
		if (!p->dir)
			kvm_iodevice_write(mmio_dev, p->addr, p->size,
+4 −2
Original line number Diff line number Diff line
@@ -460,7 +460,8 @@ static void pit_ioport_read(struct kvm_io_device *this,
	mutex_unlock(&pit_state->lock);
}

static int pit_in_range(struct kvm_io_device *this, gpa_t addr)
static int pit_in_range(struct kvm_io_device *this, gpa_t addr,
			int len, int is_write)
{
	return ((addr >= KVM_PIT_BASE_ADDRESS) &&
		(addr < KVM_PIT_BASE_ADDRESS + KVM_PIT_MEM_LENGTH));
@@ -501,7 +502,8 @@ static void speaker_ioport_read(struct kvm_io_device *this,
	mutex_unlock(&pit_state->lock);
}

static int speaker_in_range(struct kvm_io_device *this, gpa_t addr)
static int speaker_in_range(struct kvm_io_device *this, gpa_t addr,
			    int len, int is_write)
{
	return (addr == KVM_SPEAKER_BASE_ADDRESS);
}
+2 −1
Original line number Diff line number Diff line
@@ -346,7 +346,8 @@ static u32 elcr_ioport_read(void *opaque, u32 addr1)
	return s->elcr;
}

static int picdev_in_range(struct kvm_io_device *this, gpa_t addr)
static int picdev_in_range(struct kvm_io_device *this, gpa_t addr,
			   int len, int is_write)
{
	switch (addr) {
	case 0x20:
+2 −1
Original line number Diff line number Diff line
@@ -785,7 +785,8 @@ static void apic_mmio_write(struct kvm_io_device *this,

}

static int apic_mmio_range(struct kvm_io_device *this, gpa_t addr)
static int apic_mmio_range(struct kvm_io_device *this, gpa_t addr,
			   int len, int size)
{
	struct kvm_lapic *apic = (struct kvm_lapic *)this->private;
	int ret = 0;
+17 −11
Original line number Diff line number Diff line
@@ -1797,13 +1797,14 @@ static void kvm_init_msr_list(void)
 * Only apic need an MMIO device hook, so shortcut now..
 */
static struct kvm_io_device *vcpu_find_pervcpu_dev(struct kvm_vcpu *vcpu,
						gpa_t addr)
						gpa_t addr, int len,
						int is_write)
{
	struct kvm_io_device *dev;

	if (vcpu->arch.apic) {
		dev = &vcpu->arch.apic->dev;
		if (dev->in_range(dev, addr))
		if (dev->in_range(dev, addr, len, is_write))
			return dev;
	}
	return NULL;
@@ -1811,13 +1812,15 @@ static struct kvm_io_device *vcpu_find_pervcpu_dev(struct kvm_vcpu *vcpu,


static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
						gpa_t addr)
						gpa_t addr, int len,
						int is_write)
{
	struct kvm_io_device *dev;

	dev = vcpu_find_pervcpu_dev(vcpu, addr);
	dev = vcpu_find_pervcpu_dev(vcpu, addr, len, is_write);
	if (dev == NULL)
		dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr);
		dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr, len,
					  is_write);
	return dev;
}

@@ -1885,7 +1888,7 @@ static int emulator_read_emulated(unsigned long addr,
	 * Is this MMIO handled locally?
	 */
	mutex_lock(&vcpu->kvm->lock);
	mmio_dev = vcpu_find_mmio_dev(vcpu, gpa);
	mmio_dev = vcpu_find_mmio_dev(vcpu, gpa, bytes, 0);
	if (mmio_dev) {
		kvm_iodevice_read(mmio_dev, gpa, bytes, val);
		mutex_unlock(&vcpu->kvm->lock);
@@ -1940,7 +1943,7 @@ static int emulator_write_emulated_onepage(unsigned long addr,
	 * Is this MMIO handled locally?
	 */
	mutex_lock(&vcpu->kvm->lock);
	mmio_dev = vcpu_find_mmio_dev(vcpu, gpa);
	mmio_dev = vcpu_find_mmio_dev(vcpu, gpa, bytes, 1);
	if (mmio_dev) {
		kvm_iodevice_write(mmio_dev, gpa, bytes, val);
		mutex_unlock(&vcpu->kvm->lock);
@@ -2317,9 +2320,10 @@ static void pio_string_write(struct kvm_io_device *pio_dev,
}

static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu,
					       gpa_t addr)
					       gpa_t addr, int len,
					       int is_write)
{
	return kvm_io_bus_find_dev(&vcpu->kvm->pio_bus, addr);
	return kvm_io_bus_find_dev(&vcpu->kvm->pio_bus, addr, len, is_write);
}

int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
@@ -2351,7 +2355,7 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,

	kvm_x86_ops->skip_emulated_instruction(vcpu);

	pio_dev = vcpu_find_pio_dev(vcpu, port);
	pio_dev = vcpu_find_pio_dev(vcpu, port, size, !in);
	if (pio_dev) {
		kernel_pio(pio_dev, vcpu, vcpu->arch.pio_data);
		complete_pio(vcpu);
@@ -2433,7 +2437,9 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
		}
	}

	pio_dev = vcpu_find_pio_dev(vcpu, port);
	pio_dev = vcpu_find_pio_dev(vcpu, port,
				    vcpu->arch.pio.cur_count,
				    !vcpu->arch.pio.in);
	if (!vcpu->arch.pio.in) {
		/* string PIO write */
		ret = pio_copy_data(vcpu);
Loading