On Tue, Nov 16 2021 at 10:47, Ard Biesheuvel wrote: > The kmap_local conversion broke the ARM architecture, because the new > code assumes that all PTEs used for creating kmaps form a linear array > in memory, and uses array indexing to look up the kmap PTE belonging to > a certain kmap index. > > On ARM, this cannot work, not only because the PTE pages may be > non-adjacent in memory, but also because ARM/!LPAE interleaves hardware > entries and extended entries (carrying software-only bits) in a way that > is not compatible with array indexing. > > Fortunately, this only seems to affect configurations with more than 8 > CPUs, due to the way the per-CPU kmap slots are organized in memory. Ooops. I completely missed that detail. Sorry for the wreckage. > Work around this by permitting an architecture to set a Kconfig symbol > that signifies that the kmap PTEs do not form a lineary array in memory, > and so the only way to locate the appropriate one is to walk the page > tables. > +static pte_t *kmap_get_pte(unsigned long vaddr, int idx) > { > + if (IS_ENABLED(CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY)) > + /* > + * Set by the arch if __kmap_pte[-idx] does not produce > + * the correct entry. > + */ > + return virt_to_kpte(vaddr); Nit. The above is not a one line statement (even if it is from a compiler perspective). /* * Does the architecture have non-linear KMAP pte entries which * cannot be accessed by index? */ if (IS_ENABLED(CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY)) return virt_to_kpte(vaddr); or if (IS_ENABLED(CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY)) { /* PTE entries cannot be accessed by index. */ return virt_to_kpte(vaddr); } are readable but this is really breaking the brain OCR: if (IS_ENABLED(CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY)) /* * Set by the arch if __kmap_pte[-idx] does not produce * the correct entry. */ return virt_to_kpte(vaddr); if (!__kmap_pte) Other than that. Reviewed-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>