aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/mshyperv.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/cpu/mshyperv.c')
-rw-r--r--arch/x86/kernel/cpu/mshyperv.c50
1 files changed, 27 insertions, 23 deletions
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 65e20c97e04b..b5375b9497b3 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -133,26 +133,6 @@ static uint32_t __init ms_hyperv_platform(void)
133 return 0; 133 return 0;
134} 134}
135 135
136static u64 read_hv_clock(struct clocksource *arg)
137{
138 u64 current_tick;
139 /*
140 * Read the partition counter to get the current tick count. This count
141 * is set to 0 when the partition is created and is incremented in
142 * 100 nanosecond units.
143 */
144 rdmsrl(HV_X64_MSR_TIME_REF_COUNT, current_tick);
145 return current_tick;
146}
147
148static struct clocksource hyperv_cs = {
149 .name = "hyperv_clocksource",
150 .rating = 400, /* use this when running on Hyperv*/
151 .read = read_hv_clock,
152 .mask = CLOCKSOURCE_MASK(64),
153 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
154};
155
156static unsigned char hv_get_nmi_reason(void) 136static unsigned char hv_get_nmi_reason(void)
157{ 137{
158 return 0; 138 return 0;
@@ -180,6 +160,11 @@ static int hv_nmi_unknown(unsigned int val, struct pt_regs *regs)
180 160
181static void __init ms_hyperv_init_platform(void) 161static void __init ms_hyperv_init_platform(void)
182{ 162{
163 int hv_host_info_eax;
164 int hv_host_info_ebx;
165 int hv_host_info_ecx;
166 int hv_host_info_edx;
167
183 /* 168 /*
184 * Extract the features and hints 169 * Extract the features and hints
185 */ 170 */
@@ -190,6 +175,21 @@ static void __init ms_hyperv_init_platform(void)
190 pr_info("HyperV: features 0x%x, hints 0x%x\n", 175 pr_info("HyperV: features 0x%x, hints 0x%x\n",
191 ms_hyperv.features, ms_hyperv.hints); 176 ms_hyperv.features, ms_hyperv.hints);
192 177
178 /*
179 * Extract host information.
180 */
181 if (cpuid_eax(HVCPUID_VENDOR_MAXFUNCTION) >= HVCPUID_VERSION) {
182 hv_host_info_eax = cpuid_eax(HVCPUID_VERSION);
183 hv_host_info_ebx = cpuid_ebx(HVCPUID_VERSION);
184 hv_host_info_ecx = cpuid_ecx(HVCPUID_VERSION);
185 hv_host_info_edx = cpuid_edx(HVCPUID_VERSION);
186
187 pr_info("Hyper-V Host Build:%d-%d.%d-%d-%d.%d\n",
188 hv_host_info_eax, hv_host_info_ebx >> 16,
189 hv_host_info_ebx & 0xFFFF, hv_host_info_ecx,
190 hv_host_info_edx >> 24, hv_host_info_edx & 0xFFFFFF);
191 }
192
193#ifdef CONFIG_X86_LOCAL_APIC 193#ifdef CONFIG_X86_LOCAL_APIC
194 if (ms_hyperv.features & HV_X64_MSR_APIC_FREQUENCY_AVAILABLE) { 194 if (ms_hyperv.features & HV_X64_MSR_APIC_FREQUENCY_AVAILABLE) {
195 /* 195 /*
@@ -208,9 +208,6 @@ static void __init ms_hyperv_init_platform(void)
208 "hv_nmi_unknown"); 208 "hv_nmi_unknown");
209#endif 209#endif
210 210
211 if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
212 clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100);
213
214#ifdef CONFIG_X86_IO_APIC 211#ifdef CONFIG_X86_IO_APIC
215 no_timer_check = 1; 212 no_timer_check = 1;
216#endif 213#endif
@@ -227,6 +224,13 @@ static void __init ms_hyperv_init_platform(void)
227 */ 224 */
228 if (efi_enabled(EFI_BOOT)) 225 if (efi_enabled(EFI_BOOT))
229 x86_platform.get_nmi_reason = hv_get_nmi_reason; 226 x86_platform.get_nmi_reason = hv_get_nmi_reason;
227
228#if IS_ENABLED(CONFIG_HYPERV)
229 /*
230 * Setup the hook to get control post apic initialization.
231 */
232 x86_platform.apic_post_init = hyperv_init;
233#endif
230} 234}
231 235
232const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = { 236const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = {