Re: [PATCH] platform/x86/intel/vsec: allocate res with intel_vsec_dev

From: David Box

Date: Fri May 01 2026 - 17:24:19 EST


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 <rosenp@xxxxxxxxx>

Tested-by: David E. Box <david.e.box@xxxxxxxxxxxxxxx>
Reviewed-by: David E. Box <david.e.box@xxxxxxxxxxxxxxx>

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
>