Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0b5d7a2c authored by Jes Sorensen's avatar Jes Sorensen Committed by Avi Kivity
Browse files

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: default avatarJes Sorensen <jes@sgi.com>
Acked-by: default avatarXiantao Zhang <xiantao.zhang@intel.com>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent ce17c643
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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);
+31 −1
Original line number Diff line number Diff line
@@ -1671,6 +1671,35 @@ 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)
{
@@ -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*/
+30 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@

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

#include "vti.h"
#include "asm-offsets.h"
@@ -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)
+8 −4
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@ 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;
@@ -39,6 +41,8 @@ struct kvm_vmm_info vmm_info = {
	.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)