]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
arm64: mm: Add confidential computing hook to ioremap_prot()
authorWill Deacon <will@kernel.org>
Fri, 30 Aug 2024 13:01:48 +0000 (14:01 +0100)
committerWill Deacon <will@kernel.org>
Fri, 30 Aug 2024 15:30:41 +0000 (16:30 +0100)
Confidential Computing environments such as pKVM and Arm's CCA
distinguish between shared (i.e. emulated) and private (i.e. assigned)
MMIO regions.

Introduce a hook into our implementation of ioremap_prot() so that MMIO
regions can be shared if necessary.

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Acked-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20240830130150.8568-6-will@kernel.org
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/include/asm/io.h
arch/arm64/mm/ioremap.c

index 41fd90895dfc3d0fcdf9810680d5f2a64bc113f1..1ada23a6ec19004e2396f63f16f518d109710831 100644 (file)
@@ -271,6 +271,10 @@ __iowrite64_copy(void __iomem *to, const void *from, size_t count)
  * I/O memory mapping functions.
  */
 
+typedef int (*ioremap_prot_hook_t)(phys_addr_t phys_addr, size_t size,
+                                  pgprot_t *prot);
+int arm64_ioremap_prot_hook_register(const ioremap_prot_hook_t hook);
+
 #define ioremap_prot ioremap_prot
 
 #define _PAGE_IOREMAP PROT_DEVICE_nGnRE
index 269f2f63ab7dc4c1d3dccf3f6831ea47abdb3477..6cc0b7e7eb0384b991dd59ce18ea2a476cb20958 100644 (file)
@@ -3,10 +3,22 @@
 #include <linux/mm.h>
 #include <linux/io.h>
 
+static ioremap_prot_hook_t ioremap_prot_hook;
+
+int arm64_ioremap_prot_hook_register(ioremap_prot_hook_t hook)
+{
+       if (WARN_ON(ioremap_prot_hook))
+               return -EBUSY;
+
+       ioremap_prot_hook = hook;
+       return 0;
+}
+
 void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size,
                           unsigned long prot)
 {
        unsigned long last_addr = phys_addr + size - 1;
+       pgprot_t pgprot = __pgprot(prot);
 
        /* Don't allow outside PHYS_MASK */
        if (last_addr & ~PHYS_MASK)
@@ -16,7 +28,16 @@ void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size,
        if (WARN_ON(pfn_is_map_memory(__phys_to_pfn(phys_addr))))
                return NULL;
 
-       return generic_ioremap_prot(phys_addr, size, __pgprot(prot));
+       /*
+        * If a hook is registered (e.g. for confidential computing
+        * purposes), call that now and barf if it fails.
+        */
+       if (unlikely(ioremap_prot_hook) &&
+           WARN_ON(ioremap_prot_hook(phys_addr, size, &pgprot))) {
+               return NULL;
+       }
+
+       return generic_ioremap_prot(phys_addr, size, pgprot);
 }
 EXPORT_SYMBOL(ioremap_prot);