Message ID | 20240830130150.8568-6-will@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Support for running as a pKVM protected guest | expand |
On Fri, Aug 30, 2024 at 02:01:48PM +0100, Will Deacon wrote: > @@ -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); I mentioned on the CCA series, the patch is all good but we may need something similar for io_remap_pfn_range() which uses pgprot_decrypted() (I think it mostly matters for the pKVM case).
On Mon, Sep 02, 2024 at 08:08:45PM +0100, Catalin Marinas wrote: > On Fri, Aug 30, 2024 at 02:01:48PM +0100, Will Deacon wrote: > > @@ -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); > > I mentioned on the CCA series, the patch is all good but we may need > something similar for io_remap_pfn_range() which uses > pgprot_decrypted() (I think it mostly matters for the pKVM case). Thanks for pointing this out. We've not needed this on Android yet, but I think that it would be pretty straightforward to add with an arm64 definition of io_remap_pfn_range(). I'd just prefer to leave that until we know that we need it -- in all likelihood a driver would MMIO_GUARD the resources as part of its own ioremap() before remapping into userspace. Will
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h index 41fd90895dfc..1ada23a6ec19 100644 --- a/arch/arm64/include/asm/io.h +++ b/arch/arm64/include/asm/io.h @@ -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 diff --git a/arch/arm64/mm/ioremap.c b/arch/arm64/mm/ioremap.c index 269f2f63ab7d..6cc0b7e7eb03 100644 --- a/arch/arm64/mm/ioremap.c +++ b/arch/arm64/mm/ioremap.c @@ -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);
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. Signed-off-by: Will Deacon <will@kernel.org> --- arch/arm64/include/asm/io.h | 4 ++++ arch/arm64/mm/ioremap.c | 23 ++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-)