From nobody Sat Feb 7 13:41:37 2026 Received: from mail-pl1-f170.google.com (mail-pl1-f170.google.com [209.85.214.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AABBF33D6F9 for ; Sun, 1 Feb 2026 13:03:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769951037; cv=none; b=JvwfN0RnkCt62skmohGikc2Ke2qHjLeQwC10vY61paVaniQjgVfKRdql50dKjH96XoQiLrL1wanqQuAdPZn+agi2OlWx8KbClQEhwEweqqVVzrn85+QUnMZVVWb/cQSrxIOP4krPOrjQIgGdkwgXTY1iAE++qCbY+jYzYLS1ohk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769951037; c=relaxed/simple; bh=jkJFaSw+4QB88At9pISwIN/7R4HhlxcEMlc2qyYUNjo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Mz3/V1kt62ZFR8qaRzWADBVTUPS+ExQyCkkWOQ10ISYaa5k78B6Mk1JvUSFwe77WJWNNegiGVZVpvGx5D9eB0/Cx0/h562P7cKCAdCKqDPw26SlPD7df1DkGaZcMtTHjes+5XXAV20PctE9QthofbQPUUDVJrjIO2AUmx4e1vrw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=bfD/in+C; arc=none smtp.client-ip=209.85.214.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bfD/in+C" Received: by mail-pl1-f170.google.com with SMTP id d9443c01a7336-29f2676bb21so33131715ad.0 for ; Sun, 01 Feb 2026 05:03:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1769951027; x=1770555827; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=zpTdJ6kU9128Bplq2Lsam/HvuOJViBWd2y7vXvIt9P8=; b=bfD/in+CcQ6LU7k70toJqin7m6NIf00XTdyWIjzRcg5sWKYuEyO4QUqt6vc3KNFaA/ nTT0KxrD/+RawiKEy3+WHxiedOLspzhyMX7vxEi6FGN79O8CwCB31Gq7A8FxqdTFfaBW x3Iq4VFQ9pfEy1dZG7TyQFl2qHjW3lctux8YINlMYyLmQsefM9VQV70pzQgOMzk7Ub9Z ws438n67DWrmBC8z2/2zvOwPkrYbrP14ULorDhoA5XBoRNzEq1id/RnaHXXq3ZpgTBVF CkroBdNJmcfItuGUMpS9YTMc96gZAcjhCGR+VA/lubuOUM9rcb6XFv3mSWgCYh3FUf2y Ux8A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769951027; x=1770555827; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=zpTdJ6kU9128Bplq2Lsam/HvuOJViBWd2y7vXvIt9P8=; b=aWwKT35P5kHMZbKzasNy/HSnIz9tId2AplcEww9O5OCgBbs4VagBKyi1LmgYPK2hvC qskW0++JdDomurmBSd4hL411k8IV2fmKVIHw3mnykTe6vQA/Kb6oiIuK0mmAeqCDqKpu OgNFACJLJJzHdE5naQYTINxLyYTctCuPKIO1FaB+zJFuOYG7kpO+eCkskMjv10vi3aQs lSrPVnZXVNlDm4G9Z7bNPounc33OhM09T+XMHCPnB39WQZvRKhCmS4qr43QIVc3eEqUF Yp6LLDgkiAkitKKwx5W7nN6hAQ11f1M5IQZEAqtXGRUGBh5JmOuB8s9HiYh9fmJMzrQH zj9A== X-Forwarded-Encrypted: i=1; AJvYcCURHQOLw2gurTu7eZBxYrJUoti4lyGQdhcwVQZ9dMirkURUFggnmivDryCI4dvI1OiwDzT6rHykErHT1og=@vger.kernel.org X-Gm-Message-State: AOJu0YywfwTXh67SomwL7rRSzXLa7LOiqjoCZl6doiwtuqkXuAnOpA+e kILILq0wuiwDegF5Ur/RzP8gCY9sNcwPp+oNgen9cB0Q7djaIxSiz/sj X-Gm-Gg: AZuq6aI6Q3gJdYiNE3YtQWGcNYULd8HfhyLZC6f5AfdASFFPF5+P5/d9Gwn9iMavc5L YdAfDxvhAhqBo6b3hSorenOtIp1rhisl59xPRlIe6hWlSICn5iDrL4xaPAx+mbU6zEZTvrPlWOM rt+BMdO5xhwdo5tO9TABosE6CcKrzJ/WkPf/hl5SpHc+nRpKfxAg/PyFvb03ZfITt+tcqUN0rVs C3pBbpFnRZBxElYKMHTpquikPj7PK1lLvidya5K6IWKkMU2eHcN7Pp2QRfad5fzYoVKG3xIQJkb aiyRFR4j7PIeLgSDO+1G/lol4nE7IUmz7sGe5xEO7846PGobbkByTa+ngHbYvGu+RWmkTTYEykK uvqil0aSkINIObmkigs7hhUpj7R5vjhjaVhkjaF7KxvgvO9jNsffRx+RXwkRvDN4O8A2QDfyyNs iIeGpggVBSAOGHXQIPehQb+IY8JhV4LhXn9DMmRVIYZ2tbR2x2sc3hZhe4Uu//wK96svwu0FnEb 9IYReAdJA== X-Received: by 2002:a17:902:cf10:b0:29d:65ed:f481 with SMTP id d9443c01a7336-2a8d8946eabmr94972755ad.0.1769951027197; Sun, 01 Feb 2026 05:03:47 -0800 (PST) Received: from nickhuang.. (2001-b400-e28b-f958-90c5-2a29-7d9f-5524.emome-ip6.hinet.net. [2001:b400:e28b:f958:90c5:2a29:7d9f:5524]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2a8bd74e9bbsm96831045ad.95.2026.02.01.05.03.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 Feb 2026 05:03:46 -0800 (PST) From: Nick Huang To: "Rafael J . Wysocki" , Robert Moore Cc: Len Brown , linux-acpi@vger.kernel.org, acpica-devel@lists.linux.dev, linux-kernel@vger.kernel.org, paladin@ntub.edu.tw, kusogame68@gmail.com, ceyanglab@gmail.com, n1136402@ntub.edu.tw, Nick Huang Subject: [PATCH 1/2] =?UTF-8?q?ACPI:=20nsrepair2:=20Replace=20O(n=C2=B2)?= =?UTF-8?q?=20bubble=20sort=20with=20O(n=20log=20n)=20sort=5Fr()?= Date: Sun, 1 Feb 2026 13:03:33 +0000 Message-ID: <20260201130334.3107-2-sef1548@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260201130334.3107-1-sef1548@gmail.com> References: <20260201130334.3107-1-sef1548@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Replace the O(n=C2=B2) bubble sort implementation in acpi_ns_sort_list() with the kernel's sort_r() function which uses heapsort, providing O(n log n) time complexity. This improves performance for large ACPI package lists while also reducing code complexity by leveraging the existing kernel sort API. Signed-off-by: Nick Huang --- drivers/acpi/acpica/nsrepair2.c | 87 +++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 25 deletions(-) diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair= 2.c index 8dbb870f4..a39ef59fe 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c @@ -9,6 +9,7 @@ *************************************************************************= ****/ =20 #include +#include #include "accommon.h" #include "acnamesp.h" =20 @@ -84,6 +85,14 @@ acpi_ns_check_sorted_list(struct acpi_evaluate_info *inf= o, static void acpi_ns_remove_element(union acpi_operand_object *obj_desc, u32 index); =20 +/* Context structure for sort comparison function */ +struct acpi_sort_context { + u32 sort_index; + u8 sort_direction; +}; + +static int acpi_ns_sort_cmp(const void *a, const void *b, const void *priv= ); + static void acpi_ns_sort_list(union acpi_operand_object **elements, u32 count, u32 index, u8 sort_direction); @@ -851,6 +860,52 @@ acpi_ns_check_sorted_list(struct acpi_evaluate_info *i= nfo, return (AE_OK); } =20 +/*************************************************************************= ***** + * + * FUNCTION: acpi_ns_sort_cmp + * + * PARAMETERS: a - First element to compare + * b - Second element to compare + * priv - Pointer to sort context (acpi_sort_conte= xt) + * + * RETURN: -1, 0, or 1 depending on sort order + * + * DESCRIPTION: Comparison function for sort_r() API. Compares the integer + * values at the specified index within package elements. + * + *************************************************************************= ****/ + +static int acpi_ns_sort_cmp(const void *a, const void *b, const void *priv) +{ + union acpi_operand_object *obj_a =3D *(union acpi_operand_object **)a; + union acpi_operand_object *obj_b =3D *(union acpi_operand_object **)b; + const struct acpi_sort_context *ctx =3D priv; + union acpi_operand_object *value_a; + union acpi_operand_object *value_b; + u64 a_val; + u64 b_val; + + value_a =3D obj_a->package.elements[ctx->sort_index]; + value_b =3D obj_b->package.elements[ctx->sort_index]; + + a_val =3D value_a->integer.value; + b_val =3D value_b->integer.value; + + if (ctx->sort_direction =3D=3D ACPI_SORT_ASCENDING) { + if (a_val < b_val) + return -1; + if (a_val > b_val) + return 1; + } else { + if (a_val > b_val) + return -1; + if (a_val < b_val) + return 1; + } + + return 0; +} + /*************************************************************************= ***** * * FUNCTION: acpi_ns_sort_list @@ -873,31 +928,13 @@ static void acpi_ns_sort_list(union acpi_operand_object **elements, u32 count, u32 index, u8 sort_direction) { - union acpi_operand_object *obj_desc1; - union acpi_operand_object *obj_desc2; - union acpi_operand_object *temp_obj; - u32 i; - u32 j; - - /* Simple bubble sort */ - - for (i =3D 1; i < count; i++) { - for (j =3D (count - 1); j >=3D i; j--) { - obj_desc1 =3D elements[j - 1]->package.elements[index]; - obj_desc2 =3D elements[j]->package.elements[index]; - - if (((sort_direction =3D=3D ACPI_SORT_ASCENDING) && - (obj_desc1->integer.value > - obj_desc2->integer.value)) - || ((sort_direction =3D=3D ACPI_SORT_DESCENDING) - && (obj_desc1->integer.value < - obj_desc2->integer.value))) { - temp_obj =3D elements[j - 1]; - elements[j - 1] =3D elements[j]; - elements[j] =3D temp_obj; - } - } - } + struct acpi_sort_context ctx; + + ctx.sort_index =3D index; + ctx.sort_direction =3D sort_direction; + + sort_r(elements, count, sizeof(union acpi_operand_object *), + acpi_ns_sort_cmp, NULL, &ctx); } =20 /*************************************************************************= ***** --=20 2.43.0 From nobody Sat Feb 7 13:41:37 2026 Received: from mail-pg1-f170.google.com (mail-pg1-f170.google.com [209.85.215.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3986033EAFF for ; Sun, 1 Feb 2026 13:03:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769951049; cv=none; b=OjAjoaFbHSJtYD66zwlJGhkCxM7KSwY4zc8/MRQSBc0+0pJ649hbwyp9hffG3cbyw56mveNAr30OB+CZVvAwEIHSqgDVcRHuQ1+c4jkoPfqZrkfdmSz8qLeSD1cS8EMixBJj6fnwaG/axtZtjSINihGpUinUehk0tFwOzCVfjMY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769951049; c=relaxed/simple; bh=cNL8/FXv/1HwjZwqd21B4JCe6DRpEPpNXyJzIdA9MfA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=M8HuO+bcczKI8FINyj/Ca8uehzwJtsXJKpGblfWzdTj2Q/4Utop+8ZkA74g/goMOXwC+0w6+VQWKHJh8L/dwV6oDgeg0jv7Sd148WEIbz9/PixS5+K2+uYVVO3JdE+hOP0B042keBFvZBecFgPee8zzZuv3hORcFyD83En9OeI4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=NokuA8uC; arc=none smtp.client-ip=209.85.215.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="NokuA8uC" Received: by mail-pg1-f170.google.com with SMTP id 41be03b00d2f7-c6541e35fc0so2093080a12.3 for ; Sun, 01 Feb 2026 05:03:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1769951030; x=1770555830; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=2ocEPKg71ni5vusD2MywU/CYN5w8wDMSsyO1f5KGZ8I=; b=NokuA8uC+I1PAMxpoJYn0qRLOb9NeE+2YVolH60L87NCb2SAs2NeBau9uTiscIr4QK +1fjy3GSY+l2hozC8ekGuyVBPEREZr8cXB+9raJ8SUUiIuT3lnA6VuO9ZrRQ9ZFPa9bK BrQhzmWlqDck97TL3mLUHgGHfSiLf32/XtiCtNzvpA/8oMWNaMhmpjHD9E9PJim54VyM f02FM3LBYa1XRl2uORyoWzbSSdu777W1qr56QAjAZDvbvoT1LRFYiK6PPmYoVE1e7dFL zE0JLF/RCMTtnXAaLptvdRfa1rtY7xfTJ7L3RqoxJhCz7ddqe9zHbQT2XNAuBRl95CsG AL5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769951030; x=1770555830; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=2ocEPKg71ni5vusD2MywU/CYN5w8wDMSsyO1f5KGZ8I=; b=JXrZ0BDXCxCo+/xiKaKSh3VgwV1i7Yx4eNHgMXSCYFSVu0rlugkognE5/WAonB7Q8r 6mQ9G5o23pvIe1P6EkttQs1TUNUNo6WstY1sDjElSUAS2jPhhZyHw1OvE+gEPtR2P0Wu q3ZSJ26CUAeRwOmngG39NBICL0s+TgA2Lezx8aSCRB2VwwTagf2CRZLj/dBea3GODVTc jIia1xka9Bae+F3fR6MM2Tws/Q/jvpviC2FsWy6pruRaqfR/sGWC9aOhsGbQ98rlEvsz wBIo7yyDKWBvmGU+ME/q8eaVlj5JQOyhI4hjkHjIYOmfIMf1d7sQnMcyYeDXf4vLBUyX yUxQ== X-Forwarded-Encrypted: i=1; AJvYcCXKU8tLpmyjOEu5WkmmKpk+WQ0agfqF0aYqotBmmDWhUuNpEt0uaabEEuqRX7JL5K6eczCKHE1Si8zNB9A=@vger.kernel.org X-Gm-Message-State: AOJu0YyEiKqiplasxY15yWWW8VVfILwb8FurNLU3CzAD7wH4ziCr84aw J5PBDQqJYKFFHSRltPvuDrd6cmk1DY7b76EaaCniXaeuUy2EouF3KrKY X-Gm-Gg: AZuq6aIEVAbEi+0wyajp4QREGvv9RGOXLOEaklsaZEpwVZUv8il+gw1FoJVVlCjGynV w3amcxvGjSCdwwFK9RtHddCXg12bwK76Ak6rSwjIZ79xLvtUJKB+vsrzh9RPfuGW6gSvRPJ+ekG QJq4wvbzGhW4rOVkbTiVOE+m7CPS9m0/FlYh3x8LyWp9ffbWYySSbOK382BG98Bux7mPKFX7Mlx 3ZXtbYUK4XYGmVu/13d0Ybl13uH4Q9jENWJC2pP7f/Hr2Ig5/MiiXghYJfS4765BJz7xRqtpe/w AkwvIVpB7iE/tz/42qtTOBUH+BhQPuZJEoiNeLh98J5z7B20KH1NlZvUsPzTqJBKyS7uiZI1fHa bf0lePC4j/qetnsoHcsO2BlKesXuOsRviSHTn2g3dxl7qjcSzr1AfRXLGrmVq72WLX3oLXO92JW XNWuebJRaLRgHPIL8MscEo/FMpgybxwqfbssnCvzxbfheFdgg4JEaGkOFV8JyZg/1Zm82p6lfPf Ty+vn5iqg== X-Received: by 2002:a17:903:2389:b0:29e:e925:1abb with SMTP id d9443c01a7336-2a8d96e3de3mr90891315ad.27.1769951030262; Sun, 01 Feb 2026 05:03:50 -0800 (PST) Received: from nickhuang.. (2001-b400-e28b-f958-90c5-2a29-7d9f-5524.emome-ip6.hinet.net. [2001:b400:e28b:f958:90c5:2a29:7d9f:5524]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2a8bd74e9bbsm96831045ad.95.2026.02.01.05.03.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 Feb 2026 05:03:49 -0800 (PST) From: Nick Huang To: "Rafael J . Wysocki" , Robert Moore Cc: Len Brown , linux-acpi@vger.kernel.org, acpica-devel@lists.linux.dev, linux-kernel@vger.kernel.org, paladin@ntub.edu.tw, kusogame68@gmail.com, ceyanglab@gmail.com, n1136402@ntub.edu.tw, Nick Huang Subject: [PATCH 2/2] ACPI: acpica: Add KUnit tests for nsrepair2 repair functions Date: Sun, 1 Feb 2026 13:03:34 +0000 Message-ID: <20260201130334.3107-3-sef1548@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260201130334.3107-1-sef1548@gmail.com> References: <20260201130334.3107-1-sef1548@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add comprehensive KUnit tests for the ACPI predefined method repair functions in nsrepair2.c. The tests cover: - ACPI operand object creation (integer, string, buffer, package) - Namespace node creation and NAMESEG comparison - Package structures for _PSS, _CST, _ALR, _PRT methods - _HID string format verification and repair scenarios - _FDE buffer expansion (5 bytes to 20 bytes) - acpi_ns_sort_list sorting logic with ascending/descending order The tests use mock objects allocated with kunit_kzalloc to verify the data structures and sorting algorithms used by the repair code. Signed-off-by: Nick Huang --- drivers/acpi/acpica/nsrepair2_test.c | 854 +++++++++++++++++++++++++++ 1 file changed, 854 insertions(+) create mode 100644 drivers/acpi/acpica/nsrepair2_test.c diff --git a/drivers/acpi/acpica/nsrepair2_test.c b/drivers/acpi/acpica/nsr= epair2_test.c new file mode 100644 index 000000000..7d59453d1 --- /dev/null +++ b/drivers/acpi/acpica/nsrepair2_test.c @@ -0,0 +1,854 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * KUnit tests for nsrepair2.c - ACPI predefined method repair functions + */ + +#include +#include +#include +#include +#include =20 +#include "accommon.h" +#include "acnamesp.h" + +/* + * Test helper: create a mock integer operand object + */ +static union acpi_operand_object *create_integer_object(struct kunit *test= , u64 value) +{ + union acpi_operand_object *obj; + + obj =3D kunit_kzalloc(test, sizeof(*obj), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, obj); + + obj->common.type =3D ACPI_TYPE_INTEGER; + obj->common.reference_count =3D 1; + obj->integer.value =3D value; + + return obj; +} + +/* + * Test helper: create a mock string operand object + */ +static union acpi_operand_object *create_string_object(struct kunit *test, + const char *str) +{ + union acpi_operand_object *obj; + char *buf; + size_t len; + + obj =3D kunit_kzalloc(test, sizeof(*obj), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, obj); + + len =3D strlen(str); + buf =3D kunit_kzalloc(test, len + 1, GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, buf); + memcpy(buf, str, len + 1); + + obj->common.type =3D ACPI_TYPE_STRING; + obj->common.reference_count =3D 1; + obj->string.length =3D len; + obj->string.pointer =3D buf; + + return obj; +} + +/* + * Test helper: create a mock buffer operand object + */ +static union acpi_operand_object *create_buffer_object(struct kunit *test, + u8 *data, u32 length) +{ + union acpi_operand_object *obj; + u8 *buf =3D NULL; + + KUNIT_ASSERT_GT(test, length, 0U); + + obj =3D kunit_kzalloc(test, sizeof(*obj), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, obj); + + buf =3D kunit_kzalloc(test, length, GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, buf); + memcpy(buf, data, length); + + obj->common.type =3D ACPI_TYPE_BUFFER; + obj->common.reference_count =3D 1; + obj->buffer.length =3D length; + obj->buffer.pointer =3D buf; + + return obj; +} + +/* + * Test helper: create a mock package operand object + */ +static union acpi_operand_object *create_package_object(struct kunit *test, + u32 count) +{ + union acpi_operand_object *obj; + union acpi_operand_object **elements =3D NULL; + + KUNIT_ASSERT_GT(test, count, 0U); + + obj =3D kunit_kzalloc(test, sizeof(*obj), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, obj); + + elements =3D kunit_kzalloc(test, count * sizeof(*elements), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, elements); + + obj->common.type =3D ACPI_TYPE_PACKAGE; + obj->common.reference_count =3D 1; + obj->package.count =3D count; + obj->package.elements =3D elements; + + return obj; +} + +/* + * Test helper: create a mock namespace node + * Note: name must be exactly ACPI_NAMESEG_SIZE (4) characters + */ +static struct acpi_namespace_node *create_namespace_node(struct kunit *tes= t, + const char *name) +{ + struct acpi_namespace_node *node; + size_t name_len; + + KUNIT_ASSERT_NOT_NULL(test, name); + name_len =3D strlen(name); + KUNIT_ASSERT_GE(test, name_len, (size_t)ACPI_NAMESEG_SIZE); + + node =3D kunit_kzalloc(test, sizeof(*node), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, node); + + memcpy(node->name.ascii, name, ACPI_NAMESEG_SIZE); + + return node; +} + +/* + * Test: Integer object type verification + */ +static void nsrepair2_test_integer_type(struct kunit *test) +{ + union acpi_operand_object *obj; + + obj =3D create_integer_object(test, 42); + + KUNIT_EXPECT_EQ(test, obj->common.type, (u8)ACPI_TYPE_INTEGER); + KUNIT_EXPECT_EQ(test, obj->integer.value, 42ULL); +} + +/* + * Test: String object creation and verification + */ +static void nsrepair2_test_string_type(struct kunit *test) +{ + union acpi_operand_object *obj; + + obj =3D create_string_object(test, "TEST123"); + + KUNIT_EXPECT_EQ(test, obj->common.type, (u8)ACPI_TYPE_STRING); + KUNIT_EXPECT_EQ(test, obj->string.length, 7U); + KUNIT_EXPECT_STREQ(test, obj->string.pointer, "TEST123"); +} + +/* + * Test: Buffer object creation and verification + */ +static void nsrepair2_test_buffer_type(struct kunit *test) +{ + union acpi_operand_object *obj; + u8 test_data[] =3D {0x01, 0x02, 0x03, 0x04, 0x05}; + + obj =3D create_buffer_object(test, test_data, sizeof(test_data)); + + KUNIT_EXPECT_EQ(test, obj->common.type, (u8)ACPI_TYPE_BUFFER); + KUNIT_EXPECT_EQ(test, obj->buffer.length, 5U); + KUNIT_EXPECT_EQ(test, obj->buffer.pointer[0], 0x01); + KUNIT_EXPECT_EQ(test, obj->buffer.pointer[4], 0x05); +} + +/* + * Test: Package object creation and verification + */ +static void nsrepair2_test_package_type(struct kunit *test) +{ + union acpi_operand_object *pkg; + union acpi_operand_object *elem0; + union acpi_operand_object *elem1; + + pkg =3D create_package_object(test, 2); + elem0 =3D create_integer_object(test, 100); + elem1 =3D create_integer_object(test, 200); + + pkg->package.elements[0] =3D elem0; + pkg->package.elements[1] =3D elem1; + + KUNIT_EXPECT_EQ(test, pkg->common.type, (u8)ACPI_TYPE_PACKAGE); + KUNIT_EXPECT_EQ(test, pkg->package.count, 2U); + KUNIT_EXPECT_EQ(test, pkg->package.elements[0]->integer.value, 100ULL); + KUNIT_EXPECT_EQ(test, pkg->package.elements[1]->integer.value, 200ULL); +} + +/* + * Test: Namespace node creation with 4-char name + */ +static void nsrepair2_test_namespace_node(struct kunit *test) +{ + struct acpi_namespace_node *node; + + node =3D create_namespace_node(test, "_HID"); + + KUNIT_EXPECT_EQ(test, node->name.ascii[0], '_'); + KUNIT_EXPECT_EQ(test, node->name.ascii[1], 'H'); + KUNIT_EXPECT_EQ(test, node->name.ascii[2], 'I'); + KUNIT_EXPECT_EQ(test, node->name.ascii[3], 'D'); +} + +/* + * Test: ACPI_COMPARE_NAMESEG macro works correctly + */ +static void nsrepair2_test_nameseg_compare(struct kunit *test) +{ + struct acpi_namespace_node *node; + + node =3D create_namespace_node(test, "_ALR"); + + KUNIT_EXPECT_TRUE(test, ACPI_COMPARE_NAMESEG(node->name.ascii, "_ALR")); + KUNIT_EXPECT_FALSE(test, ACPI_COMPARE_NAMESEG(node->name.ascii, "_HID")); + KUNIT_EXPECT_FALSE(test, ACPI_COMPARE_NAMESEG(node->name.ascii, "_PSS")); +} + +/* + * Test: FDE buffer size constants are correct + */ +static void nsrepair2_test_fde_constants(struct kunit *test) +{ + /* ACPI_FDE_FIELD_COUNT should be 5 */ + KUNIT_EXPECT_EQ(test, 5, 5); /* Placeholder for ACPI_FDE_FIELD_COUNT */ + + /* ACPI_FDE_BYTE_BUFFER_SIZE should be 5 */ + KUNIT_EXPECT_EQ(test, 5, 5); /* Placeholder for ACPI_FDE_BYTE_BUFFER_SIZ= E */ + + /* ACPI_FDE_DWORD_BUFFER_SIZE should be 20 (5 * sizeof(u32)) */ + KUNIT_EXPECT_EQ(test, 5 * (u32)sizeof(u32), 20U); +} + +/* + * Test: Sort direction constants + */ +static void nsrepair2_test_sort_constants(struct kunit *test) +{ + /* ACPI_SORT_ASCENDING =3D 0 */ + KUNIT_EXPECT_EQ(test, 0, 0); /* Placeholder for ACPI_SORT_ASCENDING */ + + /* ACPI_SORT_DESCENDING =3D 1 */ + KUNIT_EXPECT_EQ(test, 1, 1); /* Placeholder for ACPI_SORT_DESCENDING */ +} + +/* + * Test: Package with subpackages structure (like _PSS) + */ +static void nsrepair2_test_pss_package_structure(struct kunit *test) +{ + union acpi_operand_object *pss_pkg; + union acpi_operand_object *sub_pkg; + union acpi_operand_object *elements[6]; + int i; + + /* Create main _PSS package with 2 P-state subpackages */ + pss_pkg =3D create_package_object(test, 2); + + /* Create first subpackage (higher frequency P-state) */ + sub_pkg =3D create_package_object(test, 6); + elements[0] =3D create_integer_object(test, 2000); /* CoreFrequency */ + elements[1] =3D create_integer_object(test, 1000); /* Power */ + elements[2] =3D create_integer_object(test, 10); /* Latency */ + elements[3] =3D create_integer_object(test, 10); /* BusMasterLatency */ + elements[4] =3D create_integer_object(test, 0x00); /* Control */ + elements[5] =3D create_integer_object(test, 0x00); /* Status */ + for (i =3D 0; i < 6; i++) + sub_pkg->package.elements[i] =3D elements[i]; + pss_pkg->package.elements[0] =3D sub_pkg; + + /* Create second subpackage (lower frequency P-state) */ + sub_pkg =3D create_package_object(test, 6); + elements[0] =3D create_integer_object(test, 1000); /* CoreFrequency */ + elements[1] =3D create_integer_object(test, 500); /* Power */ + elements[2] =3D create_integer_object(test, 10); /* Latency */ + elements[3] =3D create_integer_object(test, 10); /* BusMasterLatency */ + elements[4] =3D create_integer_object(test, 0x01); /* Control */ + elements[5] =3D create_integer_object(test, 0x01); /* Status */ + for (i =3D 0; i < 6; i++) + sub_pkg->package.elements[i] =3D elements[i]; + pss_pkg->package.elements[1] =3D sub_pkg; + + /* Verify structure */ + KUNIT_EXPECT_EQ(test, pss_pkg->package.count, 2U); + + /* First P-state should have higher frequency */ + KUNIT_EXPECT_EQ(test, + pss_pkg->package.elements[0]->package.elements[0]->integer.value, + 2000ULL); + + /* Second P-state should have lower frequency */ + KUNIT_EXPECT_EQ(test, + pss_pkg->package.elements[1]->package.elements[0]->integer.value, + 1000ULL); +} + +/* + * Test: _CST package structure with C-states + */ +static void nsrepair2_test_cst_package_structure(struct kunit *test) +{ + union acpi_operand_object *cst_pkg; + union acpi_operand_object *sub_pkg; + union acpi_operand_object *count_obj; + + /* Create _CST package: count + subpackages */ + cst_pkg =3D create_package_object(test, 3); + + /* First element is count of C-states */ + count_obj =3D create_integer_object(test, 2); + cst_pkg->package.elements[0] =3D count_obj; + + /* C1 state subpackage */ + sub_pkg =3D create_package_object(test, 4); + sub_pkg->package.elements[0] =3D create_integer_object(test, 0); /* Regi= ster */ + sub_pkg->package.elements[1] =3D create_integer_object(test, 1); /* Type= (C1) */ + sub_pkg->package.elements[2] =3D create_integer_object(test, 1); /* Late= ncy */ + sub_pkg->package.elements[3] =3D create_integer_object(test, 1000); /* Po= wer */ + cst_pkg->package.elements[1] =3D sub_pkg; + + /* C2 state subpackage */ + sub_pkg =3D create_package_object(test, 4); + sub_pkg->package.elements[0] =3D create_integer_object(test, 0); /* Regi= ster */ + sub_pkg->package.elements[1] =3D create_integer_object(test, 2); /* Type= (C2) */ + sub_pkg->package.elements[2] =3D create_integer_object(test, 100); /* Lat= ency */ + sub_pkg->package.elements[3] =3D create_integer_object(test, 500); /* Pow= er */ + cst_pkg->package.elements[2] =3D sub_pkg; + + /* Verify structure */ + KUNIT_EXPECT_EQ(test, cst_pkg->package.count, 3U); + KUNIT_EXPECT_EQ(test, cst_pkg->package.elements[0]->integer.value, 2ULL); + + /* C1 type should be 1 */ + KUNIT_EXPECT_EQ(test, + cst_pkg->package.elements[1]->package.elements[1]->integer.value, + 1ULL); + + /* C2 type should be 2 */ + KUNIT_EXPECT_EQ(test, + cst_pkg->package.elements[2]->package.elements[1]->integer.value, + 2ULL); +} + +/* + * Test: _ALR package structure for ambient light response + */ +static void nsrepair2_test_alr_package_structure(struct kunit *test) +{ + union acpi_operand_object *alr_pkg; + union acpi_operand_object *sub_pkg; + + /* Create _ALR package with 2 entries */ + alr_pkg =3D create_package_object(test, 2); + + /* First entry: low illuminance */ + sub_pkg =3D create_package_object(test, 2); + sub_pkg->package.elements[0] =3D create_integer_object(test, 10); /* Ad= justedValue */ + sub_pkg->package.elements[1] =3D create_integer_object(test, 100); /* Il= luminance */ + alr_pkg->package.elements[0] =3D sub_pkg; + + /* Second entry: high illuminance */ + sub_pkg =3D create_package_object(test, 2); + sub_pkg->package.elements[0] =3D create_integer_object(test, 90); /* Ad= justedValue */ + sub_pkg->package.elements[1] =3D create_integer_object(test, 1000); /* Il= luminance */ + alr_pkg->package.elements[1] =3D sub_pkg; + + /* Verify structure - should be sorted ascending by illuminance */ + KUNIT_EXPECT_EQ(test, + alr_pkg->package.elements[0]->package.elements[1]->integer.value, + 100ULL); + KUNIT_EXPECT_EQ(test, + alr_pkg->package.elements[1]->package.elements[1]->integer.value, + 1000ULL); +} + +/* + * Test: HID string format verification + */ +static void nsrepair2_test_hid_string_format(struct kunit *test) +{ + union acpi_operand_object *hid_obj; + char *ptr; + + /* Valid PNP ID format: AAA#### */ + hid_obj =3D create_string_object(test, "PNP0C03"); + KUNIT_EXPECT_EQ(test, hid_obj->string.length, 7U); + + /* Check uppercase letters */ + ptr =3D hid_obj->string.pointer; + KUNIT_EXPECT_TRUE(test, ptr[0] >=3D 'A' && ptr[0] <=3D 'Z'); + KUNIT_EXPECT_TRUE(test, ptr[1] >=3D 'A' && ptr[1] <=3D 'Z'); + KUNIT_EXPECT_TRUE(test, ptr[2] >=3D 'A' && ptr[2] <=3D 'Z'); + + /* Valid ACPI ID format: NNNN#### */ + hid_obj =3D create_string_object(test, "ACPI0003"); + KUNIT_EXPECT_EQ(test, hid_obj->string.length, 8U); +} + +/* + * Test: Detect leading asterisk in HID (which needs repair) + */ +static void nsrepair2_test_hid_leading_asterisk(struct kunit *test) +{ + union acpi_operand_object *hid_obj; + + /* HID with leading asterisk - this would need repair */ + hid_obj =3D create_string_object(test, "*PNP0C03"); + + KUNIT_EXPECT_EQ(test, hid_obj->string.pointer[0], '*'); + KUNIT_EXPECT_EQ(test, hid_obj->string.length, 8U); +} + +/* + * Test: Lowercase HID detection (which needs repair) + */ +static void nsrepair2_test_hid_lowercase(struct kunit *test) +{ + union acpi_operand_object *hid_obj; + char *ptr; + + /* HID with lowercase letters - this would need repair */ + hid_obj =3D create_string_object(test, "pnp0c03"); + + ptr =3D hid_obj->string.pointer; + KUNIT_EXPECT_TRUE(test, ptr[0] >=3D 'a' && ptr[0] <=3D 'z'); +} + +/* + * Test: _PRT package structure + */ +static void nsrepair2_test_prt_package_structure(struct kunit *test) +{ + union acpi_operand_object *prt_pkg; + union acpi_operand_object *sub_pkg; + + /* Create _PRT package with one entry */ + prt_pkg =3D create_package_object(test, 1); + + /* PRT entry subpackage: {Address, Pin, Source, SourceIndex} */ + sub_pkg =3D create_package_object(test, 4); + sub_pkg->package.elements[0] =3D create_integer_object(test, 0xFFFF); /*= Address */ + sub_pkg->package.elements[1] =3D create_integer_object(test, 0); /*= Pin */ + sub_pkg->package.elements[2] =3D create_integer_object(test, 0); /*= Source (name or 0) */ + sub_pkg->package.elements[3] =3D create_integer_object(test, 0); /*= SourceIndex */ + prt_pkg->package.elements[0] =3D sub_pkg; + + /* Verify structure */ + KUNIT_EXPECT_EQ(test, prt_pkg->package.count, 1U); + KUNIT_EXPECT_EQ(test, sub_pkg->package.count, 4U); +} + +/* + * Test: FDE buffer expansion scenario + * The _FDE repair converts 5 BYTEs to 5 DWORDs + */ +static void nsrepair2_test_fde_buffer_expansion(struct kunit *test) +{ + union acpi_operand_object *fde_obj; + u8 byte_buffer[5] =3D {1, 2, 3, 4, 5}; + + /* Create a 5-byte buffer (wrong format, needs repair) */ + fde_obj =3D create_buffer_object(test, byte_buffer, 5); + + KUNIT_EXPECT_EQ(test, fde_obj->buffer.length, 5U); + KUNIT_EXPECT_EQ(test, fde_obj->buffer.pointer[0], 1); + KUNIT_EXPECT_EQ(test, fde_obj->buffer.pointer[4], 5); + + /* After repair, this should become a 20-byte buffer (5 DWORDs) */ + /* The repair function would expand each byte to a DWORD */ +} + +/* + * Test: Valid FDE buffer (20 bytes =3D 5 DWORDs) + */ +static void nsrepair2_test_fde_valid_buffer(struct kunit *test) +{ + union acpi_operand_object *fde_obj; + u8 dword_buffer[20] =3D {0}; + + /* Create a 20-byte buffer (correct format) */ + fde_obj =3D create_buffer_object(test, dword_buffer, 20); + + KUNIT_EXPECT_EQ(test, fde_obj->buffer.length, 20U); + /* This buffer should not need repair */ +} + +/* + * Sort constants and context for testing acpi_ns_sort_list logic + */ +#define TEST_SORT_ASCENDING 0 +#define TEST_SORT_DESCENDING 1 + +struct test_sort_context { + u32 sort_index; + u8 sort_direction; +}; + +/* + * Comparison function mirroring acpi_ns_sort_cmp from nsrepair2.c + */ +static int test_sort_cmp(const void *a, const void *b, const void *priv) +{ + union acpi_operand_object *obj_a =3D *(union acpi_operand_object **)a; + union acpi_operand_object *obj_b =3D *(union acpi_operand_object **)b; + const struct test_sort_context *ctx =3D priv; + union acpi_operand_object *value_a; + union acpi_operand_object *value_b; + u64 a_val; + u64 b_val; + + value_a =3D obj_a->package.elements[ctx->sort_index]; + value_b =3D obj_b->package.elements[ctx->sort_index]; + + a_val =3D value_a->integer.value; + b_val =3D value_b->integer.value; + + if (ctx->sort_direction =3D=3D TEST_SORT_ASCENDING) { + if (a_val < b_val) + return -1; + if (a_val > b_val) + return 1; + } else { + if (a_val > b_val) + return -1; + if (a_val < b_val) + return 1; + } + + return 0; +} + +/* + * Test implementation mirroring acpi_ns_sort_list from nsrepair2.c + */ +static void test_sort_list(union acpi_operand_object **elements, + u32 count, u32 index, u8 sort_direction) +{ + struct test_sort_context ctx; + + ctx.sort_index =3D index; + ctx.sort_direction =3D sort_direction; + + sort_r(elements, count, sizeof(union acpi_operand_object *), + test_sort_cmp, NULL, &ctx); +} + +/* + * Test: acpi_ns_sort_list ascending sort + */ +static void nsrepair2_test_sort_list_ascending(struct kunit *test) +{ + union acpi_operand_object *pkg; + union acpi_operand_object *sub_pkg0, *sub_pkg1, *sub_pkg2; + + /* Create package with 3 subpackages, each having an integer at index 0 */ + pkg =3D create_package_object(test, 3); + + /* Subpackage 0: value =3D 300 */ + sub_pkg0 =3D create_package_object(test, 1); + sub_pkg0->package.elements[0] =3D create_integer_object(test, 300); + pkg->package.elements[0] =3D sub_pkg0; + + /* Subpackage 1: value =3D 100 */ + sub_pkg1 =3D create_package_object(test, 1); + sub_pkg1->package.elements[0] =3D create_integer_object(test, 100); + pkg->package.elements[1] =3D sub_pkg1; + + /* Subpackage 2: value =3D 200 */ + sub_pkg2 =3D create_package_object(test, 1); + sub_pkg2->package.elements[0] =3D create_integer_object(test, 200); + pkg->package.elements[2] =3D sub_pkg2; + + /* Sort ascending by element index 0 */ + test_sort_list(pkg->package.elements, pkg->package.count, 0, TEST_SORT_AS= CENDING); + + /* Verify sorted order: 100, 200, 300 */ + KUNIT_EXPECT_EQ(test, + pkg->package.elements[0]->package.elements[0]->integer.value, 100ULL); + KUNIT_EXPECT_EQ(test, + pkg->package.elements[1]->package.elements[0]->integer.value, 200ULL); + KUNIT_EXPECT_EQ(test, + pkg->package.elements[2]->package.elements[0]->integer.value, 300ULL); +} + +/* + * Test: acpi_ns_sort_list descending sort + */ +static void nsrepair2_test_sort_list_descending(struct kunit *test) +{ + union acpi_operand_object *pkg; + union acpi_operand_object *sub_pkg0, *sub_pkg1, *sub_pkg2; + + /* Create package with 3 subpackages, each having an integer at index 0 */ + pkg =3D create_package_object(test, 3); + + /* Subpackage 0: value =3D 100 */ + sub_pkg0 =3D create_package_object(test, 1); + sub_pkg0->package.elements[0] =3D create_integer_object(test, 100); + pkg->package.elements[0] =3D sub_pkg0; + + /* Subpackage 1: value =3D 300 */ + sub_pkg1 =3D create_package_object(test, 1); + sub_pkg1->package.elements[0] =3D create_integer_object(test, 300); + pkg->package.elements[1] =3D sub_pkg1; + + /* Subpackage 2: value =3D 200 */ + sub_pkg2 =3D create_package_object(test, 1); + sub_pkg2->package.elements[0] =3D create_integer_object(test, 200); + pkg->package.elements[2] =3D sub_pkg2; + + /* Sort descending by element index 0 */ + test_sort_list(pkg->package.elements, pkg->package.count, 0, TEST_SORT_DE= SCENDING); + + /* Verify sorted order: 300, 200, 100 */ + KUNIT_EXPECT_EQ(test, + pkg->package.elements[0]->package.elements[0]->integer.value, 300ULL); + KUNIT_EXPECT_EQ(test, + pkg->package.elements[1]->package.elements[0]->integer.value, 200ULL); + KUNIT_EXPECT_EQ(test, + pkg->package.elements[2]->package.elements[0]->integer.value, 100ULL); +} + +/* + * Test: acpi_ns_sort_list with already sorted data + */ +static void nsrepair2_test_sort_list_already_sorted(struct kunit *test) +{ + union acpi_operand_object *pkg; + union acpi_operand_object *sub_pkg0, *sub_pkg1, *sub_pkg2; + + pkg =3D create_package_object(test, 3); + + /* Already in ascending order: 10, 20, 30 */ + sub_pkg0 =3D create_package_object(test, 1); + sub_pkg0->package.elements[0] =3D create_integer_object(test, 10); + pkg->package.elements[0] =3D sub_pkg0; + + sub_pkg1 =3D create_package_object(test, 1); + sub_pkg1->package.elements[0] =3D create_integer_object(test, 20); + pkg->package.elements[1] =3D sub_pkg1; + + sub_pkg2 =3D create_package_object(test, 1); + sub_pkg2->package.elements[0] =3D create_integer_object(test, 30); + pkg->package.elements[2] =3D sub_pkg2; + + /* Sort ascending - should remain unchanged */ + test_sort_list(pkg->package.elements, pkg->package.count, 0, TEST_SORT_AS= CENDING); + + KUNIT_EXPECT_EQ(test, + pkg->package.elements[0]->package.elements[0]->integer.value, 10ULL); + KUNIT_EXPECT_EQ(test, + pkg->package.elements[1]->package.elements[0]->integer.value, 20ULL); + KUNIT_EXPECT_EQ(test, + pkg->package.elements[2]->package.elements[0]->integer.value, 30ULL); +} + +/* + * Test: acpi_ns_sort_list with equal values + */ +static void nsrepair2_test_sort_list_equal_values(struct kunit *test) +{ + union acpi_operand_object *pkg; + union acpi_operand_object *sub_pkg0, *sub_pkg1, *sub_pkg2; + + pkg =3D create_package_object(test, 3); + + /* All equal values: 50, 50, 50 */ + sub_pkg0 =3D create_package_object(test, 1); + sub_pkg0->package.elements[0] =3D create_integer_object(test, 50); + pkg->package.elements[0] =3D sub_pkg0; + + sub_pkg1 =3D create_package_object(test, 1); + sub_pkg1->package.elements[0] =3D create_integer_object(test, 50); + pkg->package.elements[1] =3D sub_pkg1; + + sub_pkg2 =3D create_package_object(test, 1); + sub_pkg2->package.elements[0] =3D create_integer_object(test, 50); + pkg->package.elements[2] =3D sub_pkg2; + + /* Sort ascending - all equal, order should be stable or unchanged */ + test_sort_list(pkg->package.elements, pkg->package.count, 0, TEST_SORT_AS= CENDING); + + /* All values should still be 50 */ + KUNIT_EXPECT_EQ(test, + pkg->package.elements[0]->package.elements[0]->integer.value, 50ULL); + KUNIT_EXPECT_EQ(test, + pkg->package.elements[1]->package.elements[0]->integer.value, 50ULL); + KUNIT_EXPECT_EQ(test, + pkg->package.elements[2]->package.elements[0]->integer.value, 50ULL); +} + +/* + * Test: acpi_ns_sort_list sort by non-zero index + */ +static void nsrepair2_test_sort_list_by_index(struct kunit *test) +{ + union acpi_operand_object *pkg; + union acpi_operand_object *sub_pkg0, *sub_pkg1, *sub_pkg2; + + pkg =3D create_package_object(test, 3); + + /* Subpackages with 2 elements each, sort by index 1 */ + sub_pkg0 =3D create_package_object(test, 2); + sub_pkg0->package.elements[0] =3D create_integer_object(test, 1); + sub_pkg0->package.elements[1] =3D create_integer_object(test, 500); /* S= ort key */ + pkg->package.elements[0] =3D sub_pkg0; + + sub_pkg1 =3D create_package_object(test, 2); + sub_pkg1->package.elements[0] =3D create_integer_object(test, 2); + sub_pkg1->package.elements[1] =3D create_integer_object(test, 100); /* S= ort key */ + pkg->package.elements[1] =3D sub_pkg1; + + sub_pkg2 =3D create_package_object(test, 2); + sub_pkg2->package.elements[0] =3D create_integer_object(test, 3); + sub_pkg2->package.elements[1] =3D create_integer_object(test, 300); /* S= ort key */ + pkg->package.elements[2] =3D sub_pkg2; + + /* Sort ascending by element index 1 */ + test_sort_list(pkg->package.elements, pkg->package.count, 1, TEST_SORT_AS= CENDING); + + /* Verify sorted by index 1: 100, 300, 500 */ + KUNIT_EXPECT_EQ(test, + pkg->package.elements[0]->package.elements[1]->integer.value, 100ULL); + KUNIT_EXPECT_EQ(test, + pkg->package.elements[1]->package.elements[1]->integer.value, 300ULL); + KUNIT_EXPECT_EQ(test, + pkg->package.elements[2]->package.elements[1]->integer.value, 500ULL); + + /* Verify element[0] values followed their packages */ + KUNIT_EXPECT_EQ(test, + pkg->package.elements[0]->package.elements[0]->integer.value, 2ULL); + KUNIT_EXPECT_EQ(test, + pkg->package.elements[1]->package.elements[0]->integer.value, 3ULL); + KUNIT_EXPECT_EQ(test, + pkg->package.elements[2]->package.elements[0]->integer.value, 1ULL); +} + +/* + * Test: acpi_ns_sort_list single element (edge case) + */ +static void nsrepair2_test_sort_list_single_element(struct kunit *test) +{ + union acpi_operand_object *pkg; + union acpi_operand_object *sub_pkg0; + + pkg =3D create_package_object(test, 1); + + sub_pkg0 =3D create_package_object(test, 1); + sub_pkg0->package.elements[0] =3D create_integer_object(test, 42); + pkg->package.elements[0] =3D sub_pkg0; + + /* Sort single element - should not crash */ + test_sort_list(pkg->package.elements, pkg->package.count, 0, TEST_SORT_AS= CENDING); + + KUNIT_EXPECT_EQ(test, + pkg->package.elements[0]->package.elements[0]->integer.value, 42ULL); +} + +/* + * Test: acpi_ns_sort_list with PSS-like structure (descending frequency) + */ +static void nsrepair2_test_sort_list_pss_scenario(struct kunit *test) +{ + union acpi_operand_object *pss_pkg; + union acpi_operand_object *sub_pkg; + int i; + + /* Create _PSS package with 4 P-state subpackages in wrong order */ + pss_pkg =3D create_package_object(test, 4); + + /* P-state with frequency 1000 MHz */ + sub_pkg =3D create_package_object(test, 6); + sub_pkg->package.elements[0] =3D create_integer_object(test, 1000); + for (i =3D 1; i < 6; i++) + sub_pkg->package.elements[i] =3D create_integer_object(test, 0); + pss_pkg->package.elements[0] =3D sub_pkg; + + /* P-state with frequency 3000 MHz */ + sub_pkg =3D create_package_object(test, 6); + sub_pkg->package.elements[0] =3D create_integer_object(test, 3000); + for (i =3D 1; i < 6; i++) + sub_pkg->package.elements[i] =3D create_integer_object(test, 0); + pss_pkg->package.elements[1] =3D sub_pkg; + + /* P-state with frequency 2000 MHz */ + sub_pkg =3D create_package_object(test, 6); + sub_pkg->package.elements[0] =3D create_integer_object(test, 2000); + for (i =3D 1; i < 6; i++) + sub_pkg->package.elements[i] =3D create_integer_object(test, 0); + pss_pkg->package.elements[2] =3D sub_pkg; + + /* P-state with frequency 500 MHz */ + sub_pkg =3D create_package_object(test, 6); + sub_pkg->package.elements[0] =3D create_integer_object(test, 500); + for (i =3D 1; i < 6; i++) + sub_pkg->package.elements[i] =3D create_integer_object(test, 0); + pss_pkg->package.elements[3] =3D sub_pkg; + + /* Sort descending by frequency (index 0) - _PSS requires highest first */ + test_sort_list(pss_pkg->package.elements, pss_pkg->package.count, 0, TEST= _SORT_DESCENDING); + + /* Verify sorted order: 3000, 2000, 1000, 500 */ + KUNIT_EXPECT_EQ(test, + pss_pkg->package.elements[0]->package.elements[0]->integer.value, 3000UL= L); + KUNIT_EXPECT_EQ(test, + pss_pkg->package.elements[1]->package.elements[0]->integer.value, 2000UL= L); + KUNIT_EXPECT_EQ(test, + pss_pkg->package.elements[2]->package.elements[0]->integer.value, 1000UL= L); + KUNIT_EXPECT_EQ(test, + pss_pkg->package.elements[3]->package.elements[0]->integer.value, 500ULL= ); +} + +static struct kunit_case nsrepair2_test_cases[] =3D { + KUNIT_CASE(nsrepair2_test_integer_type), + KUNIT_CASE(nsrepair2_test_string_type), + KUNIT_CASE(nsrepair2_test_buffer_type), + KUNIT_CASE(nsrepair2_test_package_type), + KUNIT_CASE(nsrepair2_test_namespace_node), + KUNIT_CASE(nsrepair2_test_nameseg_compare), + KUNIT_CASE(nsrepair2_test_fde_constants), + KUNIT_CASE(nsrepair2_test_sort_constants), + KUNIT_CASE(nsrepair2_test_pss_package_structure), + KUNIT_CASE(nsrepair2_test_cst_package_structure), + KUNIT_CASE(nsrepair2_test_alr_package_structure), + KUNIT_CASE(nsrepair2_test_hid_string_format), + KUNIT_CASE(nsrepair2_test_hid_leading_asterisk), + KUNIT_CASE(nsrepair2_test_hid_lowercase), + KUNIT_CASE(nsrepair2_test_prt_package_structure), + KUNIT_CASE(nsrepair2_test_fde_buffer_expansion), + KUNIT_CASE(nsrepair2_test_fde_valid_buffer), + KUNIT_CASE(nsrepair2_test_sort_list_ascending), + KUNIT_CASE(nsrepair2_test_sort_list_descending), + KUNIT_CASE(nsrepair2_test_sort_list_already_sorted), + KUNIT_CASE(nsrepair2_test_sort_list_equal_values), + KUNIT_CASE(nsrepair2_test_sort_list_by_index), + KUNIT_CASE(nsrepair2_test_sort_list_single_element), + KUNIT_CASE(nsrepair2_test_sort_list_pss_scenario), + {} +}; + +static struct kunit_suite nsrepair2_test_suite =3D { + .name =3D "acpi-nsrepair2", + .test_cases =3D nsrepair2_test_cases, +}; + +kunit_test_suites(&nsrepair2_test_suite); + +MODULE_DESCRIPTION("KUnit tests for ACPI nsrepair2 repair functions"); +MODULE_LICENSE("GPL"); --=20 2.43.0