Commit 534b0abc authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'x86_urgent_for_v6.0' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Borislav Petkov:

 - Add the respective UP last level cache mask accessors in order not to
   cause segfaults when lscpu accesses their representation in sysfs

 - Fix for a race in the alternatives batch patching machinery when
   kprobes are set

* tag 'x86_urgent_for_v6.0' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/cacheinfo: Add a cpu_llc_shared_mask() UP variant
  x86/alternative: Fix race in try_get_desc()
parents b357fd1c df5b035b
...@@ -21,16 +21,6 @@ DECLARE_PER_CPU_READ_MOSTLY(u16, cpu_llc_id); ...@@ -21,16 +21,6 @@ DECLARE_PER_CPU_READ_MOSTLY(u16, cpu_llc_id);
DECLARE_PER_CPU_READ_MOSTLY(u16, cpu_l2c_id); DECLARE_PER_CPU_READ_MOSTLY(u16, cpu_l2c_id);
DECLARE_PER_CPU_READ_MOSTLY(int, cpu_number); DECLARE_PER_CPU_READ_MOSTLY(int, cpu_number);
static inline struct cpumask *cpu_llc_shared_mask(int cpu)
{
return per_cpu(cpu_llc_shared_map, cpu);
}
static inline struct cpumask *cpu_l2c_shared_mask(int cpu)
{
return per_cpu(cpu_l2c_shared_map, cpu);
}
DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_cpu_to_apicid); DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_cpu_to_apicid);
DECLARE_EARLY_PER_CPU_READ_MOSTLY(u32, x86_cpu_to_acpiid); DECLARE_EARLY_PER_CPU_READ_MOSTLY(u32, x86_cpu_to_acpiid);
DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_bios_cpu_apicid); DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_bios_cpu_apicid);
...@@ -172,6 +162,16 @@ extern int safe_smp_processor_id(void); ...@@ -172,6 +162,16 @@ extern int safe_smp_processor_id(void);
# define safe_smp_processor_id() smp_processor_id() # define safe_smp_processor_id() smp_processor_id()
#endif #endif
static inline struct cpumask *cpu_llc_shared_mask(int cpu)
{
return per_cpu(cpu_llc_shared_map, cpu);
}
static inline struct cpumask *cpu_l2c_shared_mask(int cpu)
{
return per_cpu(cpu_l2c_shared_map, cpu);
}
#else /* !CONFIG_SMP */ #else /* !CONFIG_SMP */
#define wbinvd_on_cpu(cpu) wbinvd() #define wbinvd_on_cpu(cpu) wbinvd()
static inline int wbinvd_on_all_cpus(void) static inline int wbinvd_on_all_cpus(void)
...@@ -179,6 +179,11 @@ static inline int wbinvd_on_all_cpus(void) ...@@ -179,6 +179,11 @@ static inline int wbinvd_on_all_cpus(void)
wbinvd(); wbinvd();
return 0; return 0;
} }
static inline struct cpumask *cpu_llc_shared_mask(int cpu)
{
return (struct cpumask *)cpumask_of(0);
}
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
extern unsigned disabled_cpus; extern unsigned disabled_cpus;
......
...@@ -1319,22 +1319,23 @@ struct bp_patching_desc { ...@@ -1319,22 +1319,23 @@ struct bp_patching_desc {
atomic_t refs; atomic_t refs;
}; };
static struct bp_patching_desc *bp_desc; static struct bp_patching_desc bp_desc;
static __always_inline static __always_inline
struct bp_patching_desc *try_get_desc(struct bp_patching_desc **descp) struct bp_patching_desc *try_get_desc(void)
{ {
/* rcu_dereference */ struct bp_patching_desc *desc = &bp_desc;
struct bp_patching_desc *desc = __READ_ONCE(*descp);
if (!desc || !arch_atomic_inc_not_zero(&desc->refs)) if (!arch_atomic_inc_not_zero(&desc->refs))
return NULL; return NULL;
return desc; return desc;
} }
static __always_inline void put_desc(struct bp_patching_desc *desc) static __always_inline void put_desc(void)
{ {
struct bp_patching_desc *desc = &bp_desc;
smp_mb__before_atomic(); smp_mb__before_atomic();
arch_atomic_dec(&desc->refs); arch_atomic_dec(&desc->refs);
} }
...@@ -1367,15 +1368,15 @@ noinstr int poke_int3_handler(struct pt_regs *regs) ...@@ -1367,15 +1368,15 @@ noinstr int poke_int3_handler(struct pt_regs *regs)
/* /*
* Having observed our INT3 instruction, we now must observe * Having observed our INT3 instruction, we now must observe
* bp_desc: * bp_desc with non-zero refcount:
* *
* bp_desc = desc INT3 * bp_desc.refs = 1 INT3
* WMB RMB * WMB RMB
* write INT3 if (desc) * write INT3 if (bp_desc.refs != 0)
*/ */
smp_rmb(); smp_rmb();
desc = try_get_desc(&bp_desc); desc = try_get_desc();
if (!desc) if (!desc)
return 0; return 0;
...@@ -1429,7 +1430,7 @@ noinstr int poke_int3_handler(struct pt_regs *regs) ...@@ -1429,7 +1430,7 @@ noinstr int poke_int3_handler(struct pt_regs *regs)
ret = 1; ret = 1;
out_put: out_put:
put_desc(desc); put_desc();
return ret; return ret;
} }
...@@ -1460,18 +1461,20 @@ static int tp_vec_nr; ...@@ -1460,18 +1461,20 @@ static int tp_vec_nr;
*/ */
static void text_poke_bp_batch(struct text_poke_loc *tp, unsigned int nr_entries) static void text_poke_bp_batch(struct text_poke_loc *tp, unsigned int nr_entries)
{ {
struct bp_patching_desc desc = {
.vec = tp,
.nr_entries = nr_entries,
.refs = ATOMIC_INIT(1),
};
unsigned char int3 = INT3_INSN_OPCODE; unsigned char int3 = INT3_INSN_OPCODE;
unsigned int i; unsigned int i;
int do_sync; int do_sync;
lockdep_assert_held(&text_mutex); lockdep_assert_held(&text_mutex);
smp_store_release(&bp_desc, &desc); /* rcu_assign_pointer */ bp_desc.vec = tp;
bp_desc.nr_entries = nr_entries;
/*
* Corresponds to the implicit memory barrier in try_get_desc() to
* ensure reading a non-zero refcount provides up to date bp_desc data.
*/
atomic_set_release(&bp_desc.refs, 1);
/* /*
* Corresponding read barrier in int3 notifier for making sure the * Corresponding read barrier in int3 notifier for making sure the
...@@ -1559,12 +1562,10 @@ static void text_poke_bp_batch(struct text_poke_loc *tp, unsigned int nr_entries ...@@ -1559,12 +1562,10 @@ static void text_poke_bp_batch(struct text_poke_loc *tp, unsigned int nr_entries
text_poke_sync(); text_poke_sync();
/* /*
* Remove and synchronize_rcu(), except we have a very primitive * Remove and wait for refs to be zero.
* refcount based completion.
*/ */
WRITE_ONCE(bp_desc, NULL); /* RCU_INIT_POINTER */ if (!atomic_dec_and_test(&bp_desc.refs))
if (!atomic_dec_and_test(&desc.refs)) atomic_cond_read_acquire(&bp_desc.refs, !VAL);
atomic_cond_read_acquire(&desc.refs, !VAL);
} }
static void text_poke_loc_init(struct text_poke_loc *tp, void *addr, static void text_poke_loc_init(struct text_poke_loc *tp, void *addr,
......
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