KVM: VMX: cache exit_intr_info

Marcelo Tosatti
2008-06-27T18:06:03Z

exit_intr_info is read-only in nature, so once read it can be cached
similarly to idtv_vectoring_inf.

Reduces guest re-entry in about 50 cycles on my machine (the exception
path should be similar, but haven't measured).

Applies on top of register accessor patch.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

--- kvm.orig/arch/x86/kvm/vmx.c
+++ kvm/arch/x86/kvm/vmx.c
@@ -60,6 +60,7 @@ struct vcpu_vmx {
int launched;
u8 fail;
u32 idt_vectoring_info;
+ u32 exit_intr_info;
struct kvm_msr_entry *guest_msrs;
struct kvm_msr_entry *host_msrs;
int nmsrs;
@@ -2250,7 +2251,7 @@ static int handle_exception(struct kvm_v
enum emulation_result er;

vect_info = vmx->idt_vectoring_info;
- intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
+ intr_info = vmx->exit_intr_info;

if ((vect_info & VECTORING_INFO_VALID_MASK) &&
!is_page_fault(intr_info))
@@ -2818,7 +2819,7 @@ static void vmx_intr_assist(struct kvm_v
update_tpr_threshold(vcpu);

intr_info_field = vmcs_read32(VM_ENTRY_INTR_INFO_FIELD);
- exit_intr_info_field = vmcs_read32(VM_EXIT_INTR_INFO);
+ exit_intr_info_field = vmx->exit_intr_info;
idtv_info_field = vmx->idt_vectoring_info;
if (intr_info_field & INTR_INFO_VALID_MASK) {
if (idtv_info_field & INTR_INFO_VALID_MASK) {
@@ -2927,7 +2928,6 @@ static void vmx_flush_regs(struct kvm_vc
static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
- u32 intr_info;

vmx_flush_regs(vcpu);

@@ -3062,11 +3062,11 @@ static void vmx_vcpu_run(struct kvm_vcpu
asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
vmx->launched = 1;

- intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
+ vmx->exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO);

/* We need to handle NMIs before interrupts are enabled */
- if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200 &&
- (intr_info & INTR_INFO_VALID_MASK)) {
+ if ((vmx->exit_intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200 &&
+ (vmx->exit_intr_info & INTR_INFO_VALID_MASK)) {
KVMTRACE_0D(NMI, vcpu, handler);
asm("int $2");
}