On Thu, Mar 21, 2013 at 03:42:46AM +0000, Zhang, Yang Z wrote:
> Gleb Natapov wrote on 2013-03-20:
> > On Wed, Mar 20, 2013 at 07:36:17PM +0800, Yang Zhang wrote:
> >> From: Yang Zhang <yang.z.zh...@intel.com>
> >>
> >> Update RTC interrrupt's destination vcpu map when ioapic entry of RTC
> >> or apic register (id, ldr, dfr) is changed.
> >>
> >> Signed-off-by: Yang Zhang <yang.z.zh...@intel.com>
> >> ---
> >> virt/kvm/ioapic.c | 9 +++++++--
> >> 1 files changed, 7 insertions(+), 2 deletions(-)
> >> diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
> >> index ddf9414..91b4c08 100644
> >> --- a/virt/kvm/ioapic.c
> >> +++ b/virt/kvm/ioapic.c
> >> @@ -121,6 +121,7 @@ void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu,
> >> { struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic; union
> >> kvm_ioapic_redirect_entry *e; + unsigned long *rtc_map =
> >> ioapic->rtc_status.vcpu_map; struct kvm_lapic_irq irqe; int
> >> index;
> >> @@ -130,15 +131,19 @@ void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu,
> >> if (!e->fields.mask &&
> >> (e->fields.trig_mode == IOAPIC_LEVEL_TRIG ||
> >> kvm_irq_has_notifier(ioapic->kvm, KVM_IRQCHIP_IOAPIC,
> >> - index))) {
> >> + index) || index == 8)) {
> >> irqe.dest_id = e->fields.dest_id;
> >> irqe.vector = e->fields.vector;
> >> irqe.dest_mode = e->fields.dest_mode;
> >> irqe.shorthand = 0;
> >>
> >> if (kvm_apic_match_dest(vcpu, NULL, irqe.shorthand,
> >> - irqe.dest_id, irqe.dest_mode))
> >> + irqe.dest_id, irqe.dest_mode)) {
> >> __set_bit(irqe.vector, eoi_exit_bitmap);
> >> + if (index == 8)
> >> + __set_bit(vcpu->vcpu_id, rtc_map);
> >> + } else if (index == 8)
> >> + __clear_bit(vcpu->vcpu_id, rtc_map);
> > rtc_map bitmap is accessed from different vcpus simultaneously so access
> > has to be atomic. We also have a race:
> >
> > vcpu0 iothread
> > ioapic config changes
> > request scan ioapic
> > inject rtc interrupt
> > use old vcpu mask
> > scan_ioapic()
> > recalculate vcpu mask
> >
> > So this approach (suggested by me :() will not work.
> >
> > Need to think about it some more. May be your idea of building a bitmap
> > while injecting the interrupt is the way to go indeed: pass a pointer to
> > a bitmap to kvm_irq_delivery_to_apic() and build it there. Pass NULL
> > pointer if caller does not need to track vcpus.
> Or, we can block inject rtc interrupt during recalculate vcpu map.
>
> if(need_eoi > 0 && in_recalculating)
> return coalesced
>
This should be ||. Then you need to maintain in_recalculating and
recalculations requests may overlap. Too complex and fragile.
--
Gleb.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html