mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 04:31:50 +00:00
powerpc/pseries/iommu: Fix the VFIO_IOMMU_SPAPR_TCE_GET_INFO ioctl output
The ioctl VFIO_IOMMU_SPAPR_TCE_GET_INFO is not reporting the actuals on the platform as not all the details are correctly collected during the platform probe/scan into the iommu_table_group. Collect the information during the device setup time as the DMA window property is already looked up on parent nodes anyway. Signed-off-by: Shivaprasad G Bhat <sbhat@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://msgid.link/171923271138.1397.7908302630061814623.stgit@linux.ibm.com
This commit is contained in:
parent
b09c031d94
commit
6af67f2ddf
@ -865,13 +865,6 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
|
||||
be32_to_cpu(prop.tce_shift), NULL,
|
||||
&iommu_table_lpar_multi_ops);
|
||||
|
||||
/* Only for normal boot with default window. Doesn't matter even
|
||||
* if we set these with DDW which is 64bit during kdump, since
|
||||
* these will not be used during kdump.
|
||||
*/
|
||||
ppci->table_group->tce32_start = be64_to_cpu(prop.dma_base);
|
||||
ppci->table_group->tce32_size = 1 << be32_to_cpu(prop.window_shift);
|
||||
|
||||
if (!iommu_init_table(tbl, ppci->phb->node, 0, 0))
|
||||
panic("Failed to initialize iommu table");
|
||||
|
||||
@ -1658,6 +1651,71 @@ out_unlock:
|
||||
return direct_mapping;
|
||||
}
|
||||
|
||||
static __u64 query_page_size_to_mask(u32 query_page_size)
|
||||
{
|
||||
const long shift[] = {
|
||||
(SZ_4K), (SZ_64K), (SZ_16M),
|
||||
(SZ_32M), (SZ_64M), (SZ_128M),
|
||||
(SZ_256M), (SZ_16G), (SZ_2M)
|
||||
};
|
||||
int i, ret = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(shift); i++) {
|
||||
if (query_page_size & (1 << i))
|
||||
ret |= shift[i];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void spapr_tce_init_table_group(struct pci_dev *pdev,
|
||||
struct device_node *pdn,
|
||||
struct dynamic_dma_window_prop prop)
|
||||
{
|
||||
struct iommu_table_group *table_group = PCI_DN(pdn)->table_group;
|
||||
u32 ddw_avail[DDW_APPLICABLE_SIZE];
|
||||
|
||||
struct ddw_query_response query;
|
||||
int ret;
|
||||
|
||||
/* Only for normal boot with default window. Doesn't matter during
|
||||
* kdump, since these will not be used during kdump.
|
||||
*/
|
||||
if (is_kdump_kernel())
|
||||
return;
|
||||
|
||||
if (table_group->max_dynamic_windows_supported != 0)
|
||||
return; /* already initialized */
|
||||
|
||||
table_group->tce32_start = be64_to_cpu(prop.dma_base);
|
||||
table_group->tce32_size = 1 << be32_to_cpu(prop.window_shift);
|
||||
|
||||
if (!of_find_property(pdn, "ibm,dma-window", NULL))
|
||||
dev_err(&pdev->dev, "default dma window missing!\n");
|
||||
|
||||
ret = of_property_read_u32_array(pdn, "ibm,ddw-applicable",
|
||||
&ddw_avail[0], DDW_APPLICABLE_SIZE);
|
||||
if (ret) {
|
||||
table_group->max_dynamic_windows_supported = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
ret = query_ddw(pdev, ddw_avail, &query, pdn);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "%s: query_ddw failed\n", __func__);
|
||||
table_group->max_dynamic_windows_supported = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (query.windows_available == 0)
|
||||
table_group->max_dynamic_windows_supported = 1;
|
||||
else
|
||||
table_group->max_dynamic_windows_supported = IOMMU_TABLE_GROUP_MAX_TABLES;
|
||||
|
||||
table_group->max_levels = 1;
|
||||
table_group->pgsizes |= query_page_size_to_mask(query.page_size);
|
||||
}
|
||||
|
||||
static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
|
||||
{
|
||||
struct device_node *pdn, *dn;
|
||||
@ -1697,13 +1755,6 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
|
||||
be32_to_cpu(prop.tce_shift), NULL,
|
||||
&iommu_table_lpar_multi_ops);
|
||||
|
||||
/* Only for normal boot with default window. Doesn't matter even
|
||||
* if we set these with DDW which is 64bit during kdump, since
|
||||
* these will not be used during kdump.
|
||||
*/
|
||||
pci->table_group->tce32_start = be64_to_cpu(prop.dma_base);
|
||||
pci->table_group->tce32_size = 1 << be32_to_cpu(prop.window_shift);
|
||||
|
||||
iommu_init_table(tbl, pci->phb->node, 0, 0);
|
||||
iommu_register_group(pci->table_group,
|
||||
pci_domain_nr(pci->phb->bus), 0);
|
||||
@ -1712,6 +1763,8 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
|
||||
pr_debug(" found DMA window, table: %p\n", pci->table_group);
|
||||
}
|
||||
|
||||
spapr_tce_init_table_group(dev, pdn, prop);
|
||||
|
||||
set_iommu_table_base(&dev->dev, pci->table_group->tables[0]);
|
||||
iommu_add_device(pci->table_group, &dev->dev);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user