diff options
| -rw-r--r-- | arch/x86/include/uapi/asm/hyperv.h | 19 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mshyperv.c | 27 |
2 files changed, 46 insertions, 0 deletions
diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h index b80420bcd09d..b8f1c0176cbc 100644 --- a/arch/x86/include/uapi/asm/hyperv.h +++ b/arch/x86/include/uapi/asm/hyperv.h | |||
| @@ -27,6 +27,19 @@ | |||
| 27 | #define HV_X64_MSR_VP_RUNTIME_AVAILABLE (1 << 0) | 27 | #define HV_X64_MSR_VP_RUNTIME_AVAILABLE (1 << 0) |
| 28 | /* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/ | 28 | /* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/ |
| 29 | #define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE (1 << 1) | 29 | #define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE (1 << 1) |
| 30 | |||
| 31 | /* | ||
| 32 | * There is a single feature flag that signifies the presence of the MSR | ||
| 33 | * that can be used to retrieve both the local APIC Timer frequency as | ||
| 34 | * well as the TSC frequency. | ||
| 35 | */ | ||
| 36 | |||
| 37 | /* Local APIC timer frequency MSR (HV_X64_MSR_APIC_FREQUENCY) is available */ | ||
| 38 | #define HV_X64_MSR_APIC_FREQUENCY_AVAILABLE (1 << 11) | ||
| 39 | |||
| 40 | /* TSC frequency MSR (HV_X64_MSR_TSC_FREQUENCY) is available */ | ||
| 41 | #define HV_X64_MSR_TSC_FREQUENCY_AVAILABLE (1 << 11) | ||
| 42 | |||
| 30 | /* | 43 | /* |
| 31 | * Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM | 44 | * Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM |
| 32 | * and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15) available | 45 | * and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15) available |
| @@ -136,6 +149,12 @@ | |||
| 136 | /* MSR used to read the per-partition time reference counter */ | 149 | /* MSR used to read the per-partition time reference counter */ |
| 137 | #define HV_X64_MSR_TIME_REF_COUNT 0x40000020 | 150 | #define HV_X64_MSR_TIME_REF_COUNT 0x40000020 |
| 138 | 151 | ||
| 152 | /* MSR used to retrieve the TSC frequency */ | ||
| 153 | #define HV_X64_MSR_TSC_FREQUENCY 0x40000022 | ||
| 154 | |||
| 155 | /* MSR used to retrieve the local APIC timer frequency */ | ||
| 156 | #define HV_X64_MSR_APIC_FREQUENCY 0x40000023 | ||
| 157 | |||
| 139 | /* Define the virtual APIC registers */ | 158 | /* Define the virtual APIC registers */ |
| 140 | #define HV_X64_MSR_EOI 0x40000070 | 159 | #define HV_X64_MSR_EOI 0x40000070 |
| 141 | #define HV_X64_MSR_ICR 0x40000071 | 160 | #define HV_X64_MSR_ICR 0x40000071 |
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 71a39f3621ba..9f7ca266864a 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/clocksource.h> | 15 | #include <linux/clocksource.h> |
| 16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 17 | #include <linux/hardirq.h> | 17 | #include <linux/hardirq.h> |
| 18 | #include <linux/efi.h> | ||
| 18 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
| 19 | #include <asm/processor.h> | 20 | #include <asm/processor.h> |
| 20 | #include <asm/hypervisor.h> | 21 | #include <asm/hypervisor.h> |
| @@ -23,6 +24,8 @@ | |||
| 23 | #include <asm/desc.h> | 24 | #include <asm/desc.h> |
| 24 | #include <asm/idle.h> | 25 | #include <asm/idle.h> |
| 25 | #include <asm/irq_regs.h> | 26 | #include <asm/irq_regs.h> |
| 27 | #include <asm/i8259.h> | ||
| 28 | #include <asm/apic.h> | ||
| 26 | 29 | ||
| 27 | struct ms_hyperv_info ms_hyperv; | 30 | struct ms_hyperv_info ms_hyperv; |
| 28 | EXPORT_SYMBOL_GPL(ms_hyperv); | 31 | EXPORT_SYMBOL_GPL(ms_hyperv); |
| @@ -76,6 +79,30 @@ static void __init ms_hyperv_init_platform(void) | |||
| 76 | printk(KERN_INFO "HyperV: features 0x%x, hints 0x%x\n", | 79 | printk(KERN_INFO "HyperV: features 0x%x, hints 0x%x\n", |
| 77 | ms_hyperv.features, ms_hyperv.hints); | 80 | ms_hyperv.features, ms_hyperv.hints); |
| 78 | 81 | ||
| 82 | #ifdef CONFIG_X86_LOCAL_APIC | ||
| 83 | if (ms_hyperv.features & HV_X64_MSR_APIC_FREQUENCY_AVAILABLE) { | ||
| 84 | /* | ||
| 85 | * Get the APIC frequency. | ||
| 86 | */ | ||
| 87 | u64 hv_lapic_frequency; | ||
| 88 | |||
| 89 | rdmsrl(HV_X64_MSR_APIC_FREQUENCY, hv_lapic_frequency); | ||
| 90 | hv_lapic_frequency = div_u64(hv_lapic_frequency, HZ); | ||
| 91 | lapic_timer_frequency = hv_lapic_frequency; | ||
| 92 | printk(KERN_INFO "HyperV: LAPIC Timer Frequency: %#x\n", | ||
| 93 | lapic_timer_frequency); | ||
| 94 | |||
| 95 | /* | ||
| 96 | * On Hyper-V, when we are booting off an EFI firmware stack, | ||
| 97 | * we do not have many legacy devices including PIC, PIT etc. | ||
| 98 | */ | ||
| 99 | if (efi_enabled(EFI_BOOT)) { | ||
| 100 | printk(KERN_INFO "HyperV: Using null_legacy_pic\n"); | ||
| 101 | legacy_pic = &null_legacy_pic; | ||
| 102 | } | ||
| 103 | } | ||
| 104 | #endif | ||
| 105 | |||
| 79 | if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE) | 106 | if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE) |
| 80 | clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100); | 107 | clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100); |
| 81 | } | 108 | } |
