aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/xen/enlighten.c115
-rw-r--r--include/linux/cpuhotplug.h1
2 files changed, 66 insertions, 50 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index c7f6b1f90efa..a9ba14ac3aea 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -140,7 +140,9 @@ RESERVE_BRK(shared_info_page_brk, PAGE_SIZE);
140__read_mostly int xen_have_vector_callback; 140__read_mostly int xen_have_vector_callback;
141EXPORT_SYMBOL_GPL(xen_have_vector_callback); 141EXPORT_SYMBOL_GPL(xen_have_vector_callback);
142 142
143static struct notifier_block xen_cpu_notifier; 143static int xen_cpu_up_prepare(unsigned int cpu);
144static int xen_cpu_up_online(unsigned int cpu);
145static int xen_cpu_dead(unsigned int cpu);
144 146
145/* 147/*
146 * Point at some empty memory to start with. We map the real shared_info 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 x86_platform.legacy.rtc = 1; 1543 x86_platform.legacy.rtc = 1;
1542} 1544}
1543 1545
1546static 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/* First C function to be called on Xen boot */ 1564/* First C function to be called on Xen boot */
1545asmlinkage __visible void __init xen_start_kernel(void) 1565asmlinkage __visible void __init xen_start_kernel(void)
1546{ 1566{
@@ -1629,7 +1649,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
1629 xen_initial_gdt = &per_cpu(gdt_page, 0); 1649 xen_initial_gdt = &per_cpu(gdt_page, 0);
1630 1650
1631 xen_smp_init(); 1651 xen_smp_init();
1632 register_cpu_notifier(&xen_cpu_notifier); 1652 WARN_ON(xen_cpuhp_setup());
1633 1653
1634#ifdef CONFIG_ACPI_NUMA 1654#ifdef CONFIG_ACPI_NUMA
1635 /* 1655 /*
@@ -1823,63 +1843,58 @@ static void __init init_hvm_pv_info(void)
1823 xen_domain_type = XEN_HVM_DOMAIN; 1843 xen_domain_type = XEN_HVM_DOMAIN;
1824} 1844}
1825 1845
1826static int xen_cpu_notify(struct notifier_block *self, unsigned long action, 1846static int xen_cpu_up_prepare(unsigned int cpu)
1827 void *hcpu)
1828{ 1847{
1829 int cpu = (long)hcpu;
1830 int rc; 1848 int rc;
1831 1849
1832 switch (action) { 1850 if (xen_hvm_domain()) {
1833 case CPU_UP_PREPARE: 1851 /*
1834 if (xen_hvm_domain()) { 1852 * This can happen if CPU was offlined earlier and
1835 /* 1853 * offlining timed out in common_cpu_die().
1836 * This can happen if CPU was offlined earlier and 1854 */
1837 * offlining timed out in common_cpu_die(). 1855 if (cpu_report_state(cpu) == CPU_DEAD_FROZEN) {
1838 */ 1856 xen_smp_intr_free(cpu);
1839 if (cpu_report_state(cpu) == CPU_DEAD_FROZEN) { 1857 xen_uninit_lock_cpu(cpu);
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);
1849 } 1858 }
1850 1859
1851 if (xen_pv_domain() || 1860 if (cpu_acpi_id(cpu) != U32_MAX)
1852 (xen_have_vector_callback && 1861 per_cpu(xen_vcpu_id, cpu) = cpu_acpi_id(cpu);
1853 xen_feature(XENFEAT_hvm_safe_pvclock))) 1862 else
1854 xen_setup_timer(cpu); 1863 per_cpu(xen_vcpu_id, cpu) = cpu;
1864 xen_vcpu_setup(cpu);
1865 }
1855 1866
1856 rc = xen_smp_intr_init(cpu); 1867 if (xen_pv_domain() ||
1857 if (rc) { 1868 (xen_have_vector_callback &&
1858 WARN(1, "xen_smp_intr_init() for CPU %d failed: %d\n", 1869 xen_feature(XENFEAT_hvm_safe_pvclock)))
1859 cpu, rc); 1870 xen_setup_timer(cpu);
1860 return NOTIFY_BAD;
1861 }
1862 1871
1863 break; 1872 rc = xen_smp_intr_init(cpu);
1864 case CPU_ONLINE: 1873 if (rc) {
1865 xen_init_lock_cpu(cpu); 1874 WARN(1, "xen_smp_intr_init() for CPU %d failed: %d\n",
1866 break; 1875 cpu, rc);
1867 case CPU_UP_CANCELED: 1876 return rc;
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;
1876 } 1877 }
1877 return NOTIFY_OK; 1878 return 0;
1878} 1879}
1879 1880
1880static struct notifier_block xen_cpu_notifier = { 1881static int xen_cpu_dead(unsigned int cpu)
1881 .notifier_call = xen_cpu_notify, 1882{
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
1893static int xen_cpu_up_online(unsigned int cpu)
1894{
1895 xen_init_lock_cpu(cpu);
1896 return 0;
1897}
1883 1898
1884#ifdef CONFIG_KEXEC_CORE 1899#ifdef CONFIG_KEXEC_CORE
1885static void xen_hvm_shutdown(void) 1900static void xen_hvm_shutdown(void)
@@ -1910,7 +1925,7 @@ static void __init xen_hvm_guest_init(void)
1910 if (xen_feature(XENFEAT_hvm_callback_vector)) 1925 if (xen_feature(XENFEAT_hvm_callback_vector))
1911 xen_have_vector_callback = 1; 1926 xen_have_vector_callback = 1;
1912 xen_hvm_smp_init(); 1927 xen_hvm_smp_init();
1913 register_cpu_notifier(&xen_cpu_notifier); 1928 WARN_ON(xen_cpuhp_setup());
1914 xen_unplug_emulated_devices(); 1929 xen_unplug_emulated_devices();
1915 x86_init.irqs.intr_init = xen_init_IRQ; 1930 x86_init.irqs.intr_init = xen_init_IRQ;
1916 xen_hvm_init_time_ops(); 1931 xen_hvm_init_time_ops();
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 242bf530edfc..33d352f3295d 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -21,6 +21,7 @@ enum cpuhp_state {
21 CPUHP_X2APIC_PREPARE, 21 CPUHP_X2APIC_PREPARE,
22 CPUHP_SMPCFD_PREPARE, 22 CPUHP_SMPCFD_PREPARE,
23 CPUHP_RCUTREE_PREP, 23 CPUHP_RCUTREE_PREP,
24 CPUHP_XEN_PREPARE,
24 CPUHP_NOTIFY_PREPARE, 25 CPUHP_NOTIFY_PREPARE,
25 CPUHP_TIMERS_DEAD, 26 CPUHP_TIMERS_DEAD,
26 CPUHP_BRINGUP_CPU, 27 CPUHP_BRINGUP_CPU,