diff mbox series

[v4,1/6] arm64: vdso32: Fix syncconfig errors.

Message ID 20191002144156.2174-2-vincenzo.frascino@arm.com (mailing list archive)
State New, archived
Headers show
Series arm64: vdso32: Address various issues | expand

Commit Message

Vincenzo Frascino Oct. 2, 2019, 2:41 p.m. UTC
The .config file and the generated include/config/auto.conf can
end up out of sync after a set of commands since
CONFIG_CROSS_COMPILE_COMPAT_VDSO is not updated correctly.

The sequence can be reproduced as follows:

$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig
[...]
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
[set CONFIG_CROSS_COMPILE_COMPAT_VDSO="arm-linux-gnueabihf-"]
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-

Which results in:

arch/arm64/Makefile:62: CROSS_COMPILE_COMPAT not defined or empty,
the compat vDSO will not be built

even though the compat vDSO has been built:

$ file arch/arm64/kernel/vdso32/vdso.so
arch/arm64/kernel/vdso32/vdso.so: ELF 32-bit LSB pie executable, ARM,
EABI5 version 1 (SYSV), dynamically linked,
BuildID[sha1]=c67f6c786f2d2d6f86c71f708595594aa25247f6, stripped

A similar case that involves changing the configuration parameter multiple
times can be reconducted to the same family of problems.

The reason behind it comes from the fact that the master Makefile includes
that architecture Makefile twice, once before the syncconfig and one after.
Since the synchronization of the files happens only upon syncconfig, the
architecture Makefile included before this event does not see the change in
configuration.

As a consequence of this it is not possible to handle the cross compiler
definitions inside the architecture Makefile.

Address the problem refactoring the arm64 main Makefile and removing the
misleading warnings.

As a consequence of this it is not possible anymore to set the compat
cross compiler from menuconfig but it requires to be exported via
command line.

E.g.:

$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
CROSS_COMPILE_COMPAT=arm-linux-gnueabihf-

Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Reported-by: Will Deacon <will@kernel.org>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Tested-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/Makefile               | 18 +++++-------------
 arch/arm64/kernel/vdso32/Makefile |  2 --
 2 files changed, 5 insertions(+), 15 deletions(-)

Comments

Catalin Marinas Oct. 3, 2019, 4 p.m. UTC | #1
On Wed, Oct 02, 2019 at 03:41:51PM +0100, Vincenzo Frascino wrote:
> Cc: Will Deacon <will@kernel.org>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Reported-by: Will Deacon <will@kernel.org>
> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
> Tested-by: Catalin Marinas <catalin.marinas@arm.com>

If you changed the patch, please drop my reviewed/tested-by.

> diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
> index 84a3d502c5a5..dfa6a5cb99e4 100644
> --- a/arch/arm64/Makefile
> +++ b/arch/arm64/Makefile
> @@ -53,20 +53,12 @@ $(warning Detected assembler with broken .inst; disassembly will be unreliable)
>    endif
>  endif
>  
> +COMPATCC ?= $(CROSS_COMPILE_COMPAT)gcc
> +export COMPATCC
> +
>  ifeq ($(CONFIG_GENERIC_COMPAT_VDSO), y)
> -  CROSS_COMPILE_COMPAT ?= $(CONFIG_CROSS_COMPILE_COMPAT_VDSO:"%"=%)
> -
> -  ifeq ($(CONFIG_CC_IS_CLANG), y)
> -    $(warning CROSS_COMPILE_COMPAT is clang, the compat vDSO will not be built)
> -  else ifeq ($(strip $(CROSS_COMPILE_COMPAT)),)
> -    $(warning CROSS_COMPILE_COMPAT not defined or empty, the compat vDSO will not be built)
> -  else ifeq ($(shell which $(CROSS_COMPILE_COMPAT)gcc 2> /dev/null),)
> -    $(error $(CROSS_COMPILE_COMPAT)gcc not found, check CROSS_COMPILE_COMPAT)
> -  else
> -    export CROSS_COMPILE_COMPAT
> -    export CONFIG_COMPAT_VDSO := y
> -    compat_vdso := -DCONFIG_COMPAT_VDSO=1
> -  endif
> +  export CONFIG_COMPAT_VDSO := y
> +  compat_vdso := -DCONFIG_COMPAT_VDSO=1
>  endif

With this change, if I don't have any CROSS_COMPILE_COMPAT in my
environment, the kernel fails to build because COMPATCC becomes gcc
which cannot build the vdso32. What I really want is not to warn me, nor
fail to build the kernel when I don't care about the compat vDSO (e.g. I
have a 64-bit only machine).

What saved us before was the COMPATCC_IS_ARM_GCC check and a selection
of the GENERIC_COMPAT_VDSO dependent on this check. This was now dropped
from the previous version of the patch. We could add something like
COMPATCC_CAN_LINK.
Catalin Marinas Oct. 3, 2019, 4:16 p.m. UTC | #2
On Thu, Oct 03, 2019 at 05:00:41PM +0100, Catalin Marinas wrote:
> On Wed, Oct 02, 2019 at 03:41:51PM +0100, Vincenzo Frascino wrote:
> > diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
> > index 84a3d502c5a5..dfa6a5cb99e4 100644
> > --- a/arch/arm64/Makefile
> > +++ b/arch/arm64/Makefile
> > @@ -53,20 +53,12 @@ $(warning Detected assembler with broken .inst; disassembly will be unreliable)
> >    endif
> >  endif
> >  
> > +COMPATCC ?= $(CROSS_COMPILE_COMPAT)gcc
> > +export COMPATCC
> > +
> >  ifeq ($(CONFIG_GENERIC_COMPAT_VDSO), y)
> > -  CROSS_COMPILE_COMPAT ?= $(CONFIG_CROSS_COMPILE_COMPAT_VDSO:"%"=%)
> > -
> > -  ifeq ($(CONFIG_CC_IS_CLANG), y)
> > -    $(warning CROSS_COMPILE_COMPAT is clang, the compat vDSO will not be built)
> > -  else ifeq ($(strip $(CROSS_COMPILE_COMPAT)),)
> > -    $(warning CROSS_COMPILE_COMPAT not defined or empty, the compat vDSO will not be built)
> > -  else ifeq ($(shell which $(CROSS_COMPILE_COMPAT)gcc 2> /dev/null),)
> > -    $(error $(CROSS_COMPILE_COMPAT)gcc not found, check CROSS_COMPILE_COMPAT)
> > -  else
> > -    export CROSS_COMPILE_COMPAT
> > -    export CONFIG_COMPAT_VDSO := y
> > -    compat_vdso := -DCONFIG_COMPAT_VDSO=1
> > -  endif
> > +  export CONFIG_COMPAT_VDSO := y
> > +  compat_vdso := -DCONFIG_COMPAT_VDSO=1
> >  endif
> 
> With this change, if I don't have any CROSS_COMPILE_COMPAT in my
> environment, the kernel fails to build because COMPATCC becomes gcc
> which cannot build the vdso32. What I really want is not to warn me, nor
> fail to build the kernel when I don't care about the compat vDSO (e.g. I
> have a 64-bit only machine).
> 
> What saved us before was the COMPATCC_IS_ARM_GCC check and a selection
> of the GENERIC_COMPAT_VDSO dependent on this check. This was now dropped
> from the previous version of the patch. We could add something like
> COMPATCC_CAN_LINK.

Ah, the COMPATCC_CAN_LINK idea doesn't help because an x86 gcc can still
link. Maybe only enable CONFIG_COMPAT_VDSO above if CROSS_COMPILE_COMPAT
was set. You could move the COMPATCC setting and export under the
same 'if' block in the Makefile.
Vincenzo Frascino Oct. 3, 2019, 4:20 p.m. UTC | #3
On 03/10/2019 17:00, Catalin Marinas wrote:
> On Wed, Oct 02, 2019 at 03:41:51PM +0100, Vincenzo Frascino wrote:
>> Cc: Will Deacon <will@kernel.org>
>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> Reported-by: Will Deacon <will@kernel.org>
>> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
>> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
>> Tested-by: Catalin Marinas <catalin.marinas@arm.com>
> 
> If you changed the patch, please drop my reviewed/tested-by.
>

Sorry, forgot it in this patch.

>> diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
>> index 84a3d502c5a5..dfa6a5cb99e4 100644
>> --- a/arch/arm64/Makefile
>> +++ b/arch/arm64/Makefile
>> @@ -53,20 +53,12 @@ $(warning Detected assembler with broken .inst; disassembly will be unreliable)
>>    endif
>>  endif
>>  
>> +COMPATCC ?= $(CROSS_COMPILE_COMPAT)gcc
>> +export COMPATCC
>> +
>>  ifeq ($(CONFIG_GENERIC_COMPAT_VDSO), y)
>> -  CROSS_COMPILE_COMPAT ?= $(CONFIG_CROSS_COMPILE_COMPAT_VDSO:"%"=%)
>> -
>> -  ifeq ($(CONFIG_CC_IS_CLANG), y)
>> -    $(warning CROSS_COMPILE_COMPAT is clang, the compat vDSO will not be built)
>> -  else ifeq ($(strip $(CROSS_COMPILE_COMPAT)),)
>> -    $(warning CROSS_COMPILE_COMPAT not defined or empty, the compat vDSO will not be built)
>> -  else ifeq ($(shell which $(CROSS_COMPILE_COMPAT)gcc 2> /dev/null),)
>> -    $(error $(CROSS_COMPILE_COMPAT)gcc not found, check CROSS_COMPILE_COMPAT)
>> -  else
>> -    export CROSS_COMPILE_COMPAT
>> -    export CONFIG_COMPAT_VDSO := y
>> -    compat_vdso := -DCONFIG_COMPAT_VDSO=1
>> -  endif
>> +  export CONFIG_COMPAT_VDSO := y
>> +  compat_vdso := -DCONFIG_COMPAT_VDSO=1
>>  endif
> 
> With this change, if I don't have any CROSS_COMPILE_COMPAT in my
> environment, the kernel fails to build because COMPATCC becomes gcc
> which cannot build the vdso32. What I really want is not to warn me, nor
> fail to build the kernel when I don't care about the compat vDSO (e.g. I
> have a 64-bit only machine).
> 
> What saved us before was the COMPATCC_IS_ARM_GCC check and a selection
> of the GENERIC_COMPAT_VDSO dependent on this check. This was now dropped
> from the previous version of the patch. We could add something like
> COMPATCC_CAN_LINK.
> 

Seems not solving the problem, I am trying with COMPATCC_EMPTY as test -z
$CROSS_COMPILER_COMPAT.
Vincenzo Frascino Oct. 3, 2019, 5:03 p.m. UTC | #4
On 03/10/2019 17:16, Catalin Marinas wrote:
> On Thu, Oct 03, 2019 at 05:00:41PM +0100, Catalin Marinas wrote:
>> On Wed, Oct 02, 2019 at 03:41:51PM +0100, Vincenzo Frascino wrote:
>>> diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
>>> index 84a3d502c5a5..dfa6a5cb99e4 100644
>>> --- a/arch/arm64/Makefile
>>> +++ b/arch/arm64/Makefile
>>> @@ -53,20 +53,12 @@ $(warning Detected assembler with broken .inst; disassembly will be unreliable)
>>>    endif
>>>  endif
>>>  
>>> +COMPATCC ?= $(CROSS_COMPILE_COMPAT)gcc
>>> +export COMPATCC
>>> +
>>>  ifeq ($(CONFIG_GENERIC_COMPAT_VDSO), y)
>>> -  CROSS_COMPILE_COMPAT ?= $(CONFIG_CROSS_COMPILE_COMPAT_VDSO:"%"=%)
>>> -
>>> -  ifeq ($(CONFIG_CC_IS_CLANG), y)
>>> -    $(warning CROSS_COMPILE_COMPAT is clang, the compat vDSO will not be built)
>>> -  else ifeq ($(strip $(CROSS_COMPILE_COMPAT)),)
>>> -    $(warning CROSS_COMPILE_COMPAT not defined or empty, the compat vDSO will not be built)
>>> -  else ifeq ($(shell which $(CROSS_COMPILE_COMPAT)gcc 2> /dev/null),)
>>> -    $(error $(CROSS_COMPILE_COMPAT)gcc not found, check CROSS_COMPILE_COMPAT)
>>> -  else
>>> -    export CROSS_COMPILE_COMPAT
>>> -    export CONFIG_COMPAT_VDSO := y
>>> -    compat_vdso := -DCONFIG_COMPAT_VDSO=1
>>> -  endif
>>> +  export CONFIG_COMPAT_VDSO := y
>>> +  compat_vdso := -DCONFIG_COMPAT_VDSO=1
>>>  endif
>>
>> With this change, if I don't have any CROSS_COMPILE_COMPAT in my
>> environment, the kernel fails to build because COMPATCC becomes gcc
>> which cannot build the vdso32. What I really want is not to warn me, nor
>> fail to build the kernel when I don't care about the compat vDSO (e.g. I
>> have a 64-bit only machine).
>>
>> What saved us before was the COMPATCC_IS_ARM_GCC check and a selection
>> of the GENERIC_COMPAT_VDSO dependent on this check. This was now dropped
>> from the previous version of the patch. We could add something like
>> COMPATCC_CAN_LINK.
> 
> Ah, the COMPATCC_CAN_LINK idea doesn't help because an x86 gcc can still
> link. Maybe only enable CONFIG_COMPAT_VDSO above if CROSS_COMPILE_COMPAT
> was set. You could move the COMPATCC setting and export under the
> same 'if' block in the Makefile.
> 

Right, I did not see this before my previous reply.

If I do that I get what follows, still investigating:

make[1]: Entering directory '/data1/Projects/LinuxKernel/linux-out'
$CROSS_COMPILE_COMPAT is []
  CLEAN   arch/arm64/crypto
  CLEAN   arch/arm64/kernel/vdso
/bin/sh: 0: Illegal option -r
Vincenzo Frascino Oct. 3, 2019, 5:40 p.m. UTC | #5
Hi Catalin,

On 03/10/2019 17:16, Catalin Marinas wrote:
> On Thu, Oct 03, 2019 at 05:00:41PM +0100, Catalin Marinas wrote:
>> On Wed, Oct 02, 2019 at 03:41:51PM +0100, Vincenzo Frascino wrote:
>>> diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
>>> index 84a3d502c5a5..dfa6a5cb99e4 100644
>>> --- a/arch/arm64/Makefile
>>> +++ b/arch/arm64/Makefile
>>> @@ -53,20 +53,12 @@ $(warning Detected assembler with broken .inst; disassembly will be unreliable)
>>>    endif
>>>  endif
>>>  
>>> +COMPATCC ?= $(CROSS_COMPILE_COMPAT)gcc
>>> +export COMPATCC
>>> +
>>>  ifeq ($(CONFIG_GENERIC_COMPAT_VDSO), y)
>>> -  CROSS_COMPILE_COMPAT ?= $(CONFIG_CROSS_COMPILE_COMPAT_VDSO:"%"=%)
>>> -
>>> -  ifeq ($(CONFIG_CC_IS_CLANG), y)
>>> -    $(warning CROSS_COMPILE_COMPAT is clang, the compat vDSO will not be built)
>>> -  else ifeq ($(strip $(CROSS_COMPILE_COMPAT)),)
>>> -    $(warning CROSS_COMPILE_COMPAT not defined or empty, the compat vDSO will not be built)
>>> -  else ifeq ($(shell which $(CROSS_COMPILE_COMPAT)gcc 2> /dev/null),)
>>> -    $(error $(CROSS_COMPILE_COMPAT)gcc not found, check CROSS_COMPILE_COMPAT)
>>> -  else
>>> -    export CROSS_COMPILE_COMPAT
>>> -    export CONFIG_COMPAT_VDSO := y
>>> -    compat_vdso := -DCONFIG_COMPAT_VDSO=1
>>> -  endif
>>> +  export CONFIG_COMPAT_VDSO := y
>>> +  compat_vdso := -DCONFIG_COMPAT_VDSO=1
>>>  endif
>>
>> With this change, if I don't have any CROSS_COMPILE_COMPAT in my
>> environment, the kernel fails to build because COMPATCC becomes gcc
>> which cannot build the vdso32. What I really want is not to warn me, nor
>> fail to build the kernel when I don't care about the compat vDSO (e.g. I
>> have a 64-bit only machine).
>>
>> What saved us before was the COMPATCC_IS_ARM_GCC check and a selection
>> of the GENERIC_COMPAT_VDSO dependent on this check. This was now dropped
>> from the previous version of the patch. We could add something like
>> COMPATCC_CAN_LINK.
> 
> Ah, the COMPATCC_CAN_LINK idea doesn't help because an x86 gcc can still
> link. Maybe only enable CONFIG_COMPAT_VDSO above if CROSS_COMPILE_COMPAT
> was set. You could move the COMPATCC setting and export under the
> same 'if' block in the Makefile.
> 

The snippet below the scissors solves the problem for me. I am going to re-post
a new version of the patches that contains it.

--->8---

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 37c610963eee..b4cc8fb5344c 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -110,7 +110,7 @@ config ARM64
 	select GENERIC_STRNLEN_USER
 	select GENERIC_TIME_VSYSCALL
 	select GENERIC_GETTIMEOFDAY
-	select GENERIC_COMPAT_VDSO if (!CPU_BIG_ENDIAN && COMPAT)
+	select GENERIC_COMPAT_VDSO if (!CPU_BIG_ENDIAN && COMPAT && !COMPATCC_EMPTY)
 	select HANDLE_DOMAIN_IRQ
 	select HARDIRQS_SW_RESEND
 	select HAVE_PCI
@@ -313,6 +313,9 @@ config KASAN_SHADOW_OFFSET
 	default 0xeffffff900000000 if ARM64_VA_BITS_36 && KASAN_SW_TAGS
 	default 0xffffffffffffffff

+config COMPATCC_EMPTY
+	def_bool $(success,test -z "${CROSS_COMPILE_COMPAT}")
+
 source "arch/arm64/Kconfig.platforms"

 menu "Kernel Features"
diff mbox series

Patch

diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 84a3d502c5a5..dfa6a5cb99e4 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -53,20 +53,12 @@  $(warning Detected assembler with broken .inst; disassembly will be unreliable)
   endif
 endif
 
+COMPATCC ?= $(CROSS_COMPILE_COMPAT)gcc
+export COMPATCC
+
 ifeq ($(CONFIG_GENERIC_COMPAT_VDSO), y)
-  CROSS_COMPILE_COMPAT ?= $(CONFIG_CROSS_COMPILE_COMPAT_VDSO:"%"=%)
-
-  ifeq ($(CONFIG_CC_IS_CLANG), y)
-    $(warning CROSS_COMPILE_COMPAT is clang, the compat vDSO will not be built)
-  else ifeq ($(strip $(CROSS_COMPILE_COMPAT)),)
-    $(warning CROSS_COMPILE_COMPAT not defined or empty, the compat vDSO will not be built)
-  else ifeq ($(shell which $(CROSS_COMPILE_COMPAT)gcc 2> /dev/null),)
-    $(error $(CROSS_COMPILE_COMPAT)gcc not found, check CROSS_COMPILE_COMPAT)
-  else
-    export CROSS_COMPILE_COMPAT
-    export CONFIG_COMPAT_VDSO := y
-    compat_vdso := -DCONFIG_COMPAT_VDSO=1
-  endif
+  export CONFIG_COMPAT_VDSO := y
+  compat_vdso := -DCONFIG_COMPAT_VDSO=1
 endif
 
 KBUILD_CFLAGS	+= -mgeneral-regs-only $(lseinstr) $(brokengasinst)	\
diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile
index 1fba0776ed40..19e0d3115ffe 100644
--- a/arch/arm64/kernel/vdso32/Makefile
+++ b/arch/arm64/kernel/vdso32/Makefile
@@ -8,8 +8,6 @@ 
 ARCH_REL_TYPE_ABS := R_ARM_JUMP_SLOT|R_ARM_GLOB_DAT|R_ARM_ABS32
 include $(srctree)/lib/vdso/Makefile
 
-COMPATCC := $(CROSS_COMPILE_COMPAT)gcc
-
 # Same as cc-*option, but using COMPATCC instead of CC
 cc32-option = $(call try-run,\
         $(COMPATCC) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2))