]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
x86/ioremap: Simplify setup_data mapping variants
authorBaoquan He <bhe@redhat.com>
Sat, 23 Nov 2024 11:42:19 +0000 (19:42 +0800)
committerBorislav Petkov (AMD) <bp@alien8.de>
Sat, 7 Dec 2024 16:23:15 +0000 (17:23 +0100)
memremap_is_setup_data() and early_memremap_is_setup_data() share
completely the same process and handling, except for the differing
memremap/unmap invocations.

Add a helper __memremap_is_setup_data() extracting the common part and
simplify a lot of code while at it.

Mark __memremap_is_setup_data() as __ref to suppress this section
mismatch warning:

  WARNING: modpost: vmlinux: section mismatch in reference: __memremap_is_setup_data+0x5f (section: .text) ->
  early_memunmap (section: .init.text)

  [ bp: Massage a bit. ]

Signed-off-by: Baoquan He <bhe@redhat.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/20241123114221.149383-2-bhe@redhat.com
arch/x86/mm/ioremap.c

index 8d29163568a7458d72a83db85dc18e740b1e68cc..fe44e8180bdd4bdd6f266588a0f515aa138bf96c 100644 (file)
@@ -632,42 +632,54 @@ static bool memremap_is_efi_data(resource_size_t phys_addr,
  * Examine the physical address to determine if it is boot data by checking
  * it against the boot params setup_data chain.
  */
-static bool memremap_is_setup_data(resource_size_t phys_addr,
-                                  unsigned long size)
+static bool __ref __memremap_is_setup_data(resource_size_t phys_addr, bool early)
 {
+       unsigned int setup_data_sz = sizeof(struct setup_data);
        struct setup_indirect *indirect;
        struct setup_data *data;
        u64 paddr, paddr_next;
 
        paddr = boot_params.hdr.setup_data;
        while (paddr) {
-               unsigned int len;
+               unsigned int len, size;
 
                if (phys_addr == paddr)
                        return true;
 
-               data = memremap(paddr, sizeof(*data),
-                               MEMREMAP_WB | MEMREMAP_DEC);
+               if (early)
+                       data = early_memremap_decrypted(paddr, setup_data_sz);
+               else
+                       data = memremap(paddr, setup_data_sz, MEMREMAP_WB | MEMREMAP_DEC);
                if (!data) {
-                       pr_warn("failed to memremap setup_data entry\n");
+                       pr_warn("failed to remap setup_data entry\n");
                        return false;
                }
 
+               size = setup_data_sz;
+
                paddr_next = data->next;
                len = data->len;
 
                if ((phys_addr > paddr) &&
-                   (phys_addr < (paddr + sizeof(struct setup_data) + len))) {
-                       memunmap(data);
+                   (phys_addr < (paddr + setup_data_sz + len))) {
+                       if (early)
+                               early_memunmap(data, setup_data_sz);
+                       else
+                               memunmap(data);
                        return true;
                }
 
                if (data->type == SETUP_INDIRECT) {
-                       memunmap(data);
-                       data = memremap(paddr, sizeof(*data) + len,
-                                       MEMREMAP_WB | MEMREMAP_DEC);
+                       size += len;
+                       if (early) {
+                               early_memunmap(data, setup_data_sz);
+                               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");
+                               pr_warn("failed to remap indirect setup_data\n");
                                return false;
                        }
 
@@ -679,7 +691,10 @@ static bool memremap_is_setup_data(resource_size_t phys_addr,
                        }
                }
 
-               memunmap(data);
+               if (early)
+                       early_memunmap(data, size);
+               else
+                       memunmap(data);
 
                if ((phys_addr > paddr) && (phys_addr < (paddr + len)))
                        return true;
@@ -690,67 +705,16 @@ static bool memremap_is_setup_data(resource_size_t phys_addr,
        return false;
 }
 
-/*
- * Examine the physical address to determine if it is boot data by checking
- * it against the boot params setup_data chain (early boot version).
- */
+static bool memremap_is_setup_data(resource_size_t phys_addr,
+                                  unsigned long size)
+{
+       return __memremap_is_setup_data(phys_addr, false);
+}
+
 static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
                                                unsigned long size)
 {
-       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;
-
-               data = early_memremap_decrypted(paddr, sizeof(*data));
-               if (!data) {
-                       pr_warn("failed to early memremap setup_data entry\n");
-                       return false;
-               }
-
-               size = sizeof(*data);
-
-               paddr_next = data->next;
-               len = data->len;
-
-               if ((phys_addr > paddr) &&
-                   (phys_addr < (paddr + sizeof(struct setup_data) + len))) {
-                       early_memunmap(data, sizeof(*data));
-                       return true;
-               }
-
-               if (data->type == SETUP_INDIRECT) {
-                       size += len;
-                       early_memunmap(data, sizeof(*data));
-                       data = early_memremap_decrypted(paddr, size);
-                       if (!data) {
-                               pr_warn("failed to early memremap indirect setup_data\n");
-                               return false;
-                       }
-
-                       indirect = (struct setup_indirect *)data->data;
-
-                       if (indirect->type != SETUP_INDIRECT) {
-                               paddr = indirect->addr;
-                               len = indirect->len;
-                       }
-               }
-
-               early_memunmap(data, size);
-
-               if ((phys_addr > paddr) && (phys_addr < (paddr + len)))
-                       return true;
-
-               paddr = paddr_next;
-       }
-
-       return false;
+       return __memremap_is_setup_data(phys_addr, true);
 }
 
 /*