Skip to content

Commit 60863c0

Browse files
committed
efi: Split out EFI memory map functions into new file
Also move the functions from the EFI fake mem driver since future patches will require access to the memmap insertion code even if CONFIG_EFI_FAKE_MEM isn't enabled. This will be useful when we need to build custom EFI memory maps to allow drivers to mark regions as reserved. Tested-by: Dave Young <dyoung@redhat.com> [kexec/kdump] Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> [arm] Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Leif Lindholm <leif.lindholm@linaro.org> Cc: Peter Jones <pjones@redhat.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Taku Izumi <izumi.taku@jp.fujitsu.com> Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
1 parent c8c1a4c commit 60863c0

File tree

5 files changed

+284
-267
lines changed

5 files changed

+284
-267
lines changed

drivers/firmware/efi/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
KASAN_SANITIZE_runtime-wrappers.o := n
1111

1212
obj-$(CONFIG_EFI) += efi.o vars.o reboot.o memattr.o
13-
obj-$(CONFIG_EFI) += capsule.o
13+
obj-$(CONFIG_EFI) += capsule.o memmap.o
1414
obj-$(CONFIG_EFI_VARS) += efivars.o
1515
obj-$(CONFIG_EFI_ESRT) += esrt.o
1616
obj-$(CONFIG_EFI_VARS_PSTORE) += efi-pstore.o

drivers/firmware/efi/efi.c

Lines changed: 0 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -516,135 +516,6 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
516516
return ret;
517517
}
518518

519-
/**
520-
* __efi_memmap_init - Common code for mapping the EFI memory map
521-
* @data: EFI memory map data
522-
* @late: Use early or late mapping function?
523-
*
524-
* This function takes care of figuring out which function to use to
525-
* map the EFI memory map in efi.memmap based on how far into the boot
526-
* we are.
527-
*
528-
* During bootup @late should be %false since we only have access to
529-
* the early_memremap*() functions as the vmalloc space isn't setup.
530-
* Once the kernel is fully booted we can fallback to the more robust
531-
* memremap*() API.
532-
*
533-
* Returns zero on success, a negative error code on failure.
534-
*/
535-
static int __init
536-
__efi_memmap_init(struct efi_memory_map_data *data, bool late)
537-
{
538-
struct efi_memory_map map;
539-
phys_addr_t phys_map;
540-
541-
if (efi_enabled(EFI_PARAVIRT))
542-
return 0;
543-
544-
phys_map = data->phys_map;
545-
546-
if (late)
547-
map.map = memremap(phys_map, data->size, MEMREMAP_WB);
548-
else
549-
map.map = early_memremap(phys_map, data->size);
550-
551-
if (!map.map) {
552-
pr_err("Could not map the memory map!\n");
553-
return -ENOMEM;
554-
}
555-
556-
map.phys_map = data->phys_map;
557-
map.nr_map = data->size / data->desc_size;
558-
map.map_end = map.map + data->size;
559-
560-
map.desc_version = data->desc_version;
561-
map.desc_size = data->desc_size;
562-
map.late = late;
563-
564-
set_bit(EFI_MEMMAP, &efi.flags);
565-
566-
efi.memmap = map;
567-
568-
return 0;
569-
}
570-
571-
/**
572-
* efi_memmap_init_early - Map the EFI memory map data structure
573-
* @data: EFI memory map data
574-
*
575-
* Use early_memremap() to map the passed in EFI memory map and assign
576-
* it to efi.memmap.
577-
*/
578-
int __init efi_memmap_init_early(struct efi_memory_map_data *data)
579-
{
580-
/* Cannot go backwards */
581-
WARN_ON(efi.memmap.late);
582-
583-
return __efi_memmap_init(data, false);
584-
}
585-
586-
void __init efi_memmap_unmap(void)
587-
{
588-
if (!efi.memmap.late) {
589-
unsigned long size;
590-
591-
size = efi.memmap.desc_size * efi.memmap.nr_map;
592-
early_memunmap(efi.memmap.map, size);
593-
} else {
594-
memunmap(efi.memmap.map);
595-
}
596-
597-
efi.memmap.map = NULL;
598-
clear_bit(EFI_MEMMAP, &efi.flags);
599-
}
600-
601-
/**
602-
* efi_memmap_init_late - Map efi.memmap with memremap()
603-
* @phys_addr: Physical address of the new EFI memory map
604-
* @size: Size in bytes of the new EFI memory map
605-
*
606-
* Setup a mapping of the EFI memory map using ioremap_cache(). This
607-
* function should only be called once the vmalloc space has been
608-
* setup and is therefore not suitable for calling during early EFI
609-
* initialise, e.g. in efi_init(). Additionally, it expects
610-
* efi_memmap_init_early() to have already been called.
611-
*
612-
* The reason there are two EFI memmap initialisation
613-
* (efi_memmap_init_early() and this late version) is because the
614-
* early EFI memmap should be explicitly unmapped once EFI
615-
* initialisation is complete as the fixmap space used to map the EFI
616-
* memmap (via early_memremap()) is a scarce resource.
617-
*
618-
* This late mapping is intended to persist for the duration of
619-
* runtime so that things like efi_mem_desc_lookup() and
620-
* efi_mem_attributes() always work.
621-
*
622-
* Returns zero on success, a negative error code on failure.
623-
*/
624-
int __init efi_memmap_init_late(phys_addr_t addr, unsigned long size)
625-
{
626-
struct efi_memory_map_data data = {
627-
.phys_map = addr,
628-
.size = size,
629-
};
630-
631-
/* Did we forget to unmap the early EFI memmap? */
632-
WARN_ON(efi.memmap.map);
633-
634-
/* Were we already called? */
635-
WARN_ON(efi.memmap.late);
636-
637-
/*
638-
* It makes no sense to allow callers to register different
639-
* values for the following fields. Copy them out of the
640-
* existing early EFI memmap.
641-
*/
642-
data.desc_version = efi.memmap.desc_version;
643-
data.desc_size = efi.memmap.desc_size;
644-
645-
return __efi_memmap_init(&data, true);
646-
}
647-
648519
#ifdef CONFIG_EFI_VARS_MODULE
649520
static int __init efi_load_efivars(void)
650521
{

drivers/firmware/efi/fake_mem.c

Lines changed: 6 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,13 @@
3535

3636
#define EFI_MAX_FAKEMEM CONFIG_EFI_MAX_FAKE_MEM
3737

38-
struct fake_mem {
39-
struct range range;
40-
u64 attribute;
41-
};
42-
static struct fake_mem fake_mems[EFI_MAX_FAKEMEM];
38+
static struct efi_mem_range fake_mems[EFI_MAX_FAKEMEM];
4339
static int nr_fake_mem;
4440

4541
static int __init cmp_fake_mem(const void *x1, const void *x2)
4642
{
47-
const struct fake_mem *m1 = x1;
48-
const struct fake_mem *m2 = x2;
43+
const struct efi_mem_range *m1 = x1;
44+
const struct efi_mem_range *m2 = x2;
4945

5046
if (m1->range.start < m2->range.start)
5147
return -1;
@@ -54,133 +50,6 @@ static int __init cmp_fake_mem(const void *x1, const void *x2)
5450
return 0;
5551
}
5652

57-
/**
58-
* efi_fake_memmap_split_count - Count number of additional EFI memmap entries
59-
* @md: EFI memory descriptor to split
60-
* @range: Address range (start, end) to split around
61-
*
62-
* Returns the number of additional EFI memmap entries required to
63-
* accomodate @range.
64-
*/
65-
static int efi_fake_memmap_split_count(efi_memory_desc_t *md, struct range *range)
66-
{
67-
u64 m_start, m_end;
68-
u64 start, end;
69-
int count = 0;
70-
71-
start = md->phys_addr;
72-
end = start + (md->num_pages << EFI_PAGE_SHIFT) - 1;
73-
74-
/* modifying range */
75-
m_start = range->start;
76-
m_end = range->end;
77-
78-
if (m_start <= start) {
79-
/* split into 2 parts */
80-
if (start < m_end && m_end < end)
81-
count++;
82-
}
83-
84-
if (start < m_start && m_start < end) {
85-
/* split into 3 parts */
86-
if (m_end < end)
87-
count += 2;
88-
/* split into 2 parts */
89-
if (end <= m_end)
90-
count++;
91-
}
92-
93-
return count;
94-
}
95-
96-
/**
97-
* efi_fake_memmap_insert - Insert a fake memory region in an EFI memmap
98-
* @old_memmap: The existing EFI memory map structure
99-
* @buf: Address of buffer to store new map
100-
* @mem: Fake memory map entry to insert
101-
*
102-
* It is suggested that you call efi_fake_memmap_split_count() first
103-
* to see how large @buf needs to be.
104-
*/
105-
static void efi_fake_memmap_insert(struct efi_memory_map *old_memmap,
106-
void *buf, struct fake_mem *mem)
107-
{
108-
u64 m_start, m_end, m_attr;
109-
efi_memory_desc_t *md;
110-
u64 start, end;
111-
void *old, *new;
112-
113-
/* modifying range */
114-
m_start = mem->range.start;
115-
m_end = mem->range.end;
116-
m_attr = mem->attribute;
117-
118-
for (old = old_memmap->map, new = buf;
119-
old < old_memmap->map_end;
120-
old += old_memmap->desc_size, new += old_memmap->desc_size) {
121-
122-
/* copy original EFI memory descriptor */
123-
memcpy(new, old, old_memmap->desc_size);
124-
md = new;
125-
start = md->phys_addr;
126-
end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1;
127-
128-
if (m_start <= start && end <= m_end)
129-
md->attribute |= m_attr;
130-
131-
if (m_start <= start &&
132-
(start < m_end && m_end < end)) {
133-
/* first part */
134-
md->attribute |= m_attr;
135-
md->num_pages = (m_end - md->phys_addr + 1) >>
136-
EFI_PAGE_SHIFT;
137-
/* latter part */
138-
new += old_memmap->desc_size;
139-
memcpy(new, old, old_memmap->desc_size);
140-
md = new;
141-
md->phys_addr = m_end + 1;
142-
md->num_pages = (end - md->phys_addr + 1) >>
143-
EFI_PAGE_SHIFT;
144-
}
145-
146-
if ((start < m_start && m_start < end) && m_end < end) {
147-
/* first part */
148-
md->num_pages = (m_start - md->phys_addr) >>
149-
EFI_PAGE_SHIFT;
150-
/* middle part */
151-
new += old_memmap->desc_size;
152-
memcpy(new, old, old_memmap->desc_size);
153-
md = new;
154-
md->attribute |= m_attr;
155-
md->phys_addr = m_start;
156-
md->num_pages = (m_end - m_start + 1) >>
157-
EFI_PAGE_SHIFT;
158-
/* last part */
159-
new += old_memmap->desc_size;
160-
memcpy(new, old, old_memmap->desc_size);
161-
md = new;
162-
md->phys_addr = m_end + 1;
163-
md->num_pages = (end - m_end) >>
164-
EFI_PAGE_SHIFT;
165-
}
166-
167-
if ((start < m_start && m_start < end) &&
168-
(end <= m_end)) {
169-
/* first part */
170-
md->num_pages = (m_start - md->phys_addr) >>
171-
EFI_PAGE_SHIFT;
172-
/* latter part */
173-
new += old_memmap->desc_size;
174-
memcpy(new, old, old_memmap->desc_size);
175-
md = new;
176-
md->phys_addr = m_start;
177-
md->num_pages = (end - md->phys_addr + 1) >>
178-
EFI_PAGE_SHIFT;
179-
md->attribute |= m_attr;
180-
}
181-
}
182-
}
183-
18453
void __init efi_fake_memmap(void)
18554
{
18655
struct efi_memory_map_data data;
@@ -198,7 +67,7 @@ void __init efi_fake_memmap(void)
19867
for_each_efi_memory_desc(md) {
19968
struct range *r = &fake_mems[i].range;
20069

201-
new_nr_map += efi_fake_memmap_split_count(md, r);
70+
new_nr_map += efi_memmap_split_count(md, r);
20271
}
20372
}
20473

@@ -217,7 +86,7 @@ void __init efi_fake_memmap(void)
21786
}
21887

21988
for (i = 0; i < nr_fake_mem; i++)
220-
efi_fake_memmap_insert(&efi.memmap, new_memmap, &fake_mems[i]);
89+
efi_memmap_insert(&efi.memmap, new_memmap, &fake_mems[i]);
22190

22291
/* swap into new EFI memmap */
22392
early_memunmap(new_memmap, efi.memmap.desc_size * new_nr_map);
@@ -265,7 +134,7 @@ static int __init setup_fake_mem(char *p)
265134
p++;
266135
}
267136

268-
sort(fake_mems, nr_fake_mem, sizeof(struct fake_mem),
137+
sort(fake_mems, nr_fake_mem, sizeof(struct efi_mem_range),
269138
cmp_fake_mem, NULL);
270139

271140
for (i = 0; i < nr_fake_mem; i++)

0 commit comments

Comments
 (0)