[PATCH v5 02/10] irqchip/gic-v3-its: Align shared ITS allocations to the CoCo shared granule size

Aneesh Kumar K.V aneesh.kumar at kernel.org
Mon Jul 6 06:42:17 PDT 2026


Marc Zyngier <maz at kernel.org> writes:

> On Mon, 06 Jul 2026 07:04:24 +0100,
> "Aneesh Kumar K.V (Arm)" <aneesh.kumar at kernel.org> wrote:
>> 
>> ITS tables allocated by the coco guest are shared with the hypervisor.
>> These allocations must satisfy the host shared-buffer granule size so that
>> the full converted range is safe for host access.
>> 
>> Allocate ITS pages using a size rounded up to the shared granule size and
>> use the same allocation order when encrypting, decrypting and freeing the
>> memory. Also grow the ITT cache in shared-granule sized chunks instead of
>> assuming PAGE_SIZE is sufficient.
>> 
>> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar at kernel.org>
>> ---
>>  drivers/irqchip/irq-gic-v3-its.c | 17 +++++++++++------
>>  1 file changed, 11 insertions(+), 6 deletions(-)
>> 
>> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
>> index b57d81ad33a0..5d6d38aa0dae 100644
>> --- a/drivers/irqchip/irq-gic-v3-its.c
>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>> @@ -213,16 +213,17 @@ static gfp_t gfp_flags_quirk;
>>  static struct page *its_alloc_pages_node(int node, gfp_t gfp,
>>  					 unsigned int order)
>>  {
>> +	unsigned int alloc_order;
>>  	struct page *page;
>>  	int ret = 0;
>>  
>> -	page = alloc_pages_node(node, gfp | gfp_flags_quirk, order);
>> -
>> +	alloc_order = get_order(mem_cc_align_to_shared_granule(PAGE_SIZE << order));
>> +	page = alloc_pages_node(node, gfp | gfp_flags_quirk, alloc_order);
>>  	if (!page)
>>  		return NULL;
>>  
>>  	ret = set_memory_decrypted((unsigned long)page_address(page),
>> -				   1 << order);
>> +				   1 << alloc_order);
>>  	/*
>>  	 * If set_memory_decrypted() fails then we don't know what state the
>>  	 * page is in, so we can't free it. Instead we leak it.
>> @@ -241,13 +242,16 @@ static struct page *its_alloc_pages(gfp_t gfp, unsigned int order)
>>  
>>  static void its_free_pages(void *addr, unsigned int order)
>>  {
>> +	int alloc_order;
>> +
>> +	alloc_order = get_order(mem_cc_align_to_shared_granule(PAGE_SIZE << order));
>>  	/*
>>  	 * If the memory cannot be encrypted again then we must leak the pages.
>>  	 * set_memory_encrypted() will already have WARNed.
>>  	 */
>> -	if (set_memory_encrypted((unsigned long)addr, 1 << order))
>> +	if (set_memory_encrypted((unsigned long)addr, 1 << alloc_order))
>>  		return;
>> -	free_pages((unsigned long)addr, order);
>> +	free_pages((unsigned long)addr, alloc_order);
>
> The comments I had in [1] are still applicable.
>
> 	M.
>
> [1] https://lore.kernel.org/all/86zf2ozrb8.wl-maz@kernel.org/
>

I renamed it to alloc_order to make it clear that it refers to the
allocation order rather than the requested order. If you feel strongly
about not introducing another variable, I'll drop the new variable.

-aneesh



More information about the linux-arm-kernel mailing list