direct-io.hg
changeset 11849:8e8128077259
Workaround for bigsmp APIC mode SMP linux guests - we cannot correctly deal
with timer interrupts being delivered to VCPUs other than 0, so spit a
warning and then subsequently ignore the target. This fixes the recent
issues Intel reported when booting SMP FC5 and FC6 kernels.
Needs a better fix at some point.
Signed-off-by: Steven Hand <steven@xensource.com>
with timer interrupts being delivered to VCPUs other than 0, so spit a
warning and then subsequently ignore the target. This fixes the recent
issues Intel reported when booting SMP FC5 and FC6 kernels.
Needs a better fix at some point.
Signed-off-by: Steven Hand <steven@xensource.com>
author | Steven Hand <steven@xensource.com> |
---|---|
date | Fri Oct 20 11:43:14 2006 +0100 (2006-10-20) |
parents | 59b41031641d |
children | 1633f9a3a120 |
files | xen/arch/x86/hvm/vioapic.c |
line diff
1.1 --- a/xen/arch/x86/hvm/vioapic.c Fri Oct 20 11:00:08 2006 +0100 1.2 +++ b/xen/arch/x86/hvm/vioapic.c Fri Oct 20 11:43:14 2006 +0100 1.3 @@ -42,6 +42,9 @@ 1.4 1.5 /* HACK: Route IRQ0 only to VCPU0 to prevent time jumps. */ 1.6 #define IRQ0_SPECIAL_ROUTING 1 1.7 +#ifdef IRQ0_SPECIAL_ROUTING 1.8 +static int redir_warning_done = 0; 1.9 +#endif 1.10 1.11 #if defined(__ia64__) 1.12 #define opt_hvm_debug_level opt_vmx_debug_level 1.13 @@ -155,6 +158,7 @@ static void hvm_vioapic_update_imr(struc 1.14 clear_bit(index, &s->imr); 1.15 } 1.16 1.17 + 1.18 static void hvm_vioapic_write_indirect(struct hvm_vioapic *s, 1.19 unsigned long addr, 1.20 unsigned long length, 1.21 @@ -179,21 +183,35 @@ static void hvm_vioapic_write_indirect(s 1.22 { 1.23 uint32_t redir_index = 0; 1.24 1.25 + redir_index = (s->ioregsel - 0x10) >> 1; 1.26 + 1.27 HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "hvm_vioapic_write_indirect " 1.28 "change redir index %x val %lx\n", 1.29 redir_index, val); 1.30 1.31 - redir_index = (s->ioregsel - 0x10) >> 1; 1.32 - 1.33 if (redir_index >= 0 && redir_index < IOAPIC_NUM_PINS) { 1.34 uint64_t redir_content; 1.35 1.36 redir_content = s->redirtbl[redir_index].value; 1.37 1.38 - if (s->ioregsel & 0x1) 1.39 + if (s->ioregsel & 0x1) { 1.40 +#ifdef IRQ0_SPECIAL_ROUTING 1.41 + if ( !redir_warning_done && (redir_index == 0) && 1.42 + ((val >> 24) != 0) ) { 1.43 + /* 1.44 + * Cannot yet handle delivering PIT interrupts to 1.45 + * any VCPU != 0. Needs proper fixing, but for now 1.46 + * simply spit a warning that we're going to ignore 1.47 + * the target in practice & always deliver to VCPU 0 1.48 + */ 1.49 + printk("IO-APIC: PIT (IRQ0) redirect to VCPU %lx " 1.50 + "will be ignored.\n", val >> 24); 1.51 + redir_warning_done = 1; 1.52 + } 1.53 +#endif 1.54 redir_content = (((uint64_t)val & 0xffffffff) << 32) | 1.55 (redir_content & 0xffffffff); 1.56 - else 1.57 + } else 1.58 redir_content = ((redir_content >> 32) << 32) | 1.59 (val & 0xffffffff); 1.60 s->redirtbl[redir_index].value = redir_content; 1.61 @@ -409,6 +427,8 @@ static void ioapic_deliver(hvm_vioapic_t 1.62 uint8_t vector = s->redirtbl[irqno].RedirForm.vector; 1.63 uint8_t trig_mode = s->redirtbl[irqno].RedirForm.trigmod; 1.64 uint32_t deliver_bitmask; 1.65 + struct vlapic *target; 1.66 + 1.67 1.68 HVM_DBG_LOG(DBG_LEVEL_IOAPIC, 1.69 "dest %x dest_mode %x delivery_mode %x vector %x trig_mode %x\n", 1.70 @@ -427,9 +447,8 @@ static void ioapic_deliver(hvm_vioapic_t 1.71 switch (delivery_mode) { 1.72 case dest_LowestPrio: 1.73 { 1.74 - struct vlapic* target; 1.75 - 1.76 #ifdef IRQ0_SPECIAL_ROUTING 1.77 + /* Force round-robin to pick VCPU 0 */ 1.78 if (irqno == 0) 1.79 target = s->lapic_info[0]; 1.80 else 1.81 @@ -450,19 +469,17 @@ static void ioapic_deliver(hvm_vioapic_t 1.82 { 1.83 uint8_t bit; 1.84 for (bit = 0; bit < s->lapic_count; bit++) { 1.85 - if (deliver_bitmask & (1 << bit)) { 1.86 + if ( !(deliver_bitmask & (1 << bit)) ) 1.87 + continue; 1.88 #ifdef IRQ0_SPECIAL_ROUTING 1.89 - if ( (irqno == 0) && (bit !=0) ) 1.90 - { 1.91 - printk("PIT irq to bit %x\n", bit); 1.92 - domain_crash_synchronous(); 1.93 - } 1.94 + /* Do not deliver timer interrupts to VCPU != 0 */ 1.95 + if ( (irqno == 0) && (bit !=0 ) ) 1.96 + target = s->lapic_info[0]; 1.97 + else 1.98 #endif 1.99 - if (s->lapic_info[bit]) { 1.100 - ioapic_inj_irq(s, s->lapic_info[bit], 1.101 - vector, trig_mode, delivery_mode); 1.102 - } 1.103 - } 1.104 + target = s->lapic_info[bit]; 1.105 + if (target) 1.106 + ioapic_inj_irq(s, target, vector, trig_mode, delivery_mode); 1.107 } 1.108 break; 1.109 }