aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/hvm/vmsi.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2013-08-26 12:40:44 +0200
committerJan Beulich <jbeulich@suse.com>2013-08-26 12:40:44 +0200
commit8a7769b4453168e23e8935a85e9a875ef5117253 (patch)
tree88ea2b6e95fd935bf00850e74f1b7f4b977c73c7 /xen/arch/x86/hvm/vmsi.c
parent30e9a840b822ea57319abc0d136945a150fb915b (diff)
downloadxen-8a7769b4453168e23e8935a85e9a875ef5117253.tar.gz
xen-8a7769b4453168e23e8935a85e9a875ef5117253.tar.bz2
xen-8a7769b4453168e23e8935a85e9a875ef5117253.zip
Revert "interrupts: allow guest to set/clear MSI-X mask bit"
This reverts commit 54a46bce768033b1c36e25eace15f7abde972389. It's not fully cooked yet.
Diffstat (limited to 'xen/arch/x86/hvm/vmsi.c')
-rw-r--r--xen/arch/x86/hvm/vmsi.c61
1 files changed, 14 insertions, 47 deletions
diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c
index e36c1f0d94..0d5ef1b91e 100644
--- a/xen/arch/x86/hvm/vmsi.c
+++ b/xen/arch/x86/hvm/vmsi.c
@@ -169,7 +169,6 @@ struct msixtbl_entry
uint32_t msi_ad[3]; /* Shadow of address low, high and data */
} gentries[MAX_MSIX_ACC_ENTRIES];
struct rcu_head rcu;
- const struct pirq *pirq;
};
static DEFINE_RCU_READ_LOCK(msixtbl_rcu_lock);
@@ -255,8 +254,6 @@ static int msixtbl_write(struct vcpu *v, unsigned long address,
void *virt;
unsigned int nr_entry, index;
int r = X86EMUL_UNHANDLEABLE;
- unsigned long flags, orig;
- struct irq_desc *desc;
if ( len != 4 || (address & 3) )
return r;
@@ -286,49 +283,22 @@ static int msixtbl_write(struct vcpu *v, unsigned long address,
if ( !virt )
goto out;
- desc = pirq_spin_lock_irq_desc(entry->pirq, &flags);
- if ( !desc )
- goto out;
-
- if ( !desc->msi_desc )
- goto unlock;
-
+ /* Do not allow the mask bit to be changed. */
+#if 0 /* XXX
+ * As the mask bit is the only defined bit in the word, and as the
+ * host MSI-X code doesn't preserve the other bits anyway, doing
+ * this is pointless. So for now just discard the write (also
+ * saving us from having to determine the matching irq_desc).
+ */
+ spin_lock_irqsave(&desc->lock, flags);
orig = readl(virt);
-
- /*
- * Do not allow guest to modify MSI-X control bit if it is masked
- * by Xen. We'll only handle the case where Xen thinks that
- * bit is unmasked, but hardware has silently masked the bit
- * (in case of SR-IOV VF reset, etc). On the other hand, if Xen
- * thinks that the bit is masked, but it's really not,
- * we log a warning.
- */
- if ( desc->msi_desc->msi_attrib.masked )
- {
- if ( !(orig & PCI_MSIX_VECTOR_BITMASK) )
- printk(XENLOG_WARNING "MSI-X control bit is unmasked when"
- " it is expected to be masked [%04x:%02x:%02x.%01x]\n",
- entry->pdev->seg, entry->pdev->bus,
- PCI_SLOT(entry->pdev->devfn),
- PCI_FUNC(entry->pdev->devfn));
-
- goto unlock;
- }
-
- /*
- * The mask bit is the only defined bit in the word. But we
- * ought to preserve the reserved bits. Clearing the reserved
- * bits can result in undefined behaviour (see PCI Local Bus
- * Specification revision 2.3).
- */
- val &= PCI_MSIX_VECTOR_BITMASK;
- val |= (orig & ~PCI_MSIX_VECTOR_BITMASK);
+ val &= ~PCI_MSIX_VECTOR_BITMASK;
+ val |= orig & PCI_MSIX_VECTOR_BITMASK;
writel(val, virt);
-
-unlock:
spin_unlock_irqrestore(&desc->lock, flags);
- r = X86EMUL_OKAY;
+#endif
+ r = X86EMUL_OKAY;
out:
rcu_read_unlock(&msixtbl_rcu_lock);
return r;
@@ -358,8 +328,7 @@ const struct hvm_mmio_handler msixtbl_mmio_handler = {
static void add_msixtbl_entry(struct domain *d,
struct pci_dev *pdev,
uint64_t gtable,
- struct msixtbl_entry *entry,
- const struct pirq *pirq)
+ struct msixtbl_entry *entry)
{
u32 len;
@@ -373,7 +342,6 @@ static void add_msixtbl_entry(struct domain *d,
entry->table_len = len;
entry->pdev = pdev;
entry->gtable = (unsigned long) gtable;
- entry->pirq = pirq;
list_add_rcu(&entry->list, &d->arch.hvm_domain.msixtbl_list);
}
@@ -436,10 +404,9 @@ int msixtbl_pt_register(struct domain *d, struct pirq *pirq, uint64_t gtable)
entry = new_entry;
new_entry = NULL;
- add_msixtbl_entry(d, pdev, gtable, entry, pirq);
+ add_msixtbl_entry(d, pdev, gtable, entry);
found:
- ASSERT(entry->pirq == pirq);
atomic_inc(&entry->refcnt);
spin_unlock(&d->arch.hvm_domain.msixtbl_list_lock);
r = 0;