Messages in this thread Patch in this message | | | Subject | [PATCH 1/1] drivers/char/mem.c: Disable encryption bit in page tables for, MMIO access | From | James Puthukattukaran <> | Date | Thu, 4 Oct 2018 13:18:58 -0400 |
| |
Attempting to mmap to a memory mapped IO space returns -1s because the memory encryption bit is set for these pages. According to the AMD spec, this bit should not be set for non-DRAM space. The patch checks if this is an memory IO region being accessed and decrypts accordingly.
Signed-off-by: James Puthukattukaran<james.puthukattukaran@oracle.com> --- drivers/char/mem.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index ffeb60d..beaa374 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -355,10 +355,30 @@ static inline int private_mapping_ok(struct vm_area_struct *vma) #endif }; +static int check_flags(struct resource *res, void *arg) +{ + int *mmio = arg; + *mmio = (!((res->flags & IORESOURCE_SYSTEM_RAM) == + IORESOURCE_SYSTEM_RAM) && (res->desc == IORES_DESC_NONE)); + return *mmio; +} + +static void check_iomem_region(phys_addr_t addr, size_t size, + int *mmio) +{ + u64 start, end; + + start = (u64)addr; + end = start + size - 1; + *mmio = 0; + walk_mem_res(start, end, mmio, check_flags); +} + static int mmap_mem(struct file *file, struct vm_area_struct *vma) { size_t size = vma->vm_end - vma->vm_start; phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT; + int mmio; /* Does it even fit in phys_addr_t? */ if (offset >> PAGE_SHIFT != vma->vm_pgoff) @@ -387,6 +407,13 @@ static int mmap_mem(struct file *file, struct vm_area_struct *vma) vma->vm_ops = &mmap_mem_ops; + if (mem_encrypt_active()) { + check_iomem_region(vma->vm_pgoff, size, &mmio); + if (mmio) + vma->vm_page_prot = + pgprot_decrypted(vma->vm_page_prot); + } + /* Remap-pfn-range will mark the range VM_IO */ if (remap_pfn_range(vma, vma->vm_start,
| |