Message ID | 20110203141537.GY14984@redhat.com |
---|---|
State | New |
Headers | show |
On 02/03/2011 04:15 PM, Gleb Natapov wrote: > > > > Maybe this is true for the in-kernel model, but I don't see the issue > > (anymore) for the way user space works. > > > With patch below I can boot Windows7. > > diff --git a/hw/apic.c b/hw/apic.c > index 146deca..fdcac88 100644 > --- a/hw/apic.c > +++ b/hw/apic.c > @@ -600,7 +600,7 @@ int apic_get_interrupt(DeviceState *d) > intno = get_highest_priority_int(s->irr); > if (intno< 0) > return -1; > - if (s->tpr&& intno<= s->tpr) > + if ((s->tpr>> 4)&& (intno>> 4)<= (s->tpr>> 4)) > return s->spurious_vec& 0xff; > reset_bit(s->irr, intno); > set_bit(s->isr, intno); That still allows interrupts that have higher priority than the TPR, but lower priority than interrupts in the ISR to be injected. I think we need to use the PPR here (same as apic_update_irq()).
On Sun, Feb 06, 2011 at 12:26:40PM +0200, Avi Kivity wrote: > On 02/03/2011 04:15 PM, Gleb Natapov wrote: > >> > >> Maybe this is true for the in-kernel model, but I don't see the issue > >> (anymore) for the way user space works. > >> > >With patch below I can boot Windows7. > > > >diff --git a/hw/apic.c b/hw/apic.c > >index 146deca..fdcac88 100644 > >--- a/hw/apic.c > >+++ b/hw/apic.c > >@@ -600,7 +600,7 @@ int apic_get_interrupt(DeviceState *d) > > intno = get_highest_priority_int(s->irr); > > if (intno< 0) > > return -1; > >- if (s->tpr&& intno<= s->tpr) > >+ if ((s->tpr>> 4)&& (intno>> 4)<= (s->tpr>> 4)) > > return s->spurious_vec& 0xff; > > reset_bit(s->irr, intno); > > set_bit(s->isr, intno); > > That still allows interrupts that have higher priority than the TPR, > but lower priority than interrupts in the ISR to be injected. I > think we need to use the PPR here (same as apic_update_irq()). > We shouldn't get here if isr is non-empty, but see the patch I posted today to qemu-devel. It does what you say anyway. -- Gleb.
diff --git a/hw/apic.c b/hw/apic.c index 146deca..fdcac88 100644 --- a/hw/apic.c +++ b/hw/apic.c @@ -600,7 +600,7 @@ int apic_get_interrupt(DeviceState *d) intno = get_highest_priority_int(s->irr); if (intno < 0) return -1; - if (s->tpr && intno <= s->tpr) + if ((s->tpr >> 4) && (intno >> 4) <= (s->tpr >> 4)) return s->spurious_vec & 0xff; reset_bit(s->irr, intno); set_bit(s->isr, intno);