platform/x86: hp-bioscfg: Support allocating large number of BIOS vars

On HP systems with a large number of BIOS attribute instances, the
kzalloc_objs() allocation in hp_alloc_ordered_list_data() and
hp_alloc_string_data() can fail when physical memory is fragmented,
leaving the driver unable to register those attributes.

The same failure mode was already fixed for enumeration_data in
hp_alloc_enumeration_data() by commit 916727cfdb ("platform/x86:
hp-bioscfg: Support allocations of larger data"), reported on HP
Z2 Tower G9 and Z4 G5 Workstation systems:

  https://bugs.debian.org/1127612

order-list-attributes.c and string-attributes.c use the identical
allocation pattern and are still affected. Apply the same fix: fall back
to kvzalloc_objs()/kvfree() instead of kzalloc_objs()/kfree(), and
return -EINVAL early when the instance count is zero.

Link: https://bugs.debian.org/1127612
Signed-off-by: Artem Maksimov <okuroshioffc@gmail.com>
Link: https://patch.msgid.link/20260925194454.6850-1-okuroshioffc@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
This commit is contained in:
Artem Maksimov 2026-09-25 22:44:54 +03:00 committed by Ilpo Järvinen
parent 9523698252
commit ae53bb89b9
No known key found for this signature in database
GPG Key ID: 59AC4F6153E5CE31
2 changed files with 16 additions and 6 deletions

View File

@ -98,8 +98,13 @@ int hp_alloc_ordered_list_data(void)
{
bioscfg_drv.ordered_list_instances_count =
hp_get_instance_count(HP_WMI_BIOS_ORDERED_LIST_GUID);
bioscfg_drv.ordered_list_data = kzalloc_objs(*bioscfg_drv.ordered_list_data,
bioscfg_drv.ordered_list_instances_count);
if (!bioscfg_drv.ordered_list_instances_count)
return -EINVAL;
bioscfg_drv.ordered_list_data =
kvzalloc_objs(*bioscfg_drv.ordered_list_data,
bioscfg_drv.ordered_list_instances_count);
if (!bioscfg_drv.ordered_list_data) {
bioscfg_drv.ordered_list_instances_count = 0;
return -ENOMEM;
@ -390,6 +395,6 @@ void hp_exit_ordered_list_attributes(void)
}
bioscfg_drv.ordered_list_instances_count = 0;
kfree(bioscfg_drv.ordered_list_data);
kvfree(bioscfg_drv.ordered_list_data);
bioscfg_drv.ordered_list_data = NULL;
}

View File

@ -101,8 +101,13 @@ static const struct attribute_group string_attr_group = {
int hp_alloc_string_data(void)
{
bioscfg_drv.string_instances_count = hp_get_instance_count(HP_WMI_BIOS_STRING_GUID);
bioscfg_drv.string_data = kzalloc_objs(*bioscfg_drv.string_data,
bioscfg_drv.string_instances_count);
if (!bioscfg_drv.string_instances_count)
return -EINVAL;
bioscfg_drv.string_data =
kvzalloc_objs(*bioscfg_drv.string_data,
bioscfg_drv.string_instances_count);
if (!bioscfg_drv.string_data) {
bioscfg_drv.string_instances_count = 0;
return -ENOMEM;
@ -342,6 +347,6 @@ void hp_exit_string_attributes(void)
}
bioscfg_drv.string_instances_count = 0;
kfree(bioscfg_drv.string_data);
kvfree(bioscfg_drv.string_data);
bioscfg_drv.string_data = NULL;
}