diff options
author | Izik Eidus <izike@qumranet.com> | 2007-11-19 04:28:19 -0500 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-01-30 10:53:06 -0500 |
commit | ec8d4eaefc06636eb8fc83610c6605168796b4f7 (patch) | |
tree | c0d1accbe8ef30852789b69d4a749ca973ee5e73 | |
parent | 15b00f32d53f31fe194b17ca0384a37756b55be2 (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.h | 24 |
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 | ||