From: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
After the tag width in LAM (Linear Address Masking) is set to 4 bits,
the value isn't strictly related to the CPU features like LAM_U57 or
LAM_U48. To emphasise this, remove mentions of _U57 from the selftest
and update the bit width.
Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
---
Changelog v4:
- Remove the 'default' wording.
Changelog v3:
- Redo the patch after the removal of the debugfs part.
tools/testing/selftests/x86/lam.c | 86 +++++++++++++++----------------
1 file changed, 43 insertions(+), 43 deletions(-)
diff --git a/tools/testing/selftests/x86/lam.c b/tools/testing/selftests/x86/lam.c
index 1919fa6daec0..d27f947ea694 100644
--- a/tools/testing/selftests/x86/lam.c
+++ b/tools/testing/selftests/x86/lam.c
@@ -26,9 +26,9 @@
/* LAM modes, these definitions were copied from kernel code */
#define LAM_NONE 0
-#define LAM_U57_BITS 6
+#define LAM_BITS 4
-#define LAM_U57_MASK (0x3fULL << 57)
+#define LAM_MASK (0xfULL << 57)
/* arch prctl for LAM */
#define ARCH_GET_UNTAG_MASK 0x4001
#define ARCH_ENABLE_TAGGED_ADDR 0x4002
@@ -175,7 +175,7 @@ static int set_lam(unsigned long lam)
int ret = 0;
uint64_t ptr = 0;
- if (lam != LAM_U57_BITS && lam != LAM_NONE)
+ if (lam != LAM_BITS && lam != LAM_NONE)
return -1;
/* Skip check return */
@@ -185,8 +185,8 @@ static int set_lam(unsigned long lam)
syscall(SYS_arch_prctl, ARCH_GET_UNTAG_MASK, &ptr);
/* Check mask returned is expected */
- if (lam == LAM_U57_BITS)
- ret = (ptr != ~(LAM_U57_MASK));
+ if (lam == LAM_BITS)
+ ret = (ptr != ~(LAM_MASK));
else if (lam == LAM_NONE)
ret = (ptr != -1ULL);
@@ -204,8 +204,8 @@ static unsigned long get_default_tag_bits(void)
perror("Fork failed.");
} else if (pid == 0) {
/* Set LAM mode in child process */
- if (set_lam(LAM_U57_BITS) == 0)
- lam = LAM_U57_BITS;
+ if (set_lam(LAM_BITS) == 0)
+ lam = LAM_BITS;
else
lam = LAM_NONE;
exit(lam);
@@ -230,8 +230,8 @@ static int get_lam(void)
return -1;
/* Check mask returned is expected */
- if (ptr == ~(LAM_U57_MASK))
- ret = LAM_U57_BITS;
+ if (ptr == ~(LAM_MASK))
+ ret = LAM_BITS;
else if (ptr == -1ULL)
ret = LAM_NONE;
@@ -247,10 +247,10 @@ static uint64_t set_metadata(uint64_t src, unsigned long lam)
srand(time(NULL));
switch (lam) {
- case LAM_U57_BITS: /* Set metadata in bits 62:57 */
+ case LAM_BITS: /* Set metadata in bits 62:57 */
/* Get a random non-zero value as metadata */
- metadata = (rand() % ((1UL << LAM_U57_BITS) - 1) + 1) << 57;
- metadata |= (src & ~(LAM_U57_MASK));
+ metadata = (rand() % ((1UL << LAM_BITS) - 1) + 1) << 57;
+ metadata |= (src & ~(LAM_MASK));
break;
default:
metadata = src;
@@ -291,7 +291,7 @@ int handle_max_bits(struct testcases *test)
unsigned long bits = 0;
if (exp_bits != LAM_NONE)
- exp_bits = LAM_U57_BITS;
+ exp_bits = LAM_BITS;
/* Get LAM max tag bits */
if (syscall(SYS_arch_prctl, ARCH_GET_MAX_TAG_BITS, &bits) == -1)
@@ -719,8 +719,8 @@ int do_uring(unsigned long lam)
uint64_t addr = ((uint64_t)fi->iovecs[i].iov_base);
switch (lam) {
- case LAM_U57_BITS: /* Clear bits 62:57 */
- addr = (addr & ~(LAM_U57_MASK));
+ case LAM_BITS: /* Clear bits 60:57 */
+ addr = (addr & ~(LAM_MASK));
break;
}
free((void *)addr);
@@ -937,14 +937,14 @@ static void run_test(struct testcases *test, int count)
static struct testcases uring_cases[] = {
{
.later = 0,
- .lam = LAM_U57_BITS,
+ .lam = LAM_BITS,
.test_func = handle_uring,
- .msg = "URING: LAM_U57. Dereferencing pointer with metadata\n",
+ .msg = "URING: LAM. Dereferencing pointer with metadata\n",
},
{
.later = 1,
.expected = 1,
- .lam = LAM_U57_BITS,
+ .lam = LAM_BITS,
.test_func = handle_uring,
.msg = "URING:[Negative] Disable LAM. Dereferencing pointer with metadata.\n",
},
@@ -953,14 +953,14 @@ static struct testcases uring_cases[] = {
static struct testcases malloc_cases[] = {
{
.later = 0,
- .lam = LAM_U57_BITS,
+ .lam = LAM_BITS,
.test_func = handle_malloc,
- .msg = "MALLOC: LAM_U57. Dereferencing pointer with metadata\n",
+ .msg = "MALLOC: LAM. Dereferencing pointer with metadata\n",
},
{
.later = 1,
.expected = 2,
- .lam = LAM_U57_BITS,
+ .lam = LAM_BITS,
.test_func = handle_malloc,
.msg = "MALLOC:[Negative] Disable LAM. Dereferencing pointer with metadata.\n",
},
@@ -976,41 +976,41 @@ static struct testcases bits_cases[] = {
static struct testcases syscall_cases[] = {
{
.later = 0,
- .lam = LAM_U57_BITS,
+ .lam = LAM_BITS,
.test_func = handle_syscall,
- .msg = "SYSCALL: LAM_U57. syscall with metadata\n",
+ .msg = "SYSCALL: LAM. syscall with metadata\n",
},
{
.later = 1,
.expected = 1,
- .lam = LAM_U57_BITS,
+ .lam = LAM_BITS,
.test_func = handle_syscall,
.msg = "SYSCALL:[Negative] Disable LAM. Dereferencing pointer with metadata.\n",
},
{
.later = GET_USER_USER,
- .lam = LAM_U57_BITS,
+ .lam = LAM_BITS,
.test_func = get_user_syscall,
.msg = "GET_USER: get_user() and pass a properly tagged user pointer.\n",
},
{
.later = GET_USER_KERNEL_TOP,
.expected = 1,
- .lam = LAM_U57_BITS,
+ .lam = LAM_BITS,
.test_func = get_user_syscall,
.msg = "GET_USER:[Negative] get_user() with a kernel pointer and the top bit cleared.\n",
},
{
.later = GET_USER_KERNEL_BOT,
.expected = 1,
- .lam = LAM_U57_BITS,
+ .lam = LAM_BITS,
.test_func = get_user_syscall,
.msg = "GET_USER:[Negative] get_user() with a kernel pointer and the bottom sign-extension bit cleared.\n",
},
{
.later = GET_USER_KERNEL,
.expected = 1,
- .lam = LAM_U57_BITS,
+ .lam = LAM_BITS,
.test_func = get_user_syscall,
.msg = "GET_USER:[Negative] get_user() and pass a kernel pointer.\n",
},
@@ -1020,60 +1020,60 @@ static struct testcases mmap_cases[] = {
{
.later = 1,
.expected = 0,
- .lam = LAM_U57_BITS,
+ .lam = LAM_BITS,
.addr = HIGH_ADDR,
.test_func = handle_mmap,
- .msg = "MMAP: First mmap high address, then set LAM_U57.\n",
+ .msg = "MMAP: First mmap high address, then set LAM.\n",
},
{
.later = 0,
.expected = 0,
- .lam = LAM_U57_BITS,
+ .lam = LAM_BITS,
.addr = HIGH_ADDR,
.test_func = handle_mmap,
- .msg = "MMAP: First LAM_U57, then High address.\n",
+ .msg = "MMAP: First LAM, then High address.\n",
},
{
.later = 0,
.expected = 0,
- .lam = LAM_U57_BITS,
+ .lam = LAM_BITS,
.addr = LOW_ADDR,
.test_func = handle_mmap,
- .msg = "MMAP: First LAM_U57, then Low address.\n",
+ .msg = "MMAP: First LAM, then Low address.\n",
},
};
static struct testcases inheritance_cases[] = {
{
.expected = 0,
- .lam = LAM_U57_BITS,
+ .lam = LAM_BITS,
.test_func = handle_inheritance,
- .msg = "FORK: LAM_U57, child process should get LAM mode same as parent\n",
+ .msg = "FORK: LAM, child process should get LAM mode same as parent\n",
},
{
.expected = 0,
- .lam = LAM_U57_BITS,
+ .lam = LAM_BITS,
.test_func = handle_thread,
- .msg = "THREAD: LAM_U57, child thread should get LAM mode same as parent\n",
+ .msg = "THREAD: LAM, child thread should get LAM mode same as parent\n",
},
{
.expected = 1,
- .lam = LAM_U57_BITS,
+ .lam = LAM_BITS,
.test_func = handle_thread_enable,
.msg = "THREAD: [NEGATIVE] Enable LAM in child.\n",
},
{
.expected = 1,
.later = 1,
- .lam = LAM_U57_BITS,
+ .lam = LAM_BITS,
.test_func = handle_thread,
.msg = "THREAD: [NEGATIVE] Enable LAM in parent after thread created.\n",
},
{
.expected = 0,
- .lam = LAM_U57_BITS,
+ .lam = LAM_BITS,
.test_func = handle_execve,
- .msg = "EXECVE: LAM_U57, child process should get disabled LAM mode\n",
+ .msg = "EXECVE: LAM, child process should get disabled LAM mode\n",
},
};
@@ -1224,7 +1224,7 @@ int handle_pasid(struct testcases *test)
if (tmp & 0x1) {
/* run set lam mode*/
if ((runed & 0x1) == 0) {
- err = set_lam(LAM_U57_BITS);
+ err = set_lam(LAM_BITS);
runed = runed | 0x1;
} else
err = 1;
--
2.53.0
The subject needs a change. No new tests are being added now, right?
On 4/7/2026 10:45 AM, Maciej Wieczor-Retman wrote:
> From: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
>
> diff --git a/tools/testing/selftests/x86/lam.c b/tools/testing/selftests/x86/lam.c
> index 1919fa6daec0..d27f947ea694 100644
> --- a/tools/testing/selftests/x86/lam.c
> +++ b/tools/testing/selftests/x86/lam.c
> @@ -26,9 +26,9 @@
>
> /* LAM modes, these definitions were copied from kernel code */
> #define LAM_NONE 0
> -#define LAM_U57_BITS 6
> +#define LAM_BITS 4
>
> -#define LAM_U57_MASK (0x3fULL << 57)
> +#define LAM_MASK (0xfULL << 57)
How about calculating the LAM_MASK from the LAM bits similar to the core
code in patch 1?
Also, when copying over the defines it would be useful to name them
exactly the same as the core code. That way any name changes would
happen in sync.
> @@ -247,10 +247,10 @@ static uint64_t set_metadata(uint64_t src, unsigned long lam)
> srand(time(NULL));
>
> switch (lam) {
> - case LAM_U57_BITS: /* Set metadata in bits 62:57 */
> + case LAM_BITS: /* Set metadata in bits 62:57 */
This needs to change to 60:57 similar to the change below.
> /* Get a random non-zero value as metadata */
> - metadata = (rand() % ((1UL << LAM_U57_BITS) - 1) + 1) << 57;
> - metadata |= (src & ~(LAM_U57_MASK));
> + metadata = (rand() % ((1UL << LAM_BITS) - 1) + 1) << 57;
> + metadata |= (src & ~(LAM_MASK));
> break;
> default:
> metadata = src;
> @@ -291,7 +291,7 @@ int handle_max_bits(struct testcases *test)
> unsigned long bits = 0;
>
> if (exp_bits != LAM_NONE)
> - exp_bits = LAM_U57_BITS;
> + exp_bits = LAM_BITS;
>
> /* Get LAM max tag bits */
> if (syscall(SYS_arch_prctl, ARCH_GET_MAX_TAG_BITS, &bits) == -1)
> @@ -719,8 +719,8 @@ int do_uring(unsigned long lam)
> uint64_t addr = ((uint64_t)fi->iovecs[i].iov_base);
>
> switch (lam) {
> - case LAM_U57_BITS: /* Clear bits 62:57 */
> - addr = (addr & ~(LAM_U57_MASK));
> + case LAM_BITS: /* Clear bits 60:57 */
Just like this one.
On 2026-04-07 at 13:06:40 -0700, Sohil Mehta wrote:
>The subject needs a change. No new tests are being added now, right?
Oh, right, I'll correct that.
>On 4/7/2026 10:45 AM, Maciej Wieczor-Retman wrote:
>> From: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
>>
>> diff --git a/tools/testing/selftests/x86/lam.c b/tools/testing/selftests/x86/lam.c
>> index 1919fa6daec0..d27f947ea694 100644
>> --- a/tools/testing/selftests/x86/lam.c
>> +++ b/tools/testing/selftests/x86/lam.c
>> @@ -26,9 +26,9 @@
>>
>> /* LAM modes, these definitions were copied from kernel code */
>> #define LAM_NONE 0
>> -#define LAM_U57_BITS 6
>> +#define LAM_BITS 4
>>
>> -#define LAM_U57_MASK (0x3fULL << 57)
>> +#define LAM_MASK (0xfULL << 57)
>
>How about calculating the LAM_MASK from the LAM bits similar to the core
>code in patch 1?
>
>Also, when copying over the defines it would be useful to name them
>exactly the same as the core code. That way any name changes would
>happen in sync.
Yes, both of these sound handy, I'll change it.
>
>> @@ -247,10 +247,10 @@ static uint64_t set_metadata(uint64_t src, unsigned long lam)
>> srand(time(NULL));
>>
>> switch (lam) {
>> - case LAM_U57_BITS: /* Set metadata in bits 62:57 */
>> + case LAM_BITS: /* Set metadata in bits 62:57 */
>
>This needs to change to 60:57 similar to the change below.
Hah, thanks, I thought I got them all :)
>
>> /* Get a random non-zero value as metadata */
>> - metadata = (rand() % ((1UL << LAM_U57_BITS) - 1) + 1) << 57;
>> - metadata |= (src & ~(LAM_U57_MASK));
>> + metadata = (rand() % ((1UL << LAM_BITS) - 1) + 1) << 57;
>> + metadata |= (src & ~(LAM_MASK));
>> break;
>> default:
>> metadata = src;
>> @@ -291,7 +291,7 @@ int handle_max_bits(struct testcases *test)
>> unsigned long bits = 0;
>>
>> if (exp_bits != LAM_NONE)
>> - exp_bits = LAM_U57_BITS;
>> + exp_bits = LAM_BITS;
>>
>> /* Get LAM max tag bits */
>> if (syscall(SYS_arch_prctl, ARCH_GET_MAX_TAG_BITS, &bits) == -1)
>> @@ -719,8 +719,8 @@ int do_uring(unsigned long lam)
>> uint64_t addr = ((uint64_t)fi->iovecs[i].iov_base);
>>
>> switch (lam) {
>> - case LAM_U57_BITS: /* Clear bits 62:57 */
>> - addr = (addr & ~(LAM_U57_MASK));
>> + case LAM_BITS: /* Clear bits 60:57 */
>
>Just like this one.
--
Kind regards
Maciej Wieczór-Retman
© 2016 - 2026 Red Hat, Inc.