@@ -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);
/**
@@ -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;
@@ -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)
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(+)