mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
synced 2026-10-29 13:23:23 +01:00
ARM/efi: Apply strict permissions for UEFI Runtime Services regions
Recent UEFI versions expose permission attributes for runtime services memory regions, either in the UEFI memory map or in the separate memory attributes table. This allows the kernel to map these regions with stricter permissions, rather than the RWX permissions that are used by default. So wire this up in our mapping routine. Signed-off-by: Ard Biesheuvel <[email protected]> Signed-off-by: Matt Fleming <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Leif Lindholm <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Peter Jones <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Russell King <[email protected]> Cc: Sai Praneeth Prakhya <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Will Deacon <[email protected]> Cc: [email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
This commit is contained in:
1 parent
24d45d1dc2
commit
9fc68b717c
2 files changed
+42
No files matched your search
@@ -22,6 +22,7 @@
|
||||
void efi_init(void);
|
||||
|
||||
int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
|
||||
int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
|
||||
|
||||
#define efi_call_virt(f, ...) \
|
||||
({ \
|
||||
|
||||
@@ -11,6 +11,41 @@
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mmu_context.h>
|
||||
|
||||
static int __init set_permissions(pte_t *ptep, pgtable_t token,
|
||||
unsigned long addr, void *data)
|
||||
{
|
||||
efi_memory_desc_t *md = data;
|
||||
pte_t pte = *ptep;
|
||||
|
||||
if (md->attribute & EFI_MEMORY_RO)
|
||||
pte = set_pte_bit(pte, __pgprot(L_PTE_RDONLY));
|
||||
if (md->attribute & EFI_MEMORY_XP)
|
||||
pte = set_pte_bit(pte, __pgprot(L_PTE_XN));
|
||||
set_pte_ext(ptep, pte, PTE_EXT_NG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init efi_set_mapping_permissions(struct mm_struct *mm,
|
||||
efi_memory_desc_t *md)
|
||||
{
|
||||
unsigned long base, size;
|
||||
|
||||
base = md->virt_addr;
|
||||
size = md->num_pages << EFI_PAGE_SHIFT;
|
||||
|
||||
/*
|
||||
* We can only use apply_to_page_range() if we can guarantee that the
|
||||
* entire region was mapped using pages. This should be the case if the
|
||||
* region does not cover any naturally aligned SECTION_SIZE sized
|
||||
* blocks.
|
||||
*/
|
||||
if (round_down(base + size, SECTION_SIZE) <
|
||||
round_up(base, SECTION_SIZE) + SECTION_SIZE)
|
||||
return apply_to_page_range(mm, base, size, set_permissions, md);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
|
||||
{
|
||||
struct map_desc desc = {
|
||||
@@ -34,5 +69,11 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
|
||||
desc.type = MT_DEVICE;
|
||||
|
||||
create_mapping_late(mm, &desc, true);
|
||||
|
||||
/*
|
||||
* If stricter permissions were specified, apply them now.
|
||||
*/
|
||||
if (md->attribute & (EFI_MEMORY_RO | EFI_MEMORY_XP))
|
||||
return efi_set_mapping_permissions(mm, md);
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user