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

Commit 73196cd3 authored by Scott Wood's avatar Scott Wood Committed by Avi Kivity
Browse files

KVM: PPC: e500mc support



Add processor support for e500mc, using hardware virtualization support
(GS-mode).

Current issues include:
 - No support for external proxy (coreint) interrupt mode in the guest.

Includes work by Ashish Kalra <Ashish.Kalra@freescale.com>,
Varun Sethi <Varun.Sethi@freescale.com>, and
Liu Yu <yu.liu@freescale.com>.

Signed-off-by: default avatarScott Wood <scottwood@freescale.com>
Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent 8fae845f
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -168,6 +168,7 @@ extern const char *powerpc_base_platform;
#define CPU_FTR_LWSYNC			ASM_CONST(0x0000000008000000)
#define CPU_FTR_NOEXECUTE		ASM_CONST(0x0000000010000000)
#define CPU_FTR_INDEXED_DCR		ASM_CONST(0x0000000020000000)
#define CPU_FTR_EMB_HV			ASM_CONST(0x0000000040000000)

/*
 * Add the 64-bit processor unique features in the top half of the word;
@@ -386,11 +387,11 @@ extern const char *powerpc_base_platform;
	    CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE)
#define CPU_FTRS_E500MC	(CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \
	    CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
	    CPU_FTR_DBELL | CPU_FTR_DEBUG_LVL_EXC)
	    CPU_FTR_DBELL | CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV)
#define CPU_FTRS_E5500	(CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \
	    CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
	    CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
	    CPU_FTR_DEBUG_LVL_EXC)
	    CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV)
#define CPU_FTRS_E6500	(CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \
	    CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
	    CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
@@ -539,6 +540,7 @@ enum {
#ifdef CONFIG_PPC_E500MC
	    CPU_FTRS_E500MC & CPU_FTRS_E5500 & CPU_FTRS_E6500 &
#endif
	    ~CPU_FTR_EMB_HV &	/* can be removed at runtime */
	    CPU_FTRS_POSSIBLE,
};
#endif /* __powerpc64__ */
+1 −0
Original line number Diff line number Diff line
@@ -277,6 +277,7 @@ struct kvm_sync_regs {
#define KVM_CPU_E500V2		2
#define KVM_CPU_3S_32		3
#define KVM_CPU_3S_64		4
#define KVM_CPU_E500MC		5

/* for KVM_CAP_SPAPR_TCE */
struct kvm_create_spapr_tce {
+1 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ _GLOBAL(__setup_cpu_e500v2)
	mtlr	r4
	blr
_GLOBAL(__setup_cpu_e500mc)
	mr	r5, r4
	mflr	r4
	bl	__e500_icache_setup
	bl	__e500_dcache_setup
+46 −0
Original line number Diff line number Diff line
@@ -380,10 +380,16 @@ interrupt_base:
	mtspr	SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */
	mfspr	r10, SPRN_SPRG_THREAD
	stw	r11, THREAD_NORMSAVE(0)(r10)
#ifdef CONFIG_KVM_BOOKE_HV
BEGIN_FTR_SECTION
	mfspr	r11, SPRN_SRR1
END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
#endif
	stw	r12, THREAD_NORMSAVE(1)(r10)
	stw	r13, THREAD_NORMSAVE(2)(r10)
	mfcr	r13
	stw	r13, THREAD_NORMSAVE(3)(r10)
	DO_KVM	BOOKE_INTERRUPT_DTLB_MISS SPRN_SRR1
	mfspr	r10, SPRN_DEAR		/* Get faulting address */

	/* If we are faulting a kernel address, we have to use the
@@ -468,10 +474,16 @@ interrupt_base:
	mtspr	SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */
	mfspr	r10, SPRN_SPRG_THREAD
	stw	r11, THREAD_NORMSAVE(0)(r10)
#ifdef CONFIG_KVM_BOOKE_HV
BEGIN_FTR_SECTION
	mfspr	r11, SPRN_SRR1
END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
#endif
	stw	r12, THREAD_NORMSAVE(1)(r10)
	stw	r13, THREAD_NORMSAVE(2)(r10)
	mfcr	r13
	stw	r13, THREAD_NORMSAVE(3)(r10)
	DO_KVM	BOOKE_INTERRUPT_ITLB_MISS SPRN_SRR1
	mfspr	r10, SPRN_SRR0		/* Get faulting address */

	/* If we are faulting a kernel address, we have to use the
@@ -580,6 +592,17 @@ interrupt_base:
	DEBUG_DEBUG_EXCEPTION
	DEBUG_CRIT_EXCEPTION

	GUEST_DOORBELL_EXCEPTION

	CRITICAL_EXCEPTION(0, GUEST_DBELL_CRIT, CriticalGuestDoorbell, \
			   unknown_exception)

	/* Hypercall */
	EXCEPTION(0, HV_SYSCALL, Hypercall, unknown_exception, EXC_XFER_EE)

	/* Embedded Hypervisor Privilege */
	EXCEPTION(0, HV_PRIV, Ehvpriv, unknown_exception, EXC_XFER_EE)

/*
 * Local functions
 */
@@ -883,8 +906,31 @@ _GLOBAL(__setup_e500mc_ivors)
	mtspr	SPRN_IVOR36,r3
	li	r3,CriticalDoorbell@l
	mtspr	SPRN_IVOR37,r3

	/*
	 * We only want to touch IVOR38-41 if we're running on hardware
	 * that supports category E.HV.  The architectural way to determine
	 * this is MMUCFG[LPIDSIZE].
	 */
	mfspr	r3, SPRN_MMUCFG
	andis.	r3, r3, MMUCFG_LPIDSIZE@h
	beq	no_hv
	li	r3,GuestDoorbell@l
	mtspr	SPRN_IVOR38,r3
	li	r3,CriticalGuestDoorbell@l
	mtspr	SPRN_IVOR39,r3
	li	r3,Hypercall@l
	mtspr	SPRN_IVOR40,r3
	li	r3,Ehvpriv@l
	mtspr	SPRN_IVOR41,r3
skip_hv_ivors:
	sync
	blr
no_hv:
	lwz	r3, CPU_SPEC_FEATURES(r5)
	rlwinm	r3, r3, 0, ~CPU_FTR_EMB_HV
	stw	r3, CPU_SPEC_FEATURES(r5)
	b	skip_hv_ivors

/*
 * extern void giveup_altivec(struct task_struct *prev)
+16 −1
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ config KVM_440

config KVM_EXIT_TIMING
	bool "Detailed exit timing"
	depends on KVM_440 || KVM_E500
	depends on KVM_440 || KVM_E500 || KVM_E500MC
	---help---
	  Calculate elapsed time for every exit/enter cycle. A per-vcpu
	  report is available in debugfs kvm/vm#_vcpu#_timing.
@@ -132,6 +132,21 @@ config KVM_E500

	  If unsure, say N.

config KVM_E500MC
	bool "KVM support for PowerPC E500MC/E5500 processors"
	depends on EXPERIMENTAL && PPC_E500MC
	select KVM
	select KVM_MMIO
	select KVM_BOOKE_HV
	---help---
	  Support running unmodified E500MC/E5500 (32-bit) guest kernels in
	  virtual machines on E500MC/E5500 host processors.

	  This module provides access to the hardware capabilities through
	  a character device node named /dev/kvm.

	  If unsure, say N.

source drivers/vhost/Kconfig

endif # VIRTUALIZATION
Loading