blob: a5367aeacb755f3a1a6fff8257bdba4542b2a831 [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
*/
#include <linux/kernel.h>
#include <soc/qcom/secure_buffer.h>
#include <linux/arm-smmu-errata.h>
static struct page *guard_pages[VMID_LAST];
static DEFINE_MUTEX(guard_page_lock);
struct page *arm_smmu_errata_get_guard_page(int vmid)
{
struct page *page;
int ret;
int source_vm = VMID_HLOS;
int dest_vm = vmid;
int dest_perm = PERM_READ | PERM_WRITE | PERM_EXEC;
size_t size = ARM_SMMU_MIN_IOVA_ALIGN;
mutex_lock(&guard_page_lock);
page = guard_pages[vmid];
if (page)
goto out;
page = alloc_pages(GFP_KERNEL, get_order(size));
if (!page)
goto out;
if (vmid != VMID_HLOS) {
ret = hyp_assign_phys(page_to_phys(page), PAGE_ALIGN(size),
&source_vm, 1,
&dest_vm, &dest_perm, 1);
if (ret) {
__free_pages(page, get_order(size));
page = NULL;
}
}
guard_pages[vmid] = page;
out:
mutex_unlock(&guard_page_lock);
return page;
}