summaryrefslogtreecommitdiffstats
path: root/drivers/hv/hv.c
diff options
context:
space:
mode:
authorK. Y. Srinivasan <kys@microsoft.com>2017-01-19 13:51:46 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-01-20 08:48:03 -0500
commit63ed4e0c67df332681ebfef6eca6852da28d6300 (patch)
tree361afae5de4505521562d8a6ee6446dc9ce9fef5 /drivers/hv/hv.c
parent669c256cb9fb29a540ce4befb4328d88c665e523 (diff)
Drivers: hv: vmbus: Consolidate all Hyper-V specific clocksource code
As part of the effort to separate out architecture specific code, consolidate all Hyper-V specific clocksource code to an architecture specific code. Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv/hv.c')
-rw-r--r--drivers/hv/hv.c95
1 files changed, 0 insertions, 95 deletions
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index fd3b9b98a29d..1a33b59776d3 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -87,56 +87,6 @@ static int query_hypervisor_info(void)
87 return max_leaf; 87 return max_leaf;
88} 88}
89 89
90#ifdef CONFIG_X86_64
91static u64 read_hv_clock_tsc(struct clocksource *arg)
92{
93 u64 current_tick;
94 struct ms_hyperv_tsc_page *tsc_pg = hv_context.tsc_page;
95
96 if (tsc_pg->tsc_sequence != 0) {
97 /*
98 * Use the tsc page to compute the value.
99 */
100
101 while (1) {
102 u64 tmp;
103 u32 sequence = tsc_pg->tsc_sequence;
104 u64 cur_tsc;
105 u64 scale = tsc_pg->tsc_scale;
106 s64 offset = tsc_pg->tsc_offset;
107
108 rdtscll(cur_tsc);
109 /* current_tick = ((cur_tsc *scale) >> 64) + offset */
110 asm("mulq %3"
111 : "=d" (current_tick), "=a" (tmp)
112 : "a" (cur_tsc), "r" (scale));
113
114 current_tick += offset;
115 if (tsc_pg->tsc_sequence == sequence)
116 return current_tick;
117
118 if (tsc_pg->tsc_sequence != 0)
119 continue;
120 /*
121 * Fallback using MSR method.
122 */
123 break;
124 }
125 }
126 rdmsrl(HV_X64_MSR_TIME_REF_COUNT, current_tick);
127 return current_tick;
128}
129
130static struct clocksource hyperv_cs_tsc = {
131 .name = "hyperv_clocksource_tsc_page",
132 .rating = 425,
133 .read = read_hv_clock_tsc,
134 .mask = CLOCKSOURCE_MASK(64),
135 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
136};
137#endif
138
139
140/* 90/*
141 * hv_init - Main initialization routine. 91 * hv_init - Main initialization routine.
142 * 92 *
@@ -171,29 +121,7 @@ int hv_init(void)
171 if (!hypercall_msr.enable) 121 if (!hypercall_msr.enable)
172 return -ENOTSUPP; 122 return -ENOTSUPP;
173 123
174#ifdef CONFIG_X86_64
175 if (ms_hyperv.features & HV_X64_MSR_REFERENCE_TSC_AVAILABLE) {
176 union hv_x64_msr_hypercall_contents tsc_msr;
177 void *va_tsc;
178
179 va_tsc = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL);
180 if (!va_tsc)
181 goto cleanup;
182 hv_context.tsc_page = va_tsc;
183
184 rdmsrl(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
185
186 tsc_msr.enable = 1;
187 tsc_msr.guest_physical_address = vmalloc_to_pfn(va_tsc);
188
189 wrmsrl(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
190 clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100);
191 }
192#endif
193 return 0; 124 return 0;
194
195cleanup:
196 return -ENOTSUPP;
197} 125}
198 126
199/* 127/*
@@ -204,29 +132,6 @@ cleanup:
204void hv_cleanup(bool crash) 132void hv_cleanup(bool crash)
205{ 133{
206 134
207#ifdef CONFIG_X86_64
208 union hv_x64_msr_hypercall_contents hypercall_msr;
209 /*
210 * Cleanup the TSC page based CS.
211 */
212 if (ms_hyperv.features & HV_X64_MSR_REFERENCE_TSC_AVAILABLE) {
213 /*
214 * Crash can happen in an interrupt context and unregistering
215 * a clocksource is impossible and redundant in this case.
216 */
217 if (!oops_in_progress) {
218 clocksource_change_rating(&hyperv_cs_tsc, 10);
219 clocksource_unregister(&hyperv_cs_tsc);
220 }
221
222 hypercall_msr.as_uint64 = 0;
223 wrmsrl(HV_X64_MSR_REFERENCE_TSC, hypercall_msr.as_uint64);
224 if (!crash) {
225 vfree(hv_context.tsc_page);
226 hv_context.tsc_page = NULL;
227 }
228 }
229#endif
230} 135}
231 136
232/* 137/*