The following commit has been merged into the x86/mm branch of tip: Commit-ID: e1d30a1f6c2196de359ac7c2726ba07fcd389cc4 Gitweb: https://git.kernel.org/tip/e1d30a1f6c2196de359ac7c2726ba07fcd389cc4 Author: Baoquan He <bhe@xxxxxxxxxx> AuthorDate: Fri, 15 Nov 2024 09:21:29 +08:00 Committer: Ingo Molnar <mingo@xxxxxxxxxx> CommitterDate: Fri, 15 Nov 2024 12:03:36 +01:00 x86/ioremap: Introduce helper to check if physical address is in setup_data Functions memremap_is_setup_data() and early_memremap_is_setup_data() share completely the same process and handling, except of the different memremap/unmap invocations. Add helper __memremap_is_setup_data() to extract the common part, parameter 'early' is used to decide what kind of memremap/unmap APIs are called. Signed-off-by: Baoquan He <bhe@xxxxxxxxxx> Signed-off-by: Ingo Molnar <mingo@xxxxxxxxxx> Link: https://lore.kernel.org/r/20241115012131.509226-2-bhe@xxxxxxxxxx --- arch/x86/mm/ioremap.c | 81 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+) diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 8d29163..5ef6182 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -628,6 +628,87 @@ static bool memremap_is_efi_data(resource_size_t phys_addr, return false; } +#define SD_SIZE sizeof(struct setup_data) +/* + * Examine the physical address to determine if it is boot data by checking + * it against the boot params setup_data chain. + */ +static bool __init __memremap_is_setup_data(resource_size_t phys_addr, + bool early) +{ + struct setup_indirect *indirect; + struct setup_data *data; + u64 paddr, paddr_next; + + paddr = boot_params.hdr.setup_data; + while (paddr) { + unsigned int len, size; + + if (phys_addr == paddr) + return true; + + if (early) + data = early_memremap_decrypted(paddr, SD_SIZE); + else + data = memremap(paddr, SD_SIZE, + MEMREMAP_WB | MEMREMAP_DEC); + if (!data) { + pr_warn("failed to memremap setup_data entry\n"); + return false; + } + + size = SD_SIZE; + + paddr_next = data->next; + len = data->len; + + if ((phys_addr > paddr) && + (phys_addr < (paddr + SD_SIZE + len))) { + if (early) + early_memunmap(data, SD_SIZE); + else + memunmap(data); + return true; + } + + if (data->type == SETUP_INDIRECT) { + size += len; + if (early) { + early_memunmap(data, SD_SIZE); + data = early_memremap_decrypted(paddr, size); + } else { + memunmap(data); + data = memremap(paddr, size, + MEMREMAP_WB | MEMREMAP_DEC); + } + if (!data) { + pr_warn("failed to memremap indirect setup_data\n"); + return false; + } + + indirect = (struct setup_indirect *)data->data; + + if (indirect->type != SETUP_INDIRECT) { + paddr = indirect->addr; + len = indirect->len; + } + } + + if (early) + early_memunmap(data, size); + else + memunmap(data); + + if ((phys_addr > paddr) && (phys_addr < (paddr + len))) + return true; + + paddr = paddr_next; + } + + return false; +} +#undef SD_SIZE + /* * Examine the physical address to determine if it is boot data by checking * it against the boot params setup_data chain.