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

Commit f09ed83e authored by Avi Kivity's avatar Avi Kivity
Browse files

KVM: x86 emulator: move memop, memopp into emulation context



Simplifies further generalization of decode.

Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
parent 3329ece1
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -275,6 +275,8 @@ struct x86_emulate_ctxt {
	unsigned long _eip;
	unsigned long _eip;
	/* Fields above regs are cleared together. */
	/* Fields above regs are cleared together. */
	unsigned long regs[NR_VCPU_REGS];
	unsigned long regs[NR_VCPU_REGS];
	struct operand memop;
	struct operand *memopp;
	struct fetch_cache fetch;
	struct fetch_cache fetch;
	struct read_cache io_read;
	struct read_cache io_read;
	struct read_cache mem_read;
	struct read_cache mem_read;
+17 −17
Original line number Original line Diff line number Diff line
@@ -3323,8 +3323,9 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
	int def_op_bytes, def_ad_bytes, goffset, simd_prefix;
	int def_op_bytes, def_ad_bytes, goffset, simd_prefix;
	bool op_prefix = false;
	bool op_prefix = false;
	struct opcode opcode;
	struct opcode opcode;
	struct operand memop = { .type = OP_NONE }, *memopp = NULL;


	ctxt->memop.type = OP_NONE;
	ctxt->memopp = NULL;
	ctxt->_eip = ctxt->eip;
	ctxt->_eip = ctxt->eip;
	ctxt->fetch.start = ctxt->_eip;
	ctxt->fetch.start = ctxt->_eip;
	ctxt->fetch.end = ctxt->fetch.start + insn_len;
	ctxt->fetch.end = ctxt->fetch.start + insn_len;
@@ -3482,21 +3483,21 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)


	/* ModRM and SIB bytes. */
	/* ModRM and SIB bytes. */
	if (ctxt->d & ModRM) {
	if (ctxt->d & ModRM) {
		rc = decode_modrm(ctxt, &memop);
		rc = decode_modrm(ctxt, &ctxt->memop);
		if (!ctxt->has_seg_override)
		if (!ctxt->has_seg_override)
			set_seg_override(ctxt, ctxt->modrm_seg);
			set_seg_override(ctxt, ctxt->modrm_seg);
	} else if (ctxt->d & MemAbs)
	} else if (ctxt->d & MemAbs)
		rc = decode_abs(ctxt, &memop);
		rc = decode_abs(ctxt, &ctxt->memop);
	if (rc != X86EMUL_CONTINUE)
	if (rc != X86EMUL_CONTINUE)
		goto done;
		goto done;


	if (!ctxt->has_seg_override)
	if (!ctxt->has_seg_override)
		set_seg_override(ctxt, VCPU_SREG_DS);
		set_seg_override(ctxt, VCPU_SREG_DS);


	memop.addr.mem.seg = seg_override(ctxt);
	ctxt->memop.addr.mem.seg = seg_override(ctxt);


	if (memop.type == OP_MEM && ctxt->ad_bytes != 8)
	if (ctxt->memop.type == OP_MEM && ctxt->ad_bytes != 8)
		memop.addr.mem.ea = (u32)memop.addr.mem.ea;
		ctxt->memop.addr.mem.ea = (u32)ctxt->memop.addr.mem.ea;


	/*
	/*
	 * Decode and fetch the source operand: register, memory
	 * Decode and fetch the source operand: register, memory
@@ -3509,17 +3510,16 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
		decode_register_operand(ctxt, &ctxt->src, 0);
		decode_register_operand(ctxt, &ctxt->src, 0);
		break;
		break;
	case SrcMem16:
	case SrcMem16:
		memop.bytes = 2;
		ctxt->memop.bytes = 2;
		goto srcmem_common;
		goto srcmem_common;
	case SrcMem32:
	case SrcMem32:
		memop.bytes = 4;
		ctxt->memop.bytes = 4;
		goto srcmem_common;
		goto srcmem_common;
	case SrcMem:
	case SrcMem:
		memop.bytes = (ctxt->d & ByteOp) ? 1 :
		ctxt->memop.bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
							   ctxt->op_bytes;
	srcmem_common:
	srcmem_common:
		ctxt->src = memop;
		ctxt->src = ctxt->memop;
		memopp = &ctxt->src;
		ctxt->memopp = &ctxt->src;
		break;
		break;
	case SrcImmU16:
	case SrcImmU16:
		rc = decode_imm(ctxt, &ctxt->src, 2, false);
		rc = decode_imm(ctxt, &ctxt->src, 2, false);
@@ -3561,7 +3561,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
		insn_fetch_arr(ctxt->src.valptr, ctxt->src.bytes, ctxt);
		insn_fetch_arr(ctxt->src.valptr, ctxt->src.bytes, ctxt);
		break;
		break;
	case SrcMemFAddr:
	case SrcMemFAddr:
		memop.bytes = ctxt->op_bytes + 2;
		ctxt->memop.bytes = ctxt->op_bytes + 2;
		goto srcmem_common;
		goto srcmem_common;
		break;
		break;
	case SrcDX:
	case SrcDX:
@@ -3615,8 +3615,8 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
		break;
		break;
	case DstMem:
	case DstMem:
	case DstMem64:
	case DstMem64:
		ctxt->dst = memop;
		ctxt->dst = ctxt->memop;
		memopp = &ctxt->dst;
		ctxt->memopp = &ctxt->dst;
		if ((ctxt->d & DstMask) == DstMem64)
		if ((ctxt->d & DstMask) == DstMem64)
			ctxt->dst.bytes = 8;
			ctxt->dst.bytes = 8;
		else
		else
@@ -3654,8 +3654,8 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
	}
	}


done:
done:
	if (memopp && memopp->type == OP_MEM && ctxt->rip_relative)
	if (ctxt->memopp && ctxt->memopp->type == OP_MEM && ctxt->rip_relative)
		memopp->addr.mem.ea += ctxt->_eip;
		ctxt->memopp->addr.mem.ea += ctxt->_eip;


	return (rc != X86EMUL_CONTINUE) ? EMULATION_FAILED : EMULATION_OK;
	return (rc != X86EMUL_CONTINUE) ? EMULATION_FAILED : EMULATION_OK;
}
}