Re: [PATCH v4 02/11] x86/startup_64: Replace pointer fixups with RIP-relative references

From: Borislav Petkov
Date: Sat Feb 17 2024 - 07:51:47 EST


On Tue, Feb 13, 2024 at 01:41:46PM +0100, Ard Biesheuvel wrote:
> @@ -201,25 +201,19 @@ unsigned long __head __startup_64(unsigned long physaddr,
> load_delta += sme_get_me_mask();
>
> /* Fixup the physical addresses in the page table */
> -
> - pgd = fixup_pointer(early_top_pgt, physaddr);
> - p = pgd + pgd_index(__START_KERNEL_map);
> - if (la57)
> - *p = (unsigned long)level4_kernel_pgt;
> - else
> - *p = (unsigned long)level3_kernel_pgt;
> - *p += _PAGE_TABLE_NOENC - __START_KERNEL_map + load_delta;
> -
> if (la57) {
> - p4d = fixup_pointer(level4_kernel_pgt, physaddr);
> - p4d[511] += load_delta;
> + p4d = (p4dval_t *)&RIP_REL_REF(level4_kernel_pgt);
> + p4d[MAX_PTRS_PER_P4D - 1] += load_delta;
> }
>
> - pud = fixup_pointer(level3_kernel_pgt, physaddr);
> - pud[510] += load_delta;
> - pud[511] += load_delta;
> + pud = &RIP_REL_REF(level3_kernel_pgt)->pud;
> + pud[PTRS_PER_PUD - 2] += load_delta;
> + pud[PTRS_PER_PUD - 1] += load_delta;
> +
> + pgd = &RIP_REL_REF(early_top_pgt)->pgd;

Let's do the pgd assignment above, where it was so that we have that
natural order of p4d -> pgd -> pud ->pmd etc manipulations.

> + pgd[PTRS_PER_PGD - 1] = (pgdval_t)(la57 ? p4d : pud) | _PAGE_TABLE_NOENC;

I see what you mean with pgd_index(__START_KERNEL_map) always being 511
but this:

pgd[pgd_index(__START_KERNEL_map)] = (pgdval_t)(la57 ? p4d : pud) | _PAGE_TABLE_NOENC;

says exactly what gets mapped there in the pagetable while

PTRS_PER_PGD - 1

makes me wonder what's that last pud supposed to map.

Other than that, my gut feeling right now is, this would need extensive
testing so that we make sure there's no fallout from it.

Thx.

--
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette