KVM: x86: Factor out x86 instruction emulation with decoding
Move the instruction decode part out of x86_emulate_instruction() for it to be used in other places. Also kvm_clear_exception_queue() is moved inside the if-statement as it doesn't apply when KVM are coming back from userspace. Co-developed-by: Bandan Das <bsd@redhat.com> Signed-off-by: Bandan Das <bsd@redhat.com> Signed-off-by: Wei Huang <wei.huang2@amd.com> Message-Id: <20210126081831.570253-2-wei.huang2@amd.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
9a3ecd5e2a
commit
4aa2691dcb
@ -7317,6 +7317,42 @@ static bool is_vmware_backdoor_opcode(struct x86_emulate_ctxt *ctxt)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decode to be emulated instruction. Return EMULATION_OK if success.
|
||||||
|
*/
|
||||||
|
int x86_decode_emulated_instruction(struct kvm_vcpu *vcpu, int emulation_type,
|
||||||
|
void *insn, int insn_len)
|
||||||
|
{
|
||||||
|
int r = EMULATION_OK;
|
||||||
|
struct x86_emulate_ctxt *ctxt = vcpu->arch.emulate_ctxt;
|
||||||
|
|
||||||
|
init_emulate_ctxt(vcpu);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We will reenter on the same instruction since we do not set
|
||||||
|
* complete_userspace_io. This does not handle watchpoints yet,
|
||||||
|
* those would be handled in the emulate_ops.
|
||||||
|
*/
|
||||||
|
if (!(emulation_type & EMULTYPE_SKIP) &&
|
||||||
|
kvm_vcpu_check_breakpoint(vcpu, &r))
|
||||||
|
return r;
|
||||||
|
|
||||||
|
ctxt->interruptibility = 0;
|
||||||
|
ctxt->have_exception = false;
|
||||||
|
ctxt->exception.vector = -1;
|
||||||
|
ctxt->perm_ok = false;
|
||||||
|
|
||||||
|
ctxt->ud = emulation_type & EMULTYPE_TRAP_UD;
|
||||||
|
|
||||||
|
r = x86_decode_insn(ctxt, insn, insn_len);
|
||||||
|
|
||||||
|
trace_kvm_emulate_insn_start(vcpu);
|
||||||
|
++vcpu->stat.insn_emulation;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(x86_decode_emulated_instruction);
|
||||||
|
|
||||||
int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
|
int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
|
||||||
int emulation_type, void *insn, int insn_len)
|
int emulation_type, void *insn, int insn_len)
|
||||||
{
|
{
|
||||||
@ -7336,32 +7372,12 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
|
|||||||
*/
|
*/
|
||||||
write_fault_to_spt = vcpu->arch.write_fault_to_shadow_pgtable;
|
write_fault_to_spt = vcpu->arch.write_fault_to_shadow_pgtable;
|
||||||
vcpu->arch.write_fault_to_shadow_pgtable = false;
|
vcpu->arch.write_fault_to_shadow_pgtable = false;
|
||||||
kvm_clear_exception_queue(vcpu);
|
|
||||||
|
|
||||||
if (!(emulation_type & EMULTYPE_NO_DECODE)) {
|
if (!(emulation_type & EMULTYPE_NO_DECODE)) {
|
||||||
init_emulate_ctxt(vcpu);
|
kvm_clear_exception_queue(vcpu);
|
||||||
|
|
||||||
/*
|
r = x86_decode_emulated_instruction(vcpu, emulation_type,
|
||||||
* We will reenter on the same instruction since
|
insn, insn_len);
|
||||||
* we do not set complete_userspace_io. This does not
|
|
||||||
* handle watchpoints yet, those would be handled in
|
|
||||||
* the emulate_ops.
|
|
||||||
*/
|
|
||||||
if (!(emulation_type & EMULTYPE_SKIP) &&
|
|
||||||
kvm_vcpu_check_breakpoint(vcpu, &r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
ctxt->interruptibility = 0;
|
|
||||||
ctxt->have_exception = false;
|
|
||||||
ctxt->exception.vector = -1;
|
|
||||||
ctxt->perm_ok = false;
|
|
||||||
|
|
||||||
ctxt->ud = emulation_type & EMULTYPE_TRAP_UD;
|
|
||||||
|
|
||||||
r = x86_decode_insn(ctxt, insn, insn_len);
|
|
||||||
|
|
||||||
trace_kvm_emulate_insn_start(vcpu);
|
|
||||||
++vcpu->stat.insn_emulation;
|
|
||||||
if (r != EMULATION_OK) {
|
if (r != EMULATION_OK) {
|
||||||
if ((emulation_type & EMULTYPE_TRAP_UD) ||
|
if ((emulation_type & EMULTYPE_TRAP_UD) ||
|
||||||
(emulation_type & EMULTYPE_TRAP_UD_FORCED)) {
|
(emulation_type & EMULTYPE_TRAP_UD_FORCED)) {
|
||||||
|
@ -273,6 +273,8 @@ bool kvm_mtrr_check_gfn_range_consistency(struct kvm_vcpu *vcpu, gfn_t gfn,
|
|||||||
int page_num);
|
int page_num);
|
||||||
bool kvm_vector_hashing_enabled(void);
|
bool kvm_vector_hashing_enabled(void);
|
||||||
void kvm_fixup_and_inject_pf_error(struct kvm_vcpu *vcpu, gva_t gva, u16 error_code);
|
void kvm_fixup_and_inject_pf_error(struct kvm_vcpu *vcpu, gva_t gva, u16 error_code);
|
||||||
|
int x86_decode_emulated_instruction(struct kvm_vcpu *vcpu, int emulation_type,
|
||||||
|
void *insn, int insn_len);
|
||||||
int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
|
int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
|
||||||
int emulation_type, void *insn, int insn_len);
|
int emulation_type, void *insn, int insn_len);
|
||||||
fastpath_t handle_fastpath_set_msr_irqoff(struct kvm_vcpu *vcpu);
|
fastpath_t handle_fastpath_set_msr_irqoff(struct kvm_vcpu *vcpu);
|
||||||
|
Loading…
Reference in New Issue
Block a user