On 27/04/2026 17:34, Ard Biesheuvel wrote:
> [...]
>
> -void noinstr set_swapper_pgd(pgd_t *pgdp, pgd_t pgd)
> +void noinstr set_rodata_pte(pte_t *ptep, pte_t pte)
>  {
> -     pgd_t *fixmap_pgdp;
> +     pte_t *fixmap_ptep;
>  
>       /*
> -      * Don't bother with the fixmap if swapper_pg_dir is still mapped
> -      * writable in the kernel mapping.
> +      * Don't bother with the fixmap if rodata is still mapped
> +      * writable in the kernel and linear mappings.
>        */
>       if (rodata_is_rw) {
> -             WRITE_ONCE(*pgdp, pgd);
> +             WRITE_ONCE(*ptep, pte);
>               dsb(ishst);
>               isb();
>               return;
>       }
>  
> -     spin_lock(&swapper_pgdir_lock);
> -     fixmap_pgdp = pgd_set_fixmap(__pa_symbol(pgdp));
> -     WRITE_ONCE(*fixmap_pgdp, pgd);
> +     spin_lock(&rodata_pgdir_lock);
> +     fixmap_ptep = pte_set_fixmap(__pa_nodebug(ptep));

I don't know much about the fixmap but it strikes me as odd that we
would now use pte_set_fixmap() at all levels. I suppose the question is
whether swapper_pg_dir could be written concurrently with fixmap page
tables at PMD level or above? I'm also wondering if those fixmap page
tables are ever written to.

- Kevin

> +     WRITE_ONCE(*fixmap_ptep, pte);
>       /*
>        * We need dsb(ishst) here to ensure the page-table-walker sees
>        * our new entry before set_p?d() returns. The fixmap's
>        * flush_tlb_kernel_range() via clear_fixmap() does this for us.
>        */
> -     pgd_clear_fixmap();
> -     spin_unlock(&swapper_pgdir_lock);
> +     pte_clear_fixmap();
> +     spin_unlock(&rodata_pgdir_lock);
>  }
>
> [...]

Reply via email to