From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Jan Beulich" Subject: [PATCH v3 02/10] x86/MSI-X: access MSI-X table only after having enabled MSI-X Date: Fri, 05 Jun 2015 12:20:48 +0100 Message-ID: <5571A2300200007800081455@mail.emea.novell.com> References: <55719F9D0200007800081425@mail.emea.novell.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=__PartCAFEE300.1__=" Return-path: Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1Z0pgC-0003HD-84 for xen-devel@lists.xenproject.org; Fri, 05 Jun 2015 11:20:52 +0000 In-Reply-To: <55719F9D0200007800081425@mail.emea.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: Andrew Cooper , Keir Fraser 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. --=__PartCAFEE300.1__= Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Content-Disposition: inline As done in Linux by f598282f51 ("PCI: Fix the NIU MSI-X problem in a better way") and its broken predecessor, make sure we don't access the MSI-X table without having enabled MSI-X first, using the mask-all flag instead to prevent interrupts from occurring. Signed-off-by: Jan Beulich --- v3: temporarily enable MSI-X in setup_msi_irq() if not already enabled --- a/xen/arch/x86/msi.c +++ b/xen/arch/x86/msi.c @@ -142,6 +142,17 @@ static bool_t memory_decoded(const struc PCI_COMMAND_MEMORY); } =20 +static bool_t msix_memory_decoded(const struct pci_dev *dev, unsigned int = pos) +{ + u16 control =3D pci_conf_read16(dev->seg, dev->bus, PCI_SLOT(dev->devf= n), + PCI_FUNC(dev->devfn), msix_control_reg(p= os)); + + if ( !(control & PCI_MSIX_FLAGS_ENABLE) ) + return 0; + + return memory_decoded(dev); +} + /* * MSI message composition */ @@ -219,7 +230,8 @@ static bool_t read_msi_msg(struct msi_de void __iomem *base; base =3D entry->mask_base; =20 - if ( unlikely(!memory_decoded(entry->dev)) ) + if ( unlikely(!msix_memory_decoded(entry->dev, + entry->msi_attrib.pos)) ) return 0; msg->address_lo =3D readl(base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET)= ; msg->address_hi =3D readl(base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET)= ; @@ -285,7 +297,8 @@ static int write_msi_msg(struct msi_desc void __iomem *base; base =3D entry->mask_base; =20 - if ( unlikely(!memory_decoded(entry->dev)) ) + if ( unlikely(!msix_memory_decoded(entry->dev, + entry->msi_attrib.pos)) ) return -ENXIO; writel(msg->address_lo, base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); @@ -379,7 +392,7 @@ static bool_t msi_set_mask_bit(struct ir { struct msi_desc *entry =3D desc->msi_desc; struct pci_dev *pdev; - u16 seg; + u16 seg, control; u8 bus, slot, func; =20 ASSERT(spin_is_locked(&desc->lock)); @@ -401,35 +414,38 @@ static bool_t msi_set_mask_bit(struct ir } break; case PCI_CAP_ID_MSIX: + control =3D pci_conf_read16(seg, bus, slot, func, + msix_control_reg(entry->msi_attrib.pos))= ; + if ( unlikely(!(control & PCI_MSIX_FLAGS_ENABLE)) ) + pci_conf_write16(seg, bus, slot, func, + msix_control_reg(entry->msi_attrib.pos), + control | (PCI_MSIX_FLAGS_ENABLE | + PCI_MSIX_FLAGS_MASKALL)); if ( likely(memory_decoded(pdev)) ) { writel(flag, entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFF= SET); readl(entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); - break; + if ( likely(control & PCI_MSIX_FLAGS_ENABLE) ) + break; + flag =3D 1; } - if ( flag ) + else if ( flag && !(control & PCI_MSIX_FLAGS_MASKALL) ) { - u16 control; domid_t domid =3D pdev->domain->domain_id; =20 - control =3D pci_conf_read16(seg, bus, slot, func, - msix_control_reg(entry->msi_attrib.p= os)); - if ( control & PCI_MSIX_FLAGS_MASKALL ) - break; - pci_conf_write16(seg, bus, slot, func, - msix_control_reg(entry->msi_attrib.pos), - control | PCI_MSIX_FLAGS_MASKALL); + control |=3D PCI_MSIX_FLAGS_MASKALL; if ( pdev->msix->warned !=3D domid ) { pdev->msix->warned =3D domid; printk(XENLOG_G_WARNING - "cannot mask IRQ %d: masked MSI-X on Dom%d's = %04x:%02x:%02x.%u\n", + "cannot mask IRQ %d: masking MSI-X on Dom%d's = %04x:%02x:%02x.%u\n", desc->irq, domid, pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); } - break; } - /* fall through */ + pci_conf_write16(seg, bus, slot, func, + msix_control_reg(entry->msi_attrib.pos), = control); + return flag; default: return 0; } @@ -454,7 +470,8 @@ static int msi_get_mask_bit(const struct entry->msi.mpos) >> entry->msi_attrib.entry_nr) & 1; case PCI_CAP_ID_MSIX: - if ( unlikely(!memory_decoded(entry->dev)) ) + if ( unlikely(!msix_memory_decoded(entry->dev, + entry->msi_attrib.pos)) ) break; return readl(entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET)= & 1; } @@ -543,9 +560,31 @@ static struct msi_desc *alloc_msi_entry( =20 int setup_msi_irq(struct irq_desc *desc, struct msi_desc *msidesc) { - return __setup_msi_irq(desc, msidesc, - msi_maskable_irq(msidesc) ? &pci_msi_maskable - : &pci_msi_nonmaskabl= e); + const struct pci_dev *pdev =3D msidesc->dev; + unsigned int cpos =3D msix_control_reg(msidesc->msi_attrib.pos); + u16 control =3D ~0; + int rc; + + if ( msidesc->msi_attrib.type =3D=3D PCI_CAP_ID_MSIX ) + { + control =3D pci_conf_read16(pdev->seg, pdev->bus, PCI_SLOT(pdev->d= evfn), + PCI_FUNC(pdev->devfn), cpos); + if ( !(control & PCI_MSIX_FLAGS_ENABLE) ) + pci_conf_write16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn), + PCI_FUNC(pdev->devfn), cpos, + control | (PCI_MSIX_FLAGS_ENABLE | + PCI_MSIX_FLAGS_MASKALL)); + } + + rc =3D __setup_msi_irq(desc, msidesc, + msi_maskable_irq(msidesc) ? &pci_msi_maskable + : &pci_msi_nonmaskable)= ; + + if ( !(control & PCI_MSIX_FLAGS_ENABLE) ) + pci_conf_write16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn), + PCI_FUNC(pdev->devfn), cpos, control); + + return rc; } =20 int __setup_msi_irq(struct irq_desc *desc, struct msi_desc *msidesc, @@ -785,16 +824,32 @@ static int msix_capability_init(struct p =20 pos =3D pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSIX); control =3D pci_conf_read16(seg, bus, slot, func, msix_control_reg(pos= )); - msix_set_enable(dev, 0);/* Ensure msix is disabled as I set it up */ + /* + * Ensure MSI-X interrupts are masked during setup. Some devices = require + * MSI-X to be enabled before we can touch the MSI-X registers. We = need + * to mask all the vectors to prevent interrupts coming in before = they're + * fully set up. + */ + pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos), + control | (PCI_MSIX_FLAGS_ENABLE | + PCI_MSIX_FLAGS_MASKALL)); =20 if ( unlikely(!memory_decoded(dev)) ) + { + pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos), + control & ~PCI_MSIX_FLAGS_ENABLE); return -ENXIO; + } =20 if ( desc ) { entry =3D alloc_msi_entry(1); if ( !entry ) + { + pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos), + control & ~PCI_MSIX_FLAGS_ENABLE); return -ENOMEM; + } ASSERT(msi); } =20 @@ -825,6 +880,8 @@ static int msix_capability_init(struct p { if ( !msi || !msi->table_base ) { + pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos), + control & ~PCI_MSIX_FLAGS_ENABLE); xfree(entry); return -ENXIO; } @@ -867,6 +924,8 @@ static int msix_capability_init(struct p =20 if ( idx < 0 ) { + pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos), + control & ~PCI_MSIX_FLAGS_ENABLE); xfree(entry); return idx; } @@ -922,8 +981,7 @@ static int msix_capability_init(struct p ++msix->used_entries; =20 /* Restore MSI-X enabled bits */ - pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos), - control & ~PCI_MSIX_FLAGS_MASKALL); + pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos), = control); =20 return 0; } @@ -1072,7 +1130,10 @@ static void __pci_disable_msix(struct ms =20 pos =3D pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSIX); control =3D pci_conf_read16(seg, bus, slot, func, msix_control_reg(pos= )); - msix_set_enable(dev, 0); + if ( unlikely(!(control & PCI_MSIX_FLAGS_ENABLE)) ) + pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos), + control | (PCI_MSIX_FLAGS_ENABLE | + PCI_MSIX_FLAGS_MASKALL)); =20 BUG_ON(list_empty(&dev->msi_list)); =20 @@ -1198,6 +1259,8 @@ int pci_restore_msi_state(struct pci_dev list_for_each_entry_safe( entry, tmp, &pdev->msi_list, list ) { unsigned int i =3D 0, nr =3D 1; + u16 control =3D 0; + u8 slot =3D PCI_SLOT(pdev->devfn), func =3D PCI_FUNC(pdev->devfn);= =20 irq =3D entry->irq; desc =3D &irq_desc[irq]; @@ -1224,10 +1287,18 @@ int pci_restore_msi_state(struct pci_dev } else if ( entry->msi_attrib.type =3D=3D PCI_CAP_ID_MSIX ) { - msix_set_enable(pdev, 0); + control =3D pci_conf_read16(pdev->seg, pdev->bus, slot, func, + msix_control_reg(entry->msi_attrib.p= os)); + pci_conf_write16(pdev->seg, pdev->bus, slot, func, + msix_control_reg(entry->msi_attrib.pos), + control | (PCI_MSIX_FLAGS_ENABLE | + PCI_MSIX_FLAGS_MASKALL)); if ( unlikely(!memory_decoded(pdev)) ) { spin_unlock_irqrestore(&desc->lock, flags); + pci_conf_write16(pdev->seg, pdev->bus, slot, func, + msix_control_reg(entry->msi_attrib.pos), + control & ~PCI_MSIX_FLAGS_ENABLE); return -ENXIO; } } @@ -1256,11 +1327,9 @@ int pci_restore_msi_state(struct pci_dev if ( entry->msi_attrib.type =3D=3D PCI_CAP_ID_MSI ) { unsigned int cpos =3D msi_control_reg(entry->msi_attrib.pos); - u16 control =3D pci_conf_read16(pdev->seg, pdev->bus, - PCI_SLOT(pdev->devfn), - PCI_FUNC(pdev->devfn), cpos); =20 - control &=3D ~PCI_MSI_FLAGS_QSIZE; + control =3D pci_conf_read16(pdev->seg, pdev->bus, slot, func, = cpos) & + ~PCI_MSI_FLAGS_QSIZE; multi_msi_enable(control, entry->msi.nvec); pci_conf_write16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), cpos, control); @@ -1268,7 +1337,9 @@ int pci_restore_msi_state(struct pci_dev msi_set_enable(pdev, 1); } else if ( entry->msi_attrib.type =3D=3D PCI_CAP_ID_MSIX ) - msix_set_enable(pdev, 1); + pci_conf_write16(pdev->seg, pdev->bus, slot, func, + msix_control_reg(entry->msi_attrib.pos), + control | PCI_MSIX_FLAGS_ENABLE); } =20 return 0; --=__PartCAFEE300.1__= Content-Type: text/plain; name="x86-MSI-X-enable.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="x86-MSI-X-enable.patch" x86/MSI-X: access MSI-X table only after having enabled MSI-X=0A=0AAs done = in Linux by f598282f51 ("PCI: Fix the NIU MSI-X problem in a=0Abetter = way") and its broken predecessor, make sure we don't access the=0AMSI-X = table without having enabled MSI-X first, using the mask-all flag=0Ainstead= to prevent interrupts from occurring.=0A=0ASigned-off-by: Jan Beulich = =0A---=0Av3: temporarily enable MSI-X in setup_msi_irq()= if not already enabled=0A=0A--- a/xen/arch/x86/msi.c=0A+++ b/xen/arch/x86/= msi.c=0A@@ -142,6 +142,17 @@ static bool_t memory_decoded(const struc=0A = PCI_COMMAND_MEMORY);=0A }=0A =0A+static bool_t msix_memory_deco= ded(const struct pci_dev *dev, unsigned int pos)=0A+{=0A+ u16 control = =3D pci_conf_read16(dev->seg, dev->bus, PCI_SLOT(dev->devfn),=0A+ = PCI_FUNC(dev->devfn), msix_control_reg(pos));=0A+= =0A+ if ( !(control & PCI_MSIX_FLAGS_ENABLE) )=0A+ return = 0;=0A+=0A+ return memory_decoded(dev);=0A+}=0A+=0A /*=0A * MSI message = composition=0A */=0A@@ -219,7 +230,8 @@ static bool_t read_msi_msg(struct = msi_de=0A void __iomem *base;=0A base =3D entry->mask_base;= =0A =0A- if ( unlikely(!memory_decoded(entry->dev)) )=0A+ if = ( unlikely(!msix_memory_decoded(entry->dev,=0A+ = entry->msi_attrib.pos)) )=0A return 0;=0A = msg->address_lo =3D readl(base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);=0A = msg->address_hi =3D readl(base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);= =0A@@ -285,7 +297,8 @@ static int write_msi_msg(struct msi_desc=0A = void __iomem *base;=0A base =3D entry->mask_base;=0A =0A- = if ( unlikely(!memory_decoded(entry->dev)) )=0A+ if ( unlikely(!msix= _memory_decoded(entry->dev,=0A+ = entry->msi_attrib.pos)) )=0A return -ENXIO;=0A = writel(msg->address_lo,=0A base + PCI_MSIX_ENTRY_LOWER_ADDR_= OFFSET);=0A@@ -379,7 +392,7 @@ static bool_t msi_set_mask_bit(struct ir=0A = {=0A struct msi_desc *entry =3D desc->msi_desc;=0A struct pci_dev = *pdev;=0A- u16 seg;=0A+ u16 seg, control;=0A u8 bus, slot, = func;=0A =0A ASSERT(spin_is_locked(&desc->lock));=0A@@ -401,35 +414,38 = @@ static bool_t msi_set_mask_bit(struct ir=0A }=0A = break;=0A case PCI_CAP_ID_MSIX:=0A+ control =3D pci_conf_read16(= seg, bus, slot, func,=0A+ msix_control_reg= (entry->msi_attrib.pos));=0A+ if ( unlikely(!(control & PCI_MSIX_FLA= GS_ENABLE)) )=0A+ pci_conf_write16(seg, bus, slot, func,=0A+ = msix_control_reg(entry->msi_attrib.pos),=0A+ = control | (PCI_MSIX_FLAGS_ENABLE |=0A+ = PCI_MSIX_FLAGS_MASKALL));=0A if ( = likely(memory_decoded(pdev)) )=0A {=0A writel(flag, = entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);=0A = readl(entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);=0A- = break;=0A+ if ( likely(control & PCI_MSIX_FLAGS_ENABLE) )=0A+ = break;=0A+ flag =3D 1;=0A }=0A- if = ( flag )=0A+ else if ( flag && !(control & PCI_MSIX_FLAGS_MASKALL) = )=0A {=0A- u16 control;=0A domid_t domid = =3D pdev->domain->domain_id;=0A =0A- control =3D pci_conf_read16= (seg, bus, slot, func,=0A- msix_contro= l_reg(entry->msi_attrib.pos));=0A- if ( control & PCI_MSIX_FLAGS= _MASKALL )=0A- break;=0A- pci_conf_write16(seg, = bus, slot, func,=0A- msix_control_reg(entry->ms= i_attrib.pos),=0A- control | PCI_MSIX_FLAGS_MAS= KALL);=0A+ control |=3D PCI_MSIX_FLAGS_MASKALL;=0A = if ( pdev->msix->warned !=3D domid )=0A {=0A = pdev->msix->warned =3D domid;=0A printk(XENLOG_G_WARNING=0A= - "cannot mask IRQ %d: masked MSI-X on Dom%d's = %04x:%02x:%02x.%u\n",=0A+ "cannot mask IRQ %d: = masking MSI-X on Dom%d's %04x:%02x:%02x.%u\n",=0A = desc->irq, domid, pdev->seg, pdev->bus,=0A = PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));=0A }=0A- = break;=0A }=0A- /* fall through */=0A+ pci_conf_w= rite16(seg, bus, slot, func,=0A+ msix_control_reg(e= ntry->msi_attrib.pos), control);=0A+ return flag;=0A default:=0A= return 0;=0A }=0A@@ -454,7 +470,8 @@ static int msi_get_mask_b= it(const struct=0A entry->msi.mpos) >>=0A = entry->msi_attrib.entry_nr) & 1;=0A case PCI_CAP_ID_MSIX= :=0A- if ( unlikely(!memory_decoded(entry->dev)) )=0A+ if ( = unlikely(!msix_memory_decoded(entry->dev,=0A+ = entry->msi_attrib.pos)) )=0A break;=0A = return readl(entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET) & 1;=0A = }=0A@@ -543,9 +560,31 @@ static struct msi_desc *alloc_msi_entry(=0A = =0A int setup_msi_irq(struct irq_desc *desc, struct msi_desc *msidesc)=0A = {=0A- return __setup_msi_irq(desc, msidesc,=0A- = msi_maskable_irq(msidesc) ? &pci_msi_maskable=0A- = : &pci_msi_nonmaskable);=0A+ const struct = pci_dev *pdev =3D msidesc->dev;=0A+ unsigned int cpos =3D msix_control_r= eg(msidesc->msi_attrib.pos);=0A+ u16 control =3D ~0;=0A+ int = rc;=0A+=0A+ if ( msidesc->msi_attrib.type =3D=3D PCI_CAP_ID_MSIX )=0A+ = {=0A+ control =3D pci_conf_read16(pdev->seg, pdev->bus, PCI_SLOT(p= dev->devfn),=0A+ PCI_FUNC(pdev->devfn), = cpos);=0A+ if ( !(control & PCI_MSIX_FLAGS_ENABLE) )=0A+ = pci_conf_write16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),=0A+ = PCI_FUNC(pdev->devfn), cpos,=0A+ = control | (PCI_MSIX_FLAGS_ENABLE |=0A+ = PCI_MSIX_FLAGS_MASKALL));=0A+ }=0A+=0A+ rc =3D __setup_msi_ir= q(desc, msidesc,=0A+ msi_maskable_irq(msidesc) ? = &pci_msi_maskable=0A+ : = &pci_msi_nonmaskable);=0A+=0A+ if ( !(control & PCI_MSIX_FLAGS_ENABLE) = )=0A+ pci_conf_write16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),= =0A+ PCI_FUNC(pdev->devfn), cpos, control);=0A+=0A+= return rc;=0A }=0A =0A int __setup_msi_irq(struct irq_desc *desc, = struct msi_desc *msidesc,=0A@@ -785,16 +824,32 @@ static int msix_capabilit= y_init(struct p=0A =0A pos =3D pci_find_cap_offset(seg, bus, slot, = func, PCI_CAP_ID_MSIX);=0A control =3D pci_conf_read16(seg, bus, slot, = func, msix_control_reg(pos));=0A- msix_set_enable(dev, 0);/* Ensure = msix is disabled as I set it up */=0A+ /*=0A+ * Ensure MSI-X = interrupts are masked during setup. Some devices require=0A+ * MSI-X = to be enabled before we can touch the MSI-X registers. We need=0A+ * = to mask all the vectors to prevent interrupts coming in before they're=0A+ = * fully set up.=0A+ */=0A+ pci_conf_write16(seg, bus, slot, = func, msix_control_reg(pos),=0A+ control | (PCI_MSIX_FL= AGS_ENABLE |=0A+ PCI_MSIX_FLAGS_MASKALL));= =0A =0A if ( unlikely(!memory_decoded(dev)) )=0A+ {=0A+ = pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),=0A+ = control & ~PCI_MSIX_FLAGS_ENABLE);=0A return = -ENXIO;=0A+ }=0A =0A if ( desc )=0A {=0A entry =3D = alloc_msi_entry(1);=0A if ( !entry )=0A+ {=0A+ = pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),=0A+ = control & ~PCI_MSIX_FLAGS_ENABLE);=0A = return -ENOMEM;=0A+ }=0A ASSERT(msi);=0A }=0A =0A@@ = -825,6 +880,8 @@ static int msix_capability_init(struct p=0A {=0A = if ( !msi || !msi->table_base )=0A {=0A+ pci_conf_wri= te16(seg, bus, slot, func, msix_control_reg(pos),=0A+ = control & ~PCI_MSIX_FLAGS_ENABLE);=0A xfree(entry);=0A = return -ENXIO;=0A }=0A@@ -867,6 +924,8 @@ static int = msix_capability_init(struct p=0A =0A if ( idx < 0 )=0A = {=0A+ pci_conf_write16(seg, bus, slot, func, msix_control_reg(po= s),=0A+ control & ~PCI_MSIX_FLAGS_ENABLE);=0A = xfree(entry);=0A return idx;=0A }=0A@@ = -922,8 +981,7 @@ static int msix_capability_init(struct p=0A ++msix->us= ed_entries;=0A =0A /* Restore MSI-X enabled bits */=0A- pci_conf_wri= te16(seg, bus, slot, func, msix_control_reg(pos),=0A- = control & ~PCI_MSIX_FLAGS_MASKALL);=0A+ pci_conf_write16(seg, bus, = slot, func, msix_control_reg(pos), control);=0A =0A return 0;=0A = }=0A@@ -1072,7 +1130,10 @@ static void __pci_disable_msix(struct ms=0A =0A = pos =3D pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSIX);=0A = control =3D pci_conf_read16(seg, bus, slot, func, msix_control_reg(pos)= );=0A- msix_set_enable(dev, 0);=0A+ if ( unlikely(!(control & = PCI_MSIX_FLAGS_ENABLE)) )=0A+ pci_conf_write16(seg, bus, slot, = func, msix_control_reg(pos),=0A+ control | = (PCI_MSIX_FLAGS_ENABLE |=0A+ PCI_MSIX_FL= AGS_MASKALL));=0A =0A BUG_ON(list_empty(&dev->msi_list));=0A =0A@@ = -1198,6 +1259,8 @@ int pci_restore_msi_state(struct pci_dev=0A = list_for_each_entry_safe( entry, tmp, &pdev->msi_list, list )=0A {=0A = unsigned int i =3D 0, nr =3D 1;=0A+ u16 control =3D 0;=0A+ = u8 slot =3D PCI_SLOT(pdev->devfn), func =3D PCI_FUNC(pdev->devfn);=0A = =0A irq =3D entry->irq;=0A desc =3D &irq_desc[irq];=0A@@ = -1224,10 +1287,18 @@ int pci_restore_msi_state(struct pci_dev=0A = }=0A else if ( entry->msi_attrib.type =3D=3D PCI_CAP_ID_MSIX )=0A = {=0A- msix_set_enable(pdev, 0);=0A+ control = =3D pci_conf_read16(pdev->seg, pdev->bus, slot, func,=0A+ = msix_control_reg(entry->msi_attrib.pos));=0A+ = pci_conf_write16(pdev->seg, pdev->bus, slot, func,=0A+ = msix_control_reg(entry->msi_attrib.pos),=0A+ = control | (PCI_MSIX_FLAGS_ENABLE |=0A+ = PCI_MSIX_FLAGS_MASKALL));=0A if ( unlikely(!memory_d= ecoded(pdev)) )=0A {=0A spin_unlock_irqrestore(= &desc->lock, flags);=0A+ pci_conf_write16(pdev->seg, = pdev->bus, slot, func,=0A+ msix_control_reg= (entry->msi_attrib.pos),=0A+ control & = ~PCI_MSIX_FLAGS_ENABLE);=0A return -ENXIO;=0A = }=0A }=0A@@ -1256,11 +1327,9 @@ int pci_restore_msi_state(struct = pci_dev=0A if ( entry->msi_attrib.type =3D=3D PCI_CAP_ID_MSI )=0A = {=0A unsigned int cpos =3D msi_control_reg(entry->msi_at= trib.pos);=0A- u16 control =3D pci_conf_read16(pdev->seg, = pdev->bus,=0A- PCI_SLOT(pdev->devf= n),=0A- PCI_FUNC(pdev->devfn), = cpos);=0A =0A- control &=3D ~PCI_MSI_FLAGS_QSIZE;=0A+ = control =3D pci_conf_read16(pdev->seg, pdev->bus, slot, func, cpos) &=0A+ = ~PCI_MSI_FLAGS_QSIZE;=0A multi_msi_enable(= control, entry->msi.nvec);=0A pci_conf_write16(pdev->seg, = pdev->bus, PCI_SLOT(pdev->devfn),=0A = PCI_FUNC(pdev->devfn), cpos, control);=0A@@ -1268,7 +1337,9 @@ int = pci_restore_msi_state(struct pci_dev=0A msi_set_enable(pdev, = 1);=0A }=0A else if ( entry->msi_attrib.type =3D=3D = PCI_CAP_ID_MSIX )=0A- msix_set_enable(pdev, 1);=0A+ = pci_conf_write16(pdev->seg, pdev->bus, slot, func,=0A+ = msix_control_reg(entry->msi_attrib.pos),=0A+ = control | PCI_MSIX_FLAGS_ENABLE);=0A }=0A =0A return 0;=0A --=__PartCAFEE300.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 --=__PartCAFEE300.1__=--