[PATCH] KVM: MMU: Fold fetch_guest() into init_walker()
[cascardo/linux.git] / drivers / kvm / paging_tmpl.h
1 /*
2  * Kernel-based Virtual Machine driver for Linux
3  *
4  * This module enables machines with Intel VT-x extensions to run virtual
5  * machines without emulation or binary translation.
6  *
7  * MMU support
8  *
9  * Copyright (C) 2006 Qumranet, Inc.
10  *
11  * Authors:
12  *   Yaniv Kamay  <yaniv@qumranet.com>
13  *   Avi Kivity   <avi@qumranet.com>
14  *
15  * This work is licensed under the terms of the GNU GPL, version 2.  See
16  * the COPYING file in the top-level directory.
17  *
18  */
19
20 /*
21  * We need the mmu code to access both 32-bit and 64-bit guest ptes,
22  * so the code in this file is compiled twice, once per pte size.
23  */
24
25 #if PTTYPE == 64
26         #define pt_element_t u64
27         #define guest_walker guest_walker64
28         #define FNAME(name) paging##64_##name
29         #define PT_BASE_ADDR_MASK PT64_BASE_ADDR_MASK
30         #define PT_DIR_BASE_ADDR_MASK PT64_DIR_BASE_ADDR_MASK
31         #define PT_INDEX(addr, level) PT64_INDEX(addr, level)
32         #define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
33         #define PT_LEVEL_MASK(level) PT64_LEVEL_MASK(level)
34         #define PT_PTE_COPY_MASK PT64_PTE_COPY_MASK
35 #elif PTTYPE == 32
36         #define pt_element_t u32
37         #define guest_walker guest_walker32
38         #define FNAME(name) paging##32_##name
39         #define PT_BASE_ADDR_MASK PT32_BASE_ADDR_MASK
40         #define PT_DIR_BASE_ADDR_MASK PT32_DIR_BASE_ADDR_MASK
41         #define PT_INDEX(addr, level) PT32_INDEX(addr, level)
42         #define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
43         #define PT_LEVEL_MASK(level) PT32_LEVEL_MASK(level)
44         #define PT_PTE_COPY_MASK PT32_PTE_COPY_MASK
45 #else
46         #error Invalid PTTYPE value
47 #endif
48
49 /*
50  * The guest_walker structure emulates the behavior of the hardware page
51  * table walker.
52  */
53 struct guest_walker {
54         int level;
55         gfn_t table_gfn;
56         pt_element_t *table;
57         pt_element_t *ptep;
58         pt_element_t inherited_ar;
59 };
60
61 /*
62  * Fetch a guest pte for a guest virtual address
63  */
64 static void FNAME(walk_addr)(struct guest_walker *walker,
65                              struct kvm_vcpu *vcpu, gva_t addr)
66 {
67         hpa_t hpa;
68         struct kvm_memory_slot *slot;
69         pt_element_t *ptep;
70
71         walker->level = vcpu->mmu.root_level;
72         walker->table_gfn = (vcpu->cr3 & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT;
73         slot = gfn_to_memslot(vcpu->kvm, walker->table_gfn);
74         hpa = safe_gpa_to_hpa(vcpu, vcpu->cr3 & PT64_BASE_ADDR_MASK);
75         walker->table = kmap_atomic(pfn_to_page(hpa >> PAGE_SHIFT), KM_USER0);
76
77         ASSERT((!is_long_mode(vcpu) && is_pae(vcpu)) ||
78                (vcpu->cr3 & ~(PAGE_MASK | CR3_FLAGS_MASK)) == 0);
79
80         walker->table = (pt_element_t *)( (unsigned long)walker->table |
81                 (unsigned long)(vcpu->cr3 & ~(PAGE_MASK | CR3_FLAGS_MASK)) );
82         walker->inherited_ar = PT_USER_MASK | PT_WRITABLE_MASK;
83
84         for (;;) {
85                 int index = PT_INDEX(addr, walker->level);
86                 hpa_t paddr;
87
88                 ptep = &walker->table[index];
89                 ASSERT(((unsigned long)walker->table & PAGE_MASK) ==
90                        ((unsigned long)ptep & PAGE_MASK));
91
92                 /* Don't set accessed bit on PAE PDPTRs */
93                 if (vcpu->mmu.root_level != 3 || walker->level != 3)
94                         if ((*ptep & (PT_PRESENT_MASK | PT_ACCESSED_MASK))
95                             == PT_PRESENT_MASK)
96                                 *ptep |= PT_ACCESSED_MASK;
97
98                 if (!is_present_pte(*ptep) ||
99                     walker->level == PT_PAGE_TABLE_LEVEL ||
100                     (walker->level == PT_DIRECTORY_LEVEL &&
101                      (*ptep & PT_PAGE_SIZE_MASK) &&
102                      (PTTYPE == 64 || is_pse(vcpu))))
103                         break;
104
105                 if (walker->level != 3 || is_long_mode(vcpu))
106                         walker->inherited_ar &= walker->table[index];
107                 walker->table_gfn = (*ptep & PT_BASE_ADDR_MASK) >> PAGE_SHIFT;
108                 paddr = safe_gpa_to_hpa(vcpu, *ptep & PT_BASE_ADDR_MASK);
109                 kunmap_atomic(walker->table, KM_USER0);
110                 walker->table = kmap_atomic(pfn_to_page(paddr >> PAGE_SHIFT),
111                                             KM_USER0);
112                 --walker->level;
113         }
114         walker->ptep = ptep;
115 }
116
117 static void FNAME(release_walker)(struct guest_walker *walker)
118 {
119         kunmap_atomic(walker->table, KM_USER0);
120 }
121
122 static void FNAME(set_pte)(struct kvm_vcpu *vcpu, u64 guest_pte,
123                            u64 *shadow_pte, u64 access_bits)
124 {
125         ASSERT(*shadow_pte == 0);
126         access_bits &= guest_pte;
127         *shadow_pte = (guest_pte & PT_PTE_COPY_MASK);
128         set_pte_common(vcpu, shadow_pte, guest_pte & PT_BASE_ADDR_MASK,
129                        guest_pte & PT_DIRTY_MASK, access_bits);
130 }
131
132 static void FNAME(set_pde)(struct kvm_vcpu *vcpu, u64 guest_pde,
133                            u64 *shadow_pte, u64 access_bits,
134                            int index)
135 {
136         gpa_t gaddr;
137
138         ASSERT(*shadow_pte == 0);
139         access_bits &= guest_pde;
140         gaddr = (guest_pde & PT_DIR_BASE_ADDR_MASK) + PAGE_SIZE * index;
141         if (PTTYPE == 32 && is_cpuid_PSE36())
142                 gaddr |= (guest_pde & PT32_DIR_PSE36_MASK) <<
143                         (32 - PT32_DIR_PSE36_SHIFT);
144         *shadow_pte = guest_pde & PT_PTE_COPY_MASK;
145         set_pte_common(vcpu, shadow_pte, gaddr,
146                        guest_pde & PT_DIRTY_MASK, access_bits);
147 }
148
149 /*
150  * Fetch a shadow pte for a specific level in the paging hierarchy.
151  */
152 static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
153                               struct guest_walker *walker)
154 {
155         hpa_t shadow_addr;
156         int level;
157         u64 *prev_shadow_ent = NULL;
158         pt_element_t *guest_ent = walker->ptep;
159
160         if (!is_present_pte(*guest_ent))
161                 return NULL;
162
163         shadow_addr = vcpu->mmu.root_hpa;
164         level = vcpu->mmu.shadow_root_level;
165
166         for (; ; level--) {
167                 u32 index = SHADOW_PT_INDEX(addr, level);
168                 u64 *shadow_ent = ((u64 *)__va(shadow_addr)) + index;
169                 u64 shadow_pte;
170
171                 if (is_present_pte(*shadow_ent) || is_io_pte(*shadow_ent)) {
172                         if (level == PT_PAGE_TABLE_LEVEL)
173                                 return shadow_ent;
174                         shadow_addr = *shadow_ent & PT64_BASE_ADDR_MASK;
175                         prev_shadow_ent = shadow_ent;
176                         continue;
177                 }
178
179                 if (level == PT_PAGE_TABLE_LEVEL) {
180
181                         if (walker->level == PT_DIRECTORY_LEVEL) {
182                                 if (prev_shadow_ent)
183                                         *prev_shadow_ent |= PT_SHADOW_PS_MARK;
184                                 FNAME(set_pde)(vcpu, *guest_ent, shadow_ent,
185                                                walker->inherited_ar,
186                                           PT_INDEX(addr, PT_PAGE_TABLE_LEVEL));
187                         } else {
188                                 ASSERT(walker->level == PT_PAGE_TABLE_LEVEL);
189                                 FNAME(set_pte)(vcpu, *guest_ent, shadow_ent, walker->inherited_ar);
190                         }
191                         return shadow_ent;
192                 }
193
194                 shadow_addr = kvm_mmu_alloc_page(vcpu, shadow_ent);
195                 if (!VALID_PAGE(shadow_addr))
196                         return ERR_PTR(-ENOMEM);
197                 shadow_pte = shadow_addr | PT_PRESENT_MASK;
198                 if (vcpu->mmu.root_level > 3 || level != 3)
199                         shadow_pte |= PT_ACCESSED_MASK
200                                 | PT_WRITABLE_MASK | PT_USER_MASK;
201                 *shadow_ent = shadow_pte;
202                 prev_shadow_ent = shadow_ent;
203         }
204 }
205
206 /*
207  * The guest faulted for write.  We need to
208  *
209  * - check write permissions
210  * - update the guest pte dirty bit
211  * - update our own dirty page tracking structures
212  */
213 static int FNAME(fix_write_pf)(struct kvm_vcpu *vcpu,
214                                u64 *shadow_ent,
215                                struct guest_walker *walker,
216                                gva_t addr,
217                                int user)
218 {
219         pt_element_t *guest_ent;
220         int writable_shadow;
221         gfn_t gfn;
222
223         if (is_writeble_pte(*shadow_ent))
224                 return 0;
225
226         writable_shadow = *shadow_ent & PT_SHADOW_WRITABLE_MASK;
227         if (user) {
228                 /*
229                  * User mode access.  Fail if it's a kernel page or a read-only
230                  * page.
231                  */
232                 if (!(*shadow_ent & PT_SHADOW_USER_MASK) || !writable_shadow)
233                         return 0;
234                 ASSERT(*shadow_ent & PT_USER_MASK);
235         } else
236                 /*
237                  * Kernel mode access.  Fail if it's a read-only page and
238                  * supervisor write protection is enabled.
239                  */
240                 if (!writable_shadow) {
241                         if (is_write_protection(vcpu))
242                                 return 0;
243                         *shadow_ent &= ~PT_USER_MASK;
244                 }
245
246         guest_ent = walker->ptep;
247
248         if (!is_present_pte(*guest_ent)) {
249                 *shadow_ent = 0;
250                 return 0;
251         }
252
253         gfn = (*guest_ent & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT;
254         mark_page_dirty(vcpu->kvm, gfn);
255         *shadow_ent |= PT_WRITABLE_MASK;
256         *guest_ent |= PT_DIRTY_MASK;
257         rmap_add(vcpu->kvm, shadow_ent);
258
259         return 1;
260 }
261
262 /*
263  * Page fault handler.  There are several causes for a page fault:
264  *   - there is no shadow pte for the guest pte
265  *   - write access through a shadow pte marked read only so that we can set
266  *     the dirty bit
267  *   - write access to a shadow pte marked read only so we can update the page
268  *     dirty bitmap, when userspace requests it
269  *   - mmio access; in this case we will never install a present shadow pte
270  *   - normal guest page fault due to the guest pte marked not present, not
271  *     writable, or not executable
272  *
273  *  Returns: 1 if we need to emulate the instruction, 0 otherwise
274  */
275 static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
276                                u32 error_code)
277 {
278         int write_fault = error_code & PFERR_WRITE_MASK;
279         int pte_present = error_code & PFERR_PRESENT_MASK;
280         int user_fault = error_code & PFERR_USER_MASK;
281         struct guest_walker walker;
282         u64 *shadow_pte;
283         int fixed;
284
285         /*
286          * Look up the shadow pte for the faulting address.
287          */
288         for (;;) {
289                 FNAME(walk_addr)(&walker, vcpu, addr);
290                 shadow_pte = FNAME(fetch)(vcpu, addr, &walker);
291                 if (IS_ERR(shadow_pte)) {  /* must be -ENOMEM */
292                         nonpaging_flush(vcpu);
293                         FNAME(release_walker)(&walker);
294                         continue;
295                 }
296                 break;
297         }
298
299         /*
300          * The page is not mapped by the guest.  Let the guest handle it.
301          */
302         if (!shadow_pte) {
303                 inject_page_fault(vcpu, addr, error_code);
304                 FNAME(release_walker)(&walker);
305                 return 0;
306         }
307
308         /*
309          * Update the shadow pte.
310          */
311         if (write_fault)
312                 fixed = FNAME(fix_write_pf)(vcpu, shadow_pte, &walker, addr,
313                                             user_fault);
314         else
315                 fixed = fix_read_pf(shadow_pte);
316
317         FNAME(release_walker)(&walker);
318
319         /*
320          * mmio: emulate if accessible, otherwise its a guest fault.
321          */
322         if (is_io_pte(*shadow_pte)) {
323                 if (may_access(*shadow_pte, write_fault, user_fault))
324                         return 1;
325                 pgprintk("%s: io work, no access\n", __FUNCTION__);
326                 inject_page_fault(vcpu, addr,
327                                   error_code | PFERR_PRESENT_MASK);
328                 return 0;
329         }
330
331         /*
332          * pte not present, guest page fault.
333          */
334         if (pte_present && !fixed) {
335                 inject_page_fault(vcpu, addr, error_code);
336                 return 0;
337         }
338
339         ++kvm_stat.pf_fixed;
340
341         return 0;
342 }
343
344 static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr)
345 {
346         struct guest_walker walker;
347         pt_element_t guest_pte;
348         gpa_t gpa;
349
350         FNAME(walk_addr)(&walker, vcpu, vaddr);
351         guest_pte = *walker.ptep;
352         FNAME(release_walker)(&walker);
353
354         if (!is_present_pte(guest_pte))
355                 return UNMAPPED_GVA;
356
357         if (walker.level == PT_DIRECTORY_LEVEL) {
358                 ASSERT((guest_pte & PT_PAGE_SIZE_MASK));
359                 ASSERT(PTTYPE == 64 || is_pse(vcpu));
360
361                 gpa = (guest_pte & PT_DIR_BASE_ADDR_MASK) | (vaddr &
362                         (PT_LEVEL_MASK(PT_PAGE_TABLE_LEVEL) | ~PAGE_MASK));
363
364                 if (PTTYPE == 32 && is_cpuid_PSE36())
365                         gpa |= (guest_pte & PT32_DIR_PSE36_MASK) <<
366                                         (32 - PT32_DIR_PSE36_SHIFT);
367         } else {
368                 gpa = (guest_pte & PT_BASE_ADDR_MASK);
369                 gpa |= (vaddr & ~PAGE_MASK);
370         }
371
372         return gpa;
373 }
374
375 #undef pt_element_t
376 #undef guest_walker
377 #undef FNAME
378 #undef PT_BASE_ADDR_MASK
379 #undef PT_INDEX
380 #undef SHADOW_PT_INDEX
381 #undef PT_LEVEL_MASK
382 #undef PT_PTE_COPY_MASK
383 #undef PT_NON_PTE_COPY_MASK
384 #undef PT_DIR_BASE_ADDR_MASK