Skip to content

Commit

Permalink
arm/arm64: KVM: support for un-queuing active IRQs
Browse files Browse the repository at this point in the history
Migrating active interrupts causes the active state to be lost
completely. This implements some additional bitmaps to track the active
state on the distributor and export this to user space.

Signed-off-by: Christoffer Dall <[email protected]>
Signed-off-by: Alex Bennée <[email protected]>
Signed-off-by: Christoffer Dall <[email protected]>
  • Loading branch information
chazy committed Mar 14, 2015
1 parent 7176095 commit 47a98b1
Show file tree
Hide file tree
Showing 4 changed files with 212 additions and 38 deletions.
15 changes: 14 additions & 1 deletion include/kvm/arm_vgic.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ struct vgic_dist {
/* Level-triggered interrupt queued on VCPU interface */
struct vgic_bitmap irq_queued;

/* Interrupt was active when unqueue from VCPU interface */
struct vgic_bitmap irq_active;

/* Interrupt priority. Not used yet. */
struct vgic_bytemap irq_priority;

Expand Down Expand Up @@ -235,6 +238,9 @@ struct vgic_dist {
/* Bitmap indicating which CPU has something pending */
unsigned long *irq_pending_on_cpu;

/* Bitmap indicating which CPU has active IRQs */
unsigned long *irq_active_on_cpu;

struct vgic_vm_ops vm_ops;
};

Expand Down Expand Up @@ -266,9 +272,15 @@ struct vgic_cpu {
/* per IRQ to LR mapping */
u8 *vgic_irq_lr_map;

/* Pending interrupts on this VCPU */
/* Pending/active/both interrupts on this VCPU */
DECLARE_BITMAP( pending_percpu, VGIC_NR_PRIVATE_IRQS);
DECLARE_BITMAP( active_percpu, VGIC_NR_PRIVATE_IRQS);
DECLARE_BITMAP( pend_act_percpu, VGIC_NR_PRIVATE_IRQS);

/* Pending/active/both shared interrupts, dynamically sized */
unsigned long *pending_shared;
unsigned long *active_shared;
unsigned long *pend_act_shared;

/* Bitmap of used/free list registers */
DECLARE_BITMAP( lr_used, VGIC_V2_MAX_LRS);
Expand Down Expand Up @@ -306,6 +318,7 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
bool level);
void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run,
struct kvm_exit_mmio *mmio);

Expand Down
20 changes: 18 additions & 2 deletions virt/kvm/arm/vgic-v2-emul.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,22 @@ static bool handle_mmio_clear_pending_reg(struct kvm_vcpu *vcpu,
vcpu->vcpu_id);
}

static bool handle_mmio_set_active_reg(struct kvm_vcpu *vcpu,
struct kvm_exit_mmio *mmio,
phys_addr_t offset)
{
return vgic_handle_set_active_reg(vcpu->kvm, mmio, offset,
vcpu->vcpu_id);
}

static bool handle_mmio_clear_active_reg(struct kvm_vcpu *vcpu,
struct kvm_exit_mmio *mmio,
phys_addr_t offset)
{
return vgic_handle_clear_active_reg(vcpu->kvm, mmio, offset,
vcpu->vcpu_id);
}

static bool handle_mmio_priority_reg(struct kvm_vcpu *vcpu,
struct kvm_exit_mmio *mmio,
phys_addr_t offset)
Expand Down Expand Up @@ -344,13 +360,13 @@ static const struct kvm_mmio_range vgic_dist_ranges[] = {
.base = GIC_DIST_ACTIVE_SET,
.len = VGIC_MAX_IRQS / 8,
.bits_per_irq = 1,
.handle_mmio = handle_mmio_raz_wi,
.handle_mmio = handle_mmio_set_active_reg,
},
{
.base = GIC_DIST_ACTIVE_CLEAR,
.len = VGIC_MAX_IRQS / 8,
.bits_per_irq = 1,
.handle_mmio = handle_mmio_raz_wi,
.handle_mmio = handle_mmio_clear_active_reg,
},
{
.base = GIC_DIST_PRI,
Expand Down
Loading

0 comments on commit 47a98b1

Please sign in to comment.