From: "Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org>
To: linux-coco@lists.linux.dev, kvmarm@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, iommu@lists.linux.dev
Cc: "Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Baoquan He" <baoquan.he@linux.dev>,
"Mike Rapoport" <rppt@kernel.org>,
"Pasha Tatashin" <pasha.tatashin@soleen.com>,
"Pratyush Yadav" <pratyush@kernel.org>,
"Catalin Marinas" <catalin.marinas@arm.com>,
"Christian König" <christian.koenig@amd.com>,
"Jason Gunthorpe" <jgg@ziepe.ca>,
"Joerg Roedel" <joro@8bytes.org>, "Marc Zyngier" <maz@kernel.org>,
"Marek Szyprowski" <m.szyprowski@samsung.com>,
"Robin Murphy" <robin.murphy@arm.com>,
"Steven Price" <steven.price@arm.com>,
"Sumit Semwal" <sumit.semwal@linaro.org>,
"Suzuki K Poulose" <suzuki.poulose@arm.com>,
"Thomas Gleixner" <tglx@kernel.org>,
"Will Deacon" <will@kernel.org>,
"Russell King" <linux@armlinux.org.uk>,
"Benjamin Gaignard" <benjamin.gaignard@collabora.com>,
"Brian Starkey" <Brian.Starkey@arm.com>,
"John Stultz" <jstultz@google.com>,
"Mark Rutland" <mark.rutland@arm.com>,
"Radu Rendec" <radu@rendec.net>,
"T.J. Mercier" <tjmercier@google.com>,
"Madhavan Srinivasan" <maddy@linux.ibm.com>,
"Michael Ellerman" <mpe@ellerman.id.au>,
"Nicholas Piggin" <npiggin@gmail.com>,
"Christophe Leroy" <chleroy@kernel.org>,
"Ritesh Harjani" <ritesh.list@gmail.com>,
"Shrikanth Hegde" <sshegde@linux.ibm.com>,
"Alexander Gordeev" <agordeev@linux.ibm.com>,
"Gerald Schaefer" <gerald.schaefer@linux.ibm.com>,
"Heiko Carstens" <hca@linux.ibm.com>,
"Vasily Gorbik" <gor@linux.ibm.com>,
"Christian Borntraeger" <borntraeger@linux.ibm.com>,
"Sven Schnelle" <svens@linux.ibm.com>,
"Ingo Molnar" <mingo@redhat.com>,
"Borislav Petkov" <bp@alien8.de>,
"Dave Hansen" <dave.hansen@linux.intel.com>,
x86@kernel.org, "H . Peter Anvin" <hpa@zytor.com>,
"Kiryl Shutsemau" <kas@kernel.org>,
"Rick Edgecombe" <rick.p.edgecombe@intel.com>,
"K . Y . Srinivasan" <kys@microsoft.com>,
"Haiyang Zhang" <haiyangz@microsoft.com>,
"Wei Liu" <wei.liu@kernel.org>,
"Dexuan Cui" <decui@microsoft.com>,
"Long Li" <longli@microsoft.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Vitaly Kuznetsov" <vkuznets@redhat.com>,
"Andy Lutomirski" <luto@kernel.org>,
"Peter Zijlstra" <peterz@infradead.org>,
dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org,
linux-media@vger.kernel.org, linux-mm@kvack.org
Subject: [RFC PATCH v8 14/14] irqchip/gic-v3-its: Preallocate VPE L1 tables
Date: Thu, 24 Sep 2026 15:35:29 +0530 [thread overview]
Message-ID: <20260924100529.1398790-15-aneesh.kumar@kernel.org> (raw)
In-Reply-To: <20260924100529.1398790-1-aneesh.kumar@kernel.org>
VPE L1 tables are allocated from the CPU-starting callback, where sleeping is
not allowed. Remove the page allocation from this atomic path.
Use a blocking allocation for the boot CPU and record the resulting table
order. Allocate a page of that order from the sleepable CPU hotplug prepare
stage for each secondary CPU. Consume the preallocated page only when the CPU
cannot inherit an existing redistributor or ITS table.
Reclaim unused preallocations after the CPU reaches the online state, and from
the prepare-state teardown when CPU bring-up aborts.
Assisted-by: Codex:gpt-5
Cc: Marc Zyngier <maz@kernel.org>
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: Radu Rendec <radu@rendec.net>
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
drivers/irqchip/irq-gic-v3-its.c | 110 +++++++++++++++++++++++++++--
drivers/irqchip/irq-gic-v3.c | 4 +-
include/linux/irqchip/arm-gic-v3.h | 3 +-
3 files changed, 108 insertions(+), 9 deletions(-)
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 4814161df02e..a8f37fb97845 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -195,6 +195,7 @@ static DEFINE_PER_CPU(struct cpu_lpi_count, cpu_lpi_count);
static LIST_HEAD(its_nodes);
static DEFINE_RAW_SPINLOCK(its_lock);
static struct rdists *gic_rdists;
+static unsigned int vpe_l1_prealloc_order = UINT_MAX;
static struct irq_domain *its_parent;
static unsigned long its_list_map;
@@ -2884,12 +2885,35 @@ static bool allocate_vpe_l2_table(int cpu, u32 id)
return true;
}
-static int allocate_vpe_l1_table(void)
+static unsigned int vpe_l1_table_order(u64 val)
+{
+ unsigned int psz;
+ u64 npg;
+
+ switch (FIELD_GET(GICR_VPROPBASER_4_1_PAGE_SIZE, val)) {
+ default:
+ case GIC_PAGE_SIZE_4K:
+ psz = SZ_4K;
+ break;
+ case GIC_PAGE_SIZE_16K:
+ psz = SZ_16K;
+ break;
+ case GIC_PAGE_SIZE_64K:
+ psz = SZ_64K;
+ break;
+ }
+
+ npg = FIELD_GET(GICR_VPROPBASER_4_1_SIZE, val) + 1;
+ return get_order(npg * psz);
+}
+
+static int allocate_vpe_l1_table(bool use_prealloc)
{
void __iomem *vlpi_base = gic_data_rdist_vlpi_base();
u64 val, gpsz, npg, pa;
unsigned int psz = SZ_64K;
unsigned int np, epp, esz;
+ unsigned int order;
struct page *page;
if (!gic_rdists->has_rvpeid)
@@ -2982,7 +3006,16 @@ static int allocate_vpe_l1_table(void)
pr_debug("np = %d, npg = %lld, psz = %d, epp = %d, esz = %d\n",
np, npg, psz, epp, esz);
- page = its_alloc_pages(GFP_ATOMIC | __GFP_ZERO, get_order(np * PAGE_SIZE));
+ order = get_order(np * PAGE_SIZE);
+ if (use_prealloc) {
+ if (WARN_ON_ONCE(order != vpe_l1_prealloc_order))
+ return -EINVAL;
+
+ page = gic_data_rdist()->vpe_l1_prealloc;
+ gic_data_rdist()->vpe_l1_prealloc = NULL;
+ } else {
+ page = its_alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
+ }
if (!page)
return -ENOMEM;
@@ -2999,6 +3032,9 @@ static int allocate_vpe_l1_table(void)
val |= GICR_VPROPBASER_4_1_VALID;
out:
+ if (!use_prealloc)
+ vpe_l1_prealloc_order = vpe_l1_table_order(val);
+
gicr_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
cpumask_set_cpu(smp_processor_id(), gic_data_rdist()->vpe_table_mask);
@@ -3138,7 +3174,7 @@ static u64 its_clear_vpend_valid(void __iomem *vlpi_base, u64 clr, u64 set)
return val;
}
-static void its_cpu_init_lpis(void)
+static void its_cpu_init_lpis(bool use_prealloc)
{
void __iomem *rbase = gic_data_rdist_rd_base();
struct page *pend_page;
@@ -3251,7 +3287,7 @@ static void its_cpu_init_lpis(void)
val = its_clear_vpend_valid(vlpi_base, 0, 0);
}
- if (allocate_vpe_l1_table()) {
+ if (allocate_vpe_l1_table(use_prealloc)) {
/*
* If the allocation has failed, we're in massive trouble.
* Disable direct injection, and pray that no VM was
@@ -5422,7 +5458,7 @@ static int redist_disable_lpis(void)
return 0;
}
-int its_cpu_init(void)
+int its_cpu_init(bool use_prealloc)
{
if (!list_empty(&its_nodes)) {
int ret;
@@ -5431,13 +5467,66 @@ int its_cpu_init(void)
if (ret)
return ret;
- its_cpu_init_lpis();
+ its_cpu_init_lpis(use_prealloc);
its_cpu_init_collections();
}
return 0;
}
+static int its_vpe_l1_prepare(unsigned int cpu)
+{
+ struct page **prealloc;
+
+ if (!gic_rdists->has_rvpeid ||
+ vpe_l1_prealloc_order == UINT_MAX ||
+ (gic_data_rdist_cpu(cpu)->flags & RD_LOCAL_LPI_ENABLED))
+ return 0;
+
+ prealloc = &gic_data_rdist_cpu(cpu)->vpe_l1_prealloc;
+ if (*prealloc)
+ return 0;
+
+ *prealloc = its_alloc_pages_node(cpu_to_node(cpu),
+ GFP_KERNEL | __GFP_ZERO,
+ vpe_l1_prealloc_order);
+ return *prealloc ? 0 : -ENOMEM;
+}
+
+static int its_vpe_l1_cleanup(unsigned int cpu)
+{
+ struct page *page;
+
+ page = xchg(&gic_data_rdist_cpu(cpu)->vpe_l1_prealloc, NULL);
+ if (page)
+ its_free_pages(page_address(page), vpe_l1_prealloc_order);
+
+ return 0;
+}
+
+static int __init its_vpe_l1_cpuhp_init(void)
+{
+ int prepare_state, state;
+
+ state = cpuhp_setup_state_nocalls(CPUHP_BP_PREPARE_DYN,
+ "irqchip/arm/gicv3-vpe:prepare",
+ its_vpe_l1_prepare,
+ its_vpe_l1_cleanup);
+ if (state < 0)
+ return state;
+ prepare_state = state;
+
+ state = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
+ "irqchip/arm/gicv3-vpe:online",
+ its_vpe_l1_cleanup, NULL);
+ if (state < 0) {
+ cpuhp_remove_state_nocalls(prepare_state);
+ return state;
+ }
+
+ return 0;
+}
+
static void rdist_memreserve_cpuhp_cleanup_workfn(struct work_struct *work)
{
cpuhp_remove_state_nocalls(gic_rdists->cpuhp_memreserve_state);
@@ -5862,6 +5951,15 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
if (WARN_ON(!has_v4_1 && rdists->has_rvpeid))
rdists->has_rvpeid = false;
+ if (rdists->has_rvpeid) {
+ err = its_vpe_l1_cpuhp_init();
+ if (err) {
+ rdists->has_rvpeid = false;
+ rdists->has_vlpis = false;
+ pr_err("ITS: Failed to prepare VPE tables, disabling GICv4 support\n");
+ }
+ }
+
if (has_v4 & rdists->has_vlpis) {
const struct irq_domain_ops *sgi_ops;
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 6e1fa5b247fc..e2e00372dcfb 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -1320,7 +1320,7 @@ static int gic_starting_cpu(unsigned int cpu)
gic_cpu_init();
if (gic_dist_supports_lpis())
- its_cpu_init();
+ its_cpu_init(true);
return 0;
}
@@ -2053,7 +2053,7 @@ static int __init gic_init_bases(phys_addr_t dist_phys_base,
if (gic_dist_supports_lpis()) {
its_init(handle, &gic_data.rdists, gic_data.domain, dist_prio_irq);
- its_cpu_init();
+ its_cpu_init(false);
its_lpi_memreserve_init();
} else {
if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index ea5fd2374ebe..a5565a745100 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -621,6 +621,7 @@ struct rdists {
u64 flags;
cpumask_t *vpe_table_mask;
void *vpe_l1_base;
+ struct page *vpe_l1_prealloc;
} __percpu *rdist;
phys_addr_t prop_table_pa;
void *prop_table_va;
@@ -637,7 +638,7 @@ struct rdists {
struct irq_domain;
struct fwnode_handle;
int __init its_lpi_memreserve_init(void);
-int its_cpu_init(void);
+int its_cpu_init(bool use_prealloc);
int its_init(struct fwnode_handle *handle, struct rdists *rdists,
struct irq_domain *domain, u8 irq_prio);
int mbi_init(struct fwnode_handle *fwnode, struct irq_domain *parent);
--
2.43.0
prev parent reply other threads:[~2026-09-24 10:09 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-24 10:05 [RFC PATCH v8 00/14] coco: guest: Add a shared-granule allocator for host-shared memory Aneesh Kumar K.V (Arm)
2026-09-24 10:05 ` [RFC PATCH v8 01/14] mm: Add an allocator for CoCo shared memory Aneesh Kumar K.V (Arm)
2026-09-24 10:05 ` [RFC PATCH v8 02/14] mm: Zero memory during shared memory transitions Aneesh Kumar K.V (Arm)
2026-09-24 10:05 ` [RFC PATCH v8 03/14] irqchip/gic-v3-its: Resolve the default NUMA node explicitly Aneesh Kumar K.V (Arm)
2026-09-24 10:05 ` [RFC PATCH v8 04/14] irqchip/gic-v3-its: Allocate shared tables using CoCo shared memory allocator Aneesh Kumar K.V (Arm)
2026-09-24 10:05 ` [RFC PATCH v8 05/14] dma-contiguous: Derive shared alignment from DMA attributes Aneesh Kumar K.V (Arm)
2026-09-24 10:05 ` [RFC PATCH v8 06/14] dma-pool: Allocate CoCo atomic pools using CoCo shared memory allocator Aneesh Kumar K.V (Arm)
2026-09-24 10:05 ` [RFC PATCH v8 07/14] dma-direct: Align CoCo shared DMA allocations to the shared granule size Aneesh Kumar K.V (Arm)
2026-09-24 10:05 ` [RFC PATCH v8 08/14] swiotlb: Align shared IO TLB pools " Aneesh Kumar K.V (Arm)
2026-09-24 10:05 ` [RFC PATCH v8 09/14] swiotlb: Reject misaligned restricted DMA pools for CoCo guests Aneesh Kumar K.V (Arm)
2026-09-24 10:05 ` [RFC PATCH v8 10/14] dma-buf: system_heap: Limit scatterlist entries to the buffer size Aneesh Kumar K.V (Arm)
2026-09-24 10:05 ` [RFC PATCH v8 11/14] dma-buf: system_heap: Allocate shared buffers using CoCo shared memory allocator Aneesh Kumar K.V (Arm)
2026-09-24 10:05 ` [RFC PATCH v8 12/14] swiotlb: Make rounded shared pool capacity allocatable Aneesh Kumar K.V (Arm)
2026-09-24 10:05 ` [RFC PATCH v8 13/14] mm: Assert CoCo shared allocations may sleep Aneesh Kumar K.V (Arm)
2026-09-24 10:05 ` Aneesh Kumar K.V (Arm) [this message]
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=20260924100529.1398790-15-aneesh.kumar@kernel.org \
--to=aneesh.kumar@kernel.org \
--cc=Brian.Starkey@arm.com \
--cc=agordeev@linux.ibm.com \
--cc=akpm@linux-foundation.org \
--cc=baoquan.he@linux.dev \
--cc=benjamin.gaignard@collabora.com \
--cc=borntraeger@linux.ibm.com \
--cc=bp@alien8.de \
--cc=catalin.marinas@arm.com \
--cc=chleroy@kernel.org \
--cc=christian.koenig@amd.com \
--cc=dave.hansen@linux.intel.com \
--cc=decui@microsoft.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=gerald.schaefer@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=haiyangz@microsoft.com \
--cc=hca@linux.ibm.com \
--cc=hpa@zytor.com \
--cc=iommu@lists.linux.dev \
--cc=jgg@ziepe.ca \
--cc=joro@8bytes.org \
--cc=jstultz@google.com \
--cc=kas@kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=kys@microsoft.com \
--cc=linaro-mm-sig@lists.linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-coco@lists.linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux@armlinux.org.uk \
--cc=longli@microsoft.com \
--cc=luto@kernel.org \
--cc=m.szyprowski@samsung.com \
--cc=maddy@linux.ibm.com \
--cc=mark.rutland@arm.com \
--cc=maz@kernel.org \
--cc=mingo@redhat.com \
--cc=mpe@ellerman.id.au \
--cc=npiggin@gmail.com \
--cc=pasha.tatashin@soleen.com \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=pratyush@kernel.org \
--cc=radu@rendec.net \
--cc=rick.p.edgecombe@intel.com \
--cc=ritesh.list@gmail.com \
--cc=robin.murphy@arm.com \
--cc=rppt@kernel.org \
--cc=sshegde@linux.ibm.com \
--cc=steven.price@arm.com \
--cc=sumit.semwal@linaro.org \
--cc=suzuki.poulose@arm.com \
--cc=svens@linux.ibm.com \
--cc=tglx@kernel.org \
--cc=tjmercier@google.com \
--cc=vkuznets@redhat.com \
--cc=wei.liu@kernel.org \
--cc=will@kernel.org \
--cc=x86@kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®