Re: [PATCH v5 17/19] irqchip/gic-v3-its: Share ITS tables with a non-trusted hypervisor

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Steve,

On 8/19/24 08:19, Steven Price wrote:
External email: Use caution opening links or attachments


Within a realm guest the ITS is emulated by the host. This means the
allocations must have been made available to the host by a call to
set_memory_decrypted(). Introduce an allocation function which performs
this extra call.

For the ITT use a custom genpool-based allocator that calls
set_memory_decrypted() for each page allocated, but then suballocates
the size needed for each ITT. Note that there is no mechanism
implemented to return pages from the genpool, but it is unlikely the
peak number of devices will so much larger than the normal level - so
this isn't expected to be an issue.

Co-developed-by: Suzuki K Poulose <suzuki.poulose@xxxxxxx>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@xxxxxxx>
Tested-by: Will Deacon <will@xxxxxxxxxx>
Signed-off-by: Steven Price <steven.price@xxxxxxx>
---
Changes since v3:
  * Use BIT() macro.
  * Use a genpool based allocator in its_create_device() to avoid
    allocating a full page.
  * Fix subject to drop "realm" and use gic-v3-its.
  * Add error handling to ITS alloc/free.
Changes since v2:
  * Drop 'shared' from the new its_xxx function names as they are used
    for non-realm guests too.
  * Don't handle the NUMA_NO_NODE case specially - alloc_pages_node()
    should do the right thing.
  * Drop a pointless (void *) cast.
---
  drivers/irqchip/irq-gic-v3-its.c | 139 ++++++++++++++++++++++++++-----
  1 file changed, 116 insertions(+), 23 deletions(-)

...
+
+static void *itt_alloc_pool(int node, int size)
+{
+       unsigned long addr;
+       struct page *page;
+
+       if (size >= PAGE_SIZE) {
+               page = its_alloc_pages_node(node,
+                                           GFP_KERNEL | __GFP_ZERO,
+                                           get_order(size));
+
+               return page_address(page);
+       }
+
+       do {
+               addr = gen_pool_alloc(itt_pool, size);
+               if (addr)
+                       break;
+
+               page = its_alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, 1);


Two (2^1) pages are allocated here, but only one page is being added to the pool.
Is this a typo or intentional?

+               if (!page)
+                       break;
+
+               gen_pool_add(itt_pool, (unsigned long)page_address(page),
+                            PAGE_SIZE, node);
+       } while (!addr);
+
+       return (void *)addr;
+}
+
+static void itt_free_pool(void *addr, int size)

-Shanker




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux