On Mon, 2009-11-09 at 18:34 +0800, Stefano Stabellini wrote:
> On Mon, 9 Nov 2009, Qing He wrote:
> > The data and address registers is the sole way to update MSI vector and
> > affinity (at least when not using intremap), but the problem here is
> > that QEmu overwrite the hypervisor changes using stale data.
> > As we know, guest MSI is virtual, this means guest MSI address and data
> > are all emulated, and guest vector has nothing to do with real vector.
> > QEmu needs to map and bind MSI through Xen. via the following two calls:
> > xc_physdev_map_pirq_msi
> > xc_domain_bind_pt_irq
> > The physical content of MSI data/address is then decided and written by Xen.
> > xc_physdev_map_pirq_msi is also used to update guest MSI, including vector
> > and affinity.
> > Now come to the pt_pci_write_config logic:
> > pci_read_block(&read_val);
> > reg->u.dw.write(read_val, &val); // the handler
> > pci_write_block(val);
> > Since MSI data/address is fully emulated, val always equals to read_val,
> > i.e. write what is read back to the register. This would be OK for most of
> > the time, however, when the guest changes MSI affinity, something happens
> > between read and write. the handler calls xc_physdev_map_pirq_msi to update
> > the MSI, hypervisor changes the affinity and write a new vector/affinity
> > to the real registers. When the handler returns, pci_write_block(val)
> > overwrites the real registers, all the HV changes are lost, making the
> > MSI fail.
> If "val always equals to read_val", why do we need to call
> pci_write_block at all?
val == read_val is not necessarily true for registers other than
MSI data/address, but pt_pci_write_config tend to be generic for
all pci config.
Xen-devel mailing list