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

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

KVM: Change the emulator_{read,write,cmpxchg}_* functions to take a vcpu



... instead of a x86_emulate_ctxt, so that other callers can use it easily.

Signed-off-by: default avatarLaurent Vivier <Laurent.Vivier@bull.net>
Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
parent 0e5017d4
Loading
Loading
Loading
Loading
+11 −14
Original line number Diff line number Diff line
@@ -1020,9 +1020,8 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
static int emulator_read_std(unsigned long addr,
			     void *val,
			     unsigned int bytes,
			     struct x86_emulate_ctxt *ctxt)
			     struct kvm_vcpu *vcpu)
{
	struct kvm_vcpu *vcpu = ctxt->vcpu;
	void *data = val;

	while (bytes) {
@@ -1056,7 +1055,7 @@ static int emulator_read_std(unsigned long addr,
static int emulator_write_std(unsigned long addr,
			      const void *val,
			      unsigned int bytes,
			      struct x86_emulate_ctxt *ctxt)
			      struct kvm_vcpu *vcpu)
{
	printk(KERN_ERR "emulator_write_std: addr %lx n %d\n",
	       addr, bytes);
@@ -1083,9 +1082,8 @@ static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu,
static int emulator_read_emulated(unsigned long addr,
				  void *val,
				  unsigned int bytes,
				  struct x86_emulate_ctxt *ctxt)
				  struct kvm_vcpu *vcpu)
{
	struct kvm_vcpu      *vcpu = ctxt->vcpu;
	struct kvm_io_device *mmio_dev;
	gpa_t                 gpa;

@@ -1093,7 +1091,7 @@ static int emulator_read_emulated(unsigned long addr,
		memcpy(val, vcpu->mmio_data, bytes);
		vcpu->mmio_read_completed = 0;
		return X86EMUL_CONTINUE;
	} else if (emulator_read_std(addr, val, bytes, ctxt)
	} else if (emulator_read_std(addr, val, bytes, vcpu)
		   == X86EMUL_CONTINUE)
		return X86EMUL_CONTINUE;

@@ -1140,9 +1138,8 @@ static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
static int emulator_write_emulated_onepage(unsigned long addr,
					   const void *val,
					   unsigned int bytes,
					   struct x86_emulate_ctxt *ctxt)
					   struct kvm_vcpu *vcpu)
{
	struct kvm_vcpu      *vcpu = ctxt->vcpu;
	struct kvm_io_device *mmio_dev;
	gpa_t                 gpa = vcpu->mmu.gva_to_gpa(vcpu, addr);

@@ -1175,28 +1172,28 @@ static int emulator_write_emulated_onepage(unsigned long addr,
static int emulator_write_emulated(unsigned long addr,
				   const void *val,
				   unsigned int bytes,
				   struct x86_emulate_ctxt *ctxt)
				   struct kvm_vcpu *vcpu)
{
	/* Crossing a page boundary? */
	if (((addr + bytes - 1) ^ addr) & PAGE_MASK) {
		int rc, now;

		now = -addr & ~PAGE_MASK;
		rc = emulator_write_emulated_onepage(addr, val, now, ctxt);
		rc = emulator_write_emulated_onepage(addr, val, now, vcpu);
		if (rc != X86EMUL_CONTINUE)
			return rc;
		addr += now;
		val += now;
		bytes -= now;
	}
	return emulator_write_emulated_onepage(addr, val, bytes, ctxt);
	return emulator_write_emulated_onepage(addr, val, bytes, vcpu);
}

static int emulator_cmpxchg_emulated(unsigned long addr,
				     const void *old,
				     const void *new,
				     unsigned int bytes,
				     struct x86_emulate_ctxt *ctxt)
				     struct kvm_vcpu *vcpu)
{
	static int reported;

@@ -1204,7 +1201,7 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
		reported = 1;
		printk(KERN_WARNING "kvm: emulating exchange as write\n");
	}
	return emulator_write_emulated(addr, new, bytes, ctxt);
	return emulator_write_emulated(addr, new, bytes, vcpu);
}

static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg)
@@ -1266,7 +1263,7 @@ static void report_emulation_failure(struct x86_emulate_ctxt *ctxt)
	if (reported)
		return;

	emulator_read_std(rip_linear, (void *)opcodes, 4, ctxt);
	emulator_read_std(rip_linear, (void *)opcodes, 4, ctxt->vcpu);

	printk(KERN_ERR "emulation failed but !mmio_needed?"
	       " rip %lx %02x %02x %02x %02x\n",
+20 −15
Original line number Diff line number Diff line
@@ -420,7 +420,7 @@ struct operand {
#define insn_fetch(_type, _size, _eip)                                  \
({	unsigned long _x;						\
	rc = ops->read_std((unsigned long)(_eip) + ctxt->cs_base, &_x,	\
                                                  (_size), ctxt);       \
                                                  (_size), ctxt->vcpu); \
	if ( rc != 0 )							\
		goto done;						\
	(_eip) += (_size);						\
@@ -469,10 +469,12 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt,
	if (op_bytes == 2)
		op_bytes = 3;
	*address = 0;
	rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2, ctxt);
	rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2,
			   ctxt->vcpu);
	if (rc)
		return rc;
	rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes, ctxt);
	rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes,
			   ctxt->vcpu);
	return rc;
}

@@ -780,7 +782,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
		src.type = OP_MEM;
		src.ptr = (unsigned long *)cr2;
		if ((rc = ops->read_emulated((unsigned long)src.ptr,
					     &src.val, src.bytes, ctxt)) != 0)
					     &src.val, src.bytes, ctxt->vcpu)) != 0)
			goto done;
		src.orig_val = src.val;
		break;
@@ -850,7 +852,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
		}
		if (!(d & Mov) && /* optimisation - avoid slow emulated read */
		    ((rc = ops->read_emulated((unsigned long)dst.ptr,
					      &dst.val, dst.bytes, ctxt)) != 0))
					      &dst.val, dst.bytes, ctxt->vcpu)) != 0))
			goto done;
		break;
	}
@@ -963,7 +965,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
			dst.bytes = 8;
		if ((rc = ops->read_std(register_address(ctxt->ss_base,
							 _regs[VCPU_REGS_RSP]),
					&dst.val, dst.bytes, ctxt)) != 0)
					&dst.val, dst.bytes, ctxt->vcpu)) != 0)
			goto done;
		register_address_increment(_regs[VCPU_REGS_RSP], dst.bytes);
		break;
@@ -1048,7 +1050,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
				dst.bytes = 8;
				if ((rc = ops->read_std((unsigned long)dst.ptr,
							&dst.val, 8,
							ctxt)) != 0)
							ctxt->vcpu)) != 0)
					goto done;
			}
			register_address_increment(_regs[VCPU_REGS_RSP],
@@ -1056,7 +1058,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
			if ((rc = ops->write_std(
				     register_address(ctxt->ss_base,
						      _regs[VCPU_REGS_RSP]),
				     &dst.val, dst.bytes, ctxt)) != 0)
				     &dst.val, dst.bytes, ctxt->vcpu)) != 0)
				goto done;
			no_wb = 1;
			break;
@@ -1091,11 +1093,11 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
				rc = ops->cmpxchg_emulated((unsigned long)dst.
							   ptr, &dst.orig_val,
							   &dst.val, dst.bytes,
							   ctxt);
							   ctxt->vcpu);
			else
				rc = ops->write_emulated((unsigned long)dst.ptr,
							 &dst.val, dst.bytes,
							 ctxt);
							 ctxt->vcpu);
			if (rc != 0)
				goto done;
		default:
@@ -1130,7 +1132,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
							_regs[VCPU_REGS_RDI]);
		if ((rc = ops->read_emulated(register_address(
		      override_base ? *override_base : ctxt->ds_base,
		      _regs[VCPU_REGS_RSI]), &dst.val, dst.bytes, ctxt)) != 0)
		      _regs[VCPU_REGS_RSI]), &dst.val, dst.bytes, ctxt->vcpu)) != 0)
			goto done;
		register_address_increment(_regs[VCPU_REGS_RSI],
			     (_eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
@@ -1152,7 +1154,8 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
		dst.type = OP_REG;
		dst.bytes = (d & ByteOp) ? 1 : op_bytes;
		dst.ptr = (unsigned long *)&_regs[VCPU_REGS_RAX];
		if ((rc = ops->read_emulated(cr2, &dst.val, dst.bytes, ctxt)) != 0)
		if ((rc = ops->read_emulated(cr2, &dst.val, dst.bytes,
					     ctxt->vcpu)) != 0)
			goto done;
		register_address_increment(_regs[VCPU_REGS_RSI],
			   (_eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
@@ -1171,7 +1174,8 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)

pop_instruction:
		if ((rc = ops->read_std(register_address(ctxt->ss_base,
			_regs[VCPU_REGS_RSP]), dst.ptr, op_bytes, ctxt)) != 0)
			_regs[VCPU_REGS_RSP]), dst.ptr, op_bytes, ctxt->vcpu))
			!= 0)
			goto done;

		register_address_increment(_regs[VCPU_REGS_RSP], op_bytes);
@@ -1378,7 +1382,8 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
	case 0xc7:		/* Grp9 (cmpxchg8b) */
		{
			u64 old, new;
			if ((rc = ops->read_emulated(cr2, &old, 8, ctxt)) != 0)
			if ((rc = ops->read_emulated(cr2, &old, 8, ctxt->vcpu))
									!= 0)
				goto done;
			if (((u32) (old >> 0) != (u32) _regs[VCPU_REGS_RAX]) ||
			    ((u32) (old >> 32) != (u32) _regs[VCPU_REGS_RDX])) {
@@ -1389,7 +1394,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
				new = ((u64)_regs[VCPU_REGS_RCX] << 32)
					| (u32) _regs[VCPU_REGS_RBX];
				if ((rc = ops->cmpxchg_emulated(cr2, &old,
							  &new, 8, ctxt)) != 0)
							  &new, 8, ctxt->vcpu)) != 0)
					goto done;
				_eflags |= EFLG_ZF;
			}
+5 −5
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ struct x86_emulate_ops {
	 *  @bytes: [IN ] Number of bytes to read from memory.
	 */
	int (*read_std)(unsigned long addr, void *val,
			unsigned int bytes, struct x86_emulate_ctxt * ctxt);
			unsigned int bytes, struct kvm_vcpu *vcpu);

	/*
	 * write_std: Write bytes of standard (non-emulated/special) memory.
@@ -71,7 +71,7 @@ struct x86_emulate_ops {
	 *  @bytes: [IN ] Number of bytes to write to memory.
	 */
	int (*write_std)(unsigned long addr, const void *val,
			 unsigned int bytes, struct x86_emulate_ctxt * ctxt);
			 unsigned int bytes, struct kvm_vcpu *vcpu);

	/*
	 * read_emulated: Read bytes from emulated/special memory area.
@@ -82,7 +82,7 @@ struct x86_emulate_ops {
	int (*read_emulated) (unsigned long addr,
			      void *val,
			      unsigned int bytes,
			      struct x86_emulate_ctxt * ctxt);
			      struct kvm_vcpu *vcpu);

	/*
	 * write_emulated: Read bytes from emulated/special memory area.
@@ -94,7 +94,7 @@ struct x86_emulate_ops {
	int (*write_emulated) (unsigned long addr,
			       const void *val,
			       unsigned int bytes,
			       struct x86_emulate_ctxt * ctxt);
			       struct kvm_vcpu *vcpu);

	/*
	 * cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG operation on an
@@ -108,7 +108,7 @@ struct x86_emulate_ops {
				 const void *old,
				 const void *new,
				 unsigned int bytes,
				 struct x86_emulate_ctxt * ctxt);
				 struct kvm_vcpu *vcpu);

};