Re: [PATCH] x86: EFI runtime code mapping enhancement

From: Huang, Ying
Date: Wed Feb 13 2008 - 20:45:46 EST


On Wed, 2008-02-13 at 12:32 +0100, Andi Kleen wrote:
> Huang, Ying wrote:
> > This patch enhances EFI runtime code memory mapping as following:
> >
> > - Move __supported_pte_mask & _PAGE_NX checking before invoking
> > runtime_code_page_mkexec(). This makes it possible for compiler to
> > eliminate runtime_code_page_mkexec() on machine without NX support.
> >
> > - Use set_memory_x/nx in early_mapping_set_exec(). This eliminates the
> > duplicated implementation.
>
> It's a inefficiency because you split up the 2MB (or 1GB) pages
> in the direct mapping, although that is not strictly needed. This
> means everybody who happens to use memory in same 2M/1G region
> will eat unnecessary TLB misses.
>
> It would be generally better to only execute your code in
> ioremap_cache() because that won't affect anybody else.
>
> Eventually set_memory_x() will work correctly for ioremap() too
> so that should work then.

For EFI runtime service in virtual mode, using direct mapping is mainly
for kexec, where EFI runtime memory area need to be mapped at same
virtual address across kexec. For performance reason, it may be better
to use fixmap only instead. But this will waste some fixmap space.

But this patch is for EFI runtime service in physical mode (in 64 mode,
this needs a direct mapping page table), there are two choice.

- Use direct mapping of kernel, clean NX bit from kernel page table
temporarily before/after EFI calling. This needs not split 2M page into
4K pages, because the region changed is aligned with 2M. And, because
the changing is temporary, a little larger region is not a big issue.

- Construct a direct mapping page table for EFI only. I think this is
not good too. The code will be duplicated with kernel page table
initialization code.


An issue of this patch is that it does not work with 1G page. Aligning
EFI runtime code region with 1G seems not a good idea too. I think a
better method is adding a non-split mode to c_p_a(), where the region
changed is enlarged if necessary to avoid page allocation. This can be
used to implement early_set_memory_xx(). The early_set_memory_xx()
instead of duplicated c_p_a() variant can be used by EFI code.

Best Regards,
Huang Ying

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/