]>
Commit | Line | Data |
---|---|---|
342cd0ab CD |
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 | ||
c62ee2b2 MZ |
22 | #include <asm/cacheflush.h> |
23 | #include <asm/pgalloc.h> | |
24 | ||
342cd0ab CD |
25 | int create_hyp_mappings(void *from, void *to); |
26 | int create_hyp_io_mappings(void *from, void *to, phys_addr_t); | |
27 | void free_hyp_pmds(void); | |
28 | ||
d5d8184d CD |
29 | int kvm_alloc_stage2_pgd(struct kvm *kvm); |
30 | void kvm_free_stage2_pgd(struct kvm *kvm); | |
31 | int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, | |
32 | phys_addr_t pa, unsigned long size); | |
33 | ||
34 | int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run); | |
35 | ||
36 | void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu); | |
37 | ||
342cd0ab CD |
38 | phys_addr_t kvm_mmu_get_httbr(void); |
39 | int kvm_mmu_init(void); | |
40 | void kvm_clear_hyp_idmap(void); | |
94f8e641 | 41 | |
c62ee2b2 MZ |
42 | static inline void kvm_set_pte(pte_t *pte, pte_t new_pte) |
43 | { | |
44 | pte_val(*pte) = new_pte; | |
45 | /* | |
46 | * flush_pmd_entry just takes a void pointer and cleans the necessary | |
47 | * cache entries, so we can reuse the function for ptes. | |
48 | */ | |
49 | flush_pmd_entry(pte); | |
50 | } | |
51 | ||
94f8e641 CD |
52 | static inline bool kvm_is_write_fault(unsigned long hsr) |
53 | { | |
54 | unsigned long hsr_ec = hsr >> HSR_EC_SHIFT; | |
55 | if (hsr_ec == HSR_EC_IABT) | |
56 | return false; | |
57 | else if ((hsr & HSR_ISV) && !(hsr & HSR_WNR)) | |
58 | return false; | |
59 | else | |
60 | return true; | |
61 | } | |
62 | ||
c62ee2b2 MZ |
63 | static inline void kvm_clean_pgd(pgd_t *pgd) |
64 | { | |
65 | clean_dcache_area(pgd, PTRS_PER_S2_PGD * sizeof(pgd_t)); | |
66 | } | |
67 | ||
68 | static inline void kvm_clean_pmd_entry(pmd_t *pmd) | |
69 | { | |
70 | clean_pmd_entry(pmd); | |
71 | } | |
72 | ||
73 | static inline void kvm_clean_pte(pte_t *pte) | |
74 | { | |
75 | clean_pte_table(pte); | |
76 | } | |
77 | ||
78 | static inline void kvm_set_s2pte_writable(pte_t *pte) | |
79 | { | |
80 | pte_val(*pte) |= L_PTE_S2_RDWR; | |
81 | } | |
82 | ||
83 | struct kvm; | |
84 | ||
85 | static inline void coherent_icache_guest_page(struct kvm *kvm, gfn_t gfn) | |
86 | { | |
87 | /* | |
88 | * If we are going to insert an instruction page and the icache is | |
89 | * either VIPT or PIPT, there is a potential problem where the host | |
90 | * (or another VM) may have used the same page as this guest, and we | |
91 | * read incorrect data from the icache. If we're using a PIPT cache, | |
92 | * we can invalidate just that page, but if we are using a VIPT cache | |
93 | * we need to invalidate the entire icache - damn shame - as written | |
94 | * in the ARM ARM (DDI 0406C.b - Page B3-1393). | |
95 | * | |
96 | * VIVT caches are tagged using both the ASID and the VMID and doesn't | |
97 | * need any kind of flushing (DDI 0406C.b - Page B3-1392). | |
98 | */ | |
99 | if (icache_is_pipt()) { | |
100 | unsigned long hva = gfn_to_hva(kvm, gfn); | |
101 | __cpuc_coherent_user_range(hva, hva + PAGE_SIZE); | |
102 | } else if (!icache_is_vivt_asid_tagged()) { | |
103 | /* any kind of VIPT cache */ | |
104 | __flush_icache_all(); | |
105 | } | |
106 | } | |
107 | ||
342cd0ab | 108 | #endif /* __ARM_KVM_MMU_H__ */ |