diff options
Diffstat (limited to 'drivers/kvm')
-rw-r--r-- | drivers/kvm/mmu.c | 48 | ||||
-rw-r--r-- | drivers/kvm/paging_tmpl.h | 56 |
2 files changed, 52 insertions, 52 deletions
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c index 46491b4cd859..a7631502f22b 100644 --- a/drivers/kvm/mmu.c +++ b/drivers/kvm/mmu.c | |||
@@ -965,54 +965,6 @@ static void paging_new_cr3(struct kvm_vcpu *vcpu) | |||
965 | kvm_arch_ops->set_cr3(vcpu, vcpu->mmu.root_hpa); | 965 | kvm_arch_ops->set_cr3(vcpu, vcpu->mmu.root_hpa); |
966 | } | 966 | } |
967 | 967 | ||
968 | static inline void set_pte_common(struct kvm_vcpu *vcpu, | ||
969 | u64 *shadow_pte, | ||
970 | gpa_t gaddr, | ||
971 | int dirty, | ||
972 | u64 access_bits, | ||
973 | gfn_t gfn) | ||
974 | { | ||
975 | hpa_t paddr; | ||
976 | |||
977 | *shadow_pte |= access_bits << PT_SHADOW_BITS_OFFSET; | ||
978 | if (!dirty) | ||
979 | access_bits &= ~PT_WRITABLE_MASK; | ||
980 | |||
981 | paddr = gpa_to_hpa(vcpu, gaddr & PT64_BASE_ADDR_MASK); | ||
982 | |||
983 | *shadow_pte |= access_bits; | ||
984 | |||
985 | if (is_error_hpa(paddr)) { | ||
986 | *shadow_pte |= gaddr; | ||
987 | *shadow_pte |= PT_SHADOW_IO_MARK; | ||
988 | *shadow_pte &= ~PT_PRESENT_MASK; | ||
989 | return; | ||
990 | } | ||
991 | |||
992 | *shadow_pte |= paddr; | ||
993 | |||
994 | if (access_bits & PT_WRITABLE_MASK) { | ||
995 | struct kvm_mmu_page *shadow; | ||
996 | |||
997 | shadow = kvm_mmu_lookup_page(vcpu, gfn); | ||
998 | if (shadow) { | ||
999 | pgprintk("%s: found shadow page for %lx, marking ro\n", | ||
1000 | __FUNCTION__, gfn); | ||
1001 | access_bits &= ~PT_WRITABLE_MASK; | ||
1002 | if (is_writeble_pte(*shadow_pte)) { | ||
1003 | *shadow_pte &= ~PT_WRITABLE_MASK; | ||
1004 | kvm_arch_ops->tlb_flush(vcpu); | ||
1005 | } | ||
1006 | } | ||
1007 | } | ||
1008 | |||
1009 | if (access_bits & PT_WRITABLE_MASK) | ||
1010 | mark_page_dirty(vcpu->kvm, gaddr >> PAGE_SHIFT); | ||
1011 | |||
1012 | page_header_update_slot(vcpu->kvm, shadow_pte, gaddr); | ||
1013 | rmap_add(vcpu, shadow_pte); | ||
1014 | } | ||
1015 | |||
1016 | static void inject_page_fault(struct kvm_vcpu *vcpu, | 968 | static void inject_page_fault(struct kvm_vcpu *vcpu, |
1017 | u64 addr, | 969 | u64 addr, |
1018 | u32 err_code) | 970 | u32 err_code) |
diff --git a/drivers/kvm/paging_tmpl.h b/drivers/kvm/paging_tmpl.h index e094a8ba17a8..65763007f04d 100644 --- a/drivers/kvm/paging_tmpl.h +++ b/drivers/kvm/paging_tmpl.h | |||
@@ -192,14 +192,62 @@ static void FNAME(mark_pagetable_dirty)(struct kvm *kvm, | |||
192 | mark_page_dirty(kvm, walker->table_gfn[walker->level - 1]); | 192 | mark_page_dirty(kvm, walker->table_gfn[walker->level - 1]); |
193 | } | 193 | } |
194 | 194 | ||
195 | static void FNAME(set_pte_common)(struct kvm_vcpu *vcpu, | ||
196 | u64 *shadow_pte, | ||
197 | gpa_t gaddr, | ||
198 | int dirty, | ||
199 | u64 access_bits, | ||
200 | gfn_t gfn) | ||
201 | { | ||
202 | hpa_t paddr; | ||
203 | |||
204 | *shadow_pte |= access_bits << PT_SHADOW_BITS_OFFSET; | ||
205 | if (!dirty) | ||
206 | access_bits &= ~PT_WRITABLE_MASK; | ||
207 | |||
208 | paddr = gpa_to_hpa(vcpu, gaddr & PT64_BASE_ADDR_MASK); | ||
209 | |||
210 | *shadow_pte |= access_bits; | ||
211 | |||
212 | if (is_error_hpa(paddr)) { | ||
213 | *shadow_pte |= gaddr; | ||
214 | *shadow_pte |= PT_SHADOW_IO_MARK; | ||
215 | *shadow_pte &= ~PT_PRESENT_MASK; | ||
216 | return; | ||
217 | } | ||
218 | |||
219 | *shadow_pte |= paddr; | ||
220 | |||
221 | if (access_bits & PT_WRITABLE_MASK) { | ||
222 | struct kvm_mmu_page *shadow; | ||
223 | |||
224 | shadow = kvm_mmu_lookup_page(vcpu, gfn); | ||
225 | if (shadow) { | ||
226 | pgprintk("%s: found shadow page for %lx, marking ro\n", | ||
227 | __FUNCTION__, gfn); | ||
228 | access_bits &= ~PT_WRITABLE_MASK; | ||
229 | if (is_writeble_pte(*shadow_pte)) { | ||
230 | *shadow_pte &= ~PT_WRITABLE_MASK; | ||
231 | kvm_arch_ops->tlb_flush(vcpu); | ||
232 | } | ||
233 | } | ||
234 | } | ||
235 | |||
236 | if (access_bits & PT_WRITABLE_MASK) | ||
237 | mark_page_dirty(vcpu->kvm, gaddr >> PAGE_SHIFT); | ||
238 | |||
239 | page_header_update_slot(vcpu->kvm, shadow_pte, gaddr); | ||
240 | rmap_add(vcpu, shadow_pte); | ||
241 | } | ||
242 | |||
195 | static void FNAME(set_pte)(struct kvm_vcpu *vcpu, u64 guest_pte, | 243 | static void FNAME(set_pte)(struct kvm_vcpu *vcpu, u64 guest_pte, |
196 | u64 *shadow_pte, u64 access_bits, gfn_t gfn) | 244 | u64 *shadow_pte, u64 access_bits, gfn_t gfn) |
197 | { | 245 | { |
198 | ASSERT(*shadow_pte == 0); | 246 | ASSERT(*shadow_pte == 0); |
199 | access_bits &= guest_pte; | 247 | access_bits &= guest_pte; |
200 | *shadow_pte = (guest_pte & PT_PTE_COPY_MASK); | 248 | *shadow_pte = (guest_pte & PT_PTE_COPY_MASK); |
201 | set_pte_common(vcpu, shadow_pte, guest_pte & PT_BASE_ADDR_MASK, | 249 | FNAME(set_pte_common)(vcpu, shadow_pte, guest_pte & PT_BASE_ADDR_MASK, |
202 | guest_pte & PT_DIRTY_MASK, access_bits, gfn); | 250 | guest_pte & PT_DIRTY_MASK, access_bits, gfn); |
203 | } | 251 | } |
204 | 252 | ||
205 | static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page, | 253 | static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page, |
@@ -229,8 +277,8 @@ static void FNAME(set_pde)(struct kvm_vcpu *vcpu, u64 guest_pde, | |||
229 | gaddr |= (guest_pde & PT32_DIR_PSE36_MASK) << | 277 | gaddr |= (guest_pde & PT32_DIR_PSE36_MASK) << |
230 | (32 - PT32_DIR_PSE36_SHIFT); | 278 | (32 - PT32_DIR_PSE36_SHIFT); |
231 | *shadow_pte = guest_pde & PT_PTE_COPY_MASK; | 279 | *shadow_pte = guest_pde & PT_PTE_COPY_MASK; |
232 | set_pte_common(vcpu, shadow_pte, gaddr, | 280 | FNAME(set_pte_common)(vcpu, shadow_pte, gaddr, |
233 | guest_pde & PT_DIRTY_MASK, access_bits, gfn); | 281 | guest_pde & PT_DIRTY_MASK, access_bits, gfn); |
234 | } | 282 | } |
235 | 283 | ||
236 | /* | 284 | /* |