[PATCH] um: Allow builds with Clang

17 views
Skip to first unread message

Kees Cook

unread,
Feb 16, 2022, 7:28:47 PM2/16/22
to Jeff Dike, Kees Cook, Richard Weinberger, Anton Ivanov, Masahiro Yamada, Nick Desaulniers, Nathan Chancellor, David Gow, linu...@lists.infradead.org, linux-...@vger.kernel.org, linux-k...@vger.kernel.org, kuni...@googlegroups.com, ll...@lists.linux.dev, linux-...@vger.kernel.org, x...@kernel.org, linux-h...@vger.kernel.org
Add x86-64 target for Clang+um and update user-offsets.c to use
Clang-friendly assembler, similar to the fix from commit cf0c3e68aa81
("kbuild: fix asm-offset generation to work with clang").

This lets me run KUnit tests with Clang:

$ ./tools/testing/kunit/kunit.py config --make_options LLVM=1
...
$ ./tools/testing/kunit/kunit.py run --make_options LLVM=1
...

Cc: Jeff Dike <jd...@addtoit.com>
Cc: Richard Weinberger <ric...@nod.at>
Cc: Anton Ivanov <anton....@cambridgegreys.com>
Cc: Masahiro Yamada <masa...@kernel.org>
Cc: Nick Desaulniers <ndesau...@google.com>
Cc: Nathan Chancellor <nat...@kernel.org>
Cc: David Gow <davi...@google.com>
Cc: linu...@lists.infradead.org
Cc: linux-...@vger.kernel.org
Cc: linux-k...@vger.kernel.org
Cc: kuni...@googlegroups.com
Cc: ll...@lists.linux.dev
Signed-off-by: Kees Cook <kees...@chromium.org>
---
arch/x86/um/user-offsets.c | 4 ++--
scripts/Makefile.clang | 1 +
2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/x86/um/user-offsets.c b/arch/x86/um/user-offsets.c
index bae61554abcc..d9071827b515 100644
--- a/arch/x86/um/user-offsets.c
+++ b/arch/x86/um/user-offsets.c
@@ -10,10 +10,10 @@
#include <asm/types.h>

#define DEFINE(sym, val) \
- asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+ asm volatile("\n.ascii \"->" #sym " %0 " #val "\"": : "i" (val))

#define DEFINE_LONGS(sym, val) \
- asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long)))
+ asm volatile("\n.ascii \"->" #sym " %0 " #val "\"": : "i" (val/sizeof(unsigned long)))

void foo(void)
{
diff --git a/scripts/Makefile.clang b/scripts/Makefile.clang
index 51fc23e2e9e5..857b23de51c6 100644
--- a/scripts/Makefile.clang
+++ b/scripts/Makefile.clang
@@ -10,6 +10,7 @@ CLANG_TARGET_FLAGS_powerpc := powerpc64le-linux-gnu
CLANG_TARGET_FLAGS_riscv := riscv64-linux-gnu
CLANG_TARGET_FLAGS_s390 := s390x-linux-gnu
CLANG_TARGET_FLAGS_x86 := x86_64-linux-gnu
+CLANG_TARGET_FLAGS_um := x86_64-linux-gnu
CLANG_TARGET_FLAGS := $(CLANG_TARGET_FLAGS_$(SRCARCH))

ifeq ($(CROSS_COMPILE),)
--
2.30.2

Nathan Chancellor

unread,
Feb 16, 2022, 7:37:22 PM2/16/22
to Kees Cook, Jeff Dike, Richard Weinberger, Anton Ivanov, Masahiro Yamada, Nick Desaulniers, David Gow, linu...@lists.infradead.org, linux-...@vger.kernel.org, linux-k...@vger.kernel.org, kuni...@googlegroups.com, ll...@lists.linux.dev, linux-...@vger.kernel.org, x...@kernel.org, linux-h...@vger.kernel.org
On Wed, Feb 16, 2022 at 04:28:43PM -0800, Kees Cook wrote:
> Add x86-64 target for Clang+um and update user-offsets.c to use
> Clang-friendly assembler, similar to the fix from commit cf0c3e68aa81

Clang-friendly assembly?

> ("kbuild: fix asm-offset generation to work with clang").
>
> This lets me run KUnit tests with Clang:
>
> $ ./tools/testing/kunit/kunit.py config --make_options LLVM=1
> ...
> $ ./tools/testing/kunit/kunit.py run --make_options LLVM=1
> ...
>
> Cc: Jeff Dike <jd...@addtoit.com>
> Cc: Richard Weinberger <ric...@nod.at>
> Cc: Anton Ivanov <anton....@cambridgegreys.com>
> Cc: Masahiro Yamada <masa...@kernel.org>
> Cc: Nick Desaulniers <ndesau...@google.com>
> Cc: Nathan Chancellor <nat...@kernel.org>
> Cc: David Gow <davi...@google.com>
> Cc: linu...@lists.infradead.org
> Cc: linux-...@vger.kernel.org
> Cc: linux-k...@vger.kernel.org
> Cc: kuni...@googlegroups.com
> Cc: ll...@lists.linux.dev
> Signed-off-by: Kees Cook <kees...@chromium.org>

I am not super familiar with UML but this seems reasonable.

Reviewed-by: Nathan Chancellor <nat...@kernel.org>

One small nit below if you have to send a v2, not sure it is worth it
otherwise.
It might be nice to keep this in alphabetical order.

David Gow

unread,
Feb 16, 2022, 9:59:40 PM2/16/22
to Kees Cook, Jeff Dike, Richard Weinberger, Anton Ivanov, Masahiro Yamada, Nick Desaulniers, Nathan Chancellor, linux-um, linux-...@vger.kernel.org, open list:KERNEL SELFTEST FRAMEWORK, KUnit Development, ll...@lists.linux.dev, Linux Kernel Mailing List, x...@kernel.org, linux-h...@vger.kernel.org
On Thu, Feb 17, 2022 at 8:28 AM Kees Cook <kees...@chromium.org> wrote:
>
> Add x86-64 target for Clang+um and update user-offsets.c to use
> Clang-friendly assembler, similar to the fix from commit cf0c3e68aa81
> ("kbuild: fix asm-offset generation to work with clang").
>
> This lets me run KUnit tests with Clang:
>
> $ ./tools/testing/kunit/kunit.py config --make_options LLVM=1
> ...
> $ ./tools/testing/kunit/kunit.py run --make_options LLVM=1
> ...
>
> Cc: Jeff Dike <jd...@addtoit.com>
> Cc: Richard Weinberger <ric...@nod.at>
> Cc: Anton Ivanov <anton....@cambridgegreys.com>
> Cc: Masahiro Yamada <masa...@kernel.org>
> Cc: Nick Desaulniers <ndesau...@google.com>
> Cc: Nathan Chancellor <nat...@kernel.org>
> Cc: David Gow <davi...@google.com>
> Cc: linu...@lists.infradead.org
> Cc: linux-...@vger.kernel.org
> Cc: linux-k...@vger.kernel.org
> Cc: kuni...@googlegroups.com
> Cc: ll...@lists.linux.dev
> Signed-off-by: Kees Cook <kees...@chromium.org>
> ---

Thanks, this worked fine for me, with one small note:

I get the following warning with clang (13.0.1) under UML (but not
under x86_64):
clang: warning: argument unused during compilation:
'-mno-global-merge' [-Wunused-command-line-argument]

It's not really a problem unless -Werror is enabled, though, so this
is still definitely an improvement over clang not working at all.

With that caveat, this is:
Tested-by: David Gow <davi...@google.com>

Cheers,
-- David
> --
> You received this message because you are subscribed to the Google Groups "KUnit Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to kunit-dev+...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/kunit-dev/20220217002843.2312603-1-keescook%40chromium.org.

Masahiro Yamada

unread,
Feb 16, 2022, 11:56:10 PM2/16/22
to Kees Cook, Jeff Dike, Richard Weinberger, Anton Ivanov, Nick Desaulniers, Nathan Chancellor, David Gow, linu...@lists.infradead.org, Linux Kbuild mailing list, open list:KERNEL SELFTEST FRAMEWORK, kuni...@googlegroups.com, ll...@lists.linux.dev, Linux Kernel Mailing List, X86 ML, linux-h...@vger.kernel.org
Does this work for the i386 host?

UML supports i386 and x86_64 as the host architecture as of now,
but this always compiles UML for x86_64?







> CLANG_TARGET_FLAGS := $(CLANG_TARGET_FLAGS_$(SRCARCH))
>
> ifeq ($(CROSS_COMPILE),)
> --
> 2.30.2
>


--
Best Regards
Masahiro Yamada

Nathan Chancellor

unread,
Feb 17, 2022, 12:41:46 PM2/17/22
to Masahiro Yamada, Kees Cook, Jeff Dike, Richard Weinberger, Anton Ivanov, Nick Desaulniers, David Gow, linu...@lists.infradead.org, Linux Kbuild mailing list, open list:KERNEL SELFTEST FRAMEWORK, kuni...@googlegroups.com, ll...@lists.linux.dev, Linux Kernel Mailing List, X86 ML, linux-h...@vger.kernel.org
I think the current code will work because arch/x86/Makefile.um includes
-m32 for CONFIG_X86_32, which will implicitly change x86_64-linux-gnu
into a 32-bit target triple:

$ echo | clang --target=x86_64-linux-gnu -x c -c -o test.o -

$ file test.o
test.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

$ echo | clang --target=x86_64-linux-gnu -m32 -x c -c -o test.o -

$ file test.o
test.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped

In fact, we rely on this for ARCH=i386 LLVM=1 right now, as it uses
x86_64-linux-gnu for the target flag.

While UML only supports x86, maybe it is worth using SUBARCH instead of
hardcoding the triple? No strong opinion around that though.

diff --git a/scripts/Makefile.clang b/scripts/Makefile.clang
index 51fc23e2e9e5..87285b76adb2 100644
--- a/scripts/Makefile.clang
+++ b/scripts/Makefile.clang
@@ -10,6 +10,7 @@ CLANG_TARGET_FLAGS_powerpc := powerpc64le-linux-gnu
CLANG_TARGET_FLAGS_riscv := riscv64-linux-gnu
CLANG_TARGET_FLAGS_s390 := s390x-linux-gnu
CLANG_TARGET_FLAGS_x86 := x86_64-linux-gnu
+CLANG_TARGET_FLAGS_um := $(CLANG_TARGET_FLAGS_$(SUBARCH))

Masahiro Yamada

unread,
Feb 17, 2022, 9:20:41 PM2/17/22
to Nathan Chancellor, Kees Cook, Jeff Dike, Richard Weinberger, Anton Ivanov, Nick Desaulniers, David Gow, linu...@lists.infradead.org, Linux Kbuild mailing list, open list:KERNEL SELFTEST FRAMEWORK, kuni...@googlegroups.com, ll...@lists.linux.dev, Linux Kernel Mailing List, X86 ML, linux-h...@vger.kernel.org
Ah, you are right!


>
> $ echo | clang --target=x86_64-linux-gnu -x c -c -o test.o -
>
> $ file test.o
> test.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
>
> $ echo | clang --target=x86_64-linux-gnu -m32 -x c -c -o test.o -
>
> $ file test.o
> test.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
>
> In fact, we rely on this for ARCH=i386 LLVM=1 right now, as it uses
> x86_64-linux-gnu for the target flag.
>
> While UML only supports x86, maybe it is worth using SUBARCH instead of
> hardcoding the triple? No strong opinion around that though.
>
> diff --git a/scripts/Makefile.clang b/scripts/Makefile.clang
> index 51fc23e2e9e5..87285b76adb2 100644
> --- a/scripts/Makefile.clang
> +++ b/scripts/Makefile.clang
> @@ -10,6 +10,7 @@ CLANG_TARGET_FLAGS_powerpc := powerpc64le-linux-gnu
> CLANG_TARGET_FLAGS_riscv := riscv64-linux-gnu
> CLANG_TARGET_FLAGS_s390 := s390x-linux-gnu
> CLANG_TARGET_FLAGS_x86 := x86_64-linux-gnu
> +CLANG_TARGET_FLAGS_um := $(CLANG_TARGET_FLAGS_$(SUBARCH))


LGTM.

I also thought of not passing --target at all for ARCH=um, but
we decided to override --target all the time (for reproducibility?).
Anyway, Nathan's way is clean, and looks OK to me.

Kees Cook

unread,
Feb 24, 2022, 12:58:35 AM2/24/22
to Jeff Dike, Kees Cook, Richard Weinberger, Anton Ivanov, Masahiro Yamada, Nick Desaulniers, Nathan Chancellor, David Gow, linu...@lists.infradead.org, linux-...@vger.kernel.org, linux-k...@vger.kernel.org, kuni...@googlegroups.com, ll...@lists.linux.dev, linux-...@vger.kernel.org, x...@kernel.org, linux-h...@vger.kernel.org
Add x86-64 target for Clang+um and update user-offsets.c to use
Clang-friendly assembly, similar to the fix from commit cf0c3e68aa81
("kbuild: fix asm-offset generation to work with clang").

This lets me run KUnit tests with Clang:

$ ./tools/testing/kunit/kunit.py config --make_options LLVM=1
...
$ ./tools/testing/kunit/kunit.py run --make_options LLVM=1
...

Cc: Jeff Dike <jd...@addtoit.com>
Cc: Richard Weinberger <ric...@nod.at>
Cc: Anton Ivanov <anton....@cambridgegreys.com>
Cc: Masahiro Yamada <masa...@kernel.org>
Cc: Nick Desaulniers <ndesau...@google.com>
Cc: Nathan Chancellor <nat...@kernel.org>
Cc: David Gow <davi...@google.com>
Cc: linu...@lists.infradead.org
Cc: linux-...@vger.kernel.org
Cc: linux-k...@vger.kernel.org
Cc: kuni...@googlegroups.com
Cc: ll...@lists.linux.dev
Reviewed-by: Nathan Chancellor <nat...@kernel.org>
Link: https://lore.kernel.org/lkml/Yg2YubZxvYvx7%2F...@dev-arch.archlinux-ax161/
Tested-by: David Gow <davi...@google.com>
Link: https://lore.kernel.org/lkml/CABVgOSk=oFxsbSbQE-v65VwR2+mXe...@mail.gmail.com/
Signed-off-by: Kees Cook <kees...@chromium.org>
---
v1: https://lore.kernel.org/lkml/20220217002843.2...@chromium.org/
v2:
- tweak commit log phrasing and alphabetize targets (nathan)
- fix a missing implicit fallthrough under 32-bit builds
- add review tags
---
arch/um/os-Linux/execvp.c | 1 +
arch/x86/um/user-offsets.c | 4 ++--
scripts/Makefile.clang | 1 +
3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/um/os-Linux/execvp.c b/arch/um/os-Linux/execvp.c
index 84a0777c2a45..c09a5fd5e225 100644
--- a/arch/um/os-Linux/execvp.c
+++ b/arch/um/os-Linux/execvp.c
@@ -93,6 +93,7 @@ int execvp_noalloc(char *buf, const char *file, char *const argv[])
up finding no executable we can use, we want to diagnose
that we did find one but were denied access. */
got_eacces = 1;
+ break;
case ENOENT:
case ESTALE:
case ENOTDIR:
diff --git a/arch/x86/um/user-offsets.c b/arch/x86/um/user-offsets.c
index bae61554abcc..d9071827b515 100644
--- a/arch/x86/um/user-offsets.c
+++ b/arch/x86/um/user-offsets.c
@@ -10,10 +10,10 @@
#include <asm/types.h>

#define DEFINE(sym, val) \
- asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+ asm volatile("\n.ascii \"->" #sym " %0 " #val "\"": : "i" (val))

#define DEFINE_LONGS(sym, val) \
- asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long)))
+ asm volatile("\n.ascii \"->" #sym " %0 " #val "\"": : "i" (val/sizeof(unsigned long)))

void foo(void)
{
diff --git a/scripts/Makefile.clang b/scripts/Makefile.clang
index 51fc23e2e9e5..6e49344c6db2 100644
--- a/scripts/Makefile.clang
+++ b/scripts/Makefile.clang
@@ -9,6 +9,7 @@ CLANG_TARGET_FLAGS_mips := mipsel-linux-gnu
CLANG_TARGET_FLAGS_powerpc := powerpc64le-linux-gnu
CLANG_TARGET_FLAGS_riscv := riscv64-linux-gnu
CLANG_TARGET_FLAGS_s390 := s390x-linux-gnu
+CLANG_TARGET_FLAGS_um := x86_64-linux-gnu
CLANG_TARGET_FLAGS_x86 := x86_64-linux-gnu
CLANG_TARGET_FLAGS := $(CLANG_TARGET_FLAGS_$(SRCARCH))

--
2.30.2

Masahiro Yamada

unread,
Feb 26, 2022, 10:58:23 PM2/26/22
to Kees Cook, Jeff Dike, Richard Weinberger, Anton Ivanov, Nick Desaulniers, Nathan Chancellor, David Gow, linu...@lists.infradead.org, Linux Kbuild mailing list, open list:KERNEL SELFTEST FRAMEWORK, kuni...@googlegroups.com, ll...@lists.linux.dev, Linux Kernel Mailing List, X86 ML, linux-h...@vger.kernel.org
Another way might be #include <linux/kbuild.h> and delete this macro
definition.


> #define DEFINE_LONGS(sym, val) \
> - asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long)))
> + asm volatile("\n.ascii \"->" #sym " %0 " #val "\"": : "i" (val/sizeof(unsigned long)))


This generates wrong comments.

In include/generated/user_constants.h,
I see this:

#define HOST_BX 5 /* RBX */

(Here, the value of RBX is 40.)



#define DEFINE_LONGS(sym, val) asm volatile("\n.ascii \"->" #sym
" %0 " #val "/sizeof(unsigned long)\"": : "i" (val/sizeof(unsigned
long)))

creates valid comments:

#define HOST_BX 5 /* RBX/sizeof(unsigned long) */



Another way might be to do this indirectly.

#define DEFINE_LONGS(sym, val) DEFINE(sym, val / sizeof(unsigned long))

The comments in include/generated/user_constans.h do not retain
the original macro names, though...







> void foo(void)
> {
> diff --git a/scripts/Makefile.clang b/scripts/Makefile.clang
> index 51fc23e2e9e5..6e49344c6db2 100644
> --- a/scripts/Makefile.clang
> +++ b/scripts/Makefile.clang
> @@ -9,6 +9,7 @@ CLANG_TARGET_FLAGS_mips := mipsel-linux-gnu
> CLANG_TARGET_FLAGS_powerpc := powerpc64le-linux-gnu
> CLANG_TARGET_FLAGS_riscv := riscv64-linux-gnu
> CLANG_TARGET_FLAGS_s390 := s390x-linux-gnu
> +CLANG_TARGET_FLAGS_um := x86_64-linux-gnu


Personally, I like Nathan's idea, but we can live with the hard-coding
since we see no efforts for UML on other host arch.




> CLANG_TARGET_FLAGS_x86 := x86_64-linux-gnu
> CLANG_TARGET_FLAGS := $(CLANG_TARGET_FLAGS_$(SRCARCH))
>
> --
> 2.30.2
>


Reply all
Reply to author
Forward
0 new messages