Commit 9c6913b7 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'x86_urgent_for_v5.18_rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Borislav Petkov:

 - Fix the MSI message data struct definition

 - Use local labels in the exception table macros to avoid symbol
   conflicts with clang LTO builds

 - A couple of fixes to objtool checking of the relatively newly added
   SLS and IBT code

 - Rename a local var in the WARN* macro machinery to prevent shadowing

* tag 'x86_urgent_for_v5.18_rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/msi: Fix msi message data shadow struct
  x86/extable: Prefer local labels in .set directives
  x86,bpf: Avoid IBT objtool warning
  objtool: Fix SLS validation for kcov tail-call replacement
  objtool: Fix IBT tail-call detection
  x86/bug: Prevent shadowing in __WARN_FLAGS
  x86/mm/tlb: Revert retpoline avoidance approach
parents b51f86e9 59b18a1e
...@@ -154,24 +154,24 @@ ...@@ -154,24 +154,24 @@
# define DEFINE_EXTABLE_TYPE_REG \ # define DEFINE_EXTABLE_TYPE_REG \
".macro extable_type_reg type:req reg:req\n" \ ".macro extable_type_reg type:req reg:req\n" \
".set found, 0\n" \ ".set .Lfound, 0\n" \
".set regnr, 0\n" \ ".set .Lregnr, 0\n" \
".irp rs,rax,rcx,rdx,rbx,rsp,rbp,rsi,rdi,r8,r9,r10,r11,r12,r13,r14,r15\n" \ ".irp rs,rax,rcx,rdx,rbx,rsp,rbp,rsi,rdi,r8,r9,r10,r11,r12,r13,r14,r15\n" \
".ifc \\reg, %%\\rs\n" \ ".ifc \\reg, %%\\rs\n" \
".set found, found+1\n" \ ".set .Lfound, .Lfound+1\n" \
".long \\type + (regnr << 8)\n" \ ".long \\type + (.Lregnr << 8)\n" \
".endif\n" \ ".endif\n" \
".set regnr, regnr+1\n" \ ".set .Lregnr, .Lregnr+1\n" \
".endr\n" \ ".endr\n" \
".set regnr, 0\n" \ ".set .Lregnr, 0\n" \
".irp rs,eax,ecx,edx,ebx,esp,ebp,esi,edi,r8d,r9d,r10d,r11d,r12d,r13d,r14d,r15d\n" \ ".irp rs,eax,ecx,edx,ebx,esp,ebp,esi,edi,r8d,r9d,r10d,r11d,r12d,r13d,r14d,r15d\n" \
".ifc \\reg, %%\\rs\n" \ ".ifc \\reg, %%\\rs\n" \
".set found, found+1\n" \ ".set .Lfound, .Lfound+1\n" \
".long \\type + (regnr << 8)\n" \ ".long \\type + (.Lregnr << 8)\n" \
".endif\n" \ ".endif\n" \
".set regnr, regnr+1\n" \ ".set .Lregnr, .Lregnr+1\n" \
".endr\n" \ ".endr\n" \
".if (found != 1)\n" \ ".if (.Lfound != 1)\n" \
".error \"extable_type_reg: bad register argument\"\n" \ ".error \"extable_type_reg: bad register argument\"\n" \
".endif\n" \ ".endif\n" \
".endm\n" ".endm\n"
......
...@@ -78,9 +78,9 @@ do { \ ...@@ -78,9 +78,9 @@ do { \
*/ */
#define __WARN_FLAGS(flags) \ #define __WARN_FLAGS(flags) \
do { \ do { \
__auto_type f = BUGFLAG_WARNING|(flags); \ __auto_type __flags = BUGFLAG_WARNING|(flags); \
instrumentation_begin(); \ instrumentation_begin(); \
_BUG_FLAGS(ASM_UD2, f, ASM_REACHABLE); \ _BUG_FLAGS(ASM_UD2, __flags, ASM_REACHABLE); \
instrumentation_end(); \ instrumentation_end(); \
} while (0) } while (0)
......
...@@ -12,14 +12,17 @@ int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec, ...@@ -12,14 +12,17 @@ int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
/* Structs and defines for the X86 specific MSI message format */ /* Structs and defines for the X86 specific MSI message format */
typedef struct x86_msi_data { typedef struct x86_msi_data {
u32 vector : 8, union {
delivery_mode : 3, struct {
dest_mode_logical : 1, u32 vector : 8,
reserved : 2, delivery_mode : 3,
active_low : 1, dest_mode_logical : 1,
is_level : 1; reserved : 2,
active_low : 1,
u32 dmar_subhandle; is_level : 1;
};
u32 dmar_subhandle;
};
} __attribute__ ((packed)) arch_msi_msg_data_t; } __attribute__ ((packed)) arch_msi_msg_data_t;
#define arch_msi_msg_data x86_msi_data #define arch_msi_msg_data x86_msi_data
......
...@@ -855,13 +855,11 @@ static void flush_tlb_func(void *info) ...@@ -855,13 +855,11 @@ static void flush_tlb_func(void *info)
nr_invalidate); nr_invalidate);
} }
static bool tlb_is_not_lazy(int cpu) static bool tlb_is_not_lazy(int cpu, void *data)
{ {
return !per_cpu(cpu_tlbstate_shared.is_lazy, cpu); return !per_cpu(cpu_tlbstate_shared.is_lazy, cpu);
} }
static DEFINE_PER_CPU(cpumask_t, flush_tlb_mask);
DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state_shared, cpu_tlbstate_shared); DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state_shared, cpu_tlbstate_shared);
EXPORT_PER_CPU_SYMBOL(cpu_tlbstate_shared); EXPORT_PER_CPU_SYMBOL(cpu_tlbstate_shared);
...@@ -890,36 +888,11 @@ STATIC_NOPV void native_flush_tlb_multi(const struct cpumask *cpumask, ...@@ -890,36 +888,11 @@ STATIC_NOPV void native_flush_tlb_multi(const struct cpumask *cpumask,
* up on the new contents of what used to be page tables, while * up on the new contents of what used to be page tables, while
* doing a speculative memory access. * doing a speculative memory access.
*/ */
if (info->freed_tables) { if (info->freed_tables)
on_each_cpu_mask(cpumask, flush_tlb_func, (void *)info, true); on_each_cpu_mask(cpumask, flush_tlb_func, (void *)info, true);
} else { else
/* on_each_cpu_cond_mask(tlb_is_not_lazy, flush_tlb_func,
* Although we could have used on_each_cpu_cond_mask(), (void *)info, 1, cpumask);
* open-coding it has performance advantages, as it eliminates
* the need for indirect calls or retpolines. In addition, it
* allows to use a designated cpumask for evaluating the
* condition, instead of allocating one.
*
* This code works under the assumption that there are no nested
* TLB flushes, an assumption that is already made in
* flush_tlb_mm_range().
*
* cond_cpumask is logically a stack-local variable, but it is
* more efficient to have it off the stack and not to allocate
* it on demand. Preemption is disabled and this code is
* non-reentrant.
*/
struct cpumask *cond_cpumask = this_cpu_ptr(&flush_tlb_mask);
int cpu;
cpumask_clear(cond_cpumask);
for_each_cpu(cpu, cpumask) {
if (tlb_is_not_lazy(cpu))
__cpumask_set_cpu(cpu, cond_cpumask);
}
on_each_cpu_mask(cond_cpumask, flush_tlb_func, (void *)info, true);
}
} }
void flush_tlb_multi(const struct cpumask *cpumask, void flush_tlb_multi(const struct cpumask *cpumask,
......
...@@ -412,6 +412,7 @@ static void emit_indirect_jump(u8 **pprog, int reg, u8 *ip) ...@@ -412,6 +412,7 @@ static void emit_indirect_jump(u8 **pprog, int reg, u8 *ip)
EMIT_LFENCE(); EMIT_LFENCE();
EMIT2(0xFF, 0xE0 + reg); EMIT2(0xFF, 0xE0 + reg);
} else if (cpu_feature_enabled(X86_FEATURE_RETPOLINE)) { } else if (cpu_feature_enabled(X86_FEATURE_RETPOLINE)) {
OPTIMIZER_HIDE_VAR(reg);
emit_jump(&prog, &__x86_indirect_thunk_array[reg], ip); emit_jump(&prog, &__x86_indirect_thunk_array[reg], ip);
} else } else
#endif #endif
......
...@@ -1155,6 +1155,17 @@ static void annotate_call_site(struct objtool_file *file, ...@@ -1155,6 +1155,17 @@ static void annotate_call_site(struct objtool_file *file,
: arch_nop_insn(insn->len)); : arch_nop_insn(insn->len));
insn->type = sibling ? INSN_RETURN : INSN_NOP; insn->type = sibling ? INSN_RETURN : INSN_NOP;
if (sibling) {
/*
* We've replaced the tail-call JMP insn by two new
* insn: RET; INT3, except we only have a single struct
* insn here. Mark it retpoline_safe to avoid the SLS
* warning, instead of adding another insn.
*/
insn->retpoline_safe = true;
}
return; return;
} }
...@@ -1239,11 +1250,20 @@ static bool same_function(struct instruction *insn1, struct instruction *insn2) ...@@ -1239,11 +1250,20 @@ static bool same_function(struct instruction *insn1, struct instruction *insn2)
return insn1->func->pfunc == insn2->func->pfunc; return insn1->func->pfunc == insn2->func->pfunc;
} }
static bool is_first_func_insn(struct instruction *insn) static bool is_first_func_insn(struct objtool_file *file, struct instruction *insn)
{ {
return insn->offset == insn->func->offset || if (insn->offset == insn->func->offset)
(insn->type == INSN_ENDBR && return true;
insn->offset == insn->func->offset + insn->len);
if (ibt) {
struct instruction *prev = prev_insn_same_sym(file, insn);
if (prev && prev->type == INSN_ENDBR &&
insn->offset == insn->func->offset + prev->len)
return true;
}
return false;
} }
/* /*
...@@ -1327,7 +1347,7 @@ static int add_jump_destinations(struct objtool_file *file) ...@@ -1327,7 +1347,7 @@ static int add_jump_destinations(struct objtool_file *file)
insn->jump_dest->func->pfunc = insn->func; insn->jump_dest->func->pfunc = insn->func;
} else if (!same_function(insn, insn->jump_dest) && } else if (!same_function(insn, insn->jump_dest) &&
is_first_func_insn(insn->jump_dest)) { is_first_func_insn(file, insn->jump_dest)) {
/* internal sibling call (without reloc) */ /* internal sibling call (without reloc) */
add_call_dest(file, insn, insn->jump_dest->func, true); add_call_dest(file, insn, insn->jump_dest->func, true);
} }
......
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