Commit 1e326ad4 authored by Hou Wenlong's avatar Hou Wenlong Committed by Paolo Bonzini
Browse files

KVM: x86/emulator: Move the unhandled outer privilege level logic of far...


KVM: x86/emulator: Move the unhandled outer privilege level logic of far return into __load_segment_descriptor()

Outer-privilege level return is not implemented in emulator,
move the unhandled logic into __load_segment_descriptor to
make it easier to understand why the checks for RET are
incomplete.

Suggested-by: default avatarSean Christopherson <seanjc@google.com>
Signed-off-by: default avatarHou Wenlong <houwenlong.hwl@antgroup.com>
Message-Id: <5b7188e6388ac9f4567d14eab32db9adf3e00119.1644292363.git.houwenlong.hwl@antgroup.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 31c66dab
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -1623,9 +1623,14 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
		if (!(seg_desc.type & 8))
			goto exception;

		if (transfer == X86_TRANSFER_RET) {
			/* RET can never return to an inner privilege level. */
		if (transfer == X86_TRANSFER_RET && rpl < cpl)
			if (rpl < cpl)
				goto exception;
			/* Outer-privilege level return is not implemented */
			if (rpl > cpl)
				return X86EMUL_UNHANDLEABLE;
		}
		if (transfer == X86_TRANSFER_RET || transfer == X86_TRANSFER_TASK_SWITCH) {
			if (seg_desc.type & 4) {
				/* conforming */
@@ -2220,9 +2225,6 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt)
	rc = emulate_pop(ctxt, &cs, ctxt->op_bytes);
	if (rc != X86EMUL_CONTINUE)
		return rc;
	/* Outer-privilege level return is not implemented */
	if (ctxt->mode >= X86EMUL_MODE_PROT16 && (cs & 3) > cpl)
		return X86EMUL_UNHANDLEABLE;
	rc = __load_segment_descriptor(ctxt, (u16)cs, VCPU_SREG_CS, cpl,
				       X86_TRANSFER_RET,
				       &new_desc);