Merge branch 'android-msm-bullhead-3.10-nyc-mr1' into android-msm-bullhead-3.10-nyc-mr2
April 2017.1
Bug: 34977530
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index 4387624..32640c4 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -15,7 +15,17 @@
#include <uapi/asm/unistd.h>
-#define __NR_syscalls (384)
+/*
+ * This may need to be greater than __NR_last_syscall+1 in order to
+ * account for the padding in the syscall table
+ */
+#define __NR_syscalls (388)
+
+/*
+ * *NOTE*: This is a ghost syscall private to the kernel. Only the
+ * __kuser_cmpxchg code in entry-armv.S should be aware of its
+ * existence. Don't ever use this from user code.
+ */
#define __ARM_NR_cmpxchg (__ARM_NR_BASE+0x00fff0)
#define __ARCH_WANT_STAT64
diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h
index fb5584d..ea1f4a7 100644
--- a/arch/arm/include/uapi/asm/unistd.h
+++ b/arch/arm/include/uapi/asm/unistd.h
@@ -408,11 +408,9 @@
#define __NR_finit_module (__NR_SYSCALL_BASE+379)
#define __NR_sched_setattr (__NR_SYSCALL_BASE+380)
#define __NR_sched_getattr (__NR_SYSCALL_BASE+381)
-
-/*
- * This may need to be greater than __NR_last_syscall+1 in order to
- * account for the padding in the syscall table
- */
+#define __NR_renameat2 (__NR_SYSCALL_BASE+382)
+#define __NR_seccomp (__NR_SYSCALL_BASE+383)
+#define __NR_getrandom (__NR_SYSCALL_BASE+384)
/*
* The following SWIs are ARM private.
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 166e945..8e95c9e 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -391,6 +391,9 @@
CALL(sys_finit_module)
/* 380 */ CALL(sys_sched_setattr)
CALL(sys_sched_getattr)
+ CALL(sys_renameat2)
+ CALL(sys_seccomp)
+ CALL(sys_getrandom)
#ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
#define syscalls_counted
diff --git a/arch/arm64/configs/bullhead_defconfig b/arch/arm64/configs/bullhead_defconfig
index 43c71b6..129c135 100644
--- a/arch/arm64/configs/bullhead_defconfig
+++ b/arch/arm64/configs/bullhead_defconfig
@@ -3,6 +3,7 @@
CONFIG_HIGH_RES_TIMERS=y
CONFIG_IRQ_TIME_ACCOUNTING=y
CONFIG_RCU_FAST_NO_HZ=y
+CONFIG_RCU_BOOST=y
CONFIG_LOG_BUF_SHIFT=20
CONFIG_CGROUPS=y
CONFIG_CGROUP_DEBUG=y
@@ -650,6 +651,7 @@
CONFIG_CRYPTO_NULL=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_DEV_QCRYPTO=y
CONFIG_CRYPTO_DEV_QCE=y
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 7c73059..09d927b 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -44,7 +44,7 @@
#define __ARM_NR_compat_cacheflush (__ARM_NR_COMPAT_BASE+2)
#define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE+5)
-#define __NR_compat_syscalls 384
+#define __NR_compat_syscalls 385
#endif
#define __ARCH_WANT_SYS_CLONE
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index 3910d36..bd80a8c 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -790,4 +790,6 @@
__SYSCALL(__NR_renameat2, sys_ni_syscall)
#define __NR_seccomp 383
__SYSCALL(__NR_seccomp, sys_seccomp)
+#define __NR_getrandom 384
+__SYSCALL(__NR_getrandom, sys_getrandom)
diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl
index 531bb14..fc853fb 100644
--- a/arch/x86/syscalls/syscall_32.tbl
+++ b/arch/x86/syscalls/syscall_32.tbl
@@ -361,3 +361,4 @@
352 i386 sched_getattr sys_sched_getattr
# 353 i386 renameat2 sys_renameat2
354 i386 seccomp sys_seccomp
+355 i386 getrandom sys_getrandom
diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl
index 1c7aebc..c16897e 100644
--- a/arch/x86/syscalls/syscall_64.tbl
+++ b/arch/x86/syscalls/syscall_64.tbl
@@ -324,6 +324,7 @@
315 common sched_getattr sys_sched_getattr
# 316 common renameat2 sys_renameat2
317 common seccomp sys_seccomp
+318 common getrandom sys_getrandom
#
# x32-specific system call numbers start at 512 to avoid cache impact
diff --git a/drivers/char/random.c b/drivers/char/random.c
index b72bcd2..5e94330 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -257,6 +257,8 @@
#include <linux/ptrace.h>
#include <linux/kmemcheck.h>
#include <linux/irq.h>
+#include <linux/syscalls.h>
+#include <linux/completion.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
@@ -405,6 +407,7 @@
*/
static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
+static DECLARE_WAIT_QUEUE_HEAD(urandom_init_wait);
static struct fasync_struct *fasync;
static bool debug;
@@ -612,10 +615,15 @@
if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
goto retry;
- if (!r->initialized && nbits > 0) {
- r->entropy_total += nbits;
- if (r->entropy_total > 128)
- r->initialized = 1;
+ r->entropy_total += nbits;
+ if (!r->initialized && r->entropy_total > 128) {
+ r->initialized = 1;
+ r->entropy_total = 0;
+ if (r == &nonblocking_pool) {
+ prandom_reseed_late();
+ wake_up_all(&urandom_init_wait);
+ pr_notice("random: %s pool is initialized\n", r->name);
+ }
}
trace_credit_entropy_bits(r->name, nbits, entropy_count,
@@ -1023,13 +1031,14 @@
{
ssize_t ret = 0, i;
__u8 tmp[EXTRACT_SIZE];
+ int large_request = (nbytes > 256);
trace_extract_entropy_user(r->name, nbytes, r->entropy_count, _RET_IP_);
xfer_secondary_pool(r, nbytes);
nbytes = account(r, nbytes, 0, 0);
while (nbytes) {
- if (need_resched()) {
+ if (large_request && need_resched()) {
if (signal_pending(current)) {
if (ret == 0)
ret = -ERESTARTSYS;
@@ -1163,7 +1172,7 @@
#endif
static ssize_t
-random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
+_random_read(int nonblock, char __user *buf, size_t nbytes)
{
ssize_t n, retval = 0, count = 0;
@@ -1188,7 +1197,7 @@
n*8, (nbytes-n)*8);
if (n == 0) {
- if (file->f_flags & O_NONBLOCK) {
+ if (nonblock) {
retval = -EAGAIN;
break;
}
@@ -1220,6 +1229,12 @@
}
static ssize_t
+random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
+{
+ return _random_read(file->f_flags & O_NONBLOCK, buf, nbytes);
+}
+
+static ssize_t
urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
{
return extract_entropy_user(&nonblocking_pool, buf, nbytes);
@@ -1345,6 +1360,29 @@
.llseek = noop_llseek,
};
+SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count,
+ unsigned int, flags)
+{
+ if (flags & ~(GRND_NONBLOCK|GRND_RANDOM))
+ return -EINVAL;
+
+ if (count > INT_MAX)
+ count = INT_MAX;
+
+ if (flags & GRND_RANDOM)
+ return _random_read(flags & GRND_NONBLOCK, buf, count);
+
+ if (unlikely(nonblocking_pool.initialized == 0)) {
+ if (flags & GRND_NONBLOCK)
+ return -EAGAIN;
+ wait_event_interruptible(urandom_init_wait,
+ nonblocking_pool.initialized);
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ }
+ return urandom_read(NULL, buf, count, NULL);
+}
+
/***************************************************************
* Random UUID interface
*
diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h
index 188c60a..cb8b388 100644
--- a/drivers/gpu/msm/kgsl.h
+++ b/drivers/gpu/msm/kgsl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -142,6 +142,7 @@
unsigned int gpuaddr;
phys_addr_t physaddr;
size_t size;
+ uint64_t mapsize;
unsigned int priv; /* Internal flags and settings */
struct scatterlist *sg;
unsigned int sglen; /* Active entries in the sglist */
diff --git a/drivers/gpu/msm/kgsl_debugfs.c b/drivers/gpu/msm/kgsl_debugfs.c
index d3c73cc..bba9be7 100644
--- a/drivers/gpu/msm/kgsl_debugfs.c
+++ b/drivers/gpu/msm/kgsl_debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2008-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,2008-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -125,12 +125,12 @@
kgsl_get_memory_usage(usage, sizeof(usage), m->flags);
- seq_printf(s, "%pK %pK %8zd %5d %6s %10s %16s %5d\n",
+ seq_printf(s, "%pK %pK %8zd %5d %6s %10s %16s %5d %16llu\n",
(unsigned long *)(uintptr_t) m->gpuaddr,
(unsigned long *) m->useraddr,
m->size, entry->id, flags,
memtype_str(kgsl_memdesc_usermem_type(m)),
- usage, m->sglen);
+ usage, m->sglen, m->mapsize);
}
static int process_mem_print(struct seq_file *s, void *unused)
@@ -140,9 +140,9 @@
struct kgsl_process_private *private = s->private;
int next = 0;
- seq_printf(s, "%8s %8s %8s %5s %6s %10s %16s %5s\n",
+ seq_printf(s, "%16s %16s %16s %5s %8s %10s %16s %5s %16s\n",
"gpuaddr", "useraddr", "size", "id", "flags", "type",
- "usage", "sglen");
+ "usage", "sglen", "mapsize");
/* print all entries with a GPU address */
spin_lock(&private->mem_lock);
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index a67d775..d8ccf32 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -358,6 +358,8 @@
get_page(page);
vmf->page = page;
+ memdesc->mapsize += PAGE_SIZE;
+
return 0;
}
@@ -505,6 +507,8 @@
else if (ret == -EFAULT)
return VM_FAULT_SIGBUS;
+ memdesc->mapsize += PAGE_SIZE;
+
return VM_FAULT_NOPAGE;
}
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index eae866c..deea682 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -109,6 +109,35 @@
static DEFINE_MUTEX(app_access_lock);
static DEFINE_MUTEX(clk_access_lock);
+struct sglist_info {
+ uint32_t indexAndFlags;
+ uint32_t sizeOrCount;
+};
+
+/*
+ * The 31th bit indicates only one or multiple physical address inside
+ * the request buffer. If it is set, the index locates a single physical addr
+ * inside the request buffer, and `sizeOrCount` is the size of the memory being
+ * shared at that physical address.
+ * Otherwise, the index locates an array of {start, len} pairs (a
+ * "scatter/gather list"), and `sizeOrCount` gives the number of entries in
+ * that array.
+ *
+ * The 30th bit indicates 64 or 32bit address; when it is set, physical addr
+ * and scatter gather entry sizes are 64-bit values. Otherwise, 32-bit values.
+ *
+ * The bits [0:29] of `indexAndFlags` hold an offset into the request buffer.
+ */
+#define SGLISTINFO_SET_INDEX_FLAG(c, s, i) \
+ ((uint32_t)(((c & 1) << 31) | ((s & 1) << 30) | (i & 0x3fffffff)))
+
+#define SGLISTINFO_TABLE_SIZE (sizeof(struct sglist_info) * MAX_ION_FD)
+
+#define FEATURE_ID_WHITELIST 15 /*whitelist feature id*/
+
+#define MAKE_WHITELIST_VERSION(major, minor, patch) \
+ (((major & 0x3FF) << 22) | ((minor & 0x3FF) << 12) | (patch & 0xFFF))
+
struct qseecom_registered_listener_list {
struct list_head list;
struct qseecom_register_listener_req svc;
@@ -120,6 +149,8 @@
wait_queue_head_t rcv_req_wq;
int rcv_req_flag;
+ struct sglist_info sglistinfo_ptr[MAX_ION_FD];
+ uint32_t sglist_cnt;
};
struct qseecom_registered_app_list {
@@ -168,6 +199,7 @@
uint32_t qseos_version;
uint32_t qsee_version;
struct device *pdev;
+ bool whitelist_support;
bool commonlib_loaded;
struct ion_handle *cmnlib_ion_handle;
struct ce_hw_usage_info ce_info;
@@ -223,6 +255,9 @@
bool perf_enabled;
bool fast_load_enabled;
enum qseecom_bandwidth_request_mode mode;
+ struct sglist_info sglistinfo_ptr[MAX_ION_FD];
+ uint32_t sglist_cnt;
+ bool use_legacy_cmd;
};
struct qseecom_sg_entry {
@@ -424,6 +459,21 @@
ret = scm_call2(smc_id, &desc);
break;
}
+ case QSEOS_LISTENER_DATA_RSP_COMMAND_WHITELIST: {
+ struct qseecom_client_listener_data_irsp *req;
+ req = (struct qseecom_client_listener_data_irsp *)
+ req_buf;
+ smc_id =
+ TZ_OS_LISTENER_RESPONSE_HANDLER_WITH_WHITELIST_ID;
+ desc.arginfo =
+ TZ_OS_LISTENER_RESPONSE_HANDLER_WITH_WHITELIST_PARAM_ID;
+ desc.args[0] = req->listener_id;
+ desc.args[1] = req->status;
+ desc.args[2] = req->sglistinfo_ptr;
+ desc.args[3] = req->sglistinfo_len;
+ ret = scm_call2(smc_id, &desc);
+ break;
+ }
case QSEOS_LOAD_EXTERNAL_ELF_COMMAND: {
struct qseecom_load_app_ireq *req;
req = (struct qseecom_load_app_ireq *)req_buf;
@@ -455,6 +505,22 @@
ret = scm_call2(smc_id, &desc);
break;
}
+ case QSEOS_CLIENT_SEND_DATA_COMMAND_WHITELIST: {
+ struct qseecom_client_send_data_ireq *req;
+ req = (struct qseecom_client_send_data_ireq *)req_buf;
+ smc_id = TZ_APP_QSAPP_SEND_DATA_WITH_WHITELIST_ID;
+ desc.arginfo =
+ TZ_APP_QSAPP_SEND_DATA_WITH_WHITELIST_ID_PARAM_ID;
+ desc.args[0] = req->app_id;
+ desc.args[1] = req->req_ptr;
+ desc.args[2] = req->req_len;
+ desc.args[3] = req->rsp_ptr;
+ desc.args[4] = req->rsp_len;
+ desc.args[5] = req->sglistinfo_ptr;
+ desc.args[6] = req->sglistinfo_len;
+ ret = scm_call2(smc_id, &desc);
+ break;
+ }
case QSEOS_RPMB_PROVISION_KEY_COMMAND: {
struct qseecom_client_send_service_ireq *req;
req = (struct qseecom_client_send_service_ireq *)
@@ -565,6 +631,22 @@
ret = scm_call2(smc_id, &desc);
break;
}
+ case QSEOS_TEE_OPEN_SESSION_WHITELIST: {
+ struct qseecom_qteec_ireq *req;
+ req = (struct qseecom_qteec_ireq *)req_buf;
+ smc_id = TZ_APP_GPAPP_OPEN_SESSION_WITH_WHITELIST_ID;
+ desc.arginfo =
+ TZ_APP_GPAPP_OPEN_SESSION_WITH_WHITELIST_ID_PARAM_ID;
+ desc.args[0] = req->app_id;
+ desc.args[1] = req->req_ptr;
+ desc.args[2] = req->req_len;
+ desc.args[3] = req->resp_ptr;
+ desc.args[4] = req->resp_len;
+ desc.args[5] = req->sglistinfo_ptr;
+ desc.args[6] = req->sglistinfo_len;
+ ret = scm_call2(smc_id, &desc);
+ break;
+ }
case QSEOS_TEE_INVOKE_COMMAND: {
struct qseecom_qteec_ireq *req;
req = (struct qseecom_qteec_ireq *)req_buf;
@@ -578,6 +660,22 @@
ret = scm_call2(smc_id, &desc);
break;
}
+ case QSEOS_TEE_INVOKE_COMMAND_WHITELIST: {
+ struct qseecom_qteec_ireq *req;
+ req = (struct qseecom_qteec_ireq *)req_buf;
+ smc_id = TZ_APP_GPAPP_INVOKE_COMMAND_WITH_WHITELIST_ID;
+ desc.arginfo =
+ TZ_APP_GPAPP_INVOKE_COMMAND_WITH_WHITELIST_ID_PARAM_ID;
+ desc.args[0] = req->app_id;
+ desc.args[1] = req->req_ptr;
+ desc.args[2] = req->req_len;
+ desc.args[3] = req->resp_ptr;
+ desc.args[4] = req->resp_len;
+ desc.args[5] = req->sglistinfo_ptr;
+ desc.args[6] = req->sglistinfo_len;
+ ret = scm_call2(smc_id, &desc);
+ break;
+ }
case QSEOS_TEE_CLOSE_SESSION: {
struct qseecom_qteec_ireq *req;
req = (struct qseecom_qteec_ireq *)req_buf;
@@ -758,7 +856,7 @@
return -EBUSY;
}
- new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
+ new_entry = kzalloc(sizeof(*new_entry), GFP_KERNEL);
if (!new_entry) {
pr_err("kmalloc failed\n");
return -ENOMEM;
@@ -1166,6 +1264,16 @@
return ret || data->abort;
}
+static void __qseecom_clean_listener_sglistinfo(
+ struct qseecom_registered_listener_list *ptr_svc)
+{
+ if (ptr_svc->sglist_cnt) {
+ memset(ptr_svc->sglistinfo_ptr, 0,
+ SGLISTINFO_TABLE_SIZE);
+ ptr_svc->sglist_cnt = 0;
+ }
+}
+
static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data,
struct qseecom_command_scm_resp *resp)
{
@@ -1177,6 +1285,7 @@
struct qseecom_registered_listener_list *ptr_svc = NULL;
sigset_t new_sigset;
sigset_t old_sigset;
+ struct sglist_info *table = NULL;
while (resp->result == QSEOS_RESULT_INCOMPLETE) {
lstnr = resp->data;
@@ -1235,8 +1344,21 @@
}
qseecom.send_resp_flag = 0;
- send_data_rsp.qsee_cmd_id = QSEOS_LISTENER_DATA_RSP_COMMAND;
+ table = ptr_svc->sglistinfo_ptr;
+ if (qseecom.whitelist_support == false)
+ send_data_rsp.qsee_cmd_id =
+ QSEOS_LISTENER_DATA_RSP_COMMAND;
+ else
+ send_data_rsp.qsee_cmd_id =
+ QSEOS_LISTENER_DATA_RSP_COMMAND_WHITELIST;
+
send_data_rsp.listener_id = lstnr;
+ send_data_rsp.sglistinfo_ptr =
+ (uint32_t)virt_to_phys(table);
+ send_data_rsp.sglistinfo_len =
+ SGLISTINFO_TABLE_SIZE;
+ dmac_flush_range((void *)table,
+ (void *)table + SGLISTINFO_TABLE_SIZE);
if (ptr_svc)
msm_ion_do_cache_op(qseecom.ion_clnt, ptr_svc->ihandle,
ptr_svc->sb_virt, ptr_svc->sb_length,
@@ -1249,6 +1371,7 @@
(const void *)&send_data_rsp,
sizeof(send_data_rsp), resp,
sizeof(*resp));
+ __qseecom_clean_listener_sglistinfo(ptr_svc);
if (ret) {
pr_err("scm_call() failed with err: %d (app_id = %d)\n",
ret, data->client.app_id);
@@ -1983,12 +2106,13 @@
{
int ret = 0;
u32 reqd_len_sb_in = 0;
- struct qseecom_client_send_data_ireq send_data_req;
+ struct qseecom_client_send_data_ireq send_data_req = {0};
struct qseecom_command_scm_resp resp;
unsigned long flags;
struct qseecom_registered_app_list *ptr_app;
bool found_app = false;
int name_len = 0;
+ struct sglist_info *table = data->sglistinfo_ptr;
reqd_len_sb_in = req->cmd_req_len + req->resp_len;
/* find app_id & img_name from list */
@@ -2012,7 +2136,11 @@
return -EINVAL;
}
- send_data_req.qsee_cmd_id = QSEOS_CLIENT_SEND_DATA_COMMAND;
+ if (qseecom.whitelist_support == false || data->use_legacy_cmd == true)
+ send_data_req.qsee_cmd_id = QSEOS_CLIENT_SEND_DATA_COMMAND;
+ else
+ send_data_req.qsee_cmd_id =
+ QSEOS_CLIENT_SEND_DATA_COMMAND_WHITELIST;
send_data_req.app_id = data->client.app_id;
send_data_req.req_ptr = (uint32_t)(__qseecom_uvirt_to_kphys(data,
(uintptr_t)req->cmd_req_buf));
@@ -2020,6 +2148,11 @@
send_data_req.rsp_ptr = (uint32_t)(__qseecom_uvirt_to_kphys(data,
(uintptr_t)req->resp_buf));
send_data_req.rsp_len = req->resp_len;
+ send_data_req.sglistinfo_ptr =
+ (uint32_t)virt_to_phys(table);
+ send_data_req.sglistinfo_len = SGLISTINFO_TABLE_SIZE;
+ dmac_flush_range((void *)table,
+ (void *)table + SGLISTINFO_TABLE_SIZE);
msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
data->client.sb_virt,
@@ -2115,6 +2248,8 @@
struct qseecom_send_modfd_cmd_req *req = NULL;
struct qseecom_send_modfd_listener_resp *lstnr_resp = NULL;
struct qseecom_registered_listener_list *this_lstnr = NULL;
+ uint32_t offset;
+ struct sg_table *sg_ptr;
if ((data->type != QSEECOM_LISTENER_SERVICE) &&
(data->type != QSEECOM_CLIENT_APP))
@@ -2136,7 +2271,6 @@
}
for (i = 0; i < MAX_ION_FD; i++) {
- struct sg_table *sg_ptr = NULL;
if ((data->type != QSEECOM_LISTENER_SERVICE) &&
(req->ifd_data[i].fd > 0)) {
ihandle = ion_import_dma_buf(qseecom.ion_clnt,
@@ -2232,14 +2366,36 @@
sg = sg_next(sg);
}
}
- if (cleanup)
+ if (cleanup) {
msm_ion_do_cache_op(qseecom.ion_clnt,
ihandle, NULL, len,
ION_IOC_INV_CACHES);
- else
+ } else {
msm_ion_do_cache_op(qseecom.ion_clnt,
ihandle, NULL, len,
ION_IOC_CLEAN_INV_CACHES);
+ if (data->type == QSEECOM_CLIENT_APP) {
+ offset = req->ifd_data[i].cmd_buf_offset;
+ data->sglistinfo_ptr[i].indexAndFlags =
+ SGLISTINFO_SET_INDEX_FLAG(
+ (sg_ptr->nents == 1), 0, offset);
+ data->sglistinfo_ptr[i].sizeOrCount =
+ (sg_ptr->nents == 1) ?
+ sg->length : sg_ptr->nents;
+ data->sglist_cnt = i + 1;
+ } else {
+ offset = (lstnr_resp->ifd_data[i].cmd_buf_offset
+ + (uintptr_t)lstnr_resp->resp_buf_ptr -
+ (uintptr_t)this_lstnr->sb_virt);
+ this_lstnr->sglistinfo_ptr[i].indexAndFlags =
+ SGLISTINFO_SET_INDEX_FLAG(
+ (sg_ptr->nents == 1), 0, offset);
+ this_lstnr->sglistinfo_ptr[i].sizeOrCount =
+ (sg_ptr->nents == 1) ?
+ sg->length : sg_ptr->nents;
+ this_lstnr->sglist_cnt = i + 1;
+ }
+ }
/* Deallocate the handle */
if (!IS_ERR_OR_NULL(ihandle))
ion_free(qseecom.ion_clnt, ihandle);
@@ -3012,8 +3168,11 @@
}
perf_enabled = true;
}
+ if (!strcmp(data->client.app_name, "securemm"))
+ data->use_legacy_cmd = true;
ret = __qseecom_send_cmd(data, &req);
+ data->use_legacy_cmd = false;
if (qseecom.support_bus_scaling)
__qseecom_add_bw_scale_down_timer(
QSEECOM_SEND_CMD_CRYPTO_TIMEOUT);
@@ -4448,14 +4607,23 @@
else
*update = (uint32_t)sg_dma_address(sg_ptr->sgl);
- if (cleanup)
+ if (cleanup) {
msm_ion_do_cache_op(qseecom.ion_clnt,
- ihandle, NULL, sg->length,
- ION_IOC_INV_CACHES);
- else
+ ihandle, NULL, sg->length,
+ ION_IOC_INV_CACHES);
+ } else {
msm_ion_do_cache_op(qseecom.ion_clnt,
- ihandle, NULL, sg->length,
- ION_IOC_CLEAN_INV_CACHES);
+ ihandle, NULL, sg->length,
+ ION_IOC_CLEAN_INV_CACHES);
+ data->sglistinfo_ptr[i].indexAndFlags =
+ SGLISTINFO_SET_INDEX_FLAG(
+ (sg_ptr->nents == 1), 0,
+ req->ifd_data[i].cmd_buf_offset);
+ data->sglistinfo_ptr[i].sizeOrCount =
+ (sg_ptr->nents == 1) ?
+ sg->length : sg_ptr->nents;
+ data->sglist_cnt = i + 1;
+ }
/* Deallocate the handle */
if (!IS_ERR_OR_NULL(ihandle))
ion_free(qseecom.ion_clnt, ihandle);
@@ -4474,18 +4642,11 @@
struct qseecom_qteec_ireq ireq;
int ret = 0;
uint32_t reqd_len_sb_in = 0;
+ struct sglist_info *table = data->sglistinfo_ptr;
ret = __qseecom_qteec_validate_msg(data, req);
if (ret)
return ret;
- ireq.qsee_cmd_id = cmd_id;
- ireq.app_id = data->client.app_id;
- ireq.req_ptr = (uint32_t)__qseecom_uvirt_to_kphys(data,
- (uintptr_t)req->req_ptr);
- ireq.req_len = req->req_len;
- ireq.resp_ptr = (uint32_t)__qseecom_uvirt_to_kphys(data,
- (uintptr_t)req->resp_ptr);
- ireq.resp_len = req->resp_len;
if ((cmd_id == QSEOS_TEE_OPEN_SESSION) ||
(cmd_id == QSEOS_TEE_REQUEST_CANCELLATION)) {
@@ -4494,6 +4655,24 @@
if (ret)
return ret;
}
+
+ if (qseecom.whitelist_support == true
+ && cmd_id == QSEOS_TEE_OPEN_SESSION)
+ ireq.qsee_cmd_id = QSEOS_TEE_OPEN_SESSION_WHITELIST;
+ else
+ ireq.qsee_cmd_id = cmd_id;
+ ireq.app_id = data->client.app_id;
+ ireq.req_ptr = (uint32_t)__qseecom_uvirt_to_kphys(data,
+ (uintptr_t)req->req_ptr);
+ ireq.req_len = req->req_len;
+ ireq.resp_ptr = (uint32_t)__qseecom_uvirt_to_kphys(data,
+ (uintptr_t)req->resp_ptr);
+ ireq.resp_len = req->resp_len;
+ ireq.sglistinfo_ptr = (uint32_t)virt_to_phys(table);
+ ireq.sglistinfo_len = SGLISTINFO_TABLE_SIZE;
+ dmac_flush_range((void *)table,
+ (void *)table + SGLISTINFO_TABLE_SIZE);
+
reqd_len_sb_in = req->req_len + req->resp_len;
msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
data->client.sb_virt,
@@ -4578,6 +4757,9 @@
int ret = 0;
int i = 0;
uint32_t reqd_len_sb_in = 0;
+ struct sglist_info *table = data->sglistinfo_ptr;
+ void *req_ptr = NULL;
+ void *resp_ptr = NULL;
ret = copy_from_user(&req, argp,
sizeof(struct qseecom_qteec_modfd_req));
@@ -4589,16 +4771,8 @@
(struct qseecom_qteec_req *)(&req));
if (ret)
return ret;
-
- ireq.qsee_cmd_id = QSEOS_TEE_INVOKE_COMMAND;
- ireq.app_id = data->client.app_id;
- ireq.req_ptr = (uint32_t)__qseecom_uvirt_to_kphys(data,
- (uintptr_t)req.req_ptr);
- ireq.req_len = req.req_len;
- ireq.resp_ptr = (uint32_t)__qseecom_uvirt_to_kphys(data,
- (uintptr_t)req.resp_ptr);
- ireq.resp_len = req.resp_len;
- reqd_len_sb_in = req.req_len + req.resp_len;
+ req_ptr = req.req_ptr;
+ resp_ptr = req.resp_ptr;
/* validate offsets */
for (i = 0; i < MAX_ION_FD; i++) {
@@ -4614,6 +4788,24 @@
ret = __qseecom_update_qteec_req_buf(&req, data, false);
if (ret)
return ret;
+
+ if (qseecom.whitelist_support == true)
+ ireq.qsee_cmd_id = QSEOS_TEE_INVOKE_COMMAND_WHITELIST;
+ else
+ ireq.qsee_cmd_id = QSEOS_TEE_INVOKE_COMMAND;
+ ireq.app_id = data->client.app_id;
+ ireq.req_ptr = (uint32_t)__qseecom_uvirt_to_kphys(data,
+ (uintptr_t)req_ptr);
+ ireq.req_len = req.req_len;
+ ireq.resp_ptr = (uint32_t)__qseecom_uvirt_to_kphys(data,
+ (uintptr_t)resp_ptr);
+ ireq.resp_len = req.resp_len;
+ ireq.sglistinfo_ptr = (uint32_t)virt_to_phys(table);
+ ireq.sglistinfo_len = SGLISTINFO_TABLE_SIZE;
+ dmac_flush_range((void *)table,
+ (void *)table + SGLISTINFO_TABLE_SIZE);
+ reqd_len_sb_in = req.req_len + req.resp_len;
+
msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
data->client.sb_virt,
reqd_len_sb_in,
@@ -4669,6 +4861,15 @@
return ret;
}
+static void __qseecom_clean_data_sglistinfo(struct qseecom_dev_handle *data)
+{
+ if (data->sglist_cnt) {
+ memset(data->sglistinfo_ptr, 0,
+ SGLISTINFO_TABLE_SIZE);
+ data->sglist_cnt = 0;
+ }
+}
+
long qseecom_ioctl(struct file *file, unsigned cmd, unsigned long arg)
{
int ret = 0;
@@ -4840,6 +5041,7 @@
mutex_unlock(&app_access_lock);
if (ret)
pr_err("failed qseecom_send_cmd: %d\n", ret);
+ __qseecom_clean_data_sglistinfo(data);
break;
}
case QSEECOM_IOCTL_RECEIVE_REQ: {
@@ -5194,6 +5396,7 @@
wake_up_all(&data->abort_wq);
if (ret)
pr_err("failed qseecom_send_mod_resp: %d\n", ret);
+ __qseecom_clean_data_sglistinfo(data);
break;
}
case QSEECOM_QTEEC_IOCTL_OPEN_SESSION_REQ: {
@@ -5218,6 +5421,7 @@
mutex_unlock(&app_access_lock);
if (ret)
pr_err("failed open_session_cmd: %d\n", ret);
+ __qseecom_clean_data_sglistinfo(data);
break;
}
case QSEECOM_QTEEC_IOCTL_CLOSE_SESSION_REQ: {
@@ -5266,6 +5470,7 @@
mutex_unlock(&app_access_lock);
if (ret)
pr_err("failed Invoke cmd: %d\n", ret);
+ __qseecom_clean_data_sglistinfo(data);
break;
}
case QSEECOM_QTEEC_IOCTL_REQUEST_CANCELLATION_REQ: {
@@ -5317,7 +5522,6 @@
data->mode = INACTIVE;
init_waitqueue_head(&data->abort_wq);
atomic_set(&data->ioctl_count, 0);
-
return ret;
}
@@ -5521,6 +5725,17 @@
qclk->instance = CLK_INVALID;
}
+/*
+ * Check whitelist feature, and if TZ feature version is < 1.0.0,
+ * then whitelist feature is not supported.
+ */
+static int qseecom_check_whitelist_feature(void)
+{
+ int version = scm_get_feat_version(FEATURE_ID_WHITELIST);
+
+ return version >= MAKE_WHITELIST_VERSION(1, 0, 0);
+}
+
static int qseecom_probe(struct platform_device *pdev)
{
int rc;
@@ -5556,6 +5771,7 @@
qseecom.ce_ice.ce_core_src_clk = NULL;
qseecom.ce_ice.ce_bus_clk = NULL;
qseecom.ce_ice.clk_access_cnt = 0;
+ qseecom.whitelist_support = true;
rc = alloc_chrdev_region(&qseecom_device_no, 0, 1, QSEECOM_DEV);
if (rc < 0) {
@@ -5831,6 +6047,10 @@
qseecom.qsee_perf_client = msm_bus_scale_register_client(
qseecom_platform_support);
+ qseecom.whitelist_support = qseecom_check_whitelist_feature();
+ pr_warn("qseecom.whitelist_support = %d\n",
+ qseecom.whitelist_support);
+
if (!qseecom.qsee_perf_client)
pr_err("Unable to register bus client\n");
return 0;
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/inc/qwlan_version.h b/drivers/staging/qcacld-2.0/CORE/MAC/inc/qwlan_version.h
index 61b02b0..8d45f31 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/inc/qwlan_version.h
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/inc/qwlan_version.h
@@ -42,9 +42,9 @@
#define QWLAN_VERSION_MINOR 4
#define QWLAN_VERSION_PATCH 23
#define QWLAN_VERSION_EXTRA ""
-#define QWLAN_VERSION_BUILD 13
+#define QWLAN_VERSION_BUILD 14
-#define QWLAN_VERSIONSTR "4.4.23.013s_1"
+#define QWLAN_VERSIONSTR "4.4.23.014"
#define AR6320_REV1_VERSION 0x5000000
diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/if_pci.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/if_pci.c
index 3cfd64e..17792cd 100644
--- a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/if_pci.c
+++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/if_pci.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -2814,9 +2814,12 @@
if (retry > MAX_REG_READ_RETRIES) {
pr_err("%s: PCIe link is possible down!\n", __func__);
- print_config_soc_reg(sc);
- VOS_ASSERT(0);
- break;
+ if (vos_is_logp_in_progress(VOS_MODULE_ID_HIF, NULL))
+ return 0;
+ sc->recovery = true;
+ vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE);
+ vos_wlan_pci_link_down();
+ goto out;
}
A_MDELAY(1);
diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c
index 9ca6049..5c3f06d 100644
--- a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c
+++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c
@@ -35558,20 +35558,12 @@
WMA_LOGE("%s:DFS- Invalid WMA handle", __func__);
return -ENOENT;
}
- radar_event = (struct wma_dfs_radar_indication *)
- vos_mem_malloc(sizeof(struct wma_dfs_radar_indication));
- if (radar_event == NULL)
- {
- WMA_LOGE("%s:DFS- Invalid radar_event", __func__);
- return -ENOENT;
- }
/*
* Do not post multiple Radar events on the same channel.
* But, when DFS test mode is enabled, allow multiple dfs
* radar events to be posted on the same channel.
*/
-
adf_os_spin_lock_bh(&ic->chan_lock);
if (!pmac->sap.SapDfsInfo.disable_dfs_ch_switch)
wma->dfs_ic->disable_phy_err_processing = true;
@@ -35579,6 +35571,13 @@
if ((ichan->ic_ieee != (wma->dfs_ic->last_radar_found_chan)) ||
( pmac->sap.SapDfsInfo.disable_dfs_ch_switch == VOS_TRUE) )
{
+ radar_event = (struct wma_dfs_radar_indication *)
+ vos_mem_malloc(sizeof(*radar_event));
+ if (radar_event == NULL) {
+ WMA_LOGE(FL("Failed to allocate memory for radar_event"));
+ return -ENOMEM;
+ }
+
/* Indicate the radar event to HDD to stop the netif Tx queues*/
hdd_radar_event.ieee_chan_number = ichan->ic_ieee;
hdd_radar_event.chan_freq = ichan->ic_freq;
diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_Trace.c b/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_Trace.c
index 5e95d56..3349175 100644
--- a/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_Trace.c
+++ b/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_Trace.c
@@ -214,28 +214,28 @@
{
switch (pRecord->code) {
case TRACE_CODE_SME_COMMAND:
- smsLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(0x%x)",
+ smsLog(pMac, LOG1, "%04d %012llu S%d %-14s %-30s(0x%x)",
recIndex, pRecord->time, pRecord->session,
"SME COMMAND:",
smeTraceGetCommandString(pRecord->data),
pRecord->data);
break;
case TRACE_CODE_SME_TX_WDA_MSG:
- smsLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(0x%x)",
+ smsLog(pMac, LOG1, "%04d %012llu S%d %-14s %-30s(0x%x)",
recIndex, pRecord->time, pRecord->session,
"TX WDA Msg:",
macTraceGetWdaMsgString((tANI_U16)pRecord->data),
pRecord->data);
break;
case TRACE_CODE_SME_RX_WDA_MSG:
- smsLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(0x%x)",
+ smsLog(pMac, LOG1, "%04d %012llu S%d %-14s %-30s(0x%x)",
recIndex, pRecord->time, pRecord->session,
"RX WDA Msg:",
macTraceGetSmeMsgString((tANI_U16)pRecord->data),
pRecord->data);
break;
default:
- smsLog(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(0x%x)",
+ smsLog(pMac, LOG1, "%04d %012llu S%d %-14s %-30s(0x%x)",
recIndex, pRecord->time, pRecord->session,
"RX HDD MSG:",
smeTraceGetRxMsgString(pRecord->code),
diff --git a/include/linux/random.h b/include/linux/random.h
index 1b91d7d..efec833 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -30,6 +30,7 @@
u32 prandom_u32(void);
void prandom_bytes(void *buf, int nbytes);
void prandom_seed(u32 seed);
+void prandom_reseed_late(void);
u32 prandom_u32_state(struct rnd_state *);
void prandom_bytes_state(struct rnd_state *state, void *buf, int nbytes);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 55b8b74..2825f93 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -872,4 +872,8 @@
asmlinkage long sys_finit_module(int fd, const char __user *uargs, int flags);
asmlinkage long sys_seccomp(unsigned int op, unsigned int flags,
const char __user *uargs);
+
+asmlinkage long sys_getrandom(char __user *buf, size_t count,
+ unsigned int flags);
+
#endif
diff --git a/include/soc/qcom/qseecomi.h b/include/soc/qcom/qseecomi.h
index f380509..9357e02 100644
--- a/include/soc/qcom/qseecomi.h
+++ b/include/soc/qcom/qseecomi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -18,6 +18,7 @@
#define QSEECOM_KEY_ID_SIZE 32
+#define QSEOS_RESULT_FAIL_SEND_CMD_NO_THREAD -19 /*0xFFFFFFED*/
#define QSEOS_RESULT_FAIL_UNSUPPORTED_CE_PIPE -63
#define QSEOS_RESULT_FAIL_KS_OP -64
#define QSEOS_RESULT_FAIL_KEY_ID_EXISTS -65
@@ -61,6 +62,10 @@
QSEOS_TEE_INVOKE_MODFD_COMMAND = QSEOS_TEE_INVOKE_COMMAND,
QSEOS_TEE_CLOSE_SESSION,
QSEOS_TEE_REQUEST_CANCELLATION,
+ QSEOS_CLIENT_SEND_DATA_COMMAND_WHITELIST = 0x1C,
+ QSEOS_TEE_OPEN_SESSION_WHITELIST = 0x1D,
+ QSEOS_TEE_INVOKE_COMMAND_WHITELIST = 0x1E,
+ QSEOS_LISTENER_DATA_RSP_COMMAND_WHITELIST = 0x1F,
QSEOS_FSM_LTE_INIT_DB = 0x100,
QSEOS_FSM_LTE_STORE_KENB = 0x101,
QSEOS_FSM_LTE_GEN_KEYS = 0x102,
@@ -145,6 +150,8 @@
uint32_t req_len;
uint32_t rsp_ptr;/* First 4 bytes should be the return status */
uint32_t rsp_len;
+ uint32_t sglistinfo_ptr;
+ uint32_t sglistinfo_len;
};
__packed struct qseecom_reg_log_buf_ireq {
@@ -158,6 +165,8 @@
uint32_t qsee_cmd_id;
uint32_t listener_id;
uint32_t status;
+ uint32_t sglistinfo_ptr;
+ uint32_t sglistinfo_len;
};
/*
@@ -233,6 +242,8 @@
uint32_t req_len;
uint32_t resp_ptr;
uint32_t resp_len;
+ uint32_t sglistinfo_ptr;
+ uint32_t sglistinfo_len;
};
__packed struct qseecom_client_send_fsm_key_req {
@@ -556,4 +567,45 @@
TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
TZ_SYSCALL_PARAM_TYPE_VAL)
+#define TZ_APP_QSAPP_SEND_DATA_WITH_WHITELIST_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_TZ_APPS, \
+ TZ_SVC_APP_ID_PLACEHOLDER, 0x06)
+
+#define TZ_APP_QSAPP_SEND_DATA_WITH_WHITELIST_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_7( \
+ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+ TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_APP_GPAPP_OPEN_SESSION_WITH_WHITELIST_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_TZ_APPS, \
+ TZ_SVC_APP_ID_PLACEHOLDER, 0x07)
+
+#define TZ_APP_GPAPP_OPEN_SESSION_WITH_WHITELIST_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_7( \
+ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+ TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_APP_GPAPP_INVOKE_COMMAND_WITH_WHITELIST_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_TZ_APPS, \
+ TZ_SVC_APP_ID_PLACEHOLDER, 0x09)
+
+#define TZ_APP_GPAPP_INVOKE_COMMAND_WITH_WHITELIST_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_7( \
+ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
+ TZ_SYSCALL_PARAM_TYPE_VAL)
+
+#define TZ_OS_LISTENER_RESPONSE_HANDLER_WITH_WHITELIST_ID \
+ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x05)
+
+#define TZ_OS_LISTENER_RESPONSE_HANDLER_WITH_WHITELIST_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_4( \
+ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL, \
+ TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
+
#endif /* __QSEECOMI_H_ */
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 2464ed5..0adbef4 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -702,9 +702,11 @@
__SYSCALL(__NR_renameat2, sys_ni_syscall)
#define __NR_seccomp 277
__SYSCALL(__NR_seccomp, sys_seccomp)
+#define __NR_getrandom 278
+__SYSCALL(__NR_getrandom, sys_getrandom)
#undef __NR_syscalls
-#define __NR_syscalls 278
+#define __NR_syscalls 279
/*
* All syscalls below here should go away really,
diff --git a/include/uapi/linux/random.h b/include/uapi/linux/random.h
index 7471b5b..3017239 100644
--- a/include/uapi/linux/random.h
+++ b/include/uapi/linux/random.h
@@ -46,5 +46,13 @@
/* Exported functions */
+/*
+ * Flags for getrandom(2)
+ *
+ * GRND_NONBLOCK Don't block and return EAGAIN instead
+ * GRND_RANDOM Use the /dev/random pool instead of /dev/urandom
+ */
+#define GRND_NONBLOCK 0x0001
+#define GRND_RANDOM 0x0002
#endif /* _UAPI_LINUX_RANDOM_H */
diff --git a/lib/random32.c b/lib/random32.c
index 01e8890..6fb48477 100644
--- a/lib/random32.c
+++ b/lib/random32.c
@@ -38,6 +38,7 @@
#include <linux/export.h>
#include <linux/jiffies.h>
#include <linux/random.h>
+#include <linux/timer.h>
static DEFINE_PER_CPU(struct rnd_state, net_rand_state);
@@ -142,6 +143,7 @@
for_each_possible_cpu (i) {
struct rnd_state *state = &per_cpu(net_rand_state, i);
state->s1 = __seed(state->s1 ^ entropy, 2);
+ prandom_u32_state(state);
}
}
EXPORT_SYMBOL(prandom_seed);
@@ -174,13 +176,43 @@
}
core_initcall(prandom_init);
+static void __prandom_timer(unsigned long dontcare);
+static DEFINE_TIMER(seed_timer, __prandom_timer, 0, 0);
+
+static void __prandom_timer(unsigned long dontcare)
+{
+ u32 entropy;
+
+ get_random_bytes(&entropy, sizeof(entropy));
+ prandom_seed(entropy);
+ /* reseed every ~60 seconds, in [40 .. 80) interval with slack */
+ seed_timer.expires = jiffies + (40 * HZ + (prandom_u32() % (40 * HZ)));
+ add_timer(&seed_timer);
+}
+
+static void prandom_start_seed_timer(void)
+{
+ set_timer_slack(&seed_timer, HZ);
+ seed_timer.expires = jiffies + 40 * HZ;
+ add_timer(&seed_timer);
+}
+
/*
* Generate better values after random number generator
* is fully initialized.
*/
-static int __init prandom_reseed(void)
+static void __prandom_reseed(bool late)
{
int i;
+ unsigned long flags;
+ static bool latch = false;
+ static DEFINE_SPINLOCK(lock);
+
+ /* only allow initial seeding (late == false) once */
+ spin_lock_irqsave(&lock, flags);
+ if (latch && !late)
+ goto out;
+ latch = true;
for_each_possible_cpu(i) {
struct rnd_state *state = &per_cpu(net_rand_state,i);
@@ -194,6 +226,19 @@
/* mix it in */
prandom_u32_state(state);
}
+out:
+ spin_unlock_irqrestore(&lock, flags);
+}
+
+void prandom_reseed_late(void)
+{
+ __prandom_reseed(true);
+}
+
+static int __init prandom_reseed(void)
+{
+ __prandom_reseed(false);
+ prandom_start_seed_timer();
return 0;
}
late_initcall(prandom_reseed);
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index e03754f..fbed856 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.c
@@ -108,7 +108,7 @@
* Invalid voltage range for the detection
* of plug type with current source
*/
-#define WCD9XXX_CS_MEAS_INVALD_RANGE_LOW_MV 110
+#define WCD9XXX_CS_MEAS_INVALD_RANGE_LOW_MV 230
#define WCD9XXX_CS_MEAS_INVALD_RANGE_HIGH_MV 265
/*