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

Commit 65619eb5 authored by Eddie Dong's avatar Eddie Dong Committed by Avi Kivity
Browse files

KVM: In-kernel string pio write support



Add string pio write support to support some version of Windows.

Signed-off-by: default avatarYaozu (Eddie) Dong <eddie.dong@intel.com>
Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
parent 24cbc7e9
Loading
Loading
Loading
Loading
+37 −11
Original line number Diff line number Diff line
@@ -1760,18 +1760,35 @@ static int complete_pio(struct kvm_vcpu *vcpu)
	return 0;
}

void kernel_pio(struct kvm_io_device *pio_dev, struct kvm_vcpu *vcpu)
static void kernel_pio(struct kvm_io_device *pio_dev,
		       struct kvm_vcpu *vcpu,
		       void *pd)
{
	/* TODO: String I/O for in kernel device */

	if (vcpu->pio.in)
		kvm_iodevice_read(pio_dev, vcpu->pio.port,
				  vcpu->pio.size,
				  vcpu->pio_data);
				  pd);
	else
		kvm_iodevice_write(pio_dev, vcpu->pio.port,
				   vcpu->pio.size,
				   vcpu->pio_data);
				   pd);
}

static void pio_string_write(struct kvm_io_device *pio_dev,
			     struct kvm_vcpu *vcpu)
{
	struct kvm_pio_request *io = &vcpu->pio;
	void *pd = vcpu->pio_data;
	int i;

	for (i = 0; i < io->cur_count; i++) {
		kvm_iodevice_write(pio_dev, io->port,
				   io->size,
				   pd);
		pd += io->size;
	}
}

int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
@@ -1779,7 +1796,7 @@ int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
		  gva_t address, int rep, unsigned port)
{
	unsigned now, in_page;
	int i;
	int i, ret = 0;
	int nr_pages = 1;
	struct page *page;
	struct kvm_io_device *pio_dev;
@@ -1806,15 +1823,12 @@ int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
		memcpy(vcpu->pio_data, &vcpu->regs[VCPU_REGS_RAX], 4);
		kvm_arch_ops->decache_regs(vcpu);
		if (pio_dev) {
			kernel_pio(pio_dev, vcpu);
			kernel_pio(pio_dev, vcpu, vcpu->pio_data);
			complete_pio(vcpu);
			return 1;
		}
		return 0;
	}
	/* TODO: String I/O for in kernel device */
	if (pio_dev)
		printk(KERN_ERR "kvm_setup_pio: no string io support\n");

	if (!count) {
		kvm_arch_ops->skip_emulated_instruction(vcpu);
@@ -1862,9 +1876,21 @@ int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
		}
	}

	if (!vcpu->pio.in)
		return pio_copy_data(vcpu);
	return 0;
	if (!vcpu->pio.in) {
		/* string PIO write */
		ret = pio_copy_data(vcpu);
		if (ret >= 0 && pio_dev) {
			pio_string_write(pio_dev, vcpu);
			complete_pio(vcpu);
			if (vcpu->pio.count == 0)
				ret = 1;
		}
	} else if (pio_dev)
		printk(KERN_ERR "no string pio read support yet, "
		       "port %x size %d count %ld\n",
			port, size, count);

	return ret;
}
EXPORT_SYMBOL_GPL(kvm_setup_pio);