Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.13-rc6 146 lines 4.2 kB view raw
1/* 2 * Copyright (C) 2012 - Virtual Open Systems and Columbia University 3 * Author: Christoffer Dall <c.dall@virtualopensystems.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License, version 2, as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 */ 18 19#ifndef __ARM_KVM_MMU_H__ 20#define __ARM_KVM_MMU_H__ 21 22#include <asm/memory.h> 23#include <asm/page.h> 24 25/* 26 * We directly use the kernel VA for the HYP, as we can directly share 27 * the mapping (HTTBR "covers" TTBR1). 28 */ 29#define HYP_PAGE_OFFSET_MASK UL(~0) 30#define HYP_PAGE_OFFSET PAGE_OFFSET 31#define KERN_TO_HYP(kva) (kva) 32 33/* 34 * Our virtual mapping for the boot-time MMU-enable code. Must be 35 * shared across all the page-tables. Conveniently, we use the vectors 36 * page, where no kernel data will ever be shared with HYP. 37 */ 38#define TRAMPOLINE_VA UL(CONFIG_VECTORS_BASE) 39 40#ifndef __ASSEMBLY__ 41 42#include <asm/cacheflush.h> 43#include <asm/pgalloc.h> 44 45int create_hyp_mappings(void *from, void *to); 46int create_hyp_io_mappings(void *from, void *to, phys_addr_t); 47void free_boot_hyp_pgd(void); 48void free_hyp_pgds(void); 49 50int kvm_alloc_stage2_pgd(struct kvm *kvm); 51void kvm_free_stage2_pgd(struct kvm *kvm); 52int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, 53 phys_addr_t pa, unsigned long size); 54 55int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run); 56 57void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu); 58 59phys_addr_t kvm_mmu_get_httbr(void); 60phys_addr_t kvm_mmu_get_boot_httbr(void); 61phys_addr_t kvm_get_idmap_vector(void); 62int kvm_mmu_init(void); 63void kvm_clear_hyp_idmap(void); 64 65static inline void kvm_set_pmd(pmd_t *pmd, pmd_t new_pmd) 66{ 67 *pmd = new_pmd; 68 flush_pmd_entry(pmd); 69} 70 71static inline void kvm_set_pte(pte_t *pte, pte_t new_pte) 72{ 73 *pte = new_pte; 74 /* 75 * flush_pmd_entry just takes a void pointer and cleans the necessary 76 * cache entries, so we can reuse the function for ptes. 77 */ 78 flush_pmd_entry(pte); 79} 80 81static inline bool kvm_is_write_fault(unsigned long hsr) 82{ 83 unsigned long hsr_ec = hsr >> HSR_EC_SHIFT; 84 if (hsr_ec == HSR_EC_IABT) 85 return false; 86 else if ((hsr & HSR_ISV) && !(hsr & HSR_WNR)) 87 return false; 88 else 89 return true; 90} 91 92static inline void kvm_clean_pgd(pgd_t *pgd) 93{ 94 clean_dcache_area(pgd, PTRS_PER_S2_PGD * sizeof(pgd_t)); 95} 96 97static inline void kvm_clean_pmd_entry(pmd_t *pmd) 98{ 99 clean_pmd_entry(pmd); 100} 101 102static inline void kvm_clean_pte(pte_t *pte) 103{ 104 clean_pte_table(pte); 105} 106 107static inline void kvm_set_s2pte_writable(pte_t *pte) 108{ 109 pte_val(*pte) |= L_PTE_S2_RDWR; 110} 111 112static inline void kvm_set_s2pmd_writable(pmd_t *pmd) 113{ 114 pmd_val(*pmd) |= L_PMD_S2_RDWR; 115} 116 117struct kvm; 118 119static inline void coherent_icache_guest_page(struct kvm *kvm, hva_t hva, 120 unsigned long size) 121{ 122 /* 123 * If we are going to insert an instruction page and the icache is 124 * either VIPT or PIPT, there is a potential problem where the host 125 * (or another VM) may have used the same page as this guest, and we 126 * read incorrect data from the icache. If we're using a PIPT cache, 127 * we can invalidate just that page, but if we are using a VIPT cache 128 * we need to invalidate the entire icache - damn shame - as written 129 * in the ARM ARM (DDI 0406C.b - Page B3-1393). 130 * 131 * VIVT caches are tagged using both the ASID and the VMID and doesn't 132 * need any kind of flushing (DDI 0406C.b - Page B3-1392). 133 */ 134 if (icache_is_pipt()) { 135 __cpuc_coherent_user_range(hva, hva + size); 136 } else if (!icache_is_vivt_asid_tagged()) { 137 /* any kind of VIPT cache */ 138 __flush_icache_all(); 139 } 140} 141 142#define kvm_flush_dcache_to_poc(a,l) __cpuc_flush_dcache_area((a), (l)) 143 144#endif /* !__ASSEMBLY__ */ 145 146#endif /* __ARM_KVM_MMU_H__ */