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] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240308144933.337107-2-laura.nao@collabora.com>
Date: Fri,  8 Mar 2024 15:49:32 +0100
From: Laura Nao <laura.nao@...labora.com>
To: rafael@...nel.org,
	lenb@...nel.org,
	shuah@...nel.org
Cc: dan.carpenter@...aro.org,
	broonie@...nel.org,
	groeck@...omium.org,
	kernel@...labora.com,
	kernelci@...ts.linux.dev,
	linux-acpi@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	linux-kselftest@...r.kernel.org,
	robh+dt@...nel.org,
	saravanak@...gle.com,
	davidgow@...gle.com,
	Tim.Bird@...y.com,
	dianders@...omium.org,
	Laura Nao <laura.nao@...labora.com>
Subject: [RFC PATCH v2 1/2] acpi: Add script to extract ACPI device ids in the kernel

Add a script to extract all the supported acpi device ids
from kernel sources.

The script looks for IDs defined in acpi_device_id structs within both
c and .h files and prints them. If the -d option is used, the script
only shows the IDs that are matched by a driver, identified through
either an ACPI match table or a list of supported IDs provided by the
driver.

The list of IDs returned by the script can be used as a
reference to determine if a device declared in the ACPI namespace
with certain _HID/_CID is supported by the kernel or not.

Note: this script cannot identify IDs defined via macros.

Signed-off-by: Laura Nao <laura.nao@...labora.com>
---
 MAINTAINERS                   |  1 +
 scripts/acpi/acpi-extract-ids | 99 +++++++++++++++++++++++++++++++++++
 2 files changed, 100 insertions(+)
 create mode 100755 scripts/acpi/acpi-extract-ids

diff --git a/MAINTAINERS b/MAINTAINERS
index 375d34363777..8333ead448c4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -293,6 +293,7 @@ F:	include/linux/acpi.h
 F:	include/linux/fwnode.h
 F:	include/linux/fw_table.h
 F:	lib/fw_table.c
+F:	scripts/acpi/acpi-extract-ids
 F:	tools/power/acpi/
 
 ACPI APEI
diff --git a/scripts/acpi/acpi-extract-ids b/scripts/acpi/acpi-extract-ids
new file mode 100755
index 000000000000..4c492d384a35
--- /dev/null
+++ b/scripts/acpi/acpi-extract-ids
@@ -0,0 +1,99 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Heavily inspired by the scripts/dtc/dt-extract-compatibles script,
+# adapted for the ACPI use case.
+#
+
+import fnmatch
+import os
+import glob
+import re
+import argparse
+
+
+def parse_acpi_device_id(data, match_list=None):
+    """ Find all device ids in acpi_device_id structs """
+    acpi_device_id_list = []
+
+    for m in re.finditer(r'acpi_device_id(\s+\S+)?\s+(\S+)\[\](\s+\S+)?\s*=\s*({.*?);', data):
+        if match_list is not None and m[2] not in match_list:
+            continue
+        acpi_device_id_list += re.findall(r'\"(\S+)\"', m[4])
+
+    return acpi_device_id_list
+
+def parse_acpi_match_table(data):
+    """ Find all driver's acpi_match_table """
+    match_table_list = []
+    for m in re.finditer(r'\.acpi_match_table\s+=\s+(ACPI_PTR\()?([a-zA-Z0-9_-]+)', data):
+        match_table_list.append(m[2])
+
+    return match_table_list
+
+def parse_acpi_driver_ids(data):
+    """ Find all driver's ids """
+    id_list = []
+    for m in re.finditer(r'\.ids\s+=\s+([a-zA-Z0-9_-]+)', data):
+        id_list.append(m[1])
+
+    return id_list
+
+def is_header_file(file):
+    _, extension = os.path.splitext(file)
+    return extension.lower() == ".h"
+
+def parse_ids(file, driver_match=False):
+    with open(file, 'r', encoding='utf-8') as f:
+        data = f.read().replace('\n', '')
+
+    if is_header_file(file) or not driver_match:
+        return parse_acpi_device_id(data)
+    else:
+        match_list = parse_acpi_match_table(data) + parse_acpi_driver_ids(data)
+        return parse_acpi_device_id(data, match_list)
+
+def print_ids(filename, id_list):
+    if not id_list:
+        return
+    if show_filename:
+        compat_str = ' '.join(id_list)
+        print(filename + ": ID(s): " + compat_str)
+    else:
+        print(*id_list, sep='\n')
+
+def glob_without_symlinks(root, glob):
+    for path, dirs, files in os.walk(root):
+        # Ignore hidden directories
+        for d in dirs:
+            if fnmatch.fnmatch(d, ".*"):
+                dirs.remove(d)
+        for f in files:
+            if fnmatch.fnmatch(f, glob):
+                yield os.path.join(path, f)
+
+def files_to_parse(path_args):
+    for f in path_args:
+        if os.path.isdir(f):
+            for filename in glob_without_symlinks(f, "*.[ch]"):
+                yield filename
+        else:
+            yield f
+
+
+show_filename = False
+
+if __name__ == "__main__":
+    ap = argparse.ArgumentParser()
+    ap.add_argument("cfile", type=str, nargs='*',
+                    help="C source files or directories to parse")
+    ap.add_argument('-H', '--with-filename',
+                    help="Print filename with device ids", action="store_true")
+    ap.add_argument('-d', '--driver-match', help="Only print ids that should match to a driver", action="store_true")
+    args = ap.parse_args()
+
+    show_filename = args.with_filename
+
+    for f in files_to_parse(args.cfile):
+        id_list = parse_ids(f, args.driver_match)
+        print_ids(f, id_list)
-- 
2.30.2


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ