From: Oliver Upton <oliver.upton@linux.dev>
To: kvmarm@lists.linux.dev
Cc: Marc Zyngier <maz@kernel.org>, James Morse <james.morse@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Zenghui Yu <yuzenghui@huawei.com>,
Eric Auger <eric.auger@redhat.com>,
kvm@vger.kernel.org, Oliver Upton <oliver.upton@linux.dev>
Subject: [PATCH v3 08/19] KVM: arm64: vgic-its: Maintain a translation cache per ITS
Date: Mon, 22 Apr 2024 20:01:47 +0000 [thread overview]
Message-ID: <20240422200158.2606761-9-oliver.upton@linux.dev> (raw)
In-Reply-To: <20240422200158.2606761-1-oliver.upton@linux.dev>
Within the context of a single ITS, it is possible to use an xarray to
cache the device ID & event ID translation to a particular irq
descriptor. Take advantage of this to build a translation cache capable
of fitting all valid translations for a given ITS.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arch/arm64/kvm/vgic/vgic-its.c | 37 +++++++++++++++++++++++++++++++++-
include/kvm/arm_vgic.h | 6 ++++++
2 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
index 2caa30bf20c7..1cea0d78025b 100644
--- a/arch/arm64/kvm/vgic/vgic-its.c
+++ b/arch/arm64/kvm/vgic/vgic-its.c
@@ -511,6 +511,11 @@ static unsigned long vgic_mmio_read_its_idregs(struct kvm *kvm,
return 0;
}
+static unsigned long vgic_its_cache_key(u32 devid, u32 eventid)
+{
+ return (((unsigned long)devid) << VITS_TYPER_IDBITS) | eventid;
+}
+
static struct vgic_irq *__vgic_its_check_cache(struct vgic_dist *dist,
phys_addr_t db,
u32 devid, u32 eventid)
@@ -564,8 +569,10 @@ static void vgic_its_cache_translation(struct kvm *kvm, struct vgic_its *its,
u32 devid, u32 eventid,
struct vgic_irq *irq)
{
+ unsigned long cache_key = vgic_its_cache_key(devid, eventid);
struct vgic_dist *dist = &kvm->arch.vgic;
struct vgic_translation_cache_entry *cte;
+ struct vgic_irq *old;
unsigned long flags;
phys_addr_t db;
@@ -604,6 +611,15 @@ static void vgic_its_cache_translation(struct kvm *kvm, struct vgic_its *its,
* its_lock, as the ITE (and the reference it holds) cannot be freed.
*/
lockdep_assert_held(&its->its_lock);
+
+ /*
+ * Yes, two references are necessary at the moment:
+ * - One for the global LPI translation cache
+ * - Another for the translation cache belonging to @its
+ *
+ * This will soon disappear.
+ */
+ vgic_get_irq_kref(irq);
vgic_get_irq_kref(irq);
cte->db = db;
@@ -613,6 +629,16 @@ static void vgic_its_cache_translation(struct kvm *kvm, struct vgic_its *its,
/* Move the new translation to the head of the list */
list_move(&cte->entry, &dist->lpi_translation_cache);
+ raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
+
+ /*
+ * The per-ITS cache is a perfect cache, so it may already have an
+ * identical translation even if it were missing from the global
+ * cache. Ensure we don't leak a reference if that is the case.
+ */
+ old = xa_store(&its->translation_cache, cache_key, irq, GFP_KERNEL_ACCOUNT);
+ if (old)
+ vgic_put_irq(kvm, old);
out:
raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
@@ -623,7 +649,8 @@ static void vgic_its_invalidate_cache(struct vgic_its *its)
struct kvm *kvm = its->dev->kvm;
struct vgic_dist *dist = &kvm->arch.vgic;
struct vgic_translation_cache_entry *cte;
- unsigned long flags;
+ unsigned long flags, idx;
+ struct vgic_irq *irq;
raw_spin_lock_irqsave(&dist->lpi_list_lock, flags);
@@ -640,6 +667,11 @@ static void vgic_its_invalidate_cache(struct vgic_its *its)
}
raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
+
+ xa_for_each(&its->translation_cache, idx, irq) {
+ xa_erase(&its->translation_cache, idx);
+ vgic_put_irq(kvm, irq);
+ }
}
void vgic_its_invalidate_all_caches(struct kvm *kvm)
@@ -1962,6 +1994,7 @@ static int vgic_its_create(struct kvm_device *dev, u32 type)
INIT_LIST_HEAD(&its->device_list);
INIT_LIST_HEAD(&its->collection_list);
+ xa_init(&its->translation_cache);
dev->kvm->arch.vgic.msis_require_devid = true;
dev->kvm->arch.vgic.has_its = true;
@@ -1992,6 +2025,8 @@ static void vgic_its_destroy(struct kvm_device *kvm_dev)
vgic_its_free_device_list(kvm, its);
vgic_its_free_collection_list(kvm, its);
+ vgic_its_invalidate_cache(its);
+ xa_destroy(&its->translation_cache);
mutex_unlock(&its->its_lock);
kfree(its);
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index ac7f15ec1586..c15e7fcccb86 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -210,6 +210,12 @@ struct vgic_its {
struct mutex its_lock;
struct list_head device_list;
struct list_head collection_list;
+
+ /*
+ * Caches the (device_id, event_id) -> vgic_irq translation for
+ * LPIs that are mapped and enabled.
+ */
+ struct xarray translation_cache;
};
struct vgic_state_iter;
--
2.44.0.769.g3c40516874-goog
next prev parent reply other threads:[~2024-04-22 20:02 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-22 20:01 [PATCH v3 00/19] KVM: arm64: Transition to a per-ITS translation cache Oliver Upton
2024-04-22 20:01 ` [PATCH v3 01/19] KVM: Treat the device list as an rculist Oliver Upton
2024-04-23 0:15 ` Sean Christopherson
2024-04-22 20:01 ` [PATCH v3 02/19] KVM: arm64: vgic-its: Walk LPI xarray in its_sync_lpi_pending_table() Oliver Upton
2024-04-22 20:01 ` [PATCH v3 03/19] KVM: arm64: vgic-its: Walk LPI xarray in vgic_its_invall() Oliver Upton
2024-04-22 20:01 ` [PATCH v3 04/19] KVM: arm64: vgic-its: Walk LPI xarray in vgic_its_cmd_handle_movall() Oliver Upton
2024-04-22 20:01 ` [PATCH v3 05/19] KVM: arm64: vgic-debug: Use an xarray mark for debug iterator Oliver Upton
2024-08-06 9:23 ` Zenghui Yu
2024-08-06 12:39 ` Zenghui Yu
2024-08-06 14:11 ` Zenghui Yu
2024-08-06 16:00 ` Zenghui Yu
2024-08-06 16:21 ` Marc Zyngier
2024-08-07 5:23 ` Zenghui Yu
2024-04-22 20:01 ` [PATCH v3 06/19] KVM: arm64: vgic-its: Get rid of vgic_copy_lpi_list() Oliver Upton
2024-04-22 20:01 ` [PATCH v3 07/19] KVM: arm64: vgic-its: Scope translation cache invalidations to an ITS Oliver Upton
2024-04-22 20:01 ` Oliver Upton [this message]
2024-04-22 20:01 ` [PATCH v3 09/19] KVM: arm64: vgic-its: Spin off helper for finding ITS by doorbell addr Oliver Upton
2024-04-22 20:01 ` [PATCH v3 10/19] KVM: arm64: vgic-its: Use the per-ITS translation cache for injection Oliver Upton
2024-04-22 20:01 ` [PATCH v3 11/19] KVM: arm64: vgic-its: Rip out the global translation cache Oliver Upton
2024-04-22 20:01 ` [PATCH v3 12/19] KVM: arm64: vgic-its: Get rid of the lpi_list_lock Oliver Upton
2024-04-22 20:01 ` [PATCH v3 13/19] KVM: selftests: Align with kernel's GIC definitions Oliver Upton
2024-04-22 20:01 ` [PATCH v3 14/19] KVM: selftests: Standardise layout of GIC frames Oliver Upton
2024-04-22 20:01 ` [PATCH v3 15/19] KVM: selftests: Add quadword MMIO accessors Oliver Upton
2024-04-22 20:01 ` [PATCH v3 16/19] KVM: selftests: Add a minimal library for interacting with an ITS Oliver Upton
2024-04-22 20:01 ` [PATCH v3 17/19] KVM: selftests: Add helper for enabling LPIs on a redistributor Oliver Upton
2024-04-22 20:01 ` [PATCH v3 18/19] KVM: selftests: Use MPIDR_HWID_BITMASK from cputype.h Oliver Upton
2024-04-22 20:01 ` [PATCH v3 19/19] KVM: selftests: Add stress test for LPI injection Oliver Upton
2024-04-25 12:33 ` [PATCH v3 00/19] KVM: arm64: Transition to a per-ITS translation cache Marc Zyngier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240422200158.2606761-9-oliver.upton@linux.dev \
--to=oliver.upton@linux.dev \
--cc=eric.auger@redhat.com \
--cc=james.morse@arm.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=maz@kernel.org \
--cc=suzuki.poulose@arm.com \
--cc=yuzenghui@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.