Patch "x86/vdso: Fix output operand size of RDPID" has been added to the 6.16-stable tree
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 58 lines · Sasha Levin
This is a note to let you know that I've just added the patch titled
x86/vdso: Fix output operand size of RDPID
to the 6.16-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summaryThe filename of the patch is:
x86-vdso-fix-output-operand-size-of-rdpid.patch
and it can be found in the queue-6.16 subdirectory.If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
commit
9e09c5e5e76f1bb0480722f36d5a266d2faaf00dAuthor: Uros Bizjak <[email protected]> Date: Mon Jun 16 11:52:57 2025 +0200x86/vdso: Fix output operand size of RDPID
[ Upstream commit
ac9c408ed19d535289ca59200dd6a44a6a2d6036]RDPID instruction outputs to a word-sized register (64-bit on
x86_64and 32-bit onx86_32). Use an unsigned long variable to store the correct size.LSL outputs to 32-bit register, use %k operand prefix to always print the 32-bit name of the register.
Use RDPID insn mnemonic while at it as the minimum binutils version of 2.30 supports it.
[ bp: Merge two patches touching the same function into a single one. ]
Fixes ffebbaedc861 ("x86/vdso: Introduce helper functions for CPU and node number")Signed-off-by Uros Bizjak <[email protected]>Signed-off-by Borislav Petkov (AMD) <[email protected]>Signed-off-by Sasha Levin <[email protected]>arch/x86/include/asm/segment.h +1
-1@@ -244,7 +244,7 @@ static inline unsigned long vdso_encode_cpunode(int cpu, unsigned long node)static inline void vdso_read_cpunode (unsigned *cpu,unsigned *node) { -unsigned int p; +unsigned long p;/* * Load CPU and node number from the GDT. LSL is faster than RDTSCP @@ -254,10 +254,10 @@ static inline void vdso_read_cpunode(unsigned *cpu, unsigned *node)* * If RDPID is available, use it. */
arch/x86/include/asm/segment.h static inline void vdso_read_cpunode(unsigned *cpu, unsigned *node) · line 263
Quoted 10 lines
arch/x86/include/asm/segment.h +3
-3-alternative_io ("lsl %[seg],%[p]" , -".byte 0xf3,0x0f,0xc7,0xf8" ,/* RDPID %eax/rax */ +alternative_io ("lsl %[seg],%k[p]" , +"rdpid %[p]" , X86_FEATURE_RDPID, - [p] "=a" (p), [seg] "r" (__CPUNODE_SEG)); + [p] "=r" (p), [seg] "r" (__CPUNODE_SEG)); if (cpu) *cpu = (p & VDSO_CPUNODE_MASK);
What the actual hell?!
Doesn't *anyone* know that x86 zero-extends a 32-bit value to 64 bits?
All this code does is put a completely unnecessary REX prefix on RDPID.
Quoted 68 lines · H. Peter Anvin
Quoted 66 lines · Sasha Levin
This is a note to let you know that I've just added the patch titled
x86/vdso: Fix output operand size of RDPID
to the 6.16-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summaryThe filename of the patch is:
x86-vdso-fix-output-operand-size-of-rdpid.patch
and it can be found in the queue-6.16 subdirectory.If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
commit
9e09c5e5e76f1bb0480722f36d5a266d2faaf00dAuthor: Uros Bizjak <[email protected]> Date: Mon Jun 16 11:52:57 2025 +0200x86/vdso: Fix output operand size of RDPID
[ Upstream commit
ac9c408ed19d535289ca59200dd6a44a6a2d6036]RDPID instruction outputs to a word-sized register (64-bit on
x86_64and 32-bit onx86_32). Use an unsigned long variable to store the correct size.LSL outputs to 32-bit register, use %k operand prefix to always print the 32-bit name of the register.
Use RDPID insn mnemonic while at it as the minimum binutils version of 2.30 supports it.
[ bp: Merge two patches touching the same function into a single one. ]
Fixes ffebbaedc861 ("x86/vdso: Introduce helper functions for CPU and node number")Signed-off-by Uros Bizjak <[email protected]>Signed-off-by Borislav Petkov (AMD) <[email protected]>Signed-off-by Sasha Levin <[email protected]>arch/x86/include/asm/segment.h +4
-4@@ -244,7 +244,7 @@ static inline unsigned long vdso_encode_cpunode(int cpu, unsigned long node)static inline void vdso_read_cpunode (unsigned *cpu,unsigned *node) { -unsigned int p; +unsigned long p;/* * Load CPU and node number from the GDT. LSL is faster than RDTSCP @@ -254,10 +254,10 @@ static inline void vdso_read_cpunode(unsigned *cpu, unsigned *node)* * If RDPID is available, use it. */ -alternative_io ("lsl %[seg],%[p]" , -".byte 0xf3,0x0f,0xc7,0xf8" ,/* RDPID %eax/rax */ +alternative_io ("lsl %[seg],%k[p]" , +"rdpid %[p]" , X86_FEATURE_RDPID, - [p] "=a" (p), [seg] "r" (__CPUNODE_SEG)); + [p] "=r" (p), [seg] "r" (__CPUNODE_SEG));
Quoted 6 lines
arch/x86/include/asm/segment.h static inline void vdso_read_cpunode(unsigned *cpu, unsigned *node) · line 263
Quoted 2 lines
arch/x86/include/asm/segment.h +0
-0if (cpu) *cpu = (p &VDSO_CPUNODE_MASK );What the actual hell?!
Doesn't *anyone* know that x86 zero-extends a 32-bit value to 64 bits?
Yes, this is what %k does with LSL.
Quoted 1 line
All this code does is put a completely unnecessary REX prefix on RDPID.
No, it doesn't.
$ more rdpid.s
rdpid %eax
$ gcc -c rdpid.s
rdpid.s: Assembler messages:
rdpid.s:1: Error: operand size mismatch for `rdpid'$ more rdpid.s
rdpid %rax
$ gcc -c rdpid.s
$ objdump -dr rdpid.ordpid.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <.text>:
0: f3 0f c7 f8 rdpid %rax
Uros.
Quoted 96 lines · Uros Bizjak
Quoted 68 lines · H. Peter Anvin
Quoted 66 lines · Sasha Levin
This is a note to let you know that I've just added the patch titled
x86/vdso: Fix output operand size of RDPID
to the 6.16-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summaryThe filename of the patch is:
x86-vdso-fix-output-operand-size-of-rdpid.patch
and it can be found in the queue-6.16 subdirectory.If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
commit
9e09c5e5e76f1bb0480722f36d5a266d2faaf00dAuthor: Uros Bizjak <[email protected]> Date: Mon Jun 16 11:52:57 2025 +0200x86/vdso: Fix output operand size of RDPID
[ Upstream commit
ac9c408ed19d535289ca59200dd6a44a6a2d6036]RDPID instruction outputs to a word-sized register (64-bit on
x86_64and 32-bit onx86_32). Use an unsigned long variable to store the correct size.LSL outputs to 32-bit register, use %k operand prefix to always print the 32-bit name of the register.
Use RDPID insn mnemonic while at it as the minimum binutils version of 2.30 supports it.
[ bp: Merge two patches touching the same function into a single one. ]
Fixes ffebbaedc861 ("x86/vdso: Introduce helper functions for CPU and node number")Signed-off-by Uros Bizjak <[email protected]>Signed-off-by Borislav Petkov (AMD) <[email protected]>Signed-off-by Sasha Levin <[email protected]>arch/x86/include/asm/segment.h +4
-4@@ -244,7 +244,7 @@ static inline unsigned long vdso_encode_cpunode(int cpu, unsigned long node)static inline void vdso_read_cpunode (unsigned *cpu,unsigned *node) { -unsigned int p; +unsigned long p;/* * Load CPU and node number from the GDT. LSL is faster than RDTSCP @@ -254,10 +254,10 @@ static inline void vdso_read_cpunode(unsigned *cpu, unsigned *node)* * If RDPID is available, use it. */ -alternative_io ("lsl %[seg],%[p]" , -".byte 0xf3,0x0f,0xc7,0xf8" ,/* RDPID %eax/rax */ +alternative_io ("lsl %[seg],%k[p]" , +"rdpid %[p]" , X86_FEATURE_RDPID, - [p] "=a" (p), [seg] "r" (__CPUNODE_SEG)); + [p] "=r" (p), [seg] "r" (__CPUNODE_SEG));Quoted 6 lines
arch/x86/include/asm/segment.h static inline void vdso_read_cpunode(unsigned *cpu, unsigned *node) · line 263
Quoted 2 lines
arch/x86/include/asm/segment.h +0
-0if (cpu) *cpu = (p &VDSO_CPUNODE_MASK );What the actual hell?!
Doesn't *anyone* know that x86 zero-extends a 32-bit value to 64 bits?
Yes, this is what %k does with LSL.
Quoted 1 line
All this code does is put a completely unnecessary REX prefix on RDPID.
No, it doesn't.
$ more rdpid.s rdpid %eax $ gcc -c rdpid.s rdpid.s: Assembler messages: rdpid.s:1: Error: operand size mismatch for `rdpid'$ more rdpid.s rdpid %rax $ gcc -c rdpid.s $ objdump -dr rdpid.ordpid.o: file format elf64-x86-64
Quoted 7 lines
Disassembly of section .text:
0000000000000000 <.text>:
0: f3 0f c7 f8 rdpid %raxUros.
Ok, that's just gas being stupid and overinterpreting the fuzzy language in the SDM, then. It would have been a very good thing to put in the commit or, even better, a comment.
Quoted 100 lines · H. Peter Anvin
Quoted 98 lines · Uros Bizjak
Quoted 68 lines · H. Peter Anvin
Quoted 66 lines · Sasha Levin
This is a note to let you know that I've just added the patch titled
x86/vdso: Fix output operand size of RDPID
to the 6.16-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summaryThe filename of the patch is:
x86-vdso-fix-output-operand-size-of-rdpid.patch
and it can be found in the queue-6.16 subdirectory.If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
commit
9e09c5e5e76f1bb0480722f36d5a266d2faaf00dAuthor: Uros Bizjak <[email protected]> Date: Mon Jun 16 11:52:57 2025 +0200x86/vdso: Fix output operand size of RDPID
[ Upstream commit
ac9c408ed19d535289ca59200dd6a44a6a2d6036]RDPID instruction outputs to a word-sized register (64-bit on
x86_64and 32-bit onx86_32). Use an unsigned long variable to store the correct size.LSL outputs to 32-bit register, use %k operand prefix to always print the 32-bit name of the register.
Use RDPID insn mnemonic while at it as the minimum binutils version of 2.30 supports it.
[ bp: Merge two patches touching the same function into a single one. ]
Fixes ffebbaedc861 ("x86/vdso: Introduce helper functions for CPU and node number")Signed-off-by Uros Bizjak <[email protected]>Signed-off-by Borislav Petkov (AMD) <[email protected]>Signed-off-by Sasha Levin <[email protected]>arch/x86/include/asm/segment.h +4
-4@@ -244,7 +244,7 @@ static inline unsigned long vdso_encode_cpunode(int cpu, unsigned long node)static inline void vdso_read_cpunode (unsigned *cpu,unsigned *node) { -unsigned int p; +unsigned long p;/* * Load CPU and node number from the GDT. LSL is faster than RDTSCP @@ -254,10 +254,10 @@ static inline void vdso_read_cpunode(unsigned *cpu, unsigned *node)* * If RDPID is available, use it. */ -alternative_io ("lsl %[seg],%[p]" , -".byte 0xf3,0x0f,0xc7,0xf8" ,/* RDPID %eax/rax */ +alternative_io ("lsl %[seg],%k[p]" , +"rdpid %[p]" , X86_FEATURE_RDPID, - [p] "=a" (p), [seg] "r" (__CPUNODE_SEG)); + [p] "=r" (p), [seg] "r" (__CPUNODE_SEG));Quoted 6 lines
arch/x86/include/asm/segment.h static inline void vdso_read_cpunode(unsigned *cpu, unsigned *node) · line 263
Quoted 2 lines
arch/x86/include/asm/segment.h +0
-0if (cpu) *cpu = (p &VDSO_CPUNODE_MASK );What the actual hell?!
Doesn't *anyone* know that x86 zero-extends a 32-bit value to 64 bits?
Yes, this is what %k does with LSL.
Quoted 1 line
All this code does is put a completely unnecessary REX prefix on RDPID.
No, it doesn't.
$ more rdpid.s rdpid %eax $ gcc -c rdpid.s rdpid.s: Assembler messages: rdpid.s:1: Error: operand size mismatch for `rdpid'$ more rdpid.s rdpid %rax $ gcc -c rdpid.s $ objdump -dr rdpid.ordpid.o: file format elf64-x86-64
Disassembly of section .text:
Quoted 7 lines
Quoted 5 lines
0000000000000000 <.text>:
0: f3 0f c7 f8 rdpid %raxUros.
Ok, that's just gas being stupid and overinterpreting the fuzzy language in the SDM, then. It would have been a very good thing to put in the commit or, even better, a comment.
SDM says:
Opcode/Instruction | Op/En | 64/32-bit Mode | CPUID Feature Flag
| Description
F3 0F C7 /7 | RDPID r32 | R | N.E./V | RDPID | Read IA32_TSC_AUX into r32.
F3 0F C7 /7 | RDPID r64 | R | V/N.E. | RDPID | Read IA32_TSC_AUX into r64.
So, it is perfectly clear from the Mode column that r32 is not available in 64-bit mode and vice versa.
Uros.
Quoted 118 lines · Uros Bizjak
Quoted 100 lines · H. Peter Anvin
Quoted 98 lines · Uros Bizjak
Quoted 68 lines · H. Peter Anvin
Quoted 66 lines · Sasha Levin
This is a note to let you know that I've just added the patch titled
x86/vdso: Fix output operand size of RDPID
to the 6.16-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summaryThe filename of the patch is:
x86-vdso-fix-output-operand-size-of-rdpid.patch
and it can be found in the queue-6.16 subdirectory.If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
commit
9e09c5e5e76f1bb0480722f36d5a266d2faaf00dAuthor: Uros Bizjak <[email protected]> Date: Mon Jun 16 11:52:57 2025 +0200x86/vdso: Fix output operand size of RDPID
[ Upstream commit
ac9c408ed19d535289ca59200dd6a44a6a2d6036]RDPID instruction outputs to a word-sized register (64-bit on
x86_64and 32-bit onx86_32). Use an unsigned long variable to store the correct size.LSL outputs to 32-bit register, use %k operand prefix to always print the 32-bit name of the register.
Use RDPID insn mnemonic while at it as the minimum binutils version of 2.30 supports it.
[ bp: Merge two patches touching the same function into a single one. ]
Fixes ffebbaedc861 ("x86/vdso: Introduce helper functions for CPU and node number")Signed-off-by Uros Bizjak <[email protected]>Signed-off-by Borislav Petkov (AMD) <[email protected]>Signed-off-by Sasha Levin <[email protected]>arch/x86/include/asm/segment.h +4
-4@@ -244,7 +244,7 @@ static inline unsigned long vdso_encode_cpunode(int cpu, unsigned long node)static inline void vdso_read_cpunode (unsigned *cpu,unsigned *node) { -unsigned int p; +unsigned long p;/* * Load CPU and node number from the GDT. LSL is faster than RDTSCP @@ -254,10 +254,10 @@ static inline void vdso_read_cpunode(unsigned *cpu, unsigned *node)* * If RDPID is available, use it. */ -alternative_io ("lsl %[seg],%[p]" , -".byte 0xf3,0x0f,0xc7,0xf8" ,/* RDPID %eax/rax */ +alternative_io ("lsl %[seg],%k[p]" , +"rdpid %[p]" , X86_FEATURE_RDPID, - [p] "=a" (p), [seg] "r" (__CPUNODE_SEG)); + [p] "=r" (p), [seg] "r" (__CPUNODE_SEG));Quoted 6 lines
arch/x86/include/asm/segment.h static inline void vdso_read_cpunode(unsigned *cpu, unsigned *node) · line 263
Quoted 2 lines
arch/x86/include/asm/segment.h +0
-0if (cpu) *cpu = (p &VDSO_CPUNODE_MASK );What the actual hell?!
Doesn't *anyone* know that x86 zero-extends a 32-bit value to 64 bits?
Yes, this is what %k does with LSL.
Quoted 1 line
All this code does is put a completely unnecessary REX prefix on RDPID.
No, it doesn't.
$ more rdpid.s rdpid %eax $ gcc -c rdpid.s rdpid.s: Assembler messages: rdpid.s:1: Error: operand size mismatch for `rdpid'$ more rdpid.s rdpid %rax $ gcc -c rdpid.s $ objdump -dr rdpid.ordpid.o: file format elf64-x86-64
Disassembly of section .text:
Quoted 7 lines
Quoted 5 lines
0000000000000000 <.text>:
0: f3 0f c7 f8 rdpid %raxUros.
Ok, that's just gas being stupid and overinterpreting the fuzzy language in the SDM, then. It would have been a very good thing to put in the commit or, even better, a comment.
SDM says:
Opcode/Instruction | Op/En | 64/32-bit Mode | CPUID Feature Flag | Description
F3 0F C7 /7 | RDPID r32 | R | N.E./V | RDPID | ReadIA32_TSC_AUXinto r32.
F3 0F C7 /7 | RDPID r64 | R | V/N.E. | RDPID | ReadIA32_TSC_AUXinto r64.
Quoted 5 lines
So, it is perfectly clear from the Mode column that r32 is not available in 64-bit mode and vice versa.
Uros.
And it is complete bunk. Both cases output a 32-bit number, which gets zero-extended to 64 bits in 64-bit mode just because that's how *everything* is handled.
Whomever wrote that was trying to be helpful in the sense of telling people not to put a bogus REX prefix. Unfortunately the SDM is full of that kind of stuff.
Quoted 3 lines · H. Peter Anvin
Ok, that's just gas being stupid and overinterpreting the fuzzy language in the SDM, then. It would have been a very good thing to put in the commit or, even better, a comment.
The APM says:
"RDPID reads the value of TSC_AUX MSR used by the RDTSCP instruction into the specified destination register. Normal operand size prefixes do not apply and the update is either 32 bit or 64 bit based on the current mode."
so I interpret this as
dst_reg = MSR_TSC_AUX
which is a full u64 write. Not a sign-extended 32-bit thing.
Now if the machine does something else, I'm all ears. But we can verify that very easily...
Signature · 4 lines
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquetteQuoted 11 lines · Borislav Petkov
Quoted 3 lines · H. Peter Anvin
Ok, that's just gas being stupid and overinterpreting the fuzzy language in the SDM, then. It would have been a very good thing to put in the commit or, even better, a comment.
The APM says:
"RDPID reads the value of
TSC_AUXMSR used by the RDTSCP instruction into the specified destination register. Normal operand size prefixes do not apply and the update is either 32 bit or 64 bit based on the current mode."
Quoted 9 lines
so I interpret this as
dst_reg=MSR_TSC_AUXwhich is a full u64 write. Not a sign-extended 32-bit thing.
Now if the machine does something else, I'm all ears. But we can verify that very easily...
MSR_TSC_AUX is a 32-bit register, so the two actions are *exactly identical*. This seems like a misunderstanding that has propagated through multiple texts, or perhaps someone thought it was more "future proof" this way.
I think the Intel documentation is even crazier and says "the low 32 bits of IA32_TSC_AUX"...
Quoted 19 lines · H. Peter Anvin
Quoted 17 lines · Borislav Petkov
Quoted 3 lines · H. Peter Anvin
Ok, that's just gas being stupid and overinterpreting the fuzzy language in the SDM, then. It would have been a very good thing to put in the commit or, even better, a comment.
The APM says:
"RDPID reads the value of
TSC_AUXMSR used by the RDTSCP instruction into the specified destination register. Normal operand size prefixes do not apply and the update is either 32 bit or 64 bit based on the current mode."so I interpret this as
dst_reg=MSR_TSC_AUXwhich is a full u64 write. Not a sign-extended 32-bit thing.
Quoted 7 lines
Quoted 3 lines
Now if the machine does something else, I'm all ears. But we can verify that very easily...
MSR_TSC_AUXis a 32-bit register, so the two actions are *exactly identical*. This seems like a misunderstanding that has propagated through multiple texts, or perhaps someone thought it was more "future proof" this way.I think the Intel documentation is even crazier and says "the low 32 bits of
IA32_TSC_AUX"...
Intel SDM says:
Reads the value of the IA32_TSC_AUX MSR (address C0000103H) into the destination register. The value of CS.D and operand-size prefixes (66H and REX.W) do not affect the behavior of the RDPID instruction.
Uros.
Quoted 28 lines · Uros Bizjak
Quoted 19 lines · H. Peter Anvin
Quoted 17 lines · Borislav Petkov
Quoted 3 lines · H. Peter Anvin
Ok, that's just gas being stupid and overinterpreting the fuzzy language in the SDM, then. It would have been a very good thing to put in the commit or, even better, a comment.
The APM says:
"RDPID reads the value of
TSC_AUXMSR used by the RDTSCP instruction into the specified destination register. Normal operand size prefixes do not apply and the update is either 32 bit or 64 bit based on the current mode."so I interpret this as
dst_reg=MSR_TSC_AUXwhich is a full u64 write. Not a sign-extended 32-bit thing.
Quoted 7 lines
Quoted 3 lines
Now if the machine does something else, I'm all ears. But we can verify that very easily...
MSR_TSC_AUXis a 32-bit register, so the two actions are *exactly identical*. This seems like a misunderstanding that has propagated through multiple texts, or perhaps someone thought it was more "future proof" this way.I think the Intel documentation is even crazier and says "the low 32 bits of
IA32_TSC_AUX"...
Quoted 8 lines
Intel SDM says:
Reads the value of the
IA32_TSC_AUXMSR (address C0000103H) into the destination register. The value of CS.D and operand-size prefixes (66H and REX.W) do not affect the behavior of the RDPID instruction.Uros.
Yes, because there is nothing to affect. Anyway, it's clearly a documentation issue that has propagated into toolchains and so on. It's harmless but confusing.
Quoted 1 line · H. Peter Anvin
MSR_TSC_AUXis a 32-bit register,
Every MSR is 64-bit. This one has bits [63:32] reserved. :-P :-P But yeah, TscAux is [31:0]...
Quoted 6 lines
so the two actions are *exactly identical*. This seems like
a misunderstanding that has propagated through multiple texts, or perhaps someone thought it was more "future proof" this way.I think the Intel documentation is even crazier and says "the low 32 bits of
IA32_TSC_AUX"...
Well, funny you should mention that - this raises a good question: what happens in the future if we want to put the whole u64 into the destination reg of RDPID?
Should we extend the insn now, while the high u32 is reserved and is a don't care?
Because I can already see the CPUID bits and such saying: "this RDPID flavor reads the whole u64 MSR, yadda yadda..."
If we fix it now, there's no need for any of that.
Signature · 4 lines
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette