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

KVM: Clean up kvm_setup_pio()



Split kvm_setup_pio() into two functions, one to setup in/out pio
(kvm_emulate_pio()) and one to setup ins/outs pio (kvm_emulate_pio_string()).

Signed-off-by: default avatarLaurent Vivier <Laurent.Vivier@bull.net>
Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
parent e70669ab
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -539,8 +539,10 @@ int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data);

struct x86_emulate_ctxt;

int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
		  int size, unsigned long count, int string, int down,
int kvm_emulate_pio (struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
		     int size, unsigned port);
int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
			   int size, unsigned long count, int down,
			    gva_t address, int rep, unsigned port);
void kvm_emulate_cpuid(struct kvm_vcpu *vcpu);
int kvm_emulate_halt(struct kvm_vcpu *vcpu);
+39 −24
Original line number Diff line number Diff line
@@ -1735,37 +1735,28 @@ static void pio_string_write(struct kvm_io_device *pio_dev,
	}
}

int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
		  int size, unsigned long count, int string, int down,
		  gva_t address, int rep, unsigned port)
int kvm_emulate_pio (struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
		  int size, unsigned port)
{
	unsigned now, in_page;
	int i, ret = 0;
	int nr_pages = 1;
	struct page *page;
	struct kvm_io_device *pio_dev;

	vcpu->run->exit_reason = KVM_EXIT_IO;
	vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
	vcpu->run->io.size = size;
	vcpu->run->io.size = vcpu->pio.size = size;
	vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE;
	vcpu->run->io.count = count;
	vcpu->run->io.port = port;
	vcpu->pio.count = count;
	vcpu->pio.cur_count = count;
	vcpu->pio.size = size;
	vcpu->run->io.count = vcpu->pio.count = vcpu->pio.cur_count = 1;
	vcpu->run->io.port = vcpu->pio.port = port;
	vcpu->pio.in = in;
	vcpu->pio.port = port;
	vcpu->pio.string = string;
	vcpu->pio.down = down;
	vcpu->pio.guest_page_offset = offset_in_page(address);
	vcpu->pio.rep = rep;
	vcpu->pio.string = 0;
	vcpu->pio.down = 0;
	vcpu->pio.guest_page_offset = 0;
	vcpu->pio.rep = 0;

	pio_dev = vcpu_find_pio_dev(vcpu, port);
	if (!string) {
	kvm_arch_ops->cache_regs(vcpu);
	memcpy(vcpu->pio_data, &vcpu->regs[VCPU_REGS_RAX], 4);
	kvm_arch_ops->decache_regs(vcpu);

	pio_dev = vcpu_find_pio_dev(vcpu, port);
	if (pio_dev) {
		kernel_pio(pio_dev, vcpu, vcpu->pio_data);
		complete_pio(vcpu);
@@ -1773,6 +1764,29 @@ int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
	}
	return 0;
}
EXPORT_SYMBOL_GPL(kvm_emulate_pio);

int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
		  int size, unsigned long count, int down,
		  gva_t address, int rep, unsigned port)
{
	unsigned now, in_page;
	int i, ret = 0;
	int nr_pages = 1;
	struct page *page;
	struct kvm_io_device *pio_dev;

	vcpu->run->exit_reason = KVM_EXIT_IO;
	vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
	vcpu->run->io.size = vcpu->pio.size = size;
	vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE;
	vcpu->run->io.count = vcpu->pio.count = vcpu->pio.cur_count = count;
	vcpu->run->io.port = vcpu->pio.port = port;
	vcpu->pio.in = in;
	vcpu->pio.string = 1;
	vcpu->pio.down = down;
	vcpu->pio.guest_page_offset = offset_in_page(address);
	vcpu->pio.rep = rep;

	if (!count) {
		kvm_arch_ops->skip_emulated_instruction(vcpu);
@@ -1818,6 +1832,7 @@ int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
		}
	}

	pio_dev = vcpu_find_pio_dev(vcpu, port);
	if (!vcpu->pio.in) {
		/* string PIO write */
		ret = pio_copy_data(vcpu);
@@ -1834,7 +1849,7 @@ int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,

	return ret;
}
EXPORT_SYMBOL_GPL(kvm_setup_pio);
EXPORT_SYMBOL_GPL(kvm_emulate_pio_string);

static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
+1 −2
Original line number Diff line number Diff line
@@ -1005,8 +1005,7 @@ static int io_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
	rep = (io_info & SVM_IOIO_REP_MASK) != 0;
	down = (svm->vmcb->save.rflags & X86_EFLAGS_DF) != 0;

	return kvm_setup_pio(&svm->vcpu, kvm_run, in, size, 1, 0,
			     down, 0, rep, port);
	return kvm_emulate_pio(&svm->vcpu, kvm_run, in, size, port);
}

static int nop_on_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+1 −2
Original line number Diff line number Diff line
@@ -1785,8 +1785,7 @@ static int handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
	rep = (exit_qualification & 32) != 0;
	port = exit_qualification >> 16;

	return kvm_setup_pio(vcpu, kvm_run, in, size, 1, 0, down,
			     0, rep, port);
	return kvm_emulate_pio(vcpu, kvm_run, in, size, port);
}

static void
+2 −4
Original line number Diff line number Diff line
@@ -1123,12 +1123,11 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
	switch(b) {
	case 0x6c:		/* insb */
	case 0x6d:		/* insw/insd */
		 if (kvm_setup_pio(ctxt->vcpu, NULL,
		 if (kvm_emulate_pio_string(ctxt->vcpu, NULL,
				1, 					/* in */
				(d & ByteOp) ? 1 : op_bytes, 		/* size */
				rep_prefix ?
				address_mask(_regs[VCPU_REGS_RCX]) : 1,	/* count */
				1, 					/* strings */
				(_eflags & EFLG_DF),			/* down */
				register_address(ctxt->es_base,
						 _regs[VCPU_REGS_RDI]),	/* address */
@@ -1139,12 +1138,11 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
		return 0;
	case 0x6e:		/* outsb */
	case 0x6f:		/* outsw/outsd */
		if (kvm_setup_pio(ctxt->vcpu, NULL,
		if (kvm_emulate_pio_string(ctxt->vcpu, NULL,
				0, 					/* in */
				(d & ByteOp) ? 1 : op_bytes, 		/* size */
				rep_prefix ?
				address_mask(_regs[VCPU_REGS_RCX]) : 1,	/* count */
				1, 					/* strings */
				(_eflags & EFLG_DF),			/* down */
				register_address(override_base ?
						 *override_base : ctxt->ds_base,