All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/8] objtool: retpoline validation
@ 2018-02-12 12:48 Peter Zijlstra
  2018-02-12 12:48 ` [PATCH v2 1/8] objtool: Use existing global variables for options Peter Zijlstra
                   ` (7 more replies)
  0 siblings, 8 replies; 13+ messages in thread
From: Peter Zijlstra @ 2018-02-12 12:48 UTC (permalink / raw)
  To: David Woodhouse, Thomas Gleixner, Josh Poimboeuf
  Cc: linux-kernel, Dave Hansen, Ashok Raj, Tim Chen, Andy Lutomirski,
	Linus Torvalds, Greg KH, Andrea Arcangeli, Andi Kleen,
	Arjan Van De Ven, Dan Williams, Paolo Bonzini, Jun Nakajima,
	Asit Mallick, Peter Zijlstra

The very latest objtool retpoline validation patches, all ready for x86/pti.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2 1/8] objtool: Use existing global variables for options
  2018-02-12 12:48 [PATCH v2 0/8] objtool: retpoline validation Peter Zijlstra
@ 2018-02-12 12:48 ` Peter Zijlstra
  2018-02-12 12:48 ` [PATCH v2 2/8] objtool: Add retpoline validation Peter Zijlstra
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Peter Zijlstra @ 2018-02-12 12:48 UTC (permalink / raw)
  To: David Woodhouse, Thomas Gleixner, Josh Poimboeuf
  Cc: linux-kernel, Dave Hansen, Ashok Raj, Tim Chen, Andy Lutomirski,
	Linus Torvalds, Greg KH, Andrea Arcangeli, Andi Kleen,
	Arjan Van De Ven, Dan Williams, Paolo Bonzini, Jun Nakajima,
	Asit Mallick, Peter Zijlstra

[-- Attachment #1: peterz-objtool-unclutter.patch --]
[-- Type: text/plain, Size: 2849 bytes --]

Use the existing global variables instead of passing them around and
creating duplicate global variables.

Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 tools/objtool/builtin-check.c |    2 +-
 tools/objtool/builtin-orc.c   |    6 +-----
 tools/objtool/builtin.h       |    5 +++++
 tools/objtool/check.c         |    5 ++---
 tools/objtool/check.h         |    2 +-
 5 files changed, 10 insertions(+), 10 deletions(-)

--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -53,5 +53,5 @@ int cmd_check(int argc, const char **arg
 
 	objname = argv[0];
 
-	return check(objname, no_fp, no_unreachable, false);
+	return check(objname, false);
 }
--- a/tools/objtool/builtin-orc.c
+++ b/tools/objtool/builtin-orc.c
@@ -25,7 +25,6 @@
  */
 
 #include <string.h>
-#include <subcmd/parse-options.h>
 #include "builtin.h"
 #include "check.h"
 
@@ -36,9 +35,6 @@ static const char *orc_usage[] = {
 	NULL,
 };
 
-extern const struct option check_options[];
-extern bool no_fp, no_unreachable;
-
 int cmd_orc(int argc, const char **argv)
 {
 	const char *objname;
@@ -54,7 +50,7 @@ int cmd_orc(int argc, const char **argv)
 
 		objname = argv[0];
 
-		return check(objname, no_fp, no_unreachable, true);
+		return check(objname, true);
 	}
 
 	if (!strcmp(argv[0], "dump")) {
--- a/tools/objtool/builtin.h
+++ b/tools/objtool/builtin.h
@@ -17,6 +17,11 @@
 #ifndef _BUILTIN_H
 #define _BUILTIN_H
 
+#include <subcmd/parse-options.h>
+
+extern const struct option check_options[];
+extern bool no_fp, no_unreachable;
+
 extern int cmd_check(int argc, const char **argv);
 extern int cmd_orc(int argc, const char **argv);
 
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -18,6 +18,7 @@
 #include <string.h>
 #include <stdlib.h>
 
+#include "builtin.h"
 #include "check.h"
 #include "elf.h"
 #include "special.h"
@@ -33,7 +34,6 @@ struct alternative {
 };
 
 const char *objname;
-static bool no_fp;
 struct cfi_state initial_func_cfi;
 
 struct instruction *find_insn(struct objtool_file *file,
@@ -1978,13 +1978,12 @@ static void cleanup(struct objtool_file
 	elf_close(file->elf);
 }
 
-int check(const char *_objname, bool _no_fp, bool no_unreachable, bool orc)
+int check(const char *_objname, bool orc)
 {
 	struct objtool_file file;
 	int ret, warnings = 0;
 
 	objname = _objname;
-	no_fp = _no_fp;
 
 	file.elf = elf_open(objname, orc ? O_RDWR : O_RDONLY);
 	if (!file.elf)
--- a/tools/objtool/check.h
+++ b/tools/objtool/check.h
@@ -62,7 +62,7 @@ struct objtool_file {
 	bool ignore_unreachables, c_file, hints;
 };
 
-int check(const char *objname, bool no_fp, bool no_unreachable, bool orc);
+int check(const char *objname, bool orc);
 
 struct instruction *find_insn(struct objtool_file *file,
 			      struct section *sec, unsigned long offset);

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2 2/8] objtool: Add retpoline validation
  2018-02-12 12:48 [PATCH v2 0/8] objtool: retpoline validation Peter Zijlstra
  2018-02-12 12:48 ` [PATCH v2 1/8] objtool: Use existing global variables for options Peter Zijlstra
@ 2018-02-12 12:48 ` Peter Zijlstra
  2018-02-12 12:48 ` [PATCH v2 3/8] objtool: Add module specific retpoline rules Peter Zijlstra
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Peter Zijlstra @ 2018-02-12 12:48 UTC (permalink / raw)
  To: David Woodhouse, Thomas Gleixner, Josh Poimboeuf
  Cc: linux-kernel, Dave Hansen, Ashok Raj, Tim Chen, Andy Lutomirski,
	Linus Torvalds, Greg KH, Andrea Arcangeli, Andi Kleen,
	Arjan Van De Ven, Dan Williams, Paolo Bonzini, Jun Nakajima,
	Asit Mallick, Peter Zijlstra, David Woodhouse

[-- Attachment #1: peterz-objtool-indirect.patch --]
[-- Type: text/plain, Size: 5597 bytes --]

David requested a objtool validation pass for RETPOLINE enabled
builds, where it validates no unannotated indirect  jumps or calls are
left.

Add an additional .discard.retpoline_safe section to allow annotating
the few indirect sites that are required and safe.

Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
Requested-by: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 scripts/Makefile.build        |    4 +
 tools/objtool/builtin-check.c |    3 -
 tools/objtool/builtin.h       |    2 
 tools/objtool/check.c         |   86 +++++++++++++++++++++++++++++++++++++++++-
 tools/objtool/check.h         |    1 
 5 files changed, 93 insertions(+), 3 deletions(-)

--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -264,6 +264,10 @@ objtool_args += --no-unreachable
 else
 objtool_args += $(call cc-ifversion, -lt, 0405, --no-unreachable)
 endif
+ifdef CONFIG_RETPOLINE
+  objtool_args += --retpoline
+endif
+
 
 ifdef CONFIG_MODVERSIONS
 objtool_o = $(@D)/.tmp_$(@F)
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -29,7 +29,7 @@
 #include "builtin.h"
 #include "check.h"
 
-bool no_fp, no_unreachable;
+bool no_fp, no_unreachable, retpoline;
 
 static const char * const check_usage[] = {
 	"objtool check [<options>] file.o",
@@ -39,6 +39,7 @@ static const char * const check_usage[]
 const struct option check_options[] = {
 	OPT_BOOLEAN('f', "no-fp", &no_fp, "Skip frame pointer validation"),
 	OPT_BOOLEAN('u', "no-unreachable", &no_unreachable, "Skip 'unreachable instruction' warnings"),
+	OPT_BOOLEAN('r', "retpoline", &retpoline, "Validate retpoline assumptions"),
 	OPT_END(),
 };
 
--- a/tools/objtool/builtin.h
+++ b/tools/objtool/builtin.h
@@ -20,7 +20,7 @@
 #include <subcmd/parse-options.h>
 
 extern const struct option check_options[];
-extern bool no_fp, no_unreachable;
+extern bool no_fp, no_unreachable, retpoline;
 
 extern int cmd_check(int argc, const char **argv);
 extern int cmd_orc(int argc, const char **argv);
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -496,6 +496,7 @@ static int add_jump_destinations(struct
 			 * disguise, so convert them accordingly.
 			 */
 			insn->type = INSN_JUMP_DYNAMIC;
+			insn->retpoline_safe = true;
 			continue;
 		} else {
 			/* sibling call */
@@ -547,7 +548,8 @@ static int add_call_destinations(struct
 			if (!insn->call_dest && !insn->ignore) {
 				WARN_FUNC("unsupported intra-function call",
 					  insn->sec, insn->offset);
-				WARN("If this is a retpoline, please patch it in with alternatives and annotate it with ANNOTATE_NOSPEC_ALTERNATIVE.");
+				if (retpoline)
+					WARN("If this is a retpoline, please patch it in with alternatives and annotate it with ANNOTATE_NOSPEC_ALTERNATIVE.");
 				return -1;
 			}
 
@@ -1107,6 +1109,54 @@ static int read_unwind_hints(struct objt
 	return 0;
 }
 
+static int read_retpoline_hints(struct objtool_file *file)
+{
+	struct section *sec, *relasec;
+	struct instruction *insn;
+	struct rela *rela;
+	int i;
+
+	sec = find_section_by_name(file->elf, ".discard.retpoline_safe");
+	if (!sec)
+		return 0;
+
+	relasec = sec->rela;
+	if (!relasec) {
+		WARN("missing .rela.discard.retpoline_safe section");
+		return -1;
+	}
+
+	if (sec->len % sizeof(unsigned long)) {
+		WARN("retpoline_safe size mismatch: %d %ld", sec->len, sizeof(unsigned long));
+		return -1;
+	}
+
+	for (i = 0; i < sec->len / sizeof(unsigned long); i++) {
+		rela = find_rela_by_dest(sec, i * sizeof(unsigned long));
+		if (!rela) {
+			WARN("can't find rela for retpoline_safe[%d]", i);
+			return -1;
+		}
+
+		insn = find_insn(file, rela->sym->sec, rela->addend);
+		if (!insn) {
+			WARN("can't find insn for retpoline_safe[%d]", i);
+			return -1;
+		}
+
+		if (insn->type != INSN_JUMP_DYNAMIC &&
+		    insn->type != INSN_CALL_DYNAMIC) {
+			WARN_FUNC("retpoline_safe hint not a indirect jump/call",
+				  insn->sec, insn->offset);
+			return -1;
+		}
+
+		insn->retpoline_safe = true;
+	}
+
+	return 0;
+}
+
 static int decode_sections(struct objtool_file *file)
 {
 	int ret;
@@ -1145,6 +1195,10 @@ static int decode_sections(struct objtoo
 	if (ret)
 		return ret;
 
+	ret = read_retpoline_hints(file);
+	if (ret)
+		return ret;
+
 	return 0;
 }
 
@@ -1890,6 +1944,29 @@ static int validate_unwind_hints(struct
 	return warnings;
 }
 
+static int validate_retpoline(struct objtool_file *file)
+{
+	struct instruction *insn;
+	int warnings = 0;
+
+	for_each_insn(file, insn) {
+		if (insn->type != INSN_JUMP_DYNAMIC &&
+		    insn->type != INSN_CALL_DYNAMIC)
+			continue;
+
+		if (insn->retpoline_safe)
+			continue;
+
+		WARN_FUNC("indirect %s found in RETPOLINE build",
+			  insn->sec, insn->offset,
+			  insn->type == INSN_JUMP_DYNAMIC ? "jump" : "call");
+
+		warnings++;
+	}
+
+	return warnings;
+}
+
 static bool is_kasan_insn(struct instruction *insn)
 {
 	return (insn->type == INSN_CALL &&
@@ -2044,6 +2121,13 @@ int check(const char *_objname, bool orc
 	if (list_empty(&file.insn_list))
 		goto out;
 
+	if (retpoline) {
+		ret = validate_retpoline(&file);
+		if (ret < 0)
+			return ret;
+		warnings += ret;
+	}
+
 	ret = validate_functions(&file);
 	if (ret < 0)
 		goto out;
--- a/tools/objtool/check.h
+++ b/tools/objtool/check.h
@@ -45,6 +45,7 @@ struct instruction {
 	unsigned char type;
 	unsigned long immediate;
 	bool alt_group, visited, dead_end, ignore, hint, save, restore, ignore_alts;
+	bool retpoline_safe;
 	struct symbol *call_dest;
 	struct instruction *jump_dest;
 	struct instruction *first_jump_src;

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2 3/8] objtool: Add module specific retpoline rules
  2018-02-12 12:48 [PATCH v2 0/8] objtool: retpoline validation Peter Zijlstra
  2018-02-12 12:48 ` [PATCH v2 1/8] objtool: Use existing global variables for options Peter Zijlstra
  2018-02-12 12:48 ` [PATCH v2 2/8] objtool: Add retpoline validation Peter Zijlstra
@ 2018-02-12 12:48 ` Peter Zijlstra
  2018-02-12 13:01   ` David Woodhouse
  2018-02-12 12:48 ` [PATCH v2 4/8] objtool: Retpoline validation tweaks Peter Zijlstra
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 13+ messages in thread
From: Peter Zijlstra @ 2018-02-12 12:48 UTC (permalink / raw)
  To: David Woodhouse, Thomas Gleixner, Josh Poimboeuf
  Cc: linux-kernel, Dave Hansen, Ashok Raj, Tim Chen, Andy Lutomirski,
	Linus Torvalds, Greg KH, Andrea Arcangeli, Andi Kleen,
	Arjan Van De Ven, Dan Williams, Paolo Bonzini, Jun Nakajima,
	Asit Mallick, Peter Zijlstra

[-- Attachment #1: peterz-objtool-module-rules.patch --]
[-- Type: text/plain, Size: 2490 bytes --]

David wanted to not use retpolines in .init.text but that will trip up
objtool retpoline validation, fix that.

Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
Requested-by: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 scripts/Makefile.build        |    2 ++
 tools/objtool/builtin-check.c |    3 ++-
 tools/objtool/builtin.h       |    2 +-
 tools/objtool/check.c         |    9 +++++++++
 4 files changed, 14 insertions(+), 2 deletions(-)

--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -256,6 +256,8 @@ __objtool_obj := $(objtree)/tools/objtoo
 
 objtool_args = $(if $(CONFIG_UNWINDER_ORC),orc generate,check)
 
+objtool_args += $(if $(part-of-module), --module,)
+
 ifndef CONFIG_FRAME_POINTER
 objtool_args += --no-fp
 endif
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -29,7 +29,7 @@
 #include "builtin.h"
 #include "check.h"
 
-bool no_fp, no_unreachable, retpoline;
+bool no_fp, no_unreachable, retpoline, module;
 
 static const char * const check_usage[] = {
 	"objtool check [<options>] file.o",
@@ -40,6 +40,7 @@ const struct option check_options[] = {
 	OPT_BOOLEAN('f', "no-fp", &no_fp, "Skip frame pointer validation"),
 	OPT_BOOLEAN('u', "no-unreachable", &no_unreachable, "Skip 'unreachable instruction' warnings"),
 	OPT_BOOLEAN('r', "retpoline", &retpoline, "Validate retpoline assumptions"),
+	OPT_BOOLEAN('m', "module", &module, "Indicates the object will be part of a kernel module"),
 	OPT_END(),
 };
 
--- a/tools/objtool/builtin.h
+++ b/tools/objtool/builtin.h
@@ -20,7 +20,7 @@
 #include <subcmd/parse-options.h>
 
 extern const struct option check_options[];
-extern bool no_fp, no_unreachable, retpoline;
+extern bool no_fp, no_unreachable, retpoline, module;
 
 extern int cmd_check(int argc, const char **argv);
 extern int cmd_orc(int argc, const char **argv);
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1920,6 +1920,15 @@ static int validate_retpoline(struct obj
 		if (insn->retpoline_safe)
 			continue;
 
+		/*
+		 * .init.text code is ran before userspace and thus doesn't
+		 * strictly need retpolines, except for modules which are
+		 * loaded late, they very much do need retpoline in their
+		 * .init.text
+		 */
+		if (!strcmp(insn->sec->name, ".init.text") && !module)
+			continue;
+
 		WARN_FUNC("indirect %s found in RETPOLINE build",
 			  insn->sec, insn->offset,
 			  insn->type == INSN_JUMP_DYNAMIC ? "jump" : "call");

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2 4/8] objtool: Retpoline validation tweaks
  2018-02-12 12:48 [PATCH v2 0/8] objtool: retpoline validation Peter Zijlstra
                   ` (2 preceding siblings ...)
  2018-02-12 12:48 ` [PATCH v2 3/8] objtool: Add module specific retpoline rules Peter Zijlstra
@ 2018-02-12 12:48 ` Peter Zijlstra
  2018-02-12 12:57   ` David Woodhouse
  2018-02-12 12:49 ` [PATCH v2 5/8] x86,nospec: Annotate indirect calls/jumps Peter Zijlstra
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 13+ messages in thread
From: Peter Zijlstra @ 2018-02-12 12:48 UTC (permalink / raw)
  To: David Woodhouse, Thomas Gleixner, Josh Poimboeuf
  Cc: linux-kernel, Dave Hansen, Ashok Raj, Tim Chen, Andy Lutomirski,
	Linus Torvalds, Greg KH, Andrea Arcangeli, Andi Kleen,
	Arjan Van De Ven, Dan Williams, Paolo Bonzini, Jun Nakajima,
	Asit Mallick, Peter Zijlstra

[-- Attachment #1: peterz-objtool-config.patch --]
[-- Type: text/plain, Size: 1460 bytes --]

Disable retpoline validation if your compiler sucks, and otherwise
select the validation stuff for RETPOLINE (most builds would already
have it set due to ORC).

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 Makefile               |    5 +++++
 arch/x86/Kconfig       |    1 +
 scripts/Makefile.build |    2 ++
 3 files changed, 8 insertions(+)

--- a/Makefile
+++ b/Makefile
@@ -486,6 +486,11 @@ KBUILD_CFLAGS += $(CLANG_TARGET) $(CLANG
 KBUILD_AFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC)
 endif
 
+ifneq ($(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register),)
+  CC_HAS_RETPOLINE := 1
+endif
+export CC_HAS_RETPOLINE
+
 ifeq ($(config-targets),1)
 # ===========================================================================
 # *config targets only - make sure prerequisites are updated, and descend
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -432,6 +432,7 @@ config GOLDFISH
 config RETPOLINE
 	bool "Avoid speculative indirect branches in kernel"
 	default y
+	select STACK_VALIDATION
 	help
 	  Compile kernel with the retpoline compiler options to guard against
 	  kernel-to-user data leaks by avoiding speculative indirect
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -267,8 +267,10 @@ else
 objtool_args += $(call cc-ifversion, -lt, 0405, --no-unreachable)
 endif
 ifdef CONFIG_RETPOLINE
+ifdef CC_HAS_RETPOLINE
   objtool_args += --retpoline
 endif
+endif
 
 
 ifdef CONFIG_MODVERSIONS

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2 5/8] x86,nospec: Annotate indirect calls/jumps
  2018-02-12 12:48 [PATCH v2 0/8] objtool: retpoline validation Peter Zijlstra
                   ` (3 preceding siblings ...)
  2018-02-12 12:48 ` [PATCH v2 4/8] objtool: Retpoline validation tweaks Peter Zijlstra
@ 2018-02-12 12:49 ` Peter Zijlstra
  2018-02-12 12:49 ` [PATCH v2 6/8] x86/paravirt: Annotate indirect calls Peter Zijlstra
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Peter Zijlstra @ 2018-02-12 12:49 UTC (permalink / raw)
  To: David Woodhouse, Thomas Gleixner, Josh Poimboeuf
  Cc: linux-kernel, Dave Hansen, Ashok Raj, Tim Chen, Andy Lutomirski,
	Linus Torvalds, Greg KH, Andrea Arcangeli, Andi Kleen,
	Arjan Van De Ven, Dan Williams, Paolo Bonzini, Jun Nakajima,
	Asit Mallick, Peter Zijlstra, David Woodhouse

[-- Attachment #1: peterz-retpoline-annotate-nospec.patch --]
[-- Type: text/plain, Size: 2405 bytes --]

Annotate the indirect calls/jumps in the CALL_NOSPEC/JUMP_NOSPEC
alternatives.

Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/nospec-branch.h |   27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

--- a/arch/x86/include/asm/nospec-branch.h
+++ b/arch/x86/include/asm/nospec-branch.h
@@ -67,6 +67,18 @@
 .endm
 
 /*
+ * This should be used immediately before an indirect jump/call. It tells
+ * objtool the subsequent indirect jump/call is vouched safe for retpoline
+ * builds.
+ */
+.macro ANNOTATE_RETPOLINE_SAFE
+	.Lannotate_\@:
+	.pushsection .discard.retpoline_safe
+	_ASM_PTR .Lannotate_\@
+	.popsection
+.endm
+
+/*
  * These are the bare retpoline primitives for indirect jmp and call.
  * Do not use these directly; they only exist to make the ALTERNATIVE
  * invocation below less ugly.
@@ -102,9 +114,9 @@
 .macro JMP_NOSPEC reg:req
 #ifdef CONFIG_RETPOLINE
 	ANNOTATE_NOSPEC_ALTERNATIVE
-	ALTERNATIVE_2 __stringify(jmp *\reg),				\
+	ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *\reg),	\
 		__stringify(RETPOLINE_JMP \reg), X86_FEATURE_RETPOLINE,	\
-		__stringify(lfence; jmp *\reg), X86_FEATURE_RETPOLINE_AMD
+		__stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *\reg), X86_FEATURE_RETPOLINE_AMD
 #else
 	jmp	*\reg
 #endif
@@ -113,9 +125,9 @@
 .macro CALL_NOSPEC reg:req
 #ifdef CONFIG_RETPOLINE
 	ANNOTATE_NOSPEC_ALTERNATIVE
-	ALTERNATIVE_2 __stringify(call *\reg),				\
+	ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; call *\reg),	\
 		__stringify(RETPOLINE_CALL \reg), X86_FEATURE_RETPOLINE,\
-		__stringify(lfence; call *\reg), X86_FEATURE_RETPOLINE_AMD
+		__stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *\reg), X86_FEATURE_RETPOLINE_AMD
 #else
 	call	*\reg
 #endif
@@ -143,6 +155,12 @@
 	".long 999b - .\n\t"					\
 	".popsection\n\t"
 
+#define ANNOTATE_RETPOLINE_SAFE					\
+	"999:\n\t"						\
+	".pushsection .discard.retpoline_safe\n\t"		\
+	_ASM_PTR " 999b\n\t"					\
+	".popsection\n\t"
+
 #if defined(CONFIG_X86_64) && defined(RETPOLINE)
 
 /*
@@ -152,6 +170,7 @@
 # define CALL_NOSPEC						\
 	ANNOTATE_NOSPEC_ALTERNATIVE				\
 	ALTERNATIVE(						\
+	ANNOTATE_RETPOLINE_SAFE					\
 	"call *%[thunk_target]\n",				\
 	"call __x86_indirect_thunk_%V[thunk_target]\n",		\
 	X86_FEATURE_RETPOLINE)

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2 6/8] x86/paravirt: Annotate indirect calls
  2018-02-12 12:48 [PATCH v2 0/8] objtool: retpoline validation Peter Zijlstra
                   ` (4 preceding siblings ...)
  2018-02-12 12:49 ` [PATCH v2 5/8] x86,nospec: Annotate indirect calls/jumps Peter Zijlstra
@ 2018-02-12 12:49 ` Peter Zijlstra
  2018-02-12 12:49 ` [PATCH v2 7/8] x86: Annotate indirect jump in head_64.S Peter Zijlstra
  2018-02-12 12:49 ` [PATCH v2 8/8] x86,sme: Annotate indirect call Peter Zijlstra
  7 siblings, 0 replies; 13+ messages in thread
From: Peter Zijlstra @ 2018-02-12 12:49 UTC (permalink / raw)
  To: David Woodhouse, Thomas Gleixner, Josh Poimboeuf
  Cc: linux-kernel, Dave Hansen, Ashok Raj, Tim Chen, Andy Lutomirski,
	Linus Torvalds, Greg KH, Andrea Arcangeli, Andi Kleen,
	Arjan Van De Ven, Dan Williams, Paolo Bonzini, Jun Nakajima,
	Asit Mallick, Peter Zijlstra, David Woodhouse

[-- Attachment #1: peterz-retpoline-annotate-pv.patch --]
[-- Type: text/plain, Size: 3860 bytes --]

Paravirt emits indirect calls which get flagged by objtool retpoline
checks, annotate it away because all these indirect calls will be
patched out before we start userspace.

This patching happens through alternative_instructions() ->
apply_paravirt() -> pv_init_ops.patch() which will eventually end up
in paravirt_patch_default(). This function _will_ write direct
alternatives.

Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/paravirt.h       |   17 +++++++++++++----
 arch/x86/include/asm/paravirt_types.h |    5 ++++-
 2 files changed, 17 insertions(+), 5 deletions(-)

--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -7,6 +7,7 @@
 #ifdef CONFIG_PARAVIRT
 #include <asm/pgtable_types.h>
 #include <asm/asm.h>
+#include <asm/nospec-branch.h>
 
 #include <asm/paravirt_types.h>
 
@@ -879,23 +880,27 @@ extern void default_banner(void);
 
 #define INTERRUPT_RETURN						\
 	PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE,	\
-		  jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_iret))
+		  ANNOTATE_RETPOLINE_SAFE;					\
+		  jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_iret);)
 
 #define DISABLE_INTERRUPTS(clobbers)					\
 	PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \
 		  PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE);		\
+		  ANNOTATE_RETPOLINE_SAFE;					\
 		  call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_disable);	\
 		  PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);)
 
 #define ENABLE_INTERRUPTS(clobbers)					\
 	PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers,	\
 		  PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE);		\
+		  ANNOTATE_RETPOLINE_SAFE;					\
 		  call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_enable);	\
 		  PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);)
 
 #ifdef CONFIG_X86_32
 #define GET_CR0_INTO_EAX				\
 	push %ecx; push %edx;				\
+	ANNOTATE_RETPOLINE_SAFE;				\
 	call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0);	\
 	pop %edx; pop %ecx
 #else	/* !CONFIG_X86_32 */
@@ -917,21 +922,25 @@ extern void default_banner(void);
  */
 #define SWAPGS								\
 	PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE,	\
-		  call PARA_INDIRECT(pv_cpu_ops+PV_CPU_swapgs)		\
+		  ANNOTATE_RETPOLINE_SAFE;					\
+		  call PARA_INDIRECT(pv_cpu_ops+PV_CPU_swapgs);		\
 		 )
 
 #define GET_CR2_INTO_RAX				\
-	call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2)
+	ANNOTATE_RETPOLINE_SAFE;				\
+	call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2);
 
 #define USERGS_SYSRET64							\
 	PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret64),	\
 		  CLBR_NONE,						\
-		  jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_usergs_sysret64))
+		  ANNOTATE_RETPOLINE_SAFE;					\
+		  jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_usergs_sysret64);)
 
 #ifdef CONFIG_DEBUG_ENTRY
 #define SAVE_FLAGS(clobbers)                                        \
 	PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_save_fl), clobbers, \
 		  PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE);        \
+		  ANNOTATE_RETPOLINE_SAFE;				    \
 		  call PARA_INDIRECT(pv_irq_ops+PV_IRQ_save_fl);    \
 		  PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);)
 #endif
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -43,6 +43,7 @@
 #include <asm/desc_defs.h>
 #include <asm/kmap_types.h>
 #include <asm/pgtable_types.h>
+#include <asm/nospec-branch.h>
 
 struct page;
 struct thread_struct;
@@ -392,7 +393,9 @@ int paravirt_disable_iospace(void);
  * offset into the paravirt_patch_template structure, and can therefore be
  * freely converted back into a structure offset.
  */
-#define PARAVIRT_CALL	"call *%c[paravirt_opptr];"
+#define PARAVIRT_CALL					\
+	ANNOTATE_RETPOLINE_SAFE				\
+	"call *%c[paravirt_opptr];"
 
 /*
  * These macros are intended to wrap calls through one of the paravirt

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2 7/8] x86: Annotate indirect jump in head_64.S
  2018-02-12 12:48 [PATCH v2 0/8] objtool: retpoline validation Peter Zijlstra
                   ` (5 preceding siblings ...)
  2018-02-12 12:49 ` [PATCH v2 6/8] x86/paravirt: Annotate indirect calls Peter Zijlstra
@ 2018-02-12 12:49 ` Peter Zijlstra
  2018-02-12 12:49 ` [PATCH v2 8/8] x86,sme: Annotate indirect call Peter Zijlstra
  7 siblings, 0 replies; 13+ messages in thread
From: Peter Zijlstra @ 2018-02-12 12:49 UTC (permalink / raw)
  To: David Woodhouse, Thomas Gleixner, Josh Poimboeuf
  Cc: linux-kernel, Dave Hansen, Ashok Raj, Tim Chen, Andy Lutomirski,
	Linus Torvalds, Greg KH, Andrea Arcangeli, Andi Kleen,
	Arjan Van De Ven, Dan Williams, Paolo Bonzini, Jun Nakajima,
	Asit Mallick, Peter Zijlstra, David Woodhouse

[-- Attachment #1: peterz-objtool-retpoline-annotate.patch --]
[-- Type: text/plain, Size: 810 bytes --]

The objtool retpoline validation found this indirect jump. Seeing how
it's on CPU bringup before we run userspace it should be safe, annotate
it.

Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/kernel/head_64.S |    2 ++
 1 file changed, 2 insertions(+)

--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -23,6 +23,7 @@
 #include <asm/nops.h>
 #include "../entry/calling.h"
 #include <asm/export.h>
+#include <asm/nospec-branch.h>
 
 #ifdef CONFIG_PARAVIRT
 #include <asm/asm-offsets.h>
@@ -134,6 +135,7 @@ ENTRY(secondary_startup_64)
 
 	/* Ensure I am executing from virtual addresses */
 	movq	$1f, %rax
+	ANNOTATE_RETPOLINE_SAFE
 	jmp	*%rax
 1:
 	UNWIND_HINT_EMPTY

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2 8/8] x86,sme: Annotate indirect call
  2018-02-12 12:48 [PATCH v2 0/8] objtool: retpoline validation Peter Zijlstra
                   ` (6 preceding siblings ...)
  2018-02-12 12:49 ` [PATCH v2 7/8] x86: Annotate indirect jump in head_64.S Peter Zijlstra
@ 2018-02-12 12:49 ` Peter Zijlstra
  7 siblings, 0 replies; 13+ messages in thread
From: Peter Zijlstra @ 2018-02-12 12:49 UTC (permalink / raw)
  To: David Woodhouse, Thomas Gleixner, Josh Poimboeuf
  Cc: linux-kernel, Dave Hansen, Ashok Raj, Tim Chen, Andy Lutomirski,
	Linus Torvalds, Greg KH, Andrea Arcangeli, Andi Kleen,
	Arjan Van De Ven, Dan Williams, Paolo Bonzini, Jun Nakajima,
	Asit Mallick, Peter Zijlstra, Tom Lendacky, Borislav Petkov

[-- Attachment #1: peterz-retpoline-annotate-sme.patch --]
[-- Type: text/plain, Size: 843 bytes --]

This is boot code, we run this _way_ before userspace comes along to
poison our branch predictor.

Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Borislav Petkov <bp@suse.de>
Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/mm/mem_encrypt_boot.S |    2 ++
 1 file changed, 2 insertions(+)

--- a/arch/x86/mm/mem_encrypt_boot.S
+++ b/arch/x86/mm/mem_encrypt_boot.S
@@ -15,6 +15,7 @@
 #include <asm/page.h>
 #include <asm/processor-flags.h>
 #include <asm/msr-index.h>
+#include <asm/nospec-branch.h>
 
 	.text
 	.code64
@@ -59,6 +60,7 @@ ENTRY(sme_encrypt_execute)
 	movq	%rax, %r8		/* Workarea encryption routine */
 	addq	$PAGE_SIZE, %r8		/* Workarea intermediate copy buffer */
 
+	ANNOTATE_RETPOLINE_SAFE
 	call	*%rax			/* Call the encryption routine */
 
 	pop	%r12

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 4/8] objtool: Retpoline validation tweaks
  2018-02-12 12:48 ` [PATCH v2 4/8] objtool: Retpoline validation tweaks Peter Zijlstra
@ 2018-02-12 12:57   ` David Woodhouse
  2018-02-12 14:59     ` Peter Zijlstra
  0 siblings, 1 reply; 13+ messages in thread
From: David Woodhouse @ 2018-02-12 12:57 UTC (permalink / raw)
  To: Peter Zijlstra, Thomas Gleixner, Josh Poimboeuf
  Cc: linux-kernel, Dave Hansen, Ashok Raj, Tim Chen, Andy Lutomirski,
	Linus Torvalds, Greg KH, Andrea Arcangeli, Andi Kleen,
	Arjan Van De Ven, Dan Williams, Paolo Bonzini, Jun Nakajima,
	Asit Mallick

[-- Attachment #1: Type: text/plain, Size: 682 bytes --]



On Mon, 2018-02-12 at 13:48 +0100, Peter Zijlstra wrote:
> --- a/Makefile
> +++ b/Makefile
> @@ -486,6 +486,11 @@ KBUILD_CFLAGS += $(CLANG_TARGET) $(CLANG
>  KBUILD_AFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC)
>  endif
>  
> +ifneq ($(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register),)
> +  CC_HAS_RETPOLINE := 1
> +endif
> +export CC_HAS_RETPOLINE

Can't you do that with the existing check in arch/x86/Makefile? 

cf. http://git.infradead.org/users/dwmw2/linux-retpoline.git/commitdiff/eb12299ed
which is going nowhere until https://bugs.llvm.org/show_bug.cgi?id=36329
gets fixed but still I'd like to have the check in *one* place.

[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 5213 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 3/8] objtool: Add module specific retpoline rules
  2018-02-12 12:48 ` [PATCH v2 3/8] objtool: Add module specific retpoline rules Peter Zijlstra
@ 2018-02-12 13:01   ` David Woodhouse
  2018-02-12 13:07     ` Peter Zijlstra
  0 siblings, 1 reply; 13+ messages in thread
From: David Woodhouse @ 2018-02-12 13:01 UTC (permalink / raw)
  To: Peter Zijlstra, Thomas Gleixner, Josh Poimboeuf
  Cc: linux-kernel, Dave Hansen, Ashok Raj, Tim Chen, Andy Lutomirski,
	Linus Torvalds, Greg KH, Andrea Arcangeli, Andi Kleen,
	Arjan Van De Ven, Dan Williams, Paolo Bonzini, Jun Nakajima,
	Asit Mallick

[-- Attachment #1: Type: text/plain, Size: 513 bytes --]

On Mon, 2018-02-12 at 13:48 +0100, Peter Zijlstra wrote:
> David wanted to not use retpolines in .init.text but that will trip up
> objtool retpoline validation, fix that.

I wanted, I got. This is upstream already (66f793099a63) so this commit
message possibly wants tweaking slightly.

> Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
> Requested-by: David Woodhouse <dwmw2@infradead.org>
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Acked-by: David Woodhouse <dwmw@amazon.co.uk>

[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 5213 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 3/8] objtool: Add module specific retpoline rules
  2018-02-12 13:01   ` David Woodhouse
@ 2018-02-12 13:07     ` Peter Zijlstra
  0 siblings, 0 replies; 13+ messages in thread
From: Peter Zijlstra @ 2018-02-12 13:07 UTC (permalink / raw)
  To: David Woodhouse
  Cc: Thomas Gleixner, Josh Poimboeuf, linux-kernel, Dave Hansen,
	Ashok Raj, Tim Chen, Andy Lutomirski, Linus Torvalds, Greg KH,
	Andrea Arcangeli, Andi Kleen, Arjan Van De Ven, Dan Williams,
	Paolo Bonzini, Jun Nakajima, Asit Mallick

On Mon, Feb 12, 2018 at 01:01:20PM +0000, David Woodhouse wrote:
> On Mon, 2018-02-12 at 13:48 +0100, Peter Zijlstra wrote:
> > David wanted to not use retpolines in .init.text but that will trip up
> > objtool retpoline validation, fix that.
> 
> I wanted, I got. This is upstream already (66f793099a63) so this commit
> message possibly wants tweaking slightly.

Right you are, I should have re-read these Changelogs before posting ;-)

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 4/8] objtool: Retpoline validation tweaks
  2018-02-12 12:57   ` David Woodhouse
@ 2018-02-12 14:59     ` Peter Zijlstra
  0 siblings, 0 replies; 13+ messages in thread
From: Peter Zijlstra @ 2018-02-12 14:59 UTC (permalink / raw)
  To: David Woodhouse
  Cc: Thomas Gleixner, Josh Poimboeuf, linux-kernel, Dave Hansen,
	Ashok Raj, Tim Chen, Andy Lutomirski, Linus Torvalds, Greg KH,
	Andrea Arcangeli, Andi Kleen, Arjan Van De Ven, Dan Williams,
	Paolo Bonzini, Jun Nakajima, Asit Mallick

On Mon, Feb 12, 2018 at 12:57:40PM +0000, David Woodhouse wrote:
> 
> 
> On Mon, 2018-02-12 at 13:48 +0100, Peter Zijlstra wrote:
> > --- a/Makefile
> > +++ b/Makefile
> > @@ -486,6 +486,11 @@ KBUILD_CFLAGS += $(CLANG_TARGET) $(CLANG
> >  KBUILD_AFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC)
> >  endif
> >  
> > +ifneq ($(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register),)
> > +  CC_HAS_RETPOLINE := 1
> > +endif
> > +export CC_HAS_RETPOLINE
> 
> Can't you do that with the existing check in arch/x86/Makefile? 

I couldn't make it work there, but it could be my makefile foo isn't
strong enough. The ordering of arch/*/Makefile vs scripts/Makefile.build
is forever confusing me.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2018-02-12 14:59 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-12 12:48 [PATCH v2 0/8] objtool: retpoline validation Peter Zijlstra
2018-02-12 12:48 ` [PATCH v2 1/8] objtool: Use existing global variables for options Peter Zijlstra
2018-02-12 12:48 ` [PATCH v2 2/8] objtool: Add retpoline validation Peter Zijlstra
2018-02-12 12:48 ` [PATCH v2 3/8] objtool: Add module specific retpoline rules Peter Zijlstra
2018-02-12 13:01   ` David Woodhouse
2018-02-12 13:07     ` Peter Zijlstra
2018-02-12 12:48 ` [PATCH v2 4/8] objtool: Retpoline validation tweaks Peter Zijlstra
2018-02-12 12:57   ` David Woodhouse
2018-02-12 14:59     ` Peter Zijlstra
2018-02-12 12:49 ` [PATCH v2 5/8] x86,nospec: Annotate indirect calls/jumps Peter Zijlstra
2018-02-12 12:49 ` [PATCH v2 6/8] x86/paravirt: Annotate indirect calls Peter Zijlstra
2018-02-12 12:49 ` [PATCH v2 7/8] x86: Annotate indirect jump in head_64.S Peter Zijlstra
2018-02-12 12:49 ` [PATCH v2 8/8] x86,sme: Annotate indirect call Peter Zijlstra

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.