[RFC PATCH 1/5] x86: introduce preemption disable prefix

From: Nadav Amit
Date: Wed Oct 17 2018 - 20:56:40 EST


It is sometimes beneficial to prevent preemption for very few
instructions, or prevent preemption for some instructions that precede
a branch (this latter case will be introduced in the next patches).

To provide such functionality on x86-64, we use an empty REX-prefix
(opcode 0x40) as an indication that preemption is disabled for the
following instruction.

It is expected that this opcode is not in common use.

Signed-off-by: Nadav Amit <namit@xxxxxxxxxx>
---
arch/x86/entry/entry_64.S | 10 ++++++++++
arch/x86/include/asm/nospec-branch.h | 12 ++++++++++++
2 files changed, 22 insertions(+)

diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index cb8a5893fd33..31d59aad496e 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -643,6 +643,16 @@ retint_kernel:
jnc 1f
0: cmpl $0, PER_CPU_VAR(__preempt_count)
jnz 1f
+
+ /*
+ * Allow to use hint to prevent preemption on a certain instruction.
+ * Consider an instruction with the first byte having REX prefix
+ * without any bits set as an indication for preemption disabled.
+ */
+ movq RIP(%rsp), %rax
+ cmpb $PREEMPT_DISABLE_PREFIX, (%rax)
+ jz 1f
+
call preempt_schedule_irq
jmp 0b
1:
diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
index 80dc14422495..0267611eb247 100644
--- a/arch/x86/include/asm/nospec-branch.h
+++ b/arch/x86/include/asm/nospec-branch.h
@@ -52,6 +52,12 @@
jnz 771b; \
add $(BITS_PER_LONG/8) * nr, sp;

+/*
+ * An empty REX-prefix is an indication that preemption should not take place on
+ * this instruction.
+ */
+#define PREEMPT_DISABLE_PREFIX (0x40)
+
#ifdef __ASSEMBLY__

/*
@@ -148,6 +154,12 @@
#endif
.endm

+.macro preempt_disable_prefix
+#ifdef CONFIG_PREEMPT
+ .byte PREEMPT_DISABLE_PREFIX
+#endif
+.endm
+
#else /* __ASSEMBLY__ */

#define ANNOTATE_NOSPEC_ALTERNATIVE \
--
2.17.1