KVM: PPC: Convert DAR to shared page.
authorAlexander Graf <agraf@suse.de>
Thu, 29 Jul 2010 12:47:45 +0000 (14:47 +0200)
committerAvi Kivity <avi@redhat.com>
Sun, 24 Oct 2010 08:50:45 +0000 (10:50 +0200)
The DAR register contains the address a data page fault occured at. This
register behaves pretty much like a simple data storage register that gets
written to on data faults. There is no hypervisor interaction required on
read or write.

This patch converts all users of the current field to the shared page.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Avi Kivity <avi@redhat.com>
arch/powerpc/include/asm/kvm_host.h
arch/powerpc/include/asm/kvm_para.h
arch/powerpc/kvm/book3s.c
arch/powerpc/kvm/book3s_emulate.c
arch/powerpc/kvm/book3s_paired_singles.c
arch/powerpc/kvm/booke.c
arch/powerpc/kvm/booke_emulate.c

index ba20f90655f38b2a8214df6dd6b626a5286e698c..c852408eac3819c129ceda12651c305f10fc2339 100644 (file)
@@ -231,7 +231,6 @@ struct kvm_vcpu_arch {
        ulong csrr1;
        ulong dsrr0;
        ulong dsrr1;
-       ulong dear;
        ulong esr;
        u32 dec;
        u32 decar;
index 9f7565b1de6568cc134864c71d9ca8bdb679c729..ec72a1c8c045373b040e86af5c7f80fab99621b8 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/types.h>
 
 struct kvm_vcpu_arch_shared {
+       __u64 dar;
        __u64 msr;
        __u32 dsisr;
 };
index eb401b6d4d8c7aa1505e250c19a2a710ce51db13..4d46f8b13cc62dadf114ca170ee50d14e4728113 100644 (file)
@@ -594,14 +594,14 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu,
 
        if (page_found == -ENOENT) {
                /* Page not found in guest PTE entries */
-               vcpu->arch.dear = kvmppc_get_fault_dar(vcpu);
+               vcpu->arch.shared->dar = kvmppc_get_fault_dar(vcpu);
                vcpu->arch.shared->dsisr = to_svcpu(vcpu)->fault_dsisr;
                vcpu->arch.shared->msr |=
                        (to_svcpu(vcpu)->shadow_srr1 & 0x00000000f8000000ULL);
                kvmppc_book3s_queue_irqprio(vcpu, vec);
        } else if (page_found == -EPERM) {
                /* Storage protection */
-               vcpu->arch.dear = kvmppc_get_fault_dar(vcpu);
+               vcpu->arch.shared->dar = kvmppc_get_fault_dar(vcpu);
                vcpu->arch.shared->dsisr =
                        to_svcpu(vcpu)->fault_dsisr & ~DSISR_NOHPTE;
                vcpu->arch.shared->dsisr |= DSISR_PROTFAULT;
@@ -610,7 +610,7 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu,
                kvmppc_book3s_queue_irqprio(vcpu, vec);
        } else if (page_found == -EINVAL) {
                /* Page not found in guest SLB */
-               vcpu->arch.dear = kvmppc_get_fault_dar(vcpu);
+               vcpu->arch.shared->dar = kvmppc_get_fault_dar(vcpu);
                kvmppc_book3s_queue_irqprio(vcpu, vec + 0x80);
        } else if (!is_mmio &&
                   kvmppc_visible_gfn(vcpu, pte.raddr >> PAGE_SHIFT)) {
@@ -867,17 +867,17 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
                if (to_svcpu(vcpu)->fault_dsisr & DSISR_NOHPTE) {
                        r = kvmppc_handle_pagefault(run, vcpu, dar, exit_nr);
                } else {
-                       vcpu->arch.dear = dar;
+                       vcpu->arch.shared->dar = dar;
                        vcpu->arch.shared->dsisr = to_svcpu(vcpu)->fault_dsisr;
                        kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
-                       kvmppc_mmu_pte_flush(vcpu, vcpu->arch.dear, ~0xFFFUL);
+                       kvmppc_mmu_pte_flush(vcpu, dar, ~0xFFFUL);
                        r = RESUME_GUEST;
                }
                break;
        }
        case BOOK3S_INTERRUPT_DATA_SEGMENT:
                if (kvmppc_mmu_map_segment(vcpu, kvmppc_get_fault_dar(vcpu)) < 0) {
-                       vcpu->arch.dear = kvmppc_get_fault_dar(vcpu);
+                       vcpu->arch.shared->dar = kvmppc_get_fault_dar(vcpu);
                        kvmppc_book3s_queue_irqprio(vcpu,
                                BOOK3S_INTERRUPT_DATA_SEGMENT);
                }
@@ -997,7 +997,7 @@ program_interrupt:
                if (kvmppc_read_inst(vcpu) == EMULATE_DONE) {
                        vcpu->arch.shared->dsisr = kvmppc_alignment_dsisr(vcpu,
                                kvmppc_get_last_inst(vcpu));
-                       vcpu->arch.dear = kvmppc_alignment_dar(vcpu,
+                       vcpu->arch.shared->dar = kvmppc_alignment_dar(vcpu,
                                kvmppc_get_last_inst(vcpu));
                        kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
                }
index 9982ff163af084aec7ca7d891ddcef098936c02f..c1478642f856f4b2e0e2d6c32b0200863cc3cc4a 100644 (file)
@@ -212,7 +212,7 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
                        r = kvmppc_st(vcpu, &addr, 32, zeros, true);
                        if ((r == -ENOENT) || (r == -EPERM)) {
                                *advance = 0;
-                               vcpu->arch.dear = vaddr;
+                               vcpu->arch.shared->dar = vaddr;
                                to_svcpu(vcpu)->fault_dar = vaddr;
 
                                dsisr = DSISR_ISSTORE;
@@ -330,7 +330,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
                vcpu->arch.shared->dsisr = spr_val;
                break;
        case SPRN_DAR:
-               vcpu->arch.dear = spr_val;
+               vcpu->arch.shared->dar = spr_val;
                break;
        case SPRN_HIOR:
                to_book3s(vcpu)->hior = spr_val;
@@ -443,7 +443,7 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
                kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->dsisr);
                break;
        case SPRN_DAR:
-               kvmppc_set_gpr(vcpu, rt, vcpu->arch.dear);
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->dar);
                break;
        case SPRN_HIOR:
                kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hior);
index 749dfbd047386fcd0360c6678d8dc0cb9793c860..807576f148ce8401eafdfce9737976a07103a7b3 100644 (file)
@@ -169,7 +169,7 @@ static void kvmppc_inject_pf(struct kvm_vcpu *vcpu, ulong eaddr, bool is_store)
 
        shared->msr = kvmppc_set_field(shared->msr, 33, 36, 0);
        shared->msr = kvmppc_set_field(shared->msr, 42, 47, 0);
-       vcpu->arch.dear = eaddr;
+       shared->dar = eaddr;
        /* Page Fault */
        dsisr = kvmppc_set_field(0, 33, 33, 1);
        if (is_store)
index 4ec9d49a1cb945d7fbf959bdf94ede5f33e11aae..4aab6d2ce133fef325c90774674da0c6e644548b 100644 (file)
@@ -195,7 +195,7 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
                if (update_esr == true)
                        vcpu->arch.esr = vcpu->arch.queued_esr;
                if (update_dear == true)
-                       vcpu->arch.dear = vcpu->arch.queued_dear;
+                       vcpu->arch.shared->dar = vcpu->arch.queued_dear;
                kvmppc_set_msr(vcpu, vcpu->arch.shared->msr & msr_mask);
 
                clear_bit(priority, &vcpu->arch.pending_exceptions);
index b115203ac1185fefc67de79417798b9b383a7100..51ef4539ed51fc4082b6c8886cb71c381aa394a4 100644 (file)
@@ -105,7 +105,7 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
 
        switch (sprn) {
        case SPRN_DEAR:
-               vcpu->arch.dear = spr_val; break;
+               vcpu->arch.shared->dar = spr_val; break;
        case SPRN_ESR:
                vcpu->arch.esr = spr_val; break;
        case SPRN_DBCR0:
@@ -200,7 +200,7 @@ int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
        case SPRN_IVPR:
                kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivpr); break;
        case SPRN_DEAR:
-               kvmppc_set_gpr(vcpu, rt, vcpu->arch.dear); break;
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->dar); break;
        case SPRN_ESR:
                kvmppc_set_gpr(vcpu, rt, vcpu->arch.esr); break;
        case SPRN_DBCR0: