aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kvm/kvm-ia64.c
diff options
context:
space:
mode:
authorJes Sorensen <jes@sgi.com>2009-02-25 11:38:55 -0500
committerAvi Kivity <avi@redhat.com>2009-06-10 04:48:29 -0400
commit0b5d7a2ccb98f0403b1969295429724af9dc9d8e (patch)
tree56108639641d6634df4a1de4e3ef4d4b9589a26b /arch/ia64/kvm/kvm-ia64.c
parentce17c643738bebcacf8d19d8cab7dd3eb96f9f32 (diff)
KVM: ia64: Drop in SN2 replacement of fast path ITC emulation fault handler
Copy in SN2 RTC based ITC emulation for fast exit. The two versions have the same size, so a dropin is simpler than patching the branch instruction to hit the SN2 version. 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/kvm/kvm-ia64.c')
-rw-r--r--arch/ia64/kvm/kvm-ia64.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index ebbd995194fb..4623a90e515a 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -1671,8 +1671,37 @@ out:
1671 return 0; 1671 return 0;
1672} 1672}
1673 1673
1674
1675/*
1676 * On SN2, the ITC isn't stable, so copy in fast path code to use the
1677 * SN2 RTC, replacing the ITC based default verion.
1678 */
1679static void kvm_patch_vmm(struct kvm_vmm_info *vmm_info,
1680 struct module *module)
1681{
1682 unsigned long new_ar, new_ar_sn2;
1683 unsigned long module_base;
1684
1685 if (!ia64_platform_is("sn2"))
1686 return;
1687
1688 module_base = (unsigned long)module->module_core;
1689
1690 new_ar = kvm_vmm_base + vmm_info->patch_mov_ar - module_base;
1691 new_ar_sn2 = kvm_vmm_base + vmm_info->patch_mov_ar_sn2 - module_base;
1692
1693 printk(KERN_INFO "kvm: Patching ITC emulation to use SGI SN2 RTC "
1694 "as source\n");
1695
1696 /*
1697 * Copy the SN2 version of mov_ar into place. They are both
1698 * the same size, so 6 bundles is sufficient (6 * 0x10).
1699 */
1700 memcpy((void *)new_ar, (void *)new_ar_sn2, 0x60);
1701}
1702
1674static int kvm_relocate_vmm(struct kvm_vmm_info *vmm_info, 1703static int kvm_relocate_vmm(struct kvm_vmm_info *vmm_info,
1675 struct module *module) 1704 struct module *module)
1676{ 1705{
1677 unsigned long module_base; 1706 unsigned long module_base;
1678 unsigned long vmm_size; 1707 unsigned long vmm_size;
@@ -1694,6 +1723,7 @@ static int kvm_relocate_vmm(struct kvm_vmm_info *vmm_info,
1694 return -EFAULT; 1723 return -EFAULT;
1695 1724
1696 memcpy((void *)kvm_vmm_base, (void *)module_base, vmm_size); 1725 memcpy((void *)kvm_vmm_base, (void *)module_base, vmm_size);
1726 kvm_patch_vmm(vmm_info, module);
1697 kvm_flush_icache(kvm_vmm_base, vmm_size); 1727 kvm_flush_icache(kvm_vmm_base, vmm_size);
1698 1728
1699 /*Recalculate kvm_vmm_info based on new VMM*/ 1729 /*Recalculate kvm_vmm_info based on new VMM*/