Commit 06bd5359 authored by Eric Auger's avatar Eric Auger Committed by Christoffer Dall

KVM: arm64: vgic-its: Read config and pending bit in add_lpi()

When creating the lpi we now ask the redistributor what is the state
of the LPI (priority, enabled, pending).
Signed-off-by: default avatarEric Auger <eric.auger@redhat.com>
Reviewed-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
Reviewed-by: default avatarChristoffer Dall <cdall@linaro.org>
parent 44de9d68
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
static int vgic_its_save_tables_v0(struct vgic_its *its); static int vgic_its_save_tables_v0(struct vgic_its *its);
static int vgic_its_restore_tables_v0(struct vgic_its *its); static int vgic_its_restore_tables_v0(struct vgic_its *its);
static int vgic_its_commit_v0(struct vgic_its *its); static int vgic_its_commit_v0(struct vgic_its *its);
static int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq,
struct kvm_vcpu *filter_vcpu);
/* /*
* Creates a new (reference to a) struct vgic_irq for a given LPI. * Creates a new (reference to a) struct vgic_irq for a given LPI.
...@@ -44,10 +46,12 @@ static int vgic_its_commit_v0(struct vgic_its *its); ...@@ -44,10 +46,12 @@ static int vgic_its_commit_v0(struct vgic_its *its);
* If this is a "new" LPI, we allocate and initialize a new struct vgic_irq. * If this is a "new" LPI, we allocate and initialize a new struct vgic_irq.
* This function returns a pointer to the _unlocked_ structure. * This function returns a pointer to the _unlocked_ structure.
*/ */
static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid) static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid,
struct kvm_vcpu *vcpu)
{ {
struct vgic_dist *dist = &kvm->arch.vgic; struct vgic_dist *dist = &kvm->arch.vgic;
struct vgic_irq *irq = vgic_get_irq(kvm, NULL, intid), *oldirq; struct vgic_irq *irq = vgic_get_irq(kvm, NULL, intid), *oldirq;
int ret;
/* In this case there is no put, since we keep the reference. */ /* In this case there is no put, since we keep the reference. */
if (irq) if (irq)
...@@ -64,6 +68,7 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid) ...@@ -64,6 +68,7 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid)
irq->config = VGIC_CONFIG_EDGE; irq->config = VGIC_CONFIG_EDGE;
kref_init(&irq->refcount); kref_init(&irq->refcount);
irq->intid = intid; irq->intid = intid;
irq->target_vcpu = vcpu;
spin_lock(&dist->lpi_list_lock); spin_lock(&dist->lpi_list_lock);
...@@ -95,6 +100,19 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid) ...@@ -95,6 +100,19 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid)
out_unlock: out_unlock:
spin_unlock(&dist->lpi_list_lock); spin_unlock(&dist->lpi_list_lock);
/*
* We "cache" the configuration table entries in our struct vgic_irq's.
* However we only have those structs for mapped IRQs, so we read in
* the respective config data from memory here upon mapping the LPI.
*/
ret = update_lpi_config(kvm, irq, NULL);
if (ret)
return ERR_PTR(ret);
ret = vgic_v3_lpi_sync_pending_status(kvm, irq);
if (ret)
return ERR_PTR(ret);
return irq; return irq;
} }
...@@ -795,6 +813,7 @@ static int vgic_its_cmd_handle_mapi(struct kvm *kvm, struct vgic_its *its, ...@@ -795,6 +813,7 @@ static int vgic_its_cmd_handle_mapi(struct kvm *kvm, struct vgic_its *its,
u32 event_id = its_cmd_get_id(its_cmd); u32 event_id = its_cmd_get_id(its_cmd);
u32 coll_id = its_cmd_get_collection(its_cmd); u32 coll_id = its_cmd_get_collection(its_cmd);
struct its_ite *ite; struct its_ite *ite;
struct kvm_vcpu *vcpu = NULL;
struct its_device *device; struct its_device *device;
struct its_collection *collection, *new_coll = NULL; struct its_collection *collection, *new_coll = NULL;
int lpi_nr; int lpi_nr;
...@@ -840,7 +859,10 @@ static int vgic_its_cmd_handle_mapi(struct kvm *kvm, struct vgic_its *its, ...@@ -840,7 +859,10 @@ static int vgic_its_cmd_handle_mapi(struct kvm *kvm, struct vgic_its *its,
ite->collection = collection; ite->collection = collection;
ite->lpi = lpi_nr; ite->lpi = lpi_nr;
irq = vgic_add_lpi(kvm, lpi_nr); if (its_is_collection_mapped(collection))
vcpu = kvm_get_vcpu(kvm, collection->target_addr);
irq = vgic_add_lpi(kvm, lpi_nr, vcpu);
if (IS_ERR(irq)) { if (IS_ERR(irq)) {
if (new_coll) if (new_coll)
vgic_its_free_collection(its, coll_id); vgic_its_free_collection(its, coll_id);
...@@ -849,15 +871,6 @@ static int vgic_its_cmd_handle_mapi(struct kvm *kvm, struct vgic_its *its, ...@@ -849,15 +871,6 @@ static int vgic_its_cmd_handle_mapi(struct kvm *kvm, struct vgic_its *its,
} }
ite->irq = irq; ite->irq = irq;
update_affinity_ite(kvm, ite);
/*
* We "cache" the configuration table entries in out struct vgic_irq's.
* However we only have those structs for mapped IRQs, so we read in
* the respective config data from memory here upon mapping the LPI.
*/
update_lpi_config(kvm, ite->irq, NULL);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment