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: Sean Christopherson <seanjc@google.com> Signed-off-by: Hou Wenlong <houwenlong.hwl@antgroup.com> Message-Id: <5b7188e6388ac9f4567d14eab32db9adf3e00119.1644292363.git.houwenlong.hwl@antgroup.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
31c66dabaa
commit
1e326ad429
@ -1623,9 +1623,14 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
|
||||
if (!(seg_desc.type & 8))
|
||||
goto exception;
|
||||
|
||||
/* RET can never return to an inner privilege level. */
|
||||
if (transfer == X86_TRANSFER_RET && rpl < cpl)
|
||||
goto exception;
|
||||
if (transfer == X86_TRANSFER_RET) {
|
||||
/* RET can never return to an inner privilege level. */
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user