LINUX.ORG.RU

не компилируется модуль non-retpoline компилятором

 , , ,


0

1

Приветствую,

Имеется RedHat-8.5 с ядром 4.18.0-348.20.1.el8_5.x86_64, gcc-8.5.0

Установил пакеты kernel-devel и kernel-headers, и попробовал собрать простейший ядерный модуль:

#include <linux/module.h>
#include <linux/kernel.h>

static __init test_init(void)
{
   printk("Init module\n");
   return 0;
}

static __exit void test_exit(void)
{
   printk("Cleanup modulen\n");
}

module_init(test_init)
module_exit(test_exit)

MODULE_DESCRIPTION("Test module")
MODULE_LICENSE("GPL")

Makefile:

obj-m += test_mod.o
MSRC ?= $(PWD)
KDIR ?= /lib/modules/`uname -r`/build/
all:
    make -C $(KDIR) M=$(MSRC) modules
clean:
    make -C $(KDIR) M=$(MSRC) clean

Далее:

%  make V=1
make -C /lib/modules/`uname -r`/build M= modules
make[1]: Entering directory '/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64'
arch/x86/Makefile:249: *** You are building kernel with non-retpoline compiler, please update your compiler..  Stop.
make[1]: Leaving directory '/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64'
make: *** [Makefile:4: all] Error 2
%

man gcc на моей системе (RHEL8.5) сообщает что -mindirect-branch= поддерживается компилятором (насколько я понимаю, именно эта опция «включает» retpoline).

Далее, проверил arch/x86/Makefile:

ifdef CONFIG_RETPOLINE
ifeq ($(RETPOLINE_CFLAGS),)
  $(error You are building kernel with non-retpoline compiler, please update your compiler.)
endif
...

endif

Похоже, что переменная RETPOLINE_CFLAGS не определена, перезапускаю make:

% make V=1 RETPOLINE_CFLAGS=y
make -C /lib/modules/`uname -r`/build/ M= modules
make[1]: Entering directory '/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64'
make -f ./scripts/Makefile.build obj=arch/x86/entry/syscalls all
make -f ./scripts/Makefile.build obj=scripts/basic
(cat /dev/null; ) > scripts/basic/modules.order
rm -f .tmp_quiet_recordmcount
make -f ./scripts/Makefile.build obj=arch/x86/tools relocs
set -e; mkdir -p include/config/;       echo "4.18.0-348.20.1.el8_5.x86_64$(/bin/sh ./scripts/setlocalversion .)" < include/config/auto.conf > include/config/kernel.release.tmp; if [ -r include/config/kernel.release ] && cmp -s include/config/kernel.release include/config/kernel.release.tmp; then rm -f include/config/kernel.release.tmp; else : '  UPD     include/config/kernel.release'; mv -f include/config/kernel.release.tmp include/config/kernel.release; fi
make -f ./scripts/Makefile.asm-generic \
            src=uapi/asm obj=arch/x86/include/generated/uapi/asm
make -f ./scripts/Makefile.asm-generic \
            src=asm obj=arch/x86/include/generated/asm
set -e; mkdir -p include/generated/uapi/linux/;         (echo \#define LINUX_VERSION_CODE 266752; echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))'; echo '#define RHEL_MAJOR 8'; echo '#define RHEL_MINOR 5'; echo '#define RHEL_RELEASE_VERSION(a,b) (((a) << 8) + (b))'; echo '#define RHEL_RELEASE_CODE 2053'; echo '#define RHEL_RELEASE "348.20.1"';) < Makefile > include/generated/uapi/linux/version.h.tmp; if [ -r include/generated/uapi/linux/version.h ] && cmp -s include/generated/uapi/linux/version.h include/generated/uapi/linux/version.h.tmp; then rm -f include/generated/uapi/linux/version.h.tmp; else : '  UPD     include/generated/uapi/linux/version.h'; mv -f include/generated/uapi/linux/version.h.tmp include/generated/uapi/linux/version.h; fi
rm -f include/linux/version.h
set -e; mkdir -p include/generated/;    if [ `echo -n "4.18.0-348.20.1.el8_5.x86_64" | wc -c ` -gt 64 ]; then echo '"4.18.0-348.20.1.el8_5.x86_64" exceeds 64 characters' >&2; exit 1; fi; (echo \#define UTS_RELEASE \"4.18.0-348.20.1.el8_5.x86_64\";) < include/config/kernel.release > include/generated/utsrelease.h.tmp; if [ -r include/generated/utsrelease.h ] && cmp -s include/generated/utsrelease.h include/generated/utsrelease.h.tmp; then rm -f include/generated/utsrelease.h.tmp; else : '  UPD     include/generated/utsrelease.h'; mv -f include/generated/utsrelease.h.tmp include/generated/utsrelease.h; fi
mkdir -p .tmp_versions ; rm -f .tmp_versions/*
make -f ./scripts/Makefile.build obj=.
(cat /dev/null; ) > modules.order
mkdir -p ./tools
make LDFLAGS= MAKEFLAGS=" " O=/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64 subdir=tools -C ./tools/ objtool
mkdir -p /usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64/tools/objtool && make O=/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64 subdir=tools/objtool --no-print-directory -C objtool
make -C /usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64/tools/build CFLAGS= LDFLAGS= /usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64/tools/objtool/fixdep
make -f /usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64/tools/build/Makefile.build dir=. obj=fixdep
/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64/tools/build/Makefile.build:37: /usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64/tools/build/Build.include: No such file or directory
make[5]: *** No rule to make target '/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64/tools/build/Build.include'.  Stop.
make[4]: *** [Makefile:47: /usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64/tools/objtool/fixdep-in.o] Error 2
make[3]: *** [/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64/tools/build/Makefile.include:4: fixdep] Error 2
make[2]: *** [Makefile:65: objtool] Error 2
make[1]: *** [Makefile:1699: tools/objtool] Error 2
make[1]: Leaving directory '/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64'
make: *** [Makefile:4: all] Error 2
%

/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64/tools/build/Build.include действительно отсутствует. Какой пакет устанавливает этот файл?

Или может быть проще отключить retpoline в ядре насовсем? Можно ли это сделать без пересборки ядра?

Попробовал отключить retpoline при загрузке ядра, т.е. добавил в grub конфигурационный файл опцию spectre_v2=off, однако компиляция все равно срывается, теперь на другом:

% make V=1
make -C /lib/modules/`uname -r`/build/ M=/home/mrv/tmp modules
make[1]: Entering directory '/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64'
test -e include/generated/autoconf.h -a -e include/config/auto.conf || (                \
echo >&2;                                                       \
echo >&2 "  ERROR: Kernel configuration is invalid.";           \
echo >&2 "         include/generated/autoconf.h or include/config/auto.conf are missing.";\
echo >&2 "         Run 'make oldconfig && make prepare' on kernel src to fix it.";      \
echo >&2 ;                                                      \
/bin/false)
mkdir -p /home/mrv/tmp/.tmp_versions ; rm -f /home/mrv/tmp/.tmp_versions/*
make -f ./scripts/Makefile.build obj=/home/mrv/tmp
(cat /dev/null;   echo kernel//home/mrv/tmp/test_mod.ko;) > /home/mrv/tmp/modules.order
  gcc -Wp,-MD,/home/mrv/tmp/.test_mod.o.d  -nostdinc -isystem /usr/lib/gcc/x86_64-redhat-linux/8/include -I./arch/x86/include -I./arch/x86/include/generated   -I./include/drm-backport -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -include ./include/linux/compiler_types.h -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-PIE -DCC_HAVE_ASM_GOTO -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -DCONFIG_TPAUSE=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -Wframe-larger-than=2048 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -g -gdwarf-4 -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -fno-inline-functions-called-once -Wdeclaration-after-statement -Wno-pointer-sign -Wno-stringop-truncation -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -fmacro-prefix-map=./= -Wno-packed-not-aligned  -DMODULE  -DKBUILD_BASENAME='"test_mod"' -DKBUILD_MODNAME='"test_mod"' -c -o /home/mrv/tmp/.tmp_test_mod.o /home/mrv/tmp/test_mod.c
In file included from ./include/linux/module.h:18,
                 from /home/mrv/tmp/test_mod.c:1:
./include/linux/moduleparam.h:22:1: error: expected ‘,’ or ‘;’ before ‘static’
 static const char __UNIQUE_ID(name)[]       \
 ^~~~~~
./include/linux/module.h:158:32: note: in expansion of macro ‘__MODULE_INFO’
 #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
                                ^~~~~~~~~~~~~
./include/linux/module.h:196:34: note: in expansion of macro ‘MODULE_INFO’
 #define MODULE_LICENSE(_license) MODULE_INFO(license, _license)
                                  ^~~~~~~~~~~
/home/mrv/tmp/test_mod.c:19:1: note: in expansion of macro ‘MODULE_LICENSE’
 MODULE_LICENSE("GPL")
 ^~~~~~~~~~~~~~
make[2]: *** [scripts/Makefile.build:322: /home/mrv/tmp/test_mod.o] Error 1
make[1]: *** [Makefile:1571: _module_/home/mrv/tmp] Error 2
make[1]: Leaving directory '/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64'
make: *** [Makefile:6: all] Error 2
%

Перехожу в /usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64 и делаю make oldconfig && make V=1 prepare, почти сразу сваливается на невозможности найти tools/build/Build.include

★★

Ответ на: комментарий от monk

Что-то не так с Makefile. Может это поможет: https://stackoverflow.com/questions/61281561/make-for-objtool-in-ubuntu-20-04-fails-because-of-missing-build-include-file

Изучил все по ссылке, но не сильно помогло. Свой Makefile я добавил в первоначальный пост, вроде все в норме.

Закрадывается ощущение что RedHat специально оставил невозможность компилить свои модули.

cruz7 ★★ ()
Ответ на: комментарий от cruz7

Изучил все по ссылке, но не сильно помогло. Свой Makefile я добавил в первоначальный пост, вроде все в норме.

Закрадывается ощущение что RedHat специально оставил невозможность компилить свои модули.

Посыпаю голову пеплом. Проблема была в моем модуле! Забыл поставить ';' после MODULE_*() макросов, отсюда и ошибка компиляции.

#include <linux/module.h>
#include <linux/kernel.h>

static __init test_init(void)
{
   printk("Init module\n");
   return 0;
}

static __exit void test_exit(void)
{
   printk("Cleanup modulen\n");
}

module_init(test_init)
module_exit(test_exit)

MODULE_DESCRIPTION("Test module");
MODULE_LICENSE("GPL");

То есть отключение retpoline при загрузке ядра помогает преодолеть первую ошибку компиляции (см. выше в оригинальном посте, когда заявляется что компилятор gcc-8.5.0 не поддерживает retpoline-опции, хотя судя по документации как-раз таки поддерживает).

cruz7 ★★ ()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.