KVM: x86: Add kvm_skip_emulated_instruction and use it.
kvm_skip_emulated_instruction calls both kvm_x86_ops->skip_emulated_instruction and kvm_vcpu_check_singlestep, skipping the emulated instruction and generating a trap if necessary. Replacing skip_emulated_instruction calls with kvm_skip_emulated_instruction is straightforward, except for: - ICEBP, which is already inside a trap, so avoid triggering another trap. - Instructions that can trigger exits to userspace, such as the IO insns, MOVs to CR8, and HALT. If kvm_skip_emulated_instruction does trigger a KVM_GUESTDBG_SINGLESTEP exit, and the handling code for IN/OUT/MOV CR8/HALT also triggers an exit to userspace, the latter will take precedence. The singlestep will be triggered again on the next instruction, which is the current behavior. - Task switch instructions which would require additional handling (e.g. the task switch bit) and are instead left alone. - Cases where VMLAUNCH/VMRESUME do not proceed to the next instruction, which do not trigger singlestep traps as mentioned previously. Signed-off-by: Kyle Huey <khuey@kylehuey.com> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
This commit is contained in:
@@ -3151,8 +3151,7 @@ static int skinit_interception(struct vcpu_svm *svm)
|
||||
|
||||
static int wbinvd_interception(struct vcpu_svm *svm)
|
||||
{
|
||||
kvm_emulate_wbinvd(&svm->vcpu);
|
||||
return 1;
|
||||
return kvm_emulate_wbinvd(&svm->vcpu);
|
||||
}
|
||||
|
||||
static int xsetbv_interception(struct vcpu_svm *svm)
|
||||
@@ -3275,9 +3274,7 @@ static int rdpmc_interception(struct vcpu_svm *svm)
|
||||
return emulate_on_interception(svm);
|
||||
|
||||
err = kvm_rdpmc(&svm->vcpu);
|
||||
kvm_complete_insn_gp(&svm->vcpu, err);
|
||||
|
||||
return 1;
|
||||
return kvm_complete_insn_gp(&svm->vcpu, err);
|
||||
}
|
||||
|
||||
static bool check_selective_cr0_intercepted(struct vcpu_svm *svm,
|
||||
@@ -3374,9 +3371,7 @@ static int cr_interception(struct vcpu_svm *svm)
|
||||
}
|
||||
kvm_register_write(&svm->vcpu, reg, val);
|
||||
}
|
||||
kvm_complete_insn_gp(&svm->vcpu, err);
|
||||
|
||||
return 1;
|
||||
return kvm_complete_insn_gp(&svm->vcpu, err);
|
||||
}
|
||||
|
||||
static int dr_interception(struct vcpu_svm *svm)
|
||||
|
Reference in New Issue
Block a user