Skip to content

Commit

Permalink
KVM: PPC: Implement level interrupts for BookE
Browse files Browse the repository at this point in the history
BookE also wants to support level based interrupts, so let's implement
all the necessary logic there. We need to trick a bit here because the
irqprios are 1:1 assigned to architecture defined values. But since there
is some space left there, we can just pick a random one and move it later
on - it's internal anyways.

Signed-off-by: Alexander Graf <agraf@suse.de>
  • Loading branch information
Alexander Graf authored and Avi Kivity committed Oct 24, 2010
1 parent 7b4203e commit c5335f1
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 3 deletions.
17 changes: 15 additions & 2 deletions arch/powerpc/kvm/booke.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,19 @@ void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu)
void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
struct kvm_interrupt *irq)
{
kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_EXTERNAL);
unsigned int prio = BOOKE_IRQPRIO_EXTERNAL;

if (irq->irq == KVM_INTERRUPT_SET_LEVEL)
prio = BOOKE_IRQPRIO_EXTERNAL_LEVEL;

kvmppc_booke_queue_irqprio(vcpu, prio);
}

void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu,
struct kvm_interrupt *irq)
{
clear_bit(BOOKE_IRQPRIO_EXTERNAL, &vcpu->arch.pending_exceptions);
clear_bit(BOOKE_IRQPRIO_EXTERNAL_LEVEL, &vcpu->arch.pending_exceptions);
}

/* Deliver the interrupt of the corresponding priority, if possible. */
Expand All @@ -150,6 +156,7 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
ulong crit_raw = vcpu->arch.shared->critical;
ulong crit_r1 = kvmppc_get_gpr(vcpu, 1);
bool crit;
bool keep_irq = false;

/* Truncate crit indicators in 32 bit mode */
if (!(vcpu->arch.shared->msr & MSR_SF)) {
Expand All @@ -162,6 +169,11 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
/* ... and we're in supervisor mode */
crit = crit && !(vcpu->arch.shared->msr & MSR_PR);

if (priority == BOOKE_IRQPRIO_EXTERNAL_LEVEL) {
priority = BOOKE_IRQPRIO_EXTERNAL;
keep_irq = true;
}

switch (priority) {
case BOOKE_IRQPRIO_DTLB_MISS:
case BOOKE_IRQPRIO_DATA_STORAGE:
Expand Down Expand Up @@ -214,7 +226,8 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
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);
if (!keep_irq)
clear_bit(priority, &vcpu->arch.pending_exceptions);
}

return allowed;
Expand Down
4 changes: 3 additions & 1 deletion arch/powerpc/kvm/booke.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@
#define BOOKE_IRQPRIO_FIT 17
#define BOOKE_IRQPRIO_DECREMENTER 18
#define BOOKE_IRQPRIO_PERFORMANCE_MONITOR 19
#define BOOKE_IRQPRIO_MAX 19
/* Internal pseudo-irqprio for level triggered externals */
#define BOOKE_IRQPRIO_EXTERNAL_LEVEL 20
#define BOOKE_IRQPRIO_MAX 20

extern unsigned long kvmppc_booke_handlers;

Expand Down

0 comments on commit c5335f1

Please sign in to comment.