[PATCH v3 01/17] ACPI: GTDT: Account for GTDTv3 size when walking the platform timer descriptors

Hanjun Guo guohanjun at huawei.com
Mon May 25 19:02:49 PDT 2026


On 2026/5/23 22:02, Marc Zyngier wrote:
> Since ARMv8.1, the architecture has grown an EL2-private virtual
> timer. This has been described in ACPI since ACPI v6.3 and revision
> 3 of the GTDT table.
> 
> An aditional structure was added in ACPICA, though in a rather
> bizarre way, and merged in v5.1 as 8f5a14d053100 ("ACPICA: ACPI 6.3:
> add GTDT Revision 3 support").
> 
> Finally plug the table parsing in GTDT, and correct the parsing of
> the platform timer subtables to account for the expanded size of
> the base table. This also comes with some extra sanitisation of
> the table, in the unlikely case someone got it wrong...
> 
> Suggested-by: Sudeep Holla <sudeep.holla at kernel.org>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>   drivers/acpi/arm64/gtdt.c | 22 ++++++++++++++++++++--
>   1 file changed, 20 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
> index ffc867bac2d60..950d5efdf85ea 100644
> --- a/drivers/acpi/arm64/gtdt.c
> +++ b/drivers/acpi/arm64/gtdt.c
> @@ -34,14 +34,25 @@ struct acpi_gtdt_descriptor {
>   	void *platform_timer;
>   };
>   
> +struct gtdt_v3 {
> +	struct acpi_table_gtdt	gtdt_v2;
> +	struct acpi_gtdt_el2	el2_vtimer;
> +};
> +
>   static struct acpi_gtdt_descriptor acpi_gtdt_desc __initdata;
>   
>   static __init bool platform_timer_valid(void *platform_timer)
>   {
>   	struct acpi_gtdt_header *gh = platform_timer;
> +	void *platform_timer_begin;
>   
> -	return (platform_timer >= (void *)(acpi_gtdt_desc.gtdt + 1) &&
> -		platform_timer < acpi_gtdt_desc.gtdt_end &&
> +	if (acpi_gtdt_desc.gtdt->header.revision >= 3)
> +		platform_timer_begin = container_of(acpi_gtdt_desc.gtdt, struct gtdt_v3, gtdt_v2) + 1;
> +	else
> +		platform_timer_begin = acpi_gtdt_desc.gtdt + 1;
> +
> +	return (platform_timer >= platform_timer_begin &&
> +		platform_timer + sizeof(*gh) <= acpi_gtdt_desc.gtdt_end &&
>   		gh->length != 0 &&
>   		platform_timer + gh->length <= acpi_gtdt_desc.gtdt_end);
>   }
> @@ -166,6 +177,13 @@ int __init acpi_gtdt_init(struct acpi_table_header *table,
>   	u32 cnt = 0;
>   
>   	gtdt = container_of(table, struct acpi_table_gtdt, header);
> +
> +	if ((gtdt->header.revision >= 3 && gtdt->header.length < sizeof(struct gtdt_v3)) ||
> +	    (gtdt->header.revision == 2 && gtdt->header.length < sizeof(*gtdt))) {
> +		pr_err(FW_BUG "GTDT with invalid size %d\n", gtdt->header.length);
> +		return -EINVAL;
> +	}
> +
>   	acpi_gtdt_desc.gtdt = gtdt;
>   	acpi_gtdt_desc.gtdt_end = (void *)table + table->length;
>   	acpi_gtdt_desc.platform_timer = NULL;

Reviewed-by: Hanjun Guo <guohanjun at huawei.com>

Thanks
Hanjun



More information about the linux-arm-kernel mailing list