KVM: arm64: Remove hyp_pool pointer from struct hyp_page
authorQuentin Perret <qperret@google.com>
Tue, 8 Jun 2021 11:45:16 +0000 (11:45 +0000)
committerMarc Zyngier <maz@kernel.org>
Fri, 11 Jun 2021 12:24:11 +0000 (13:24 +0100)
Each struct hyp_page currently contains a pointer to a hyp_pool struct
where the page should be freed if its refcount reaches 0. However, this
information can always be inferred from the context in the EL2 code, so
drop the pointer to save a few bytes in the vmemmap.

Signed-off-by: Quentin Perret <qperret@google.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20210608114518.748712-6-qperret@google.com
arch/arm64/kvm/hyp/include/nvhe/gfp.h
arch/arm64/kvm/hyp/include/nvhe/memory.h
arch/arm64/kvm/hyp/nvhe/mem_protect.c
arch/arm64/kvm/hyp/nvhe/page_alloc.c
arch/arm64/kvm/hyp/nvhe/setup.c

index f2c84e4fa40facbe99882f35dc4559505b6c2d37..3ea7bfb6c380a91b816eed5a5dc70ceda2a28c2a 100644 (file)
@@ -24,8 +24,8 @@ struct hyp_pool {
 
 /* Allocation */
 void *hyp_alloc_pages(struct hyp_pool *pool, unsigned int order);
-void hyp_get_page(void *addr);
-void hyp_put_page(void *addr);
+void hyp_get_page(struct hyp_pool *pool, void *addr);
+void hyp_put_page(struct hyp_pool *pool, void *addr);
 
 /* Used pages cannot be freed */
 int hyp_pool_init(struct hyp_pool *pool, u64 pfn, unsigned int nr_pages,
index 7691ab495eb4cac8e8596d4f4dedf1476947af58..991636be2f46672066af5feb3ef83b56e99a5679 100644 (file)
@@ -7,11 +7,9 @@
 
 #include <linux/types.h>
 
-struct hyp_pool;
 struct hyp_page {
        unsigned int refcount;
        unsigned int order;
-       struct hyp_pool *pool;
 };
 
 extern u64 __hyp_vmemmap;
index c8ed7e86231b10efcd2cec72c95a237703e2a7d0..d938ce95d3bdf255251cc0c69722c89275832749 100644 (file)
@@ -43,6 +43,16 @@ static void *host_s2_zalloc_page(void *pool)
        return hyp_alloc_pages(pool, 0);
 }
 
+static void host_s2_get_page(void *addr)
+{
+       hyp_get_page(&host_s2_pool, addr);
+}
+
+static void host_s2_put_page(void *addr)
+{
+       hyp_put_page(&host_s2_pool, addr);
+}
+
 static int prepare_s2_pool(void *pgt_pool_base)
 {
        unsigned long nr_pages, pfn;
@@ -60,8 +70,8 @@ static int prepare_s2_pool(void *pgt_pool_base)
                .phys_to_virt = hyp_phys_to_virt,
                .virt_to_phys = hyp_virt_to_phys,
                .page_count = hyp_page_count,
-               .get_page = hyp_get_page,
-               .put_page = hyp_put_page,
+               .get_page = host_s2_get_page,
+               .put_page = host_s2_put_page,
        };
 
        return 0;
index 34f0eb026dd24d0fd8e1c6214045c23ef5fee3d5..e3689def7033522b4e12c7584e4b9715dcce21a6 100644 (file)
@@ -174,20 +174,18 @@ static void __hyp_put_page(struct hyp_pool *pool, struct hyp_page *p)
  * section to guarantee transient states (e.g. a page with null refcount but
  * not yet attached to a free list) can't be observed by well-behaved readers.
  */
-void hyp_put_page(void *addr)
+void hyp_put_page(struct hyp_pool *pool, void *addr)
 {
        struct hyp_page *p = hyp_virt_to_page(addr);
-       struct hyp_pool *pool = hyp_page_to_pool(p);
 
        hyp_spin_lock(&pool->lock);
        __hyp_put_page(pool, p);
        hyp_spin_unlock(&pool->lock);
 }
 
-void hyp_get_page(void *addr)
+void hyp_get_page(struct hyp_pool *pool, void *addr)
 {
        struct hyp_page *p = hyp_virt_to_page(addr);
-       struct hyp_pool *pool = hyp_page_to_pool(p);
 
        hyp_spin_lock(&pool->lock);
        hyp_page_ref_inc(p);
@@ -236,7 +234,6 @@ int hyp_pool_init(struct hyp_pool *pool, u64 pfn, unsigned int nr_pages,
        /* Init the vmemmap portion */
        p = hyp_phys_to_page(phys);
        for (i = 0; i < nr_pages; i++) {
-               p[i].pool = pool;
                p[i].order = 0;
                hyp_set_page_refcounted(&p[i]);
        }
index 1cff3259a493191e97475f69449822a59b9bb381..f834833ac9210270ffa5fa860618023c2e73f79f 100644 (file)
@@ -137,6 +137,16 @@ static void *hyp_zalloc_hyp_page(void *arg)
        return hyp_alloc_pages(&hpool, 0);
 }
 
+static void hpool_get_page(void *addr)
+{
+       hyp_get_page(&hpool, addr);
+}
+
+static void hpool_put_page(void *addr)
+{
+       hyp_put_page(&hpool, addr);
+}
+
 void __noreturn __pkvm_init_finalise(void)
 {
        struct kvm_host_data *host_data = this_cpu_ptr(&kvm_host_data);
@@ -160,8 +170,8 @@ void __noreturn __pkvm_init_finalise(void)
                .zalloc_page = hyp_zalloc_hyp_page,
                .phys_to_virt = hyp_phys_to_virt,
                .virt_to_phys = hyp_virt_to_phys,
-               .get_page = hyp_get_page,
-               .put_page = hyp_put_page,
+               .get_page = hpool_get_page,
+               .put_page = hpool_put_page,
        };
        pkvm_pgtable.mm_ops = &pkvm_pgtable_mm_ops;