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

KVM: x86 emulator: emulate SGDT/SIDT



Opcodes 0F 01 /0 and 0F 01 /1

Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent a6e3407b
Loading
Loading
Loading
Loading
+31 −2
Original line number Diff line number Diff line
@@ -3026,6 +3026,35 @@ static int em_vmcall(struct x86_emulate_ctxt *ctxt)
	return X86EMUL_CONTINUE;
}

static int emulate_store_desc_ptr(struct x86_emulate_ctxt *ctxt,
				  void (*get)(struct x86_emulate_ctxt *ctxt,
					      struct desc_ptr *ptr))
{
	struct desc_ptr desc_ptr;

	if (ctxt->mode == X86EMUL_MODE_PROT64)
		ctxt->op_bytes = 8;
	get(ctxt, &desc_ptr);
	if (ctxt->op_bytes == 2) {
		ctxt->op_bytes = 4;
		desc_ptr.address &= 0x00ffffff;
	}
	/* Disable writeback. */
	ctxt->dst.type = OP_NONE;
	return segmented_write(ctxt, ctxt->dst.addr.mem,
			       &desc_ptr, 2 + ctxt->op_bytes);
}

static int em_sgdt(struct x86_emulate_ctxt *ctxt)
{
	return emulate_store_desc_ptr(ctxt, ctxt->ops->get_gdt);
}

static int em_sidt(struct x86_emulate_ctxt *ctxt)
{
	return emulate_store_desc_ptr(ctxt, ctxt->ops->get_idt);
}

static int em_lgdt(struct x86_emulate_ctxt *ctxt)
{
	struct desc_ptr desc_ptr;
@@ -3485,8 +3514,8 @@ static struct opcode group6[] = {
};

static struct group_dual group7 = { {
	DI(Mov | DstMem | Priv,			sgdt),
	DI(Mov | DstMem | Priv,			sidt),
	II(Mov | DstMem | Priv,			em_sgdt, sgdt),
	II(Mov | DstMem | Priv,			em_sidt, sidt),
	II(SrcMem | Priv,			em_lgdt, lgdt),
	II(SrcMem | Priv,			em_lidt, lidt),
	II(SrcNone | DstMem | Mov,		em_smsw, smsw), N,