direct-io.hg
changeset 10899:a6cb8ba24a91
[HVM] Place all APIC registers into one page in native format.
With this change we can re-use code at include/asm-x86/apicdef.h,
making the code much cleaner. Also it help for future enhancement.
This patch does not change any logic except the change to
CONTROL_REG_ACCESS_NUM, which should be 0xf for CR8 access.
Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com
With this change we can re-use code at include/asm-x86/apicdef.h,
making the code much cleaner. Also it help for future enhancement.
This patch does not change any logic except the change to
CONTROL_REG_ACCESS_NUM, which should be 0xf for CR8 access.
Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com
author | kfraser@localhost.localdomain |
---|---|
date | Wed Aug 02 10:07:03 2006 +0100 (2006-08-02) |
parents | 637b6d60e792 |
children | 637e64826342 |
files | xen/arch/x86/hvm/i8259.c xen/arch/x86/hvm/svm/intr.c xen/arch/x86/hvm/vioapic.c xen/arch/x86/hvm/vlapic.c xen/arch/x86/hvm/vmx/io.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-ia64/vmx_platform.h xen/include/asm-x86/hvm/support.h xen/include/asm-x86/hvm/vlapic.h xen/include/asm-x86/hvm/vmx/vmx.h |
line diff
1.1 --- a/xen/arch/x86/hvm/i8259.c Wed Aug 02 10:04:27 2006 +0100 1.2 +++ b/xen/arch/x86/hvm/i8259.c Wed Aug 02 10:07:03 2006 +0100 1.3 @@ -590,7 +590,7 @@ int cpu_get_pic_interrupt(struct vcpu *v 1.4 1.5 /* read the irq from the PIC */ 1.6 intno = pic_read_irq(s); 1.7 - *type = VLAPIC_DELIV_MODE_EXT; 1.8 + *type = APIC_DM_EXTINT; 1.9 return intno; 1.10 } 1.11 1.12 @@ -598,7 +598,7 @@ int is_pit_irq(struct vcpu *v, int irq, 1.13 { 1.14 int pit_vec; 1.15 1.16 - if (type == VLAPIC_DELIV_MODE_EXT) 1.17 + if (type == APIC_DM_EXTINT) 1.18 pit_vec = v->domain->arch.hvm_domain.vpic.pics[0].irq_base; 1.19 else 1.20 pit_vec =
2.1 --- a/xen/arch/x86/hvm/svm/intr.c Wed Aug 02 10:04:27 2006 +0100 2.2 +++ b/xen/arch/x86/hvm/svm/intr.c Wed Aug 02 10:07:03 2006 +0100 2.3 @@ -76,7 +76,7 @@ interrupt_post_injection(struct vcpu * v 2.4 2.5 switch(type) 2.6 { 2.7 - case VLAPIC_DELIV_MODE_EXT: 2.8 + case APIC_DM_EXTINT: 2.9 break; 2.10 2.11 default: 2.12 @@ -112,7 +112,7 @@ asmlinkage void svm_intr_assist(void) 2.13 struct hvm_domain *plat=&v->domain->arch.hvm_domain; 2.14 struct periodic_time *pt = &plat->pl_time.periodic_tm; 2.15 struct hvm_virpic *pic= &plat->vpic; 2.16 - int intr_type = VLAPIC_DELIV_MODE_EXT; 2.17 + int intr_type = APIC_DM_EXTINT; 2.18 int intr_vector = -1; 2.19 int re_injecting = 0; 2.20 unsigned long rflags; 2.21 @@ -172,9 +172,9 @@ asmlinkage void svm_intr_assist(void) 2.22 /* have we got an interrupt to inject? */ 2.23 if (intr_vector >= 0) { 2.24 switch (intr_type) { 2.25 - case VLAPIC_DELIV_MODE_EXT: 2.26 - case VLAPIC_DELIV_MODE_FIXED: 2.27 - case VLAPIC_DELIV_MODE_LPRI: 2.28 + case APIC_DM_EXTINT: 2.29 + case APIC_DM_FIXED: 2.30 + case APIC_DM_LOWEST: 2.31 /* Re-injecting a PIT interruptt? */ 2.32 if (re_injecting && 2.33 is_pit_irq(v, intr_vector, intr_type)) { 2.34 @@ -185,10 +185,10 @@ asmlinkage void svm_intr_assist(void) 2.35 svm_inject_extint(v, intr_vector, VMX_DELIVER_NO_ERROR_CODE); 2.36 interrupt_post_injection(v, intr_vector, intr_type); 2.37 break; 2.38 - case VLAPIC_DELIV_MODE_SMI: 2.39 - case VLAPIC_DELIV_MODE_NMI: 2.40 - case VLAPIC_DELIV_MODE_INIT: 2.41 - case VLAPIC_DELIV_MODE_STARTUP: 2.42 + case APIC_DM_SMI: 2.43 + case APIC_DM_NMI: 2.44 + case APIC_DM_INIT: 2.45 + case APIC_DM_STARTUP: 2.46 default: 2.47 printk("Unsupported interrupt type: %d\n", intr_type); 2.48 BUG();
3.1 --- a/xen/arch/x86/hvm/vioapic.c Wed Aug 02 10:04:27 2006 +0100 3.2 +++ b/xen/arch/x86/hvm/vioapic.c Wed Aug 02 10:07:03 2006 +0100 3.3 @@ -197,7 +197,7 @@ static void hvm_vioapic_write_indirect(s 3.4 redir_content = ((redir_content >> 32) << 32) | 3.5 (val & 0xffffffff); 3.6 s->redirtbl[redir_index].value = redir_content; 3.7 - hvm_vioapic_update_imr(s, redir_index); 3.8 + hvm_vioapic_update_imr(s, redir_index); 3.9 } else { 3.10 printk("hvm_vioapic_write_indirect " 3.11 "error register %x\n", s->ioregsel); 3.12 @@ -295,8 +295,8 @@ static int ioapic_inj_irq(hvm_vioapic_t 3.13 vector, trig_mode, delivery_mode); 3.14 3.15 switch (delivery_mode) { 3.16 - case VLAPIC_DELIV_MODE_FIXED: 3.17 - case VLAPIC_DELIV_MODE_LPRI: 3.18 + case dest_Fixed: 3.19 + case dest_LowestPrio: 3.20 if (vlapic_set_irq(target, vector, trig_mode) && (trig_mode == 1)) 3.21 printk("<ioapic_inj_irq> level interrupt happen before cleared\n"); 3.22 result = 1; 3.23 @@ -314,6 +314,7 @@ static int ioapic_inj_irq(hvm_vioapic_t 3.24 static int ioapic_match_logical_addr(hvm_vioapic_t *s, int number, uint8_t dest) 3.25 { 3.26 int result = 0; 3.27 + uint32_t logical_dest = vlapic_get_reg(s->lapic_info[number], APIC_LDR); 3.28 3.29 ASSERT(s && s->lapic_info[number]); 3.30 3.31 @@ -321,17 +322,17 @@ static int ioapic_match_logical_addr(hvm 3.32 "number %i dest %x\n", 3.33 number, dest); 3.34 3.35 - switch (((s->lapic_info[number]->dest_format >> 28) & 0xf)) { 3.36 - case 0xf: 3.37 + switch (vlapic_get_reg(s->lapic_info[number], APIC_DFR)) 3.38 + { 3.39 + case APIC_DFR_FLAT: 3.40 result = 3.41 - (dest & ((s->lapic_info[number]->logical_dest >> 24) & 0xff)) != 0; 3.42 + (dest & GET_APIC_LOGICAL_ID(logical_dest)) != 0; 3.43 break; 3.44 - case 0x0: 3.45 + case APIC_DFR_CLUSTER: 3.46 /* Should we support flat cluster mode ?*/ 3.47 - if ( ((s->lapic_info[number]->logical_dest >> 28) 3.48 + if ( (GET_APIC_LOGICAL_ID(logical_dest) >> 4 3.49 == ((dest >> 0x4) & 0xf)) && 3.50 - (((s->lapic_info[number]->logical_dest >> 24) & 0xf) 3.51 - & (dest & 0xf)) ) 3.52 + (logical_dest & (dest & 0xf)) ) 3.53 result = 1; 3.54 break; 3.55 default: 3.56 @@ -410,7 +411,7 @@ static void ioapic_deliver(hvm_vioapic_t 3.57 } 3.58 3.59 switch (delivery_mode) { 3.60 - case VLAPIC_DELIV_MODE_LPRI: 3.61 + case dest_LowestPrio: 3.62 { 3.63 struct vlapic* target; 3.64 3.65 @@ -430,8 +431,8 @@ static void ioapic_deliver(hvm_vioapic_t 3.66 break; 3.67 } 3.68 3.69 - case VLAPIC_DELIV_MODE_FIXED: 3.70 - case VLAPIC_DELIV_MODE_EXT: 3.71 + case dest_Fixed: 3.72 + case dest_ExtINT: 3.73 { 3.74 uint8_t bit; 3.75 for (bit = 0; bit < s->lapic_count; bit++) { 3.76 @@ -452,10 +453,10 @@ static void ioapic_deliver(hvm_vioapic_t 3.77 break; 3.78 } 3.79 3.80 - case VLAPIC_DELIV_MODE_SMI: 3.81 - case VLAPIC_DELIV_MODE_NMI: 3.82 - case VLAPIC_DELIV_MODE_INIT: 3.83 - case VLAPIC_DELIV_MODE_STARTUP: 3.84 + case dest_SMI: 3.85 + case dest_NMI: 3.86 + case dest_INIT: 3.87 + case dest__reserved_2: 3.88 default: 3.89 printk("Not support delivey mode %d\n", delivery_mode); 3.90 break;
4.1 --- a/xen/arch/x86/hvm/vlapic.c Wed Aug 02 10:04:27 2006 +0100 4.2 +++ b/xen/arch/x86/hvm/vlapic.c Wed Aug 02 10:07:03 2006 +0100 4.3 @@ -43,35 +43,43 @@ extern u32 get_apic_bus_cycle(void); 4.4 4.5 static unsigned int vlapic_lvt_mask[VLAPIC_LVT_NUM] = 4.6 { 4.7 - 0x310ff, 0x117ff, 0x117ff, 0x1f7ff, 0x1f7ff, 0x117ff 4.8 + /* LVTT */ 4.9 + LVT_MASK | APIC_LVT_TIMER_PERIODIC, 4.10 + /* LVTTHMR */ 4.11 + LVT_MASK | APIC_MODE_MASK, 4.12 + /* LVTPC */ 4.13 + LVT_MASK | APIC_MODE_MASK, 4.14 + /* LVT0-1 */ 4.15 + LINT_MASK, LINT_MASK, 4.16 + /* LVTERR */ 4.17 + LVT_MASK 4.18 }; 4.19 4.20 -int vlapic_find_highest_irr(struct vlapic *vlapic) 4.21 -{ 4.22 - int result; 4.23 - 4.24 - result = find_highest_bit(vlapic->irr, MAX_VECTOR); 4.25 - 4.26 - if ( result != -1 && result < 16 ) 4.27 - { 4.28 - printk("VLAPIC: irr on reserved bits %d\n ", result); 4.29 - domain_crash_synchronous(); 4.30 - } 4.31 - 4.32 - return result; 4.33 -} 4.34 - 4.35 int hvm_apic_support(struct domain *d) 4.36 { 4.37 return d->arch.hvm_domain.apic_enabled; 4.38 } 4.39 4.40 +int vlapic_find_highest_irr(struct vlapic *vlapic) 4.41 +{ 4.42 + int result; 4.43 + 4.44 + result = find_highest_bit((unsigned long *)(vlapic->regs + APIC_IRR), 4.45 + MAX_VECTOR); 4.46 + 4.47 + ASSERT( result == -1 || result > 16); 4.48 + 4.49 + return result; 4.50 +} 4.51 + 4.52 s_time_t get_apictime_scheduled(struct vcpu *v) 4.53 { 4.54 struct vlapic *vlapic = VLAPIC(v); 4.55 4.56 - if ( !hvm_apic_support(v->domain) || !vlapic_lvt_timer_enabled(vlapic) ) 4.57 + if ( !hvm_apic_support(v->domain) || 4.58 + !vlapic_lvt_enabled(vlapic, APIC_LVTT) ) 4.59 return -1; 4.60 + 4.61 return vlapic->vlapic_timer.expires; 4.62 } 4.63 4.64 @@ -79,16 +87,10 @@ int vlapic_find_highest_isr(struct vlapi 4.65 { 4.66 int result; 4.67 4.68 - result = find_highest_bit(vlapic->isr, MAX_VECTOR); 4.69 + result = find_highest_bit((unsigned long *)(vlapic->regs + APIC_ISR), 4.70 + MAX_VECTOR); 4.71 4.72 - if ( result != -1 && result < 16 ) 4.73 - { 4.74 - int i = 0; 4.75 - printk("VLAPIC: isr on reserved bits %d, isr is\n ", result); 4.76 - for ( i = 0; i < ARRAY_SIZE(vlapic->isr); i++ ) 4.77 - printk("%d: %p\n", i, (void *)vlapic->isr[i]); 4.78 - return -1; 4.79 - } 4.80 + ASSERT( result == -1 || result > 16); 4.81 4.82 return result; 4.83 } 4.84 @@ -98,20 +100,21 @@ uint32_t vlapic_update_ppr(struct vlapic 4.85 uint32_t tpr, isrv, ppr; 4.86 int isr; 4.87 4.88 - tpr = (vlapic->task_priority >> 4) & 0xf; /* we want 7:4 */ 4.89 + tpr = vlapic_get_reg(vlapic, APIC_TASKPRI); 4.90 4.91 isr = vlapic_find_highest_isr(vlapic); 4.92 + 4.93 if ( isr != -1 ) 4.94 isrv = (isr >> 4) & 0xf; /* ditto */ 4.95 else 4.96 isrv = 0; 4.97 4.98 - if ( tpr >= isrv ) 4.99 - ppr = vlapic->task_priority & 0xff; 4.100 + if ( (tpr >> 4) >= isrv ) 4.101 + ppr = tpr & 0xff; 4.102 else 4.103 ppr = isrv << 4; /* low 4 bits of PPR have to be cleared */ 4.104 4.105 - vlapic->processor_priority = ppr; 4.106 + vlapic_set_reg(vlapic, APIC_PROCPRI, ppr); 4.107 4.108 HVM_DBG_LOG(DBG_LEVEL_VLAPIC_INTERRUPT, 4.109 "vlapic %p, ppr 0x%x, isr 0x%x, isrv 0x%x.", 4.110 @@ -133,9 +136,9 @@ static int vlapic_match_dest(struct vcpu 4.111 target, source, dest, dest_mode, short_hand, delivery_mode); 4.112 4.113 if ( unlikely(target == NULL) && 4.114 - ((delivery_mode != VLAPIC_DELIV_MODE_INIT) && 4.115 - (delivery_mode != VLAPIC_DELIV_MODE_STARTUP) && 4.116 - (delivery_mode != VLAPIC_DELIV_MODE_NMI)) ) 4.117 + ((delivery_mode != APIC_DM_INIT) && 4.118 + (delivery_mode != APIC_DM_STARTUP) && 4.119 + (delivery_mode != APIC_DM_NMI)) ) 4.120 { 4.121 HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "uninitialized target vcpu %p, " 4.122 "delivery_mode 0x%x, dest 0x%x.\n", v, delivery_mode, dest); 4.123 @@ -143,22 +146,27 @@ static int vlapic_match_dest(struct vcpu 4.124 } 4.125 4.126 switch ( short_hand ) { 4.127 - case VLAPIC_NO_SHORTHAND: 4.128 + case APIC_DEST_NOSHORT: /* no shorthand */ 4.129 if ( !dest_mode ) /* Physical */ 4.130 { 4.131 - result = (target != NULL ? target->id : v->vcpu_id) == dest; 4.132 + result = ( ((target != NULL) ? 4.133 + GET_APIC_ID(vlapic_get_reg(target, APIC_ID)): 4.134 + v->vcpu_id)) == dest; 4.135 } 4.136 else /* Logical */ 4.137 { 4.138 + uint32_t ldr = vlapic_get_reg(target, APIC_LDR); 4.139 + 4.140 if ( target == NULL ) 4.141 break; 4.142 - if ( ((target->dest_format >> 28) & 0xf) == 0xf ) /* Flat mode */ 4.143 + /* Flat mode */ 4.144 + if ( vlapic_get_reg(target, APIC_DFR) == APIC_DFR_FLAT) 4.145 { 4.146 - result = (target->logical_dest >> 24) & dest; 4.147 + result = GET_APIC_LOGICAL_ID(ldr) & dest; 4.148 } 4.149 else 4.150 { 4.151 - if ( (delivery_mode == VLAPIC_DELIV_MODE_LPRI) && 4.152 + if ( (delivery_mode == APIC_DM_LOWEST) && 4.153 (dest == 0xff) ) 4.154 { 4.155 /* What shall we do now? */ 4.156 @@ -166,22 +174,22 @@ static int vlapic_match_dest(struct vcpu 4.157 "delivery mode\n"); 4.158 domain_crash_synchronous(); 4.159 } 4.160 - result = (target->logical_dest == (dest & 0xf)) ? 4.161 - ((target->logical_dest >> 4) & (dest >> 4)) : 0; 4.162 + result = (GET_APIC_LOGICAL_ID(ldr) == (dest & 0xf)) ? 4.163 + (GET_APIC_LOGICAL_ID(ldr) >> 4) & (dest >> 4) : 0; 4.164 } 4.165 } 4.166 break; 4.167 4.168 - case VLAPIC_SHORTHAND_SELF: 4.169 + case APIC_DEST_SELF: 4.170 if ( target == source ) 4.171 result = 1; 4.172 break; 4.173 4.174 - case VLAPIC_SHORTHAND_INCLUDE_SELF: 4.175 + case APIC_DEST_ALLINC: 4.176 result = 1; 4.177 break; 4.178 4.179 - case VLAPIC_SHORTHAND_EXCLUDE_SELF: 4.180 + case APIC_DEST_ALLBUT: 4.181 if ( target != source ) 4.182 result = 1; 4.183 break; 4.184 @@ -204,13 +212,13 @@ static int vlapic_accept_irq(struct vcpu 4.185 struct vlapic *vlapic = VLAPIC(v); 4.186 4.187 switch ( delivery_mode ) { 4.188 - case VLAPIC_DELIV_MODE_FIXED: 4.189 - case VLAPIC_DELIV_MODE_LPRI: 4.190 + case APIC_DM_FIXED: 4.191 + case APIC_DM_LOWEST: 4.192 /* FIXME add logic for vcpu on reset */ 4.193 if ( unlikely(vlapic == NULL || !vlapic_enabled(vlapic)) ) 4.194 break; 4.195 4.196 - if ( test_and_set_bit(vector, &vlapic->irr[0]) && level) 4.197 + if ( test_and_set_bit(vector, vlapic->regs + APIC_IRR) ) 4.198 { 4.199 HVM_DBG_LOG(DBG_LEVEL_VLAPIC, 4.200 "level trig mode repeatedly for vector %d\n", vector); 4.201 @@ -221,25 +229,25 @@ static int vlapic_accept_irq(struct vcpu 4.202 { 4.203 HVM_DBG_LOG(DBG_LEVEL_VLAPIC, 4.204 "level trig mode for vector %d\n", vector); 4.205 - set_bit(vector, &vlapic->tmr[0]); 4.206 + set_bit(vector, vlapic->regs + APIC_TMR); 4.207 } 4.208 evtchn_set_pending(v, iopacket_port(v)); 4.209 4.210 result = 1; 4.211 break; 4.212 4.213 - case VLAPIC_DELIV_MODE_RESERVED: 4.214 + case APIC_DM_REMRD: 4.215 printk("Ignore deliver mode 3 in vlapic_accept_irq\n"); 4.216 break; 4.217 4.218 - case VLAPIC_DELIV_MODE_SMI: 4.219 - case VLAPIC_DELIV_MODE_NMI: 4.220 + case APIC_DM_SMI: 4.221 + case APIC_DM_NMI: 4.222 /* Fixme */ 4.223 printk("TODO: for guest SMI/NMI\n"); 4.224 break; 4.225 4.226 - case VLAPIC_DELIV_MODE_INIT: 4.227 - if ( !level && trig_mode == 1 ) //Deassert 4.228 + case APIC_DM_INIT: 4.229 + if ( level && !(trig_mode & APIC_INT_ASSERT) ) //Deassert 4.230 printk("This hvm_vlapic is for P4, no work for De-assert init\n"); 4.231 else 4.232 { 4.233 @@ -255,7 +263,7 @@ static int vlapic_accept_irq(struct vcpu 4.234 } 4.235 break; 4.236 4.237 - case VLAPIC_DELIV_MODE_STARTUP: 4.238 + case APIC_DM_STARTUP: 4.239 if ( v->arch.hvm_vcpu.init_sipi_sipi_state == 4.240 HVM_VCPU_INIT_SIPI_SIPI_STATE_NORM ) 4.241 break; 4.242 @@ -346,22 +354,23 @@ void vlapic_EOI_set(struct vlapic *vlapi 4.243 if ( vector == -1 ) 4.244 return ; 4.245 4.246 - clear_bit(vector, &vlapic->isr[0]); 4.247 + clear_bit(vector, vlapic->regs + APIC_ISR); 4.248 vlapic_update_ppr(vlapic); 4.249 4.250 - if ( test_and_clear_bit(vector, &vlapic->tmr[0]) ) 4.251 + if ( test_and_clear_bit(vector, vlapic->regs + APIC_TMR) ) 4.252 ioapic_update_EOI(vlapic->domain, vector); 4.253 } 4.254 4.255 -int vlapic_check_vector(struct vlapic *vlapic, 4.256 - unsigned char dm, int vector) 4.257 +static int vlapic_check_vector(struct vlapic *vlapic, 4.258 + uint32_t dm, uint32_t vector) 4.259 { 4.260 - if ( (dm == VLAPIC_DELIV_MODE_FIXED) && (vector < 16) ) 4.261 + if ( (dm == APIC_DM_FIXED) && (vector < 16) ) 4.262 { 4.263 vlapic->err_status |= 0x40; 4.264 - vlapic_accept_irq(vlapic->vcpu, VLAPIC_DELIV_MODE_FIXED, 4.265 - vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR), 0, 0); 4.266 - printk("<vlapic_check_vector>: check failed.\n"); 4.267 + vlapic_accept_irq(vlapic->vcpu, APIC_DM_FIXED, 4.268 + vlapic_lvt_vector(vlapic, APIC_LVTERR), 0, 0); 4.269 + printk("<vlapic_check_vector>: check failed " 4.270 + " dm %x vector %x\n", dm, vector); 4.271 return 0; 4.272 } 4.273 return 1; 4.274 @@ -369,13 +378,16 @@ int vlapic_check_vector(struct vlapic *v 4.275 4.276 void vlapic_ipi(struct vlapic *vlapic) 4.277 { 4.278 - unsigned int dest = (vlapic->icr_high >> 24) & 0xff; 4.279 - unsigned int short_hand = (vlapic->icr_low >> 18) & 3; 4.280 - unsigned int trig_mode = (vlapic->icr_low >> 15) & 1; 4.281 - unsigned int level = (vlapic->icr_low >> 14) & 1; 4.282 - unsigned int dest_mode = (vlapic->icr_low >> 11) & 1; 4.283 - unsigned int delivery_mode = (vlapic->icr_low >> 8) & 7; 4.284 - unsigned int vector = (vlapic->icr_low & 0xff); 4.285 + uint32_t icr_low = vlapic_get_reg(vlapic, APIC_ICR); 4.286 + uint32_t icr_high = vlapic_get_reg(vlapic, APIC_ICR2); 4.287 + 4.288 + unsigned int dest = GET_APIC_DEST_FIELD(icr_high); 4.289 + unsigned int short_hand = icr_low & APIC_SHORT_MASK; 4.290 + unsigned int trig_mode = icr_low & APIC_INT_ASSERT; 4.291 + unsigned int level = icr_low & APIC_INT_LEVELTRIG; 4.292 + unsigned int dest_mode = icr_low & APIC_DEST_MASK; 4.293 + unsigned int delivery_mode = icr_low & APIC_MODE_MASK; 4.294 + unsigned int vector = icr_low & APIC_VECTOR_MASK; 4.295 4.296 struct vlapic *target; 4.297 struct vcpu *v = NULL; 4.298 @@ -384,7 +396,7 @@ void vlapic_ipi(struct vlapic *vlapic) 4.299 HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "icr_high 0x%x, icr_low 0x%x, " 4.300 "short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, " 4.301 "dest_mode 0x%x, delivery_mode 0x%x, vector 0x%x.", 4.302 - vlapic->icr_high, vlapic->icr_low, short_hand, dest, 4.303 + icr_high, icr_low, short_hand, dest, 4.304 trig_mode, level, dest_mode, delivery_mode, vector); 4.305 4.306 for_each_vcpu ( vlapic->domain, v ) 4.307 @@ -392,7 +404,7 @@ void vlapic_ipi(struct vlapic *vlapic) 4.308 if ( vlapic_match_dest(v, vlapic, short_hand, 4.309 dest, dest_mode, delivery_mode) ) 4.310 { 4.311 - if ( delivery_mode == VLAPIC_DELIV_MODE_LPRI ) 4.312 + if ( delivery_mode == APIC_DM_LOWEST) 4.313 set_bit(v->vcpu_id, &lpr_map); 4.314 else 4.315 vlapic_accept_irq(v, delivery_mode, 4.316 @@ -400,7 +412,7 @@ void vlapic_ipi(struct vlapic *vlapic) 4.317 } 4.318 } 4.319 4.320 - if ( delivery_mode == VLAPIC_DELIV_MODE_LPRI ) 4.321 + if ( delivery_mode == APIC_DM_LOWEST) 4.322 { 4.323 v = vlapic->vcpu; 4.324 target = apic_round_robin(v->domain, dest_mode, vector, lpr_map); 4.325 @@ -411,158 +423,73 @@ void vlapic_ipi(struct vlapic *vlapic) 4.326 } 4.327 } 4.328 4.329 +static uint32_t vlapic_get_tmcct(struct vlapic *vlapic) 4.330 +{ 4.331 + uint32_t counter_passed; 4.332 + s_time_t passed, now = NOW(); 4.333 + uint32_t tmcct = vlapic_get_reg(vlapic, APIC_TMCCT); 4.334 + 4.335 + ASSERT(vlapic != NULL); 4.336 + 4.337 + if ( unlikely(now <= vlapic->timer_last_update) ) 4.338 + { 4.339 + passed = ~0x0LL - vlapic->timer_last_update + now; 4.340 + HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "time elapsed."); 4.341 + } 4.342 + else 4.343 + passed = now - vlapic->timer_last_update; 4.344 + 4.345 + counter_passed = passed / 4.346 + (APIC_BUS_CYCLE_NS * vlapic->timer_divide_count); 4.347 + 4.348 + tmcct -= counter_passed; 4.349 + 4.350 + if ( tmcct <= 0 ) 4.351 + { 4.352 + if ( unlikely(!vlapic_lvtt_period(vlapic)) ) 4.353 + { 4.354 + tmcct = 0; 4.355 + // FIXME: should we add interrupt here? 4.356 + } 4.357 + else 4.358 + { 4.359 + do { 4.360 + tmcct += vlapic_get_reg(vlapic, APIC_TMICT); 4.361 + } while ( tmcct < 0 ); 4.362 + } 4.363 + } 4.364 + 4.365 + vlapic->timer_last_update = now; 4.366 + vlapic_set_reg(vlapic, APIC_TMCCT, tmcct); 4.367 + 4.368 + HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, 4.369 + "timer initial count 0x%x, timer current count 0x%x, " 4.370 + "update 0x%016"PRIx64", now 0x%016"PRIx64", offset 0x%x.", 4.371 + vlapic_get_reg(vlapic, APIC_TMICT), 4.372 + vlapic_get_reg(vlapic, APIC_TMCCT), 4.373 + vlapic->timer_last_update, now, counter_passed); 4.374 + 4.375 + return tmcct; 4.376 +} 4.377 + 4.378 static void vlapic_read_aligned(struct vlapic *vlapic, unsigned int offset, 4.379 unsigned int len, unsigned int *result) 4.380 { 4.381 - if ( len != 4 ) 4.382 - printk("<vlapic_read_aligned> read with len=%d (should be 4).\n", len); 4.383 + ASSERT(len == 4 && offset > 0 && offset <= APIC_TDCR); 4.384 4.385 *result = 0; 4.386 4.387 switch ( offset ) { 4.388 - case APIC_ID: 4.389 - *result = vlapic->id << 24; 4.390 - break; 4.391 - 4.392 - case APIC_LVR: 4.393 - *result = vlapic->version; 4.394 - break; 4.395 - 4.396 - case APIC_TASKPRI: 4.397 - *result = vlapic->task_priority; 4.398 - break; 4.399 - 4.400 case APIC_ARBPRI: 4.401 printk("access local APIC ARBPRI register which is for P6\n"); 4.402 break; 4.403 4.404 - case APIC_PROCPRI: 4.405 - *result = vlapic->processor_priority; 4.406 - break; 4.407 - 4.408 - case APIC_EOI: /* EOI is write only */ 4.409 - break; 4.410 - 4.411 - case APIC_LDR: 4.412 - *result = vlapic->logical_dest; 4.413 - break; 4.414 - 4.415 - case APIC_DFR: 4.416 - *result = vlapic->dest_format; 4.417 - break; 4.418 - 4.419 - case APIC_SPIV: 4.420 - *result = vlapic->spurious_vec; 4.421 - break; 4.422 - 4.423 - case APIC_ISR: 4.424 - case 0x110: 4.425 - case 0x120: 4.426 - case 0x130: 4.427 - case 0x140: 4.428 - case 0x150: 4.429 - case 0x160: 4.430 - case 0x170: 4.431 - *result = vlapic->isr[(offset - APIC_ISR) >> 4]; 4.432 - break; 4.433 - 4.434 - case APIC_TMR: 4.435 - case 0x190: 4.436 - case 0x1a0: 4.437 - case 0x1b0: 4.438 - case 0x1c0: 4.439 - case 0x1d0: 4.440 - case 0x1e0: 4.441 - case 0x1f0: 4.442 - *result = vlapic->tmr[(offset - APIC_TMR) >> 4]; 4.443 - break; 4.444 - 4.445 - case APIC_IRR: 4.446 - case 0x210: 4.447 - case 0x220: 4.448 - case 0x230: 4.449 - case 0x240: 4.450 - case 0x250: 4.451 - case 0x260: 4.452 - case 0x270: 4.453 - *result = vlapic->irr[(offset - APIC_IRR) >> 4]; 4.454 - break; 4.455 - 4.456 - case APIC_ESR: 4.457 - if ( vlapic->err_write_count ) 4.458 - *result = vlapic->err_status; 4.459 - break; 4.460 - 4.461 - case APIC_ICR: 4.462 - *result = vlapic->icr_low; 4.463 - break; 4.464 - 4.465 - case APIC_ICR2: 4.466 - *result = vlapic->icr_high; 4.467 - break; 4.468 - 4.469 - case APIC_LVTT: /* LVT Timer Reg */ 4.470 - case APIC_LVTTHMR: /* LVT Thermal Monitor */ 4.471 - case APIC_LVTPC: /* LVT Performance Counter */ 4.472 - case APIC_LVT0: /* LVT LINT0 Reg */ 4.473 - case APIC_LVT1: /* LVT Lint1 Reg */ 4.474 - case APIC_LVTERR: /* LVT Error Reg */ 4.475 - *result = vlapic->lvt[(offset - APIC_LVTT) >> 4]; 4.476 - break; 4.477 - 4.478 - case APIC_TMICT: 4.479 - *result = vlapic->timer_initial_count; 4.480 - break; 4.481 - 4.482 case APIC_TMCCT: //Timer CCR 4.483 - { 4.484 - uint32_t counter_passed; 4.485 - s_time_t passed, now = NOW(); 4.486 - 4.487 - if ( unlikely(now <= vlapic->timer_current_update) ) 4.488 - { 4.489 - passed = ~0x0LL - vlapic->timer_current_update + now; 4.490 - HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "time elapsed."); 4.491 - } 4.492 - else 4.493 - passed = now - vlapic->timer_current_update; 4.494 - 4.495 - counter_passed = passed / 4.496 - (APIC_BUS_CYCLE_NS * vlapic->timer_divide_count); 4.497 - vlapic->timer_current_count -= counter_passed; 4.498 - if ( vlapic->timer_current_count <= 0 ) 4.499 - { 4.500 - if ( unlikely(!vlapic_lvt_timer_period(vlapic)) ) 4.501 - { 4.502 - vlapic->timer_current_count = 0; 4.503 - // FIXME: should we add interrupt here? 4.504 - } 4.505 - else 4.506 - { 4.507 - do { 4.508 - vlapic->timer_current_count += vlapic->timer_initial_count; 4.509 - } while ( vlapic->timer_current_count < 0 ); 4.510 - } 4.511 - } 4.512 - 4.513 - *result = vlapic->timer_current_count; 4.514 - vlapic->timer_current_update = now; 4.515 - 4.516 - HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, 4.517 - "timer initial count 0x%x, timer current count 0x%x, " 4.518 - "update 0x%016"PRIx64", now 0x%016"PRIx64", offset 0x%x.", 4.519 - vlapic->timer_initial_count, vlapic->timer_current_count, 4.520 - vlapic->timer_current_update, now, counter_passed); 4.521 - } 4.522 - break; 4.523 - 4.524 - case APIC_TDCR: 4.525 - *result = vlapic->timer_divconf; 4.526 + *result = vlapic_get_tmcct(vlapic); 4.527 break; 4.528 4.529 default: 4.530 - printk("Read local APIC address 0x%x not implemented\n", offset); 4.531 - *result = 0; 4.532 + *result = vlapic_get_reg(vlapic, offset); 4.533 break; 4.534 } 4.535 } 4.536 @@ -576,6 +503,9 @@ static unsigned long vlapic_read(struct 4.537 struct vlapic *vlapic = VLAPIC(v); 4.538 unsigned int offset = address - vlapic->base_address; 4.539 4.540 + if ( offset > APIC_TDCR) 4.541 + return 0; 4.542 + 4.543 /* some bugs on kernel cause read this with byte*/ 4.544 if ( len != 4 ) 4.545 HVM_DBG_LOG(DBG_LEVEL_VLAPIC, 4.546 @@ -671,11 +601,11 @@ static void vlapic_write(struct vcpu *v, 4.547 4.548 switch ( offset ) { 4.549 case APIC_ID: /* Local APIC ID */ 4.550 - vlapic->id = ((val) >> 24) & VAPIC_ID_MASK; 4.551 + vlapic_set_reg(vlapic, APIC_ID, val); 4.552 break; 4.553 4.554 case APIC_TASKPRI: 4.555 - vlapic->task_priority = val & 0xff; 4.556 + vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff); 4.557 vlapic_update_ppr(vlapic); 4.558 break; 4.559 4.560 @@ -684,24 +614,41 @@ static void vlapic_write(struct vcpu *v, 4.561 break; 4.562 4.563 case APIC_LDR: 4.564 - vlapic->logical_dest = val & VAPIC_LDR_MASK; 4.565 + vlapic_set_reg(vlapic, APIC_LDR, val & APIC_LDR_MASK); 4.566 break; 4.567 4.568 case APIC_DFR: 4.569 - vlapic->dest_format = val ; 4.570 + vlapic_set_reg(vlapic, APIC_DFR, val); 4.571 break; 4.572 4.573 case APIC_SPIV: 4.574 - vlapic->spurious_vec = val & 0x1ff; 4.575 - if ( !(vlapic->spurious_vec & 0x100) ) 4.576 + vlapic_set_reg(vlapic, APIC_SPIV, val & 0x1ff); 4.577 + 4.578 + if ( !( val & APIC_SPIV_APIC_ENABLED) ) 4.579 { 4.580 int i; 4.581 + uint32_t lvt_val; 4.582 + 4.583 + vlapic->status |= VLAPIC_SOFTWARE_DISABLE_MASK; 4.584 + 4.585 for ( i = 0; i < VLAPIC_LVT_NUM; i++ ) 4.586 - vlapic->lvt[i] |= 0x10000; 4.587 - vlapic->status |= VLAPIC_SOFTWARE_DISABLE_MASK; 4.588 + { 4.589 + lvt_val = vlapic_get_reg(vlapic, APIC_LVT1 + 0x10 * i); 4.590 + vlapic_set_reg(vlapic, APIC_LVTT + 0x10 * i, 4.591 + lvt_val | APIC_LVT_MASKED); 4.592 + } 4.593 + 4.594 + if ( (vlapic_get_reg(vlapic, APIC_LVT0) & APIC_MODE_MASK) 4.595 + == APIC_DM_EXTINT ) 4.596 + clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status); 4.597 } 4.598 else 4.599 + { 4.600 vlapic->status &= ~VLAPIC_SOFTWARE_DISABLE_MASK; 4.601 + if ( (vlapic_get_reg(vlapic, APIC_LVT0) & APIC_MODE_MASK) 4.602 + == APIC_DM_EXTINT ) 4.603 + set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status); 4.604 + } 4.605 break; 4.606 4.607 case APIC_ESR: 4.608 @@ -712,12 +659,12 @@ static void vlapic_write(struct vcpu *v, 4.609 4.610 case APIC_ICR: 4.611 /* No delay here, so we always clear the pending bit*/ 4.612 - vlapic->icr_low = val & ~(1 << 12); 4.613 + vlapic_set_reg(vlapic, APIC_ICR, val & ~(1 << 12)); 4.614 vlapic_ipi(vlapic); 4.615 break; 4.616 4.617 case APIC_ICR2: 4.618 - vlapic->icr_high = val & 0xff000000; 4.619 + vlapic_set_reg(vlapic, APIC_ICR2, val & 0xff000000); 4.620 break; 4.621 4.622 case APIC_LVTT: // LVT Timer Reg 4.623 @@ -727,26 +674,25 @@ static void vlapic_write(struct vcpu *v, 4.624 case APIC_LVT1: // LVT Lint1 Reg 4.625 case APIC_LVTERR: // LVT Error Reg 4.626 { 4.627 - int vt = (offset - APIC_LVTT) >> 4; 4.628 + if ( vlapic->status & VLAPIC_SOFTWARE_DISABLE_MASK ) 4.629 + val |= APIC_LVT_MASKED; 4.630 4.631 - vlapic->lvt[vt] = val & vlapic_lvt_mask[vt]; 4.632 - if ( vlapic->status & VLAPIC_SOFTWARE_DISABLE_MASK ) 4.633 - vlapic->lvt[vt] |= VLAPIC_LVT_BIT_MASK; 4.634 + val &= vlapic_lvt_mask[(offset - APIC_LVTT) >> 4]; 4.635 + 4.636 + vlapic_set_reg(vlapic, offset, val); 4.637 4.638 /* On hardware, when write vector less than 0x20 will error */ 4.639 - vlapic_check_vector(vlapic, vlapic_lvt_dm(vlapic->lvt[vt]), 4.640 - vlapic_lvt_vector(vlapic, vt)); 4.641 + if ( !(val & APIC_LVT_MASKED) ) 4.642 + vlapic_check_vector(vlapic, vlapic_lvt_dm(vlapic, offset), 4.643 + vlapic_lvt_vector(vlapic, offset)); 4.644 4.645 if ( !vlapic->vcpu_id && (offset == APIC_LVT0) ) 4.646 { 4.647 - if ( (vlapic->lvt[VLAPIC_LVT_LINT0] & VLAPIC_LVT_BIT_DELIMOD) 4.648 - == 0x700 ) 4.649 - { 4.650 - if ( vlapic->lvt[VLAPIC_LVT_LINT0] & VLAPIC_LVT_BIT_MASK ) 4.651 + if ( (val & APIC_MODE_MASK) == APIC_DM_EXTINT ) 4.652 + if ( val & APIC_LVT_MASKED) 4.653 clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status); 4.654 else 4.655 set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status); 4.656 - } 4.657 else 4.658 clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status); 4.659 } 4.660 @@ -758,16 +704,14 @@ static void vlapic_write(struct vcpu *v, 4.661 { 4.662 s_time_t now = NOW(), offset; 4.663 4.664 - if ( vlapic_timer_active(vlapic) ) 4.665 - stop_timer(&vlapic->vlapic_timer); 4.666 + stop_timer(&vlapic->vlapic_timer); 4.667 4.668 - vlapic->timer_initial_count = val; 4.669 - vlapic->timer_current_count = val; 4.670 - vlapic->timer_current_update = now; 4.671 + vlapic_set_reg(vlapic, APIC_TMICT, val); 4.672 + vlapic_set_reg(vlapic, APIC_TMCCT, val); 4.673 + vlapic->timer_last_update = now; 4.674 4.675 offset = APIC_BUS_CYCLE_NS * 4.676 - vlapic->timer_divide_count * 4.677 - vlapic->timer_initial_count; 4.678 + vlapic->timer_divide_count * val; 4.679 4.680 set_timer(&vlapic->vlapic_timer, now + offset); 4.681 4.682 @@ -775,7 +719,8 @@ static void vlapic_write(struct vcpu *v, 4.683 "bus cycle is %"PRId64"ns, now 0x%016"PRIx64", " 4.684 "timer initial count 0x%x, offset 0x%016"PRIx64", " 4.685 "expire @ 0x%016"PRIx64".", 4.686 - APIC_BUS_CYCLE_NS, now, vlapic->timer_initial_count, 4.687 + APIC_BUS_CYCLE_NS, now, 4.688 + vlapic_get_reg(vlapic, APIC_TMICT), 4.689 offset, now + offset); 4.690 } 4.691 break; 4.692 @@ -788,6 +733,8 @@ static void vlapic_write(struct vcpu *v, 4.693 tmp2 = ((tmp1 & 0x3) | ((tmp1 & 0x8) >> 1)) + 1; 4.694 vlapic->timer_divide_count = 0x1 << (tmp2 & 0x7); 4.695 4.696 + vlapic_set_reg(vlapic, APIC_TDCR, val); 4.697 + 4.698 HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, "timer divide count is 0x%x", 4.699 vlapic->timer_divide_count); 4.700 } 4.701 @@ -827,21 +774,20 @@ void vlapic_msr_set(struct vlapic *vlapi 4.702 value &= ~MSR_IA32_APICBASE_BSP; 4.703 4.704 vlapic->apic_base_msr = value; 4.705 - vlapic->base_address = vlapic_get_base_address(vlapic); 4.706 + vlapic->base_address = vlapic->apic_base_msr & 4.707 + MSR_IA32_APICBASE_BASE; 4.708 4.709 - if ( !(value & 0x800) ) 4.710 + /* with FSB delivery interrupt, we can restart APIC functionality */ 4.711 + if ( !(value & MSR_IA32_APICBASE_ENABLE) ) 4.712 set_bit(_VLAPIC_GLOB_DISABLE, &vlapic->status ); 4.713 + else 4.714 + clear_bit(_VLAPIC_GLOB_DISABLE, &vlapic->status); 4.715 4.716 HVM_DBG_LOG(DBG_LEVEL_VLAPIC, 4.717 "apic base msr is 0x%016"PRIx64", and base address is 0x%lx.", 4.718 vlapic->apic_base_msr, vlapic->base_address); 4.719 } 4.720 4.721 -static inline int vlapic_get_init_id(struct vcpu *v) 4.722 -{ 4.723 - return v->vcpu_id; 4.724 -} 4.725 - 4.726 void vlapic_timer_fn(void *data) 4.727 { 4.728 struct vlapic *vlapic = data; 4.729 @@ -850,31 +796,32 @@ void vlapic_timer_fn(void *data) 4.730 s_time_t now; 4.731 4.732 if ( unlikely(!vlapic_enabled(vlapic) || 4.733 - !vlapic_lvt_timer_enabled(vlapic)) ) 4.734 + !vlapic_lvt_enabled(vlapic, APIC_LVTT)) ) 4.735 return; 4.736 4.737 v = vlapic->vcpu; 4.738 - timer_vector = vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER); 4.739 + timer_vector = vlapic_lvt_vector(vlapic, APIC_LVTT); 4.740 now = NOW(); 4.741 4.742 - vlapic->timer_current_update = now; 4.743 + vlapic->timer_last_update = now; 4.744 4.745 - if ( test_and_set_bit(timer_vector, &vlapic->irr[0]) ) 4.746 + if ( test_and_set_bit(timer_vector, vlapic->regs + APIC_IRR )) 4.747 vlapic->intr_pending_count[timer_vector]++; 4.748 4.749 - if ( vlapic_lvt_timer_period(vlapic) ) 4.750 + if ( vlapic_lvtt_period(vlapic) ) 4.751 { 4.752 s_time_t offset; 4.753 + uint32_t tmict = vlapic_get_reg(vlapic, APIC_TMICT); 4.754 4.755 - vlapic->timer_current_count = vlapic->timer_initial_count; 4.756 + vlapic_set_reg(vlapic, APIC_TMCCT, tmict); 4.757 4.758 offset = APIC_BUS_CYCLE_NS * 4.759 - vlapic->timer_divide_count * 4.760 - vlapic->timer_initial_count; 4.761 + vlapic->timer_divide_count * tmict; 4.762 + 4.763 set_timer(&vlapic->vlapic_timer, now + offset); 4.764 } 4.765 else 4.766 - vlapic->timer_current_count = 0; 4.767 + vlapic_set_reg(vlapic, APIC_TMCCT, 0); 4.768 4.769 #if 0 4.770 if ( test_bit(_VCPUF_running, &v->vcpu_flags) ) 4.771 @@ -887,8 +834,8 @@ void vlapic_timer_fn(void *data) 4.772 "now 0x%016"PRIx64", expire @ 0x%016"PRIx64", " 4.773 "timer initial count 0x%x, timer current count 0x%x.", 4.774 now, vlapic->vlapic_timer.expires, 4.775 - vlapic->timer_initial_count, 4.776 - vlapic->timer_current_count); 4.777 + vlapic_get_reg(vlapic, APIC_TMICT), 4.778 + vlapic_get_reg(vlapic, APIC_TMCCT)); 4.779 } 4.780 4.781 #if 0 4.782 @@ -923,23 +870,23 @@ int cpu_get_apic_interrupt(struct vcpu * 4.783 int highest_irr = vlapic_find_highest_irr(vlapic); 4.784 4.785 if ( highest_irr != -1 && 4.786 - ( (highest_irr & 0xF0) > vlapic->processor_priority ) ) 4.787 + ( (highest_irr & 0xF0) > vlapic_get_reg(vlapic, APIC_PROCPRI) ) ) 4.788 { 4.789 if ( highest_irr < 0x10 ) 4.790 { 4.791 uint32_t err_vector; 4.792 4.793 vlapic->err_status |= 0x20; 4.794 - err_vector = vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR); 4.795 + err_vector = vlapic_lvt_vector(vlapic, APIC_LVTERR); 4.796 4.797 HVM_DBG_LOG(DBG_LEVEL_VLAPIC, 4.798 "Sending an illegal vector 0x%x.", highest_irr); 4.799 4.800 - set_bit(err_vector, &vlapic->irr[0]); 4.801 + set_bit(err_vector, vlapic->regs + APIC_IRR); 4.802 highest_irr = err_vector; 4.803 } 4.804 4.805 - *mode = VLAPIC_DELIV_MODE_FIXED; 4.806 + *mode = APIC_DM_FIXED; 4.807 return highest_irr; 4.808 } 4.809 } 4.810 @@ -954,7 +901,7 @@ int cpu_has_apic_interrupt(struct vcpu* 4.811 int highest_irr = vlapic_find_highest_irr(vlapic); 4.812 4.813 if ( highest_irr != -1 && 4.814 - ( (highest_irr & 0xF0) > vlapic->processor_priority ) ) { 4.815 + ( (highest_irr & 0xF0) > vlapic_get_reg(vlapic, APIC_PROCPRI) ) ) { 4.816 return 1; 4.817 } 4.818 } 4.819 @@ -969,30 +916,30 @@ void vlapic_post_injection(struct vcpu * 4.820 return; 4.821 4.822 switch ( deliver_mode ) { 4.823 - case VLAPIC_DELIV_MODE_FIXED: 4.824 - case VLAPIC_DELIV_MODE_LPRI: 4.825 - set_bit(vector, &vlapic->isr[0]); 4.826 - clear_bit(vector, &vlapic->irr[0]); 4.827 + case APIC_DM_FIXED: 4.828 + case APIC_DM_LOWEST: 4.829 + set_bit(vector, vlapic->regs + APIC_ISR); 4.830 + clear_bit(vector, vlapic->regs + APIC_IRR); 4.831 vlapic_update_ppr(vlapic); 4.832 4.833 - if ( vector == vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER) ) 4.834 + if ( vector == vlapic_lvt_vector(vlapic, APIC_LVTT) ) 4.835 { 4.836 vlapic->intr_pending_count[vector]--; 4.837 if ( vlapic->intr_pending_count[vector] > 0 ) 4.838 - test_and_set_bit(vector, &vlapic->irr[0]); 4.839 + test_and_set_bit(vector, vlapic->regs + APIC_IRR); 4.840 } 4.841 break; 4.842 4.843 /*XXX deal with these later */ 4.844 - case VLAPIC_DELIV_MODE_RESERVED: 4.845 + case APIC_DM_REMRD: 4.846 printk("Ignore deliver mode 3 in vlapic_post_injection\n"); 4.847 break; 4.848 4.849 - case VLAPIC_DELIV_MODE_SMI: 4.850 - case VLAPIC_DELIV_MODE_NMI: 4.851 - case VLAPIC_DELIV_MODE_INIT: 4.852 - case VLAPIC_DELIV_MODE_STARTUP: 4.853 - vlapic->direct_intr.deliver_mode &= ~(1 << deliver_mode); 4.854 + case APIC_DM_SMI: 4.855 + case APIC_DM_NMI: 4.856 + case APIC_DM_INIT: 4.857 + case APIC_DM_STARTUP: 4.858 + vlapic->direct_intr.deliver_mode &= deliver_mode; 4.859 break; 4.860 4.861 default: 4.862 @@ -1004,7 +951,7 @@ void vlapic_post_injection(struct vcpu * 4.863 static int vlapic_reset(struct vlapic *vlapic) 4.864 { 4.865 struct vcpu *v; 4.866 - int apic_id, i; 4.867 + int i; 4.868 4.869 ASSERT( vlapic != NULL ); 4.870 4.871 @@ -1012,29 +959,28 @@ static int vlapic_reset(struct vlapic *v 4.872 4.873 ASSERT( v != NULL ); 4.874 4.875 - apic_id = v->vcpu_id; 4.876 - 4.877 vlapic->domain = v->domain; 4.878 4.879 - vlapic->id = apic_id; 4.880 - 4.881 vlapic->vcpu_id = v->vcpu_id; 4.882 4.883 - vlapic->version = VLAPIC_VERSION; 4.884 + vlapic_set_reg(vlapic, APIC_ID, v->vcpu_id << 24); 4.885 + 4.886 + vlapic_set_reg(vlapic, APIC_LVR, VLAPIC_VERSION); 4.887 + 4.888 + for ( i = 0; i < VLAPIC_LVT_NUM; i++ ) 4.889 + vlapic_set_reg(vlapic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED); 4.890 4.891 - vlapic->apic_base_msr = VLAPIC_BASE_MSR_INIT_VALUE; 4.892 + vlapic_set_reg(vlapic, APIC_DFR, 0xffffffffU); 4.893 + 4.894 + vlapic_set_reg(vlapic, APIC_SPIV, 0xff); 4.895 4.896 - if ( apic_id == 0 ) 4.897 + vlapic->apic_base_msr = MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE; 4.898 + 4.899 + if ( v->vcpu_id == 0 ) 4.900 vlapic->apic_base_msr |= MSR_IA32_APICBASE_BSP; 4.901 4.902 - vlapic->base_address = vlapic_get_base_address(vlapic); 4.903 - 4.904 - for ( i = 0; i < VLAPIC_LVT_NUM; i++ ) 4.905 - vlapic->lvt[i] = VLAPIC_LVT_BIT_MASK; 4.906 - 4.907 - vlapic->dest_format = 0xffffffffU; 4.908 - 4.909 - vlapic->spurious_vec = 0xff; 4.910 + vlapic->base_address = vlapic->apic_base_msr & 4.911 + MSR_IA32_APICBASE_BASE; 4.912 4.913 hvm_vioapic_add_lapic(vlapic, v); 4.914 4.915 @@ -1048,8 +994,8 @@ static int vlapic_reset(struct vlapic *v 4.916 */ 4.917 if ( !v->vcpu_id ) 4.918 { 4.919 - vlapic->lvt[VLAPIC_LVT_LINT0] = 0x700; 4.920 - vlapic->lvt[VLAPIC_LVT_LINT1] = 0x500; 4.921 + vlapic_set_reg(vlapic, APIC_LVT0, APIC_MODE_EXTINT << 8); 4.922 + vlapic_set_reg(vlapic, APIC_LVT1, APIC_MODE_NMI << 8); 4.923 set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status); 4.924 } 4.925 #endif 4.926 @@ -1057,7 +1003,8 @@ static int vlapic_reset(struct vlapic *v 4.927 HVM_DBG_LOG(DBG_LEVEL_VLAPIC, 4.928 "vcpu=%p, id=%d, vlapic_apic_base_msr=0x%016"PRIx64", " 4.929 "base_address=0x%0lx.", 4.930 - v, vlapic->id, vlapic->apic_base_msr, vlapic->base_address); 4.931 + v, GET_APIC_ID(vlapic_get_reg(vlapic, APIC_ID)), 4.932 + vlapic->apic_base_msr, vlapic->base_address); 4.933 4.934 return 1; 4.935 } 4.936 @@ -1079,6 +1026,18 @@ int vlapic_init(struct vcpu *v) 4.937 4.938 memset(vlapic, 0, sizeof(struct vlapic)); 4.939 4.940 + vlapic->regs_page = alloc_domheap_page(NULL); 4.941 + if ( vlapic->regs_page == NULL ) 4.942 + { 4.943 + printk("malloc vlapic regs error for vcpu %x\n", v->vcpu_id); 4.944 + xfree(vlapic); 4.945 + return -ENOMEM; 4.946 + } 4.947 + 4.948 + vlapic->regs = map_domain_page_global(page_to_mfn(vlapic->regs_page)); 4.949 + 4.950 + memset(vlapic->regs, 0, PAGE_SIZE); 4.951 + 4.952 VLAPIC(v) = vlapic; 4.953 4.954 vlapic->vcpu = v;
5.1 --- a/xen/arch/x86/hvm/vmx/io.c Wed Aug 02 10:04:27 2006 +0100 5.2 +++ b/xen/arch/x86/hvm/vmx/io.c Wed Aug 02 10:07:03 2006 +0100 5.3 @@ -81,7 +81,7 @@ interrupt_post_injection(struct vcpu * v 5.4 5.5 switch(type) 5.6 { 5.7 - case VLAPIC_DELIV_MODE_EXT: 5.8 + case APIC_DM_EXTINT: 5.9 break; 5.10 5.11 default: 5.12 @@ -198,16 +198,17 @@ asmlinkage void vmx_intr_assist(void) 5.13 5.14 highest_vector = cpu_get_interrupt(v, &intr_type); 5.15 switch (intr_type) { 5.16 - case VLAPIC_DELIV_MODE_EXT: 5.17 - case VLAPIC_DELIV_MODE_FIXED: 5.18 - case VLAPIC_DELIV_MODE_LPRI: 5.19 + case APIC_DM_EXTINT: 5.20 + case APIC_DM_FIXED: 5.21 + case APIC_DM_LOWEST: 5.22 vmx_inject_extint(v, highest_vector, VMX_DELIVER_NO_ERROR_CODE); 5.23 TRACE_3D(TRC_VMX_INT, v->domain->domain_id, highest_vector, 0); 5.24 break; 5.25 - case VLAPIC_DELIV_MODE_SMI: 5.26 - case VLAPIC_DELIV_MODE_NMI: 5.27 - case VLAPIC_DELIV_MODE_INIT: 5.28 - case VLAPIC_DELIV_MODE_STARTUP: 5.29 + 5.30 + case APIC_DM_SMI: 5.31 + case APIC_DM_NMI: 5.32 + case APIC_DM_INIT: 5.33 + case APIC_DM_STARTUP: 5.34 default: 5.35 printk("Unsupported interrupt type\n"); 5.36 BUG();
6.1 --- a/xen/arch/x86/hvm/vmx/vmx.c Wed Aug 02 10:04:27 2006 +0100 6.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c Wed Aug 02 10:07:03 2006 +0100 6.3 @@ -137,6 +137,8 @@ static void vmx_relinquish_guest_resourc 6.4 if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) ) 6.5 { 6.6 kill_timer(&VLAPIC(v)->vlapic_timer); 6.7 + unmap_domain_page_global(VLAPIC(v)->regs); 6.8 + free_domheap_page(VLAPIC(v)->regs_page); 6.9 xfree(VLAPIC(v)); 6.10 } 6.11 }
7.1 --- a/xen/include/asm-ia64/vmx_platform.h Wed Aug 02 10:04:27 2006 +0100 7.2 +++ b/xen/include/asm-ia64/vmx_platform.h Wed Aug 02 10:07:03 2006 +0100 7.3 @@ -59,6 +59,17 @@ static inline int vlapic_set_irq(struct 7.4 return vmx_vcpu_pend_interrupt(t->vcpu, vec); 7.5 } 7.6 7.7 +enum ioapic_irq_destination_types { 7.8 + dest_Fixed = 0, 7.9 + dest_LowestPrio = 1, 7.10 + dest_SMI = 2, 7.11 + dest__reserved_1 = 3, 7.12 + dest_NMI = 4, 7.13 + dest_INIT = 5, 7.14 + dest__reserved_2 = 6, 7.15 + dest_ExtINT = 7 7.16 +}; 7.17 + 7.18 /* As long as we register vlsapic to ioapic controller, it's said enabled */ 7.19 #define vlapic_enabled(l) 1 7.20 #define hvm_apic_support(d) 1
8.1 --- a/xen/include/asm-x86/hvm/support.h Wed Aug 02 10:04:27 2006 +0100 8.2 +++ b/xen/include/asm-x86/hvm/support.h Wed Aug 02 10:07:03 2006 +0100 8.3 @@ -29,7 +29,7 @@ 8.4 #ifndef NDEBUG 8.5 #define HVM_DEBUG 1 8.6 #else 8.7 -#define HVM_DEBUG 0 8.8 +#define HVM_DEBUG 1 8.9 #endif 8.10 8.11 #define hvm_guest(v) ((v)->arch.guest_context.flags & VGCF_HVM_GUEST)
9.1 --- a/xen/include/asm-x86/hvm/vlapic.h Wed Aug 02 10:04:27 2006 +0100 9.2 +++ b/xen/include/asm-x86/hvm/vlapic.h Wed Aug 02 10:07:03 2006 +0100 9.3 @@ -33,58 +33,31 @@ static __inline__ int find_highest_bit(u 9.4 9.5 #define VLAPIC(v) (v->arch.hvm_vcpu.vlapic) 9.6 9.7 -#define VAPIC_ID_MASK 0xff 9.8 -#define VAPIC_LDR_MASK (VAPIC_ID_MASK << 24) 9.9 #define VLAPIC_VERSION 0x00050014 9.10 9.11 -#define VLAPIC_BASE_MSR_MASK 0x00000000fffff900ULL 9.12 -#define VLAPIC_BASE_MSR_INIT_BASE_ADDR 0xfee00000U 9.13 -#define VLAPIC_BASE_MSR_BASE_ADDR_MASK 0xfffff000U 9.14 -#define VLAPIC_BASE_MSR_INIT_VALUE (VLAPIC_BASE_MSR_INIT_BASE_ADDR | \ 9.15 - MSR_IA32_APICBASE_ENABLE) 9.16 #define VLOCAL_APIC_MEM_LENGTH (1 << 12) 9.17 9.18 -#define VLAPIC_LVT_TIMER 0 9.19 -#define VLAPIC_LVT_THERMAL 1 9.20 -#define VLAPIC_LVT_PERFORM 2 9.21 -#define VLAPIC_LVT_LINT0 3 9.22 -#define VLAPIC_LVT_LINT1 4 9.23 -#define VLAPIC_LVT_ERROR 5 9.24 #define VLAPIC_LVT_NUM 6 9.25 9.26 -#define VLAPIC_LVT_BIT_MASK (1 << 16) 9.27 -#define VLAPIC_LVT_BIT_VECTOR 0xff 9.28 -#define VLAPIC_LVT_BIT_DELIMOD (0x7 << 8) 9.29 -#define VLAPIC_LVT_BIT_DELISTATUS (1 << 12) 9.30 -#define VLAPIC_LVT_BIT_POLARITY (1 << 13) 9.31 -#define VLAPIC_LVT_BIT_IRR (1 << 14) 9.32 -#define VLAPIC_LVT_BIT_TRIG (1 << 15) 9.33 -#define VLAPIC_LVT_TIMERMODE (1 << 17) 9.34 +#define VLAPIC_ID(vlapic) \ 9.35 + (GET_APIC_ID(vlapic_get_reg(vlapic, APIC_ID))) 9.36 + 9.37 +/* followed define is not in apicdef.h */ 9.38 +#define APIC_SHORT_MASK 0xc0000 9.39 +#define APIC_DEST_NOSHORT 0x0 9.40 +#define APIC_DEST_MASK 0x800 9.41 9.42 -#define VLAPIC_DELIV_MODE_FIXED 0x0 9.43 -#define VLAPIC_DELIV_MODE_LPRI 0x1 9.44 -#define VLAPIC_DELIV_MODE_SMI 0x2 9.45 -#define VLAPIC_DELIV_MODE_RESERVED 0x3 9.46 -#define VLAPIC_DELIV_MODE_NMI 0x4 9.47 -#define VLAPIC_DELIV_MODE_INIT 0x5 9.48 -#define VLAPIC_DELIV_MODE_STARTUP 0x6 9.49 -#define VLAPIC_DELIV_MODE_EXT 0x7 9.50 +#define vlapic_lvt_enabled(vlapic, lvt_type) \ 9.51 + (!(vlapic_get_reg(vlapic, lvt_type) & APIC_LVT_MASKED)) 9.52 9.53 +#define vlapic_lvt_vector(vlapic, lvt_type) \ 9.54 + (vlapic_get_reg(vlapic, lvt_type) & APIC_VECTOR_MASK) 9.55 9.56 -#define VLAPIC_NO_SHORTHAND 0x0 9.57 -#define VLAPIC_SHORTHAND_SELF 0x1 9.58 -#define VLAPIC_SHORTHAND_INCLUDE_SELF 0x2 9.59 -#define VLAPIC_SHORTHAND_EXCLUDE_SELF 0x3 9.60 +#define vlapic_lvt_dm(vlapic, lvt_type) \ 9.61 + (vlapic_get_reg(vlapic, lvt_type) & APIC_MODE_MASK) 9.62 9.63 -#define vlapic_lvt_timer_enabled(vlapic) \ 9.64 - (!((vlapic)->lvt[VLAPIC_LVT_TIMER] & VLAPIC_LVT_BIT_MASK)) 9.65 - 9.66 -#define vlapic_lvt_vector(vlapic, type) \ 9.67 - ((vlapic)->lvt[(type)] & VLAPIC_LVT_BIT_VECTOR) 9.68 - 9.69 -#define vlapic_lvt_dm(value) (((value) >> 8) && 7) 9.70 -#define vlapic_lvt_timer_period(vlapic) \ 9.71 - ((vlapic)->lvt[VLAPIC_LVT_TIMER] & VLAPIC_LVT_TIMERMODE) 9.72 +#define vlapic_lvtt_period(vlapic) \ 9.73 + (vlapic_get_reg(vlapic, APIC_LVTT) & APIC_LVT_TIMER_PERIODIC) 9.74 9.75 #define _VLAPIC_GLOB_DISABLE 0x0 9.76 #define VLAPIC_GLOB_DISABLE_MASK 0x1 9.77 @@ -98,8 +71,12 @@ static __inline__ int find_highest_bit(u 9.78 #define vlapic_global_enabled(vlapic) \ 9.79 (!(test_bit(_VLAPIC_GLOB_DISABLE, &(vlapic)->status))) 9.80 9.81 -#define VLAPIC_IRR(t) ((t)->irr[0]) 9.82 -#define VLAPIC_ID(t) ((t)->id) 9.83 +#define LVT_MASK \ 9.84 + APIC_LVT_MASKED | APIC_SEND_PENDING | APIC_VECTOR_MASK 9.85 + 9.86 +#define LINT_MASK \ 9.87 + LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY |\ 9.88 + APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER 9.89 9.90 typedef struct direct_intr_info { 9.91 int deliver_mode; 9.92 @@ -109,73 +86,53 @@ typedef struct direct_intr_info { 9.93 #define MAX_VECTOR 256 9.94 9.95 struct vlapic { 9.96 - uint32_t version; 9.97 uint32_t status; 9.98 - uint32_t id; 9.99 uint32_t vcpu_id; 9.100 + uint64_t apic_base_msr; 9.101 unsigned long base_address; 9.102 - unsigned long isr[BITS_TO_LONGS(MAX_VECTOR)]; 9.103 - unsigned long irr[BITS_TO_LONGS(MAX_VECTOR)]; 9.104 - unsigned long tmr[BITS_TO_LONGS(MAX_VECTOR)]; 9.105 - uint32_t task_priority; 9.106 - uint32_t processor_priority; 9.107 - uint32_t logical_dest; 9.108 - uint32_t dest_format; 9.109 - uint32_t spurious_vec; 9.110 - uint32_t lvt[6]; 9.111 - uint32_t timer_initial_count; 9.112 - uint32_t timer_current_count; 9.113 - uint32_t timer_divconf; 9.114 uint32_t timer_divide_count; 9.115 struct timer vlapic_timer; 9.116 int intr_pending_count[MAX_VECTOR]; 9.117 - s_time_t timer_current_update; 9.118 - uint32_t icr_high; 9.119 - uint32_t icr_low; 9.120 + s_time_t timer_last_update; 9.121 direct_intr_info_t direct_intr; 9.122 uint32_t err_status; 9.123 - unsigned long init_ticks; 9.124 uint32_t err_write_count; 9.125 - uint64_t apic_base_msr; 9.126 struct vcpu *vcpu; 9.127 struct domain *domain; 9.128 + struct page_info *regs_page; 9.129 + void *regs; 9.130 }; 9.131 9.132 -static inline int vlapic_set_irq(struct vlapic *t, uint8_t vec, uint8_t trig) 9.133 +static inline int vlapic_set_irq(struct vlapic *vlapic, 9.134 + uint8_t vec, uint8_t trig) 9.135 { 9.136 int ret; 9.137 9.138 - ret = test_and_set_bit(vec, &t->irr[0]); 9.139 + ret = test_and_set_bit(vec, vlapic->regs + APIC_IRR); 9.140 if ( trig ) 9.141 - set_bit(vec, &t->tmr[0]); 9.142 + set_bit(vec, vlapic->regs + APIC_TMR); 9.143 9.144 /* We may need to wake up target vcpu, besides set pending bit here */ 9.145 return ret; 9.146 } 9.147 9.148 -static inline int vlapic_timer_active(struct vlapic *vlapic) 9.149 +static inline uint32_t vlapic_get_reg(struct vlapic *vlapic, uint32_t reg) 9.150 { 9.151 - return active_timer(&vlapic->vlapic_timer); 9.152 + return *( (uint32_t *)(vlapic->regs + reg)); 9.153 } 9.154 9.155 -int vlapic_find_highest_irr(struct vlapic *vlapic); 9.156 - 9.157 -int vlapic_find_highest_isr(struct vlapic *vlapic); 9.158 +static inline void vlapic_set_reg(struct vlapic *vlapic, 9.159 + uint32_t reg, uint32_t val) 9.160 +{ 9.161 + *((uint32_t *)(vlapic->regs + reg)) = val; 9.162 +} 9.163 9.164 -static uint32_t inline vlapic_get_base_address(struct vlapic *vlapic) 9.165 -{ 9.166 - return (vlapic->apic_base_msr & VLAPIC_BASE_MSR_BASE_ADDR_MASK); 9.167 -} 9.168 9.169 void vlapic_post_injection(struct vcpu* v, int vector, int deliver_mode); 9.170 9.171 int cpu_has_apic_interrupt(struct vcpu* v); 9.172 int cpu_get_apic_interrupt(struct vcpu* v, int *mode); 9.173 9.174 -extern uint32_t vlapic_update_ppr(struct vlapic *vlapic); 9.175 - 9.176 -int vlapic_update(struct vcpu *v); 9.177 - 9.178 extern int vlapic_init(struct vcpu *vc); 9.179 9.180 extern void vlapic_msr_set(struct vlapic *vlapic, uint64_t value);
10.1 --- a/xen/include/asm-x86/hvm/vmx/vmx.h Wed Aug 02 10:04:27 2006 +0100 10.2 +++ b/xen/include/asm-x86/hvm/vmx/vmx.h Wed Aug 02 10:07:03 2006 +0100 10.3 @@ -153,7 +153,7 @@ extern unsigned int cpu_rev; 10.4 /* 10.5 * Exit Qualifications for MOV for Control Register Access 10.6 */ 10.7 -#define CONTROL_REG_ACCESS_NUM 0x7 /* 2:0, number of control register */ 10.8 +#define CONTROL_REG_ACCESS_NUM 0xf /* 3:0, number of control register */ 10.9 #define CONTROL_REG_ACCESS_TYPE 0x30 /* 5:4, access type */ 10.10 #define CONTROL_REG_ACCESS_REG 0xf00 /* 10:8, general purpose register */ 10.11 #define LMSW_SOURCE_DATA (0xFFFF << 16) /* 16:31 lmsw source */