[MINI-OS PATCH v2 1/2] mm: provide a way to do very early page table allocations

Juergen Gross posted 2 patches 3 months ago
[MINI-OS PATCH v2 1/2] mm: provide a way to do very early page table allocations
Posted by Juergen Gross 3 months ago
Add a small pool of statically allocated memory pages to be handed out
for very early page table allocations.

This will make it possible to do virtual allocations e.g. for mapping
the shared info page.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
V2:
- add comment (Jan Beulich)
- drop N_PT in favor of ARRAY_SIZE() (Jan Beulich)
- use 2-dimensional array (Jan Beulich)
---
 arch/x86/mm.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/x86/mm.c b/arch/x86/mm.c
index ebc85e0d..fd808884 100644
--- a/arch/x86/mm.c
+++ b/arch/x86/mm.c
@@ -640,13 +640,20 @@ void change_readonly(bool readonly)
 /*
  * return a valid PTE for a given virtual address. If PTE does not exist,
  * allocate page-table pages.
+ * Provide a small pool for allocating some page tables very early. Those are
+ * needed currently for mapping the shared info page, so 2 pages ought to be
+ * enough. Add one spare page anyway.
  */
+static char early_pt[4][PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
+static unsigned int n_early_pt = ARRAY_SIZE(early_pt);
+
 static int need_pgt_func(unsigned long va, unsigned int lvl, bool is_leaf,
                          pgentry_t *pte, void *par)
 {
     pgentry_t **result = par;
     unsigned long pt_mfn;
     unsigned long pt_pfn;
+    unsigned long pt_addr;
     unsigned int idx;
 
     if ( !is_leaf )
@@ -665,7 +672,11 @@ static int need_pgt_func(unsigned long va, unsigned int lvl, bool is_leaf,
     }
 
     pt_mfn = virt_to_mfn(pte);
-    pt_pfn = virt_to_pfn(alloc_page());
+    if ( n_early_pt )
+        pt_addr = (unsigned long)early_pt[--n_early_pt];
+    else
+        pt_addr = alloc_page();
+    pt_pfn = virt_to_pfn(pt_addr);
     if ( !pt_pfn )
         return -1;
     idx = idx_from_va_lvl(va, lvl);
-- 
2.43.0
Re: [MINI-OS PATCH v2 1/2] mm: provide a way to do very early page table allocations
Posted by Jan Beulich 3 months ago
On 29.07.2025 10:38, Juergen Gross wrote:
> --- a/arch/x86/mm.c
> +++ b/arch/x86/mm.c
> @@ -640,13 +640,20 @@ void change_readonly(bool readonly)
>  /*
>   * return a valid PTE for a given virtual address. If PTE does not exist,
>   * allocate page-table pages.
> + * Provide a small pool for allocating some page tables very early. Those are
> + * needed currently for mapping the shared info page, so 2 pages ought to be
> + * enough. Add one spare page anyway.
>   */

Hmm, 2 pages plus one spare doesn't yield ...

> +static char early_pt[4][PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));

... 4. Was 2 a typo, and 3 was meant? (Which, just to mention it, then isn't
correct for 32-bit aiui.) Whatever adjustment wants making - happy to do so
while committing. Just need to know which way. Then
Reviewed-by: Jan Beulich <jbeulich@suse.com>

Jan
Re: [MINI-OS PATCH v2 1/2] mm: provide a way to do very early page table allocations
Posted by Jürgen Groß 3 months ago
On 29.07.25 10:52, Jan Beulich wrote:
> On 29.07.2025 10:38, Juergen Gross wrote:
>> --- a/arch/x86/mm.c
>> +++ b/arch/x86/mm.c
>> @@ -640,13 +640,20 @@ void change_readonly(bool readonly)
>>   /*
>>    * return a valid PTE for a given virtual address. If PTE does not exist,
>>    * allocate page-table pages.
>> + * Provide a small pool for allocating some page tables very early. Those are
>> + * needed currently for mapping the shared info page, so 2 pages ought to be
>> + * enough. Add one spare page anyway.
>>    */
> 
> Hmm, 2 pages plus one spare doesn't yield ...
> 
>> +static char early_pt[4][PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
> 
> ... 4. Was 2 a typo, and 3 was meant? (Which, just to mention it, then isn't
> correct for 32-bit aiui.) Whatever adjustment wants making - happy to do so
> while committing. Just need to know which way. Then
> Reviewed-by: Jan Beulich <jbeulich@suse.com>

Thanks. Should have been 3, of course. And even on 32-bit 3 are enough. :-)


Juergen