@@ -140,7 +140,9 @@ RESERVE_BRK(shared_info_page_brk, PAGE_SIZE);
140
140
__read_mostly int xen_have_vector_callback ;
141
141
EXPORT_SYMBOL_GPL (xen_have_vector_callback );
142
142
143
- static struct notifier_block xen_cpu_notifier ;
143
+ static int xen_cpu_up_prepare (unsigned int cpu );
144
+ static int xen_cpu_up_online (unsigned int cpu );
145
+ static int xen_cpu_dead (unsigned int cpu );
144
146
145
147
/*
146
148
* Point at some empty memory to start with. We map the real shared_info
@@ -1541,6 +1543,24 @@ static void __init xen_dom0_set_legacy_features(void)
1541
1543
x86_platform .legacy .rtc = 1 ;
1542
1544
}
1543
1545
1546
+ static int xen_cpuhp_setup (void )
1547
+ {
1548
+ int rc ;
1549
+
1550
+ rc = cpuhp_setup_state_nocalls (CPUHP_XEN_PREPARE ,
1551
+ "XEN_HVM_GUEST_PREPARE" ,
1552
+ xen_cpu_up_prepare , xen_cpu_dead );
1553
+ if (rc >= 0 ) {
1554
+ rc = cpuhp_setup_state_nocalls (CPUHP_AP_ONLINE_DYN ,
1555
+ "XEN_HVM_GUEST_ONLINE" ,
1556
+ xen_cpu_up_online , NULL );
1557
+ if (rc < 0 )
1558
+ cpuhp_remove_state_nocalls (CPUHP_XEN_PREPARE );
1559
+ }
1560
+
1561
+ return rc >= 0 ? 0 : rc ;
1562
+ }
1563
+
1544
1564
/* First C function to be called on Xen boot */
1545
1565
asmlinkage __visible void __init xen_start_kernel (void )
1546
1566
{
@@ -1629,7 +1649,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
1629
1649
xen_initial_gdt = & per_cpu (gdt_page , 0 );
1630
1650
1631
1651
xen_smp_init ();
1632
- register_cpu_notifier ( & xen_cpu_notifier );
1652
+ WARN_ON ( xen_cpuhp_setup () );
1633
1653
1634
1654
#ifdef CONFIG_ACPI_NUMA
1635
1655
/*
@@ -1823,63 +1843,58 @@ static void __init init_hvm_pv_info(void)
1823
1843
xen_domain_type = XEN_HVM_DOMAIN ;
1824
1844
}
1825
1845
1826
- static int xen_cpu_notify (struct notifier_block * self , unsigned long action ,
1827
- void * hcpu )
1846
+ static int xen_cpu_up_prepare (unsigned int cpu )
1828
1847
{
1829
- int cpu = (long )hcpu ;
1830
1848
int rc ;
1831
1849
1832
- switch (action ) {
1833
- case CPU_UP_PREPARE :
1834
- if (xen_hvm_domain ()) {
1835
- /*
1836
- * This can happen if CPU was offlined earlier and
1837
- * offlining timed out in common_cpu_die().
1838
- */
1839
- if (cpu_report_state (cpu ) == CPU_DEAD_FROZEN ) {
1840
- xen_smp_intr_free (cpu );
1841
- xen_uninit_lock_cpu (cpu );
1842
- }
1843
-
1844
- if (cpu_acpi_id (cpu ) != U32_MAX )
1845
- per_cpu (xen_vcpu_id , cpu ) = cpu_acpi_id (cpu );
1846
- else
1847
- per_cpu (xen_vcpu_id , cpu ) = cpu ;
1848
- xen_vcpu_setup (cpu );
1850
+ if (xen_hvm_domain ()) {
1851
+ /*
1852
+ * This can happen if CPU was offlined earlier and
1853
+ * offlining timed out in common_cpu_die().
1854
+ */
1855
+ if (cpu_report_state (cpu ) == CPU_DEAD_FROZEN ) {
1856
+ xen_smp_intr_free (cpu );
1857
+ xen_uninit_lock_cpu (cpu );
1849
1858
}
1850
1859
1851
- if (xen_pv_domain () ||
1852
- (xen_have_vector_callback &&
1853
- xen_feature (XENFEAT_hvm_safe_pvclock )))
1854
- xen_setup_timer (cpu );
1860
+ if (cpu_acpi_id (cpu ) != U32_MAX )
1861
+ per_cpu (xen_vcpu_id , cpu ) = cpu_acpi_id (cpu );
1862
+ else
1863
+ per_cpu (xen_vcpu_id , cpu ) = cpu ;
1864
+ xen_vcpu_setup (cpu );
1865
+ }
1855
1866
1856
- rc = xen_smp_intr_init (cpu );
1857
- if (rc ) {
1858
- WARN (1 , "xen_smp_intr_init() for CPU %d failed: %d\n" ,
1859
- cpu , rc );
1860
- return NOTIFY_BAD ;
1861
- }
1867
+ if (xen_pv_domain () ||
1868
+ (xen_have_vector_callback &&
1869
+ xen_feature (XENFEAT_hvm_safe_pvclock )))
1870
+ xen_setup_timer (cpu );
1862
1871
1863
- break ;
1864
- case CPU_ONLINE :
1865
- xen_init_lock_cpu (cpu );
1866
- break ;
1867
- case CPU_UP_CANCELED :
1868
- xen_smp_intr_free (cpu );
1869
- if (xen_pv_domain () ||
1870
- (xen_have_vector_callback &&
1871
- xen_feature (XENFEAT_hvm_safe_pvclock )))
1872
- xen_teardown_timer (cpu );
1873
- break ;
1874
- default :
1875
- break ;
1872
+ rc = xen_smp_intr_init (cpu );
1873
+ if (rc ) {
1874
+ WARN (1 , "xen_smp_intr_init() for CPU %d failed: %d\n" ,
1875
+ cpu , rc );
1876
+ return rc ;
1876
1877
}
1877
- return NOTIFY_OK ;
1878
+ return 0 ;
1878
1879
}
1879
1880
1880
- static struct notifier_block xen_cpu_notifier = {
1881
- .notifier_call = xen_cpu_notify ,
1882
- };
1881
+ static int xen_cpu_dead (unsigned int cpu )
1882
+ {
1883
+ xen_smp_intr_free (cpu );
1884
+
1885
+ if (xen_pv_domain () ||
1886
+ (xen_have_vector_callback &&
1887
+ xen_feature (XENFEAT_hvm_safe_pvclock )))
1888
+ xen_teardown_timer (cpu );
1889
+
1890
+ return 0 ;
1891
+ }
1892
+
1893
+ static int xen_cpu_up_online (unsigned int cpu )
1894
+ {
1895
+ xen_init_lock_cpu (cpu );
1896
+ return 0 ;
1897
+ }
1883
1898
1884
1899
#ifdef CONFIG_KEXEC_CORE
1885
1900
static void xen_hvm_shutdown (void )
@@ -1910,7 +1925,7 @@ static void __init xen_hvm_guest_init(void)
1910
1925
if (xen_feature (XENFEAT_hvm_callback_vector ))
1911
1926
xen_have_vector_callback = 1 ;
1912
1927
xen_hvm_smp_init ();
1913
- register_cpu_notifier ( & xen_cpu_notifier );
1928
+ WARN_ON ( xen_cpuhp_setup () );
1914
1929
xen_unplug_emulated_devices ();
1915
1930
x86_init .irqs .intr_init = xen_init_IRQ ;
1916
1931
xen_hvm_init_time_ops ();
0 commit comments