linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Juergen Gross <jgross@suse.com>
To: xen-devel@lists.xenproject.org, x86@kernel.org,
	linux-kernel@vger.kernel.org
Cc: Juergen Gross <jgross@suse.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
	"H. Peter Anvin" <hpa@zytor.com>,
	Josh Poimboeuf <jpoimboe@redhat.com>,
	Peter Zijlstra <peterz@infradead.org>
Subject: [PATCH v5 04/12] x86/alternative: support not-feature
Date: Mon,  8 Mar 2021 13:28:36 +0100	[thread overview]
Message-ID: <20210308122844.30488-5-jgross@suse.com> (raw)
In-Reply-To: <20210308122844.30488-1-jgross@suse.com>

Add support for alternative patching for the case a feature is not
present on the current cpu.

For this purpose add a flag byte to struct alt_instr adding the
information that the inverted feature should be used.

For users of ALTERNATIVE() and friends an inverted feature is specified
by negating it, e.g.:

ALTERNATIVE(old, new, ~feature)

This requires adapting the objtool information for struct alt_instr.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
V5:
- split off from next patch
- reworked to use flag byte (Boris Petkov)
---
 arch/x86/include/asm/alternative-asm.h        | 6 ++++++
 arch/x86/include/asm/alternative.h            | 8 ++++++++
 arch/x86/include/asm/cpufeature.h             | 2 ++
 arch/x86/kernel/alternative.c                 | 5 +++--
 tools/objtool/arch/x86/include/arch/special.h | 6 +++---
 5 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/alternative-asm.h b/arch/x86/include/asm/alternative-asm.h
index 464034db299f..9a1763550217 100644
--- a/arch/x86/include/asm/alternative-asm.h
+++ b/arch/x86/include/asm/alternative-asm.h
@@ -39,7 +39,13 @@
 .macro altinstruction_entry orig alt feature orig_len alt_len pad_len
 	.long \orig - .
 	.long \alt - .
+	.iflt \feature
+	.word ~(\feature)
+	.byte 1
+	.else
 	.word \feature
+	.byte 0
+	.endif
 	.byte \orig_len
 	.byte \alt_len
 	.byte \pad_len
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
index 5753fb2ac489..b9749cf21ada 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -59,6 +59,8 @@ struct alt_instr {
 	s32 instr_offset;	/* original instruction */
 	s32 repl_offset;	/* offset to replacement instruction */
 	u16 cpuid;		/* cpuid bit set for replacement */
+	u8  flag;		/* flag byte */
+#define ALTINSTR_FLAG_INV	0x01
 	u8  instrlen;		/* length of original instruction */
 	u8  replacementlen;	/* length of new instruction */
 	u8  padlen;		/* length of build-time padding */
@@ -145,7 +147,13 @@ static inline int alternatives_text_reserved(void *start, void *end)
 #define ALTINSTR_ENTRY(feature, num)					      \
 	" .long 661b - .\n"				/* label           */ \
 	" .long " b_replacement(num)"f - .\n"		/* new instruction */ \
+	" .iflt " __stringify(feature) "\n"		/* inverted?       */ \
+	" .word ~(" __stringify(feature) ")\n"		/* feature bit     */ \
+	" .byte " __stringify(ALTINSTR_FLAG_INV) "\n"	/* flag byte       */ \
+	" .else\n"							      \
 	" .word " __stringify(feature) "\n"		/* feature bit     */ \
+	" .byte 0\n"					/* flag byte       */ \
+	" .endif\n"							      \
 	" .byte " alt_total_slen "\n"			/* source len      */ \
 	" .byte " alt_rlen(num) "\n"			/* replacement len */ \
 	" .byte " alt_pad_len "\n"			/* pad len */
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 1728d4ce5730..f060d3186ee4 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -184,6 +184,7 @@ static __always_inline bool _static_cpu_has(u16 bit)
 		 " .long 1b - .\n"		/* src offset */
 		 " .long 4f - .\n"		/* repl offset */
 		 " .word %P[always]\n"		/* always replace */
+		 " .byte 0\n"			/* flag byte */
 		 " .byte 3b - 1b\n"		/* src len */
 		 " .byte 5f - 4f\n"		/* repl len */
 		 " .byte 3b - 2b\n"		/* pad len */
@@ -196,6 +197,7 @@ static __always_inline bool _static_cpu_has(u16 bit)
 		 " .long 1b - .\n"		/* src offset */
 		 " .long 0\n"			/* no replacement */
 		 " .word %P[feature]\n"		/* feature bit */
+		 " .byte 0\n"			/* flag byte */
 		 " .byte 3b - 1b\n"		/* src len */
 		 " .byte 0\n"			/* repl len */
 		 " .byte 0\n"			/* pad len */
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 8d778e46725d..1296a90aa5b8 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -393,14 +393,15 @@ void __init_or_module noinline apply_alternatives(struct alt_instr *start,
 		replacement = (u8 *)&a->repl_offset + a->repl_offset;
 		BUG_ON(a->instrlen > sizeof(insn_buff));
 		BUG_ON(a->cpuid >= (NCAPINTS + NBUGINTS) * 32);
-		if (!boot_cpu_has(a->cpuid)) {
+		if (!boot_cpu_has(a->cpuid) == !(a->flag & ALTINSTR_FLAG_INV)) {
 			if (a->padlen > 1)
 				optimize_nops(a, instr);
 
 			continue;
 		}
 
-		DPRINTK("feat: %d*32+%d, old: (%pS (%px) len: %d), repl: (%px, len: %d), pad: %d",
+		DPRINTK("feat: %s%d*32+%d, old: (%pS (%px) len: %d), repl: (%px, len: %d), pad: %d",
+			(a->flag & ALTINSTR_FLAG_INV) ? "~" : "",
 			a->cpuid >> 5,
 			a->cpuid & 0x1f,
 			instr, instr, a->instrlen,
diff --git a/tools/objtool/arch/x86/include/arch/special.h b/tools/objtool/arch/x86/include/arch/special.h
index d818b2bffa02..afde39063963 100644
--- a/tools/objtool/arch/x86/include/arch/special.h
+++ b/tools/objtool/arch/x86/include/arch/special.h
@@ -10,11 +10,11 @@
 #define JUMP_ORIG_OFFSET	0
 #define JUMP_NEW_OFFSET		4
 
-#define ALT_ENTRY_SIZE		13
+#define ALT_ENTRY_SIZE		14
 #define ALT_ORIG_OFFSET		0
 #define ALT_NEW_OFFSET		4
 #define ALT_FEATURE_OFFSET	8
-#define ALT_ORIG_LEN_OFFSET	10
-#define ALT_NEW_LEN_OFFSET	11
+#define ALT_ORIG_LEN_OFFSET	11
+#define ALT_NEW_LEN_OFFSET	12
 
 #endif /* _X86_ARCH_SPECIAL_H */
-- 
2.26.2


  parent reply	other threads:[~2021-03-08 12:29 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-08 12:28 [PATCH v5 00/12] x86: major paravirt cleanup Juergen Gross
2021-03-08 12:28 ` [PATCH v5 01/12] staticcall: move struct static_call_key definition to static_call_types.h Juergen Gross
2021-03-08 16:27   ` Peter Zijlstra
2021-03-08 12:28 ` [PATCH v5 02/12] x86/paravirt: switch time pvops functions to use static_call() Juergen Gross
2021-03-08 17:00   ` Boris Ostrovsky
2021-03-09  6:14     ` Jürgen Groß
2021-03-08 12:28 ` [PATCH v5 03/12] x86/alternative: drop feature parameter from ALTINSTR_REPLACEMENT() Juergen Gross
2021-03-08 12:28 ` Juergen Gross [this message]
2021-03-08 12:28 ` [PATCH v5 05/12] x86/alternative: support ALTERNATIVE_TERNARY Juergen Gross
2021-03-08 12:28 ` [PATCH v5 06/12] x86: add new features for paravirt patching Juergen Gross
2021-03-08 12:28 ` [PATCH v5 07/12] x86/paravirt: remove no longer needed 32-bit pvops cruft Juergen Gross
2021-03-08 12:28 ` [PATCH v5 08/12] x86/paravirt: simplify paravirt macros Juergen Gross
2021-03-08 12:28 ` [PATCH v5 09/12] x86/paravirt: switch iret pvops to ALTERNATIVE Juergen Gross
2021-03-08 12:28 ` [PATCH v5 10/12] x86/paravirt: add new macros PVOP_ALT* supporting pvops in ALTERNATIVEs Juergen Gross
2021-03-08 12:28 ` [PATCH v5 11/12] x86/paravirt: switch functions with custom code to ALTERNATIVE Juergen Gross
2021-03-08 18:30   ` Borislav Petkov
2021-03-09  6:21     ` Jürgen Groß
2021-03-08 12:28 ` [PATCH v5 12/12] x86/paravirt: have only one paravirt patch function Juergen Gross
2021-03-08 16:31 ` [PATCH v5 00/12] x86: major paravirt cleanup Peter Zijlstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210308122844.30488-5-jgross@suse.com \
    --to=jgross@suse.com \
    --cc=bp@alien8.de \
    --cc=hpa@zytor.com \
    --cc=jpoimboe@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).