* [PATCH v2 1/4] fs/nls: Fix utf16 to utf8 conversion
2025-11-11 13:11 [PATCH v2 0/4] platform/x86: wmi: Prepare for future changes Armin Wolf
@ 2025-11-11 13:11 ` Armin Wolf
2025-11-26 15:18 ` Andy Shevchenko
2025-11-11 13:11 ` [PATCH v2 2/4] platform/x86: wmi: Use correct type when populating ACPI objects Armin Wolf
` (3 subsequent siblings)
4 siblings, 1 reply; 8+ messages in thread
From: Armin Wolf @ 2025-11-11 13:11 UTC (permalink / raw)
To: viro, brauner, hansg, ilpo.jarvinen
Cc: superm1, jack, linux-fsdevel, linux-kernel, platform-driver-x86
Currently the function responsible for converting between utf16 and
utf8 strings will ignore any characters that cannot be converted. This
however also includes multi-byte characters that do not fit into the
provided string buffer.
This can cause problems if such a multi-byte character is followed by
a single-byte character. In such a case the multi-byte character might
be ignored when the provided string buffer is too small, but the
single-byte character might fit and is thus still copied into the
resulting string.
Fix this by stop filling the provided string buffer once a character
does not fit. In order to be able to do this extend utf32_to_utf8()
to return useful errno codes instead of -1.
Fixes: 74675a58507e ("NLS: update handling of Unicode")
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
---
fs/nls/nls_base.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c
index 18d597e49a19..d434c4463a8f 100644
--- a/fs/nls/nls_base.c
+++ b/fs/nls/nls_base.c
@@ -94,7 +94,7 @@ int utf32_to_utf8(unicode_t u, u8 *s, int maxout)
l = u;
if (l > UNICODE_MAX || (l & SURROGATE_MASK) == SURROGATE_PAIR)
- return -1;
+ return -EILSEQ;
nc = 0;
for (t = utf8_table; t->cmask && maxout; t++, maxout--) {
@@ -110,7 +110,7 @@ int utf32_to_utf8(unicode_t u, u8 *s, int maxout)
return nc;
}
}
- return -1;
+ return -EOVERFLOW;
}
EXPORT_SYMBOL(utf32_to_utf8);
@@ -217,8 +217,16 @@ int utf16s_to_utf8s(const wchar_t *pwcs, int inlen, enum utf16_endian endian,
inlen--;
}
size = utf32_to_utf8(u, op, maxout);
- if (size == -1) {
- /* Ignore character and move on */
+ if (size < 0) {
+ if (size == -EILSEQ) {
+ /* Ignore character and move on */
+ continue;
+ }
+ /*
+ * Stop filling the buffer with data once a character
+ * does not fit anymore.
+ */
+ break;
} else {
op += size;
maxout -= size;
--
2.39.5
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v2 1/4] fs/nls: Fix utf16 to utf8 conversion
2025-11-11 13:11 ` [PATCH v2 1/4] fs/nls: Fix utf16 to utf8 conversion Armin Wolf
@ 2025-11-26 15:18 ` Andy Shevchenko
2025-11-26 19:34 ` Armin Wolf
0 siblings, 1 reply; 8+ messages in thread
From: Andy Shevchenko @ 2025-11-26 15:18 UTC (permalink / raw)
To: Armin Wolf
Cc: viro, brauner, hansg, ilpo.jarvinen, superm1, jack, linux-fsdevel,
linux-kernel, platform-driver-x86
On Tue, Nov 11, 2025 at 02:11:22PM +0100, Armin Wolf wrote:
> Currently the function responsible for converting between utf16 and
> utf8 strings will ignore any characters that cannot be converted. This
> however also includes multi-byte characters that do not fit into the
> provided string buffer.
>
> This can cause problems if such a multi-byte character is followed by
> a single-byte character. In such a case the multi-byte character might
> be ignored when the provided string buffer is too small, but the
> single-byte character might fit and is thus still copied into the
> resulting string.
>
> Fix this by stop filling the provided string buffer once a character
> does not fit. In order to be able to do this extend utf32_to_utf8()
> to return useful errno codes instead of -1.
Can you also update utf8_to_utf32() to return meaningful error codes?
Without that done we have inconsistent APIs.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/4] fs/nls: Fix utf16 to utf8 conversion
2025-11-26 15:18 ` Andy Shevchenko
@ 2025-11-26 19:34 ` Armin Wolf
0 siblings, 0 replies; 8+ messages in thread
From: Armin Wolf @ 2025-11-26 19:34 UTC (permalink / raw)
To: Andy Shevchenko
Cc: viro, brauner, hansg, ilpo.jarvinen, superm1, jack, linux-fsdevel,
linux-kernel, platform-driver-x86
Am 26.11.25 um 16:18 schrieb Andy Shevchenko:
> On Tue, Nov 11, 2025 at 02:11:22PM +0100, Armin Wolf wrote:
>> Currently the function responsible for converting between utf16 and
>> utf8 strings will ignore any characters that cannot be converted. This
>> however also includes multi-byte characters that do not fit into the
>> provided string buffer.
>>
>> This can cause problems if such a multi-byte character is followed by
>> a single-byte character. In such a case the multi-byte character might
>> be ignored when the provided string buffer is too small, but the
>> single-byte character might fit and is thus still copied into the
>> resulting string.
>>
>> Fix this by stop filling the provided string buffer once a character
>> does not fit. In order to be able to do this extend utf32_to_utf8()
>> to return useful errno codes instead of -1.
> Can you also update utf8_to_utf32() to return meaningful error codes?
> Without that done we have inconsistent APIs.
>
Sure, i will send a separate patch for that.
Thanks,
Armin Wolf
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 2/4] platform/x86: wmi: Use correct type when populating ACPI objects
2025-11-11 13:11 [PATCH v2 0/4] platform/x86: wmi: Prepare for future changes Armin Wolf
2025-11-11 13:11 ` [PATCH v2 1/4] fs/nls: Fix utf16 to utf8 conversion Armin Wolf
@ 2025-11-11 13:11 ` Armin Wolf
2025-11-11 13:11 ` [PATCH v2 3/4] platform/x86: wmi: Remove extern keyword from prototypes Armin Wolf
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Armin Wolf @ 2025-11-11 13:11 UTC (permalink / raw)
To: viro, brauner, hansg, ilpo.jarvinen
Cc: superm1, jack, linux-fsdevel, linux-kernel, platform-driver-x86
When evaluating a WMxx/WSxx ACPI control method, the data buffer
either needs to be passed as an ACPI buffer or as an ACPI string.
Use the correct type (buffer/string) when populating the associated
ACPI object.
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
---
drivers/platform/x86/wmi.c | 34 ++++++++++++++++++++--------------
1 file changed, 20 insertions(+), 14 deletions(-)
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index 4e86a422f05f..6878c4fcb0b5 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -142,14 +142,6 @@ static inline void get_acpi_method_name(const struct wmi_block *wblock,
buffer[4] = '\0';
}
-static inline acpi_object_type get_param_acpi_type(const struct wmi_block *wblock)
-{
- if (wblock->gblock.flags & ACPI_WMI_STRING)
- return ACPI_TYPE_STRING;
- else
- return ACPI_TYPE_BUFFER;
-}
-
static int wmidev_match_guid(struct device *dev, const void *data)
{
struct wmi_block *wblock = dev_to_wblock(dev);
@@ -351,9 +343,16 @@ acpi_status wmidev_evaluate_method(struct wmi_device *wdev, u8 instance, u32 met
params[0].integer.value = instance;
params[1].type = ACPI_TYPE_INTEGER;
params[1].integer.value = method_id;
- params[2].type = get_param_acpi_type(wblock);
- params[2].buffer.length = in->length;
- params[2].buffer.pointer = in->pointer;
+
+ if (wblock->gblock.flags & ACPI_WMI_STRING) {
+ params[2].type = ACPI_TYPE_STRING;
+ params[2].string.length = in->length;
+ params[2].string.pointer = in->pointer;
+ } else {
+ params[2].type = ACPI_TYPE_BUFFER;
+ params[2].buffer.length = in->length;
+ params[2].buffer.pointer = in->pointer;
+ }
get_acpi_method_name(wblock, 'M', method);
@@ -519,9 +518,16 @@ acpi_status wmidev_block_set(struct wmi_device *wdev, u8 instance, const struct
input.pointer = params;
params[0].type = ACPI_TYPE_INTEGER;
params[0].integer.value = instance;
- params[1].type = get_param_acpi_type(wblock);
- params[1].buffer.length = in->length;
- params[1].buffer.pointer = in->pointer;
+
+ if (wblock->gblock.flags & ACPI_WMI_STRING) {
+ params[1].type = ACPI_TYPE_STRING;
+ params[1].string.length = in->length;
+ params[1].string.pointer = in->pointer;
+ } else {
+ params[1].type = ACPI_TYPE_BUFFER;
+ params[1].buffer.length = in->length;
+ params[1].buffer.pointer = in->pointer;
+ }
get_acpi_method_name(wblock, 'S', method);
--
2.39.5
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v2 3/4] platform/x86: wmi: Remove extern keyword from prototypes
2025-11-11 13:11 [PATCH v2 0/4] platform/x86: wmi: Prepare for future changes Armin Wolf
2025-11-11 13:11 ` [PATCH v2 1/4] fs/nls: Fix utf16 to utf8 conversion Armin Wolf
2025-11-11 13:11 ` [PATCH v2 2/4] platform/x86: wmi: Use correct type when populating ACPI objects Armin Wolf
@ 2025-11-11 13:11 ` Armin Wolf
2025-11-11 13:11 ` [PATCH v2 4/4] platform/x86: wmi: Move WMI core code into a separate directory Armin Wolf
2025-11-18 10:08 ` [PATCH v2 0/4] platform/x86: wmi: Prepare for future changes Ilpo Järvinen
4 siblings, 0 replies; 8+ messages in thread
From: Armin Wolf @ 2025-11-11 13:11 UTC (permalink / raw)
To: viro, brauner, hansg, ilpo.jarvinen
Cc: superm1, jack, linux-fsdevel, linux-kernel, platform-driver-x86
The external function definitions do not need the "extern" keyword.
Remove it to silence the associated checkpatch warnings.
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
---
include/linux/wmi.h | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/include/linux/wmi.h b/include/linux/wmi.h
index 10751c8e5e6a..665ea7dc8a92 100644
--- a/include/linux/wmi.h
+++ b/include/linux/wmi.h
@@ -36,13 +36,10 @@ struct wmi_device {
*/
#define to_wmi_device(device) container_of_const(device, struct wmi_device, dev)
-extern acpi_status wmidev_evaluate_method(struct wmi_device *wdev,
- u8 instance, u32 method_id,
- const struct acpi_buffer *in,
- struct acpi_buffer *out);
+acpi_status wmidev_evaluate_method(struct wmi_device *wdev, u8 instance, u32 method_id,
+ const struct acpi_buffer *in, struct acpi_buffer *out);
-extern union acpi_object *wmidev_block_query(struct wmi_device *wdev,
- u8 instance);
+union acpi_object *wmidev_block_query(struct wmi_device *wdev, u8 instance);
acpi_status wmidev_block_set(struct wmi_device *wdev, u8 instance, const struct acpi_buffer *in);
@@ -81,9 +78,9 @@ struct wmi_driver {
*/
#define to_wmi_driver(drv) container_of_const(drv, struct wmi_driver, driver)
-extern int __must_check __wmi_driver_register(struct wmi_driver *driver,
- struct module *owner);
-extern void wmi_driver_unregister(struct wmi_driver *driver);
+int __must_check __wmi_driver_register(struct wmi_driver *driver, struct module *owner);
+
+void wmi_driver_unregister(struct wmi_driver *driver);
/**
* wmi_driver_register() - Helper macro to register a WMI driver
--
2.39.5
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v2 4/4] platform/x86: wmi: Move WMI core code into a separate directory
2025-11-11 13:11 [PATCH v2 0/4] platform/x86: wmi: Prepare for future changes Armin Wolf
` (2 preceding siblings ...)
2025-11-11 13:11 ` [PATCH v2 3/4] platform/x86: wmi: Remove extern keyword from prototypes Armin Wolf
@ 2025-11-11 13:11 ` Armin Wolf
2025-11-18 10:08 ` [PATCH v2 0/4] platform/x86: wmi: Prepare for future changes Ilpo Järvinen
4 siblings, 0 replies; 8+ messages in thread
From: Armin Wolf @ 2025-11-11 13:11 UTC (permalink / raw)
To: viro, brauner, hansg, ilpo.jarvinen
Cc: superm1, jack, linux-fsdevel, linux-kernel, platform-driver-x86
Move the WMI core code into a separate directory to prepare for
future additions to the WMI driver. Also update the description
of the Kconfig entry to better fit with the other subsystem
Kconfig entries.
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
---
Documentation/driver-api/wmi.rst | 2 +-
MAINTAINERS | 2 +-
drivers/platform/Kconfig | 2 ++
drivers/platform/Makefile | 1 +
drivers/platform/wmi/Kconfig | 34 ++++++++++++++++++++++
drivers/platform/wmi/Makefile | 8 +++++
drivers/platform/{x86/wmi.c => wmi/core.c} | 0
drivers/platform/x86/Kconfig | 30 -------------------
drivers/platform/x86/Makefile | 1 -
9 files changed, 47 insertions(+), 33 deletions(-)
create mode 100644 drivers/platform/wmi/Kconfig
create mode 100644 drivers/platform/wmi/Makefile
rename drivers/platform/{x86/wmi.c => wmi/core.c} (100%)
diff --git a/Documentation/driver-api/wmi.rst b/Documentation/driver-api/wmi.rst
index 4e8dbdb1fc67..db835b43c937 100644
--- a/Documentation/driver-api/wmi.rst
+++ b/Documentation/driver-api/wmi.rst
@@ -16,5 +16,5 @@ which will be bound to compatible WMI devices by the driver core.
.. kernel-doc:: include/linux/wmi.h
:internal:
-.. kernel-doc:: drivers/platform/x86/wmi.c
+.. kernel-doc:: drivers/platform/wmi/core.c
:export:
diff --git a/MAINTAINERS b/MAINTAINERS
index 46126ce2f968..2dc2e6cd58df 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -402,7 +402,7 @@ S: Maintained
F: Documentation/ABI/testing/sysfs-bus-wmi
F: Documentation/driver-api/wmi.rst
F: Documentation/wmi/
-F: drivers/platform/x86/wmi.c
+F: drivers/platform/wmi/
F: include/uapi/linux/wmi.h
ACRN HYPERVISOR SERVICE MODULE
diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig
index 960fd6a82450..6bb645aed3d1 100644
--- a/drivers/platform/Kconfig
+++ b/drivers/platform/Kconfig
@@ -18,3 +18,5 @@ source "drivers/platform/surface/Kconfig"
source "drivers/platform/x86/Kconfig"
source "drivers/platform/arm64/Kconfig"
+
+source "drivers/platform/wmi/Kconfig"
diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile
index 19ac54648586..533f500dfcff 100644
--- a/drivers/platform/Makefile
+++ b/drivers/platform/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_CHROME_PLATFORMS) += chrome/
obj-$(CONFIG_CZNIC_PLATFORMS) += cznic/
obj-$(CONFIG_SURFACE_PLATFORMS) += surface/
obj-$(CONFIG_ARM64_PLATFORM_DEVICES) += arm64/
+obj-$(CONFIG_ACPI_WMI) += wmi/
diff --git a/drivers/platform/wmi/Kconfig b/drivers/platform/wmi/Kconfig
new file mode 100644
index 000000000000..77fcbb18746b
--- /dev/null
+++ b/drivers/platform/wmi/Kconfig
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# ACPI WMI Core
+#
+
+menuconfig ACPI_WMI
+ tristate "ACPI-WMI support"
+ depends on ACPI && X86
+ help
+ This option enables support for the ACPI-WMI driver core.
+
+ The ACPI-WMI interface is a proprietary extension of ACPI allowing
+ the platform firmware to expose WMI (Windows Management Instrumentation)
+ objects used for managing various aspects of the underlying system.
+ Mapping between ACPI control methods and WMI objects happens through
+ special mapper devices (PNP0C14) defined inside the ACPI tables.
+
+ Enabling this option is necessary for building the vendor specific
+ ACPI-WMI client drivers for Acer, Dell an HP machines (among others).
+
+ It is safe to enable this option even for machines that do not contain
+ any ACPI-WMI mapper devices at all.
+
+if ACPI_WMI
+
+config ACPI_WMI_LEGACY_DEVICE_NAMES
+ bool "Use legacy WMI device naming scheme"
+ help
+ Say Y here to force the WMI driver core to use the old WMI device naming
+ scheme when creating WMI devices. Doing so might be necessary for some
+ userspace applications but will cause the registration of WMI devices with
+ the same GUID to fail in some corner cases.
+
+endif # ACPI_WMI
diff --git a/drivers/platform/wmi/Makefile b/drivers/platform/wmi/Makefile
new file mode 100644
index 000000000000..98393d7391ec
--- /dev/null
+++ b/drivers/platform/wmi/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Makefile for linux/drivers/platform/wmi
+# ACPI WMI core
+#
+
+wmi-y := core.o
+obj-$(CONFIG_ACPI_WMI) += wmi.o
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/wmi/core.c
similarity index 100%
rename from drivers/platform/x86/wmi.c
rename to drivers/platform/wmi/core.c
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 46e62feeda3c..8c13430366ae 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -16,36 +16,6 @@ menuconfig X86_PLATFORM_DEVICES
if X86_PLATFORM_DEVICES
-config ACPI_WMI
- tristate "WMI"
- depends on ACPI
- help
- This driver adds support for the ACPI-WMI (Windows Management
- Instrumentation) mapper device (PNP0C14) found on some systems.
-
- ACPI-WMI is a proprietary extension to ACPI to expose parts of the
- ACPI firmware to userspace - this is done through various vendor
- defined methods and data blocks in a PNP0C14 device, which are then
- made available for userspace to call.
-
- The implementation of this in Linux currently only exposes this to
- other kernel space drivers.
-
- This driver is a required dependency to build the firmware specific
- drivers needed on many machines, including Acer and HP laptops.
-
- It is safe to enable this driver even if your DSDT doesn't define
- any ACPI-WMI devices.
-
-config ACPI_WMI_LEGACY_DEVICE_NAMES
- bool "Use legacy WMI device naming scheme"
- depends on ACPI_WMI
- help
- Say Y here to force the WMI driver core to use the old WMI device naming
- scheme when creating WMI devices. Doing so might be necessary for some
- userspace applications but will cause the registration of WMI devices with
- the same GUID to fail in some corner cases.
-
config WMI_BMOF
tristate "WMI embedded Binary MOF driver"
depends on ACPI_WMI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index c7db2a88c11a..978cb55672da 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -5,7 +5,6 @@
#
# Windows Management Interface
-obj-$(CONFIG_ACPI_WMI) += wmi.o
obj-$(CONFIG_WMI_BMOF) += wmi-bmof.o
# WMI drivers
--
2.39.5
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v2 0/4] platform/x86: wmi: Prepare for future changes
2025-11-11 13:11 [PATCH v2 0/4] platform/x86: wmi: Prepare for future changes Armin Wolf
` (3 preceding siblings ...)
2025-11-11 13:11 ` [PATCH v2 4/4] platform/x86: wmi: Move WMI core code into a separate directory Armin Wolf
@ 2025-11-18 10:08 ` Ilpo Järvinen
4 siblings, 0 replies; 8+ messages in thread
From: Ilpo Järvinen @ 2025-11-18 10:08 UTC (permalink / raw)
To: viro, brauner, hansg, Armin Wolf
Cc: superm1, jack, linux-fsdevel, linux-kernel, platform-driver-x86
On Tue, 11 Nov 2025 14:11:21 +0100, Armin Wolf wrote:
> After over a year of reverse engineering, i am finally ready to
> introduce support for WMI-ACPI marshaling inside the WMI driver core.
> Since the resulting patch series is quite large, i am planning to
> submit the necessary patches as three separate patch series.
>
> This is supposed to be the first of the three patch series. Its main
> purpose is to prepare the WMI driver core for the upcoming changes.
> The first patch fixes an issue inside the nls utf16 to utf8 conversion
> code, while the next two patches fix some minor issues inside the WMI
> driver core itself. The last patch finally moves the code of the WMI
> driver core into a separate repository to allow for future additions
> without cluttering the main directory.
>
> [...]
Thank you for your contribution, it has been applied to my local
review-ilpo-next branch. Note it will show up in the public
platform-drivers-x86/review-ilpo-next branch only once I've pushed my
local branch there, which might take a while.
The list of commits applied:
[1/4] fs/nls: Fix utf16 to utf8 conversion
commit: 25524b6190295577e4918c689644451365e6466d
[2/4] platform/x86: wmi: Use correct type when populating ACPI objects
commit: c209195a2a4ad920ff481b56628ca942d62e01b1
[3/4] platform/x86: wmi: Remove extern keyword from prototypes
commit: 32e3fee88a4ac183541b478f5bc94084ea76436c
[4/4] platform/x86: wmi: Move WMI core code into a separate directory
commit: e2c1b56f3dfa014128e775e898774c0356e3ff05
--
i.
^ permalink raw reply [flat|nested] 8+ messages in thread