diff options
author | Jes Sorensen <jes@sgi.com> | 2009-02-25 11:38:55 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-06-10 04:48:29 -0400 |
commit | 0b5d7a2ccb98f0403b1969295429724af9dc9d8e (patch) | |
tree | 56108639641d6634df4a1de4e3ef4d4b9589a26b /arch/ia64/kvm/kvm-ia64.c | |
parent | ce17c643738bebcacf8d19d8cab7dd3eb96f9f32 (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.c | 32 |
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 | */ | ||
1679 | static 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 | |||
1674 | static int kvm_relocate_vmm(struct kvm_vmm_info *vmm_info, | 1703 | static 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*/ |