diff options
author | K. Y. Srinivasan <kys@microsoft.com> | 2017-01-19 13:51:46 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-01-20 08:48:03 -0500 |
commit | 63ed4e0c67df332681ebfef6eca6852da28d6300 (patch) | |
tree | 361afae5de4505521562d8a6ee6446dc9ce9fef5 /drivers/hv/hv.c | |
parent | 669c256cb9fb29a540ce4befb4328d88c665e523 (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.c | 95 |
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 | ||
91 | static 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 | |||
130 | static 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 | |||
195 | cleanup: | ||
196 | return -ENOTSUPP; | ||
197 | } | 125 | } |
198 | 126 | ||
199 | /* | 127 | /* |
@@ -204,29 +132,6 @@ cleanup: | |||
204 | void hv_cleanup(bool crash) | 132 | void 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 | /* |