Loading arch/arm/include/asm/kvm_arm.h +4 −1 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 */ Loading Loading @@ -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) Loading arch/arm/include/asm/kvm_mmu.h +14 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading @@ -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(); Loading arch/arm/include/asm/pgtable-3level.h +2 −0 Original line number Diff line number Diff line Loading @@ -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. */ Loading arch/arm/kvm/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -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 Loading arch/arm/kvm/handle_exit.c +13 −7 Original line number Diff line number Diff line Loading @@ -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 Loading
arch/arm/include/asm/kvm_arm.h +4 −1 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 */ Loading Loading @@ -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) Loading
arch/arm/include/asm/kvm_mmu.h +14 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading @@ -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(); Loading
arch/arm/include/asm/pgtable-3level.h +2 −0 Original line number Diff line number Diff line Loading @@ -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. */ Loading
arch/arm/kvm/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
arch/arm/kvm/handle_exit.c +13 −7 Original line number Diff line number Diff line Loading @@ -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