aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIzik Eidus <izike@qumranet.com>2007-11-19 04:28:19 -0500
committerAvi Kivity <avi@qumranet.com>2008-01-30 10:53:06 -0500
commitec8d4eaefc06636eb8fc83610c6605168796b4f7 (patch)
treec0d1accbe8ef30852789b69d4a749ca973ee5e73
parent15b00f32d53f31fe194b17ca0384a37756b55be2 (diff)
KVM: MMU: Change guest pte access to kvm_{read,write}_guest()
Things are simpler and more regular this way. Signed-off-by: Izik Eidus <izike@qumranet.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r--drivers/kvm/paging_tmpl.h24
1 files changed, 5 insertions, 19 deletions
diff --git a/drivers/kvm/paging_tmpl.h b/drivers/kvm/paging_tmpl.h
index 0f0266af3f68..be6640178f6b 100644
--- a/drivers/kvm/paging_tmpl.h
+++ b/drivers/kvm/paging_tmpl.h
@@ -72,7 +72,6 @@ static int FNAME(walk_addr)(struct guest_walker *walker,
72 struct kvm_vcpu *vcpu, gva_t addr, 72 struct kvm_vcpu *vcpu, gva_t addr,
73 int write_fault, int user_fault, int fetch_fault) 73 int write_fault, int user_fault, int fetch_fault)
74{ 74{
75 struct page *page = NULL;
76 pt_element_t *table; 75 pt_element_t *table;
77 pt_element_t pte; 76 pt_element_t pte;
78 gfn_t table_gfn; 77 gfn_t table_gfn;
@@ -99,16 +98,13 @@ static int FNAME(walk_addr)(struct guest_walker *walker,
99 index = PT_INDEX(addr, walker->level); 98 index = PT_INDEX(addr, walker->level);
100 99
101 table_gfn = (pte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT; 100 table_gfn = (pte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT;
101 pte_gpa = table_gfn << PAGE_SHIFT;
102 pte_gpa += index * sizeof(pt_element_t);
102 walker->table_gfn[walker->level - 1] = table_gfn; 103 walker->table_gfn[walker->level - 1] = table_gfn;
103 pgprintk("%s: table_gfn[%d] %lx\n", __FUNCTION__, 104 pgprintk("%s: table_gfn[%d] %lx\n", __FUNCTION__,
104 walker->level - 1, table_gfn); 105 walker->level - 1, table_gfn);
105 106
106 page = gfn_to_page(vcpu->kvm, (pte & PT64_BASE_ADDR_MASK) 107 kvm_read_guest(vcpu->kvm, pte_gpa, &pte, sizeof(pte));
107 >> PAGE_SHIFT);
108
109 table = kmap_atomic(page, KM_USER0);
110 pte = table[index];
111 kunmap_atomic(table, KM_USER0);
112 108
113 if (!is_present_pte(pte)) 109 if (!is_present_pte(pte))
114 goto not_present; 110 goto not_present;
@@ -128,9 +124,7 @@ static int FNAME(walk_addr)(struct guest_walker *walker,
128 if (!(pte & PT_ACCESSED_MASK)) { 124 if (!(pte & PT_ACCESSED_MASK)) {
129 mark_page_dirty(vcpu->kvm, table_gfn); 125 mark_page_dirty(vcpu->kvm, table_gfn);
130 pte |= PT_ACCESSED_MASK; 126 pte |= PT_ACCESSED_MASK;
131 table = kmap_atomic(page, KM_USER0); 127 kvm_write_guest(vcpu->kvm, pte_gpa, &pte, sizeof(pte));
132 table[index] = pte;
133 kunmap_atomic(table, KM_USER0);
134 } 128 }
135 129
136 if (walker->level == PT_PAGE_TABLE_LEVEL) { 130 if (walker->level == PT_PAGE_TABLE_LEVEL) {
@@ -149,21 +143,15 @@ static int FNAME(walk_addr)(struct guest_walker *walker,
149 143
150 walker->inherited_ar &= pte; 144 walker->inherited_ar &= pte;
151 --walker->level; 145 --walker->level;
152 kvm_release_page(page);
153 } 146 }
154 147
155 if (write_fault && !is_dirty_pte(pte)) { 148 if (write_fault && !is_dirty_pte(pte)) {
156 mark_page_dirty(vcpu->kvm, table_gfn); 149 mark_page_dirty(vcpu->kvm, table_gfn);
157 pte |= PT_DIRTY_MASK; 150 pte |= PT_DIRTY_MASK;
158 table = kmap_atomic(page, KM_USER0); 151 kvm_write_guest(vcpu->kvm, pte_gpa, &pte, sizeof(pte));
159 table[index] = pte;
160 kunmap_atomic(table, KM_USER0);
161 pte_gpa = table_gfn << PAGE_SHIFT;
162 pte_gpa += index * sizeof(pt_element_t);
163 kvm_mmu_pte_write(vcpu, pte_gpa, (u8 *)&pte, sizeof(pte)); 152 kvm_mmu_pte_write(vcpu, pte_gpa, (u8 *)&pte, sizeof(pte));
164 } 153 }
165 154
166 kvm_release_page(page);
167 walker->pte = pte; 155 walker->pte = pte;
168 pgprintk("%s: pte %llx\n", __FUNCTION__, (u64)pte); 156 pgprintk("%s: pte %llx\n", __FUNCTION__, (u64)pte);
169 return 1; 157 return 1;
@@ -182,8 +170,6 @@ err:
182 walker->error_code |= PFERR_USER_MASK; 170 walker->error_code |= PFERR_USER_MASK;
183 if (fetch_fault) 171 if (fetch_fault)
184 walker->error_code |= PFERR_FETCH_MASK; 172 walker->error_code |= PFERR_FETCH_MASK;
185 if (page)
186 kvm_release_page(page);
187 return 0; 173 return 0;
188} 174}
189 175