Commit 8c69e7af authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'x86_alternatives_for_v6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 instruction alternatives updates from Borislav Petkov:

 - Up until now the Fast Short Rep Mov optimizations implied the
   presence of the ERMS CPUID flag. AMD decoupled them with a BIOS
   setting so decouple that dependency in the kernel code too

 - Teach the alternatives machinery to handle relocations

 - Make debug_alternative accept flags in order to see only that set of
   patching done one is interested in

 - Other fixes, cleanups and optimizations to the patching code

* tag 'x86_alternatives_for_v6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/alternative: PAUSE is not a NOP
  x86/alternatives: Add cond_resched() to text_poke_bp_batch()
  x86/nospec: Shorten RESET_CALL_DEPTH
  x86/alternatives: Add longer 64-bit NOPs
  x86/alternatives: Fix section mismatch warnings
  x86/alternative: Optimize returns patching
  x86/alternative: Complicate optimize_nops() some more
  x86/alternative: Rewrite optimize_nops() some
  x86/lib/memmove: Decouple ERMS from FSRM
  x86/alternative: Support relocations in alternatives
  x86/alternative: Make debug-alternative selective
parents aa35a483 2bd4aa93
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#define BYTES_NOP7 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00 #define BYTES_NOP7 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00
#define BYTES_NOP8 0x3e,BYTES_NOP7 #define BYTES_NOP8 0x3e,BYTES_NOP7
#define ASM_NOP_MAX 8
#else #else
/* /*
...@@ -47,6 +49,9 @@ ...@@ -47,6 +49,9 @@
* 6: osp nopl 0x00(%eax,%eax,1) * 6: osp nopl 0x00(%eax,%eax,1)
* 7: nopl 0x00000000(%eax) * 7: nopl 0x00000000(%eax)
* 8: nopl 0x00000000(%eax,%eax,1) * 8: nopl 0x00000000(%eax,%eax,1)
* 9: cs nopl 0x00000000(%eax,%eax,1)
* 10: osp cs nopl 0x00000000(%eax,%eax,1)
* 11: osp osp cs nopl 0x00000000(%eax,%eax,1)
*/ */
#define BYTES_NOP1 0x90 #define BYTES_NOP1 0x90
#define BYTES_NOP2 0x66,BYTES_NOP1 #define BYTES_NOP2 0x66,BYTES_NOP1
...@@ -56,6 +61,15 @@ ...@@ -56,6 +61,15 @@
#define BYTES_NOP6 0x66,BYTES_NOP5 #define BYTES_NOP6 0x66,BYTES_NOP5
#define BYTES_NOP7 0x0f,0x1f,0x80,0x00,0x00,0x00,0x00 #define BYTES_NOP7 0x0f,0x1f,0x80,0x00,0x00,0x00,0x00
#define BYTES_NOP8 0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00 #define BYTES_NOP8 0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00
#define BYTES_NOP9 0x2e,BYTES_NOP8
#define BYTES_NOP10 0x66,BYTES_NOP9
#define BYTES_NOP11 0x66,BYTES_NOP10
#define ASM_NOP9 _ASM_BYTES(BYTES_NOP9)
#define ASM_NOP10 _ASM_BYTES(BYTES_NOP10)
#define ASM_NOP11 _ASM_BYTES(BYTES_NOP11)
#define ASM_NOP_MAX 11
#endif /* CONFIG_64BIT */ #endif /* CONFIG_64BIT */
...@@ -68,8 +82,6 @@ ...@@ -68,8 +82,6 @@
#define ASM_NOP7 _ASM_BYTES(BYTES_NOP7) #define ASM_NOP7 _ASM_BYTES(BYTES_NOP7)
#define ASM_NOP8 _ASM_BYTES(BYTES_NOP8) #define ASM_NOP8 _ASM_BYTES(BYTES_NOP8)
#define ASM_NOP_MAX 8
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
extern const unsigned char * const x86_nops[]; extern const unsigned char * const x86_nops[];
#endif #endif
......
...@@ -84,12 +84,12 @@ ...@@ -84,12 +84,12 @@
movq $-1, PER_CPU_VAR(pcpu_hot + X86_call_depth); movq $-1, PER_CPU_VAR(pcpu_hot + X86_call_depth);
#define RESET_CALL_DEPTH \ #define RESET_CALL_DEPTH \
mov $0x80, %rax; \ xor %eax, %eax; \
shl $56, %rax; \ bts $63, %rax; \
movq %rax, PER_CPU_VAR(pcpu_hot + X86_call_depth); movq %rax, PER_CPU_VAR(pcpu_hot + X86_call_depth);
#define RESET_CALL_DEPTH_FROM_CALL \ #define RESET_CALL_DEPTH_FROM_CALL \
mov $0xfc, %rax; \ movb $0xfc, %al; \
shl $56, %rax; \ shl $56, %rax; \
movq %rax, PER_CPU_VAR(pcpu_hot + X86_call_depth); \ movq %rax, PER_CPU_VAR(pcpu_hot + X86_call_depth); \
CALL_THUNKS_DEBUG_INC_CALLS CALL_THUNKS_DEBUG_INC_CALLS
......
This diff is collapsed.
...@@ -38,10 +38,12 @@ SYM_FUNC_START(__memmove) ...@@ -38,10 +38,12 @@ SYM_FUNC_START(__memmove)
cmp %rdi, %r8 cmp %rdi, %r8
jg 2f jg 2f
/* FSRM implies ERMS => no length checks, do the copy directly */ #define CHECK_LEN cmp $0x20, %rdx; jb 1f
#define MEMMOVE_BYTES movq %rdx, %rcx; rep movsb; RET
.Lmemmove_begin_forward: .Lmemmove_begin_forward:
ALTERNATIVE "cmp $0x20, %rdx; jb 1f", "", X86_FEATURE_FSRM ALTERNATIVE_2 __stringify(CHECK_LEN), \
ALTERNATIVE "", "jmp .Lmemmove_erms", X86_FEATURE_ERMS __stringify(CHECK_LEN; MEMMOVE_BYTES), X86_FEATURE_ERMS, \
__stringify(MEMMOVE_BYTES), X86_FEATURE_FSRM
/* /*
* movsq instruction have many startup latency * movsq instruction have many startup latency
...@@ -207,11 +209,6 @@ SYM_FUNC_START(__memmove) ...@@ -207,11 +209,6 @@ SYM_FUNC_START(__memmove)
movb %r11b, (%rdi) movb %r11b, (%rdi)
13: 13:
RET RET
.Lmemmove_erms:
movq %rdx, %rcx
rep movsb
RET
SYM_FUNC_END(__memmove) SYM_FUNC_END(__memmove)
EXPORT_SYMBOL(__memmove) EXPORT_SYMBOL(__memmove)
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#define BYTES_NOP7 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00 #define BYTES_NOP7 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00
#define BYTES_NOP8 0x3e,BYTES_NOP7 #define BYTES_NOP8 0x3e,BYTES_NOP7
#define ASM_NOP_MAX 8
#else #else
/* /*
...@@ -47,6 +49,9 @@ ...@@ -47,6 +49,9 @@
* 6: osp nopl 0x00(%eax,%eax,1) * 6: osp nopl 0x00(%eax,%eax,1)
* 7: nopl 0x00000000(%eax) * 7: nopl 0x00000000(%eax)
* 8: nopl 0x00000000(%eax,%eax,1) * 8: nopl 0x00000000(%eax,%eax,1)
* 9: cs nopl 0x00000000(%eax,%eax,1)
* 10: osp cs nopl 0x00000000(%eax,%eax,1)
* 11: osp osp cs nopl 0x00000000(%eax,%eax,1)
*/ */
#define BYTES_NOP1 0x90 #define BYTES_NOP1 0x90
#define BYTES_NOP2 0x66,BYTES_NOP1 #define BYTES_NOP2 0x66,BYTES_NOP1
...@@ -56,6 +61,15 @@ ...@@ -56,6 +61,15 @@
#define BYTES_NOP6 0x66,BYTES_NOP5 #define BYTES_NOP6 0x66,BYTES_NOP5
#define BYTES_NOP7 0x0f,0x1f,0x80,0x00,0x00,0x00,0x00 #define BYTES_NOP7 0x0f,0x1f,0x80,0x00,0x00,0x00,0x00
#define BYTES_NOP8 0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00 #define BYTES_NOP8 0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00
#define BYTES_NOP9 0x2e,BYTES_NOP8
#define BYTES_NOP10 0x66,BYTES_NOP9
#define BYTES_NOP11 0x66,BYTES_NOP10
#define ASM_NOP9 _ASM_BYTES(BYTES_NOP9)
#define ASM_NOP10 _ASM_BYTES(BYTES_NOP10)
#define ASM_NOP11 _ASM_BYTES(BYTES_NOP11)
#define ASM_NOP_MAX 11
#endif /* CONFIG_64BIT */ #endif /* CONFIG_64BIT */
...@@ -68,8 +82,6 @@ ...@@ -68,8 +82,6 @@
#define ASM_NOP7 _ASM_BYTES(BYTES_NOP7) #define ASM_NOP7 _ASM_BYTES(BYTES_NOP7)
#define ASM_NOP8 _ASM_BYTES(BYTES_NOP8) #define ASM_NOP8 _ASM_BYTES(BYTES_NOP8)
#define ASM_NOP_MAX 8
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
extern const unsigned char * const x86_nops[]; extern const unsigned char * const x86_nops[];
#endif #endif
......
...@@ -42,13 +42,7 @@ bool arch_support_alt_relocation(struct special_alt *special_alt, ...@@ -42,13 +42,7 @@ bool arch_support_alt_relocation(struct special_alt *special_alt,
struct instruction *insn, struct instruction *insn,
struct reloc *reloc) struct reloc *reloc)
{ {
/* return true;
* The x86 alternatives code adjusts the offsets only when it
* encounters a branch instruction at the very beginning of the
* replacement group.
*/
return insn->offset == special_alt->new_off &&
(insn->type == INSN_CALL || is_jump(insn));
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment