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

Commit 5bb3398d authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvm-arm-for-3.13-2' of git://git.linaro.org/people/cdall/linux-kvm-arm into kvm-queue

Updates for KVM/ARM, take 2 including:
 - Transparent Huge Pages and hugetlbfs support for KVM/ARM
 - Yield CPU when guest executes WFE to speed up CPU overcommit
parents e0230e13 9b5fdb97
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@
 * TSC:		Trap SMC
 * TSW:		Trap cache operations by set/way
 * TWI:		Trap WFI
 * TWE:		Trap WFE
 * TIDCP:	Trap L2CTLR/L2ECTLR
 * BSU_IS:	Upgrade barriers to the inner shareable domain
 * FB:		Force broadcast of all maintainance operations
@@ -67,7 +68,7 @@
 */
#define HCR_GUEST_MASK (HCR_TSC | HCR_TSW | HCR_TWI | HCR_VM | HCR_BSU_IS | \
			HCR_FB | HCR_TAC | HCR_AMO | HCR_IMO | HCR_FMO | \
			HCR_SWIO | HCR_TIDCP)
			HCR_TWE | HCR_SWIO | HCR_TIDCP)
#define HCR_VIRT_EXCP_MASK (HCR_VA | HCR_VI | HCR_VF)

/* System Control Register (SCTLR) bits */
@@ -208,6 +209,8 @@
#define HSR_EC_DABT	(0x24)
#define HSR_EC_DABT_HYP	(0x25)

#define HSR_WFI_IS_WFE		(1U << 0)

#define HSR_HVC_IMM_MASK	((1UL << 16) - 1)

#define HSR_DABT_S1PTW		(1U << 7)
+14 −3
Original line number Diff line number Diff line
@@ -62,6 +62,12 @@ phys_addr_t kvm_get_idmap_vector(void);
int kvm_mmu_init(void);
void kvm_clear_hyp_idmap(void);

static inline void kvm_set_pmd(pmd_t *pmd, pmd_t new_pmd)
{
	*pmd = new_pmd;
	flush_pmd_entry(pmd);
}

static inline void kvm_set_pte(pte_t *pte, pte_t new_pte)
{
	*pte = new_pte;
@@ -103,9 +109,15 @@ static inline void kvm_set_s2pte_writable(pte_t *pte)
	pte_val(*pte) |= L_PTE_S2_RDWR;
}

static inline void kvm_set_s2pmd_writable(pmd_t *pmd)
{
	pmd_val(*pmd) |= L_PMD_S2_RDWR;
}

struct kvm;

static inline void coherent_icache_guest_page(struct kvm *kvm, gfn_t gfn)
static inline void coherent_icache_guest_page(struct kvm *kvm, hva_t hva,
					      unsigned long size)
{
	/*
	 * If we are going to insert an instruction page and the icache is
@@ -120,8 +132,7 @@ static inline void coherent_icache_guest_page(struct kvm *kvm, gfn_t gfn)
	 * need any kind of flushing (DDI 0406C.b - Page B3-1392).
	 */
	if (icache_is_pipt()) {
		unsigned long hva = gfn_to_hva(kvm, gfn);
		__cpuc_coherent_user_range(hva, hva + PAGE_SIZE);
		__cpuc_coherent_user_range(hva, hva + size);
	} else if (!icache_is_vivt_asid_tagged()) {
		/* any kind of VIPT cache */
		__flush_icache_all();
+2 −0
Original line number Diff line number Diff line
@@ -126,6 +126,8 @@
#define L_PTE_S2_RDONLY		 (_AT(pteval_t, 1) << 6)   /* HAP[1]   */
#define L_PTE_S2_RDWR		 (_AT(pteval_t, 3) << 6)   /* HAP[2:1] */

#define L_PMD_S2_RDWR		 (_AT(pmdval_t, 3) << 6)   /* HAP[2:1] */

/*
 * Hyp-mode PL2 PTE definitions for LPAE.
 */
+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ config KVM
	bool "Kernel-based Virtual Machine (KVM) support"
	select PREEMPT_NOTIFIERS
	select ANON_INODES
	select HAVE_KVM_CPU_RELAX_INTERCEPT
	select KVM_MMIO
	select KVM_ARM_HOST
	depends on ARM_VIRT_EXT && ARM_LPAE
+13 −7
Original line number Diff line number Diff line
@@ -73,23 +73,29 @@ static int handle_dabt_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run)
}

/**
 * kvm_handle_wfi - handle a wait-for-interrupts instruction executed by a guest
 * kvm_handle_wfx - handle a WFI or WFE instructions trapped in guests
 * @vcpu:	the vcpu pointer
 * @run:	the kvm_run structure pointer
 *
 * Simply sets the wait_for_interrupts flag on the vcpu structure, which will
 * halt execution of world-switches and schedule other host processes until
 * there is an incoming IRQ or FIQ to the VM.
 * WFE: Yield the CPU and come back to this vcpu when the scheduler
 * decides to.
 * WFI: Simply call kvm_vcpu_block(), which will halt execution of
 * world-switches and schedule other host processes until there is an
 * incoming IRQ or FIQ to the VM.
 */
static int kvm_handle_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run)
static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
	trace_kvm_wfi(*vcpu_pc(vcpu));
	if (kvm_vcpu_get_hsr(vcpu) & HSR_WFI_IS_WFE)
		kvm_vcpu_on_spin(vcpu);
	else
		kvm_vcpu_block(vcpu);

	return 1;
}

static exit_handle_fn arm_exit_handlers[] = {
	[HSR_EC_WFI]		= kvm_handle_wfi,
	[HSR_EC_WFI]		= kvm_handle_wfx,
	[HSR_EC_CP15_32]	= kvm_handle_cp15_32,
	[HSR_EC_CP15_64]	= kvm_handle_cp15_64,
	[HSR_EC_CP14_MR]	= kvm_handle_cp14_access,
Loading