@@ -62,6 +62,34 @@ static struct hyp_page *__find_buddy_avail(struct hyp_pool *pool,
6262
6363}
6464
65+ /*
66+ * Pages that are available for allocation are tracked in free-lists, so we use
67+ * the pages themselves to store the list nodes to avoid wasting space. As the
68+ * allocator always returns zeroed pages (which are zeroed on the hyp_put_page()
69+ * path to optimize allocation speed), we also need to clean-up the list node in
70+ * each page when we take it out of the list.
71+ */
72+ static inline void page_remove_from_list (struct hyp_page * p )
73+ {
74+ struct list_head * node = hyp_page_to_virt (p );
75+
76+ __list_del_entry (node );
77+ memset (node , 0 , sizeof (* node ));
78+ }
79+
80+ static inline void page_add_to_list (struct hyp_page * p , struct list_head * head )
81+ {
82+ struct list_head * node = hyp_page_to_virt (p );
83+
84+ INIT_LIST_HEAD (node );
85+ list_add_tail (node , head );
86+ }
87+
88+ static inline struct hyp_page * node_to_page (struct list_head * node )
89+ {
90+ return hyp_virt_to_page (node );
91+ }
92+
6593static void __hyp_attach_page (struct hyp_pool * pool ,
6694 struct hyp_page * p )
6795{
@@ -83,14 +111,14 @@ static void __hyp_attach_page(struct hyp_pool *pool,
83111 break ;
84112
85113 /* Take the buddy out of its list, and coallesce with @p */
86- list_del_init ( & buddy -> node );
114+ page_remove_from_list ( buddy );
87115 buddy -> order = HYP_NO_ORDER ;
88116 p = min (p , buddy );
89117 }
90118
91119 /* Mark the new head, and insert it */
92120 p -> order = order ;
93- list_add_tail ( & p -> node , & pool -> free_area [order ]);
121+ page_add_to_list ( p , & pool -> free_area [order ]);
94122}
95123
96124static struct hyp_page * __hyp_extract_page (struct hyp_pool * pool ,
@@ -99,7 +127,7 @@ static struct hyp_page *__hyp_extract_page(struct hyp_pool *pool,
99127{
100128 struct hyp_page * buddy ;
101129
102- list_del_init ( & p -> node );
130+ page_remove_from_list ( p );
103131 while (p -> order > order ) {
104132 /*
105133 * The buddy of order n - 1 currently has HYP_NO_ORDER as it
@@ -110,7 +138,7 @@ static struct hyp_page *__hyp_extract_page(struct hyp_pool *pool,
110138 p -> order -- ;
111139 buddy = __find_buddy_nocheck (pool , p , p -> order );
112140 buddy -> order = p -> order ;
113- list_add_tail ( & buddy -> node , & pool -> free_area [buddy -> order ]);
141+ page_add_to_list ( buddy , & pool -> free_area [buddy -> order ]);
114142 }
115143
116144 return p ;
@@ -182,7 +210,7 @@ void *hyp_alloc_pages(struct hyp_pool *pool, unsigned int order)
182210 }
183211
184212 /* Extract it from the tree at the right order */
185- p = list_first_entry ( & pool -> free_area [i ], struct hyp_page , node );
213+ p = node_to_page ( pool -> free_area [i ]. next );
186214 p = __hyp_extract_page (pool , p , order );
187215
188216 hyp_set_page_refcounted (p );
@@ -210,7 +238,6 @@ int hyp_pool_init(struct hyp_pool *pool, u64 pfn, unsigned int nr_pages,
210238 for (i = 0 ; i < nr_pages ; i ++ ) {
211239 p [i ].pool = pool ;
212240 p [i ].order = 0 ;
213- INIT_LIST_HEAD (& p [i ].node );
214241 hyp_set_page_refcounted (& p [i ]);
215242 }
216243
0 commit comments