Merge tag 'efi_updates_for_v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / firmware / efi / capsule.c
index 598b780..7684302 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/highmem.h>
 #include <linux/efi.h>
 #include <linux/vmalloc.h>
+#include <asm/efi.h>
 #include <asm/io.h>
 
 typedef struct {
@@ -244,7 +245,7 @@ int efi_capsule_update(efi_capsule_header_t *capsule, phys_addr_t *pages)
        for (i = 0; i < sg_count; i++) {
                efi_capsule_block_desc_t *sglist;
 
-               sglist = kmap(sg_pages[i]);
+               sglist = kmap_atomic(sg_pages[i]);
 
                for (j = 0; j < SGLIST_PER_PAGE && count > 0; j++) {
                        u64 sz = min_t(u64, imagesize,
@@ -265,7 +266,18 @@ int efi_capsule_update(efi_capsule_header_t *capsule, phys_addr_t *pages)
                else
                        sglist[j].data = page_to_phys(sg_pages[i + 1]);
 
-               kunmap(sg_pages[i]);
+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
+               /*
+                * At runtime, the firmware has no way to find out where the
+                * sglist elements are mapped, if they are mapped in the first
+                * place. Therefore, on architectures that can only perform
+                * cache maintenance by virtual address, the firmware is unable
+                * to perform this maintenance, and so it is up to the OS to do
+                * it instead.
+                */
+               efi_capsule_flush_cache_range(sglist, PAGE_SIZE);
+#endif
+               kunmap_atomic(sglist);
        }
 
        mutex_lock(&capsule_mutex);