From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Jan Beulich" Subject: [PATCH 2/2] AMD IOMMU: handle MSI for phantom functions Date: Wed, 06 Feb 2013 13:12:42 +0000 Message-ID: <511264DA02000078000BC758@nat28.tlf.novell.com> References: <511262E302000078000BC738@nat28.tlf.novell.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=__PartA797E9DA.1__=" Return-path: In-Reply-To: <511262E302000078000BC738@nat28.tlf.novell.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel Cc: Boris Ostrovsky , Sherry Hurwitz List-Id: xen-devel@lists.xenproject.org This is a MIME message. If you are reading this text, you may want to consider changing to a mail reader or gateway that understands how to properly handle MIME multipart messages. --=__PartA797E9DA.1__= Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Content-Disposition: inline With ordinary requests allowed to come from phantom functions, the remapping tables ought to be set up to also allow for MSI triggers to come from other than the "real" device too. It is not clear to me whether the alias-ID handling also needs adjustment for this to work properly, or whether firmware can be expected to properly express this through a device alias range descriptor (or multiple device alias ones). Signed-off-by: Jan Beulich --- a/xen/drivers/passthrough/amd/iommu_intr.c +++ b/xen/drivers/passthrough/amd/iommu_intr.c @@ -286,7 +286,7 @@ void amd_iommu_ioapic_update_ire( =20 static void update_intremap_entry_from_msi_msg( struct amd_iommu *iommu, u16 bdf, - struct msi_desc *msi_desc, struct msi_msg *msg) + int *remap_index, const struct msi_msg *msg) { unsigned long flags; u32* entry; @@ -302,7 +302,7 @@ static void update_intremap_entry_from_m { lock =3D get_intremap_lock(iommu->seg, req_id); spin_lock_irqsave(lock, flags); - free_intremap_entry(iommu->seg, req_id, msi_desc->remap_index); + free_intremap_entry(iommu->seg, req_id, *remap_index); spin_unlock_irqrestore(lock, flags); =20 if ( ( req_id !=3D alias_id ) && @@ -310,7 +310,7 @@ static void update_intremap_entry_from_m { lock =3D get_intremap_lock(iommu->seg, alias_id); spin_lock_irqsave(lock, flags); - free_intremap_entry(iommu->seg, alias_id, msi_desc->remap_inde= x); + free_intremap_entry(iommu->seg, alias_id, *remap_index); spin_unlock_irqrestore(lock, flags); } goto done; @@ -324,7 +324,10 @@ static void update_intremap_entry_from_m vector =3D (msg->data >> MSI_DATA_VECTOR_SHIFT) & MSI_DATA_VECTOR_MASK= ; dest =3D (msg->address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff; offset =3D get_intremap_offset(vector, delivery_mode); - msi_desc->remap_index =3D offset; + if ( *remap_index < 0) + *remap_index =3D offset; + else + BUG_ON(*remap_index !=3D offset); =20 entry =3D (u32*)get_intremap_entry(iommu->seg, req_id, offset); update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest); @@ -379,12 +382,30 @@ void amd_iommu_msi_msg_update_ire( } =20 if ( msi_desc->remap_index >=3D 0 ) - update_intremap_entry_from_msi_msg(iommu, bdf, msi_desc, NULL); + { + do { + update_intremap_entry_from_msi_msg(iommu, bdf, + &msi_desc->remap_index, = NULL); + if ( !pdev || !pdev->phantom_stride ) + break; + bdf +=3D pdev->phantom_stride; + } while ( PCI_SLOT(bdf) =3D=3D PCI_SLOT(pdev->devfn) ); + + msi_desc->remap_index =3D -1; + if ( pdev ) + bdf =3D PCI_BDF2(pdev->bus, pdev->devfn); + } =20 if ( !msg ) return; =20 - update_intremap_entry_from_msi_msg(iommu, bdf, msi_desc, msg); + do { + update_intremap_entry_from_msi_msg(iommu, bdf, &msi_desc->remap_in= dex, + msg); + if ( !pdev || !pdev->phantom_stride ) + break; + bdf +=3D pdev->phantom_stride; + } while ( PCI_SLOT(bdf) =3D=3D PCI_SLOT(pdev->devfn) ); } =20 void amd_iommu_read_msi_from_ire( --=__PartA797E9DA.1__= Content-Type: text/plain; name="AMD-IOMMU-phantom-MSI.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="AMD-IOMMU-phantom-MSI.patch" AMD IOMMU: handle MSI for phantom functions=0A=0AWith ordinary requests = allowed to come from phantom functions, the=0Aremapping tables ought to be = set up to also allow for MSI triggers to=0Acome from other than the "real" = device too.=0A=0AIt is not clear to me whether the alias-ID handling also = needs=0Aadjustment for this to work properly, or whether firmware can = be=0Aexpected to properly express this through a device alias range=0Adescr= iptor (or multiple device alias ones).=0A=0ASigned-off-by: Jan Beulich = =0A=0A--- a/xen/drivers/passthrough/amd/iommu_intr.c=0A+= ++ b/xen/drivers/passthrough/amd/iommu_intr.c=0A@@ -286,7 +286,7 @@ void = amd_iommu_ioapic_update_ire(=0A =0A static void update_intremap_entry_from_= msi_msg(=0A struct amd_iommu *iommu, u16 bdf,=0A- struct msi_desc = *msi_desc, struct msi_msg *msg)=0A+ int *remap_index, const struct = msi_msg *msg)=0A {=0A unsigned long flags;=0A u32* entry;=0A@@ = -302,7 +302,7 @@ static void update_intremap_entry_from_m=0A {=0A = lock =3D get_intremap_lock(iommu->seg, req_id);=0A spin_lock_irq= save(lock, flags);=0A- free_intremap_entry(iommu->seg, req_id, = msi_desc->remap_index);=0A+ free_intremap_entry(iommu->seg, req_id, = *remap_index);=0A spin_unlock_irqrestore(lock, flags);=0A =0A = if ( ( req_id !=3D alias_id ) &&=0A@@ -310,7 +310,7 @@ static void = update_intremap_entry_from_m=0A {=0A lock =3D = get_intremap_lock(iommu->seg, alias_id);=0A spin_lock_irqsave(l= ock, flags);=0A- free_intremap_entry(iommu->seg, alias_id, = msi_desc->remap_index);=0A+ free_intremap_entry(iommu->seg, = alias_id, *remap_index);=0A spin_unlock_irqrestore(lock, = flags);=0A }=0A goto done;=0A@@ -324,7 +324,10 @@ static = void update_intremap_entry_from_m=0A vector =3D (msg->data >> = MSI_DATA_VECTOR_SHIFT) & MSI_DATA_VECTOR_MASK;=0A dest =3D (msg->addres= s_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff;=0A offset =3D get_intremap_offs= et(vector, delivery_mode);=0A- msi_desc->remap_index =3D offset;=0A+ = if ( *remap_index < 0)=0A+ *remap_index =3D offset;=0A+ else=0A+ = BUG_ON(*remap_index !=3D offset);=0A =0A entry =3D (u32*)get_int= remap_entry(iommu->seg, req_id, offset);=0A update_intremap_entry(entry= , vector, delivery_mode, dest_mode, dest);=0A@@ -379,12 +382,30 @@ void = amd_iommu_msi_msg_update_ire(=0A }=0A =0A if ( msi_desc->remap_inde= x >=3D 0 )=0A- update_intremap_entry_from_msi_msg(iommu, bdf, = msi_desc, NULL);=0A+ {=0A+ do {=0A+ update_intremap_en= try_from_msi_msg(iommu, bdf,=0A+ = &msi_desc->remap_index, NULL);=0A+ if ( !pdev || !pdev->phan= tom_stride )=0A+ break;=0A+ bdf +=3D pdev->phanto= m_stride;=0A+ } while ( PCI_SLOT(bdf) =3D=3D PCI_SLOT(pdev->devfn) = );=0A+=0A+ msi_desc->remap_index =3D -1;=0A+ if ( pdev )=0A+ = bdf =3D PCI_BDF2(pdev->bus, pdev->devfn);=0A+ }=0A =0A = if ( !msg )=0A return;=0A =0A- update_intremap_entry_from_msi_ms= g(iommu, bdf, msi_desc, msg);=0A+ do {=0A+ update_intremap_entry_= from_msi_msg(iommu, bdf, &msi_desc->remap_index,=0A+ = msg);=0A+ if ( !pdev || !pdev->phantom_stride = )=0A+ break;=0A+ bdf +=3D pdev->phantom_stride;=0A+ } = while ( PCI_SLOT(bdf) =3D=3D PCI_SLOT(pdev->devfn) );=0A }=0A =0A void = amd_iommu_read_msi_from_ire(=0A --=__PartA797E9DA.1__= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel --=__PartA797E9DA.1__=--