Commit c8c1a4c5 authored by Matt Fleming's avatar Matt Fleming

efi/fake_mem: Refactor main two code chunks into functions

There is a whole load of generic EFI memory map code inside of the
fake_mem driver which is better suited to being grouped with the rest
of the generic EFI code for manipulating EFI memory maps.

In preparation for that, this patch refactors the core code, so that
it's possible to move entire functions later.

Tested-by: Dave Young <dyoung@redhat.com> [kexec/kdump]
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> [arm]
Acked-by: default avatarArd 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: default avatarMatt Fleming <matt@codeblueprint.co.uk>
parent dca0f971
...@@ -54,76 +54,77 @@ static int __init cmp_fake_mem(const void *x1, const void *x2) ...@@ -54,76 +54,77 @@ static int __init cmp_fake_mem(const void *x1, const void *x2)
return 0; return 0;
} }
void __init efi_fake_memmap(void) /**
* efi_fake_memmap_split_count - Count number of additional EFI memmap entries
* @md: EFI memory descriptor to split
* @range: Address range (start, end) to split around
*
* Returns the number of additional EFI memmap entries required to
* accomodate @range.
*/
static int efi_fake_memmap_split_count(efi_memory_desc_t *md, struct range *range)
{ {
u64 start, end, m_start, m_end, m_attr; u64 m_start, m_end;
struct efi_memory_map_data data; u64 start, end;
int new_nr_map = efi.memmap.nr_map; int count = 0;
efi_memory_desc_t *md;
phys_addr_t new_memmap_phy;
void *new_memmap;
void *old, *new;
int i;
if (!nr_fake_mem)
return;
/* count up the number of EFI memory descriptor */
for_each_efi_memory_desc(md) {
start = md->phys_addr; start = md->phys_addr;
end = start + (md->num_pages << EFI_PAGE_SHIFT) - 1; end = start + (md->num_pages << EFI_PAGE_SHIFT) - 1;
for (i = 0; i < nr_fake_mem; i++) {
/* modifying range */ /* modifying range */
m_start = fake_mems[i].range.start; m_start = range->start;
m_end = fake_mems[i].range.end; m_end = range->end;
if (m_start <= start) { if (m_start <= start) {
/* split into 2 parts */ /* split into 2 parts */
if (start < m_end && m_end < end) if (start < m_end && m_end < end)
new_nr_map++; count++;
} }
if (start < m_start && m_start < end) { if (start < m_start && m_start < end) {
/* split into 3 parts */ /* split into 3 parts */
if (m_end < end) if (m_end < end)
new_nr_map += 2; count += 2;
/* split into 2 parts */ /* split into 2 parts */
if (end <= m_end) if (end <= m_end)
new_nr_map++; count++;
}
}
} }
/* allocate memory for new EFI memmap */ return count;
new_memmap_phy = memblock_alloc(efi.memmap.desc_size * new_nr_map, }
PAGE_SIZE);
if (!new_memmap_phy)
return;
/* create new EFI memmap */ /**
new_memmap = early_memremap(new_memmap_phy, * efi_fake_memmap_insert - Insert a fake memory region in an EFI memmap
efi.memmap.desc_size * new_nr_map); * @old_memmap: The existing EFI memory map structure
if (!new_memmap) { * @buf: Address of buffer to store new map
memblock_free(new_memmap_phy, efi.memmap.desc_size * new_nr_map); * @mem: Fake memory map entry to insert
return; *
} * It is suggested that you call efi_fake_memmap_split_count() first
* to see how large @buf needs to be.
*/
static void efi_fake_memmap_insert(struct efi_memory_map *old_memmap,
void *buf, struct fake_mem *mem)
{
u64 m_start, m_end, m_attr;
efi_memory_desc_t *md;
u64 start, end;
void *old, *new;
/* modifying range */
m_start = mem->range.start;
m_end = mem->range.end;
m_attr = mem->attribute;
for (old = efi.memmap.map, new = new_memmap; for (old = old_memmap->map, new = buf;
old < efi.memmap.map_end; old < old_memmap->map_end;
old += efi.memmap.desc_size, new += efi.memmap.desc_size) { old += old_memmap->desc_size, new += old_memmap->desc_size) {
/* copy original EFI memory descriptor */ /* copy original EFI memory descriptor */
memcpy(new, old, efi.memmap.desc_size); memcpy(new, old, old_memmap->desc_size);
md = new; md = new;
start = md->phys_addr; start = md->phys_addr;
end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1; end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1;
for (i = 0; i < nr_fake_mem; i++) {
/* modifying range */
m_start = fake_mems[i].range.start;
m_end = fake_mems[i].range.end;
m_attr = fake_mems[i].attribute;
if (m_start <= start && end <= m_end) if (m_start <= start && end <= m_end)
md->attribute |= m_attr; md->attribute |= m_attr;
...@@ -134,8 +135,8 @@ void __init efi_fake_memmap(void) ...@@ -134,8 +135,8 @@ void __init efi_fake_memmap(void)
md->num_pages = (m_end - md->phys_addr + 1) >> md->num_pages = (m_end - md->phys_addr + 1) >>
EFI_PAGE_SHIFT; EFI_PAGE_SHIFT;
/* latter part */ /* latter part */
new += efi.memmap.desc_size; new += old_memmap->desc_size;
memcpy(new, old, efi.memmap.desc_size); memcpy(new, old, old_memmap->desc_size);
md = new; md = new;
md->phys_addr = m_end + 1; md->phys_addr = m_end + 1;
md->num_pages = (end - md->phys_addr + 1) >> md->num_pages = (end - md->phys_addr + 1) >>
...@@ -147,16 +148,16 @@ void __init efi_fake_memmap(void) ...@@ -147,16 +148,16 @@ void __init efi_fake_memmap(void)
md->num_pages = (m_start - md->phys_addr) >> md->num_pages = (m_start - md->phys_addr) >>
EFI_PAGE_SHIFT; EFI_PAGE_SHIFT;
/* middle part */ /* middle part */
new += efi.memmap.desc_size; new += old_memmap->desc_size;
memcpy(new, old, efi.memmap.desc_size); memcpy(new, old, old_memmap->desc_size);
md = new; md = new;
md->attribute |= m_attr; md->attribute |= m_attr;
md->phys_addr = m_start; md->phys_addr = m_start;
md->num_pages = (m_end - m_start + 1) >> md->num_pages = (m_end - m_start + 1) >>
EFI_PAGE_SHIFT; EFI_PAGE_SHIFT;
/* last part */ /* last part */
new += efi.memmap.desc_size; new += old_memmap->desc_size;
memcpy(new, old, efi.memmap.desc_size); memcpy(new, old, old_memmap->desc_size);
md = new; md = new;
md->phys_addr = m_end + 1; md->phys_addr = m_end + 1;
md->num_pages = (end - m_end) >> md->num_pages = (end - m_end) >>
...@@ -169,8 +170,8 @@ void __init efi_fake_memmap(void) ...@@ -169,8 +170,8 @@ void __init efi_fake_memmap(void)
md->num_pages = (m_start - md->phys_addr) >> md->num_pages = (m_start - md->phys_addr) >>
EFI_PAGE_SHIFT; EFI_PAGE_SHIFT;
/* latter part */ /* latter part */
new += efi.memmap.desc_size; new += old_memmap->desc_size;
memcpy(new, old, efi.memmap.desc_size); memcpy(new, old, old_memmap->desc_size);
md = new; md = new;
md->phys_addr = m_start; md->phys_addr = m_start;
md->num_pages = (end - md->phys_addr + 1) >> md->num_pages = (end - md->phys_addr + 1) >>
...@@ -178,8 +179,46 @@ void __init efi_fake_memmap(void) ...@@ -178,8 +179,46 @@ void __init efi_fake_memmap(void)
md->attribute |= m_attr; md->attribute |= m_attr;
} }
} }
}
void __init efi_fake_memmap(void)
{
struct efi_memory_map_data data;
int new_nr_map = efi.memmap.nr_map;
efi_memory_desc_t *md;
phys_addr_t new_memmap_phy;
void *new_memmap;
int i;
if (!nr_fake_mem)
return;
/* count up the number of EFI memory descriptor */
for (i = 0; i < nr_fake_mem; i++) {
for_each_efi_memory_desc(md) {
struct range *r = &fake_mems[i].range;
new_nr_map += efi_fake_memmap_split_count(md, r);
}
}
/* allocate memory for new EFI memmap */
new_memmap_phy = memblock_alloc(efi.memmap.desc_size * new_nr_map,
PAGE_SIZE);
if (!new_memmap_phy)
return;
/* create new EFI memmap */
new_memmap = early_memremap(new_memmap_phy,
efi.memmap.desc_size * new_nr_map);
if (!new_memmap) {
memblock_free(new_memmap_phy, efi.memmap.desc_size * new_nr_map);
return;
} }
for (i = 0; i < nr_fake_mem; i++)
efi_fake_memmap_insert(&efi.memmap, new_memmap, &fake_mems[i]);
/* swap into new EFI memmap */ /* swap into new EFI memmap */
early_memunmap(new_memmap, efi.memmap.desc_size * new_nr_map); early_memunmap(new_memmap, efi.memmap.desc_size * new_nr_map);
efi_memmap_unmap(); efi_memmap_unmap();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment