This patch enlarges interrupt remapping table to fix the out-of range
table access when using many multiple-function PCI devices.
Signed-Off-By: Zhai Edwin <edwin.zhai@xxxxxxxxx>
--
best rgds,
edwin
Index: hv/xen/drivers/passthrough/vtd/intremap.c
===================================================================
--- hv.orig/xen/drivers/passthrough/vtd/intremap.c
+++ hv/xen/drivers/passthrough/vtd/intremap.c
@@ -208,7 +208,7 @@ static int ioapic_rte_to_remap_entry(str
{
dprintk(XENLOG_ERR VTDPREFIX,
"%s: intremap index (%d) is larger than"
- " the maximum index (%ld)!\n",
+ " the maximum index (%d)!\n",
__func__, index, IREMAP_ENTRY_NR - 1);
spin_unlock_irqrestore(&ir_ctrl->iremap_lock, flags);
return -EFAULT;
@@ -502,7 +502,7 @@ static int msi_msg_to_remap_entry(
{
dprintk(XENLOG_ERR VTDPREFIX,
"%s: intremap index (%d) is larger than"
- " the maximum index (%ld)!\n",
+ " the maximum index (%d)!\n",
__func__, index, IREMAP_ENTRY_NR - 1);
msi_desc->remap_index = -1;
spin_unlock_irqrestore(&ir_ctrl->iremap_lock, flags);
@@ -617,7 +617,7 @@ int enable_intremap(struct iommu *iommu)
if ( ir_ctrl->iremap_maddr == 0 )
{
drhd = iommu_to_drhd(iommu);
- ir_ctrl->iremap_maddr = alloc_pgtable_maddr(drhd, 1);
+ ir_ctrl->iremap_maddr = alloc_pgtable_maddr(drhd, IREMAP_PAGE_NR );
if ( ir_ctrl->iremap_maddr == 0 )
{
dprintk(XENLOG_WARNING VTDPREFIX,
Index: hv/xen/drivers/passthrough/vtd/iommu.h
===================================================================
--- hv.orig/xen/drivers/passthrough/vtd/iommu.h
+++ hv/xen/drivers/passthrough/vtd/iommu.h
@@ -302,7 +302,14 @@ struct iremap_entry {
}hi;
};
};
-#define IREMAP_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct iremap_entry))
+
+/* Max intr remapping table page order is 8, as max number of IRTEs is 64K */
+#define IREMAP_PAGE_ORDER 8
+#define IREMAP_PAGE_NR ( 1 << IREMAP_PAGE_ORDER )
+
+/* Each entry is 16 byte */
+#define IREMAP_ENTRY_NR ( 1 << ( IREMAP_PAGE_ORDER + 8 ) )
+
#define iremap_present(v) ((v).lo & 1)
#define iremap_fault_disable(v) (((v).lo >> 1) & 1)
@@ -429,9 +436,9 @@ struct qinval_entry {
#define IEC_GLOBAL_INVL 0
#define IEC_INDEX_INVL 1
#define IRTA_REG_EIME_SHIFT 11
-#define IRTA_REG_TABLE_SIZE 7 // 4k page = 256 * 16 byte entries
- // 2^^(IRTA_REG_TABLE_SIZE + 1) = 256
- // IRTA_REG_TABLE_SIZE = 7
+
+/* 2^(IRTA_REG_TABLE_SIZE + 1) = IREMAP_ENTRY_NR */
+#define IRTA_REG_TABLE_SIZE ( IREMAP_PAGE_ORDER + 7 )
#define VTD_PAGE_TABLE_LEVEL_3 3
#define VTD_PAGE_TABLE_LEVEL_4 4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|