blob: 28d18cecd53911b830de0020255542df54481ec5 [file] [log] [blame]
/*
* Copyright (C) 2014 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/types.h>
#include <linux/printk.h>
#include <linux/pagemap.h>
#include "ote_protocol.h"
int te_fill_page_info(struct te_oper_param_page_info *pg_inf,
unsigned long start, struct page *page,
struct vm_area_struct *vma)
{
uint64_t mair;
uint64_t pte;
uint8_t memory_type;
uint64_t attr_index;
if (!page || !vma)
return -1;
/* Only support normal memory types. */
if ((vma->vm_page_prot & PTE_ATTRINDX_MASK) !=
PTE_ATTRINDX(MT_NORMAL)) {
pr_err("%s: unsupported memory type: %llx\n", __func__,
vma->vm_page_prot & PTE_ATTRINDX_MASK);
return -1;
}
/*
* Recreate the pte of the page - we can't access it
* safely here race free.
*/
pte = page_to_phys(page);
pte |= pgprot_val(vma->vm_page_prot);
if (vma->vm_flags & VM_WRITE)
pte &= ~PTE_RDONLY;
/* Pull the mt index out of the pte */
attr_index = (pte & PTE_ATTRINDX_MASK) >> 2;
/* Pull the memory attributes out of the mair register. */
asm ("mrs %0, mair_el1\n" : "=&r" (mair));
memory_type = (mair >> (attr_index * 8)) & 0xff;
pg_inf->attr = (pte & 0x0000FFFFFFFFFFFFull) |
((uint64_t)memory_type << 48);
return 0;
}