Skip to content

Commit

Permalink
KVM: ia64: Drop in SN2 replacement of fast path ITC emulation fault h…
Browse files Browse the repository at this point in the history
…andler

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>
  • Loading branch information
Jes Sorensen authored and Avi Kivity committed Jun 10, 2009
1 parent ce17c64 commit 0b5d7a2
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 5 deletions.
2 changes: 2 additions & 0 deletions arch/ia64/include/asm/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,8 @@ struct kvm_vmm_info{
kvm_vmm_entry *vmm_entry;
kvm_tramp_entry *tramp_entry;
unsigned long vmm_ivt;
unsigned long patch_mov_ar;
unsigned long patch_mov_ar_sn2;
};

int kvm_highest_pending_irq(struct kvm_vcpu *vcpu);
Expand Down
32 changes: 31 additions & 1 deletion arch/ia64/kvm/kvm-ia64.c
Original file line number Diff line number Diff line change
Expand Up @@ -1671,8 +1671,37 @@ static int vti_cpu_has_kvm_support(void)
return 0;
}


/*
* On SN2, the ITC isn't stable, so copy in fast path code to use the
* SN2 RTC, replacing the ITC based default verion.
*/
static void kvm_patch_vmm(struct kvm_vmm_info *vmm_info,
struct module *module)
{
unsigned long new_ar, new_ar_sn2;
unsigned long module_base;

if (!ia64_platform_is("sn2"))
return;

module_base = (unsigned long)module->module_core;

new_ar = kvm_vmm_base + vmm_info->patch_mov_ar - module_base;
new_ar_sn2 = kvm_vmm_base + vmm_info->patch_mov_ar_sn2 - module_base;

printk(KERN_INFO "kvm: Patching ITC emulation to use SGI SN2 RTC "
"as source\n");

/*
* Copy the SN2 version of mov_ar into place. They are both
* the same size, so 6 bundles is sufficient (6 * 0x10).
*/
memcpy((void *)new_ar, (void *)new_ar_sn2, 0x60);
}

static int kvm_relocate_vmm(struct kvm_vmm_info *vmm_info,
struct module *module)
struct module *module)
{
unsigned long module_base;
unsigned long vmm_size;
Expand All @@ -1694,6 +1723,7 @@ static int kvm_relocate_vmm(struct kvm_vmm_info *vmm_info,
return -EFAULT;

memcpy((void *)kvm_vmm_base, (void *)module_base, vmm_size);
kvm_patch_vmm(vmm_info, module);
kvm_flush_icache(kvm_vmm_base, vmm_size);

/*Recalculate kvm_vmm_info based on new VMM*/
Expand Down
30 changes: 30 additions & 0 deletions arch/ia64/kvm/optvfault.S
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <asm/asmmacro.h>
#include <asm/processor.h>
#include <asm/kvm_host.h>

#include "vti.h"
#include "asm-offsets.h"
Expand Down Expand Up @@ -140,6 +141,35 @@ GLOBAL_ENTRY(kvm_asm_mov_from_ar)
;;
END(kvm_asm_mov_from_ar)

/*
* Special SGI SN2 optimized version of mov_from_ar using the SN2 RTC
* clock as it's source for emulating the ITC. This version will be
* copied on top of the original version if the host is determined to
* be an SN2.
*/
GLOBAL_ENTRY(kvm_asm_mov_from_ar_sn2)
add r18=VMM_VCPU_ITC_OFS_OFFSET, r21
movl r19 = (KVM_VMM_BASE+(1<<KVM_VMM_SHIFT))

add r16=VMM_VCPU_LAST_ITC_OFFSET,r21
extr.u r17=r25,6,7
mov r24=b0
;;
ld8 r18=[r18]
ld8 r19=[r19]
addl r20=@gprel(asm_mov_to_reg),gp
;;
add r19=r19,r18
shladd r17=r17,4,r20
;;
adds r30=kvm_resume_to_guest-asm_mov_to_reg,r20
st8 [r16] = r19
mov b0=r17
br.sptk.few b0
;;
END(kvm_asm_mov_from_ar_sn2)



// mov r1=rr[r3]
GLOBAL_ENTRY(kvm_asm_mov_from_rr)
Expand Down
12 changes: 8 additions & 4 deletions arch/ia64/kvm/vmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,19 @@ MODULE_AUTHOR("Intel");
MODULE_LICENSE("GPL");

extern char kvm_ia64_ivt;
extern char kvm_asm_mov_from_ar;
extern char kvm_asm_mov_from_ar_sn2;
extern fpswa_interface_t *vmm_fpswa_interface;

long vmm_sanity = 1;

struct kvm_vmm_info vmm_info = {
.module = THIS_MODULE,
.vmm_entry = vmm_entry,
.tramp_entry = vmm_trampoline,
.vmm_ivt = (unsigned long)&kvm_ia64_ivt,
.module = THIS_MODULE,
.vmm_entry = vmm_entry,
.tramp_entry = vmm_trampoline,
.vmm_ivt = (unsigned long)&kvm_ia64_ivt,
.patch_mov_ar = (unsigned long)&kvm_asm_mov_from_ar,
.patch_mov_ar_sn2 = (unsigned long)&kvm_asm_mov_from_ar_sn2,
};

static int __init kvm_vmm_init(void)
Expand Down

0 comments on commit 0b5d7a2

Please sign in to comment.