From da0ba0ccce54059d6c6b788a75099bfce95126da Mon Sep 17 00:00:00 2001 From: Dongliang Mu Date: Thu, 9 Mar 2023 12:01:07 +0800 Subject: [PATCH 1/9] platform/x86/intel: vsec: Fix a memory leak in intel_vsec_add_aux The first error handling code in intel_vsec_add_aux misses the deallocation of intel_vsec_dev->resource. Fix this by adding kfree(intel_vsec_dev->resource) in the error handling code. Reviewed-by: David E. Box Signed-off-by: Dongliang Mu Link: https://lore.kernel.org/r/20230309040107.534716-4-dzm91@hust.edu.cn Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/intel/vsec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/x86/intel/vsec.c b/drivers/platform/x86/intel/vsec.c index 13decf36c6ded..2311c16cb975d 100644 --- a/drivers/platform/x86/intel/vsec.c +++ b/drivers/platform/x86/intel/vsec.c @@ -154,6 +154,7 @@ int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent, ret = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL); mutex_unlock(&vsec_ida_lock); if (ret < 0) { + kfree(intel_vsec_dev->resource); kfree(intel_vsec_dev); return ret; } From 4d5a2a7d2c97dbd658533eea5f79dab1ad5dc0ee Mon Sep 17 00:00:00 2001 From: Dongliang Mu Date: Thu, 9 Mar 2023 12:01:05 +0800 Subject: [PATCH 2/9] platform/x86/intel: tpmi: Fix double free in tpmi_create_device() The previous commit 6a192c0cbf38 ("platform/x86/intel/tpmi: Fix double free reported by Smatch") incorrectly handle the deallocation of res variable. As shown in the comment, intel_vsec_add_aux handles all the deallocation of res and feature_vsec_dev. Therefore, kfree(res) can still cause double free if intel_vsec_add_aux returns error. Fix this by adjusting the error handling part in tpmi_create_device, following the function intel_vsec_add_dev. Fixes: 6a192c0cbf38 ("platform/x86/intel/tpmi: Fix double free reported by Smatch") Signed-off-by: Dongliang Mu Link: https://lore.kernel.org/r/20230309040107.534716-2-dzm91@hust.edu.cn Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/intel/tpmi.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/platform/x86/intel/tpmi.c b/drivers/platform/x86/intel/tpmi.c index c999732b0f1e5..a8733c43e4abe 100644 --- a/drivers/platform/x86/intel/tpmi.c +++ b/drivers/platform/x86/intel/tpmi.c @@ -203,7 +203,7 @@ static int tpmi_create_device(struct intel_tpmi_info *tpmi_info, struct intel_vsec_device *feature_vsec_dev; struct resource *res, *tmp; const char *name; - int ret, i; + int i; name = intel_tpmi_name(pfs->pfs_header.tpmi_id); if (!name) @@ -215,8 +215,8 @@ static int tpmi_create_device(struct intel_tpmi_info *tpmi_info, feature_vsec_dev = kzalloc(sizeof(*feature_vsec_dev), GFP_KERNEL); if (!feature_vsec_dev) { - ret = -ENOMEM; - goto free_res; + kfree(res); + return -ENOMEM; } snprintf(feature_id_name, sizeof(feature_id_name), "tpmi-%s", name); @@ -242,17 +242,8 @@ static int tpmi_create_device(struct intel_tpmi_info *tpmi_info, * feature_vsec_dev memory is also freed as part of device * delete. */ - ret = intel_vsec_add_aux(vsec_dev->pcidev, &vsec_dev->auxdev.dev, - feature_vsec_dev, feature_id_name); - if (ret) - goto free_res; - - return 0; - -free_res: - kfree(res); - - return ret; + return intel_vsec_add_aux(vsec_dev->pcidev, &vsec_dev->auxdev.dev, + feature_vsec_dev, feature_id_name); } static int tpmi_create_devices(struct intel_tpmi_info *tpmi_info) From 8d13d50b157655247cdb3a69aca7836b58ff8735 Mon Sep 17 00:00:00 2001 From: Dongliang Mu Date: Thu, 9 Mar 2023 12:01:06 +0800 Subject: [PATCH 3/9] platform/x86/intel: tpmi: Revise the comment of intel_vsec_add_aux intel_vsec_add_aux() is resource managed including res and feature_vsec_dev memory. Fix this by revising the comment of intel_vsec_add_aux since res variable will also be freed in the intel_vsec_add_aux. Signed-off-by: Dongliang Mu Link: https://lore.kernel.org/r/20230309040107.534716-3-dzm91@hust.edu.cn Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/intel/tpmi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/intel/tpmi.c b/drivers/platform/x86/intel/tpmi.c index a8733c43e4abe..a5227951decce 100644 --- a/drivers/platform/x86/intel/tpmi.c +++ b/drivers/platform/x86/intel/tpmi.c @@ -239,8 +239,8 @@ static int tpmi_create_device(struct intel_tpmi_info *tpmi_info, /* * intel_vsec_add_aux() is resource managed, no explicit * delete is required on error or on module unload. - * feature_vsec_dev memory is also freed as part of device - * delete. + * feature_vsec_dev and res memory are also freed as part of + * device deletion. */ return intel_vsec_add_aux(vsec_dev->pcidev, &vsec_dev->auxdev.dev, feature_vsec_dev, feature_id_name); From b7c994f8c35e916e27c60803bb21457bc1373500 Mon Sep 17 00:00:00 2001 From: Frank Crawford Date: Sat, 18 Mar 2023 20:14:41 +1100 Subject: [PATCH 4/9] platform/x86 (gigabyte-wmi): Add support for A320M-S2H V2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for A320M-S2H V2. Tested using module force_load option. Signed-off-by: Frank Crawford Acked-by: Thomas Weißschuh Link: https://lore.kernel.org/r/20230318091441.1240921-1-frank@crawford.emu.id.au Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/gigabyte-wmi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/x86/gigabyte-wmi.c b/drivers/platform/x86/gigabyte-wmi.c index 322cfaeda17ba..4dd39ab6ecfa2 100644 --- a/drivers/platform/x86/gigabyte-wmi.c +++ b/drivers/platform/x86/gigabyte-wmi.c @@ -140,6 +140,7 @@ static u8 gigabyte_wmi_detect_sensor_usability(struct wmi_device *wdev) }} static const struct dmi_system_id gigabyte_wmi_known_working_platforms[] = { + DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("A320M-S2H V2-CF"), DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B450M DS3H-CF"), DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B450M DS3H WIFI-CF"), DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B450M S2H V2"), From 583329dcf22e568a328a944f20427ccfc95dce01 Mon Sep 17 00:00:00 2001 From: Mark Pearson Date: Sun, 19 Mar 2023 20:32:18 -0400 Subject: [PATCH 5/9] platform/x86: think-lmi: add missing type attribute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver was missing the mandatory type attribute...oops. Add it in along with logic to determine whether the attribute is an enumeration type or a string by parsing the possible_values attribute. Upstream bug https://bugzilla.kernel.org/show_bug.cgi?id=216460 Fixes: a40cd7ef22fb ("platform/x86: think-lmi: Add WMI interface support on Lenovo platforms") Signed-off-by: Mark Pearson Link: https://lore.kernel.org/r/20230320003221.561750-1-mpearson-lenovo@squebb.ca Reviewed-by: Thomas Weißschuh Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/think-lmi.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index 86b33b74519be..5fa5451c48026 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -947,6 +947,20 @@ static ssize_t possible_values_show(struct kobject *kobj, struct kobj_attribute return sysfs_emit(buf, "%s\n", setting->possible_values); } +static ssize_t type_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj); + + if (setting->possible_values) { + /* Figure out what setting type is as BIOS does not return this */ + if (strchr(setting->possible_values, ',')) + return sysfs_emit(buf, "enumeration\n"); + } + /* Anything else is going to be a string */ + return sysfs_emit(buf, "string\n"); +} + static ssize_t current_value_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) @@ -1036,10 +1050,13 @@ static struct kobj_attribute attr_possible_values = __ATTR_RO(possible_values); static struct kobj_attribute attr_current_val = __ATTR_RW_MODE(current_value, 0600); +static struct kobj_attribute attr_type = __ATTR_RO(type); + static struct attribute *tlmi_attrs[] = { &attr_displ_name.attr, &attr_current_val.attr, &attr_possible_values.attr, + &attr_type.attr, NULL }; From 45e21289bfc6e257885514790a8a8887da822d40 Mon Sep 17 00:00:00 2001 From: Mark Pearson Date: Sun, 19 Mar 2023 20:32:19 -0400 Subject: [PATCH 6/9] platform/x86: think-lmi: use correct possible_values delimiters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit firmware-attributes class requires that possible values are delimited using ';' but the Lenovo firmware uses ',' instead. Parse string and replace where appropriate. Suggested-by: Thomas Weißschuh Fixes: a40cd7ef22fb ("platform/x86: think-lmi: Add WMI interface support on Lenovo platforms") Signed-off-by: Mark Pearson Link: https://lore.kernel.org/r/20230320003221.561750-2-mpearson-lenovo@squebb.ca Reviewed-by: Thomas Weißschuh Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/think-lmi.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index 5fa5451c48026..e190fec260214 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -954,7 +954,7 @@ static ssize_t type_show(struct kobject *kobj, struct kobj_attribute *attr, if (setting->possible_values) { /* Figure out what setting type is as BIOS does not return this */ - if (strchr(setting->possible_values, ',')) + if (strchr(setting->possible_values, ';')) return sysfs_emit(buf, "enumeration\n"); } /* Anything else is going to be a string */ @@ -1441,6 +1441,13 @@ static int tlmi_analyze(void) pr_info("Error retrieving possible values for %d : %s\n", i, setting->display_name); } + /* + * firmware-attributes requires that possible_values are separated by ';' but + * Lenovo FW uses ','. Replace appropriately. + */ + if (setting->possible_values) + strreplace(setting->possible_values, ',', ';'); + kobject_init(&setting->kobj, &tlmi_attr_setting_ktype); tlmi_priv.setting[i] = setting; kfree(item); From cf337f27f3bfc4aeab4954c468239fd6233c7638 Mon Sep 17 00:00:00 2001 From: Mark Pearson Date: Sun, 19 Mar 2023 20:32:20 -0400 Subject: [PATCH 7/9] platform/x86: think-lmi: only display possible_values if available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some attributes don't have any values available. In those cases don't make the possible_values entry visible. Fixes: a40cd7ef22fb ("platform/x86: think-lmi: Add WMI interface support on Lenovo platforms") Signed-off-by: Mark Pearson Link: https://lore.kernel.org/r/20230320003221.561750-3-mpearson-lenovo@squebb.ca Reviewed-by: Thomas Weißschuh Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/think-lmi.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index e190fec260214..3f0641360251f 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -941,9 +941,6 @@ static ssize_t possible_values_show(struct kobject *kobj, struct kobj_attribute { struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj); - if (!tlmi_priv.can_get_bios_selections) - return -EOPNOTSUPP; - return sysfs_emit(buf, "%s\n", setting->possible_values); } @@ -1052,6 +1049,18 @@ static struct kobj_attribute attr_current_val = __ATTR_RW_MODE(current_value, 06 static struct kobj_attribute attr_type = __ATTR_RO(type); +static umode_t attr_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj); + + /* We don't want to display possible_values attributes if not available */ + if ((attr == &attr_possible_values.attr) && (!setting->possible_values)) + return 0; + + return attr->mode; +} + static struct attribute *tlmi_attrs[] = { &attr_displ_name.attr, &attr_current_val.attr, @@ -1061,6 +1070,7 @@ static struct attribute *tlmi_attrs[] = { }; static const struct attribute_group tlmi_attr_group = { + .is_visible = attr_is_visible, .attrs = tlmi_attrs, }; From 8a02d70679fc1c434401863333c8ea7dbf201494 Mon Sep 17 00:00:00 2001 From: Mark Pearson Date: Sun, 19 Mar 2023 20:32:21 -0400 Subject: [PATCH 8/9] platform/x86: think-lmi: Add possible_values for ThinkStation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ThinkStation platforms don't support the API to return possible_values but instead embed it in the settings string. Try and extract this information and set the possible_values attribute appropriately. Fixes: a40cd7ef22fb ("platform/x86: think-lmi: Add WMI interface support on Lenovo platforms") Signed-off-by: Mark Pearson Link: https://lore.kernel.org/r/20230320003221.561750-4-mpearson-lenovo@squebb.ca Reviewed-by: Thomas Weißschuh Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/think-lmi.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index 3f0641360251f..c816646eb6616 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -1450,6 +1450,26 @@ static int tlmi_analyze(void) if (ret || !setting->possible_values) pr_info("Error retrieving possible values for %d : %s\n", i, setting->display_name); + } else { + /* + * Older Thinkstations don't support the bios_selections API. + * Instead they store this as a [Optional:Option1,Option2] section of the + * name string. + * Try and pull that out if it's available. + */ + char *item, *optstart, *optend; + + if (!tlmi_setting(setting->index, &item, LENOVO_BIOS_SETTING_GUID)) { + optstart = strstr(item, "[Optional:"); + if (optstart) { + optstart += strlen("[Optional:"); + optend = strstr(optstart, "]"); + if (optend) + setting->possible_values = + kstrndup(optstart, optend - optstart, + GFP_KERNEL); + } + } } /* * firmware-attributes requires that possible_values are separated by ';' but From acd0acb802b90f88d19ad4337183e44fd0f77c50 Mon Sep 17 00:00:00 2001 From: Liang He Date: Wed, 22 Mar 2023 11:30:57 +0800 Subject: [PATCH 9/9] platform/surface: aggregator: Add missing fwnode_handle_put() In fwnode_for_each_child_node(), we should add fwnode_handle_put() when break out of the iteration fwnode_for_each_child_node() as it will automatically increase and decrease the refcounter. Fixes: fc622b3d36e6 ("platform/surface: Set up Surface Aggregator device registry") Signed-off-by: Liang He Reviewed-by: Maximilian Luz Link: https://lore.kernel.org/r/20230322033057.1855741-1-windhl@126.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/surface/aggregator/bus.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/platform/surface/aggregator/bus.c b/drivers/platform/surface/aggregator/bus.c index aaad41294200d..42ccd7f1c9b9c 100644 --- a/drivers/platform/surface/aggregator/bus.c +++ b/drivers/platform/surface/aggregator/bus.c @@ -485,8 +485,10 @@ int __ssam_register_clients(struct device *parent, struct ssam_controller *ctrl, * device, so ignore it and continue with the next one. */ status = ssam_add_client_device(parent, ctrl, child); - if (status && status != -ENODEV) + if (status && status != -ENODEV) { + fwnode_handle_put(child); goto err; + } } return 0;