RE: [PATCH 2/2] x86/fred: Fix build with CONFIG_IA32_EMULATION=n

From: Li, Xin3
Date: Tue Jan 30 2024 - 10:24:24 EST


> > When CONFIG_IA32_EMULATION=n, int80_emulation() is NOT defined, fix it.
> >
> > Fixes: 5e0636a41485 ("x86/fred: FRED entry/exit and dispatch code")
> > Link:
> > https://lore.kernel.org/lkml/20240126100519.GBZbOD3xFB0v3mp5B1@fat_cra
> > te.local/
> > Reported-by: Borislav Petkov (AMD) <bp@xxxxxxxxx>
> > Signed-off-by: Xin Li <xin3.li@xxxxxxxxx>
> > ---
> > arch/x86/entry/entry_fred.c | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/arch/x86/entry/entry_fred.c b/arch/x86/entry/entry_fred.c
> > index 06d00c60ea64..ac120cbdaaf2 100644
> > --- a/arch/x86/entry/entry_fred.c
> > +++ b/arch/x86/entry/entry_fred.c
> > @@ -62,11 +62,13 @@ static noinstr void fred_intx(struct pt_regs *regs)
> > case X86_TRAP_OF:
> > return exc_overflow(regs);
> >
> > +#ifdef CONFIG_IA32_EMULATION
> > /* INT80 */
> > case IA32_SYSCALL_VECTOR:
> > if (ia32_enabled())
> > return int80_emulation(regs);
> > fallthrough;
> > +#endif
> >
> > default:
> > return exc_general_protection(regs, 0);
> > --
>
> That .config is still not happy after this:
>
> ld: vmlinux.o: in function `fred_entry_from_user':
> (.noinstr.text+0x177a): undefined reference to `do_fast_syscall_32'
> make[2]: *** [scripts/Makefile.vmlinux:37: vmlinux] Error 1
> make[1]: *** [/mnt/kernel/kernel/linux/Makefile:1158: vmlinux] Error 2
> make: *** [Makefile:240: __sub-make] Error 2

Sign, I'm sorry it still doesn’t work with GCC.

> I'm pushing the latest state I have here:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git/log/?h=tip-x86-fred

Because clang can compile it, I checked the generated assembly code and
see that clang optimizes it by simply converting ia32_enabled() to false
when CONFIG_IA32_EMULATION=n thus never calling do_fast_syscall_32().

It looks to me that the following patch is better than adding another
#ifdef CONFIG_IA32_EMULATION around do_fast_syscall_32().

How do you think?

BTW, I have tested it with both GCC and clang with CONFIG_IA32_EMULATION=n.

Thanks!
-Xin

diff --git a/arch/x86/include/asm/ia32.h b/arch/x86/include/asm/ia32.h
index c7ef6ea2fa99..01342d343c19 100644
--- a/arch/x86/include/asm/ia32.h
+++ b/arch/x86/include/asm/ia32.h
@@ -81,7 +81,7 @@ static inline void ia32_disable(void)

#else /* !CONFIG_IA32_EMULATION */

-static inline bool ia32_enabled(void)
+static __always_inline bool ia32_enabled(void)
{
return IS_ENABLED(CONFIG_X86_32);
}