[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v6 7/8] AMD/IOMMU: allocate one device table per PCI segment
> -----Original Message----- > From: Xen-devel <xen-devel-bounces@xxxxxxxxxxxxxxxxxxxx> On Behalf Of Jan > Beulich > Sent: 19 September 2019 14:25 > To: xen-devel@xxxxxxxxxxxxxxxxxxxx > Cc: Andrew Cooper <Andrew.Cooper3@xxxxxxxxxx>; Suravee Suthikulpanit > <suravee.suthikulpanit@xxxxxxx> > Subject: [Xen-devel] [PATCH v6 7/8] AMD/IOMMU: allocate one device table per > PCI segment > > Having a single device table for all segments can't possibly be right. The copy of the spec. I have says (on page 253: Fixed-Length IVHD Blocks) that IVHD entries must have a segment group of 0, so can't the code just require iommu->seg == 0? Paul > (Even worse, the symbol wasn't static despite being used in just one > source file.) Attach the device tables to their respective IVRS mapping > ones. > > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> > --- > v6: New. > > --- > xen/drivers/passthrough/amd/iommu_init.c | 81 > ++++++++++++++++--------------- > 1 file changed, 43 insertions(+), 38 deletions(-) > > --- a/xen/drivers/passthrough/amd/iommu_init.c > +++ b/xen/drivers/passthrough/amd/iommu_init.c > @@ -39,7 +39,6 @@ unsigned int __read_mostly ivrs_bdf_entr > u8 __read_mostly ivhd_type; > static struct radix_tree_root ivrs_maps; > LIST_HEAD_READ_MOSTLY(amd_iommu_head); > -struct table_struct device_table; > bool_t iommuv2_enabled; > > static bool iommu_has_ht_flag(struct amd_iommu *iommu, u8 mask) > @@ -989,6 +988,12 @@ static void disable_iommu(struct amd_iom > spin_unlock_irqrestore(&iommu->lock, flags); > } > > +static unsigned int __init dt_alloc_size(void) > +{ > + return PAGE_SIZE << get_order_from_bytes(ivrs_bdf_entries * > + IOMMU_DEV_TABLE_ENTRY_SIZE); > +} > + > static void __init deallocate_buffer(void *buf, uint32_t sz) > { > int order = 0; > @@ -999,12 +1004,6 @@ static void __init deallocate_buffer(voi > } > } > > -static void __init deallocate_device_table(struct table_struct *table) > -{ > - deallocate_buffer(table->buffer, table->alloc_size); > - table->buffer = NULL; > -} > - > static void __init deallocate_ring_buffer(struct ring_buffer *ring_buf) > { > deallocate_buffer(ring_buf->buffer, ring_buf->alloc_size); > @@ -1068,8 +1067,29 @@ static void * __init allocate_ppr_log(st > IOMMU_PPR_LOG_DEFAULT_ENTRIES, "PPR Log"); > } > > +/* > + * Within ivrs_mappings[] we allocate an extra array element to store > + * - segment number, > + * - device table. > + */ > +#define IVRS_MAPPINGS_SEG(m) (m)[ivrs_bdf_entries].dte_requestor_id > +#define IVRS_MAPPINGS_DEVTAB(m) (m)[ivrs_bdf_entries].intremap_table > + > +static void __init free_ivrs_mapping(void *ptr) > +{ > + const struct ivrs_mappings *ivrs_mappings = ptr; > + > + if ( IVRS_MAPPINGS_DEVTAB(ivrs_mappings) ) > + deallocate_buffer(IVRS_MAPPINGS_DEVTAB(ivrs_mappings), > + dt_alloc_size()); > + > + xfree(ptr); > +} > + > static int __init amd_iommu_init_one(struct amd_iommu *iommu, bool intr) > { > + const struct ivrs_mappings *ivrs_mappings; > + > if ( allocate_cmd_buffer(iommu) == NULL ) > goto error_out; > > @@ -1082,13 +1102,15 @@ static int __init amd_iommu_init_one(str > if ( intr && !set_iommu_interrupt_handler(iommu) ) > goto error_out; > > - /* To make sure that device_table.buffer has been successfully allocated > */ > - if ( device_table.buffer == NULL ) > + /* Make sure that the device table has been successfully allocated. */ > + ivrs_mappings = get_ivrs_mappings(iommu->seg); > + if ( !IVRS_MAPPINGS_DEVTAB(ivrs_mappings) ) > goto error_out; > > - iommu->dev_table.alloc_size = device_table.alloc_size; > - iommu->dev_table.entries = device_table.entries; > - iommu->dev_table.buffer = device_table.buffer; > + iommu->dev_table.alloc_size = dt_alloc_size(); > + iommu->dev_table.entries = iommu->dev_table.alloc_size / > + IOMMU_DEV_TABLE_ENTRY_SIZE; > + iommu->dev_table.buffer = IVRS_MAPPINGS_DEVTAB(ivrs_mappings); > > enable_iommu(iommu); > printk("AMD-Vi: IOMMU %d Enabled.\n", nr_amd_iommus ); > @@ -1135,11 +1157,8 @@ static void __init amd_iommu_init_cleanu > xfree(iommu); > } > > - /* free device table */ > - deallocate_device_table(&device_table); > - > - /* free ivrs_mappings[] */ > - radix_tree_destroy(&ivrs_maps, xfree); > + /* Free ivrs_mappings[] and their device tables. */ > + radix_tree_destroy(&ivrs_maps, free_ivrs_mapping); > > iommu_enabled = 0; > iommu_hwdom_passthrough = false; > @@ -1147,12 +1166,6 @@ static void __init amd_iommu_init_cleanu > iommuv2_enabled = 0; > } > > -/* > - * We allocate an extra array element to store the segment number > - * (and in the future perhaps other global information). > - */ > -#define IVRS_MAPPINGS_SEG(m) m[ivrs_bdf_entries].dte_requestor_id > - > struct ivrs_mappings *get_ivrs_mappings(u16 seg) > { > return radix_tree_lookup(&ivrs_maps, seg); > @@ -1235,24 +1248,18 @@ static int __init alloc_ivrs_mappings(u1 > static int __init amd_iommu_setup_device_table( > u16 seg, struct ivrs_mappings *ivrs_mappings) > { > + struct amd_iommu_dte *dt = IVRS_MAPPINGS_DEVTAB(ivrs_mappings); > unsigned int bdf; > > BUG_ON( (ivrs_bdf_entries == 0) ); > > - if ( !device_table.buffer ) > + if ( !dt ) > { > /* allocate 'device table' on a 4K boundary */ > - device_table.alloc_size = PAGE_SIZE << > - get_order_from_bytes( > - PAGE_ALIGN(ivrs_bdf_entries * > - IOMMU_DEV_TABLE_ENTRY_SIZE)); > - device_table.entries = device_table.alloc_size / > - IOMMU_DEV_TABLE_ENTRY_SIZE; > - > - device_table.buffer = allocate_buffer(device_table.alloc_size, > - "Device Table"); > + dt = IVRS_MAPPINGS_DEVTAB(ivrs_mappings) = > + allocate_buffer(dt_alloc_size(), "Device Table"); > } > - if ( !device_table.buffer ) > + if ( !dt ) > return -ENOMEM; > > /* Add device table entries */ > @@ -1260,12 +1267,10 @@ static int __init amd_iommu_setup_device > { > if ( ivrs_mappings[bdf].valid ) > { > - void *dte; > const struct pci_dev *pdev = NULL; > > /* add device table entry */ > - dte = device_table.buffer + (bdf * IOMMU_DEV_TABLE_ENTRY_SIZE); > - iommu_dte_add_device_entry(dte, &ivrs_mappings[bdf]); > + iommu_dte_add_device_entry(&dt[bdf], &ivrs_mappings[bdf]); > > if ( iommu_intremap && > ivrs_mappings[bdf].dte_requestor_id == bdf && > @@ -1308,7 +1313,7 @@ static int __init amd_iommu_setup_device > } > > amd_iommu_set_intremap_table( > - dte, ivrs_mappings[bdf].intremap_table, > + &dt[bdf], ivrs_mappings[bdf].intremap_table, > ivrs_mappings[bdf].iommu, iommu_intremap); > } > } > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@xxxxxxxxxxxxxxxxxxxx > https://lists.xenproject.org/mailman/listinfo/xen-devel _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |