aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
authorJes Sorensen <jes@sgi.com>2009-02-25 11:38:53 -0500
committerAvi Kivity <avi@redhat.com>2009-06-10 04:48:28 -0400
commitc6c9fcdf0fff7da77c088be11e3c4d0181b36941 (patch)
tree2de6d8ecc5e58a3d3b744defa741faf191144d0b /arch/ia64
parent0c72ea7fb8a39b4bba071b19f5f835af5b5e538a (diff)
KVM: ia64: Create inline function kvm_get_itc() to centralize ITC reading.
Move all reading of special register 'AR_ITC' into two functions, one in the kernel and one in the VMM module. When running on SN2, base the result on the RTC rather the system ITC, as the ITC isn't synchronized. Signed-off-by: Jes Sorensen <jes@sgi.com> Acked-by: Xiantao Zhang <xiantao.zhang@intel.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/kvm/kvm-ia64.c18
-rw-r--r--arch/ia64/kvm/vcpu.c20
2 files changed, 32 insertions, 6 deletions
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index 14a3fabc7d62..ebbd995194fb 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -68,6 +68,16 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
68 { NULL } 68 { NULL }
69}; 69};
70 70
71static unsigned long kvm_get_itc(struct kvm_vcpu *vcpu)
72{
73#if defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC)
74 if (vcpu->kvm->arch.is_sn2)
75 return rtc_time();
76 else
77#endif
78 return ia64_getreg(_IA64_REG_AR_ITC);
79}
80
71static void kvm_flush_icache(unsigned long start, unsigned long len) 81static void kvm_flush_icache(unsigned long start, unsigned long len)
72{ 82{
73 int l; 83 int l;
@@ -457,7 +467,7 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu)
457 467
458 if (irqchip_in_kernel(vcpu->kvm)) { 468 if (irqchip_in_kernel(vcpu->kvm)) {
459 469
460 vcpu_now_itc = ia64_getreg(_IA64_REG_AR_ITC) + vcpu->arch.itc_offset; 470 vcpu_now_itc = kvm_get_itc(vcpu) + vcpu->arch.itc_offset;
461 471
462 if (time_after(vcpu_now_itc, vpd->itm)) { 472 if (time_after(vcpu_now_itc, vpd->itm)) {
463 vcpu->arch.timer_check = 1; 473 vcpu->arch.timer_check = 1;
@@ -929,7 +939,7 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
929 RESTORE_REGS(saved_gp); 939 RESTORE_REGS(saved_gp);
930 940
931 vcpu->arch.irq_new_pending = 1; 941 vcpu->arch.irq_new_pending = 1;
932 vcpu->arch.itc_offset = regs->saved_itc - ia64_getreg(_IA64_REG_AR_ITC); 942 vcpu->arch.itc_offset = regs->saved_itc - kvm_get_itc(vcpu);
933 set_bit(KVM_REQ_RESUME, &vcpu->requests); 943 set_bit(KVM_REQ_RESUME, &vcpu->requests);
934 944
935 vcpu_put(vcpu); 945 vcpu_put(vcpu);
@@ -1210,7 +1220,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
1210 regs->cr_iip = PALE_RESET_ENTRY; 1220 regs->cr_iip = PALE_RESET_ENTRY;
1211 1221
1212 /*Initialize itc offset for vcpus*/ 1222 /*Initialize itc offset for vcpus*/
1213 itc_offset = 0UL - ia64_getreg(_IA64_REG_AR_ITC); 1223 itc_offset = 0UL - kvm_get_itc(vcpu);
1214 for (i = 0; i < kvm->arch.online_vcpus; i++) { 1224 for (i = 0; i < kvm->arch.online_vcpus; i++) {
1215 v = (struct kvm_vcpu *)((char *)vcpu + 1225 v = (struct kvm_vcpu *)((char *)vcpu +
1216 sizeof(struct kvm_vcpu_data) * i); 1226 sizeof(struct kvm_vcpu_data) * i);
@@ -1472,7 +1482,7 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
1472 } 1482 }
1473 for (i = 0; i < 4; i++) 1483 for (i = 0; i < 4; i++)
1474 regs->insvc[i] = vcpu->arch.insvc[i]; 1484 regs->insvc[i] = vcpu->arch.insvc[i];
1475 regs->saved_itc = vcpu->arch.itc_offset + ia64_getreg(_IA64_REG_AR_ITC); 1485 regs->saved_itc = vcpu->arch.itc_offset + kvm_get_itc(vcpu);
1476 SAVE_REGS(xtp); 1486 SAVE_REGS(xtp);
1477 SAVE_REGS(metaphysical_rr0); 1487 SAVE_REGS(metaphysical_rr0);
1478 SAVE_REGS(metaphysical_rr4); 1488 SAVE_REGS(metaphysical_rr4);
diff --git a/arch/ia64/kvm/vcpu.c b/arch/ia64/kvm/vcpu.c
index a18ee17b9192..a2c6c15e4761 100644
--- a/arch/ia64/kvm/vcpu.c
+++ b/arch/ia64/kvm/vcpu.c
@@ -788,13 +788,29 @@ void vcpu_set_fpreg(struct kvm_vcpu *vcpu, unsigned long reg,
788 setfpreg(reg, val, regs); /* FIXME: handle NATs later*/ 788 setfpreg(reg, val, regs); /* FIXME: handle NATs later*/
789} 789}
790 790
791/*
792 * The Altix RTC is mapped specially here for the vmm module
793 */
794#define SN_RTC_BASE (u64 *)(KVM_VMM_BASE+(1UL<<KVM_VMM_SHIFT))
795static long kvm_get_itc(struct kvm_vcpu *vcpu)
796{
797#if defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC)
798 struct kvm *kvm = (struct kvm *)KVM_VM_BASE;
799
800 if (kvm->arch.is_sn2)
801 return (*SN_RTC_BASE);
802 else
803#endif
804 return ia64_getreg(_IA64_REG_AR_ITC);
805}
806
791/************************************************************************ 807/************************************************************************
792 * lsapic timer 808 * lsapic timer
793 ***********************************************************************/ 809 ***********************************************************************/
794u64 vcpu_get_itc(struct kvm_vcpu *vcpu) 810u64 vcpu_get_itc(struct kvm_vcpu *vcpu)
795{ 811{
796 unsigned long guest_itc; 812 unsigned long guest_itc;
797 guest_itc = VMX(vcpu, itc_offset) + ia64_getreg(_IA64_REG_AR_ITC); 813 guest_itc = VMX(vcpu, itc_offset) + kvm_get_itc(vcpu);
798 814
799 if (guest_itc >= VMX(vcpu, last_itc)) { 815 if (guest_itc >= VMX(vcpu, last_itc)) {
800 VMX(vcpu, last_itc) = guest_itc; 816 VMX(vcpu, last_itc) = guest_itc;
@@ -809,7 +825,7 @@ static void vcpu_set_itc(struct kvm_vcpu *vcpu, u64 val)
809 struct kvm_vcpu *v; 825 struct kvm_vcpu *v;
810 struct kvm *kvm; 826 struct kvm *kvm;
811 int i; 827 int i;
812 long itc_offset = val - ia64_getreg(_IA64_REG_AR_ITC); 828 long itc_offset = val - kvm_get_itc(vcpu);
813 unsigned long vitv = VCPU(vcpu, itv); 829 unsigned long vitv = VCPU(vcpu, itv);
814 830
815 kvm = (struct kvm *)KVM_VM_BASE; 831 kvm = (struct kvm *)KVM_VM_BASE;