Commit 098accf2 authored by Robin Murphy's avatar Robin Murphy Committed by Joerg Roedel

iommu: Use C99 flexible array in fwspec

Although the 1-element array was a typical pre-C99 way to implement
variable-length structures, and indeed is a fundamental construct in the
APIs of certain other popular platforms, there's no good reason for it
here (and in particular the sizeof() trick is far too "clever" for its
own good). We can just as easily implement iommu_fwspec's preallocation
behaviour using a standard flexible array member, so let's make it look
the way most readers would expect.
Signed-off-by: default avatarRobin Murphy <robin.murphy@arm.com>
Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent f8788d86
...@@ -2405,7 +2405,8 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode, ...@@ -2405,7 +2405,8 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
if (fwspec) if (fwspec)
return ops == fwspec->ops ? 0 : -EINVAL; return ops == fwspec->ops ? 0 : -EINVAL;
fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL); /* Preallocate for the overwhelmingly common case of 1 ID */
fwspec = kzalloc(struct_size(fwspec, ids, 1), GFP_KERNEL);
if (!fwspec) if (!fwspec)
return -ENOMEM; return -ENOMEM;
...@@ -2432,15 +2433,15 @@ EXPORT_SYMBOL_GPL(iommu_fwspec_free); ...@@ -2432,15 +2433,15 @@ EXPORT_SYMBOL_GPL(iommu_fwspec_free);
int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids) int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
{ {
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
size_t size; int i, new_num;
int i;
if (!fwspec) if (!fwspec)
return -EINVAL; return -EINVAL;
size = offsetof(struct iommu_fwspec, ids[fwspec->num_ids + num_ids]); new_num = fwspec->num_ids + num_ids;
if (size > sizeof(*fwspec)) { if (new_num > 1) {
fwspec = krealloc(fwspec, size, GFP_KERNEL); fwspec = krealloc(fwspec, struct_size(fwspec, ids, new_num),
GFP_KERNEL);
if (!fwspec) if (!fwspec)
return -ENOMEM; return -ENOMEM;
...@@ -2450,7 +2451,7 @@ int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids) ...@@ -2450,7 +2451,7 @@ int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
for (i = 0; i < num_ids; i++) for (i = 0; i < num_ids; i++)
fwspec->ids[fwspec->num_ids + i] = ids[i]; fwspec->ids[fwspec->num_ids + i] = ids[i];
fwspec->num_ids += num_ids; fwspec->num_ids = new_num;
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(iommu_fwspec_add_ids); EXPORT_SYMBOL_GPL(iommu_fwspec_add_ids);
......
...@@ -592,7 +592,7 @@ struct iommu_fwspec { ...@@ -592,7 +592,7 @@ struct iommu_fwspec {
u32 flags; u32 flags;
u32 num_pasid_bits; u32 num_pasid_bits;
unsigned int num_ids; unsigned int num_ids;
u32 ids[1]; u32 ids[];
}; };
/* ATS is supported */ /* ATS is supported */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment