ia64/xen-unstable

changeset 12719:a3aab403ec21

[HVM][VMX] Rename io.c -> intr.c.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Fri Dec 01 09:51:13 2006 +0000 (2006-12-01)
parents 2801a14d169a
children e6b4dc82b1e3
files xen/arch/x86/hvm/vmx/Makefile xen/arch/x86/hvm/vmx/intr.c xen/arch/x86/hvm/vmx/io.c
line diff
     1.1 --- a/xen/arch/x86/hvm/vmx/Makefile	Fri Dec 01 09:48:18 2006 +0000
     1.2 +++ b/xen/arch/x86/hvm/vmx/Makefile	Fri Dec 01 09:51:13 2006 +0000
     1.3 @@ -1,6 +1,6 @@
     1.4  subdir-$(x86_32) += x86_32
     1.5  subdir-$(x86_64) += x86_64
     1.6  
     1.7 -obj-y += io.o
     1.8 +obj-y += intr.o
     1.9  obj-y += vmcs.o
    1.10  obj-y += vmx.o
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/xen/arch/x86/hvm/vmx/intr.c	Fri Dec 01 09:51:13 2006 +0000
     2.3 @@ -0,0 +1,196 @@
     2.4 +/*
     2.5 + * io.c: handling I/O, interrupts related VMX entry/exit
     2.6 + * Copyright (c) 2004, Intel Corporation.
     2.7 + *
     2.8 + * This program is free software; you can redistribute it and/or modify it
     2.9 + * under the terms and conditions of the GNU General Public License,
    2.10 + * version 2, as published by the Free Software Foundation.
    2.11 + *
    2.12 + * This program is distributed in the hope it will be useful, but WITHOUT
    2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    2.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    2.15 + * more details.
    2.16 + *
    2.17 + * You should have received a copy of the GNU General Public License along with
    2.18 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    2.19 + * Place - Suite 330, Boston, MA 02111-1307 USA.
    2.20 + *
    2.21 + */
    2.22 +
    2.23 +#include <xen/config.h>
    2.24 +#include <xen/init.h>
    2.25 +#include <xen/mm.h>
    2.26 +#include <xen/lib.h>
    2.27 +#include <xen/errno.h>
    2.28 +#include <xen/trace.h>
    2.29 +#include <xen/event.h>
    2.30 +
    2.31 +#include <asm/current.h>
    2.32 +#include <asm/cpufeature.h>
    2.33 +#include <asm/processor.h>
    2.34 +#include <asm/msr.h>
    2.35 +#include <asm/hvm/hvm.h>
    2.36 +#include <asm/hvm/io.h>
    2.37 +#include <asm/hvm/support.h>
    2.38 +#include <asm/hvm/vmx/vmx.h>
    2.39 +#include <asm/hvm/vmx/vmcs.h>
    2.40 +#include <asm/hvm/vpic.h>
    2.41 +#include <asm/hvm/vlapic.h>
    2.42 +#include <public/hvm/ioreq.h>
    2.43 +
    2.44 +
    2.45 +static inline void
    2.46 +enable_irq_window(struct vcpu *v)
    2.47 +{
    2.48 +    u32  *cpu_exec_control = &v->arch.hvm_vcpu.u.vmx.exec_control;
    2.49 +    
    2.50 +    if (!(*cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING)) {
    2.51 +        *cpu_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
    2.52 +        __vmwrite(CPU_BASED_VM_EXEC_CONTROL, *cpu_exec_control);
    2.53 +    }
    2.54 +}
    2.55 +
    2.56 +static inline void
    2.57 +disable_irq_window(struct vcpu *v)
    2.58 +{
    2.59 +    u32  *cpu_exec_control = &v->arch.hvm_vcpu.u.vmx.exec_control;
    2.60 +    
    2.61 +    if ( *cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING ) {
    2.62 +        *cpu_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
    2.63 +        __vmwrite(CPU_BASED_VM_EXEC_CONTROL, *cpu_exec_control);
    2.64 +    }
    2.65 +}
    2.66 +
    2.67 +static inline int is_interruptibility_state(void)
    2.68 +{
    2.69 +    return __vmread(GUEST_INTERRUPTIBILITY_INFO);
    2.70 +}
    2.71 +
    2.72 +#ifdef __x86_64__
    2.73 +static void update_tpr_threshold(struct vlapic *vlapic)
    2.74 +{
    2.75 +    int max_irr, tpr;
    2.76 +
    2.77 +    if ( !vlapic_enabled(vlapic) || 
    2.78 +         ((max_irr = vlapic_find_highest_irr(vlapic)) == -1) )
    2.79 +    {
    2.80 +        __vmwrite(TPR_THRESHOLD, 0);
    2.81 +        return;
    2.82 +    }
    2.83 +
    2.84 +    tpr = vlapic_get_reg(vlapic, APIC_TASKPRI) & 0xF0;
    2.85 +    __vmwrite(TPR_THRESHOLD, (max_irr > tpr) ? (tpr >> 4) : (max_irr >> 4));
    2.86 +}
    2.87 +#else
    2.88 +#define update_tpr_threshold(v) ((void)0)
    2.89 +#endif
    2.90 +
    2.91 +asmlinkage void vmx_intr_assist(void)
    2.92 +{
    2.93 +    int intr_type = 0;
    2.94 +    int highest_vector;
    2.95 +    unsigned long eflags;
    2.96 +    struct vcpu *v = current;
    2.97 +    struct hvm_domain *plat=&v->domain->arch.hvm_domain;
    2.98 +    struct periodic_time *pt = &plat->pl_time.periodic_tm;
    2.99 +    unsigned int idtv_info_field;
   2.100 +    unsigned long inst_len;
   2.101 +    int    has_ext_irq;
   2.102 +
   2.103 +    if ( (v->vcpu_id == 0) && pt->enabled && pt->pending_intr_nr )
   2.104 +    {
   2.105 +        hvm_isa_irq_deassert(current->domain, pt->irq);
   2.106 +        hvm_isa_irq_assert(current->domain, pt->irq);
   2.107 +    }
   2.108 +
   2.109 +    hvm_set_callback_irq_level();
   2.110 +
   2.111 +    update_tpr_threshold(vcpu_vlapic(v));
   2.112 +
   2.113 +    has_ext_irq = cpu_has_pending_irq(v);
   2.114 +
   2.115 +    if ( unlikely(v->arch.hvm_vmx.vector_injected) )
   2.116 +    {
   2.117 +        v->arch.hvm_vmx.vector_injected=0;
   2.118 +        if (unlikely(has_ext_irq)) enable_irq_window(v);
   2.119 +        return;
   2.120 +    }
   2.121 +
   2.122 +    /* This could be moved earlier in the VMX resume sequence. */
   2.123 +    idtv_info_field = __vmread(IDT_VECTORING_INFO_FIELD);
   2.124 +    if ( unlikely(idtv_info_field & INTR_INFO_VALID_MASK) )
   2.125 +    {
   2.126 +        __vmwrite(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field);
   2.127 +
   2.128 +        /*
   2.129 +         * Safe: the length will only be interpreted for software exceptions
   2.130 +         * and interrupts. If we get here then delivery of some event caused a
   2.131 +         * fault, and this always results in defined VM_EXIT_INSTRUCTION_LEN.
   2.132 +         */
   2.133 +        inst_len = __vmread(VM_EXIT_INSTRUCTION_LEN); /* Safe */
   2.134 +        __vmwrite(VM_ENTRY_INSTRUCTION_LEN, inst_len);
   2.135 +
   2.136 +        if (unlikely(idtv_info_field & 0x800)) /* valid error code */
   2.137 +            __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE,
   2.138 +                      __vmread(IDT_VECTORING_ERROR_CODE));
   2.139 +        if (unlikely(has_ext_irq))
   2.140 +            enable_irq_window(v);
   2.141 +
   2.142 +        HVM_DBG_LOG(DBG_LEVEL_1, "idtv_info_field=%x", idtv_info_field);
   2.143 +
   2.144 +        return;
   2.145 +    }
   2.146 +
   2.147 +    if ( likely(!has_ext_irq) )
   2.148 +        return;
   2.149 +
   2.150 +    if ( unlikely(is_interruptibility_state()) )
   2.151 +    {
   2.152 +        /* pre-cleared for emulated instruction */
   2.153 +        enable_irq_window(v);
   2.154 +        HVM_DBG_LOG(DBG_LEVEL_1, "interruptibility");
   2.155 +        return;
   2.156 +    }
   2.157 +
   2.158 +    eflags = __vmread(GUEST_RFLAGS);
   2.159 +    if ( irq_masked(eflags) )
   2.160 +    {
   2.161 +        enable_irq_window(v);
   2.162 +        return;
   2.163 +    }
   2.164 +
   2.165 +    highest_vector = cpu_get_interrupt(v, &intr_type);
   2.166 +    if ( highest_vector < 0 )
   2.167 +        return;
   2.168 +
   2.169 +    switch ( intr_type )
   2.170 +    {
   2.171 +    case APIC_DM_EXTINT:
   2.172 +    case APIC_DM_FIXED:
   2.173 +    case APIC_DM_LOWEST:
   2.174 +        vmx_inject_extint(v, highest_vector, VMX_DELIVER_NO_ERROR_CODE);
   2.175 +        TRACE_3D(TRC_VMX_INTR, v->domain->domain_id, highest_vector, 0);
   2.176 +        break;
   2.177 +
   2.178 +    case APIC_DM_SMI:
   2.179 +    case APIC_DM_NMI:
   2.180 +    case APIC_DM_INIT:
   2.181 +    case APIC_DM_STARTUP:
   2.182 +    default:
   2.183 +        printk("Unsupported interrupt type\n");
   2.184 +        BUG();
   2.185 +        break;
   2.186 +    }
   2.187 +    
   2.188 +    hvm_interrupt_post(v, highest_vector, intr_type);
   2.189 +}
   2.190 +
   2.191 +/*
   2.192 + * Local variables:
   2.193 + * mode: C
   2.194 + * c-set-style: "BSD"
   2.195 + * c-basic-offset: 4
   2.196 + * tab-width: 4
   2.197 + * indent-tabs-mode: nil
   2.198 + * End:
   2.199 + */
     3.1 --- a/xen/arch/x86/hvm/vmx/io.c	Fri Dec 01 09:48:18 2006 +0000
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,196 +0,0 @@
     3.4 -/*
     3.5 - * io.c: handling I/O, interrupts related VMX entry/exit
     3.6 - * Copyright (c) 2004, Intel Corporation.
     3.7 - *
     3.8 - * This program is free software; you can redistribute it and/or modify it
     3.9 - * under the terms and conditions of the GNU General Public License,
    3.10 - * version 2, as published by the Free Software Foundation.
    3.11 - *
    3.12 - * This program is distributed in the hope it will be useful, but WITHOUT
    3.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    3.15 - * more details.
    3.16 - *
    3.17 - * You should have received a copy of the GNU General Public License along with
    3.18 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    3.19 - * Place - Suite 330, Boston, MA 02111-1307 USA.
    3.20 - *
    3.21 - */
    3.22 -
    3.23 -#include <xen/config.h>
    3.24 -#include <xen/init.h>
    3.25 -#include <xen/mm.h>
    3.26 -#include <xen/lib.h>
    3.27 -#include <xen/errno.h>
    3.28 -#include <xen/trace.h>
    3.29 -#include <xen/event.h>
    3.30 -
    3.31 -#include <asm/current.h>
    3.32 -#include <asm/cpufeature.h>
    3.33 -#include <asm/processor.h>
    3.34 -#include <asm/msr.h>
    3.35 -#include <asm/hvm/hvm.h>
    3.36 -#include <asm/hvm/io.h>
    3.37 -#include <asm/hvm/support.h>
    3.38 -#include <asm/hvm/vmx/vmx.h>
    3.39 -#include <asm/hvm/vmx/vmcs.h>
    3.40 -#include <asm/hvm/vpic.h>
    3.41 -#include <asm/hvm/vlapic.h>
    3.42 -#include <public/hvm/ioreq.h>
    3.43 -
    3.44 -
    3.45 -static inline void
    3.46 -enable_irq_window(struct vcpu *v)
    3.47 -{
    3.48 -    u32  *cpu_exec_control = &v->arch.hvm_vcpu.u.vmx.exec_control;
    3.49 -    
    3.50 -    if (!(*cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING)) {
    3.51 -        *cpu_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
    3.52 -        __vmwrite(CPU_BASED_VM_EXEC_CONTROL, *cpu_exec_control);
    3.53 -    }
    3.54 -}
    3.55 -
    3.56 -static inline void
    3.57 -disable_irq_window(struct vcpu *v)
    3.58 -{
    3.59 -    u32  *cpu_exec_control = &v->arch.hvm_vcpu.u.vmx.exec_control;
    3.60 -    
    3.61 -    if ( *cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING ) {
    3.62 -        *cpu_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
    3.63 -        __vmwrite(CPU_BASED_VM_EXEC_CONTROL, *cpu_exec_control);
    3.64 -    }
    3.65 -}
    3.66 -
    3.67 -static inline int is_interruptibility_state(void)
    3.68 -{
    3.69 -    return __vmread(GUEST_INTERRUPTIBILITY_INFO);
    3.70 -}
    3.71 -
    3.72 -#ifdef __x86_64__
    3.73 -static void update_tpr_threshold(struct vlapic *vlapic)
    3.74 -{
    3.75 -    int max_irr, tpr;
    3.76 -
    3.77 -    if ( !vlapic_enabled(vlapic) || 
    3.78 -         ((max_irr = vlapic_find_highest_irr(vlapic)) == -1) )
    3.79 -    {
    3.80 -        __vmwrite(TPR_THRESHOLD, 0);
    3.81 -        return;
    3.82 -    }
    3.83 -
    3.84 -    tpr = vlapic_get_reg(vlapic, APIC_TASKPRI) & 0xF0;
    3.85 -    __vmwrite(TPR_THRESHOLD, (max_irr > tpr) ? (tpr >> 4) : (max_irr >> 4));
    3.86 -}
    3.87 -#else
    3.88 -#define update_tpr_threshold(v) ((void)0)
    3.89 -#endif
    3.90 -
    3.91 -asmlinkage void vmx_intr_assist(void)
    3.92 -{
    3.93 -    int intr_type = 0;
    3.94 -    int highest_vector;
    3.95 -    unsigned long eflags;
    3.96 -    struct vcpu *v = current;
    3.97 -    struct hvm_domain *plat=&v->domain->arch.hvm_domain;
    3.98 -    struct periodic_time *pt = &plat->pl_time.periodic_tm;
    3.99 -    unsigned int idtv_info_field;
   3.100 -    unsigned long inst_len;
   3.101 -    int    has_ext_irq;
   3.102 -
   3.103 -    if ( (v->vcpu_id == 0) && pt->enabled && pt->pending_intr_nr )
   3.104 -    {
   3.105 -        hvm_isa_irq_deassert(current->domain, pt->irq);
   3.106 -        hvm_isa_irq_assert(current->domain, pt->irq);
   3.107 -    }
   3.108 -
   3.109 -    hvm_set_callback_irq_level();
   3.110 -
   3.111 -    update_tpr_threshold(vcpu_vlapic(v));
   3.112 -
   3.113 -    has_ext_irq = cpu_has_pending_irq(v);
   3.114 -
   3.115 -    if ( unlikely(v->arch.hvm_vmx.vector_injected) )
   3.116 -    {
   3.117 -        v->arch.hvm_vmx.vector_injected=0;
   3.118 -        if (unlikely(has_ext_irq)) enable_irq_window(v);
   3.119 -        return;
   3.120 -    }
   3.121 -
   3.122 -    /* This could be moved earlier in the VMX resume sequence. */
   3.123 -    idtv_info_field = __vmread(IDT_VECTORING_INFO_FIELD);
   3.124 -    if ( unlikely(idtv_info_field & INTR_INFO_VALID_MASK) )
   3.125 -    {
   3.126 -        __vmwrite(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field);
   3.127 -
   3.128 -        /*
   3.129 -         * Safe: the length will only be interpreted for software exceptions
   3.130 -         * and interrupts. If we get here then delivery of some event caused a
   3.131 -         * fault, and this always results in defined VM_EXIT_INSTRUCTION_LEN.
   3.132 -         */
   3.133 -        inst_len = __vmread(VM_EXIT_INSTRUCTION_LEN); /* Safe */
   3.134 -        __vmwrite(VM_ENTRY_INSTRUCTION_LEN, inst_len);
   3.135 -
   3.136 -        if (unlikely(idtv_info_field & 0x800)) /* valid error code */
   3.137 -            __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE,
   3.138 -                      __vmread(IDT_VECTORING_ERROR_CODE));
   3.139 -        if (unlikely(has_ext_irq))
   3.140 -            enable_irq_window(v);
   3.141 -
   3.142 -        HVM_DBG_LOG(DBG_LEVEL_1, "idtv_info_field=%x", idtv_info_field);
   3.143 -
   3.144 -        return;
   3.145 -    }
   3.146 -
   3.147 -    if ( likely(!has_ext_irq) )
   3.148 -        return;
   3.149 -
   3.150 -    if ( unlikely(is_interruptibility_state()) )
   3.151 -    {
   3.152 -        /* pre-cleared for emulated instruction */
   3.153 -        enable_irq_window(v);
   3.154 -        HVM_DBG_LOG(DBG_LEVEL_1, "interruptibility");
   3.155 -        return;
   3.156 -    }
   3.157 -
   3.158 -    eflags = __vmread(GUEST_RFLAGS);
   3.159 -    if ( irq_masked(eflags) )
   3.160 -    {
   3.161 -        enable_irq_window(v);
   3.162 -        return;
   3.163 -    }
   3.164 -
   3.165 -    highest_vector = cpu_get_interrupt(v, &intr_type);
   3.166 -    if ( highest_vector < 0 )
   3.167 -        return;
   3.168 -
   3.169 -    switch ( intr_type )
   3.170 -    {
   3.171 -    case APIC_DM_EXTINT:
   3.172 -    case APIC_DM_FIXED:
   3.173 -    case APIC_DM_LOWEST:
   3.174 -        vmx_inject_extint(v, highest_vector, VMX_DELIVER_NO_ERROR_CODE);
   3.175 -        TRACE_3D(TRC_VMX_INTR, v->domain->domain_id, highest_vector, 0);
   3.176 -        break;
   3.177 -
   3.178 -    case APIC_DM_SMI:
   3.179 -    case APIC_DM_NMI:
   3.180 -    case APIC_DM_INIT:
   3.181 -    case APIC_DM_STARTUP:
   3.182 -    default:
   3.183 -        printk("Unsupported interrupt type\n");
   3.184 -        BUG();
   3.185 -        break;
   3.186 -    }
   3.187 -    
   3.188 -    hvm_interrupt_post(v, highest_vector, intr_type);
   3.189 -}
   3.190 -
   3.191 -/*
   3.192 - * Local variables:
   3.193 - * mode: C
   3.194 - * c-set-style: "BSD"
   3.195 - * c-basic-offset: 4
   3.196 - * tab-width: 4
   3.197 - * indent-tabs-mode: nil
   3.198 - * End:
   3.199 - */