On Thu, Apr 30, 2026 at 03:43:07PM -0700, Rosen Penev wrote:
> Use a flexible array member to combine allocations. Avoids having to
> free separately.
> 
> Add __counted_by for extra runtime analysis.
> 
> Move counting variable assignment to after allocations as is already
> done by kzalloc_flex for GCC 15 and above.
> 
> Signed-off-by: Rosen Penev <[email protected]>

Tested-by: David E. Box <[email protected]>
Reviewed-by: David E. Box <[email protected]>

Thanks

> ---
>  drivers/platform/x86/intel/vsec.c      | 14 ++++----------
>  drivers/platform/x86/intel/vsec_tpmi.c | 13 ++++---------
>  include/linux/intel_vsec.h             |  6 +++---
>  3 files changed, 11 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/platform/x86/intel/vsec.c 
> b/drivers/platform/x86/intel/vsec.c
> index 7d5dbc1c1d05..9ef0f043bbee 100644
> --- a/drivers/platform/x86/intel/vsec.c
> +++ b/drivers/platform/x86/intel/vsec.c
> @@ -112,7 +112,6 @@ static void intel_vsec_dev_release(struct device *dev)
>       ida_free(intel_vsec_dev->ida, intel_vsec_dev->auxdev.id);
>  
>       kfree(intel_vsec_dev->acpi_disc);
> -     kfree(intel_vsec_dev->resource);
>       kfree(intel_vsec_dev);
>  }
>  
> @@ -225,7 +224,6 @@ int intel_vsec_add_aux(struct device *parent,
>       ret = xa_alloc(&auxdev_array, &intel_vsec_dev->id, intel_vsec_dev,
>                      PMT_XA_LIMIT, GFP_KERNEL);
>       if (ret < 0) {
> -             kfree(intel_vsec_dev->resource);
>               kfree(intel_vsec_dev);
>               return ret;
>       }
> @@ -233,7 +231,6 @@ int intel_vsec_add_aux(struct device *parent,
>       id = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL);
>       if (id < 0) {
>               xa_erase(&auxdev_array, intel_vsec_dev->id);
> -             kfree(intel_vsec_dev->resource);
>               kfree(intel_vsec_dev);
>               return id;
>       }
> @@ -282,7 +279,7 @@ static int intel_vsec_add_dev(struct device *dev, struct 
> intel_vsec_header *head
>                             unsigned long cap_id, u64 base_addr)
>  {
>       struct intel_vsec_device __free(kfree) *intel_vsec_dev = NULL;
> -     struct resource __free(kfree) *res = NULL;
> +     struct resource *res;
>       struct resource *tmp;
>       struct device *parent;
>       unsigned long quirks = info->quirks;
> @@ -306,13 +303,12 @@ static int intel_vsec_add_dev(struct device *dev, 
> struct intel_vsec_header *head
>               return -EINVAL;
>       }
>  
> -     intel_vsec_dev = kzalloc_obj(*intel_vsec_dev);
> +     intel_vsec_dev = kzalloc_flex(*intel_vsec_dev, resource, 
> header->num_entries);
>       if (!intel_vsec_dev)
>               return -ENOMEM;
>  
> -     res = kzalloc_objs(*res, header->num_entries);
> -     if (!res)
> -             return -ENOMEM;
> +     intel_vsec_dev->num_resources = header->num_entries;
> +     res = intel_vsec_dev->resource;
>  
>       if (quirks & VSEC_QUIRK_TABLE_SHIFT)
>               header->offset >>= TABLE_OFFSET_SHIFT;
> @@ -342,8 +338,6 @@ static int intel_vsec_add_dev(struct device *dev, struct 
> intel_vsec_header *head
>       }
>  
>       intel_vsec_dev->dev = dev;
> -     intel_vsec_dev->resource = no_free_ptr(res);
> -     intel_vsec_dev->num_resources = header->num_entries;
>       intel_vsec_dev->quirks = info->quirks;
>       intel_vsec_dev->base_addr = info->base_addr;
>       intel_vsec_dev->priv_data = info->priv_data;
> diff --git a/drivers/platform/x86/intel/vsec_tpmi.c 
> b/drivers/platform/x86/intel/vsec_tpmi.c
> index 79c0cbea2dee..908f3377b05a 100644
> --- a/drivers/platform/x86/intel/vsec_tpmi.c
> +++ b/drivers/platform/x86/intel/vsec_tpmi.c
> @@ -626,15 +626,12 @@ static int tpmi_create_device(struct intel_tpmi_info 
> *tpmi_info,
>       if (!name)
>               return -EOPNOTSUPP;
>  
> -     res = kzalloc_objs(*res, pfs->pfs_header.num_entries);
> -     if (!res)
> +     feature_vsec_dev = kzalloc_flex(*feature_vsec_dev, resource, 
> pfs->pfs_header.num_entries);
> +     if (!feature_vsec_dev)
>               return -ENOMEM;
>  
> -     feature_vsec_dev = kzalloc_obj(*feature_vsec_dev);
> -     if (!feature_vsec_dev) {
> -             kfree(res);
> -             return -ENOMEM;
> -     }
> +     feature_vsec_dev->num_resources = pfs->pfs_header.num_entries;
> +     res = feature_vsec_dev->resource;
>  
>       snprintf(feature_id_name, sizeof(feature_id_name), "tpmi-%s", name);
>  
> @@ -647,8 +644,6 @@ static int tpmi_create_device(struct intel_tpmi_info 
> *tpmi_info,
>       }
>  
>       feature_vsec_dev->dev = vsec_dev->dev;
> -     feature_vsec_dev->resource = res;
> -     feature_vsec_dev->num_resources = pfs->pfs_header.num_entries;
>       feature_vsec_dev->priv_data = &tpmi_info->plat_info;
>       feature_vsec_dev->priv_data_size = sizeof(tpmi_info->plat_info);
>       feature_vsec_dev->ida = &intel_vsec_tpmi_ida;
> diff --git a/include/linux/intel_vsec.h b/include/linux/intel_vsec.h
> index 1fe5665a9d02..07ea563f524e 100644
> --- a/include/linux/intel_vsec.h
> +++ b/include/linux/intel_vsec.h
> @@ -135,8 +135,6 @@ struct intel_vsec_platform_info {
>   * struct intel_vsec_device - Auxbus specific device information
>   * @auxdev:        auxbus device struct for auxbus access
>   * @dev:           struct device associated with the device
> - * @resource:      PCI discovery resources (BAR windows), one per discovery
> - *                 instance. Valid only when @src == INTEL_VSEC_DISC_PCI
>   * @acpi_disc:     ACPI discovery tables, each entry is two QWORDs
>   *                 in little-endian format as defined by the PMT ACPI spec.
>   *                 Valid only when @src == INTEL_VSEC_DISC_ACPI.
> @@ -149,11 +147,12 @@ struct intel_vsec_platform_info {
>   * @quirks:        specified quirks
>   * @base_addr:     base address of entries (if specified)
>   * @cap_id:        the enumerated id of the vsec feature
> + * @resource:      PCI discovery resources (BAR windows), one per discovery
> + *                 instance. Valid only when @src == INTEL_VSEC_DISC_PCI
>   */
>  struct intel_vsec_device {
>       struct auxiliary_device auxdev;
>       struct device *dev;
> -     struct resource *resource;
>       u32 (*acpi_disc)[4];
>       enum intel_vsec_disc_source src;
>       struct ida *ida;
> @@ -164,6 +163,7 @@ struct intel_vsec_device {
>       unsigned long quirks;
>       u64 base_addr;
>       unsigned long cap_id;
> +     struct resource resource[] __counted_by(num_resources);
>  };
>  
>  /**
> -- 
> 2.54.0
> 

Reply via email to