diff options
author | Juergen Gross <jgross@suse.com> | 2017-04-13 03:37:20 -0400 |
---|---|---|
committer | Juergen Gross <jgross@suse.com> | 2017-05-02 05:14:24 -0400 |
commit | d40342a2ac035444897e5952ea72a50440a2a028 (patch) | |
tree | 665a2fcc778d0628cc75f7c74d0d92064ba85703 | |
parent | 6807cf65f5ba6f2902ab64355d71506b9c14a9dd (diff) |
vmware: set cpu capabilities during platform initialization
There is no need to set the same capabilities for each cpu
individually. This can be done for all cpus in platform initialization.
Cc: Alok Kataria <akataria@vmware.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
Cc: virtualization@lists.linux-foundation.org
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Acked-by: Alok Kataria <akataria@vmware.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
-rw-r--r-- | arch/x86/kernel/cpu/vmware.c | 39 |
1 files changed, 20 insertions, 19 deletions
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c index 22403a28caf5..40ed26852ebd 100644 --- a/arch/x86/kernel/cpu/vmware.c +++ b/arch/x86/kernel/cpu/vmware.c | |||
@@ -113,6 +113,24 @@ static void __init vmware_paravirt_ops_setup(void) | |||
113 | #define vmware_paravirt_ops_setup() do {} while (0) | 113 | #define vmware_paravirt_ops_setup() do {} while (0) |
114 | #endif | 114 | #endif |
115 | 115 | ||
116 | /* | ||
117 | * VMware hypervisor takes care of exporting a reliable TSC to the guest. | ||
118 | * Still, due to timing difference when running on virtual cpus, the TSC can | ||
119 | * be marked as unstable in some cases. For example, the TSC sync check at | ||
120 | * bootup can fail due to a marginal offset between vcpus' TSCs (though the | ||
121 | * TSCs do not drift from each other). Also, the ACPI PM timer clocksource | ||
122 | * is not suitable as a watchdog when running on a hypervisor because the | ||
123 | * kernel may miss a wrap of the counter if the vcpu is descheduled for a | ||
124 | * long time. To skip these checks at runtime we set these capability bits, | ||
125 | * so that the kernel could just trust the hypervisor with providing a | ||
126 | * reliable virtual TSC that is suitable for timekeeping. | ||
127 | */ | ||
128 | static void __init vmware_set_capabilities(void) | ||
129 | { | ||
130 | setup_force_cpu_cap(X86_FEATURE_CONSTANT_TSC); | ||
131 | setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE); | ||
132 | } | ||
133 | |||
116 | static void __init vmware_platform_setup(void) | 134 | static void __init vmware_platform_setup(void) |
117 | { | 135 | { |
118 | uint32_t eax, ebx, ecx, edx; | 136 | uint32_t eax, ebx, ecx, edx; |
@@ -152,6 +170,8 @@ static void __init vmware_platform_setup(void) | |||
152 | #ifdef CONFIG_X86_IO_APIC | 170 | #ifdef CONFIG_X86_IO_APIC |
153 | no_timer_check = 1; | 171 | no_timer_check = 1; |
154 | #endif | 172 | #endif |
173 | |||
174 | vmware_set_capabilities(); | ||
155 | } | 175 | } |
156 | 176 | ||
157 | /* | 177 | /* |
@@ -176,24 +196,6 @@ static uint32_t __init vmware_platform(void) | |||
176 | return 0; | 196 | return 0; |
177 | } | 197 | } |
178 | 198 | ||
179 | /* | ||
180 | * VMware hypervisor takes care of exporting a reliable TSC to the guest. | ||
181 | * Still, due to timing difference when running on virtual cpus, the TSC can | ||
182 | * be marked as unstable in some cases. For example, the TSC sync check at | ||
183 | * bootup can fail due to a marginal offset between vcpus' TSCs (though the | ||
184 | * TSCs do not drift from each other). Also, the ACPI PM timer clocksource | ||
185 | * is not suitable as a watchdog when running on a hypervisor because the | ||
186 | * kernel may miss a wrap of the counter if the vcpu is descheduled for a | ||
187 | * long time. To skip these checks at runtime we set these capability bits, | ||
188 | * so that the kernel could just trust the hypervisor with providing a | ||
189 | * reliable virtual TSC that is suitable for timekeeping. | ||
190 | */ | ||
191 | static void vmware_set_cpu_features(struct cpuinfo_x86 *c) | ||
192 | { | ||
193 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); | ||
194 | set_cpu_cap(c, X86_FEATURE_TSC_RELIABLE); | ||
195 | } | ||
196 | |||
197 | /* Checks if hypervisor supports x2apic without VT-D interrupt remapping. */ | 199 | /* Checks if hypervisor supports x2apic without VT-D interrupt remapping. */ |
198 | static bool __init vmware_legacy_x2apic_available(void) | 200 | static bool __init vmware_legacy_x2apic_available(void) |
199 | { | 201 | { |
@@ -206,7 +208,6 @@ static bool __init vmware_legacy_x2apic_available(void) | |||
206 | const __refconst struct hypervisor_x86 x86_hyper_vmware = { | 208 | const __refconst struct hypervisor_x86 x86_hyper_vmware = { |
207 | .name = "VMware", | 209 | .name = "VMware", |
208 | .detect = vmware_platform, | 210 | .detect = vmware_platform, |
209 | .set_cpu_features = vmware_set_cpu_features, | ||
210 | .init_platform = vmware_platform_setup, | 211 | .init_platform = vmware_platform_setup, |
211 | .x2apic_available = vmware_legacy_x2apic_available, | 212 | .x2apic_available = vmware_legacy_x2apic_available, |
212 | }; | 213 | }; |