Commit f7adbba1e5d464b0d449adac1eb2519be6be9728
Committed by
Marcelo Tosatti
1 parent
1c0006d8d1
Exists in
master
and in
7 other branches
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
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