aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2010-07-20 07:43:23 -0400
committerAvi Kivity <avi@redhat.com>2010-10-24 04:52:52 -0400
commit83422e17c19d61399cab7dbf9bf40ff9af2a7dd2 (patch)
tree66baed88c811ca2f2a453254af08eb980ee3c842 /arch
parent537b37e2674b7e4390a490e03cae53ca9ca99e30 (diff)
KVM: VMX: Parameterize vmx_complete_interrupts() for both exit and entry
Currently vmx_complete_interrupts() can decode event information from vmx exit fields into the generic kvm event queues. Make it able to decode the information from the entry fields as well by parametrizing it. Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/vmx.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 541f0d2412b4..3237f6cc930d 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -182,7 +182,7 @@ static int init_rmode(struct kvm *kvm);
182static u64 construct_eptp(unsigned long root_hpa); 182static u64 construct_eptp(unsigned long root_hpa);
183static void kvm_cpu_vmxon(u64 addr); 183static void kvm_cpu_vmxon(u64 addr);
184static void kvm_cpu_vmxoff(void); 184static void kvm_cpu_vmxoff(void);
185static void fixup_rmode_irq(struct vcpu_vmx *vmx); 185static void fixup_rmode_irq(struct vcpu_vmx *vmx, u32 *idt_vectoring_info);
186 186
187static DEFINE_PER_CPU(struct vmcs *, vmxarea); 187static DEFINE_PER_CPU(struct vmcs *, vmxarea);
188static DEFINE_PER_CPU(struct vmcs *, current_vmcs); 188static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
@@ -3827,17 +3827,18 @@ static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx)
3827 ktime_to_ns(ktime_sub(ktime_get(), vmx->entry_time)); 3827 ktime_to_ns(ktime_sub(ktime_get(), vmx->entry_time));
3828} 3828}
3829 3829
3830static void vmx_complete_interrupts(struct vcpu_vmx *vmx) 3830static void __vmx_complete_interrupts(struct vcpu_vmx *vmx,
3831 u32 idt_vectoring_info,
3832 int instr_len_field,
3833 int error_code_field)
3831{ 3834{
3832 u32 idt_vectoring_info;
3833 u8 vector; 3835 u8 vector;
3834 int type; 3836 int type;
3835 bool idtv_info_valid; 3837 bool idtv_info_valid;
3836 3838
3837 if (vmx->rmode.irq.pending) 3839 if (vmx->rmode.irq.pending)
3838 fixup_rmode_irq(vmx); 3840 fixup_rmode_irq(vmx, &idt_vectoring_info);
3839 3841
3840 idt_vectoring_info = vmx->idt_vectoring_info;
3841 idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK; 3842 idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK;
3842 3843
3843 vmx->vcpu.arch.nmi_injected = false; 3844 vmx->vcpu.arch.nmi_injected = false;
@@ -3865,18 +3866,18 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
3865 break; 3866 break;
3866 case INTR_TYPE_SOFT_EXCEPTION: 3867 case INTR_TYPE_SOFT_EXCEPTION:
3867 vmx->vcpu.arch.event_exit_inst_len = 3868 vmx->vcpu.arch.event_exit_inst_len =
3868 vmcs_read32(VM_EXIT_INSTRUCTION_LEN); 3869 vmcs_read32(instr_len_field);
3869 /* fall through */ 3870 /* fall through */
3870 case INTR_TYPE_HARD_EXCEPTION: 3871 case INTR_TYPE_HARD_EXCEPTION:
3871 if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) { 3872 if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) {
3872 u32 err = vmcs_read32(IDT_VECTORING_ERROR_CODE); 3873 u32 err = vmcs_read32(error_code_field);
3873 kvm_queue_exception_e(&vmx->vcpu, vector, err); 3874 kvm_queue_exception_e(&vmx->vcpu, vector, err);
3874 } else 3875 } else
3875 kvm_queue_exception(&vmx->vcpu, vector); 3876 kvm_queue_exception(&vmx->vcpu, vector);
3876 break; 3877 break;
3877 case INTR_TYPE_SOFT_INTR: 3878 case INTR_TYPE_SOFT_INTR:
3878 vmx->vcpu.arch.event_exit_inst_len = 3879 vmx->vcpu.arch.event_exit_inst_len =
3879 vmcs_read32(VM_EXIT_INSTRUCTION_LEN); 3880 vmcs_read32(instr_len_field);
3880 /* fall through */ 3881 /* fall through */
3881 case INTR_TYPE_EXT_INTR: 3882 case INTR_TYPE_EXT_INTR:
3882 kvm_queue_interrupt(&vmx->vcpu, vector, 3883 kvm_queue_interrupt(&vmx->vcpu, vector,
@@ -3887,24 +3888,31 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
3887 } 3888 }
3888} 3889}
3889 3890
3891static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
3892{
3893 __vmx_complete_interrupts(vmx, vmx->idt_vectoring_info,
3894 VM_EXIT_INSTRUCTION_LEN,
3895 IDT_VECTORING_ERROR_CODE);
3896}
3897
3890/* 3898/*
3891 * Failure to inject an interrupt should give us the information 3899 * Failure to inject an interrupt should give us the information
3892 * in IDT_VECTORING_INFO_FIELD. However, if the failure occurs 3900 * in IDT_VECTORING_INFO_FIELD. However, if the failure occurs
3893 * when fetching the interrupt redirection bitmap in the real-mode 3901 * when fetching the interrupt redirection bitmap in the real-mode
3894 * tss, this doesn't happen. So we do it ourselves. 3902 * tss, this doesn't happen. So we do it ourselves.
3895 */ 3903 */
3896static void fixup_rmode_irq(struct vcpu_vmx *vmx) 3904static void fixup_rmode_irq(struct vcpu_vmx *vmx, u32 *idt_vectoring_info)
3897{ 3905{
3898 vmx->rmode.irq.pending = 0; 3906 vmx->rmode.irq.pending = 0;
3899 if (kvm_rip_read(&vmx->vcpu) + 1 != vmx->rmode.irq.rip) 3907 if (kvm_rip_read(&vmx->vcpu) + 1 != vmx->rmode.irq.rip)
3900 return; 3908 return;
3901 kvm_rip_write(&vmx->vcpu, vmx->rmode.irq.rip); 3909 kvm_rip_write(&vmx->vcpu, vmx->rmode.irq.rip);
3902 if (vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK) { 3910 if (*idt_vectoring_info & VECTORING_INFO_VALID_MASK) {
3903 vmx->idt_vectoring_info &= ~VECTORING_INFO_TYPE_MASK; 3911 *idt_vectoring_info &= ~VECTORING_INFO_TYPE_MASK;
3904 vmx->idt_vectoring_info |= INTR_TYPE_EXT_INTR; 3912 *idt_vectoring_info |= INTR_TYPE_EXT_INTR;
3905 return; 3913 return;
3906 } 3914 }
3907 vmx->idt_vectoring_info = 3915 *idt_vectoring_info =
3908 VECTORING_INFO_VALID_MASK 3916 VECTORING_INFO_VALID_MASK
3909 | INTR_TYPE_EXT_INTR 3917 | INTR_TYPE_EXT_INTR
3910 | vmx->rmode.irq.vector; 3918 | vmx->rmode.irq.vector;