summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJes Sorensen <jes@sgi.com>2009-02-25 17:38:54 +0100
committerAvi Kivity <avi@redhat.com>2009-06-10 10:48:29 +0200
commitce17c643738bebcacf8d19d8cab7dd3eb96f9f32 (patch)
treea214837252c040ac265d6af58b322414e491063e
parentKVM: ia64: Create inline function kvm_get_itc() to centralize ITC reading. (diff)
downloadlinux-ce17c643738bebcacf8d19d8cab7dd3eb96f9f32.tar.xz
linux-ce17c643738bebcacf8d19d8cab7dd3eb96f9f32.zip
KVM: ia64: SN2 adjust emulated ITC frequency to match RTC frequency
On SN2 do not pass down the real ITC frequency, but rather patch the values to match the SN2 RTC frequency. Signed-off-by: Jes Sorensen <jes@sgi.com> Acked-by: Xiantao Zhang <xiantao.zhang@intel.com> Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--arch/ia64/kvm/kvm_fw.c28
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 @@
#include <linux/kvm_host.h>
#include <linux/smp.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/clksupport.h>
+#include <asm/sn/shub_mmr.h>
#include "vti.h"
#include "misc.h"
@@ -188,12 +191,35 @@ static struct ia64_pal_retval pal_freq_base(struct kvm_vcpu *vcpu)
return result;
}
-static struct ia64_pal_retval pal_freq_ratios(struct kvm_vcpu *vcpu)
+/*
+ * On the SGI SN2, the ITC isn't stable. Emulation backed by the SN2
+ * RTC is used instead. This function patches the ratios from SAL
+ * to match the RTC before providing them to the guest.
+ */
+static void sn2_patch_itc_freq_ratios(struct ia64_pal_retval *result)
{
+ struct pal_freq_ratio *ratio;
+ unsigned long sal_freq, sal_drift, factor;
+
+ result->status = ia64_sal_freq_base(SAL_FREQ_BASE_PLATFORM,
+ &sal_freq, &sal_drift);
+ ratio = (struct pal_freq_ratio *)&result->v2;
+ factor = ((sal_freq * 3) + (sn_rtc_cycles_per_second / 2)) /
+ sn_rtc_cycles_per_second;
+
+ ratio->num = 3;
+ ratio->den = factor;
+}
+static struct ia64_pal_retval pal_freq_ratios(struct kvm_vcpu *vcpu)
+{
struct ia64_pal_retval result;
PAL_CALL(result, PAL_FREQ_RATIOS, 0, 0, 0);
+
+ if (vcpu->kvm->arch.is_sn2)
+ sn2_patch_itc_freq_ratios(&result);
+
return result;
}