ia64/xen-unstable
changeset 18947:2dffa6ceb0af
Support S3 for MSI interrupt
From: "Jiang, Yunhong" <yunhong.jiang@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
From: "Jiang, Yunhong" <yunhong.jiang@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Fri Dec 19 14:56:36 2008 +0000 (2008-12-19) |
parents | 738513b106fa |
children | 4d5203f95498 |
files | xen/arch/x86/msi.c xen/arch/x86/physdev.c xen/include/asm-x86/msi.h xen/include/public/physdev.h |
line diff
1.1 --- a/xen/arch/x86/msi.c Fri Dec 19 14:52:32 2008 +0000 1.2 +++ b/xen/arch/x86/msi.c Fri Dec 19 14:56:36 2008 +0000 1.3 @@ -741,3 +741,43 @@ void pci_cleanup_msi(struct pci_dev *pde 1.4 msi_free_vectors(pdev); 1.5 } 1.6 1.7 +int pci_restore_msi_state(struct pci_dev *pdev) 1.8 +{ 1.9 + unsigned long flags; 1.10 + int vector; 1.11 + struct msi_desc *entry, *tmp; 1.12 + irq_desc_t *desc; 1.13 + 1.14 + ASSERT(spin_is_locked(&pcidevs_lock)); 1.15 + 1.16 + if (!pdev) 1.17 + return -EINVAL; 1.18 + 1.19 + list_for_each_entry_safe( entry, tmp, &pdev->msi_list, list ) 1.20 + { 1.21 + vector = entry->vector; 1.22 + desc = &irq_desc[vector]; 1.23 + 1.24 + spin_lock_irqsave(&desc->lock, flags); 1.25 + 1.26 + ASSERT(desc->msi_desc == entry); 1.27 + 1.28 + if (desc->msi_desc != entry) 1.29 + { 1.30 + dprintk(XENLOG_ERR, "Restore MSI for dev %x:%x not set before?\n", 1.31 + pdev->bus, pdev->devfn); 1.32 + spin_unlock_irqrestore(&desc->lock, flags); 1.33 + return -EINVAL; 1.34 + } 1.35 + 1.36 + msi_set_enable(pdev, 0); 1.37 + write_msi_msg(entry, &entry->msg); 1.38 + 1.39 + msi_set_enable(pdev, 1); 1.40 + msi_set_mask_bit(vector, entry->msi_attrib.masked); 1.41 + spin_unlock_irqrestore(&desc->lock, flags); 1.42 + } 1.43 + 1.44 + return 0; 1.45 +} 1.46 +
2.1 --- a/xen/arch/x86/physdev.c Fri Dec 19 14:52:32 2008 +0000 2.2 +++ b/xen/arch/x86/physdev.c Fri Dec 19 14:56:36 2008 +0000 2.3 @@ -415,6 +415,24 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H 2.4 break; 2.5 } 2.6 2.7 + case PHYSDEVOP_restore_msi: { 2.8 + struct physdev_restore_msi restore_msi; 2.9 + struct pci_dev *pdev; 2.10 + 2.11 + ret = -EPERM; 2.12 + if ( !IS_PRIV(v->domain) ) 2.13 + break; 2.14 + 2.15 + ret = -EFAULT; 2.16 + if ( copy_from_guest(&restore_msi, arg, 1) != 0 ) 2.17 + break; 2.18 + 2.19 + spin_lock(&pcidevs_lock); 2.20 + pdev = pci_get_pdev(restore_msi.bus, restore_msi.devfn); 2.21 + ret = pdev ? pci_restore_msi_state(pdev) : -ENODEV; 2.22 + spin_unlock(&pcidevs_lock); 2.23 + break; 2.24 + } 2.25 default: 2.26 ret = -ENOSYS; 2.27 break;
3.1 --- a/xen/include/asm-x86/msi.h Fri Dec 19 14:52:32 2008 +0000 3.2 +++ b/xen/include/asm-x86/msi.h Fri Dec 19 14:56:36 2008 +0000 3.3 @@ -79,6 +79,7 @@ extern void pci_cleanup_msi(struct pci_d 3.4 extern int setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc); 3.5 extern void teardown_msi_vector(int vector); 3.6 extern int msi_free_vector(struct msi_desc *entry); 3.7 +extern int pci_restore_msi_state(struct pci_dev *pdev); 3.8 3.9 struct msi_desc { 3.10 struct {
4.1 --- a/xen/include/public/physdev.h Fri Dec 19 14:52:32 2008 +0000 4.2 +++ b/xen/include/public/physdev.h Fri Dec 19 14:56:36 2008 +0000 4.3 @@ -183,6 +183,15 @@ struct physdev_manage_pci { 4.4 typedef struct physdev_manage_pci physdev_manage_pci_t; 4.5 DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_t); 4.6 4.7 +#define PHYSDEVOP_restore_msi 19 4.8 +struct physdev_restore_msi { 4.9 + /* IN */ 4.10 + uint8_t bus; 4.11 + uint8_t devfn; 4.12 +}; 4.13 +typedef struct physdev_restore_msi physdev_restore_msi_t; 4.14 +DEFINE_XEN_GUEST_HANDLE(physdev_restore_msi_t); 4.15 + 4.16 /* 4.17 * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op() 4.18 * hypercall since 0x00030202.