lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <c98adc65-f756-1f4b-aaab-85f7633dd0cc@linux.intel.com>
Date: Mon, 4 Aug 2025 10:31:41 +0300 (EEST)
From: Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>
To: Gladyshev Ilya <foxido@...ido.dev>
cc: w_armin@....de, linux-input@...r.kernel.org, 
    nikita.nikita.krasnov@...il.com, Hans de Goede <hansg@...nel.org>, 
    LKML <linux-kernel@...r.kernel.org>, platform-driver-x86@...r.kernel.org
Subject: Re: [PATCH v3] platform/x86: Add WMI driver for Redmibook
 keyboard.

On Wed, 30 Jul 2025, Gladyshev Ilya wrote:

> This driver implements support for various Fn keys (like Cut) and Xiaomi
> specific AI button.
> 
> Signed-off-by: Gladyshev Ilya <foxido@...ido.dev>

Thank you for the patch. Small correction requests below.

> ---
> Changes since v2:
> - Fix Kconfig dependencies
> - Accept WMI buffers that are bigger than expected
> 
> Link to v2: https://lore.kernel.org/platform-driver-x86/20250729190528.8446-1-foxido@foxido.dev/
> ---
>  MAINTAINERS                      |   6 ++
>  drivers/platform/x86/Kconfig     |  12 +++
>  drivers/platform/x86/Makefile    |   1 +
>  drivers/platform/x86/redmi-wmi.c | 129 +++++++++++++++++++++++++++++++
>  4 files changed, 148 insertions(+)
>  create mode 100644 drivers/platform/x86/redmi-wmi.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index c0b444e5fd5a..eb25fb10e751 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -20965,6 +20965,12 @@ S:	Maintained
>  T:	git https://github.com/pkshih/rtw.git
>  F:	drivers/net/wireless/realtek/rtw89/
>  
> +REDMIBOOK WMI DRIVERS
> +M:	Gladyshev Ilya <foxido@...ido.dev>
> +L:	platform-driver-x86@...r.kernel.org
> +S:	Maintained
> +F:	drivers/platform/x86/redmi-wmi.c
> +
>  REDPINE WIRELESS DRIVER
>  L:	linux-wireless@...r.kernel.org
>  S:	Orphan
> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> index e5cbd58a99f3..9f98a7042e43 100644
> --- a/drivers/platform/x86/Kconfig
> +++ b/drivers/platform/x86/Kconfig
> @@ -109,6 +109,18 @@ config XIAOMI_WMI
>  	  To compile this driver as a module, choose M here: the module will
>  	  be called xiaomi-wmi.
>  
> +config REDMI_WMI
> +	tristate "Redmibook WMI key driver"
> +	depends on ACPI_WMI
> +	depends on INPUT
> +	select INPUT_SPARSEKMAP
> +	help
> +	  Say Y here if you want support for WMI-based hotkey events on
> +	  Xiaomi Redmibook devices.
> +
> +	  To compile this driver as a module, choose M here: the module will
> +	  be called redmi-wmi.
> +
>  config GIGABYTE_WMI
>  	tristate "Gigabyte WMI temperature driver"
>  	depends on ACPI_WMI
> diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
> index bea87a85ae75..406dd0807ba7 100644
> --- a/drivers/platform/x86/Makefile
> +++ b/drivers/platform/x86/Makefile
> @@ -13,6 +13,7 @@ obj-$(CONFIG_HUAWEI_WMI)		+= huawei-wmi.o
>  obj-$(CONFIG_MXM_WMI)			+= mxm-wmi.o
>  obj-$(CONFIG_NVIDIA_WMI_EC_BACKLIGHT)	+= nvidia-wmi-ec-backlight.o
>  obj-$(CONFIG_XIAOMI_WMI)		+= xiaomi-wmi.o
> +obj-$(CONFIG_REDMI_WMI)			+= redmi-wmi.o
>  obj-$(CONFIG_GIGABYTE_WMI)		+= gigabyte-wmi.o
>  
>  # Acer
> diff --git a/drivers/platform/x86/redmi-wmi.c b/drivers/platform/x86/redmi-wmi.c
> new file mode 100644
> index 000000000000..3dbf4a40a4ff
> --- /dev/null
> +++ b/drivers/platform/x86/redmi-wmi.c
> @@ -0,0 +1,129 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* WMI driver for Xiaomi Redmibooks */
> +
> +#include <linux/acpi.h>
> +#include <linux/device.h>
> +#include <linux/input.h>
> +#include <linux/input/sparse-keymap.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/unaligned.h>
> +#include <linux/wmi.h>
> +
> +#include <uapi/linux/input-event-codes.h>
> +
> +#define WMI_REDMIBOOK_KEYBOARD_EVENT_GUID "46C93E13-EE9B-4262-8488-563BCA757FEF"
> +
> +#define AI_KEY_VALUE_MASK 0x00000100
> +
> +static const struct key_entry redmi_wmi_keymap[] = {
> +	{KE_KEY, 0x00000201,	{KEY_SELECTIVE_SCREENSHOT}},
> +	{KE_KEY, 0x00000301,	{KEY_ALL_APPLICATIONS}},
> +	{KE_KEY, 0x00001b01,	{KEY_SETUP}},
> +
> +	/* AI button has code for each position */
> +	{KE_KEY, 0x00011801,	{KEY_ASSISTANT}},
> +	{KE_KEY, 0x00011901,	{KEY_ASSISTANT}},
> +
> +	/* Keyboard backlight */
> +	{KE_IGNORE, 0x00000501, {}},
> +	{KE_IGNORE, 0x00800501, {}},
> +	{KE_IGNORE, 0x00050501, {}},
> +	{KE_IGNORE, 0x000a0501, {}},
> +
> +	{KE_END}
> +};
> +
> +struct redmi_wmi {
> +	struct input_dev *input_dev;
> +	/* Protects the key event sequence */
> +	struct mutex key_lock;
> +};
> +
> +static int redmi_wmi_probe(struct wmi_device *wdev, const void *context)
> +{
> +	struct redmi_wmi *data;
> +	int err;
> +
> +	/* Init dev */
> +	data = devm_kzalloc(&wdev->dev, sizeof(*data), GFP_KERNEL);
> +	if (!data)
> +		return -ENOMEM;
> +
> +	dev_set_drvdata(&wdev->dev, data);
> +
> +	err = devm_mutex_init(&wdev->dev, &data->key_lock);
> +	if (err)
> +		return err;
> +
> +	/* Setup input device */

I'd drop this comment as it doesn't really add much value.

> +	data->input_dev = devm_input_allocate_device(&wdev->dev);
> +	if (!data->input_dev)
> +		return -ENOMEM;
> +	data->input_dev->name = "Redmibook WMI keys";
> +	data->input_dev->phys = "wmi/input0";
> +
> +	err = sparse_keymap_setup(data->input_dev, redmi_wmi_keymap, NULL);
> +	if (err)
> +		return err;
> +
> +	return input_register_device(data->input_dev);
> +}
> +
> +static void redmi_wmi_notify(struct wmi_device *wdev, union acpi_object *obj)
> +{
> +	struct redmi_wmi *data = dev_get_drvdata(&wdev->dev);
> +	bool autorelease = true;
> +	int value = 1;
> +
> +	if (obj->type != ACPI_TYPE_BUFFER) {
> +		dev_err(&wdev->dev, "Bad response type %u\n", obj->type);

To me it feels like these prints from the notify handlers should be 
ratelimited just in case, but then I notice the other drivers don't 
ratelimit them either so perhaps it has never caused an issue.

> +		return;
> +	}
> +
> +	if (obj->buffer.length < 32) {
> +		dev_err(&wdev->dev, "Invalid buffer length %u\n", obj->buffer.length);
> +		return;
> +	}
> +
> +	/* For linearizability */

This comment doesn't really tell anything we don't know already from 
seeing the mutex being taken.

> +	guard(mutex)(&data->key_lock);
> +
> +	u32 payload = get_unaligned_le32(obj->buffer.pointer);

Please always declare variables at the beginning of a function or a block, 
not in the middle of it. The only allowed exception to this rule is 
cleanup.h related variables as there the cleanup order really matters.

> +	struct key_entry *entry = sparse_keymap_entry_from_scancode(data->input_dev, payload);
> +
> +	if (!entry) {
> +		dev_dbg(&wdev->dev, "Unknown WMI event with payload %u", payload);
> +		return;
> +	}
> +
> +	/* AI key quirk */
> +	if (entry->keycode == KEY_ASSISTANT) {
> +		value = !(payload & AI_KEY_VALUE_MASK);
> +		autorelease = false;
> +	}
> +
> +	sparse_keymap_report_entry(data->input_dev, entry, value, autorelease);
> +}
> +
> +static const struct wmi_device_id redmi_wmi_id_table[] = {
> +	{ .guid_string = WMI_REDMIBOOK_KEYBOARD_EVENT_GUID },
> +	{ }
> +};
> +
> +static struct wmi_driver redmi_wmi_driver = {
> +	.driver = {
> +		.name = "redmi-wmi",
> +		.probe_type = PROBE_PREFER_ASYNCHRONOUS

Please put a comma on any non-terminating entries so that a future 
diff won't have to add it on that (unrelated) line.

> +	},
> +	.id_table = redmi_wmi_id_table,
> +	.probe = redmi_wmi_probe,
> +	.notify = redmi_wmi_notify,
> +	.no_singleton = true,
> +};
> +module_wmi_driver(redmi_wmi_driver);
> +
> +MODULE_DEVICE_TABLE(wmi, redmi_wmi_id_table);
> +MODULE_AUTHOR("Gladyshev Ilya <foxido@...ido.dev>");
> +MODULE_DESCRIPTION("Redmibook WMI driver");
> +MODULE_LICENSE("GPL");
> 

-- 
 i.


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ