From nobody Sun Apr 5 13:20:39 2026 Received: from mail-106120.protonmail.ch (mail-106120.protonmail.ch [79.135.106.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 244BC344DAA for ; Fri, 20 Feb 2026 12:49:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=79.135.106.120 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771591755; cv=none; b=Kf1ncdEby57tgi3T/T40b99rp09aZlXhZ8a+tbUcCNc+hWZZXYr19WibICN4wYelFa0uBB6t1DiDeN9fwzem0EyATbbtDGaipSJJ0kWnwj2sqok6Kuz7M/JLvjxHc+bxNA9wpPpmmHOjnwdeRLKs5eAM9QGOeXfbSemR0fgEz5s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771591755; c=relaxed/simple; bh=Key36d9CQNDC2jdXVq+xiTTel29uUeOXeIWgO+AuEUM=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=MF6J/GFLJtcaxcao0WzhJkF+4MuDbq/qXevXinxWpYAZhLvuygX6kLx34FhtwGcz2u1xCE6Ft5wmsFu4AC0KMH0vFLouE+ov5nHrrewBWOyJBKHe3ERMzJYMesoOFHlpMqF1NGuA36L+ZL3Q/kfQGEeXCskRfzMGad4jXVLNza4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me; spf=pass smtp.mailfrom=pm.me; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b=LLvUpuPR; arc=none smtp.client-ip=79.135.106.120 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pm.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b="LLvUpuPR" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1771591751; x=1771850951; bh=TOcZfslwyOLnqfStp7w1Zf0CKilK3beX2XrqjjIDxw4=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=LLvUpuPRtmw8ZnCiefPGWoDUT1Q/+TAKNXLz3ErxU0c1r1vBYz+nRxyzxqDSZ/W3u Jpr0Ox6KLC1k5WWq4pR/g+lFUbsmkEy5e182ZBSN4kIb1KJjRkJw97aQYko3KEXmI8 Yiwo7YziEU4755+lLMtNJRe2itocjkRGQrvybJECNTxPKobz9PP27oZlyyMosw3Gz5 4T9q6FZLm7FifHDuKav8au3KkvvrpuQAppIYVZ+InxEQngf4DlT9V8iWDkkokKn41D zUJPeAbcoJqhGC9j+p/aI9oZd7dsBWdFOWVX29fpiq3WjJg44AEDq8E0NmKO12q5Ln Rnkhu9RKU1SdA== Date: Fri, 20 Feb 2026 12:49:01 +0000 To: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Shuah Khan From: Maciej Wieczor-Retman Cc: m.wieczorretman@pm.me, Maciej Wieczor-Retman , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH v1 4/4] selftests/lam: Add test cases for different LAM tag widths Message-ID: <8b604b5ec11051437940fb0537ab4c2ed6bb5bb4.1771589807.git.m.wieczorretman@pm.me> In-Reply-To: References: Feedback-ID: 164464600:user:proton X-Pm-Message-ID: 26fbcd654c44720f93558be50b48fe99bae1ef41 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" From: Maciej Wieczor-Retman After the default tag width in LAM (Linear Address Masking) is set to 4 bits, it's still possible to enable 6 bit wide tags for debug purposes through debugfs. When a program enables LAM, it should be able to, through a syscall, request a number of tag bits equal or smaller to the one used system wide. If it requests a smaller one it should receive the system wide setting anyway. Change the default tag width. Add four tests to check all combinations of tag width requests. Modify the existing test infrastructure to check with a syscall what the needed tag width actually is. Signed-off-by: Maciej Wieczor-Retman --- tools/testing/selftests/x86/lam.c | 87 ++++++++++++++++++++++++++----- 1 file changed, 74 insertions(+), 13 deletions(-) diff --git a/tools/testing/selftests/x86/lam.c b/tools/testing/selftests/x8= 6/lam.c index 1919fa6daec0..9ed2964082eb 100644 --- a/tools/testing/selftests/x86/lam.c +++ b/tools/testing/selftests/x86/lam.c @@ -26,9 +26,11 @@ =20 /* LAM modes, these definitions were copied from kernel code */ #define LAM_NONE 0 -#define LAM_U57_BITS 6 +#define LAM_U57_BITS 4 +#define LAM_MAX_BITS 6 =20 -#define LAM_U57_MASK (0x3fULL << 57) +#define LAM_U57_MASK (0xfULL << 57) +#define LAM_MAX_MASK (0x3fULL << 57) /* arch prctl for LAM */ #define ARCH_GET_UNTAG_MASK 0x4001 #define ARCH_ENABLE_TAGGED_ADDR 0x4002 @@ -175,7 +177,7 @@ static int set_lam(unsigned long lam) int ret =3D 0; uint64_t ptr =3D 0; =20 - if (lam !=3D LAM_U57_BITS && lam !=3D LAM_NONE) + if (lam !=3D LAM_U57_BITS && lam !=3D LAM_MAX_BITS && lam !=3D LAM_NONE) return -1; =20 /* Skip check return */ @@ -184,16 +186,21 @@ static int set_lam(unsigned long lam) /* Get untagged mask */ syscall(SYS_arch_prctl, ARCH_GET_UNTAG_MASK, &ptr); =20 + /* Update lam in case lam6 is enabled */ + syscall(SYS_arch_prctl, ARCH_GET_MAX_TAG_BITS, &lam); + /* Check mask returned is expected */ if (lam =3D=3D LAM_U57_BITS) ret =3D (ptr !=3D ~(LAM_U57_MASK)); + else if (lam =3D=3D LAM_MAX_BITS) + ret =3D (ptr !=3D ~(LAM_MAX_MASK)); else if (lam =3D=3D LAM_NONE) ret =3D (ptr !=3D -1ULL); =20 return ret; } =20 -static unsigned long get_default_tag_bits(void) +static unsigned long get_default_tag_bits(int bits) { pid_t pid; int lam =3D LAM_NONE; @@ -204,8 +211,8 @@ static unsigned long get_default_tag_bits(void) perror("Fork failed."); } else if (pid =3D=3D 0) { /* Set LAM mode in child process */ - if (set_lam(LAM_U57_BITS) =3D=3D 0) - lam =3D LAM_U57_BITS; + if (set_lam(bits) =3D=3D 0) + syscall(SYS_arch_prctl, ARCH_GET_MAX_TAG_BITS, &lam); else lam =3D LAM_NONE; exit(lam); @@ -217,6 +224,27 @@ static unsigned long get_default_tag_bits(void) return lam; } =20 +static int change_lam_width(unsigned char width) +{ + char buf[2]; + int ret, fd; + + snprintf(buf, sizeof(buf), "%u", width); + fd =3D open("/sys/kernel/debug/x86/lam_available_bits", O_WRONLY); + if (fd < 0) { + ksft_print_msg("lam_available_bits debug file not found!\n"); + return fd; + } + + ret =3D write(fd, buf, sizeof(buf)); + if (ret < 0) + return ret; + + close(fd); + + return 0; +} + /* * Set tagged address and read back untag mask. * check if the untag mask is expected. @@ -284,20 +312,32 @@ static int handle_lam_test(void *src, unsigned int la= m) return (!!strcmp((char *)src, (char *)ptr)); } =20 - int handle_max_bits(struct testcases *test) { - unsigned long exp_bits =3D get_default_tag_bits(); - unsigned long bits =3D 0; + unsigned long exp_bits, bits =3D 0; + int ret =3D 1; =20 - if (exp_bits !=3D LAM_NONE) - exp_bits =3D LAM_U57_BITS; + if (test->later) { + ret =3D change_lam_width(LAM_MAX_BITS); + if (ret) + return ret; + } + + exp_bits =3D get_default_tag_bits(test->lam); =20 /* Get LAM max tag bits */ if (syscall(SYS_arch_prctl, ARCH_GET_MAX_TAG_BITS, &bits) =3D=3D -1) - return 1; + goto out; =20 - return (exp_bits !=3D bits); + ret =3D exp_bits !=3D bits; +out: + if (test->later) { + ret =3D change_lam_width(LAM_U57_BITS); + if (ret) + return ret; + } + + return ret; } =20 /* @@ -968,9 +1008,30 @@ static struct testcases malloc_cases[] =3D { =20 static struct testcases bits_cases[] =3D { { + .later =3D 0, + .lam =3D LAM_U57_BITS, .test_func =3D handle_max_bits, .msg =3D "BITS: Check default tag bits\n", }, + { + .later =3D 1, + .lam =3D LAM_U57_BITS, + .test_func =3D handle_max_bits, + .msg =3D "BITS: Check if 4 bits can be requested in 6 bit mode.\n", + }, + { + .later =3D 0, + .expected =3D 1, + .lam =3D LAM_MAX_BITS, + .test_func =3D handle_max_bits, + .msg =3D "BITS:[Negative] Check if 6 bits can be requested in 4 bit mode= .\n", + }, + { + .later =3D 1, + .lam =3D LAM_MAX_BITS, + .test_func =3D handle_max_bits, + .msg =3D "BITS: Check if 6 bits can be requested in 6 bit mode.\n", + }, }; =20 static struct testcases syscall_cases[] =3D { --=20 2.53.0