aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kvm/kvm-ia64.c
diff options
context:
space:
mode:
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*/