Skip to content

Commit 60253f1

Browse files
ubizjaksuryasaimadhu
authored andcommitted
x86/boot: Remove x86_32 PIC using %ebx workaround
The currently supported minimum gcc version is 5.1. Before that, the PIC register, when generating Position Independent Code, was considered "fixed" in the sense that it wasn't in the set of registers available to the compiler's register allocator. Which, on x86-32, is already a very small set. What is more, the register allocator was unable to satisfy extended asm "=b" constraints. (Yes, PIC code uses %ebx on 32-bit as the base reg.) With gcc 5.1: "Reuse of the PIC hard register, instead of using a fixed register, was implemented on x86/x86-64 targets. This improves generated PIC code performance as more hard registers can be used. Shared libraries can significantly benefit from this optimization. Currently it is switched on only for x86/x86-64 targets. As RA infrastructure is already implemented for PIC register reuse, other targets might follow this in the future." (from: https://gcc.gnu.org/gcc-5/changes.html) which basically means that the register allocator has a higher degree of freedom when handling %ebx, including reloading it with the correct value before a PIC access. Furthermore: arch/x86/Makefile: # Never want PIC in a 32-bit kernel, prevent breakage with GCC built # with nonstandard options KBUILD_CFLAGS += -fno-pic $ gcc -Wp,-MMD,arch/x86/boot/.cpuflags.o.d ... -fno-pic ... -D__KBUILD_MODNAME=kmod_cpuflags -c -o arch/x86/boot/cpuflags.o arch/x86/boot/cpuflags.c so the 32-bit workaround in cpuid_count() is fixing exactly nothing because 32-bit configs don't even allow PIC builds. As to 64-bit builds: they're done using -mcmodel=kernel which produces RIP-relative addressing for PIC builds and thus does not apply here either. So get rid of the thing and make cpuid_count() nice and simple. There should be no functional changes resulting from this. [ bp: Expand commit message. ] Signed-off-by: Uros Bizjak <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent f1e5250 commit 60253f1

File tree

1 file changed

+3
-12
lines changed

1 file changed

+3
-12
lines changed

arch/x86/boot/cpuflags.c

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,20 +64,11 @@ int has_eflag(unsigned long mask)
6464
return !!((f0^f1) & mask);
6565
}
6666

67-
/* Handle x86_32 PIC using ebx. */
68-
#if defined(__i386__) && defined(__PIC__)
69-
# define EBX_REG "=r"
70-
#else
71-
# define EBX_REG "=b"
72-
#endif
73-
7467
void cpuid_count(u32 id, u32 count, u32 *a, u32 *b, u32 *c, u32 *d)
7568
{
76-
asm volatile(".ifnc %%ebx,%3 ; movl %%ebx,%3 ; .endif \n\t"
77-
"cpuid \n\t"
78-
".ifnc %%ebx,%3 ; xchgl %%ebx,%3 ; .endif \n\t"
79-
: "=a" (*a), "=c" (*c), "=d" (*d), EBX_REG (*b)
80-
: "a" (id), "c" (count)
69+
asm volatile("cpuid"
70+
: "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d)
71+
: "0" (id), "2" (count)
8172
);
8273
}
8374

0 commit comments

Comments
 (0)