aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/booke.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kvm/booke.c')
-rw-r--r--arch/powerpc/kvm/booke.c61
1 files changed, 47 insertions, 14 deletions
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index b1e90a15155a..138014acf3cf 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -134,6 +134,40 @@ void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu)
134 } 134 }
135} 135}
136 136
137static void kvmppc_booke_queue_exception(struct kvm_vcpu *vcpu, int exception)
138{
139 unsigned int priority = exception_priority[exception];
140 set_bit(priority, &vcpu->arch.pending_exceptions);
141}
142
143static void kvmppc_booke_clear_exception(struct kvm_vcpu *vcpu, int exception)
144{
145 unsigned int priority = exception_priority[exception];
146 clear_bit(priority, &vcpu->arch.pending_exceptions);
147}
148
149void kvmppc_core_queue_program(struct kvm_vcpu *vcpu)
150{
151 kvmppc_booke_queue_exception(vcpu, BOOKE_INTERRUPT_PROGRAM);
152}
153
154void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu)
155{
156 kvmppc_booke_queue_exception(vcpu, BOOKE_INTERRUPT_DECREMENTER);
157}
158
159int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu)
160{
161 unsigned int priority = exception_priority[BOOKE_INTERRUPT_DECREMENTER];
162 return test_bit(priority, &vcpu->arch.pending_exceptions);
163}
164
165void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
166 struct kvm_interrupt *irq)
167{
168 kvmppc_booke_queue_exception(vcpu, BOOKE_INTERRUPT_EXTERNAL);
169}
170
137/* Check if we are ready to deliver the interrupt */ 171/* Check if we are ready to deliver the interrupt */
138static int kvmppc_can_deliver_interrupt(struct kvm_vcpu *vcpu, int interrupt) 172static int kvmppc_can_deliver_interrupt(struct kvm_vcpu *vcpu, int interrupt)
139{ 173{
@@ -168,7 +202,7 @@ static int kvmppc_can_deliver_interrupt(struct kvm_vcpu *vcpu, int interrupt)
168 return r; 202 return r;
169} 203}
170 204
171static void kvmppc_deliver_interrupt(struct kvm_vcpu *vcpu, int interrupt) 205static void kvmppc_booke_deliver_interrupt(struct kvm_vcpu *vcpu, int interrupt)
172{ 206{
173 switch (interrupt) { 207 switch (interrupt) {
174 case BOOKE_INTERRUPT_DECREMENTER: 208 case BOOKE_INTERRUPT_DECREMENTER:
@@ -183,7 +217,7 @@ static void kvmppc_deliver_interrupt(struct kvm_vcpu *vcpu, int interrupt)
183} 217}
184 218
185/* Check pending exceptions and deliver one, if possible. */ 219/* Check pending exceptions and deliver one, if possible. */
186void kvmppc_check_and_deliver_interrupts(struct kvm_vcpu *vcpu) 220void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
187{ 221{
188 unsigned long *pending = &vcpu->arch.pending_exceptions; 222 unsigned long *pending = &vcpu->arch.pending_exceptions;
189 unsigned int exception; 223 unsigned int exception;
@@ -193,8 +227,8 @@ void kvmppc_check_and_deliver_interrupts(struct kvm_vcpu *vcpu)
193 while (priority <= BOOKE_MAX_INTERRUPT) { 227 while (priority <= BOOKE_MAX_INTERRUPT) {
194 exception = priority_exception[priority]; 228 exception = priority_exception[priority];
195 if (kvmppc_can_deliver_interrupt(vcpu, exception)) { 229 if (kvmppc_can_deliver_interrupt(vcpu, exception)) {
196 kvmppc_clear_exception(vcpu, exception); 230 kvmppc_booke_clear_exception(vcpu, exception);
197 kvmppc_deliver_interrupt(vcpu, exception); 231 kvmppc_booke_deliver_interrupt(vcpu, exception);
198 break; 232 break;
199 } 233 }
200 234
@@ -251,7 +285,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
251 /* Program traps generated by user-level software must be handled 285 /* Program traps generated by user-level software must be handled
252 * by the guest kernel. */ 286 * by the guest kernel. */
253 vcpu->arch.esr = vcpu->arch.fault_esr; 287 vcpu->arch.esr = vcpu->arch.fault_esr;
254 kvmppc_queue_exception(vcpu, BOOKE_INTERRUPT_PROGRAM); 288 kvmppc_booke_queue_exception(vcpu, BOOKE_INTERRUPT_PROGRAM);
255 r = RESUME_GUEST; 289 r = RESUME_GUEST;
256 break; 290 break;
257 } 291 }
@@ -284,27 +318,27 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
284 break; 318 break;
285 319
286 case BOOKE_INTERRUPT_FP_UNAVAIL: 320 case BOOKE_INTERRUPT_FP_UNAVAIL:
287 kvmppc_queue_exception(vcpu, exit_nr); 321 kvmppc_booke_queue_exception(vcpu, exit_nr);
288 r = RESUME_GUEST; 322 r = RESUME_GUEST;
289 break; 323 break;
290 324
291 case BOOKE_INTERRUPT_DATA_STORAGE: 325 case BOOKE_INTERRUPT_DATA_STORAGE:
292 vcpu->arch.dear = vcpu->arch.fault_dear; 326 vcpu->arch.dear = vcpu->arch.fault_dear;
293 vcpu->arch.esr = vcpu->arch.fault_esr; 327 vcpu->arch.esr = vcpu->arch.fault_esr;
294 kvmppc_queue_exception(vcpu, exit_nr); 328 kvmppc_booke_queue_exception(vcpu, exit_nr);
295 vcpu->stat.dsi_exits++; 329 vcpu->stat.dsi_exits++;
296 r = RESUME_GUEST; 330 r = RESUME_GUEST;
297 break; 331 break;
298 332
299 case BOOKE_INTERRUPT_INST_STORAGE: 333 case BOOKE_INTERRUPT_INST_STORAGE:
300 vcpu->arch.esr = vcpu->arch.fault_esr; 334 vcpu->arch.esr = vcpu->arch.fault_esr;
301 kvmppc_queue_exception(vcpu, exit_nr); 335 kvmppc_booke_queue_exception(vcpu, exit_nr);
302 vcpu->stat.isi_exits++; 336 vcpu->stat.isi_exits++;
303 r = RESUME_GUEST; 337 r = RESUME_GUEST;
304 break; 338 break;
305 339
306 case BOOKE_INTERRUPT_SYSCALL: 340 case BOOKE_INTERRUPT_SYSCALL:
307 kvmppc_queue_exception(vcpu, exit_nr); 341 kvmppc_booke_queue_exception(vcpu, exit_nr);
308 vcpu->stat.syscall_exits++; 342 vcpu->stat.syscall_exits++;
309 r = RESUME_GUEST; 343 r = RESUME_GUEST;
310 break; 344 break;
@@ -318,7 +352,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
318 gtlbe = kvmppc_44x_dtlb_search(vcpu, eaddr); 352 gtlbe = kvmppc_44x_dtlb_search(vcpu, eaddr);
319 if (!gtlbe) { 353 if (!gtlbe) {
320 /* The guest didn't have a mapping for it. */ 354 /* The guest didn't have a mapping for it. */
321 kvmppc_queue_exception(vcpu, exit_nr); 355 kvmppc_booke_queue_exception(vcpu, exit_nr);
322 vcpu->arch.dear = vcpu->arch.fault_dear; 356 vcpu->arch.dear = vcpu->arch.fault_dear;
323 vcpu->arch.esr = vcpu->arch.fault_esr; 357 vcpu->arch.esr = vcpu->arch.fault_esr;
324 vcpu->stat.dtlb_real_miss_exits++; 358 vcpu->stat.dtlb_real_miss_exits++;
@@ -360,7 +394,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
360 gtlbe = kvmppc_44x_itlb_search(vcpu, eaddr); 394 gtlbe = kvmppc_44x_itlb_search(vcpu, eaddr);
361 if (!gtlbe) { 395 if (!gtlbe) {
362 /* The guest didn't have a mapping for it. */ 396 /* The guest didn't have a mapping for it. */
363 kvmppc_queue_exception(vcpu, exit_nr); 397 kvmppc_booke_queue_exception(vcpu, exit_nr);
364 vcpu->stat.itlb_real_miss_exits++; 398 vcpu->stat.itlb_real_miss_exits++;
365 break; 399 break;
366 } 400 }
@@ -380,8 +414,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
380 gtlbe->word2); 414 gtlbe->word2);
381 } else { 415 } else {
382 /* Guest mapped and leaped at non-RAM! */ 416 /* Guest mapped and leaped at non-RAM! */
383 kvmppc_queue_exception(vcpu, 417 kvmppc_booke_queue_exception(vcpu, BOOKE_INTERRUPT_MACHINE_CHECK);
384 BOOKE_INTERRUPT_MACHINE_CHECK);
385 } 418 }
386 419
387 break; 420 break;
@@ -409,7 +442,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
409 442
410 local_irq_disable(); 443 local_irq_disable();
411 444
412 kvmppc_check_and_deliver_interrupts(vcpu); 445 kvmppc_core_deliver_interrupts(vcpu);
413 446
414 /* Do some exit accounting. */ 447 /* Do some exit accounting. */
415 vcpu->stat.sum_exits++; 448 vcpu->stat.sum_exits++;