diff options
Diffstat (limited to 'arch/ia64/kvm')
-rw-r--r-- | arch/ia64/kvm/kvm_fw.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/arch/ia64/kvm/kvm_fw.c b/arch/ia64/kvm/kvm_fw.c index a8ae52ed5635..e4b82319881d 100644 --- a/arch/ia64/kvm/kvm_fw.c +++ b/arch/ia64/kvm/kvm_fw.c | |||
@@ -21,6 +21,9 @@ | |||
21 | 21 | ||
22 | #include <linux/kvm_host.h> | 22 | #include <linux/kvm_host.h> |
23 | #include <linux/smp.h> | 23 | #include <linux/smp.h> |
24 | #include <asm/sn/addrs.h> | ||
25 | #include <asm/sn/clksupport.h> | ||
26 | #include <asm/sn/shub_mmr.h> | ||
24 | 27 | ||
25 | #include "vti.h" | 28 | #include "vti.h" |
26 | #include "misc.h" | 29 | #include "misc.h" |
@@ -188,12 +191,35 @@ static struct ia64_pal_retval pal_freq_base(struct kvm_vcpu *vcpu) | |||
188 | return result; | 191 | return result; |
189 | } | 192 | } |
190 | 193 | ||
191 | static struct ia64_pal_retval pal_freq_ratios(struct kvm_vcpu *vcpu) | 194 | /* |
195 | * On the SGI SN2, the ITC isn't stable. Emulation backed by the SN2 | ||
196 | * RTC is used instead. This function patches the ratios from SAL | ||
197 | * to match the RTC before providing them to the guest. | ||
198 | */ | ||
199 | static void sn2_patch_itc_freq_ratios(struct ia64_pal_retval *result) | ||
192 | { | 200 | { |
201 | struct pal_freq_ratio *ratio; | ||
202 | unsigned long sal_freq, sal_drift, factor; | ||
203 | |||
204 | result->status = ia64_sal_freq_base(SAL_FREQ_BASE_PLATFORM, | ||
205 | &sal_freq, &sal_drift); | ||
206 | ratio = (struct pal_freq_ratio *)&result->v2; | ||
207 | factor = ((sal_freq * 3) + (sn_rtc_cycles_per_second / 2)) / | ||
208 | sn_rtc_cycles_per_second; | ||
209 | |||
210 | ratio->num = 3; | ||
211 | ratio->den = factor; | ||
212 | } | ||
193 | 213 | ||
214 | static struct ia64_pal_retval pal_freq_ratios(struct kvm_vcpu *vcpu) | ||
215 | { | ||
194 | struct ia64_pal_retval result; | 216 | struct ia64_pal_retval result; |
195 | 217 | ||
196 | PAL_CALL(result, PAL_FREQ_RATIOS, 0, 0, 0); | 218 | PAL_CALL(result, PAL_FREQ_RATIOS, 0, 0, 0); |
219 | |||
220 | if (vcpu->kvm->arch.is_sn2) | ||
221 | sn2_patch_itc_freq_ratios(&result); | ||
222 | |||
197 | return result; | 223 | return result; |
198 | } | 224 | } |
199 | 225 | ||