diff mbox series

[RFC,v2,17/22] resource: Mark encrypted MMIO resource on validation

Message ID 20250218111017.491719-18-aik@amd.com
State New
Headers show
Series [RFC,v2,01/22] pci/doe: Define protocol types and make those public | expand

Commit Message

Alexey Kardashevskiy Feb. 18, 2025, 11:10 a.m. UTC
In order to allow encrypted MMIO, a TDISP device needs to have it set up
as "TEE" (means "trusted") and the platform needs to allow accessing it
as encrypted (which is "pvalidate"'ed in AMD terms).

Once TDISP MMIO validation succeeded, a resource needs to be mapped as
encrypted or the device will reject it.

Add encrypt_resource() which marks the resource as "validated".
The TSM module is going to call this API.

Modify __ioremap_check_encrypted() to look for the new flag to allow
ioremap() correctly map encrypted resources.

Signed-off-by: Alexey Kardashevskiy <aik@amd.com>
---

Should it also be IORESOURCE_BUSY?
---
 include/linux/ioport.h |  2 +
 arch/x86/mm/ioremap.c  |  2 +
 kernel/resource.c      | 48 ++++++++++++++++++++
 3 files changed, 52 insertions(+)
diff mbox series

Patch

diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 5385349f0b8a..f2e0b9f02373 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -55,6 +55,7 @@  struct resource {
 #define IORESOURCE_MEM_64	0x00100000
 #define IORESOURCE_WINDOW	0x00200000	/* forwarded by bridge */
 #define IORESOURCE_MUXED	0x00400000	/* Resource is software muxed */
+#define IORESOURCE_VALIDATED	0x00800000	/* TDISP validated */
 
 #define IORESOURCE_EXT_TYPE_BITS 0x01000000	/* Resource extended types */
 #define IORESOURCE_SYSRAM	0x01000000	/* System RAM (modifier) */
@@ -248,6 +249,7 @@  extern int allocate_resource(struct resource *root, struct resource *new,
 struct resource *lookup_resource(struct resource *root, resource_size_t start);
 int adjust_resource(struct resource *res, resource_size_t start,
 		    resource_size_t size);
+int encrypt_resource(struct resource *res, unsigned int flags);
 resource_size_t resource_alignment(struct resource *res);
 
 /**
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 38ff7791a9c7..748f39af127a 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -100,6 +100,8 @@  static unsigned int __ioremap_check_encrypted(struct resource *res)
 	switch (res->desc) {
 	case IORES_DESC_NONE:
 	case IORES_DESC_RESERVED:
+		if (res->flags & IORESOURCE_VALIDATED)
+			return IORES_MAP_ENCRYPTED;
 		break;
 	default:
 		return IORES_MAP_ENCRYPTED;
diff --git a/kernel/resource.c b/kernel/resource.c
index 12004452d999..c5a80da58033 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -503,6 +503,13 @@  int walk_mem_res(u64 start, u64 end, void *arg,
 {
 	unsigned long flags = IORESOURCE_MEM | IORESOURCE_BUSY;
 
+	int ret =  __walk_iomem_res_desc(start, end, flags, IORES_DESC_NONE, arg,
+				     func);
+	if (ret < 0)
+		return ret;
+
+	flags = IORESOURCE_MEM | IORESOURCE_VALIDATED;
+
 	return __walk_iomem_res_desc(start, end, flags, IORES_DESC_NONE, arg,
 				     func);
 }
@@ -1085,6 +1092,47 @@  int adjust_resource(struct resource *res, resource_size_t start,
 }
 EXPORT_SYMBOL(adjust_resource);
 
+int encrypt_resource(struct resource *res, unsigned int flags)
+{
+	struct resource *p;
+	int result = 0;
+
+	if (!res)
+		return -EINVAL;
+
+	write_lock(&resource_lock);
+
+	for_each_resource(&iomem_resource, p, false) {
+		/* If we passed the resource we are looking for, stop */
+		if (p->start > res->end) {
+			p = NULL;
+			break;
+		}
+
+		/* Skip until we find a range that matches what we look for */
+		if (p->end < res->start)
+			continue;
+
+		if (p->start == res->start && p->end == res->end) {
+			if ((p->flags & res->flags) != res->flags)
+				p = NULL;
+			break;
+		}
+	}
+
+	if (p) {
+		p->flags = (p->flags & ~(IORESOURCE_VALIDATED)) | flags;
+		res->flags = (res->flags & ~(IORESOURCE_VALIDATED)) | flags;
+	} else {
+		result = -EINVAL;
+	}
+
+	write_unlock(&resource_lock);
+
+	return result;
+}
+EXPORT_SYMBOL(encrypt_resource);
+
 static void __init
 __reserve_region_with_split(struct resource *root, resource_size_t start,
 			    resource_size_t end, const char *name)