summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSunyeal Hong <sunyeal.hong@samsung.com>2016-11-17 20:03:30 +0900
committerSooman Jeong <sm5.jeong@samsung.com>2016-11-29 01:48:46 +0000
commit20a6af298d83f83f89f76712b24afff127c034e6 (patch)
tree76152cd24e3cf276d02ba37b42d0927ae0189295
parent855f77afdc9cefec659460ec87774857632f29c3 (diff)
downloadlinux-artik7-20a6af298d83f83f89f76712b24afff127c034e6.tar.gz
linux-artik7-20a6af298d83f83f89f76712b24afff127c034e6.tar.bz2
linux-artik7-20a6af298d83f83f89f76712b24afff127c034e6.zip
misc: artiktee: release 2.23.1.8
- add support for exporting pfnmap memory. - fixup bug in aarch64 v2p_translation. - hide physical address in user space. Change-Id: Iee2742de36284409f5f5043542b7771286cf1e4c Signed-off-by: Sunyeal Hong <sunyeal.hong@samsung.com>
-rw-r--r--drivers/misc/artiktee/dumpdev_core.c8
-rw-r--r--drivers/misc/artiktee/ssdev_core.c5
-rw-r--r--drivers/misc/artiktee/ssdev_file.c4
-rw-r--r--drivers/misc/artiktee/tzdev_internal.h11
-rw-r--r--drivers/misc/artiktee/tzdev_main.c42
-rw-r--r--drivers/misc/artiktee/tzdev_smc.c9
-rw-r--r--drivers/misc/artiktee/tzdev_smc.h4
-rw-r--r--drivers/misc/artiktee/tzlinkmgr.c3
-rw-r--r--drivers/misc/artiktee/tzlog.c1
-rw-r--r--drivers/misc/artiktee/tzlog_core.c23
-rw-r--r--drivers/misc/artiktee/tzlog_core.h2
-rw-r--r--drivers/misc/artiktee/tzlog_print.c4
-rw-r--r--drivers/misc/artiktee/tzmem.c10
-rw-r--r--drivers/misc/artiktee/tzsys.c5
-rw-r--r--drivers/misc/artiktee/tzwsm.c212
15 files changed, 277 insertions, 66 deletions
diff --git a/drivers/misc/artiktee/dumpdev_core.c b/drivers/misc/artiktee/dumpdev_core.c
index 091039a3be07..80e0b3f73f57 100644
--- a/drivers/misc/artiktee/dumpdev_core.c
+++ b/drivers/misc/artiktee/dumpdev_core.c
@@ -36,7 +36,7 @@ extern uint get_minidump_buf_size(void);
/* TODO : will be remove this declare. and should be share tzsys.c's dump path */
#define ERROR_DUMP_DIR_PATH "/save_error_log/error_log/secureos_dump/"
-static char* get_file_full_path(char *file_name, char *dst_buf, int dst_buf_len)
+static char *get_file_full_path(char *file_name, char *dst_buf, int dst_buf_len)
{
if (file_name == NULL)
return NULL;
@@ -71,8 +71,7 @@ static int copy_to_file_from_ring(
iov[i].iov_len);
break;
}
- }
- else {
+ } else {
if (ss_file_append_object(file_full_path,
iov[i].iov_base,
iov[i].iov_len) != iov[i].iov_len) {
@@ -87,7 +86,6 @@ static int copy_to_file_from_ring(
return n_written;
}
-
void dumpdev_handler(NSRPCTransaction_t *txn_object)
{
int ret = 0;
@@ -100,7 +98,7 @@ void dumpdev_handler(NSRPCTransaction_t *txn_object)
dumpdev_ctrl = (pss_dump_ctrl)nsrpc_payload_ptr(txn_object);
ring_size = get_minidump_buf_size();
- ring = (struct chimera_ring_buffer*)get_minidump_buf();
+ ring = (struct chimera_ring_buffer *)get_minidump_buf();
if (ring == NULL || ring_size == 0) {
tzlog_print(K_ERR, "NSRPC: can not process : ring : %p ring_size : %d\n",
ring, ring_size);
diff --git a/drivers/misc/artiktee/ssdev_core.c b/drivers/misc/artiktee/ssdev_core.c
index eb98f5dc0485..fa8da4754738 100644
--- a/drivers/misc/artiktee/ssdev_core.c
+++ b/drivers/misc/artiktee/ssdev_core.c
@@ -35,7 +35,6 @@
#include "ssdev_file.h"
#include "tzdev.h"
-#include "tzpage.h"
#include "tzdev_internal.h"
#include "tzdev_smc.h"
#include "nsrpc_ree_slave.h"
@@ -394,7 +393,7 @@ static void ssdev_file_create_data(NSRPCTransaction_t *tsx)
int ret;
int file_size;
void *wsm_buffer =
- (char *)ss_wsm_channel.payload + nsrpc_wsm_offset(tsx,
+ (char *)ss_wsm_channel.payload + nsrpc_wsm_offset(tsx,
&wsm_size);
ssdev_filename_create(file_main, sizeof(file_main),
@@ -899,4 +898,4 @@ int libprov_handler(NSRPCTransaction_t *txn_object)
return 0;
}
-#endif
+#endif /* CONFIG_TEE_LIBRARY_PROVISION */
diff --git a/drivers/misc/artiktee/ssdev_file.c b/drivers/misc/artiktee/ssdev_file.c
index 065176153aaf..dc6c5cb48601 100644
--- a/drivers/misc/artiktee/ssdev_file.c
+++ b/drivers/misc/artiktee/ssdev_file.c
@@ -114,6 +114,8 @@ void ss_file_delete_object(char *path)
return;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
if (0)
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0))
+ if (!d_is_file(file_path.dentry))
#else
if (!d_is_file(file_path.dentry)
|| d_really_is_negative(file_path.dentry))
@@ -128,6 +130,8 @@ void ss_file_delete_object(char *path)
if (!IS_ERR(dir)) {
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
err = vfs_unlink(dir->d_inode, file_path.dentry);
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0))
+ err = vfs_unlink(dir->d_inode, file_path.dentry, NULL);
#else
err = vfs_unlink(d_inode(dir), file_path.dentry, NULL);
#endif
diff --git a/drivers/misc/artiktee/tzdev_internal.h b/drivers/misc/artiktee/tzdev_internal.h
index 8c291014d2fb..4bd4b757e2ac 100644
--- a/drivers/misc/artiktee/tzdev_internal.h
+++ b/drivers/misc/artiktee/tzdev_internal.h
@@ -102,6 +102,9 @@ struct secos_kern_info {
/* Secos build type */
char build_type[32];
+
+ /* Secos build info */
+ char build_info[256];
};
#define SECOS_KERN_INFO_V1 (sizeof(struct secos_kern_info))
@@ -133,6 +136,7 @@ void tzio_release_link(struct tzio_link *link);
int tzwsm_register_tzdev_memory(
uint64_t ctx_id,
struct page **pages,
+ phys_addr_t *pfns,
size_t num_pages,
gfp_t gfp,
int for_kernel);
@@ -144,8 +148,15 @@ int tzwsm_register_user_memory(
int rw,
gfp_t gfp,
struct page ***p_pages,
+ phys_addr_t **p_pfns,
size_t *p_num_pages);
void tzwsm_unregister_kernel_memory(int wsmid);
+void tzwsm_unregister_user_memory(
+ int wsmid,
+ struct page **pages,
+ phys_addr_t *pfns,
+ size_t num_pages);
+
#endif /* __SecureOS__ */
#endif /* __SOURCE_TZDEV_TZDEV_INTERNAL_H__ */
diff --git a/drivers/misc/artiktee/tzdev_main.c b/drivers/misc/artiktee/tzdev_main.c
index 44e07877cc56..f19ea3148c1e 100644
--- a/drivers/misc/artiktee/tzdev_main.c
+++ b/drivers/misc/artiktee/tzdev_main.c
@@ -53,7 +53,6 @@
#include "tzdev_init.h"
#include "tzdev_internal.h"
#include "nsrpc_ree_slave.h"
-#include "tzpage.h"
#include "tzdev_smc.h"
#include "tzdev_plat.h"
@@ -1828,8 +1827,6 @@ static int fetch_kernel_info(void)
}
memcpy(&secos_kernel_info, &kinfo, sizeof(kinfo));
- if (kinfo.shmem_base && kinfo.shmem_size)
- tzpage_init(kinfo.shmem_base, kinfo.shmem_size);
return rc;
}
@@ -1843,18 +1840,25 @@ extern struct miscdevice tzrsrc;
#define TZCMA_LLI_TBL_PAGE 4
#define TZCMA_ALLOC_MAX_COUNT 4
#define TZCMA_MAX_SUPPORT_SIZE SZ_4M
+#define TZCMA_UNMMAPED 0
+#define TZCMA_MMAPED 1
static struct device *tzcma_dev;
struct tzcma_info {
int chan_id;
size_t size;
- dma_addr_t phyAddr;
unsigned long virtAddr;
};
-
-static void *tzcma_cpuAddr[TZCMA_ALLOC_MAX_COUNT];
struct tzcma_info g_tzcmas[TZCMA_ALLOC_MAX_COUNT];
struct dma_chan *g_tzcma_channels[TZCMA_ALLOC_MAX_COUNT];
+
+struct tzcma_info_internal {
+ int is_mmaped;
+ dma_addr_t phyAddr;
+ void *cpuAddr;
+};
+static struct tzcma_info_internal g_tzcmas_internal[TZCMA_ALLOC_MAX_COUNT];
+
int g_tzcma_alloc_cnt;
bool g_tzcma_state_opened;
@@ -1879,7 +1883,7 @@ static int tzcma_get_alloc_idx(void)
int i;
for (i = 0; i < TZCMA_ALLOC_MAX_COUNT; i++) {
- if (g_tzcmas[i].phyAddr == 0)
+ if (g_tzcmas_internal[i].phyAddr == 0)
return i;
}
return -1;
@@ -1890,7 +1894,8 @@ static int tzcma_get_free_idx(struct tzcma_info mem)
int i;
for (i = 0; i < TZCMA_ALLOC_MAX_COUNT; i++) {
- if (g_tzcmas[i].phyAddr == mem.phyAddr)
+ if (g_tzcmas[i].chan_id == mem.chan_id
+ && g_tzcmas[i].size == mem.size)
return i;
}
return -1;
@@ -1909,12 +1914,13 @@ static void tzcma_free(int idx)
dma_free_size = round_up(g_tzcmas[idx].size, PAGE_SIZE) +
TZCMA_LLI_TBL_PAGE * PAGE_SIZE;
dma_free_writecombine(tzcma_dev, dma_free_size,
- tzcma_cpuAddr[idx], g_tzcmas[idx].phyAddr);
+ g_tzcmas_internal[idx].cpuAddr, g_tzcmas_internal[idx].phyAddr);
if (g_tzcma_channels[idx] != NULL) {
dma_release_channel(g_tzcma_channels[idx]);
g_tzcma_channels[idx] = NULL;
}
memset(&g_tzcmas[idx], 0, sizeof(struct tzcma_info));
+ memset(&g_tzcmas_internal[idx], 0, sizeof(struct tzcma_info_internal));
}
static int tzcma_alloc(int idx, size_t size)
@@ -1940,8 +1946,9 @@ static int tzcma_alloc(int idx, size_t size)
return -ENOMEM;
}
g_tzcmas[idx].size = size;
- g_tzcmas[idx].phyAddr = phyAddr;
- tzcma_cpuAddr[idx] = cpuAddr;
+ g_tzcmas_internal[idx].is_mmaped = TZCMA_UNMMAPED;
+ g_tzcmas_internal[idx].phyAddr = phyAddr;
+ g_tzcmas_internal[idx].cpuAddr = cpuAddr;
dma_cap_zero(mask);
dma_cap_set(DMA_MEMCPY, mask);
@@ -1968,6 +1975,8 @@ static int tzcma_open(struct inode *inode, struct file *file)
g_tzcma_state_opened = true;
for (i = 0; i < TZCMA_ALLOC_MAX_COUNT; i++) {
memset(&g_tzcmas[i], 0, sizeof(struct tzcma_info));
+ memset(&g_tzcmas_internal[i], 0,
+ sizeof(struct tzcma_info_internal));
g_tzcma_channels[i] = NULL;
}
g_tzcma_alloc_cnt = 0;
@@ -1986,8 +1995,9 @@ static int tzcma_mmap(struct file *file, struct vm_area_struct *vma)
size = vma->vm_end - vma->vm_start;
for (i = 0; i < TZCMA_ALLOC_MAX_COUNT; i++) {
- if ((g_tzcmas[i].phyAddr == vma->vm_start)
+ if ((g_tzcmas_internal[i].is_mmaped == TZCMA_UNMMAPED)
&& (size == round_up(g_tzcmas[i].size, PAGE_SIZE))) {
+ g_tzcmas_internal[i].is_mmaped = TZCMA_MMAPED;
idx = i;
break;
}
@@ -1997,8 +2007,8 @@ static int tzcma_mmap(struct file *file, struct vm_area_struct *vma)
return -ENXIO;
}
- cpu_addr = tzcma_cpuAddr[idx];
- dma_addr = g_tzcmas[idx].phyAddr;
+ cpu_addr = g_tzcmas_internal[idx].cpuAddr;
+ dma_addr = g_tzcmas_internal[idx].phyAddr;
ret = dma_mmap_writecombine(tzcma_dev, vma, cpu_addr, dma_addr, size);
return ret;
@@ -2061,7 +2071,7 @@ static int tzcma_release(struct inode *inode, struct file *file)
int ret = 0;
for (i = 0; i < TZCMA_ALLOC_MAX_COUNT; i++) {
- if (g_tzcmas[i].phyAddr != 0)
+ if (g_tzcmas_internal[i].phyAddr != 0)
tzcma_free(i);
}
g_tzcma_alloc_cnt = 0;
@@ -2242,7 +2252,7 @@ static int __init init_tzdev(void)
wake_up_process(thr);
}
- tzlog_init();
+ tzlog_init(secos_kernel_info.build_info);
plat_init();
diff --git a/drivers/misc/artiktee/tzdev_smc.c b/drivers/misc/artiktee/tzdev_smc.c
index eb5627fffb2f..f93aa72d633e 100644
--- a/drivers/misc/artiktee/tzdev_smc.c
+++ b/drivers/misc/artiktee/tzdev_smc.c
@@ -22,7 +22,6 @@
#include "tzdev.h"
#include "tzdev_internal.h"
#include "tzdev_smc.h"
-#include "tzpage.h"
#include "tzlog_print.h"
#include "tzrsrc_msg.h"
@@ -44,7 +43,7 @@ static DEFINE_PER_CPU(SMC_STATUS, smc_status_each_core);
static void update_smc_status(int cpu, int inout_status, int function_nubmer)
{
- SMC_STATUS * smc_status;
+ SMC_STATUS *smc_status;
smc_status = &per_cpu(smc_status_each_core, cpu);
smc_status->inout_status = inout_status;
@@ -55,7 +54,7 @@ static void update_smc_status(int cpu, int inout_status, int function_nubmer)
else if (inout_status == 1)
do_gettimeofday(&smc_status->smc_out);
- if(inout_status == 1) {
+ if (inout_status == 1) {
struct timeval temp;
unsigned long difftime;
@@ -97,7 +96,7 @@ void init_smc_status(void)
smc_status->smc_out.tv_usec = 0;
}
}
-#endif
+#endif /* CONFIG_TZDEV_DEBUG */
static inline void __do_call_smc_internal(struct monitor_arguments *args,
struct monitor_result *result)
@@ -164,7 +163,7 @@ int smc_init_monitor(void)
do_call_smc_internal(&args, &res, SMC_OP);
if (res.res[0] == -1) {
- tzlog_print(TZLOG_INFO, "Failed to query SecureOS UUID.\n");
+ tzlog_print(TZLOG_ERROR, "Failed to query SecureOS UUID.\n");
return -1;
}
uuid.uuid0 = res.res[0];
diff --git a/drivers/misc/artiktee/tzdev_smc.h b/drivers/misc/artiktee/tzdev_smc.h
index 12399c50c8ed..f5b8f8a98508 100644
--- a/drivers/misc/artiktee/tzdev_smc.h
+++ b/drivers/misc/artiktee/tzdev_smc.h
@@ -22,8 +22,8 @@
#define SMC_STANDARD_CALL 0x00000000
#define SMC_FAST_CALL 0x80000000
-#define SMC_32CALL 0x00000000
-#define SMC_64CALL 0x40000000
+#define SMC_32CALL 0x00000000
+#define SMC_64CALL 0x40000000
#define SMC_ENTITY_MASK 0x3F000000
#define SMC_ENTITY_SHIFT 24
diff --git a/drivers/misc/artiktee/tzlinkmgr.c b/drivers/misc/artiktee/tzlinkmgr.c
index 68e54f4edbb6..3e7136b5c96a 100644
--- a/drivers/misc/artiktee/tzlinkmgr.c
+++ b/drivers/misc/artiktee/tzlinkmgr.c
@@ -20,7 +20,6 @@
#include "circular_buffer.h"
#include "tzdev.h"
#include "tzdev_internal.h"
-#include "tzpage.h"
#include "tzdev_smc.h"
#include "tzlog_print.h"
@@ -48,7 +47,7 @@ static struct tzio_link *tzio_alloc_link(gfp_t gfp)
}
link->mux_link = page_address(link->pg);
- link->id = tzwsm_register_tzdev_memory(0, &link->pg, 1, gfp, 1);
+ link->id = tzwsm_register_tzdev_memory(0, &link->pg, NULL, 1, gfp, 1);
if (link->id < 0) {
tzlog_print(TZLOG_ERROR,
diff --git a/drivers/misc/artiktee/tzlog.c b/drivers/misc/artiktee/tzlog.c
index 6d123735f0eb..055b49132cca 100644
--- a/drivers/misc/artiktee/tzlog.c
+++ b/drivers/misc/artiktee/tzlog.c
@@ -31,7 +31,6 @@
#include "circular_buffer.h"
#include "tzdev.h"
#include "tzdev_internal.h"
-#include "tzpage.h"
#include "tzdev_smc.h"
/*#define CONFIG_INSTANCE_DEBUG*/
diff --git a/drivers/misc/artiktee/tzlog_core.c b/drivers/misc/artiktee/tzlog_core.c
index fcd2fa54f1cd..58b23c88e61e 100644
--- a/drivers/misc/artiktee/tzlog_core.c
+++ b/drivers/misc/artiktee/tzlog_core.c
@@ -32,7 +32,6 @@
#include "circular_buffer.h"
#include "tzdev.h"
#include "tzdev_internal.h"
-#include "tzpage.h"
#include "tzdev_smc.h"
#include "ssdev_file.h"
@@ -110,7 +109,7 @@ static int tzlog_output_to_error_log(char *data, int data_size,
do_gettimeofday(&now);
T = (now.tv_sec * 1000ULL) + (now.tv_usec / 1000LL);
- file_full_path = (char*)vmalloc(PATH_MAX);
+ file_full_path = (char *)vmalloc(PATH_MAX);
if (file_full_path == NULL) {
tzlog_print(K_ERR, "vmalloc failed\n");
ret = -ENOMEM;
@@ -125,7 +124,7 @@ static int tzlog_output_to_error_log(char *data, int data_size,
tzlog_print(K_INFO, "file_full_path-log %s \n", file_full_path);
#if defined(CONFIG_INSTANCE_DEBUG) && defined(CONFIG_USB_DUMP)
- if(ss_file_object_exist(file_full_path) == 1)
+ if (ss_file_object_exist(file_full_path) == 1)
copy_file_to_usb(file_full_path);
else
tzlog_print(K_ERR, "file(%s) not exist \n", file_full_path);
@@ -133,7 +132,7 @@ static int tzlog_output_to_error_log(char *data, int data_size,
exit_tzlog_output_to_error_log:
- if(file_full_path != NULL)
+ if (file_full_path != NULL)
vfree(file_full_path);
return ret;
@@ -253,7 +252,7 @@ void tzlog_notify(void)
up(&log_data.sem);
}
-void __init tzlog_init(void)
+void __init tzlog_init(char *default_msg)
{
int ret;
@@ -277,11 +276,21 @@ void __init tzlog_init(void)
GFP_KERNEL);
tzlog_print(TZLOG_DEBUG, "TZLOG ring at %p\n", log_data.ring);
- if (log_data.ring != NULL)
+ if (log_data.ring != NULL) {
tzlog_print(TZLOG_DEBUG, "ring size %d\n", log_data.ring->size);
+ if (strlen(default_msg) > 0) {
+ chimera_ring_buffer_write(
+ log_data.ring,
+ (const uint8_t *)default_msg,
+ strlen(default_msg),
+ log_data.ring->size +
+ sizeof(struct chimera_ring_buffer));
+ }
+ }
+
log_data.log_wsm_id =
- tzwsm_register_tzdev_memory(0, &log_data.log_page,
+ tzwsm_register_tzdev_memory(0, &log_data.log_page, NULL,
1U << TZLOG_PAGE_ORDER, GFP_KERNEL, 1);
if (log_data.log_wsm_id < 0)
diff --git a/drivers/misc/artiktee/tzlog_core.h b/drivers/misc/artiktee/tzlog_core.h
index 73bdfa4ee86c..7348603f27e2 100644
--- a/drivers/misc/artiktee/tzlog_core.h
+++ b/drivers/misc/artiktee/tzlog_core.h
@@ -40,6 +40,6 @@ typedef struct tzlog_data {
} s_tzlog_data;
void tzlog_notify(void);
-void tzlog_init(void);
+void tzlog_init(char *default_msg);
#endif /* __TZLOG_CORE_H__ */
diff --git a/drivers/misc/artiktee/tzlog_print.c b/drivers/misc/artiktee/tzlog_print.c
index 518d5ceaf5e2..ab78cac38876 100644
--- a/drivers/misc/artiktee/tzlog_print.c
+++ b/drivers/misc/artiktee/tzlog_print.c
@@ -113,6 +113,10 @@ static int tzlog_print_common(
return 0;
}
+/*
+ * will be use bit flag for decreasing parameter count.
+ * we can change log_header_info to use bit flag
+ */
void tzlog_print_for_tee(uint32_t level,
const char *label,
const char *fmt, ...)
diff --git a/drivers/misc/artiktee/tzmem.c b/drivers/misc/artiktee/tzmem.c
index af68f2f8e0e3..68404aa9b403 100644
--- a/drivers/misc/artiktee/tzmem.c
+++ b/drivers/misc/artiktee/tzmem.c
@@ -34,9 +34,7 @@
#include "tzdev_internal.h"
#include "tzlog_print.h"
#include "nsrpc_ree_slave.h"
-#include "tzpage.h"
#include "tzdev_smc.h"
-#include "tzwsm.h"
static int register_user_memory(struct file *owner,
unsigned long base,
@@ -205,6 +203,7 @@ struct tzmem_registration {
int id; /* WSM id */
size_t num_pages; /* Number of pages */
struct page **pages; /* From get_user_pages() */
+ phys_addr_t *pfns;
unsigned long tee_ctx_id; /* TEE context ID */
struct file *owner; /* File which owns this WSM */
};
@@ -219,7 +218,8 @@ static void tzmem_registration_free(struct kref *kref)
node = container_of(kref, struct tzmem_registration, kref);
tzlog_print(TZLOG_DEBUG, "Free WSM %d with ptr %p\n", node->id, node);
- tzwsm_unregister_user_memory(node->id, node->pages, node->num_pages);
+ tzwsm_unregister_user_memory(node->id, node->pages,
+ node->pfns, node->num_pages);
kmem_cache_free(tzmem_registration_slab, node);
}
@@ -314,7 +314,9 @@ static int register_user_memory(struct file *owner,
size,
rw ? VERIFY_WRITE : VERIFY_READ,
GFP_KERNEL,
- &node->pages, &node->num_pages);
+ &node->pages,
+ &node->pfns,
+ &node->num_pages);
if (error < 0) {
tzlog_print(TZLOG_ERROR,
diff --git a/drivers/misc/artiktee/tzsys.c b/drivers/misc/artiktee/tzsys.c
index 286cb13ae147..8639abc6eab2 100644
--- a/drivers/misc/artiktee/tzsys.c
+++ b/drivers/misc/artiktee/tzsys.c
@@ -28,7 +28,6 @@
#include "tzdev.h"
#include "tzdev_internal.h"
-#include "tzpage.h"
#include "tzdev_smc.h"
#include "tzlog_print.h"
#include "ssdev_file.h"
@@ -85,7 +84,7 @@ void __init tzsys_init(void)
tz_syspage = (struct secos_syspage *)page_address(pg);
- memid = tzwsm_register_tzdev_memory(0, &pg, 1, GFP_KERNEL, 1);
+ memid = tzwsm_register_tzdev_memory(0, &pg, NULL, 1, GFP_KERNEL, 1);
BUG_ON(memid < 0);
rc = scm_syscrash_register(memid);
@@ -151,7 +150,7 @@ int tzlog_output_do_dump(int is_kernel)
do_gettimeofday(&now);
T = (now.tv_sec * 1000ULL) + (now.tv_usec / 1000LL);
- file_full_path = (char*)vmalloc(PATH_MAX);
+ file_full_path = (char *)vmalloc(PATH_MAX);
if (file_full_path == NULL) {
tzlog_print(K_ERR, "vmalloc failed\n");
ret = -1;
diff --git a/drivers/misc/artiktee/tzwsm.c b/drivers/misc/artiktee/tzwsm.c
index 8ea20e05b0ee..9c490b5a6484 100644
--- a/drivers/misc/artiktee/tzwsm.c
+++ b/drivers/misc/artiktee/tzwsm.c
@@ -23,13 +23,120 @@
#include <linux/uaccess.h>
#include <linux/slab.h>
#include "tzdev.h"
-#include "tzpage.h"
#include "tzdev_smc.h"
#include "wsm.h"
#include "tzlog_print.h"
+#define ARCH_V2P_ERROR 1
+
+#ifdef __arm__
+#ifdef CONFIG_ARM_LPAE
+static inline phys_addr_t arch_v2p_translate(unsigned long addr, int is_write)
+{
+ phys_addr_t result;
+
+ if (is_write) {
+ __asm__ __volatile__(
+ "MCR p15, 0, %1, c7, c8, 3\n\t"
+ "ISB\n\t"
+ "MRRC p15, 0, %Q0, %R0, c7\n\t"
+ : "=r"(result)
+ : "r"(addr));
+ } else {
+ __asm__ __volatile__(
+ "MCR p15, 0, %1, c7, c8, 2\n\t"
+ "ISB\n\t"
+ "MRRC p15, 0, %Q0, %R0, c7\n\t"
+ : "=r"(result)
+ : "r"(addr));
+ }
+
+ if (result & 1)
+ return ARCH_V2P_ERROR;
+
+ return result & 0x000000FFFFFFF000ULL;
+}
+#else
+static inline phys_addr_t arch_v2p_translate(unsigned long addr, int is_write)
+{
+ uint32_t result;
+
+ if (is_write) {
+ __asm__ __volatile__(
+ "MCR p15, 0, %1, c7, c8, 3\n\t"
+ "ISB\n\t"
+ "MRC p15, 0, %0, c7, c4, 0\n\t"
+ : "=r"(result)
+ : "r"(addr));
+ } else {
+ __asm__ __volatile__(
+ "MCR p15, 0, %1, c7, c8, 2\n\t"
+ "ISB\n\t"
+ "MRC p15, 0, %0, c7, c4, 0\n\t"
+ : "=r"(result)
+ : "r"(addr));
+ }
+
+ if (result & 1)
+ return ARCH_V2P_ERROR;
+
+ /* Supersection */
+ if (result & 2) {
+ return ((phys_addr_t)(result & 0xFF000000)) |
+ (((phys_addr_t)(result & 0x00FF0000)) << 16) |
+ (addr & 0x00FFF000);
+ }
+
+ return result & 0xFFFFF000;
+}
+#endif /* __arm__ */
+#elif defined(__aarch64__)
+static inline phys_addr_t arch_v2p_translate(unsigned long addr, int is_write)
+{
+ phys_addr_t result;
+
+ if (is_write) {
+ __asm__ __volatile__(
+ "AT S1E0W, %1\n\t"
+ "ISB\n\t"
+ "mrs %0, PAR_EL1\n\t"
+ : "=r"(result)
+ : "r"(addr));
+ } else {
+ __asm__ __volatile__(
+ "AT S1E0R, %1\n\t"
+ "ISB\n\t"
+ "mrs %0, PAR_EL1\n\t"
+ : "=r"(result)
+ : "r"(addr));
+ }
+
+ if (result & 1)
+ return ARCH_V2P_ERROR;
+
+ return result & 0x000FFFFFFFFFF000ULL;
+}
+#else /* __aarch64__ */
+#error "Unsupported TLB operation"
+#endif
+
+static inline phys_addr_t v2p_translate(unsigned long addr, int is_write)
+{
+ phys_addr_t phys = arch_v2p_translate(addr, is_write);
+ char c;
+
+ if (phys != ARCH_V2P_ERROR)
+ return phys;
+
+ if (copy_from_user(&c, (const void * __user)addr, sizeof(c)))
+ return ARCH_V2P_ERROR;
+
+ return arch_v2p_translate(addr, is_write);
+}
+
int tzwsm_register_tzdev_memory(uint64_t ctx_id, struct page **pages,
- size_t num_pages, gfp_t gfp, int for_kernel)
+ phys_addr_t *pfns, size_t num_pages,
+ gfp_t gfp, int for_kernel)
{
struct page *level0_page = NULL;
struct page **level1_pages = NULL;
@@ -102,11 +209,12 @@ int tzwsm_register_tzdev_memory(uint64_t ctx_id, struct page **pages,
tzlog_print(TZLOG_DEBUG,
"Level 1 Indirection #%zd Address %llx\n",
- l1index,
+ l1index,
(uint64_t)page_to_phys(level1_pages[l1index]));
for (j = 0; j < level1->num_pfns; ++j, ++i) {
- level1->address[j] = page_to_phys(pages[i]);
+ level1->address[j] = pages ?
+ page_to_phys(pages[i]) : pfns[i];
tzlog_print(TZLOG_DEBUG,
"Page #%zu Address %llx\n", i,
@@ -117,7 +225,8 @@ int tzwsm_register_tzdev_memory(uint64_t ctx_id, struct page **pages,
tzlog_print(TZLOG_DEBUG, "No need for level1 pages\n");
for (i = 0; i < num_pages; ++i) {
- level0->address[i] = page_to_phys(pages[i]);
+ level0->address[i] = pages ?
+ page_to_phys(pages[i]) : pfns[i];
tzlog_print(TZLOG_DEBUG, "Page #%zu Address %llx\n", i,
(uint64_t) level0->address[i]);
@@ -190,7 +299,7 @@ int tzwsm_register_kernel_memory(const void *ptr, size_t size, gfp_t gfp)
}
}
- result = tzwsm_register_tzdev_memory(0, pages, size, gfp, 1);
+ result = tzwsm_register_tzdev_memory(0, pages, NULL, size, gfp, 1);
kfree(pages);
@@ -204,9 +313,11 @@ void tzwsm_unregister_kernel_memory(int wsmid)
int tzwsm_register_user_memory(uint64_t ctx_id, const void *__user ptr,
size_t size, int rw, gfp_t gfp,
- struct page ***p_pages, size_t *p_num_pages)
+ struct page ***p_pages, phys_addr_t **p_pfns,
+ size_t *p_num_pages)
{
struct page **pages;
+ phys_addr_t *pfns = NULL;
size_t num_pages;
int error;
size_t i;
@@ -238,45 +349,112 @@ int tzwsm_register_user_memory(uint64_t ctx_id, const void *__user ptr,
error = get_user_pages_fast(
(unsigned long)ptr_base, num_pages, 0, pages);
+ if (error == -EFAULT) {
+ struct mm_struct *mm;
+ struct vm_area_struct *vma;
+
+ kfree(pages);
+ pages = NULL;
+
+ mm = current->mm;
+ down_read(&mm->mmap_sem);
+ vma = find_vma(mm, ptr_base);
+ if (vma != NULL) {
+ if (vma->vm_flags & (VM_IO | VM_PFNMAP)) {
+ if (ptr_end <= vma->vm_end) {
+ error = 0;
+ } else {
+ tzlog_print(TZLOG_ERROR,
+ "wsm: Pointer to PFNMAP %p must fit same vma\n",
+ ptr);
+ }
+ }
+ }
+ up_read(&mm->mmap_sem);
+
+ if (error == 0) {
+ unsigned long trans_addr;
+ unsigned int index = 0;
+
+ pfns = (phys_addr_t *)kzalloc(
+ sizeof(phys_addr_t) * num_pages, gfp);
+
+ if (!pfns)
+ return -ENOMEM;
+
+ for (trans_addr = ptr_base; trans_addr < ptr_end;
+ trans_addr += PAGE_SIZE) {
+ pfns[index] = v2p_translate(trans_addr,
+ rw == VERIFY_READ ? 0 : 1);
+
+ if (pfns[index] == ARCH_V2P_ERROR) {
+ tzlog_print(TZLOG_ERROR,
+ "Error translating address %p. You must ensure user mapping %p \exists\n",
+ (void *)trans_addr, ptr);
+ error = -EFAULT;
+ break;
+ }
+
+ ++index;
+ }
+
+ if (error == 0)
+ error = num_pages;
+ }
+ }
+
if (error <= 0) {
kfree(pages);
+ kfree(pfns);
return error == 0 ? -EFAULT : error;
}
- if ((size_t) error != num_pages) {
-
- for (i = 0; i < (size_t) error; ++i)
- put_page(pages[i]);
+ if ((size_t)error != num_pages) {
+ if (pages) {
+ for (i = 0; i < (size_t)error; ++i)
+ put_page(pages[i]);
+ }
kfree(pages);
+ kfree(pfns);
+
return -EFAULT;
}
- error = tzwsm_register_tzdev_memory(ctx_id, pages, num_pages, gfp, 0);
+ error = tzwsm_register_tzdev_memory(ctx_id, pages, pfns, num_pages,
+ gfp, 0);
if (error < 0) {
- for (i = 0; i < num_pages; ++i)
- put_page(pages[i]);
+ if (pages) {
+ for (i = 0; i < num_pages; ++i)
+ put_page(pages[i]);
+ }
+ kfree(pfns);
kfree(pages);
+
return error;
}
*p_pages = pages;
*p_num_pages = num_pages;
+ *p_pfns = pfns;
return error;
}
void tzwsm_unregister_user_memory(int wsmid, struct page **pages,
- size_t num_pages)
+ phys_addr_t *pfns, size_t num_pages)
{
size_t i;
scm_unregister_wsm(wsmid);
- for (i = 0; i < num_pages; ++i)
- put_page(pages[i]);
+ if (pages) {
+ for (i = 0; i < num_pages; ++i)
+ put_page(pages[i]);
+ }
kfree(pages);
+ kfree(pfns);
}