debuggers.hg
changeset 12704:a3aab403ec21
[HVM][VMX] Rename io.c -> intr.c.
Signed-off-by: Keir Fraser <keir@xensource.com>
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 - */