Skip to content

Commit 368990a

Browse files
committed
xen: fix multicall debug data referencing
The recent adding of multicall debug mixed up the referencing of the debug data. A __percpu tagged pointer can't be initialized with a plain pointer, so use another percpu variable for the pointer and set it on each new cpu via a function. Fixes: 942d917 ("xen: make multicall debug boot time selectable") Reported-by: kernel test robot <[email protected]> Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/ Signed-off-by: Juergen Gross <[email protected]> Reviewed-by: Boris Ostrovsky <[email protected]> Signed-off-by: Juergen Gross <[email protected]>
1 parent 9fe6a8c commit 368990a

File tree

3 files changed

+16
-7
lines changed

3 files changed

+16
-7
lines changed

arch/x86/xen/multicalls.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@ struct mc_debug_data {
5454

5555
static DEFINE_PER_CPU(struct mc_buffer, mc_buffer);
5656
static struct mc_debug_data mc_debug_data_early __initdata;
57-
static struct mc_debug_data __percpu *mc_debug_data __refdata =
57+
static DEFINE_PER_CPU(struct mc_debug_data *, mc_debug_data) =
5858
&mc_debug_data_early;
59+
static struct mc_debug_data __percpu *mc_debug_data_ptr;
5960
DEFINE_PER_CPU(unsigned long, xen_mc_irq_flags);
6061

6162
static struct static_key mc_debug __ro_after_init;
@@ -70,16 +71,20 @@ static int __init xen_parse_mc_debug(char *arg)
7071
}
7172
early_param("xen_mc_debug", xen_parse_mc_debug);
7273

74+
void mc_percpu_init(unsigned int cpu)
75+
{
76+
per_cpu(mc_debug_data, cpu) = per_cpu_ptr(mc_debug_data_ptr, cpu);
77+
}
78+
7379
static int __init mc_debug_enable(void)
7480
{
75-
struct mc_debug_data __percpu *mcdb;
7681
unsigned long flags;
7782

7883
if (!mc_debug_enabled)
7984
return 0;
8085

81-
mcdb = alloc_percpu(struct mc_debug_data);
82-
if (!mcdb) {
86+
mc_debug_data_ptr = alloc_percpu(struct mc_debug_data);
87+
if (!mc_debug_data_ptr) {
8388
pr_err("xen_mc_debug inactive\n");
8489
static_key_slow_dec(&mc_debug);
8590
return -ENOMEM;
@@ -88,7 +93,7 @@ static int __init mc_debug_enable(void)
8893
/* Be careful when switching to percpu debug data. */
8994
local_irq_save(flags);
9095
xen_mc_flush();
91-
mc_debug_data = mcdb;
96+
mc_percpu_init(0);
9297
local_irq_restore(flags);
9398

9499
pr_info("xen_mc_debug active\n");
@@ -150,7 +155,7 @@ void xen_mc_flush(void)
150155
trace_xen_mc_flush(b->mcidx, b->argidx, b->cbidx);
151156

152157
if (static_key_false(&mc_debug)) {
153-
mcdb = this_cpu_ptr(mc_debug_data);
158+
mcdb = __this_cpu_read(mc_debug_data);
154159
memcpy(mcdb->entries, b->entries,
155160
b->mcidx * sizeof(struct multicall_entry));
156161
}
@@ -230,7 +235,7 @@ struct multicall_space __xen_mc_entry(size_t args)
230235

231236
ret.mc = &b->entries[b->mcidx];
232237
if (static_key_false(&mc_debug)) {
233-
struct mc_debug_data *mcdb = this_cpu_ptr(mc_debug_data);
238+
struct mc_debug_data *mcdb = __this_cpu_read(mc_debug_data);
234239

235240
mcdb->caller[b->mcidx] = __builtin_return_address(0);
236241
mcdb->argsz[b->mcidx] = args;

arch/x86/xen/smp_pv.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ static int xen_pv_kick_ap(unsigned int cpu, struct task_struct *idle)
305305
return rc;
306306

307307
xen_pmu_init(cpu);
308+
mc_percpu_init(cpu);
308309

309310
/*
310311
* Why is this a BUG? If the hypercall fails then everything can be

arch/x86/xen/xen-ops.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,9 @@ void xen_mc_callback(void (*fn)(void *), void *data);
257257
*/
258258
struct multicall_space xen_mc_extend_args(unsigned long op, size_t arg_size);
259259

260+
/* Do percpu data initialization for multicalls. */
261+
void mc_percpu_init(unsigned int cpu);
262+
260263
extern bool is_xen_pmu;
261264

262265
irqreturn_t xen_pmu_irq_handler(int irq, void *dev_id);

0 commit comments

Comments
 (0)