[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] VT-d: fix MSI source-id of interrupt remapping
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1245397555 -3600 # Node ID 703ced548925c50cd88598b5e1e8cd774f91b33b # Parent 2f1fa2215e60a325aabc14e22187761c13987f20 VT-d: fix MSI source-id of interrupt remapping This patch fixes an issue of MSI source-id. Currently MSI source-ids are all set device bdf. It's incorrect for PCI (not PCIe) devices. The patch set correct requester-ids of MSI to source-id. And also, wrap functions to clean ioapic source-id. Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx> --- xen/drivers/passthrough/vtd/intremap.c | 95 ++++++++++++++++++++++++++++++--- 1 files changed, 88 insertions(+), 7 deletions(-) diff -r 2f1fa2215e60 -r 703ced548925 xen/drivers/passthrough/vtd/intremap.c --- a/xen/drivers/passthrough/vtd/intremap.c Fri Jun 19 08:45:20 2009 +0100 +++ b/xen/drivers/passthrough/vtd/intremap.c Fri Jun 19 08:45:55 2009 +0100 @@ -39,6 +39,27 @@ #define nr_ioapic_registers(i) nr_ioapic_registers[i] #endif +/* + * source validation type (SVT) + */ +#define SVT_NO_VERIFY 0x0 /* no verification is required */ +#define SVT_VERIFY_SID_SQ 0x1 /* verify using SID and SQ fiels */ +#define SVT_VERIFY_BUS 0x2 /* verify bus of request-id */ + +/* + * source-id qualifier (SQ) + */ +#define SQ_ALL_16 0x0 /* verify all 16 bits of request-id */ +#define SQ_13_IGNORE_1 0x1 /* verify most significant 13 bits, ignore + * the third least significant bit + */ +#define SQ_13_IGNORE_2 0x2 /* verify most significant 13 bits, ignore + * the second and third least significant bits + */ +#define SQ_13_IGNORE_3 0x3 /* verify most significant 13 bits, ignore + * the least three significant bits + */ + /* apic_pin_2_ir_idx[apicid][pin] = interrupt remapping table index */ static unsigned int **apic_pin_2_ir_idx; @@ -84,6 +105,20 @@ u16 apicid_to_bdf(int apic_id) dprintk(XENLOG_ERR VTDPREFIX, "Didn't find the bdf for the apic_id!\n"); return 0; +} + +static void set_ire_sid(struct iremap_entry *ire, + unsigned int svt, unsigned int sq, unsigned int sid) +{ + ire->hi.svt = svt; + ire->hi.sq = sq; + ire->hi.sid = sid; +} + +static void set_ioapic_source_id(int apic_id, struct iremap_entry *ire) +{ + set_ire_sid(ire, SVT_VERIFY_SID_SQ, SQ_ALL_16, + apicid_to_bdf(apic_id)); } static int remap_entry_to_ioapic_rte( @@ -191,10 +226,8 @@ static int ioapic_rte_to_remap_entry(str new_ire.lo.res_1 = 0; new_ire.lo.vector = new_rte.vector; new_ire.lo.res_2 = 0; - new_ire.hi.sid = apicid_to_bdf(IO_APIC_ID(apic)); - - new_ire.hi.sq = 0; /* comparing all 16-bit of SID */ - new_ire.hi.svt = 1; /* requestor ID verification SID/SQ */ + + set_ioapic_source_id(IO_APIC_ID(apic), &new_ire); new_ire.hi.res_1 = 0; new_ire.lo.p = 1; /* finally, set present bit */ @@ -345,6 +378,56 @@ void io_apic_write_remap_rte( } #if defined(__i386__) || defined(__x86_64__) + +static void set_msi_source_id(struct pci_dev *pdev, struct iremap_entry *ire) +{ + int type; + u8 bus, devfn, secbus; + int ret; + + if ( !pdev || !ire ) + return; + + bus = pdev->bus; + devfn = pdev->devfn; + type = pdev_type(bus, devfn); + switch ( type ) + { + case DEV_TYPE_PCIe_BRIDGE: + case DEV_TYPE_PCIe2PCI_BRIDGE: + case DEV_TYPE_LEGACY_PCI_BRIDGE: + break; + + case DEV_TYPE_PCIe_ENDPOINT: + set_ire_sid(ire, SVT_VERIFY_SID_SQ, SQ_ALL_16, PCI_BDF2(bus, devfn)); + break; + + case DEV_TYPE_PCI: + ret = find_upstream_bridge(&bus, &devfn, &secbus); + if ( ret == 0 ) /* integrated PCI device */ + { + set_ire_sid(ire, SVT_VERIFY_SID_SQ, SQ_ALL_16, + PCI_BDF2(bus, devfn)); + } + else if ( ret == 1 ) /* find upstream bridge */ + { + if ( pdev_type(bus, devfn) == DEV_TYPE_PCIe2PCI_BRIDGE ) + set_ire_sid(ire, SVT_VERIFY_BUS, SQ_ALL_16, + (bus << 8) | pdev->bus); + else if ( pdev_type(bus, devfn) == DEV_TYPE_LEGACY_PCI_BRIDGE ) + set_ire_sid(ire, SVT_VERIFY_BUS, SQ_ALL_16, + PCI_BDF2(bus, devfn)); + } + break; + + default: + gdprintk(XENLOG_WARNING VTDPREFIX, + "set_msi_source_id: unknown type : bdf = %x:%x.%x\n", + bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); + break; + } +} + static int remap_entry_to_msi_msg( struct iommu *iommu, struct msi_msg *msg) { @@ -456,9 +539,7 @@ static int msi_msg_to_remap_entry( new_ire.lo.dst = ((msg->address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff) << 8; - new_ire.hi.sid = (pdev->bus << 8) | pdev->devfn; - new_ire.hi.sq = 0; - new_ire.hi.svt = 1; + set_msi_source_id(pdev, &new_ire); new_ire.hi.res_1 = 0; new_ire.lo.p = 1; /* finally, set present bit */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |