Commit f7adbba1e5d464b0d449adac1eb2519be6be9728

Authored by Alexander Graf
Committed by Marcelo Tosatti
1 parent 1c0006d8d1

KVM: PPC: Keep SRR1 flags around in shadow_msr

SRR1 stores more information that just the MSR value. It also stores
valuable information about the type of interrupt we received, for
example whether the storage interrupt we just got was because of a
missing htab entry or not.

We use that information to speed up the exit path.

Now if we get preempted before we can interpret the shadow_msr values,
we get into vcpu_put which then calls the MSR handler, which then sets
all the SRR1 information bits in shadow_msr to 0. Great.

So let's preserve the SRR1 specific bits in shadow_msr whenever we set
the MSR. They don't hurt.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Avi Kivity <avi@redhat.com>

Showing 4 changed files with 10 additions and 7 deletions Side-by-side Diff

arch/powerpc/include/asm/kvm_host.h
... ... @@ -198,6 +198,7 @@
198 198 ulong msr;
199 199 #ifdef CONFIG_PPC64
200 200 ulong shadow_msr;
  201 + ulong shadow_srr1;
201 202 ulong hflags;
202 203 ulong guest_owned_ext;
203 204 #endif
arch/powerpc/kernel/asm-offsets.c
... ... @@ -433,6 +433,7 @@
433 433 DEFINE(VCPU_HOST_R2, offsetof(struct kvm_vcpu, arch.host_r2));
434 434 DEFINE(VCPU_HOST_MSR, offsetof(struct kvm_vcpu, arch.host_msr));
435 435 DEFINE(VCPU_SHADOW_MSR, offsetof(struct kvm_vcpu, arch.shadow_msr));
  436 + DEFINE(VCPU_SHADOW_SRR1, offsetof(struct kvm_vcpu, arch.shadow_srr1));
436 437 DEFINE(VCPU_TRAMPOLINE_LOWMEM, offsetof(struct kvm_vcpu, arch.trampoline_lowmem));
437 438 DEFINE(VCPU_TRAMPOLINE_ENTER, offsetof(struct kvm_vcpu, arch.trampoline_enter));
438 439 DEFINE(VCPU_HIGHMEM_HANDLER, offsetof(struct kvm_vcpu, arch.highmem_handler));
arch/powerpc/kvm/book3s.c
... ... @@ -524,14 +524,14 @@
524 524 /* Page not found in guest PTE entries */
525 525 vcpu->arch.dear = vcpu->arch.fault_dear;
526 526 to_book3s(vcpu)->dsisr = vcpu->arch.fault_dsisr;
527   - vcpu->arch.msr |= (vcpu->arch.shadow_msr & 0x00000000f8000000ULL);
  527 + vcpu->arch.msr |= (vcpu->arch.shadow_srr1 & 0x00000000f8000000ULL);
528 528 kvmppc_book3s_queue_irqprio(vcpu, vec);
529 529 } else if (page_found == -EPERM) {
530 530 /* Storage protection */
531 531 vcpu->arch.dear = vcpu->arch.fault_dear;
532 532 to_book3s(vcpu)->dsisr = vcpu->arch.fault_dsisr & ~DSISR_NOHPTE;
533 533 to_book3s(vcpu)->dsisr |= DSISR_PROTFAULT;
534   - vcpu->arch.msr |= (vcpu->arch.shadow_msr & 0x00000000f8000000ULL);
  534 + vcpu->arch.msr |= (vcpu->arch.shadow_srr1 & 0x00000000f8000000ULL);
535 535 kvmppc_book3s_queue_irqprio(vcpu, vec);
536 536 } else if (page_found == -EINVAL) {
537 537 /* Page not found in guest SLB */
... ... @@ -693,7 +693,7 @@
693 693 case BOOK3S_INTERRUPT_INST_STORAGE:
694 694 vcpu->stat.pf_instruc++;
695 695 /* only care about PTEG not found errors, but leave NX alone */
696   - if (vcpu->arch.shadow_msr & 0x40000000) {
  696 + if (vcpu->arch.shadow_srr1 & 0x40000000) {
697 697 r = kvmppc_handle_pagefault(run, vcpu, vcpu->arch.pc, exit_nr);
698 698 vcpu->stat.sp_instruc++;
699 699 } else if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
... ... @@ -705,7 +705,7 @@
705 705 */
706 706 kvmppc_mmu_pte_flush(vcpu, vcpu->arch.pc, ~0xFFFULL);
707 707 } else {
708   - vcpu->arch.msr |= (vcpu->arch.shadow_msr & 0x58000000);
  708 + vcpu->arch.msr |= vcpu->arch.shadow_srr1 & 0x58000000;
709 709 kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
710 710 kvmppc_mmu_pte_flush(vcpu, vcpu->arch.pc, ~0xFFFULL);
711 711 r = RESUME_GUEST;
... ... @@ -753,7 +753,7 @@
753 753 enum emulation_result er;
754 754 ulong flags;
755 755  
756   - flags = (vcpu->arch.shadow_msr & 0x1f0000ull);
  756 + flags = vcpu->arch.shadow_srr1 & 0x1f0000ull;
757 757  
758 758 if (vcpu->arch.msr & MSR_PR) {
759 759 #ifdef EXIT_DEBUG
... ... @@ -808,7 +808,8 @@
808 808 break;
809 809 default:
810 810 /* Ugh - bork here! What did we get? */
811   - printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | msr=0x%lx\n", exit_nr, vcpu->arch.pc, vcpu->arch.shadow_msr);
  811 + printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | msr=0x%lx\n",
  812 + exit_nr, vcpu->arch.pc, vcpu->arch.shadow_srr1);
812 813 r = RESUME_HOST;
813 814 BUG();
814 815 break;
arch/powerpc/kvm/book3s_64_interrupts.S
... ... @@ -169,7 +169,7 @@
169 169 stw r0, VCPU_LAST_INST(r7)
170 170  
171 171 std r3, VCPU_PC(r7)
172   - std r4, VCPU_SHADOW_MSR(r7)
  172 + std r4, VCPU_SHADOW_SRR1(r7)
173 173 std r5, VCPU_FAULT_DEAR(r7)
174 174 std r6, VCPU_FAULT_DSISR(r7)
175 175