aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/booke.c
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2013-01-04 12:12:48 -0500
committerAlexander Graf <agraf@suse.de>2013-01-10 07:42:31 -0500
commit1c810636556c8d53a37406b34a64d9b9b0161aa6 (patch)
treeb163d427c9dcff066330d4ac13de529a9831a044 /arch/powerpc/kvm/booke.c
parent37ecb257f68ce4fb7c7048a1123bbcbbe36d9575 (diff)
KVM: PPC: BookE: Implement EPR exit
The External Proxy Facility in FSL BookE chips allows the interrupt controller to automatically acknowledge an interrupt as soon as a core gets its pending external interrupt delivered. Today, user space implements the interrupt controller, so we need to check on it during such a cycle. This patch implements logic for user space to enable EPR exiting, disable EPR exiting and EPR exiting itself, so that user space can acknowledge an interrupt when an external interrupt has successfully been delivered into the guest vcpu. Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc/kvm/booke.c')
-rw-r--r--arch/powerpc/kvm/booke.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 964f4475f55c..940ec806187e 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -306,7 +306,7 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
306{ 306{
307 int allowed = 0; 307 int allowed = 0;
308 ulong msr_mask = 0; 308 ulong msr_mask = 0;
309 bool update_esr = false, update_dear = false; 309 bool update_esr = false, update_dear = false, update_epr = false;
310 ulong crit_raw = vcpu->arch.shared->critical; 310 ulong crit_raw = vcpu->arch.shared->critical;
311 ulong crit_r1 = kvmppc_get_gpr(vcpu, 1); 311 ulong crit_r1 = kvmppc_get_gpr(vcpu, 1);
312 bool crit; 312 bool crit;
@@ -330,6 +330,9 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
330 keep_irq = true; 330 keep_irq = true;
331 } 331 }
332 332
333 if ((priority == BOOKE_IRQPRIO_EXTERNAL) && vcpu->arch.epr_enabled)
334 update_epr = true;
335
333 switch (priority) { 336 switch (priority) {
334 case BOOKE_IRQPRIO_DTLB_MISS: 337 case BOOKE_IRQPRIO_DTLB_MISS:
335 case BOOKE_IRQPRIO_DATA_STORAGE: 338 case BOOKE_IRQPRIO_DATA_STORAGE:
@@ -408,6 +411,8 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
408 set_guest_esr(vcpu, vcpu->arch.queued_esr); 411 set_guest_esr(vcpu, vcpu->arch.queued_esr);
409 if (update_dear == true) 412 if (update_dear == true)
410 set_guest_dear(vcpu, vcpu->arch.queued_dear); 413 set_guest_dear(vcpu, vcpu->arch.queued_dear);
414 if (update_epr == true)
415 kvm_make_request(KVM_REQ_EPR_EXIT, vcpu);
411 416
412 new_msr &= msr_mask; 417 new_msr &= msr_mask;
413#if defined(CONFIG_64BIT) 418#if defined(CONFIG_64BIT)
@@ -615,6 +620,13 @@ int kvmppc_core_check_requests(struct kvm_vcpu *vcpu)
615 r = 0; 620 r = 0;
616 } 621 }
617 622
623 if (kvm_check_request(KVM_REQ_EPR_EXIT, vcpu)) {
624 vcpu->run->epr.epr = 0;
625 vcpu->arch.epr_needed = true;
626 vcpu->run->exit_reason = KVM_EXIT_EPR;
627 r = 0;
628 }
629
618 return r; 630 return r;
619} 631}
620 632