diff options
Diffstat (limited to 'arch/powerpc/kvm')
-rw-r--r-- | arch/powerpc/kvm/44x_tlb.c | 9 | ||||
-rw-r--r-- | arch/powerpc/kvm/booke_guest.c | 33 | ||||
-rw-r--r-- | arch/powerpc/kvm/emulate.c | 12 |
3 files changed, 16 insertions, 38 deletions
diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c index f5d7a5eab96e..75dff7cfa814 100644 --- a/arch/powerpc/kvm/44x_tlb.c +++ b/arch/powerpc/kvm/44x_tlb.c | |||
@@ -116,8 +116,6 @@ static void kvmppc_44x_shadow_release(struct kvm_vcpu *vcpu, | |||
116 | struct tlbe *stlbe = &vcpu->arch.shadow_tlb[index]; | 116 | struct tlbe *stlbe = &vcpu->arch.shadow_tlb[index]; |
117 | struct page *page = vcpu->arch.shadow_pages[index]; | 117 | struct page *page = vcpu->arch.shadow_pages[index]; |
118 | 118 | ||
119 | kunmap(vcpu->arch.shadow_pages[index]); | ||
120 | |||
121 | if (get_tlb_v(stlbe)) { | 119 | if (get_tlb_v(stlbe)) { |
122 | if (kvmppc_44x_tlbe_is_writable(stlbe)) | 120 | if (kvmppc_44x_tlbe_is_writable(stlbe)) |
123 | kvm_release_page_dirty(page); | 121 | kvm_release_page_dirty(page); |
@@ -144,18 +142,19 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, u64 asid, | |||
144 | stlbe = &vcpu->arch.shadow_tlb[victim]; | 142 | stlbe = &vcpu->arch.shadow_tlb[victim]; |
145 | 143 | ||
146 | /* Get reference to new page. */ | 144 | /* Get reference to new page. */ |
147 | down_write(¤t->mm->mmap_sem); | 145 | down_read(¤t->mm->mmap_sem); |
148 | new_page = gfn_to_page(vcpu->kvm, gfn); | 146 | new_page = gfn_to_page(vcpu->kvm, gfn); |
149 | if (is_error_page(new_page)) { | 147 | if (is_error_page(new_page)) { |
150 | printk(KERN_ERR "Couldn't get guest page!\n"); | 148 | printk(KERN_ERR "Couldn't get guest page for gfn %lx!\n", gfn); |
151 | kvm_release_page_clean(new_page); | 149 | kvm_release_page_clean(new_page); |
150 | up_read(¤t->mm->mmap_sem); | ||
152 | return; | 151 | return; |
153 | } | 152 | } |
154 | hpaddr = page_to_phys(new_page); | 153 | hpaddr = page_to_phys(new_page); |
155 | 154 | ||
156 | /* Drop reference to old page. */ | 155 | /* Drop reference to old page. */ |
157 | kvmppc_44x_shadow_release(vcpu, victim); | 156 | kvmppc_44x_shadow_release(vcpu, victim); |
158 | up_write(¤t->mm->mmap_sem); | 157 | up_read(¤t->mm->mmap_sem); |
159 | 158 | ||
160 | vcpu->arch.shadow_pages[victim] = new_page; | 159 | vcpu->arch.shadow_pages[victim] = new_page; |
161 | 160 | ||
diff --git a/arch/powerpc/kvm/booke_guest.c b/arch/powerpc/kvm/booke_guest.c index 712d89a28c46..9c8ad850c6e3 100644 --- a/arch/powerpc/kvm/booke_guest.c +++ b/arch/powerpc/kvm/booke_guest.c | |||
@@ -227,39 +227,6 @@ void kvmppc_check_and_deliver_interrupts(struct kvm_vcpu *vcpu) | |||
227 | } | 227 | } |
228 | } | 228 | } |
229 | 229 | ||
230 | static int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu) | ||
231 | { | ||
232 | enum emulation_result er; | ||
233 | int r; | ||
234 | |||
235 | er = kvmppc_emulate_instruction(run, vcpu); | ||
236 | switch (er) { | ||
237 | case EMULATE_DONE: | ||
238 | /* Future optimization: only reload non-volatiles if they were | ||
239 | * actually modified. */ | ||
240 | r = RESUME_GUEST_NV; | ||
241 | break; | ||
242 | case EMULATE_DO_MMIO: | ||
243 | run->exit_reason = KVM_EXIT_MMIO; | ||
244 | /* We must reload nonvolatiles because "update" load/store | ||
245 | * instructions modify register state. */ | ||
246 | /* Future optimization: only reload non-volatiles if they were | ||
247 | * actually modified. */ | ||
248 | r = RESUME_HOST_NV; | ||
249 | break; | ||
250 | case EMULATE_FAIL: | ||
251 | /* XXX Deliver Program interrupt to guest. */ | ||
252 | printk(KERN_EMERG "%s: emulation failed (%08x)\n", __func__, | ||
253 | vcpu->arch.last_inst); | ||
254 | r = RESUME_HOST; | ||
255 | break; | ||
256 | default: | ||
257 | BUG(); | ||
258 | } | ||
259 | |||
260 | return r; | ||
261 | } | ||
262 | |||
263 | /** | 230 | /** |
264 | * kvmppc_handle_exit | 231 | * kvmppc_handle_exit |
265 | * | 232 | * |
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index a03fe0c80698..000097461283 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c | |||
@@ -246,6 +246,11 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
246 | case 31: | 246 | case 31: |
247 | switch (get_xop(inst)) { | 247 | switch (get_xop(inst)) { |
248 | 248 | ||
249 | case 23: /* lwzx */ | ||
250 | rt = get_rt(inst); | ||
251 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); | ||
252 | break; | ||
253 | |||
249 | case 83: /* mfmsr */ | 254 | case 83: /* mfmsr */ |
250 | rt = get_rt(inst); | 255 | rt = get_rt(inst); |
251 | vcpu->arch.gpr[rt] = vcpu->arch.msr; | 256 | vcpu->arch.gpr[rt] = vcpu->arch.msr; |
@@ -267,6 +272,13 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
267 | kvmppc_set_msr(vcpu, vcpu->arch.gpr[rs]); | 272 | kvmppc_set_msr(vcpu, vcpu->arch.gpr[rs]); |
268 | break; | 273 | break; |
269 | 274 | ||
275 | case 151: /* stwx */ | ||
276 | rs = get_rs(inst); | ||
277 | emulated = kvmppc_handle_store(run, vcpu, | ||
278 | vcpu->arch.gpr[rs], | ||
279 | 4, 1); | ||
280 | break; | ||
281 | |||
270 | case 163: /* wrteei */ | 282 | case 163: /* wrteei */ |
271 | vcpu->arch.msr = (vcpu->arch.msr & ~MSR_EE) | 283 | vcpu->arch.msr = (vcpu->arch.msr & ~MSR_EE) |
272 | | (inst & MSR_EE); | 284 | | (inst & MSR_EE); |