mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 16:24:13 +08:00
iommu/amd: Introduce per PCI segment device table size
With multiple pci segment support, number of BDF supported by each segment may differ. Hence introduce per segment device table size which depends on last_bdf. This will replace global "device_table_size" variable. Co-developed-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Signed-off-by: Vasant Hegde <vasant.hegde@amd.com> Link: https://lore.kernel.org/r/20220706113825.25582-12-vasant.hegde@amd.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
307959008d
commit
b5c852907e
@ -555,6 +555,9 @@ struct amd_iommu_pci_seg {
|
||||
/* Largest PCI device id we expect translation requests for */
|
||||
u16 last_bdf;
|
||||
|
||||
/* Size of the device table */
|
||||
u32 dev_table_size;
|
||||
|
||||
/*
|
||||
* device table virtual address
|
||||
*
|
||||
|
@ -416,6 +416,7 @@ static void iommu_set_cwwb_range(struct amd_iommu *iommu)
|
||||
static void iommu_set_device_table(struct amd_iommu *iommu)
|
||||
{
|
||||
u64 entry;
|
||||
u32 dev_table_size = iommu->pci_seg->dev_table_size;
|
||||
|
||||
BUG_ON(iommu->mmio_base == NULL);
|
||||
|
||||
@ -652,7 +653,7 @@ static int __init find_last_devid_acpi(struct acpi_table_header *table, u16 pci_
|
||||
static inline int __init alloc_dev_table(struct amd_iommu_pci_seg *pci_seg)
|
||||
{
|
||||
pci_seg->dev_table = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO | GFP_DMA32,
|
||||
get_order(dev_table_size));
|
||||
get_order(pci_seg->dev_table_size));
|
||||
if (!pci_seg->dev_table)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -662,7 +663,7 @@ static inline int __init alloc_dev_table(struct amd_iommu_pci_seg *pci_seg)
|
||||
static inline void free_dev_table(struct amd_iommu_pci_seg *pci_seg)
|
||||
{
|
||||
free_pages((unsigned long)pci_seg->dev_table,
|
||||
get_order(dev_table_size));
|
||||
get_order(pci_seg->dev_table_size));
|
||||
pci_seg->dev_table = NULL;
|
||||
}
|
||||
|
||||
@ -1035,7 +1036,7 @@ static bool __copy_device_table(struct amd_iommu *iommu)
|
||||
entry = (((u64) hi) << 32) + lo;
|
||||
|
||||
old_devtb_size = ((entry & ~PAGE_MASK) + 1) << 12;
|
||||
if (old_devtb_size != dev_table_size) {
|
||||
if (old_devtb_size != pci_seg->dev_table_size) {
|
||||
pr_err("The device table size of IOMMU:%d is not expected!\n",
|
||||
iommu->index);
|
||||
return false;
|
||||
@ -1054,15 +1055,15 @@ static bool __copy_device_table(struct amd_iommu *iommu)
|
||||
}
|
||||
old_devtb = (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT) && is_kdump_kernel())
|
||||
? (__force void *)ioremap_encrypted(old_devtb_phys,
|
||||
dev_table_size)
|
||||
: memremap(old_devtb_phys, dev_table_size, MEMREMAP_WB);
|
||||
pci_seg->dev_table_size)
|
||||
: memremap(old_devtb_phys, pci_seg->dev_table_size, MEMREMAP_WB);
|
||||
|
||||
if (!old_devtb)
|
||||
return false;
|
||||
|
||||
gfp_flag = GFP_KERNEL | __GFP_ZERO | GFP_DMA32;
|
||||
pci_seg->old_dev_tbl_cpy = (void *)__get_free_pages(gfp_flag,
|
||||
get_order(dev_table_size));
|
||||
get_order(pci_seg->dev_table_size));
|
||||
if (pci_seg->old_dev_tbl_cpy == NULL) {
|
||||
pr_err("Failed to allocate memory for copying old device table!\n");
|
||||
memunmap(old_devtb);
|
||||
@ -1581,6 +1582,7 @@ static struct amd_iommu_pci_seg *__init alloc_pci_segment(u16 id,
|
||||
|
||||
pci_seg->last_bdf = last_bdf;
|
||||
DUMP_printk("PCI segment : 0x%0x, last bdf : 0x%04x\n", id, last_bdf);
|
||||
pci_seg->dev_table_size = tbl_size(DEV_TABLE_ENTRY_SIZE);
|
||||
|
||||
pci_seg->id = id;
|
||||
init_llist_head(&pci_seg->dev_data_list);
|
||||
@ -2678,7 +2680,7 @@ static void early_enable_iommus(void)
|
||||
for_each_pci_segment(pci_seg) {
|
||||
if (pci_seg->old_dev_tbl_cpy != NULL) {
|
||||
free_pages((unsigned long)pci_seg->old_dev_tbl_cpy,
|
||||
get_order(dev_table_size));
|
||||
get_order(pci_seg->dev_table_size));
|
||||
pci_seg->old_dev_tbl_cpy = NULL;
|
||||
}
|
||||
}
|
||||
@ -2692,7 +2694,7 @@ static void early_enable_iommus(void)
|
||||
|
||||
for_each_pci_segment(pci_seg) {
|
||||
free_pages((unsigned long)pci_seg->dev_table,
|
||||
get_order(dev_table_size));
|
||||
get_order(pci_seg->dev_table_size));
|
||||
pci_seg->dev_table = pci_seg->old_dev_tbl_cpy;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user