diff options
Diffstat (limited to 'arch/powerpc/kvm/booke_interrupts.S')
-rw-r--r-- | arch/powerpc/kvm/booke_interrupts.S | 79 |
1 files changed, 47 insertions, 32 deletions
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S index 3b653b5309b8..95e165baf85f 100644 --- a/arch/powerpc/kvm/booke_interrupts.S +++ b/arch/powerpc/kvm/booke_interrupts.S | |||
@@ -42,7 +42,8 @@ | |||
42 | #define HOST_STACK_LR (HOST_STACK_SIZE + 4) /* In caller stack frame. */ | 42 | #define HOST_STACK_LR (HOST_STACK_SIZE + 4) /* In caller stack frame. */ |
43 | 43 | ||
44 | #define NEED_INST_MASK ((1<<BOOKE_INTERRUPT_PROGRAM) | \ | 44 | #define NEED_INST_MASK ((1<<BOOKE_INTERRUPT_PROGRAM) | \ |
45 | (1<<BOOKE_INTERRUPT_DTLB_MISS)) | 45 | (1<<BOOKE_INTERRUPT_DTLB_MISS) | \ |
46 | (1<<BOOKE_INTERRUPT_DEBUG)) | ||
46 | 47 | ||
47 | #define NEED_DEAR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \ | 48 | #define NEED_DEAR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \ |
48 | (1<<BOOKE_INTERRUPT_DTLB_MISS)) | 49 | (1<<BOOKE_INTERRUPT_DTLB_MISS)) |
@@ -331,51 +332,57 @@ lightweight_exit: | |||
331 | 332 | ||
332 | mfspr r3, SPRN_PID | 333 | mfspr r3, SPRN_PID |
333 | stw r3, VCPU_HOST_PID(r4) | 334 | stw r3, VCPU_HOST_PID(r4) |
334 | lwz r3, VCPU_PID(r4) | 335 | lwz r3, VCPU_SHADOW_PID(r4) |
335 | mtspr SPRN_PID, r3 | 336 | mtspr SPRN_PID, r3 |
336 | 337 | ||
337 | /* Prevent all TLB updates. */ | 338 | /* Prevent all asynchronous TLB updates. */ |
338 | mfmsr r5 | 339 | mfmsr r5 |
339 | lis r6, (MSR_EE|MSR_CE|MSR_ME|MSR_DE)@h | 340 | lis r6, (MSR_EE|MSR_CE|MSR_ME|MSR_DE)@h |
340 | ori r6, r6, (MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l | 341 | ori r6, r6, (MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l |
341 | andc r6, r5, r6 | 342 | andc r6, r5, r6 |
342 | mtmsr r6 | 343 | mtmsr r6 |
343 | 344 | ||
344 | /* Save the host's non-pinned TLB mappings, and load the guest mappings | 345 | /* Load the guest mappings, leaving the host's "pinned" kernel mappings |
345 | * over them. Leave the host's "pinned" kernel mappings in place. */ | 346 | * in place. */ |
346 | /* XXX optimization: use generation count to avoid swapping unmodified | ||
347 | * entries. */ | ||
348 | mfspr r10, SPRN_MMUCR /* Save host MMUCR. */ | 347 | mfspr r10, SPRN_MMUCR /* Save host MMUCR. */ |
349 | lis r8, tlb_44x_hwater@ha | 348 | li r5, PPC44x_TLB_SIZE |
350 | lwz r8, tlb_44x_hwater@l(r8) | 349 | lis r5, tlb_44x_hwater@ha |
351 | addi r3, r4, VCPU_HOST_TLB - 4 | 350 | lwz r5, tlb_44x_hwater@l(r5) |
352 | addi r9, r4, VCPU_SHADOW_TLB - 4 | 351 | mtctr r5 |
353 | li r6, 0 | 352 | addi r9, r4, VCPU_SHADOW_TLB |
353 | addi r5, r4, VCPU_SHADOW_MOD | ||
354 | li r3, 0 | ||
354 | 1: | 355 | 1: |
355 | /* Save host entry. */ | 356 | lbzx r7, r3, r5 |
356 | tlbre r7, r6, PPC44x_TLB_PAGEID | 357 | cmpwi r7, 0 |
357 | mfspr r5, SPRN_MMUCR | 358 | beq 3f |
358 | stwu r5, 4(r3) | 359 | |
359 | stwu r7, 4(r3) | ||
360 | tlbre r7, r6, PPC44x_TLB_XLAT | ||
361 | stwu r7, 4(r3) | ||
362 | tlbre r7, r6, PPC44x_TLB_ATTRIB | ||
363 | stwu r7, 4(r3) | ||
364 | /* Load guest entry. */ | 360 | /* Load guest entry. */ |
365 | lwzu r7, 4(r9) | 361 | mulli r11, r3, TLBE_BYTES |
362 | add r11, r11, r9 | ||
363 | lwz r7, 0(r11) | ||
366 | mtspr SPRN_MMUCR, r7 | 364 | mtspr SPRN_MMUCR, r7 |
367 | lwzu r7, 4(r9) | 365 | lwz r7, 4(r11) |
368 | tlbwe r7, r6, PPC44x_TLB_PAGEID | 366 | tlbwe r7, r3, PPC44x_TLB_PAGEID |
369 | lwzu r7, 4(r9) | 367 | lwz r7, 8(r11) |
370 | tlbwe r7, r6, PPC44x_TLB_XLAT | 368 | tlbwe r7, r3, PPC44x_TLB_XLAT |
371 | lwzu r7, 4(r9) | 369 | lwz r7, 12(r11) |
372 | tlbwe r7, r6, PPC44x_TLB_ATTRIB | 370 | tlbwe r7, r3, PPC44x_TLB_ATTRIB |
373 | /* Increment index. */ | 371 | 3: |
374 | addi r6, r6, 1 | 372 | addi r3, r3, 1 /* Increment index. */ |
375 | cmpw r6, r8 | 373 | bdnz 1b |
376 | blt 1b | 374 | |
377 | mtspr SPRN_MMUCR, r10 /* Restore host MMUCR. */ | 375 | mtspr SPRN_MMUCR, r10 /* Restore host MMUCR. */ |
378 | 376 | ||
377 | /* Clear bitmap of modified TLB entries */ | ||
378 | li r5, PPC44x_TLB_SIZE>>2 | ||
379 | mtctr r5 | ||
380 | addi r5, r4, VCPU_SHADOW_MOD - 4 | ||
381 | li r6, 0 | ||
382 | 1: | ||
383 | stwu r6, 4(r5) | ||
384 | bdnz 1b | ||
385 | |||
379 | iccci 0, 0 /* XXX hack */ | 386 | iccci 0, 0 /* XXX hack */ |
380 | 387 | ||
381 | /* Load some guest volatiles. */ | 388 | /* Load some guest volatiles. */ |
@@ -431,6 +438,14 @@ lightweight_exit: | |||
431 | oris r3, r3, KVMPPC_MSR_MASK@h | 438 | oris r3, r3, KVMPPC_MSR_MASK@h |
432 | ori r3, r3, KVMPPC_MSR_MASK@l | 439 | ori r3, r3, KVMPPC_MSR_MASK@l |
433 | mtsrr1 r3 | 440 | mtsrr1 r3 |
441 | |||
442 | /* Clear any debug events which occurred since we disabled MSR[DE]. | ||
443 | * XXX This gives us a 3-instruction window in which a breakpoint | ||
444 | * intended for guest context could fire in the host instead. */ | ||
445 | lis r3, 0xffff | ||
446 | ori r3, r3, 0xffff | ||
447 | mtspr SPRN_DBSR, r3 | ||
448 | |||
434 | lwz r3, VCPU_GPR(r3)(r4) | 449 | lwz r3, VCPU_GPR(r3)(r4) |
435 | lwz r4, VCPU_GPR(r4)(r4) | 450 | lwz r4, VCPU_GPR(r4)(r4) |
436 | rfi | 451 | rfi |