@@ -68,6 +68,16 @@ static void hv_kmsg_dump_unregister(void);
68
68
69
69
static struct ctl_table_header * hv_ctl_table_hdr ;
70
70
71
+ /*
72
+ * Per-cpu array holding the tail pointer for the SynIC event ring buffer
73
+ * for each SINT.
74
+ *
75
+ * We cannot maintain this in mshv driver because the tail pointer should
76
+ * persist even if the mshv driver is unloaded.
77
+ */
78
+ u8 * __percpu * hv_synic_eventring_tail ;
79
+ EXPORT_SYMBOL_GPL (hv_synic_eventring_tail );
80
+
71
81
/*
72
82
* Hyper-V specific initialization and shutdown code that is
73
83
* common across all architectures. Called from architecture
@@ -90,6 +100,9 @@ void __init hv_common_free(void)
90
100
91
101
free_percpu (hyperv_pcpu_input_arg );
92
102
hyperv_pcpu_input_arg = NULL ;
103
+
104
+ free_percpu (hv_synic_eventring_tail );
105
+ hv_synic_eventring_tail = NULL ;
93
106
}
94
107
95
108
/*
@@ -372,6 +385,11 @@ int __init hv_common_init(void)
372
385
BUG_ON (!hyperv_pcpu_output_arg );
373
386
}
374
387
388
+ if (hv_root_partition ()) {
389
+ hv_synic_eventring_tail = alloc_percpu (u8 * );
390
+ BUG_ON (!hv_synic_eventring_tail );
391
+ }
392
+
375
393
hv_vp_index = kmalloc_array (nr_cpu_ids , sizeof (* hv_vp_index ),
376
394
GFP_KERNEL );
377
395
if (!hv_vp_index ) {
@@ -460,20 +478,21 @@ void __init ms_hyperv_late_init(void)
460
478
int hv_common_cpu_init (unsigned int cpu )
461
479
{
462
480
void * * inputarg , * * outputarg ;
481
+ u8 * * synic_eventring_tail ;
463
482
u64 msr_vp_index ;
464
483
gfp_t flags ;
465
484
const int pgcount = hv_output_page_exists () ? 2 : 1 ;
466
485
void * mem ;
467
- int ret ;
486
+ int ret = 0 ;
468
487
469
488
/* hv_cpu_init() can be called with IRQs disabled from hv_resume() */
470
489
flags = irqs_disabled () ? GFP_ATOMIC : GFP_KERNEL ;
471
490
472
491
inputarg = (void * * )this_cpu_ptr (hyperv_pcpu_input_arg );
473
492
474
493
/*
475
- * hyperv_pcpu_input_arg and hyperv_pcpu_output_arg memory is already
476
- * allocated if this CPU was previously online and then taken offline
494
+ * The per-cpu memory is already allocated if this CPU was previously
495
+ * online and then taken offline
477
496
*/
478
497
if (!* inputarg ) {
479
498
mem = kmalloc (pgcount * HV_HYP_PAGE_SIZE , flags );
@@ -520,11 +539,21 @@ int hv_common_cpu_init(unsigned int cpu)
520
539
if (msr_vp_index > hv_max_vp_index )
521
540
hv_max_vp_index = msr_vp_index ;
522
541
523
- return 0 ;
542
+ if (hv_root_partition ()) {
543
+ synic_eventring_tail = (u8 * * )this_cpu_ptr (hv_synic_eventring_tail );
544
+ * synic_eventring_tail = kcalloc (HV_SYNIC_SINT_COUNT ,
545
+ sizeof (u8 ), flags );
546
+ /* No need to unwind any of the above on failure here */
547
+ if (unlikely (!* synic_eventring_tail ))
548
+ ret = - ENOMEM ;
549
+ }
550
+
551
+ return ret ;
524
552
}
525
553
526
554
int hv_common_cpu_die (unsigned int cpu )
527
555
{
556
+ u8 * * synic_eventring_tail ;
528
557
/*
529
558
* The hyperv_pcpu_input_arg and hyperv_pcpu_output_arg memory
530
559
* is not freed when the CPU goes offline as the hyperv_pcpu_input_arg
@@ -537,6 +566,10 @@ int hv_common_cpu_die(unsigned int cpu)
537
566
* originally allocated memory is reused in hv_common_cpu_init().
538
567
*/
539
568
569
+ synic_eventring_tail = this_cpu_ptr (hv_synic_eventring_tail );
570
+ kfree (* synic_eventring_tail );
571
+ * synic_eventring_tail = NULL ;
572
+
540
573
return 0 ;
541
574
}
542
575
0 commit comments