1 From b08e2f42e86b5848add254da45b56fc672e2bced Mon Sep 17 00:00:00 2001
2 From: Steven Price <steven.price@arm.com>
3 Date: Wed, 2 Oct 2024 15:16:29 +0100
4 Subject: [PATCH] irqchip/gic-v3-its: Share ITS tables with a non-trusted
7 Within a realm guest the ITS is emulated by the host. This means the
8 allocations must have been made available to the host by a call to
9 set_memory_decrypted(). Introduce an allocation function which performs
12 For the ITT use a custom genpool-based allocator that calls
13 set_memory_decrypted() for each page allocated, but then suballocates the
14 size needed for each ITT. Note that there is no mechanism implemented to
15 return pages from the genpool, but it is unlikely that the peak number of
16 devices will be much larger than the normal level - so this isn't expected
19 Co-developed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
20 Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
21 Signed-off-by: Steven Price <steven.price@arm.com>
22 Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
23 Tested-by: Will Deacon <will@kernel.org>
24 Reviewed-by: Marc Zyngier <maz@kernel.org>
25 Link: https://lore.kernel.org/all/20241002141630.433502-2-steven.price@arm.com
27 drivers/irqchip/irq-gic-v3-its.c | 138 +++++++++++++++++++++++++------
28 1 file changed, 115 insertions(+), 23 deletions(-)
30 --- a/drivers/irqchip/irq-gic-v3-its.c
31 +++ b/drivers/irqchip/irq-gic-v3-its.c
33 #include <linux/crash_dump.h>
34 #include <linux/delay.h>
35 #include <linux/efi.h>
36 +#include <linux/genalloc.h>
37 #include <linux/interrupt.h>
38 #include <linux/iommu.h>
39 #include <linux/iopoll.h>
40 #include <linux/irqdomain.h>
41 #include <linux/list.h>
42 #include <linux/log2.h>
43 +#include <linux/mem_encrypt.h>
44 #include <linux/memblock.h>
46 #include <linux/msi.h>
48 #include <linux/of_pci.h>
49 #include <linux/of_platform.h>
50 #include <linux/percpu.h>
51 +#include <linux/set_memory.h>
52 #include <linux/slab.h>
53 #include <linux/syscore_ops.h>
55 @@ -163,6 +166,7 @@ struct its_device {
57 struct event_lpi_map event_map;
63 @@ -198,6 +202,87 @@ static DEFINE_IDA(its_vpeid_ida);
64 #define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base)
65 #define gic_data_rdist_vlpi_base() (gic_data_rdist_rd_base() + SZ_128K)
67 +static struct page *its_alloc_pages_node(int node, gfp_t gfp,
73 + page = alloc_pages_node(node, gfp, order);
78 + ret = set_memory_decrypted((unsigned long)page_address(page),
81 + * If set_memory_decrypted() fails then we don't know what state the
82 + * page is in, so we can't free it. Instead we leak it.
83 + * set_memory_decrypted() will already have WARNed.
91 +static struct page *its_alloc_pages(gfp_t gfp, unsigned int order)
93 + return its_alloc_pages_node(NUMA_NO_NODE, gfp, order);
96 +static void its_free_pages(void *addr, unsigned int order)
99 + * If the memory cannot be encrypted again then we must leak the pages.
100 + * set_memory_encrypted() will already have WARNed.
102 + if (set_memory_encrypted((unsigned long)addr, 1 << order))
104 + free_pages((unsigned long)addr, order);
107 +static struct gen_pool *itt_pool;
109 +static void *itt_alloc_pool(int node, int size)
111 + unsigned long addr;
114 + if (size >= PAGE_SIZE) {
115 + page = its_alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, get_order(size));
117 + return page ? page_address(page) : NULL;
121 + addr = gen_pool_alloc(itt_pool, size);
125 + page = its_alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, 1);
129 + gen_pool_add(itt_pool, (unsigned long)page_address(page), PAGE_SIZE, node);
132 + return (void *)addr;
135 +static void itt_free_pool(void *addr, int size)
140 + if (size >= PAGE_SIZE) {
141 + its_free_pages(addr, get_order(size));
145 + gen_pool_free(itt_pool, (unsigned long)addr, size);
149 * Skip ITSs that have no vLPIs mapped, unless we're on GICv4.1, as we
150 * always have vSGIs mapped.
151 @@ -2192,7 +2277,8 @@ static struct page *its_allocate_prop_ta
153 struct page *prop_page;
155 - prop_page = alloc_pages(gfp_flags, get_order(LPI_PROPBASE_SZ));
156 + prop_page = its_alloc_pages(gfp_flags,
157 + get_order(LPI_PROPBASE_SZ));
161 @@ -2203,8 +2289,7 @@ static struct page *its_allocate_prop_ta
163 static void its_free_prop_table(struct page *prop_page)
165 - free_pages((unsigned long)page_address(prop_page),
166 - get_order(LPI_PROPBASE_SZ));
167 + its_free_pages(page_address(prop_page), get_order(LPI_PROPBASE_SZ));
170 static bool gic_check_reserved_range(phys_addr_t addr, unsigned long size)
171 @@ -2326,7 +2411,7 @@ static int its_setup_baser(struct its_no
172 order = get_order(GITS_BASER_PAGES_MAX * psz);
175 - page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, order);
176 + page = its_alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO, order);
180 @@ -2339,7 +2424,7 @@ static int its_setup_baser(struct its_no
181 /* 52bit PA is supported only when PageSize=64K */
183 pr_err("ITS: no 52bit PA support when psz=%d\n", psz);
184 - free_pages((unsigned long)base, order);
185 + its_free_pages(base, order);
189 @@ -2395,7 +2480,7 @@ retry_baser:
190 pr_err("ITS@%pa: %s doesn't stick: %llx %llx\n",
191 &its->phys_base, its_base_type_string[type],
193 - free_pages((unsigned long)base, order);
194 + its_free_pages(base, order);
198 @@ -2534,8 +2619,7 @@ static void its_free_tables(struct its_n
200 for (i = 0; i < GITS_BASER_NR_REGS; i++) {
201 if (its->tables[i].base) {
202 - free_pages((unsigned long)its->tables[i].base,
203 - its->tables[i].order);
204 + its_free_pages(its->tables[i].base, its->tables[i].order);
205 its->tables[i].base = NULL;
208 @@ -2801,7 +2885,7 @@ static bool allocate_vpe_l2_table(int cp
210 /* Allocate memory for 2nd level table */
212 - page = alloc_pages(GFP_KERNEL | __GFP_ZERO, get_order(psz));
213 + page = its_alloc_pages(GFP_KERNEL | __GFP_ZERO, get_order(psz));
217 @@ -2920,7 +3004,7 @@ static int allocate_vpe_l1_table(void)
219 pr_debug("np = %d, npg = %lld, psz = %d, epp = %d, esz = %d\n",
220 np, npg, psz, epp, esz);
221 - page = alloc_pages(GFP_ATOMIC | __GFP_ZERO, get_order(np * PAGE_SIZE));
222 + page = its_alloc_pages(GFP_ATOMIC | __GFP_ZERO, get_order(np * PAGE_SIZE));
226 @@ -2966,8 +3050,7 @@ static struct page *its_allocate_pending
228 struct page *pend_page;
230 - pend_page = alloc_pages(gfp_flags | __GFP_ZERO,
231 - get_order(LPI_PENDBASE_SZ));
232 + pend_page = its_alloc_pages(gfp_flags | __GFP_ZERO, get_order(LPI_PENDBASE_SZ));
236 @@ -2979,7 +3062,7 @@ static struct page *its_allocate_pending
238 static void its_free_pending_table(struct page *pt)
240 - free_pages((unsigned long)page_address(pt), get_order(LPI_PENDBASE_SZ));
241 + its_free_pages(page_address(pt), get_order(LPI_PENDBASE_SZ));
245 @@ -3314,8 +3397,8 @@ static bool its_alloc_table_entry(struct
247 /* Allocate memory for 2nd level table */
249 - page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
250 - get_order(baser->psz));
251 + page = its_alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
252 + get_order(baser->psz));
256 @@ -3410,7 +3493,6 @@ static struct its_device *its_create_dev
257 if (WARN_ON(!is_power_of_2(nvecs)))
258 nvecs = roundup_pow_of_two(nvecs);
260 - dev = kzalloc(sizeof(*dev), GFP_KERNEL);
262 * Even if the device wants a single LPI, the ITT must be
263 * sized as a power of two (and you need at least one bit...).
264 @@ -3418,7 +3500,11 @@ static struct its_device *its_create_dev
265 nr_ites = max(2, nvecs);
266 sz = nr_ites * (FIELD_GET(GITS_TYPER_ITT_ENTRY_SIZE, its->typer) + 1);
267 sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
268 - itt = kzalloc_node(sz, GFP_KERNEL, its->numa_node);
270 + itt = itt_alloc_pool(its->numa_node, sz);
272 + dev = kzalloc(sizeof(*dev), GFP_KERNEL);
275 lpi_map = its_lpi_alloc(nvecs, &lpi_base, &nr_lpis);
277 @@ -3430,9 +3516,9 @@ static struct its_device *its_create_dev
281 - if (!dev || !itt || !col_map || (!lpi_map && alloc_lpis)) {
282 + if (!dev || !itt || !col_map || (!lpi_map && alloc_lpis)) {
285 + itt_free_pool(itt, sz);
286 bitmap_free(lpi_map);
289 @@ -3442,6 +3528,7 @@ static struct its_device *its_create_dev
294 dev->nr_ites = nr_ites;
295 dev->event_map.lpi_map = lpi_map;
296 dev->event_map.col_map = col_map;
297 @@ -3469,7 +3556,7 @@ static void its_free_device(struct its_d
298 list_del(&its_dev->entry);
299 raw_spin_unlock_irqrestore(&its_dev->its->lock, flags);
300 kfree(its_dev->event_map.col_map);
301 - kfree(its_dev->itt);
302 + itt_free_pool(its_dev->itt, its_dev->itt_sz);
306 @@ -5112,8 +5199,9 @@ static int __init its_probe_one(struct i
310 - page = alloc_pages_node(its->numa_node, GFP_KERNEL | __GFP_ZERO,
311 - get_order(ITS_CMD_QUEUE_SZ));
312 + page = its_alloc_pages_node(its->numa_node,
313 + GFP_KERNEL | __GFP_ZERO,
314 + get_order(ITS_CMD_QUEUE_SZ));
318 @@ -5177,7 +5265,7 @@ static int __init its_probe_one(struct i
320 its_free_tables(its);
322 - free_pages((unsigned long)its->cmd_base, get_order(ITS_CMD_QUEUE_SZ));
323 + its_free_pages(its->cmd_base, get_order(ITS_CMD_QUEUE_SZ));
326 iounmap(its->sgir_base);
327 @@ -5659,6 +5747,10 @@ int __init its_init(struct fwnode_handle
328 bool has_v4_1 = false;
331 + itt_pool = gen_pool_create(get_order(ITS_ITT_ALIGN), -1);
337 its_parent = parent_domain;