diff options
author | Pavel Tatashin <pasha.tatashin@oracle.com> | 2018-07-19 16:55:31 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2018-07-19 18:02:39 -0400 |
commit | 7b25b9cb0dad8395b5cf5a02196d0e88ccda67d5 (patch) | |
tree | fad684ea5a4888867df6c2a650dbe49a79f773f4 | |
parent | fe9af81e524e8a86bdd59c0cc0d9e2b0ccaf840f (diff) |
x86/xen/time: Initialize pv xen time in init_hypervisor_platform()
In every hypervisor except for xen pv time ops are initialized in
init_hypervisor_platform().
Xen PV domains initialize time ops in x86_init.paging.pagetable_init(),
by calling xen_setup_shared_info() which is a poor design, as time is
needed prior to memory allocator.
xen_setup_shared_info() is called from two places: during boot, and
after suspend. Split the content of xen_setup_shared_info() into
three places:
1. add the clock relavent data into new xen pv init_platform vector, and
set clock ops in there.
2. move xen_setup_vcpu_info_placement() to new xen_pv_guest_late_init()
call.
3. Re-initializing parts of shared info copy to xen_pv_post_suspend() to
be symmetric to xen_pv_pre_suspend
Signed-off-by: Pavel Tatashin <pasha.tatashin@oracle.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: steven.sistare@oracle.com
Cc: daniel.m.jordan@oracle.com
Cc: linux@armlinux.org.uk
Cc: schwidefsky@de.ibm.com
Cc: heiko.carstens@de.ibm.com
Cc: john.stultz@linaro.org
Cc: sboyd@codeaurora.org
Cc: hpa@zytor.com
Cc: douly.fnst@cn.fujitsu.com
Cc: peterz@infradead.org
Cc: prarit@redhat.com
Cc: feng.tang@intel.com
Cc: pmladek@suse.com
Cc: gnomes@lxorguk.ukuu.org.uk
Cc: linux-s390@vger.kernel.org
Cc: boris.ostrovsky@oracle.com
Cc: jgross@suse.com
Cc: pbonzini@redhat.com
Link: https://lkml.kernel.org/r/20180719205545.16512-13-pasha.tatashin@oracle.com
-rw-r--r-- | arch/x86/xen/enlighten_pv.c | 51 | ||||
-rw-r--r-- | arch/x86/xen/mmu_pv.c | 6 | ||||
-rw-r--r-- | arch/x86/xen/suspend_pv.c | 5 | ||||
-rw-r--r-- | arch/x86/xen/time.c | 7 | ||||
-rw-r--r-- | arch/x86/xen/xen-ops.h | 6 |
5 files changed, 34 insertions, 41 deletions
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 439a94bf89ad..105a57d73701 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c | |||
@@ -119,6 +119,27 @@ static void __init xen_banner(void) | |||
119 | version >> 16, version & 0xffff, extra.extraversion, | 119 | version >> 16, version & 0xffff, extra.extraversion, |
120 | xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : ""); | 120 | xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : ""); |
121 | } | 121 | } |
122 | |||
123 | static void __init xen_pv_init_platform(void) | ||
124 | { | ||
125 | set_fixmap(FIX_PARAVIRT_BOOTMAP, xen_start_info->shared_info); | ||
126 | HYPERVISOR_shared_info = (void *)fix_to_virt(FIX_PARAVIRT_BOOTMAP); | ||
127 | |||
128 | /* xen clock uses per-cpu vcpu_info, need to init it for boot cpu */ | ||
129 | xen_vcpu_info_reset(0); | ||
130 | |||
131 | /* pvclock is in shared info area */ | ||
132 | xen_init_time_ops(); | ||
133 | } | ||
134 | |||
135 | static void __init xen_pv_guest_late_init(void) | ||
136 | { | ||
137 | #ifndef CONFIG_SMP | ||
138 | /* Setup shared vcpu info for non-smp configurations */ | ||
139 | xen_setup_vcpu_info_placement(); | ||
140 | #endif | ||
141 | } | ||
142 | |||
122 | /* Check if running on Xen version (major, minor) or later */ | 143 | /* Check if running on Xen version (major, minor) or later */ |
123 | bool | 144 | bool |
124 | xen_running_on_version_or_later(unsigned int major, unsigned int minor) | 145 | xen_running_on_version_or_later(unsigned int major, unsigned int minor) |
@@ -947,34 +968,8 @@ static void xen_write_msr(unsigned int msr, unsigned low, unsigned high) | |||
947 | xen_write_msr_safe(msr, low, high); | 968 | xen_write_msr_safe(msr, low, high); |
948 | } | 969 | } |
949 | 970 | ||
950 | void xen_setup_shared_info(void) | ||
951 | { | ||
952 | set_fixmap(FIX_PARAVIRT_BOOTMAP, xen_start_info->shared_info); | ||
953 | |||
954 | HYPERVISOR_shared_info = | ||
955 | (struct shared_info *)fix_to_virt(FIX_PARAVIRT_BOOTMAP); | ||
956 | |||
957 | xen_setup_mfn_list_list(); | ||
958 | |||
959 | if (system_state == SYSTEM_BOOTING) { | ||
960 | #ifndef CONFIG_SMP | ||
961 | /* | ||
962 | * In UP this is as good a place as any to set up shared info. | ||
963 | * Limit this to boot only, at restore vcpu setup is done via | ||
964 | * xen_vcpu_restore(). | ||
965 | */ | ||
966 | xen_setup_vcpu_info_placement(); | ||
967 | #endif | ||
968 | /* | ||
969 | * Now that shared info is set up we can start using routines | ||
970 | * that point to pvclock area. | ||
971 | */ | ||
972 | xen_init_time_ops(); | ||
973 | } | ||
974 | } | ||
975 | |||
976 | /* This is called once we have the cpu_possible_mask */ | 971 | /* This is called once we have the cpu_possible_mask */ |
977 | void __ref xen_setup_vcpu_info_placement(void) | 972 | void __init xen_setup_vcpu_info_placement(void) |
978 | { | 973 | { |
979 | int cpu; | 974 | int cpu; |
980 | 975 | ||
@@ -1228,6 +1223,8 @@ asmlinkage __visible void __init xen_start_kernel(void) | |||
1228 | x86_init.irqs.intr_mode_init = x86_init_noop; | 1223 | x86_init.irqs.intr_mode_init = x86_init_noop; |
1229 | x86_init.oem.arch_setup = xen_arch_setup; | 1224 | x86_init.oem.arch_setup = xen_arch_setup; |
1230 | x86_init.oem.banner = xen_banner; | 1225 | x86_init.oem.banner = xen_banner; |
1226 | x86_init.hyper.init_platform = xen_pv_init_platform; | ||
1227 | x86_init.hyper.guest_late_init = xen_pv_guest_late_init; | ||
1231 | 1228 | ||
1232 | /* | 1229 | /* |
1233 | * Set up some pagetable state before starting to set any ptes. | 1230 | * Set up some pagetable state before starting to set any ptes. |
diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c index 2c30cabfda90..52206ad81e4b 100644 --- a/arch/x86/xen/mmu_pv.c +++ b/arch/x86/xen/mmu_pv.c | |||
@@ -1230,8 +1230,7 @@ static void __init xen_pagetable_p2m_free(void) | |||
1230 | * We roundup to the PMD, which means that if anybody at this stage is | 1230 | * We roundup to the PMD, which means that if anybody at this stage is |
1231 | * using the __ka address of xen_start_info or | 1231 | * using the __ka address of xen_start_info or |
1232 | * xen_start_info->shared_info they are in going to crash. Fortunatly | 1232 | * xen_start_info->shared_info they are in going to crash. Fortunatly |
1233 | * we have already revectored in xen_setup_kernel_pagetable and in | 1233 | * we have already revectored in xen_setup_kernel_pagetable. |
1234 | * xen_setup_shared_info. | ||
1235 | */ | 1234 | */ |
1236 | size = roundup(size, PMD_SIZE); | 1235 | size = roundup(size, PMD_SIZE); |
1237 | 1236 | ||
@@ -1292,8 +1291,7 @@ static void __init xen_pagetable_init(void) | |||
1292 | 1291 | ||
1293 | /* Remap memory freed due to conflicts with E820 map */ | 1292 | /* Remap memory freed due to conflicts with E820 map */ |
1294 | xen_remap_memory(); | 1293 | xen_remap_memory(); |
1295 | 1294 | xen_setup_mfn_list_list(); | |
1296 | xen_setup_shared_info(); | ||
1297 | } | 1295 | } |
1298 | static void xen_write_cr2(unsigned long cr2) | 1296 | static void xen_write_cr2(unsigned long cr2) |
1299 | { | 1297 | { |
diff --git a/arch/x86/xen/suspend_pv.c b/arch/x86/xen/suspend_pv.c index a2e0f110af56..8303b58c79a9 100644 --- a/arch/x86/xen/suspend_pv.c +++ b/arch/x86/xen/suspend_pv.c | |||
@@ -27,8 +27,9 @@ void xen_pv_pre_suspend(void) | |||
27 | void xen_pv_post_suspend(int suspend_cancelled) | 27 | void xen_pv_post_suspend(int suspend_cancelled) |
28 | { | 28 | { |
29 | xen_build_mfn_list_list(); | 29 | xen_build_mfn_list_list(); |
30 | 30 | set_fixmap(FIX_PARAVIRT_BOOTMAP, xen_start_info->shared_info); | |
31 | xen_setup_shared_info(); | 31 | HYPERVISOR_shared_info = (void *)fix_to_virt(FIX_PARAVIRT_BOOTMAP); |
32 | xen_setup_mfn_list_list(); | ||
32 | 33 | ||
33 | if (suspend_cancelled) { | 34 | if (suspend_cancelled) { |
34 | xen_start_info->store_mfn = | 35 | xen_start_info->store_mfn = |
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index e0f1bcf01d63..53bb7a8d10b5 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c | |||
@@ -40,7 +40,7 @@ static unsigned long xen_tsc_khz(void) | |||
40 | return pvclock_tsc_khz(info); | 40 | return pvclock_tsc_khz(info); |
41 | } | 41 | } |
42 | 42 | ||
43 | u64 xen_clocksource_read(void) | 43 | static u64 xen_clocksource_read(void) |
44 | { | 44 | { |
45 | struct pvclock_vcpu_time_info *src; | 45 | struct pvclock_vcpu_time_info *src; |
46 | u64 ret; | 46 | u64 ret; |
@@ -503,7 +503,7 @@ static void __init xen_time_init(void) | |||
503 | pvclock_gtod_register_notifier(&xen_pvclock_gtod_notifier); | 503 | pvclock_gtod_register_notifier(&xen_pvclock_gtod_notifier); |
504 | } | 504 | } |
505 | 505 | ||
506 | void __ref xen_init_time_ops(void) | 506 | void __init xen_init_time_ops(void) |
507 | { | 507 | { |
508 | pv_time_ops = xen_time_ops; | 508 | pv_time_ops = xen_time_ops; |
509 | 509 | ||
@@ -542,8 +542,7 @@ void __init xen_hvm_init_time_ops(void) | |||
542 | return; | 542 | return; |
543 | 543 | ||
544 | if (!xen_feature(XENFEAT_hvm_safe_pvclock)) { | 544 | if (!xen_feature(XENFEAT_hvm_safe_pvclock)) { |
545 | printk(KERN_INFO "Xen doesn't support pvclock on HVM," | 545 | pr_info("Xen doesn't support pvclock on HVM, disable pv timer"); |
546 | "disable pv timer\n"); | ||
547 | return; | 546 | return; |
548 | } | 547 | } |
549 | 548 | ||
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index 3b34745d0a52..e78684597f57 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h | |||
@@ -31,7 +31,6 @@ extern struct shared_info xen_dummy_shared_info; | |||
31 | extern struct shared_info *HYPERVISOR_shared_info; | 31 | extern struct shared_info *HYPERVISOR_shared_info; |
32 | 32 | ||
33 | void xen_setup_mfn_list_list(void); | 33 | void xen_setup_mfn_list_list(void); |
34 | void xen_setup_shared_info(void); | ||
35 | void xen_build_mfn_list_list(void); | 34 | void xen_build_mfn_list_list(void); |
36 | void xen_setup_machphys_mapping(void); | 35 | void xen_setup_machphys_mapping(void); |
37 | void xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn); | 36 | void xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn); |
@@ -68,12 +67,11 @@ void xen_init_irq_ops(void); | |||
68 | void xen_setup_timer(int cpu); | 67 | void xen_setup_timer(int cpu); |
69 | void xen_setup_runstate_info(int cpu); | 68 | void xen_setup_runstate_info(int cpu); |
70 | void xen_teardown_timer(int cpu); | 69 | void xen_teardown_timer(int cpu); |
71 | u64 xen_clocksource_read(void); | ||
72 | void xen_setup_cpu_clockevents(void); | 70 | void xen_setup_cpu_clockevents(void); |
73 | void xen_save_time_memory_area(void); | 71 | void xen_save_time_memory_area(void); |
74 | void xen_restore_time_memory_area(void); | 72 | void xen_restore_time_memory_area(void); |
75 | void __ref xen_init_time_ops(void); | 73 | void xen_init_time_ops(void); |
76 | void __init xen_hvm_init_time_ops(void); | 74 | void xen_hvm_init_time_ops(void); |
77 | 75 | ||
78 | irqreturn_t xen_debug_interrupt(int irq, void *dev_id); | 76 | irqreturn_t xen_debug_interrupt(int irq, void *dev_id); |
79 | 77 | ||