aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Pfetsch <spfetsch@google.com>2017-10-12 19:41:38 -0700
committerSteve Pfetsch <spfetsch@google.com>2017-10-12 19:41:38 -0700
commit33ace82f84ba203ceb58b2c28a0f2e3389870030 (patch)
tree2fe60ab39b8266a3de8b4feabd47490d6d7bd56f
parent6ba119257516c87a577993487c0b5aaa1ab0c0a1 (diff)
parente40328e12f0eee2436cdfa83aa519e3c490daf62 (diff)
Merge branch 'android-msm-angler-3.10-oc' into android-msm-angler-3.10android-o-mr1-preview-2_r0.1android-8.1.0_r0.1
December 2017.1 Bug: 67749245 Change-Id: I3cc87859f6679d5c91a622d101a172f2a0598520
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile3
-rw-r--r--drivers/char/diag/diag_dci.c38
-rw-r--r--drivers/char/diag/diagchar_core.c96
-rw-r--r--drivers/coresight/coresight-tmc.c33
-rw-r--r--drivers/gud/Kconfig31
-rw-r--r--drivers/gud/Makefile40
-rw-r--r--drivers/gud/MobiCoreDriver/Makefile31
-rw-r--r--drivers/gud/MobiCoreDriver/api.c119
-rw-r--r--drivers/gud/MobiCoreDriver/arm.h87
-rw-r--r--drivers/gud/MobiCoreDriver/build.sh28
-rw-r--r--drivers/gud/MobiCoreDriver/debug.h64
-rw-r--r--drivers/gud/MobiCoreDriver/fastcall.h255
-rw-r--r--drivers/gud/MobiCoreDriver/logging.c375
-rw-r--r--drivers/gud/MobiCoreDriver/logging.h30
-rw-r--r--drivers/gud/MobiCoreDriver/main.c1595
-rw-r--r--drivers/gud/MobiCoreDriver/main.h152
-rw-r--r--drivers/gud/MobiCoreDriver/mem.c764
-rw-r--r--drivers/gud/MobiCoreDriver/mem.h142
-rw-r--r--drivers/gud/MobiCoreDriver/ops.c421
-rw-r--r--drivers/gud/MobiCoreDriver/ops.h37
-rw-r--r--drivers/gud/MobiCoreDriver/platforms/MSM8960_SURF_STD/platform.h122
-rw-r--r--drivers/gud/MobiCoreDriver/pm.c291
-rw-r--r--drivers/gud/MobiCoreDriver/pm.h47
-rw-r--r--drivers/gud/MobiCoreDriver/public/mc_kernel_api.h88
-rw-r--r--drivers/gud/MobiCoreDriver/public/mc_linux.h207
-rw-r--r--drivers/gud/MobiCoreDriver/public/version.h21
-rw-r--r--drivers/gud/MobiCoreKernelApi/Makefile73
-rw-r--r--drivers/gud/MobiCoreKernelApi/build.sh34
-rw-r--r--drivers/gud/MobiCoreKernelApi/clientlib.c1068
-rw-r--r--drivers/gud/MobiCoreKernelApi/common.h80
-rw-r--r--drivers/gud/MobiCoreKernelApi/connection.c203
-rw-r--r--drivers/gud/MobiCoreKernelApi/connection.h61
-rw-r--r--drivers/gud/MobiCoreKernelApi/device.c233
-rw-r--r--drivers/gud/MobiCoreKernelApi/device.h63
-rw-r--r--drivers/gud/MobiCoreKernelApi/include/mcinq.h104
-rw-r--r--drivers/gud/MobiCoreKernelApi/include/mcuuid.h24
-rw-r--r--drivers/gud/MobiCoreKernelApi/main.c190
-rw-r--r--drivers/gud/MobiCoreKernelApi/public/mobicore_driver_api.h399
-rw-r--r--drivers/gud/MobiCoreKernelApi/public/mobicore_driver_cmd.h250
-rw-r--r--drivers/gud/MobiCoreKernelApi/session.c208
-rw-r--r--drivers/gud/MobiCoreKernelApi/session.h146
-rw-r--r--drivers/gud/MobiCoreKernelApi/wsm.h30
-rw-r--r--drivers/gud/README6
-rw-r--r--drivers/gud/build_tag.h15
-rw-r--r--drivers/gud/setupDrivers.sh19
-rw-r--r--drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c27
-rw-r--r--drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.h1
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c2
-rw-r--r--drivers/media/platform/msm/vidc/msm_v4l2_vidc.c5
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc.c1
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_debug.c245
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_debug.h3
-rw-r--r--drivers/media/v4l2-core/v4l2-compat-ioctl32.c602
-rw-r--r--drivers/misc/qseecom.c14
-rw-r--r--drivers/platform/msm/ipa/ipa_qmi_service.c47
-rw-r--r--drivers/platform/msm/ipa/ipa_qmi_service.h6
-rw-r--r--drivers/platform/msm/ipa/rmnet_ipa.c4
-rw-r--r--[-rwxr-xr-x]drivers/power/reset/msm-poweroff.c4
-rw-r--r--drivers/scsi/sg.c3
-rwxr-xr-xdrivers/staging/android/ion/ion.c2
-rw-r--r--drivers/video/msm/mdss/mdss_hdmi_edid.c21
-rw-r--r--drivers/video/msm/mdss/mdss_mdp_overlay.c5
-rw-r--r--fs/dcache.c37
-rw-r--r--fs/debugfs/inode.c10
-rw-r--r--fs/namei.c8
-rw-r--r--fs/notify/fsnotify.c8
-rw-r--r--include/linux/dcache.h7
-rw-r--r--include/linux/fsnotify.h31
-rw-r--r--net/bluetooth/bnep/core.c4
-rw-r--r--net/bluetooth/cmtp/core.c3
-rw-r--r--sound/core/timer.c296
-rw-r--r--sound/soc/msm/qdsp6v2/audio_cal_utils.c2
73 files changed, 997 insertions, 8726 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 69c7c1c99fbf..7cee566fad87 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -172,8 +172,6 @@ source "drivers/irqchip/Kconfig"
source "drivers/ipack/Kconfig"
-source "drivers/gud/Kconfig"
-
source "drivers/reset/Kconfig"
source "drivers/coresight/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 1e45a0a5cafa..3f56ff9e6fbf 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -159,9 +159,6 @@ obj-$(CONFIG_VME_BUS) += vme/
obj-$(CONFIG_IPACK_BUS) += ipack/
obj-$(CONFIG_NTB) += ntb/
-#MobiCore
-obj-$(CONFIG_MOBICORE_SUPPORT) += gud/
-
obj-$(CONFIG_CORESIGHT) += coresight/
obj-$(CONFIG_ESOC) += esoc/
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index 80a46020c5bf..c5c7b4325991 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, 2017 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
@@ -342,6 +342,7 @@ void diag_dci_wakeup_clients()
struct list_head *start, *temp;
struct diag_dci_client_tbl *entry = NULL;
+ mutex_lock(&driver->dci_mutex);
list_for_each_safe(start, temp, &driver->dci_client_list) {
entry = list_entry(start, struct diag_dci_client_tbl, track);
@@ -357,6 +358,7 @@ void diag_dci_wakeup_clients()
DCI_DATA_TYPE);
}
}
+ mutex_unlock(&driver->dci_mutex);
}
void dci_data_drain_work_fn(struct work_struct *work)
@@ -367,6 +369,7 @@ void dci_data_drain_work_fn(struct work_struct *work)
struct diag_dci_buf_peripheral_t *proc_buf = NULL;
struct diag_dci_buffer_t *buf_temp = NULL;
+ mutex_lock(&driver->dci_mutex);
list_for_each_safe(start, temp, &driver->dci_client_list) {
entry = list_entry(start, struct diag_dci_client_tbl, track);
for (i = 0; i < entry->num_buffers; i++) {
@@ -396,6 +399,7 @@ void dci_data_drain_work_fn(struct work_struct *work)
DCI_DATA_TYPE);
}
}
+ mutex_unlock(&driver->dci_mutex);
dci_timer_in_progress = 0;
}
@@ -561,6 +565,8 @@ start:
buf += header_len + dci_pkt_len; /* advance to next DCI pkt */
}
end:
+ if (err)
+ return err;
/* wake up all sleeping DCI clients which have some data */
diag_dci_wakeup_clients();
dci_check_drain_timer();
@@ -621,6 +627,8 @@ int diag_process_smd_dci_read_data(struct diag_smd_info *smd_info, void *buf,
buf += 5 + dci_pkt_len; /* advance to next DCI pkt */
}
+ if (err)
+ return err;
/* wake up all sleeping DCI clients which have some data */
diag_dci_wakeup_clients();
dci_check_drain_timer();
@@ -967,9 +975,11 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
return;
}
+ mutex_lock(&driver->dci_mutex);
req_entry = diag_dci_get_request_entry(tag);
if (!req_entry) {
- pr_err("diag: No matching client for DCI data\n");
+ pr_err_ratelimited("diag: No matching client for DCI data\n");
+ mutex_unlock(&driver->dci_mutex);
return;
}
@@ -977,18 +987,17 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
if (!entry) {
pr_err("diag: In %s, couldn't find client entry, id:%d\n",
__func__, req_entry->client_id);
+ mutex_unlock(&driver->dci_mutex);
return;
}
save_req_uid = req_entry->uid;
/* Remove the headers and send only the response to this function */
- mutex_lock(&driver->dci_mutex);
delete_flag = diag_dci_remove_req_entry(temp, rsp_len, req_entry);
if (delete_flag < 0) {
mutex_unlock(&driver->dci_mutex);
return;
}
- mutex_unlock(&driver->dci_mutex);
rsp_buf = entry->buffers[data_source].buf_cmd;
@@ -1006,6 +1015,7 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
if (!temp_buf) {
pr_err("diag: DCI realloc failed\n");
mutex_unlock(&rsp_buf->data_mutex);
+ mutex_unlock(&driver->dci_mutex);
return;
} else {
rsp_buf->data = temp_buf;
@@ -1041,6 +1051,7 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
* for log and event buffers to be full
*/
dci_add_buffer_to_list(entry, rsp_buf);
+ mutex_unlock(&driver->dci_mutex);
}
static void copy_dci_event(unsigned char *buf, int len,
@@ -1176,6 +1187,7 @@ void extract_dci_events(unsigned char *buf, int len, int data_source, int token)
the event data */
total_event_len = 2 + 10 + payload_len_field + payload_len;
/* parse through event mask tbl of each client and check mask */
+ mutex_lock(&driver->dci_mutex);
list_for_each_safe(start, temp, &driver->dci_client_list) {
entry = list_entry(start, struct diag_dci_client_tbl,
track);
@@ -1187,6 +1199,7 @@ void extract_dci_events(unsigned char *buf, int len, int data_source, int token)
entry, data_source);
}
}
+ mutex_unlock(&driver->dci_mutex);
}
}
@@ -1278,6 +1291,7 @@ void extract_dci_log(unsigned char *buf, int len, int data_source, int token)
}
/* parse through log mask table of each client and check mask */
+ mutex_lock(&driver->dci_mutex);
list_for_each_safe(start, temp, &driver->dci_client_list) {
entry = list_entry(start, struct diag_dci_client_tbl, track);
if (entry->client_info.token != token)
@@ -1289,6 +1303,7 @@ void extract_dci_log(unsigned char *buf, int len, int data_source, int token)
copy_dci_log(buf, len, entry, data_source);
}
}
+ mutex_unlock(&driver->dci_mutex);
}
void diag_update_smd_dci_work_fn(struct work_struct *work)
@@ -1312,6 +1327,7 @@ void diag_update_smd_dci_work_fn(struct work_struct *work)
* which log entries in the cumulative logs that need
* to be updated on the peripheral.
*/
+ mutex_lock(&driver->dci_mutex);
list_for_each_safe(start, temp, &driver->dci_client_list) {
entry = list_entry(start, struct diag_dci_client_tbl, track);
if (entry->client_info.token != DCI_LOCAL_PROC)
@@ -1323,6 +1339,7 @@ void diag_update_smd_dci_work_fn(struct work_struct *work)
client_log_mask_ptr += 514;
}
}
+ mutex_unlock(&driver->dci_mutex);
mutex_lock(&dci_log_mask_mutex);
/* Update the appropriate dirty bits in the cumulative mask */
@@ -2971,13 +2988,12 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry)
return DIAG_DCI_NOT_SUPPORTED;
token = entry->client_info.token;
-
- mutex_lock(&driver->dci_mutex);
/*
* Remove the entry from the list before freeing the buffers
* to ensure that we don't have any invalid access.
*/
- list_del(&entry->track);
+ if (!list_empty(&entry->track))
+ list_del(&entry->track);
driver->num_dci_client--;
/*
* Clear the client's log and event masks, update the cumulative
@@ -3006,7 +3022,8 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry)
req_entry = list_entry(start, struct dci_pkt_req_entry_t,
track);
if (req_entry->client_id == entry->client_info.client_id) {
- list_del(&req_entry->track);
+ if (!list_empty(&req_entry->track))
+ list_del(&req_entry->track);
kfree(req_entry);
}
}
@@ -3015,7 +3032,8 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry)
mutex_lock(&entry->write_buf_mutex);
list_for_each_entry_safe(buf_entry, temp, &entry->list_write_buf,
buf_track) {
- list_del(&buf_entry->buf_track);
+ if (!list_empty(&buf_entry->buf_track))
+ list_del(&buf_entry->buf_track);
if (buf_entry->buf_type == DCI_BUF_SECONDARY) {
mutex_lock(&buf_entry->data_mutex);
diagmem_free(driver, buf_entry->data, POOL_TYPE_DCI);
@@ -3084,8 +3102,6 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry)
}
queue_work(driver->diag_real_time_wq, &driver->diag_real_time_work);
- mutex_unlock(&driver->dci_mutex);
-
return DIAG_DCI_NO_ERROR;
}
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index d510af49f503..c9461d65d7e6 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -348,9 +348,11 @@ static int diagchar_close(struct inode *inode, struct file *file)
* This will specially help in case of ungraceful exit of any DCI client
* This call will remove any pending registrations of such client
*/
+ mutex_lock(&driver->dci_mutex);
dci_entry = dci_lookup_client_entry_pid(current->pid);
if (dci_entry)
diag_dci_deinit_client(dci_entry);
+ mutex_unlock(&driver->dci_mutex);
/* If the exiting process is the socket process */
mutex_lock(&driver->diagchar_mutex);
if (driver->socket_process &&
@@ -1250,37 +1252,57 @@ long diagchar_compat_ioctl(struct file *filp,
result = diag_ioctl_dci_reg(ioarg);
break;
case DIAG_IOCTL_DCI_DEINIT:
+ mutex_lock(&driver->dci_mutex);
if (copy_from_user((void *)&client_id, (void __user *)ioarg,
- sizeof(int)))
+ sizeof(int))) {
+ mutex_unlock(&driver->dci_mutex);
return -EFAULT;
+ }
dci_client = diag_dci_get_client_entry(client_id);
- if (!dci_client)
+ if (!dci_client) {
+ mutex_unlock(&driver->dci_mutex);
return DIAG_DCI_NOT_SUPPORTED;
+ }
result = diag_dci_deinit_client(dci_client);
+ mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_SUPPORT:
result = diag_ioctl_dci_support(ioarg);
break;
case DIAG_IOCTL_DCI_HEALTH_STATS:
+ mutex_lock(&driver->dci_mutex);
result = diag_ioctl_dci_health_stats(ioarg);
+ mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_LOG_STATUS:
+ mutex_lock(&driver->dci_mutex);
result = diag_ioctl_dci_log_status(ioarg);
+ mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_EVENT_STATUS:
+ mutex_lock(&driver->dci_mutex);
result = diag_ioctl_dci_event_status(ioarg);
+ mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_CLEAR_LOGS:
+ mutex_lock(&driver->dci_mutex);
if (copy_from_user((void *)&client_id, (void __user *)ioarg,
- sizeof(int)))
+ sizeof(int))) {
+ mutex_unlock(&driver->dci_mutex);
return -EFAULT;
+ }
result = diag_dci_clear_log_mask(client_id);
+ mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_CLEAR_EVENTS:
+ mutex_lock(&driver->dci_mutex);
if (copy_from_user(&client_id, (void __user *)ioarg,
- sizeof(int)))
+ sizeof(int))) {
+ mutex_unlock(&driver->dci_mutex);
return -EFAULT;
+ }
result = diag_dci_clear_event_mask(client_id);
+ mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_LSM_DEINIT:
result = diag_ioctl_lsm_deinit();
@@ -1300,7 +1322,9 @@ long diagchar_compat_ioctl(struct file *filp,
result = 1;
break;
case DIAG_IOCTL_VOTE_REAL_TIME:
+ mutex_lock(&driver->dci_mutex);
result = diag_ioctl_vote_real_time(ioarg);
+ mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_GET_REAL_TIME:
result = diag_ioctl_get_real_time(ioarg);
@@ -1347,37 +1371,57 @@ long diagchar_ioctl(struct file *filp,
result = diag_ioctl_dci_reg(ioarg);
break;
case DIAG_IOCTL_DCI_DEINIT:
+ mutex_lock(&driver->dci_mutex);
if (copy_from_user((void *)&client_id, (void __user *)ioarg,
- sizeof(int)))
+ sizeof(int))) {
+ mutex_unlock(&driver->dci_mutex);
return -EFAULT;
+ }
dci_client = diag_dci_get_client_entry(client_id);
- if (!dci_client)
+ if (!dci_client) {
+ mutex_unlock(&driver->dci_mutex);
return DIAG_DCI_NOT_SUPPORTED;
+ }
result = diag_dci_deinit_client(dci_client);
+ mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_SUPPORT:
result = diag_ioctl_dci_support(ioarg);
break;
case DIAG_IOCTL_DCI_HEALTH_STATS:
+ mutex_lock(&driver->dci_mutex);
result = diag_ioctl_dci_health_stats(ioarg);
+ mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_LOG_STATUS:
+ mutex_lock(&driver->dci_mutex);
result = diag_ioctl_dci_log_status(ioarg);
+ mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_EVENT_STATUS:
+ mutex_lock(&driver->dci_mutex);
result = diag_ioctl_dci_event_status(ioarg);
+ mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_CLEAR_LOGS:
+ mutex_lock(&driver->dci_mutex);
if (copy_from_user((void *)&client_id, (void __user *)ioarg,
- sizeof(int)))
+ sizeof(int))) {
+ mutex_unlock(&driver->dci_mutex);
return -EFAULT;
+ }
result = diag_dci_clear_log_mask(client_id);
+ mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_DCI_CLEAR_EVENTS:
+ mutex_lock(&driver->dci_mutex);
if (copy_from_user(&client_id, (void __user *)ioarg,
- sizeof(int)))
+ sizeof(int))) {
+ mutex_unlock(&driver->dci_mutex);
return -EFAULT;
+ }
result = diag_dci_clear_event_mask(client_id);
+ mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_LSM_DEINIT:
result = diag_ioctl_lsm_deinit();
@@ -1397,7 +1441,9 @@ long diagchar_ioctl(struct file *filp,
result = 1;
break;
case DIAG_IOCTL_VOTE_REAL_TIME:
+ mutex_lock(&driver->dci_mutex);
result = diag_ioctl_vote_real_time(ioarg);
+ mutex_unlock(&driver->dci_mutex);
break;
case DIAG_IOCTL_GET_REAL_TIME:
result = diag_ioctl_get_real_time(ioarg);
@@ -1540,7 +1586,10 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
goto exit;
}
+exit:
+ mutex_unlock(&driver->diagchar_mutex);
if (driver->data_ready[index] & DCI_DATA_TYPE) {
+ mutex_lock(&driver->dci_mutex);
/* Copy the type of data being passed */
data_type = driver->data_ready[index] & DCI_DATA_TYPE;
list_for_each_safe(start, temp, &driver->dci_client_list) {
@@ -1550,16 +1599,28 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
continue;
if (!entry->in_service)
continue;
- COPY_USER_SPACE_OR_EXIT(buf + ret, data_type,
- sizeof(int));
- COPY_USER_SPACE_OR_EXIT(buf + ret,
- entry->client_info.token, sizeof(int));
+ if (copy_to_user(buf + ret, &data_type, sizeof(int))) {
+ mutex_unlock(&driver->dci_mutex);
+ goto end;
+ }
+ ret += sizeof(int);
+ if (copy_to_user(buf + ret, &entry->client_info.token,
+ sizeof(int))) {
+ mutex_unlock(&driver->dci_mutex);
+ goto end;
+ }
+ ret += sizeof(int);
copy_dci_data = 1;
exit_stat = diag_copy_dci(buf, count, entry, &ret);
+ mutex_lock(&driver->diagchar_mutex);
driver->data_ready[index] ^= DCI_DATA_TYPE;
- if (exit_stat == 1)
- goto exit;
+ mutex_unlock(&driver->diagchar_mutex);
+ if (exit_stat == 1) {
+ mutex_unlock(&driver->dci_mutex);
+ goto end;
+ }
}
+ mutex_lock(&driver->diagchar_mutex);
for (i = 0; i < NUM_SMD_DCI_CHANNELS; i++) {
if (driver->smd_dci[i].ch) {
queue_work(driver->diag_dci_wq,
@@ -1577,10 +1638,11 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
}
}
}
- goto exit;
+ mutex_unlock(&driver->diagchar_mutex);
+ mutex_unlock(&driver->dci_mutex);
+ goto end;
}
-exit:
- mutex_unlock(&driver->diagchar_mutex);
+end:
/*
* Flush any read that is currently pending on DCI data and
* command channnels. This will ensure that the next read is not
diff --git a/drivers/coresight/coresight-tmc.c b/drivers/coresight/coresight-tmc.c
index 18208698cd09..a15acd12084a 100644
--- a/drivers/coresight/coresight-tmc.c
+++ b/drivers/coresight/coresight-tmc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, 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
@@ -846,6 +846,14 @@ static int tmc_enable(struct tmc_drvdata *drvdata, enum tmc_mode mode)
return ret;
mutex_lock(&drvdata->usb_lock);
+ spin_lock_irqsave(&drvdata->spinlock, flags);
+ if (drvdata->reading) {
+ ret = -EBUSY;
+ spin_unlock_irqrestore(&drvdata->spinlock, flags);
+ goto err0;
+ }
+ spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
if (drvdata->config_type == TMC_CONFIG_TYPE_ETB) {
coresight_cti_map_trigout(drvdata->cti_flush, 1, 0);
coresight_cti_map_trigin(drvdata->cti_reset, 2, 0);
@@ -892,10 +900,6 @@ static int tmc_enable(struct tmc_drvdata *drvdata, enum tmc_mode mode)
}
spin_lock_irqsave(&drvdata->spinlock, flags);
- if (drvdata->reading) {
- ret = -EBUSY;
- goto err1;
- }
if (drvdata->config_type == TMC_CONFIG_TYPE_ETB) {
__tmc_etb_enable(drvdata);
@@ -920,11 +924,6 @@ static int tmc_enable(struct tmc_drvdata *drvdata, enum tmc_mode mode)
dev_info(drvdata->dev, "TMC enabled\n");
return 0;
-err1:
- spin_unlock_irqrestore(&drvdata->spinlock, flags);
- if (drvdata->config_type == TMC_CONFIG_TYPE_ETR)
- if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB)
- usb_qdss_close(drvdata->usbch);
err0:
mutex_unlock(&drvdata->usb_lock);
clk_disable_unprepare(drvdata->clk);
@@ -1317,6 +1316,7 @@ static int tmc_read_prepare(struct tmc_drvdata *drvdata)
unsigned long flags;
enum tmc_mode mode;
+ mutex_lock(&drvdata->usb_lock);
spin_lock_irqsave(&drvdata->spinlock, flags);
if (!drvdata->sticky_enable) {
dev_err(drvdata->dev, "enable tmc once before reading\n");
@@ -1347,11 +1347,13 @@ static int tmc_read_prepare(struct tmc_drvdata *drvdata)
out:
drvdata->reading = true;
spin_unlock_irqrestore(&drvdata->spinlock, flags);
+ mutex_unlock(&drvdata->usb_lock);
dev_info(drvdata->dev, "TMC read start\n");
return 0;
err:
spin_unlock_irqrestore(&drvdata->spinlock, flags);
+ mutex_unlock(&drvdata->usb_lock);
return ret;
}
@@ -1533,8 +1535,12 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
{
struct tmc_drvdata *drvdata = container_of(file->private_data,
struct tmc_drvdata, miscdev);
- char *bufp = drvdata->buf + *ppos;
- char *end = (char *)(drvdata->vaddr + drvdata->size);
+ char *bufp, *end;
+
+ mutex_lock(&drvdata->usb_lock);
+
+ bufp = drvdata->buf + *ppos;
+ end = (char *)(drvdata->vaddr + drvdata->size);
if (*ppos + len > drvdata->size)
len = drvdata->size - *ppos;
@@ -1561,6 +1567,7 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
if (copy_to_user(data, bufp, len)) {
dev_dbg(drvdata->dev, "%s: copy_to_user failed\n", __func__);
+ mutex_unlock(&drvdata->usb_lock);
return -EFAULT;
}
@@ -1568,6 +1575,8 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
out:
dev_dbg(drvdata->dev, "%s: %zu bytes copied, %d bytes left\n",
__func__, len, (int) (drvdata->size - *ppos));
+
+ mutex_unlock(&drvdata->usb_lock);
return len;
}
diff --git a/drivers/gud/Kconfig b/drivers/gud/Kconfig
deleted file mode 100644
index d643ab8fcd58..000000000000
--- a/drivers/gud/Kconfig
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# MobiCore configuration
-#
-config MOBICORE_SUPPORT
- tristate "Linux MobiCore Support"
- depends on ARCH_MSM
- ---help---
- Enable Linux Kernel MobiCore Support
-
-config MOBICORE_DEBUG
- bool "MobiCore Module debug mode"
- depends on MOBICORE_SUPPORT
- ---help---
- Enable Debug mode in the MobiCore Driver.
- It enables printing information about MobiCore operations
-
-config MOBICORE_VERBOSE
- bool "MobiCore Module verbose debug mode"
- depends on MOBICORE_DEBUG
- ---help---
- Enable Verbose Debug mode in the MobiCore Driver.
- It enables printing extra information about MobiCore operations
- Beware: this is only useful for debuging deep in the driver because
- it prints too much logs
-
-
-config MOBICORE_API
- tristate "Linux MobiCore API"
- depends on MOBICORE_SUPPORT
- ---help---
- Enable Linux Kernel MobiCore API
diff --git a/drivers/gud/Makefile b/drivers/gud/Makefile
deleted file mode 100644
index 69d88ec40b60..000000000000
--- a/drivers/gud/Makefile
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# Makefile for the kernel mobicore drivers
-#
-GUD_ROOT_FOLDER := drivers/gud
-# add our modules to kernel.
-obj-$(CONFIG_MOBICORE_API) += mcKernelApi.o
-obj-$(CONFIG_MOBICORE_SUPPORT) += mcDrvModule.o
-
-mcDrvModule-objs := MobiCoreDriver/logging.o \
- MobiCoreDriver/ops.o \
- MobiCoreDriver/mem.o \
- MobiCoreDriver/api.o \
- MobiCoreDriver/pm.o \
- MobiCoreDriver/main.o
-
-mcKernelApi-objs := MobiCoreKernelApi/main.o \
- MobiCoreKernelApi/clientlib.o \
- MobiCoreKernelApi/device.o \
- MobiCoreKernelApi/session.o \
- MobiCoreKernelApi/connection.o
-
-# Release mode by default
-ccflags-y := -DNDEBUG -I$(GUD_ROOT_FOLDER)
-ccflags-y += -Wno-declaration-after-statement
-
-#Netlink changed arguments number
-ccflags-y += -DMC_NETLINK_COMPAT_V37
-
-ccflags-$(CONFIG_MOBICORE_DEBUG) += -DDEBUG
-ccflags-$(CONFIG_MOBICORE_VERBOSE) += -DDEBUG_VERBOSE
-
-# Choose one platform from the folder
-MOBICORE_PLATFORM := $(shell (ls -1 $(srctree)/$(GUD_ROOT_FOLDER)/MobiCoreDriver/platforms | tail -1) )
-# Use the available platform folder
-ccflags-y += -I$(GUD_ROOT_FOLDER)/MobiCoreDriver/platforms/$(MOBICORE_PLATFORM)
-# MobiCore Driver includes
-ccflags-y += -I$(GUD_ROOT_FOLDER)/MobiCoreDriver/public
-# MobiCore KernelApi required incldes
-ccflags-y += -I$(GUD_ROOT_FOLDER)/MobiCoreKernelApi/include
-ccflags-y += -I$(GUD_ROOT_FOLDER)/MobiCoreKernelApi/public
diff --git a/drivers/gud/MobiCoreDriver/Makefile b/drivers/gud/MobiCoreDriver/Makefile
deleted file mode 100644
index c97c0d7d50a1..000000000000
--- a/drivers/gud/MobiCoreDriver/Makefile
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# this makefile is called from the kernel make system. Thus we basically
-# add things to "obj-m" here.
-
-ifeq ($(MODE),release)
- ccflags-y = -O2 -DNDEBUG
-else
- ccflags-y = -DDEBUG
-endif # DEBUG/RELEASE
-
-# CFLAG for testable mode
-ifeq ($(IS_TESTABLE),yes)
- ccflags-y = -DTEST
-endif
-
-# CFLAGS from the build script
-ifdef MOBICORE_CFLAGS
- ccflags-y += $(MOBICORE_CFLAGS)
-endif
-#EXTRA_CFLAGS+=-DDEBUG_VERBOSE
-
-ccflags-y += -Wall -D__$(PLATFORM)__
-# add our module to kernel.
-obj-m += mcDrvModule.o
-
-mcDrvModule-objs :=logging.o ops.o mem.o api.o pm.o main.o
-
-clean:
- rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions \
- Module.markers Module.symvers modules.order
-
diff --git a/drivers/gud/MobiCoreDriver/api.c b/drivers/gud/MobiCoreDriver/api.c
deleted file mode 100644
index 755f80b39d26..000000000000
--- a/drivers/gud/MobiCoreDriver/api.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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/module.h>
-
-#include "main.h"
-#include "mem.h"
-#include "debug.h"
-
-int mobicore_map_vmem(struct mc_instance *instance, void *addr,
- uint32_t len, uint32_t *handle)
-{
- phys_addr_t phys;
- return mc_register_wsm_mmu(instance, addr, len,
- handle, &phys);
-}
-EXPORT_SYMBOL(mobicore_map_vmem);
-
-/*
- * Unmap a virtual memory buffer from mobicore
- * @param instance
- * @param handle
- *
- * @return 0 if no error
- *
- */
-int mobicore_unmap_vmem(struct mc_instance *instance, uint32_t handle)
-{
- return mc_unregister_wsm_mmu(instance, handle);
-}
-EXPORT_SYMBOL(mobicore_unmap_vmem);
-
-/*
- * Free a WSM buffer allocated with mobicore_allocate_wsm
- * @param instance
- * @param handle handle of the buffer
- *
- * @return 0 if no error
- *
- */
-int mobicore_free_wsm(struct mc_instance *instance, uint32_t handle)
-{
- return mc_free_buffer(instance, handle);
-}
-EXPORT_SYMBOL(mobicore_free_wsm);
-
-
-/*
- * Allocate WSM for given instance
- *
- * @param instance instance
- * @param requested_size size of the WSM
- * @param handle pointer where the handle will be saved
- * @param virt_kernel_addr pointer for the kernel virtual address
- *
- * @return error code or 0 for success
- */
-int mobicore_allocate_wsm(struct mc_instance *instance,
- unsigned long requested_size, uint32_t *handle, void **virt_kernel_addr)
-{
- struct mc_buffer *buffer = NULL;
-
- /* Setup the WSM buffer structure! */
- if (mc_get_buffer(instance, &buffer, requested_size))
- return -EFAULT;
-
- *handle = buffer->handle;
- *virt_kernel_addr = buffer->addr;
- return 0;
-}
-EXPORT_SYMBOL(mobicore_allocate_wsm);
-
-/*
- * Initialize a new mobicore API instance object
- *
- * @return Instance or NULL if no allocation was possible.
- */
-struct mc_instance *mobicore_open(void)
-{
- struct mc_instance *instance = mc_alloc_instance();
- if(instance) {
- instance->admin = true;
- }
- return instance;
-}
-EXPORT_SYMBOL(mobicore_open);
-
-/*
- * Release a mobicore instance object and all objects related to it
- * @param instance instance
- * @return 0 if Ok or -E ERROR
- */
-int mobicore_release(struct mc_instance *instance)
-{
- return mc_release_instance(instance);
-}
-EXPORT_SYMBOL(mobicore_release);
-
-/*
- * Test if mobicore can sleep
- *
- * @return true if mobicore can sleep, false if it can't sleep
- */
-bool mobicore_sleep_ready(void)
-{
- return mc_sleep_ready();
-}
-EXPORT_SYMBOL(mobicore_sleep_ready);
-
diff --git a/drivers/gud/MobiCoreDriver/arm.h b/drivers/gud/MobiCoreDriver/arm.h
deleted file mode 100644
index 8c9fc37eee22..000000000000
--- a/drivers/gud/MobiCoreDriver/arm.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-#ifndef _MC_ARM_H_
-#define _MC_ARM_H_
-
-#include "debug.h"
-
-#ifdef CONFIG_ARM64
-inline bool has_security_extensions(void)
-{
- return true;
-}
-
-inline bool is_secure_mode(void)
-{
- return false;
-}
-#else
-/*
- * ARM Trustzone specific masks and modes
- * Vanilla Linux is unaware of TrustZone extension.
- * I.e. arch/arm/include/asm/ptrace.h does not define monitor mode.
- * Also TZ bits in cpuid are not defined, ARM port uses magic numbers,
- * see arch/arm/kernel/setup.c
- */
-#define ARM_MONITOR_MODE (0x16) /*(0b10110)*/
-#define ARM_SECURITY_EXTENSION_MASK (0x30)
-
-/* check if CPU supports the ARM TrustZone Security Extensions */
-inline bool has_security_extensions(void)
-{
- u32 fea = 0;
- asm volatile(
- "mrc p15, 0, %[fea], cr0, cr1, 0" :
- [fea]"=r" (fea));
-
- MCDRV_DBG_VERBOSE(mcd, "CPU Features: 0x%X", fea);
-
- /*
- * If the CPU features ID has 0 for security features then the CPU
- * doesn't support TrustZone at all!
- */
- if ((fea & ARM_SECURITY_EXTENSION_MASK) == 0)
- return false;
-
- return true;
-}
-
-/* check if running in secure mode */
-inline bool is_secure_mode(void)
-{
- u32 cpsr = 0;
- u32 nsacr = 0;
-
- asm volatile(
- "mrc p15, 0, %[nsacr], cr1, cr1, 2\n"
- "mrs %[cpsr], cpsr\n" :
- [nsacr]"=r" (nsacr),
- [cpsr]"=r"(cpsr));
-
- MCDRV_DBG_VERBOSE(mcd, "CPRS.M = set to 0x%X\n", cpsr & MODE_MASK);
- MCDRV_DBG_VERBOSE(mcd, "SCR.NS = set to 0x%X\n", nsacr);
-
- /*
- * If the NSACR contains the reset value(=0) then most likely we are
- * running in Secure MODE.
- * If the cpsr mode is set to monitor mode then we cannot load!
- */
- if (nsacr == 0 || ((cpsr & MODE_MASK) == ARM_MONITOR_MODE))
- return true;
-
- return false;
-}
-#endif
-
-#endif /* _MC_ARM_H_ */
diff --git a/drivers/gud/MobiCoreDriver/build.sh b/drivers/gud/MobiCoreDriver/build.sh
deleted file mode 100644
index db8410c39629..000000000000
--- a/drivers/gud/MobiCoreDriver/build.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
-
-# source the setup script
-if [ -z $COMP_PATH_ROOT ]; then
- echo "The build environment is not set!"
- echo "Trying to source setupDrivers.sh automatically!"
- source ../setupDrivers.sh || exit 1
-fi
-
-ROOT_PATH=$(dirname $(readlink -f $0))
-# These folders need to be relative to the kernel dir or absolute!
-PLATFORM=EXYNOS_5410_STD
-CODE_INCLUDE=$(readlink -f $ROOT_PATH/Locals/Code)
-PLATFORM_INCLUDE="$CODE_INCLUDE/platforms/$PLATFORM"
-MOBICORE_DAEMON=$COMP_PATH_MobiCoreDriverLib/Public
-
-MOBICORE_CFLAGS="-I$MOBICORE_DRIVER/Public -I$MOBICORE_DAEMON -I$COMP_PATH_MobiCore/inc/Mci -I$COMP_PATH_MobiCore/inc -I${PLATFORM_INCLUDE}"
-
-# Clean first
-make -C $CODE_INCLUDE clean
-
-make -C $LINUX_PATH \
- MODE=$MODE \
- ARCH=arm \
- CROSS_COMPILE=$CROSS_COMPILE \
- M=$CODE_INCLUDE \
- "MOBICORE_CFLAGS=$MOBICORE_CFLAGS" \
- modules
diff --git a/drivers/gud/MobiCoreDriver/debug.h b/drivers/gud/MobiCoreDriver/debug.h
deleted file mode 100644
index 52362b346552..000000000000
--- a/drivers/gud/MobiCoreDriver/debug.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-#ifndef _MC_DEBUG_H_
-#define _MC_DEBUG_H_
-/* Found in main.c */
-extern struct device *mcd;
-
-#define MCDRV_DBG_ERROR(dev, txt, ...) \
- dev_err(dev, "MobiCore %s() ### ERROR: " txt "\n", \
- __func__, \
- ##__VA_ARGS__)
-
-/* dummy function helper macro. */
-#define DUMMY_FUNCTION() do {} while (0)
-
-#if defined(DEBUG)
-
-/* #define DEBUG_VERBOSE */
-#if defined(DEBUG_VERBOSE)
-#define MCDRV_DBG_VERBOSE MCDRV_DBG
-#else
-#define MCDRV_DBG_VERBOSE(...) DUMMY_FUNCTION()
-#endif
-
-#define MCDRV_DBG(dev, txt, ...) \
- dev_info(dev, "MobiCore %s(): " txt "\n", \
- __func__, \
- ##__VA_ARGS__)
-
-#define MCDRV_DBG_WARN(dev, txt, ...) \
- dev_warn(dev, "MobiCore %s() WARNING: " txt "\n", \
- __func__, \
- ##__VA_ARGS__)
-
-#define MCDRV_ASSERT(cond) \
- do { \
- if (unlikely(!(cond))) { \
- panic("Assertion failed: %s:%d\n", \
- __FILE__, __LINE__); \
- } \
- } while (0)
-
-#else
-
-#define MCDRV_DBG_VERBOSE(...) DUMMY_FUNCTION()
-#define MCDRV_DBG(...) DUMMY_FUNCTION()
-#define MCDRV_DBG_WARN(...) DUMMY_FUNCTION()
-
-#define MCDRV_ASSERT(...) DUMMY_FUNCTION()
-
-#endif /* [not] defined(DEBUG) */
-
-#endif /* _MC_DEBUG_H_ */
diff --git a/drivers/gud/MobiCoreDriver/fastcall.h b/drivers/gud/MobiCoreDriver/fastcall.h
deleted file mode 100644
index 1b2e2a67d8fc..000000000000
--- a/drivers/gud/MobiCoreDriver/fastcall.h
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-#ifndef _MC_FASTCALL_H_
-#define _MC_FASTCALL_H_
-
-#include "debug.h"
-#include "platform.h"
-
-/* Use the arch_extension sec pseudo op before switching to secure world */
-#if defined(__GNUC__) && \
- defined(__GNUC_MINOR__) && \
- defined(__GNUC_PATCHLEVEL__) && \
- ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)) \
- >= 40502
-#ifndef CONFIG_ARM64
-#define MC_ARCH_EXTENSION_SEC
-#endif
-#endif
-
-/*
- * MobiCore SMCs
- */
-#define MC_SMC_N_YIELD 0x3 /* Yield to switch from NWd to SWd. */
-#define MC_SMC_N_SIQ 0x4 /* SIQ to switch from NWd to SWd. */
-
-/*
- * MobiCore fast calls. See MCI documentation
- */
-#ifdef MC_AARCH32_FC
-
-#define MC_FC_STD64_BASE ((uint32_t)0xFF000000)
-/**< Initializing FastCall. */
-#define MC_FC_INIT (MC_FC_STD64_BASE+1)
-/**< Info FastCall. */
-#define MC_FC_INFO (MC_FC_STD64_BASE+2)
-/**< Enable SWd tracing via memory */
-#define MC_FC_NWD_TRACE (MC_FC_STD64_BASE+10)
-#ifdef TBASE_CORE_SWITCHER
-/**< Core switching fastcall */
-#define MC_FC_SWITCH_CORE (MC_FC_STD64_BASE+54)
-#endif
-
-#else
-
-#define MC_FC_INIT -1
-#define MC_FC_INFO -2
-#define MC_FC_NWD_TRACE -31
-#ifdef TBASE_CORE_SWITCHER
-#define MC_FC_SWITCH_CORE 0x84000005
-#endif
-#endif
-
-/*
- * return code for fast calls
- */
-#define MC_FC_RET_OK 0
-#define MC_FC_RET_ERR_INVALID 1
-#define MC_FC_RET_ERR_ALREADY_INITIALIZED 5
-
-
-/* structure wrappers for specific fastcalls */
-
-/* generic fast call parameters */
-union fc_generic {
- struct {
- uint32_t cmd;
- uint32_t param[3];
- } as_in;
- struct {
- uint32_t resp;
- uint32_t ret;
- uint32_t param[2];
- } as_out;
-};
-
-/* fast call init */
-union mc_fc_init {
- union fc_generic as_generic;
- struct {
- uint32_t cmd;
- uint32_t base;
- uint32_t nq_info;
- uint32_t mcp_info;
- } as_in;
- struct {
- uint32_t resp;
- uint32_t ret;
- uint32_t rfu[2];
- } as_out;
-};
-
-/* fast call info parameters */
-union mc_fc_info {
- union fc_generic as_generic;
- struct {
- uint32_t cmd;
- uint32_t ext_info_id;
- uint32_t rfu[2];
- } as_in;
- struct {
- uint32_t resp;
- uint32_t ret;
- uint32_t state;
- uint32_t ext_info;
- } as_out;
-};
-
-#ifdef TBASE_CORE_SWITCHER
-/* fast call switch Core parameters */
-union mc_fc_swich_core {
- union fc_generic as_generic;
- struct {
- uint32_t cmd;
- uint32_t core_id;
- uint32_t rfu[2];
- } as_in;
- struct {
- uint32_t resp;
- uint32_t ret;
- uint32_t state;
- uint32_t ext_info;
- } as_out;
-};
-#endif
-/*
- * _smc() - fast call to MobiCore
- *
- * @data: pointer to fast call data
- */
-#ifdef CONFIG_ARM64
-static inline long _smc(void *data)
-{
- int ret = 0;
-
- if (data == NULL)
- return -EPERM;
-
- #ifdef MC_SMC_FASTCALL
- {
- ret = smc_fastcall(data, sizeof(union fc_generic));
- }
- #else
- {
- union fc_generic *fc_generic = data;
- /* SMC expect values in x0-x3 */
- register u64 reg0 __asm__("x0") = fc_generic->as_in.cmd;
- register u64 reg1 __asm__("x1") = fc_generic->as_in.param[0];
- register u64 reg2 __asm__("x2") = fc_generic->as_in.param[1];
- register u64 reg3 __asm__("x3") = fc_generic->as_in.param[2];
-
- __asm__ volatile (
- "smc #0\n"
- : "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3)
- );
-
- /* set response */
- fc_generic->as_out.resp = reg0;
- fc_generic->as_out.ret = reg1;
- fc_generic->as_out.param[0] = reg2;
- fc_generic->as_out.param[1] = reg3;
- }
- #endif
- return ret;
-}
-
-#else
-static inline long _smc(void *data)
-{
- int ret = 0;
-
- if (data == NULL)
- return -EPERM;
-
- #ifdef MC_SMC_FASTCALL
- {
- ret = smc_fastcall(data, sizeof(union fc_generic));
- }
- #else
- {
- union fc_generic *fc_generic = data;
- /* SMC expect values in r0-r3 */
- register u32 reg0 __asm__("r0") = fc_generic->as_in.cmd;
- register u32 reg1 __asm__("r1") = fc_generic->as_in.param[0];
- register u32 reg2 __asm__("r2") = fc_generic->as_in.param[1];
- register u32 reg3 __asm__("r3") = fc_generic->as_in.param[2];
-
- __asm__ volatile (
-#ifdef MC_ARCH_EXTENSION_SEC
- /* This pseudo op is supported and required from
- * binutils 2.21 on */
- ".arch_extension sec\n"
-#endif
- "smc #0\n"
- : "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3)
- );
-
-
-#ifdef __ARM_VE_A9X4_QEMU__
- /* Qemu does not return to the address following the SMC
- * instruction so we have to insert several nop instructions to
- * workaround this Qemu bug. */
- __asm__ volatile (
- "nop\n"
- "nop\n"
- "nop\n"
- "nop"
- );
-#endif
-
- /* set response */
- fc_generic->as_out.resp = reg0;
- fc_generic->as_out.ret = reg1;
- fc_generic->as_out.param[0] = reg2;
- fc_generic->as_out.param[1] = reg3;
- }
- #endif
- return ret;
-}
-#endif
-
-/*
- * convert fast call return code to linux driver module error code
- */
-static inline int convert_fc_ret(uint32_t sret)
-{
- int ret = -EFAULT;
-
- switch (sret) {
- case MC_FC_RET_OK:
- ret = 0;
- break;
- case MC_FC_RET_ERR_INVALID:
- ret = -EINVAL;
- break;
- case MC_FC_RET_ERR_ALREADY_INITIALIZED:
- ret = -EBUSY;
- break;
- default:
- break;
- }
- return ret;
-}
-
-#endif /* _MC_FASTCALL_H_ */
diff --git a/drivers/gud/MobiCoreDriver/logging.c b/drivers/gud/MobiCoreDriver/logging.c
deleted file mode 100644
index 044e297dfcbd..000000000000
--- a/drivers/gud/MobiCoreDriver/logging.c
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright (c) 2013-2014 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-/*
- * MobiCore Driver Logging Subsystem.
- *
- * The logging subsystem provides the interface between the Mobicore trace
- * buffer and the Linux log
- */
-#include <linux/miscdevice.h>
-#include <linux/moduleparam.h>
-#include <linux/kthread.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/device.h>
-
-#include "main.h"
-#include "debug.h"
-#include "ops.h"
-#include "logging.h"
-
-/* Default length of the log ring buffer 256KB*/
-#define LOG_BUF_SIZE (64 * PAGE_SIZE)
-
-/* Max Len of a log line for printing */
-#define LOG_LINE_SIZE 256
-
-static uint32_t log_size = LOG_BUF_SIZE;
-
-module_param(log_size, uint, 0);
-MODULE_PARM_DESC(log_size, "Size of the MobiCore log ringbuffer(256KB def)");
-
-/* Definitions for log version 2 */
-#define LOG_TYPE_MASK (0x0007)
-#define LOG_TYPE_CHAR 0
-#define LOG_TYPE_INTEGER 1
-/* Field length */
-#define LOG_LENGTH_MASK (0x00F8)
-#define LOG_LENGTH_SHIFT 3
-/* Extra attributes */
-#define LOG_EOL (0x0100)
-#define LOG_INTEGER_DECIMAL (0x0200)
-#define LOG_INTEGER_SIGNED (0x0400)
-
-struct logmsg_struct {
- uint16_t ctrl; /* Type and format of data */
- uint16_t source; /* Unique value for each event source */
- uint32_t log_data; /* Value, if any */
-};
-
-static uint16_t prev_source; /* Previous Log source */
-static uint32_t log_pos; /* MobiCore log previous position */
-static struct mc_trace_buf *log_buf; /* MobiCore log buffer structure */
-struct task_struct *log_thread; /* Log Thread task structure */
-static char *log_line; /* Log Line buffer */
-static uint32_t log_line_len; /* Log Line buffer current length */
-static int thread_err;
-
-static void log_eol(uint16_t source)
-{
- if (!strnlen(log_line, LOG_LINE_SIZE)) {
- /* In case a TA tries to print a 0x0 */
- log_line_len = 0;
- return;
- }
- /* MobiCore Userspace */
- if (prev_source)
- dev_info(mcd, "%03x|%s\n", prev_source, log_line);
- /* MobiCore kernel */
- else
- dev_info(mcd, "%s\n", log_line);
-
- log_line_len = 0;
- log_line[0] = 0;
-}
-
-/*
- * Collect chars in log_line buffer and output the buffer when it is full.
- * No locking needed because only "mobicore_log" thread updates this buffer.
- */
-static void log_char(char ch, uint16_t source)
-{
- if (ch == '\n' || ch == '\r') {
- log_eol(source);
- return;
- }
-
- if (log_line_len >= LOG_LINE_SIZE - 1 || source != prev_source)
- log_eol(source);
-
-
- log_line[log_line_len] = ch;
- log_line[log_line_len + 1] = 0;
- log_line_len++;
- prev_source = source;
-}
-
-static const uint8_t HEX2ASCII[16] = {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
-
-static void dbg_raw_nro(uint32_t format, uint32_t value, uint16_t source)
-{
- int digits = 1;
- uint32_t base = (format & LOG_INTEGER_DECIMAL) ? 10 : 16;
- int width = (format & LOG_LENGTH_MASK) >> LOG_LENGTH_SHIFT;
- int negative = 0;
- uint32_t digit_base = 1;
-
- if ((format & LOG_INTEGER_SIGNED) != 0 && ((signed int)value) < 0) {
- negative = 1;
- value = (uint32_t)(-(signed int)value);
- width--;
- }
-
- /* Find length and divider to get largest digit */
- while (value / digit_base >= base) {
- digit_base *= base;
- digits++;
- }
-
- if (width > digits) {
- char ch = (base == 10) ? ' ' : '0';
- while (width > digits) {
- log_char(ch, source);
- width--;
- }
- }
-
- if (negative)
- log_char('-', source);
-
- while (digits-- > 0) {
- uint32_t d = value / digit_base;
- log_char(HEX2ASCII[d], source);
- value = value - d * digit_base;
- digit_base /= base;
- }
-}
-
-static void log_msg(struct logmsg_struct *msg)
-{
- switch (msg->ctrl & LOG_TYPE_MASK) {
- case LOG_TYPE_CHAR: {
- uint32_t ch;
- ch = msg->log_data;
- while (ch != 0) {
- log_char(ch & 0xFF, msg->source);
- ch >>= 8;
- }
- break;
- }
- case LOG_TYPE_INTEGER: {
- dbg_raw_nro(msg->ctrl, msg->log_data, msg->source);
- break;
- }
- default:
- break;
- }
- if (msg->ctrl & LOG_EOL)
- log_eol(msg->source);
-}
-
-static uint32_t process_log(void)
-{
- char *last_msg = log_buf->buff + log_buf->write_pos;
- char *buff = log_buf->buff + log_pos;
-
- while (buff != last_msg) {
- log_msg((struct logmsg_struct *)buff);
- buff += sizeof(struct logmsg_struct);
- /* Wrap around */
- if ((buff + sizeof(struct logmsg_struct)) >
- ((char *)log_buf + log_size))
- buff = log_buf->buff;
- }
- return buff - log_buf->buff;
-}
-
-static void log_exit(void)
-{
- union fc_generic fc_log;
-
- memset(&fc_log, 0, sizeof(fc_log));
- fc_log.as_in.cmd = MC_FC_NWD_TRACE;
-
- MCDRV_DBG(mcd, "Unregister the trace buffer");
- mc_fastcall(&fc_log);
- MCDRV_DBG(mcd, "fc_log out ret=0x%08x", fc_log.as_out.ret);
-
- if (fc_log.as_out.ret == 0) {
- free_pages((unsigned long)log_buf, get_order(log_size));
- log_buf = NULL;
- }
-}
-
-/* log_worker() - Worker thread processing the log_buf buffer. */
-static int log_worker(void *p)
-{
- int ret = 0;
- if (log_buf == NULL) {
- ret = -EFAULT;
- goto err_kthread;
- }
-
- while (!kthread_should_stop()) {
- if (log_buf->write_pos == log_pos)
- schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT);
-
- switch (log_buf->version) {
- case 2:
- log_pos = process_log();
- break;
- default:
- MCDRV_DBG_ERROR(mcd, "Unknown Mobicore log data");
- log_pos = log_buf->write_pos;
- /*
- * Stop the thread as we have no idea what
- * happens next
- */
- ret = -EFAULT;
- goto err_kthread;
- }
- }
-err_kthread:
- MCDRV_DBG(mcd, "Logging thread stopped!");
- thread_err = ret;
- /* Wait until the next kthread_stop() is called, if it was already
- * called we just slip through, if there is an error signal it and
- * wait to get the signal */
- set_current_state(TASK_INTERRUPTIBLE);
- while (!kthread_should_stop()) {
- schedule();
- set_current_state(TASK_INTERRUPTIBLE);
- }
- set_current_state(TASK_RUNNING);
-
- log_exit();
-
- return ret;
-}
-
-/*
- * Wake up the log reader thread
- * This should be called from the places where calls into MobiCore have
- * generated some logs(eg, yield, SIQ...)
- */
-void mobicore_log_read(void)
-{
- if (log_thread == NULL || IS_ERR(log_thread))
- return;
-
- /* The thread itself is in some error condition so just get
- * rid of it */
- if (thread_err != 0) {
- kthread_stop(log_thread);
- log_thread = NULL;
- return;
- }
-
- wake_up_process(log_thread);
-}
-
-/*
- * Setup MobiCore kernel log. It assumes it's running on CORE 0!
- * The fastcall will complain is that is not the case!
- */
-long mobicore_log_setup(void)
-{
- phys_addr_t phys_log_buf;
- union fc_generic fc_log;
- struct sched_param param = { .sched_priority = 1 };
-
- long ret;
- log_pos = 0;
- log_buf = NULL;
- log_thread = NULL;
- log_line = NULL;
- log_line_len = 0;
- prev_source = 0;
- thread_err = 0;
-
- /* Sanity check for the log size */
- if (log_size < PAGE_SIZE)
- return -EFAULT;
- else
- log_size = PAGE_ALIGN(log_size);
-
- log_line = kzalloc(LOG_LINE_SIZE, GFP_KERNEL);
- if (IS_ERR(log_line)) {
- MCDRV_DBG_ERROR(mcd, "failed to allocate log line!");
- return -ENOMEM;
- }
-
- log_thread = kthread_create(log_worker, NULL, "mc_log");
- if (IS_ERR(log_thread)) {
- MCDRV_DBG_ERROR(mcd, "MobiCore log thread creation failed!");
- ret = -EFAULT;
- goto err_free_line;
- }
-
- sched_setscheduler(log_thread, SCHED_IDLE, &param);
- /*
- * We are going to map this buffer into virtual address space in SWd.
- * To reduce complexity there, we use a contiguous buffer.
- */
- log_buf = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
- get_order(log_size));
- if (!log_buf) {
- MCDRV_DBG_ERROR(mcd, "Failed to get page for logger!");
- ret = -ENOMEM;
- goto err_stop_kthread;
- }
- phys_log_buf = virt_to_phys(log_buf);
-
- memset(&fc_log, 0, sizeof(fc_log));
- fc_log.as_in.cmd = MC_FC_NWD_TRACE;
- fc_log.as_in.param[0] = (uint32_t)phys_log_buf;
-#ifdef CONFIG_PHYS_ADDR_T_64BIT
- fc_log.as_in.param[1] = (uint32_t)(phys_log_buf >> 32);
-#endif
- fc_log.as_in.param[2] = log_size;
-
- MCDRV_DBG(mcd, "fc_log virt=%p phys=0x%llX",
- log_buf, (u64)phys_log_buf);
- mc_fastcall(&fc_log);
- MCDRV_DBG(mcd, "fc_log out ret=0x%08x", fc_log.as_out.ret);
-
- /* If the setup failed we must free the memory allocated */
- if (fc_log.as_out.ret) {
- MCDRV_DBG_ERROR(mcd, "MobiCore shared traces setup failed!");
- free_pages((unsigned long)log_buf, get_order(log_size));
- log_buf = NULL;
- ret = -EIO;
- goto err_stop_kthread;
- }
-
- set_task_state(log_thread, TASK_INTERRUPTIBLE);
-
- MCDRV_DBG(mcd, "fc_log Logger version %u", log_buf->version);
- return 0;
-
-err_stop_kthread:
- kthread_stop(log_thread);
- log_thread = NULL;
-err_free_line:
- kfree(log_line);
- log_line = NULL;
- return ret;
-}
-
-/*
- * Free kernel log components.
- * ATTN: We can't free the log buffer because it's also in use by MobiCore and
- * even if the module is unloaded MobiCore is still running.
- */
-void mobicore_log_free(void)
-{
- if (log_thread && !IS_ERR(log_thread)) {
- /* We don't really care what the thread returns for exit */
- kthread_stop(log_thread);
- }
-
- kfree(log_line);
-}
diff --git a/drivers/gud/MobiCoreDriver/logging.h b/drivers/gud/MobiCoreDriver/logging.h
deleted file mode 100644
index a3cbca21c8e7..000000000000
--- a/drivers/gud/MobiCoreDriver/logging.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-#ifndef _MC_LOGGING_H_
-#define _MC_LOGGING_H_
-
-/* MobiCore internal trace buffer structure. */
-struct mc_trace_buf {
- uint32_t version; /* version of trace buffer */
- uint32_t length; /* length of allocated buffer(includes header) */
- uint32_t write_pos; /* last write position */
- char buff[1]; /* start of the log buffer */
-};
-
-/* MobiCore internal trace log setup. */
-void mobicore_log_read(void);
-long mobicore_log_setup(void);
-void mobicore_log_free(void);
-
-#endif /* _MC_LOGGING_H_ */
diff --git a/drivers/gud/MobiCoreDriver/main.c b/drivers/gud/MobiCoreDriver/main.c
deleted file mode 100644
index f1ebaad22815..000000000000
--- a/drivers/gud/MobiCoreDriver/main.c
+++ /dev/null
@@ -1,1595 +0,0 @@
-/*
- * Copyright (c) 2013-2014 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-/*
- * MobiCore Driver Kernel Module.
- *
- * This driver represents the command proxy on the lowest layer, from the
- * secure world to the non secure world, and vice versa.
-
- * This driver offers IOCTL commands, for access to the secure world, and has
- * the interface from the secure world to the normal world.
- * The access to the driver is possible with a file descriptor,
- * which has to be created by the fd = open(/dev/mobicore) command or
- * fd = open(/dev/mobicore-user)
- */
-#include <linux/miscdevice.h>
-#include <linux/interrupt.h>
-#include <linux/highmem.h>
-#include <linux/slab.h>
-#include <linux/kthread.h>
-#include <linux/device.h>
-#include <linux/module.h>
-#include <linux/ioctl.h>
-#include <linux/mm.h>
-#include <linux/mman.h>
-#include <linux/completion.h>
-#include <linux/fdtable.h>
-#include <linux/cdev.h>
-#include <net/net_namespace.h>
-#include <net/sock.h>
-#include <net/tcp_states.h>
-#include <net/af_unix.h>
-
-
-#include "main.h"
-#include "fastcall.h"
-
-#include "arm.h"
-#include "mem.h"
-#include "ops.h"
-#include "pm.h"
-#include "debug.h"
-#include "logging.h"
-#include "build_tag.h"
-
-#if defined(MC_CRYPTO_CLOCK_MANAGEMENT) && defined(MC_USE_DEVICE_TREE)
-#include <linux/platform_device.h>
-#endif
-
-/* Define a MobiCore device structure for use with dev_debug() etc */
-struct device_driver mcd_debug_name = {
- .name = "MobiCore"
-};
-
-struct device mcd_debug_subname = {
- .driver = &mcd_debug_name
-};
-
-struct device *mcd = &mcd_debug_subname;
-
-/* We need 2 devices for admin and user interface*/
-#define MC_DEV_MAX 2
-
-/* Need to discover a chrdev region for the driver */
-static dev_t mc_dev_admin, mc_dev_user;
-struct cdev mc_admin_cdev, mc_user_cdev;
-/* Device class for the driver assigned major */
-static struct class *mc_device_class;
-
-#ifndef FMODE_PATH
- #define FMODE_PATH 0x0
-#endif
-
-static struct sock *__get_socket(struct file *filp)
-{
- struct sock *u_sock = NULL;
- struct inode *inode = filp->f_path.dentry->d_inode;
-
- /*
- * Socket ?
- */
- if (S_ISSOCK(inode->i_mode) && !(filp->f_mode & FMODE_PATH)) {
- struct socket *sock = SOCKET_I(inode);
- struct sock *s = sock->sk;
-
- /*
- * PF_UNIX ?
- */
- if (s && sock->ops && sock->ops->family == PF_UNIX)
- u_sock = s;
- }
- return u_sock;
-}
-
-
-/* MobiCore interrupt context data */
-struct mc_context ctx;
-
-/* Get process context from file pointer */
-static struct mc_instance *get_instance(struct file *file)
-{
- return (struct mc_instance *)(file->private_data);
-}
-
-static uint32_t get_new_buffer_handle(void)
-{
- uint32_t handle;
- struct mc_buffer *buffer;
- /* assumption ctx.bufs_lock mutex is locked */
-retry:
- handle = atomic_inc_return(&ctx.buffer_counter);
- /* The handle must leave 12 bits (PAGE_SHIFT) for the 12 LSBs to be
- * zero, as mmap requires the offset to be page-aligned, plus 1 bit for
- * the MSB to be 0 too, so mmap does not see the offset as negative
- * and fail.
- */
- if ((handle << (PAGE_SHIFT+1)) == 0) {
- atomic_set(&ctx.buffer_counter, 1);
- handle = 1;
- }
- list_for_each_entry(buffer, &ctx.cont_bufs, list) {
- if (buffer->handle == handle)
- goto retry;
- }
-
- return handle;
-}
-
-/* Clears the reserved bit of each page and frees the pages */
-static inline void free_continguous_pages(void *addr, unsigned int order)
-{
- int i;
- struct page *page = virt_to_page(addr);
- for (i = 0; i < (1<<order); i++) {
- MCDRV_DBG_VERBOSE(mcd, "free page at 0x%p", page);
- clear_bit(PG_reserved, &page->flags);
- page++;
- }
-
- MCDRV_DBG_VERBOSE(mcd, "freeing addr:%p, order:%x", addr, order);
- free_pages((unsigned long)addr, order);
-}
-
-/* Frees the memory associated with a buffer */
-static int free_buffer(struct mc_buffer *buffer)
-{
- if (buffer->handle == 0)
- return -EINVAL;
-
- if (buffer->addr == 0)
- return -EINVAL;
-
- MCDRV_DBG_VERBOSE(mcd,
- "handle=%u phys_addr=0x%llx, virt_addr=0x%p len=%u",
- buffer->handle, (u64)buffer->phys,
- buffer->addr, buffer->len);
-
- if (!atomic_dec_and_test(&buffer->usage)) {
- MCDRV_DBG_VERBOSE(mcd, "Could not free %u", buffer->handle);
- return 0;
- }
-
- list_del(&buffer->list);
-
- free_continguous_pages(buffer->addr, buffer->order);
- kfree(buffer);
- return 0;
-}
-
-static uint32_t mc_find_cont_wsm_addr(struct mc_instance *instance, void *uaddr,
- void **addr, uint32_t len)
-{
- int ret = 0;
- struct mc_buffer *buffer;
-
- if (WARN(!instance, "No instance data available"))
- return -EFAULT;
-
- mutex_lock(&instance->lock);
-
- mutex_lock(&ctx.bufs_lock);
-
- /* search for the given handle in the buffers list */
- list_for_each_entry(buffer, &ctx.cont_bufs, list) {
- if (buffer->uaddr == uaddr && buffer->len == len) {
- *addr = buffer->addr;
- goto found;
- }
- }
-
- /* Coundn't find the buffer */
- ret = -EINVAL;
-
-found:
- mutex_unlock(&ctx.bufs_lock);
- mutex_unlock(&instance->lock);
-
- return ret;
-}
-
-bool mc_check_owner_fd(struct mc_instance *instance, int32_t fd)
-{
-#ifndef __ARM_VE_A9X4_STD__
- struct file *fp;
- struct sock *s;
- struct files_struct *files;
- struct task_struct *peer = NULL;
- bool ret = false;
-
- MCDRV_DBG_VERBOSE(mcd, "Finding wsm for fd = %d", fd);
- if (!instance)
- return false;
-
- if (is_daemon(instance))
- return true;
-
- rcu_read_lock();
- fp = fcheck_files(current->files, fd);
- if (fp == NULL)
- goto out;
- s = __get_socket(fp);
- if (s)
- peer = get_pid_task(s->sk_peer_pid, PIDTYPE_PID);
-
- if (peer) {
- task_lock(peer);
- files = peer->files;
- if (!files)
- goto out;
- for (fd = 0; fd < files_fdtable(files)->max_fds; fd++) {
- fp = fcheck_files(files, fd);
- if (!fp)
- continue;
- if (fp->private_data == instance) {
- ret = true;
- break;
- }
- }
- } else {
- MCDRV_DBG(mcd, "Owner not found!");
- }
-out:
- if (peer)
- task_unlock(peer);
- rcu_read_unlock();
- if (!ret)
- MCDRV_DBG(mcd, "Owner not found!");
- return ret;
-#else
- return true;
-#endif
-}
-static uint32_t mc_find_cont_wsm(struct mc_instance *instance, uint32_t handle,
- int32_t fd, phys_addr_t *phys, uint32_t *len)
-{
- int ret = 0;
- struct mc_buffer *buffer;
-
- if (WARN(!instance, "No instance data available"))
- return -EFAULT;
-
- if (WARN_ON(!is_daemon(instance))) {
- MCDRV_DBG_ERROR(mcd, "caller not MobiCore Daemon");
- return -EPERM;
- }
-
- mutex_lock(&instance->lock);
-
- mutex_lock(&ctx.bufs_lock);
-
- /* search for the given handle in the buffers list */
- list_for_each_entry(buffer, &ctx.cont_bufs, list) {
- if (buffer->handle == handle) {
- if (mc_check_owner_fd(buffer->instance, fd)) {
- *phys = buffer->phys;
- *len = buffer->len;
- goto found;
- } else {
- break;
- }
- }
- }
-
- /* Couldn't find the buffer */
- ret = -EINVAL;
-
-found:
- mutex_unlock(&ctx.bufs_lock);
- mutex_unlock(&instance->lock);
-
- return ret;
-}
-
-/*
- * __free_buffer - Free a WSM buffer allocated with mobicore_allocate_wsm
- *
- * @instance
- * @handle handle of the buffer
- *
- * Returns 0 if no error
- *
- */
-static int __free_buffer(struct mc_instance *instance, uint32_t handle,
- bool unlock)
-{
- int ret = 0;
- struct mc_buffer *buffer;
-#ifndef MC_VM_UNMAP
- struct mm_struct *mm = current->mm;
-#endif
-
- if (WARN(!instance, "No instance data available"))
- return -EFAULT;
-
- mutex_lock(&ctx.bufs_lock);
- /* search for the given handle in the buffers list */
- list_for_each_entry(buffer, &ctx.cont_bufs, list) {
- if (buffer->handle == handle)
- goto found_buffer;
- }
- ret = -EINVAL;
- goto err;
-found_buffer:
- if (!is_daemon(instance) && buffer->instance != instance) {
- ret = -EPERM;
- goto err;
- }
- mutex_unlock(&ctx.bufs_lock);
- /* Only unmap if the request is coming from the user space and
- * it hasn't already been unmapped */
- if (!unlock && buffer->uaddr != NULL) {
-#ifndef MC_VM_UNMAP
- /* do_munmap must be done with mm->mmap_sem taken */
- down_write(&mm->mmap_sem);
- ret = do_munmap(mm,
- (long unsigned int)buffer->uaddr,
- buffer->len);
- up_write(&mm->mmap_sem);
-
-#else
- ret = vm_munmap((long unsigned int)buffer->uaddr, buffer->len);
-#endif
- if (ret < 0) {
- /* Something is not right if we end up here, better not
- * clean the buffer so we just leak memory instead of
- * creating security issues */
- MCDRV_DBG_ERROR(mcd, "Memory can't be unmapped");
- return -EINVAL;
- }
- }
-
- mutex_lock(&ctx.bufs_lock);
- /* search for the given handle in the buffers list */
- list_for_each_entry(buffer, &ctx.cont_bufs, list) {
- if (buffer->handle == handle)
- goto del_buffer;
- }
- ret = -EINVAL;
- goto err;
-
-del_buffer:
- if (is_daemon(instance) || buffer->instance == instance)
- ret = free_buffer(buffer);
- else
- ret = -EPERM;
-err:
- mutex_unlock(&ctx.bufs_lock);
- return ret;
-}
-
-int mc_free_buffer(struct mc_instance *instance, uint32_t handle)
-{
- int ret = 0;
-
- if (WARN(!instance, "No instance data available"))
- return -EFAULT;
-
- mutex_lock(&instance->lock);
-
- ret = __free_buffer(instance, handle, false);
- mutex_unlock(&instance->lock);
- return ret;
-}
-
-
-int mc_get_buffer(struct mc_instance *instance,
- struct mc_buffer **buffer, unsigned long len)
-{
- struct mc_buffer *cbuffer = NULL;
- void *addr = 0;
- phys_addr_t phys = 0;
- unsigned int order;
-#if defined(DEBUG_VERBOSE)
- unsigned long allocated_size;
-#endif
- int ret = 0;
-
- if (WARN(!instance, "No instance data available"))
- return -EFAULT;
-
- if (len == 0) {
- MCDRV_DBG_WARN(mcd, "cannot allocate size 0");
- return -ENOMEM;
- }
-
- order = get_order(len);
- if (order > MAX_ORDER) {
- MCDRV_DBG_WARN(mcd, "Buffer size too large");
- return -ENOMEM;
- }
-#if defined(DEBUG_VERBOSE)
- allocated_size = (1 << order) * PAGE_SIZE;
-#endif
-
- if (mutex_lock_interruptible(&instance->lock))
- return -ERESTARTSYS;
-
- /* allocate a new buffer. */
- cbuffer = kzalloc(sizeof(*cbuffer), GFP_KERNEL);
-
- if (cbuffer == NULL) {
- MCDRV_DBG_WARN(mcd,
- "MMAP_WSM request: could not allocate buffer");
- ret = -ENOMEM;
- goto unlock_instance;
- }
- mutex_lock(&ctx.bufs_lock);
-
- MCDRV_DBG_VERBOSE(mcd, "size %ld -> order %d --> %ld (2^n pages)",
- len, order, allocated_size);
-
- addr = (void *)__get_free_pages(GFP_USER | __GFP_ZERO | __GFP_COMP,
- order);
-
- if (addr == NULL) {
- MCDRV_DBG_WARN(mcd, "get_free_pages failed");
- ret = -ENOMEM;
- goto err;
- }
- phys = virt_to_phys(addr);
- cbuffer->handle = get_new_buffer_handle();
- cbuffer->phys = phys;
- cbuffer->addr = addr;
- cbuffer->order = order;
- cbuffer->len = len;
- cbuffer->instance = instance;
- cbuffer->uaddr = 0;
- /* Refcount +1 because the TLC is requesting it */
- atomic_set(&cbuffer->usage, 1);
-
- INIT_LIST_HEAD(&cbuffer->list);
- list_add(&cbuffer->list, &ctx.cont_bufs);
-
- MCDRV_DBG_VERBOSE(mcd,
- "allocd phys=0x%llx-0x%llx, size=%ld kvirt=0x%p h=%d",
- (u64)phys,
- (u64)(phys+allocated_size),
- allocated_size, addr, cbuffer->handle);
- *buffer = cbuffer;
- goto unlock;
-
-err:
- kfree(cbuffer);
-unlock:
- mutex_unlock(&ctx.bufs_lock);
-unlock_instance:
- mutex_unlock(&instance->lock);
- return ret;
-}
-
-/*
- * __lock_buffer() - Locks a contiguous buffer - +1 refcount.
- * Assumes the instance lock is already taken!
- */
-static int __lock_buffer(struct mc_instance *instance, uint32_t handle)
-{
- int ret = 0;
- struct mc_buffer *buffer;
-
- if (WARN(!instance, "No instance data available"))
- return -EFAULT;
-
- if (WARN_ON(!is_daemon(instance))) {
- MCDRV_DBG_ERROR(mcd, "caller not MobiCore Daemon");
- return -EPERM;
- }
-
- mutex_lock(&ctx.bufs_lock);
- /* search for the given handle in the buffers list */
- list_for_each_entry(buffer, &ctx.cont_bufs, list) {
- if (buffer->handle == handle) {
- atomic_inc(&buffer->usage);
- goto unlock;
- }
- }
- ret = -EINVAL;
-
-unlock:
- mutex_unlock(&ctx.bufs_lock);
- return ret;
-}
-
-static phys_addr_t get_mci_base_phys(unsigned int len)
-{
- if (ctx.mci_base.phys) {
- return ctx.mci_base.phys;
- } else {
- unsigned int order = get_order(len);
- ctx.mcp = NULL;
- ctx.mci_base.order = order;
- ctx.mci_base.addr =
- (void *)__get_free_pages(GFP_USER | __GFP_ZERO, order);
- if (ctx.mci_base.addr == NULL) {
- MCDRV_DBG_WARN(mcd, "get_free_pages failed");
- memset(&ctx.mci_base, 0, sizeof(ctx.mci_base));
- return 0;
- }
- ctx.mci_base.phys = virt_to_phys(ctx.mci_base.addr);
- return ctx.mci_base.phys;
- }
-}
-
-/*
- * Create a MMU table from a virtual memory buffer which can be vmalloc
- * or user space virtual memory
- */
-int mc_register_wsm_mmu(struct mc_instance *instance,
- void *buffer, uint32_t len,
- uint32_t *handle, phys_addr_t *phys)
-{
- int ret = 0;
- struct mc_mmu_table *table = NULL;
- struct task_struct *task = current;
- void *kbuff = NULL;
-
- if (WARN(!instance, "No instance data available"))
- return -EFAULT;
-
- if (len == 0) {
- MCDRV_DBG_ERROR(mcd, "len=0 is not supported!");
- return -EINVAL;
- }
-
- MCDRV_DBG_VERBOSE(mcd, "buffer: %p, len=%08x", buffer, len);
-
- if (!mc_find_cont_wsm_addr(instance, buffer, &kbuff, len))
- table = mc_alloc_mmu_table(instance, NULL, kbuff, len);
- else
- table = mc_alloc_mmu_table(instance, task, buffer, len);
-
- if (IS_ERR(table)) {
- MCDRV_DBG_ERROR(mcd, "mc_alloc_mmu_table() failed");
- return -EINVAL;
- }
-
- /* set response */
- *handle = table->handle;
- /* WARNING: daemon shouldn't know this either, but live with it */
- if (is_daemon(instance))
- *phys = table->phys;
- else
- *phys = 0;
-
- MCDRV_DBG_VERBOSE(mcd, "handle: %d, phys=0x%llX",
- *handle, (u64)(*phys));
-
- MCDRV_DBG_VERBOSE(mcd, "exit with %d/0x%08X", ret, ret);
-
- return ret;
-}
-
-int mc_unregister_wsm_mmu(struct mc_instance *instance, uint32_t handle)
-{
- int ret = 0;
-
- if (WARN(!instance, "No instance data available"))
- return -EFAULT;
-
- /* free table (if no further locks exist) */
- mc_free_mmu_table(instance, handle);
-
- return ret;
-}
-/* Lock the object from handle, it could be a WSM MMU table or a cont buffer! */
-static int mc_lock_handle(struct mc_instance *instance, uint32_t handle)
-{
- int ret = 0;
-
- if (WARN(!instance, "No instance data available"))
- return -EFAULT;
-
- if (WARN_ON(!is_daemon(instance))) {
- MCDRV_DBG_ERROR(mcd, "caller not MobiCore Daemon");
- return -EPERM;
- }
-
- mutex_lock(&instance->lock);
- ret = mc_lock_mmu_table(instance, handle);
-
- /* Handle was not a MMU table but a cont buffer */
- if (ret == -EINVAL) {
- /* Call the non locking variant! */
- ret = __lock_buffer(instance, handle);
- }
-
- mutex_unlock(&instance->lock);
-
- return ret;
-}
-
-static int mc_unlock_handle(struct mc_instance *instance, uint32_t handle)
-{
- int ret = 0;
-
- if (WARN(!instance, "No instance data available"))
- return -EFAULT;
-
- if (WARN_ON(!is_daemon(instance))) {
- MCDRV_DBG_ERROR(mcd, "caller not MobiCore Daemon");
- return -EPERM;
- }
-
- mutex_lock(&instance->lock);
- ret = mc_free_mmu_table(instance, handle);
-
- /* Not a MMU table, then it must be a buffer */
- if (ret == -EINVAL) {
- /* Call the non locking variant! */
- ret = __free_buffer(instance, handle, true);
- }
- mutex_unlock(&instance->lock);
-
- return ret;
-}
-
-static phys_addr_t mc_find_wsm_mmu(struct mc_instance *instance,
- uint32_t handle, int32_t fd)
-{
- if (WARN(!instance, "No instance data available"))
- return 0;
-
- if (WARN_ON(!is_daemon(instance))) {
- MCDRV_DBG_ERROR(mcd, "caller not MobiCore Daemon");
- return 0;
- }
-
- return mc_find_mmu_table(handle, fd);
-}
-
-static int mc_clean_wsm_mmu(struct mc_instance *instance)
-{
- if (WARN(!instance, "No instance data available"))
- return -EFAULT;
-
- if (WARN_ON(!is_daemon(instance))) {
- MCDRV_DBG_ERROR(mcd, "caller not MobiCore Daemon");
- return -EPERM;
- }
-
- mc_clean_mmu_tables();
-
- return 0;
-}
-
-static int mc_fd_mmap(struct file *file, struct vm_area_struct *vmarea)
-{
- struct mc_instance *instance = get_instance(file);
- unsigned long len = vmarea->vm_end - vmarea->vm_start;
- uint32_t handle = vmarea->vm_pgoff;
- struct mc_buffer *buffer = 0;
- int ret = 0;
-
- MCDRV_DBG_VERBOSE(mcd, "start=0x%p, size=%ld, offset=%ld, mci=0x%llX",
- (void *)vmarea->vm_start, len, vmarea->vm_pgoff,
- (u64)ctx.mci_base.phys);
-
- if (WARN(!instance, "No instance data available"))
- return -EFAULT;
-
- if (len == 0) {
- MCDRV_DBG_ERROR(mcd, "cannot allocate size 0");
- return -ENOMEM;
- }
- if (handle) {
- mutex_lock(&ctx.bufs_lock);
-
- /* search for the buffer list. */
- list_for_each_entry(buffer, &ctx.cont_bufs, list) {
- /* Only allow mapping if the client owns it!*/
- if (buffer->handle == handle &&
- buffer->instance == instance) {
- /* We shouldn't do remap with larger size */
- if (buffer->len > len)
- break;
- /* We can't allow mapping the buffer twice */
- if (!buffer->uaddr)
- goto found;
- else
- break;
- }
- }
- /* Nothing found return */
- mutex_unlock(&ctx.bufs_lock);
- MCDRV_DBG_ERROR(mcd, "handle not found");
- return -EINVAL;
-
-found:
- buffer->uaddr = (void *)vmarea->vm_start;
- vmarea->vm_flags |= VM_IO;
- /*
- * Convert kernel address to user address. Kernel address begins
- * at PAGE_OFFSET, user address range is below PAGE_OFFSET.
- * Remapping the area is always done, so multiple mappings
- * of one region are possible. Now remap kernel address
- * space into user space
- */
- ret = (int)remap_pfn_range(vmarea, vmarea->vm_start,
- page_to_pfn(virt_to_page(buffer->addr)),
- buffer->len, vmarea->vm_page_prot);
- /* If the remap failed then don't mark this buffer as marked
- * since the unmaping will also fail */
- if (ret)
- buffer->uaddr = NULL;
- mutex_unlock(&ctx.bufs_lock);
- } else {
- if (!is_daemon(instance))
- return -EPERM;
-
- if (!ctx.mci_base.addr)
- return -EFAULT;
-
- vmarea->vm_flags |= VM_IO;
- /* Convert kernel address to user address. Kernel address begins
- * at PAGE_OFFSET, user address range is below PAGE_OFFSET.
- * Remapping the area is always done, so multiple mappings
- * of one region are possible. Now remap kernel address
- * space into user space */
- ret = (int)remap_pfn_range(vmarea, vmarea->vm_start,
- page_to_pfn(virt_to_page(ctx.mci_base.addr)),
- len, vmarea->vm_page_prot);
- }
-
- MCDRV_DBG_VERBOSE(mcd, "exit with %d/0x%08X", ret, ret);
-
- return ret;
-}
-
-static inline int ioctl_check_pointer(unsigned int cmd, int __user *uarg)
-{
- int err = 0;
- if (_IOC_DIR(cmd) & _IOC_READ)
- err = !access_ok(VERIFY_WRITE, uarg, _IOC_SIZE(cmd));
- else if (_IOC_DIR(cmd) & _IOC_WRITE)
- err = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd));
- if (err)
- return -EFAULT;
-
- return 0;
-}
-
-/*
- * mc_fd_user_ioctl() - Will be called from user space as ioctl(..)
- * @file pointer to file
- * @cmd command
- * @arg arguments
- *
- * Returns 0 for OK and an errno in case of error
- */
-static long mc_fd_user_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct mc_instance *instance = get_instance(file);
- int __user *uarg = (int __user *)arg;
- int ret = -EINVAL;
-
- if (WARN(!instance, "No instance data available"))
- return -EFAULT;
-
- if (ioctl_check_pointer(cmd, uarg))
- return -EFAULT;
-
- switch (cmd) {
- case MC_IO_FREE:
- ret = mc_free_buffer(instance, (uint32_t)arg);
- break;
-
- /* 32/64 bit interface compatiblity notice:
- * mc_ioctl_reg_wsm has been defined with the buffer parameter
- * as void* which means that the size and layout of the structure
- * are different between 32 and 64 bit variants.
- * However our 64 bit Linux driver must be able to service both
- * 32 and 64 bit clients so we have to allow both IOCTLs. Though
- * we have a bit of copy paste code we provide maximum backwards
- * compatiblity */
- case MC_IO_REG_WSM:{
- struct mc_ioctl_reg_wsm reg;
- phys_addr_t phys = 0;
- if (copy_from_user(&reg, uarg, sizeof(reg)))
- return -EFAULT;
-
- ret = mc_register_wsm_mmu(instance,
- (void *)(uintptr_t)reg.buffer,
- reg.len, &reg.handle, &phys);
- reg.table_phys = phys;
-
- if (!ret) {
- if (copy_to_user(uarg, &reg, sizeof(reg))) {
- ret = -EFAULT;
- mc_unregister_wsm_mmu(instance, reg.handle);
- }
- }
- break;
- }
- case MC_COMPAT_REG_WSM:{
- struct mc_compat_ioctl_reg_wsm reg;
- phys_addr_t phys = 0;
- if (copy_from_user(&reg, uarg, sizeof(reg)))
- return -EFAULT;
-
- ret = mc_register_wsm_mmu(instance,
- (void *)(uintptr_t)reg.buffer,
- reg.len, &reg.handle, &phys);
- reg.table_phys = phys;
-
- if (!ret) {
- if (copy_to_user(uarg, &reg, sizeof(reg))) {
- ret = -EFAULT;
- mc_unregister_wsm_mmu(instance, reg.handle);
- }
- }
- break;
- }
- case MC_IO_UNREG_WSM:
- ret = mc_unregister_wsm_mmu(instance, (uint32_t)arg);
- break;
-
- case MC_IO_VERSION:
- ret = put_user(mc_get_version(), uarg);
- if (ret)
- MCDRV_DBG_ERROR(mcd,
- "IOCTL_GET_VERSION failed to put data");
- break;
-
- case MC_IO_MAP_WSM:{
- struct mc_ioctl_map map;
- struct mc_buffer *buffer = 0;
- if (copy_from_user(&map, uarg, sizeof(map)))
- return -EFAULT;
-
- /* Setup the WSM buffer structure! */
- if (mc_get_buffer(instance, &buffer, map.len))
- return -EFAULT;
-
- map.handle = buffer->handle;
- /* Trick: to keep the same interface with the user space, store
- the handle in the physical address.
- It is given back with the offset when mmap() is called. */
- map.phys_addr = buffer->handle << PAGE_SHIFT;
- map.reused = 0;
- if (copy_to_user(uarg, &map, sizeof(map)))
- ret = -EFAULT;
- else
- ret = 0;
- break;
- }
- default:
- MCDRV_DBG_ERROR(mcd, "unsupported cmd=0x%x", cmd);
- ret = -ENOIOCTLCMD;
- break;
-
- } /* end switch(cmd) */
-
-#ifdef MC_MEM_TRACES
- mobicore_log_read();
-#endif
-
- return (int)ret;
-}
-
-static long mc_fd_admin_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct mc_instance *instance = get_instance(file);
- int __user *uarg = (int __user *)arg;
- int ret = -EINVAL;
-
- if (WARN(!instance, "No instance data available"))
- return -EFAULT;
-
- if (WARN_ON(!is_daemon(instance))) {
- MCDRV_DBG_ERROR(mcd, "caller not MobiCore Daemon");
- return -EPERM;
- }
-
- if (ioctl_check_pointer(cmd, uarg))
- return -EFAULT;
-
- switch (cmd) {
- case MC_IO_INIT: {
- struct mc_ioctl_init init;
- ctx.mcp = NULL;
- if (!ctx.mci_base.phys) {
- MCDRV_DBG_ERROR(mcd,
- "Cannot init MobiCore without MCI!");
- return -EINVAL;
- }
- if (copy_from_user(&init, uarg, sizeof(init)))
- return -EFAULT;
-
- ctx.mcp = ctx.mci_base.addr + init.mcp_offset;
- ret = mc_init(ctx.mci_base.phys, init.nq_length,
- init.mcp_offset, init.mcp_length);
- break;
- }
- case MC_IO_INFO: {
- struct mc_ioctl_info info;
- if (copy_from_user(&info, uarg, sizeof(info)))
- return -EFAULT;
-
- ret = mc_info(info.ext_info_id, &info.state,
- &info.ext_info);
-
- if (!ret) {
- if (copy_to_user(uarg, &info, sizeof(info)))
- ret = -EFAULT;
- }
- break;
- }
- case MC_IO_YIELD:
- ret = mc_yield();
- break;
-
- case MC_IO_NSIQ:
- ret = mc_nsiq();
- break;
-
- case MC_IO_LOCK_WSM: {
- ret = mc_lock_handle(instance, (uint32_t)arg);
- break;
- }
- case MC_IO_UNLOCK_WSM:
- ret = mc_unlock_handle(instance, (uint32_t)arg);
- break;
- case MC_IO_CLEAN_WSM:
- ret = mc_clean_wsm_mmu(instance);
- break;
- case MC_IO_RESOLVE_WSM: {
- phys_addr_t phys;
- struct mc_ioctl_resolv_wsm wsm;
- if (copy_from_user(&wsm, uarg, sizeof(wsm)))
- return -EFAULT;
- phys = mc_find_wsm_mmu(instance, wsm.handle, wsm.fd);
- if (!phys)
- return -EINVAL;
-
- wsm.phys = phys;
- if (copy_to_user(uarg, &wsm, sizeof(wsm)))
- return -EFAULT;
- ret = 0;
- break;
- }
- case MC_IO_RESOLVE_CONT_WSM: {
- struct mc_ioctl_resolv_cont_wsm cont_wsm;
- phys_addr_t phys = 0;
- uint32_t len = 0;
- if (copy_from_user(&cont_wsm, uarg, sizeof(cont_wsm)))
- return -EFAULT;
- ret = mc_find_cont_wsm(instance, cont_wsm.handle, cont_wsm.fd,
- &phys, &len);
- if (!ret) {
- cont_wsm.phys = phys;
- cont_wsm.length = len;
- if (copy_to_user(uarg, &cont_wsm, sizeof(cont_wsm)))
- ret = -EFAULT;
- }
- break;
- }
- case MC_IO_MAP_MCI:{
- struct mc_ioctl_map map;
- phys_addr_t phys_addr;
- if (copy_from_user(&map, uarg, sizeof(map)))
- return -EFAULT;
-
- map.reused = (ctx.mci_base.phys != 0);
- phys_addr = get_mci_base_phys(map.len);
- if (!phys_addr) {
- MCDRV_DBG_ERROR(mcd, "Failed to setup MCI buffer!");
- return -EFAULT;
- }
- map.phys_addr = 0;
- if (copy_to_user(uarg, &map, sizeof(map)))
- ret = -EFAULT;
- ret = 0;
- break;
- }
- case MC_IO_LOG_SETUP: {
-#ifdef MC_MEM_TRACES
- ret = mobicore_log_setup();
-#endif
- break;
- }
-
- /* The rest is handled commonly by user IOCTL */
- default:
- ret = mc_fd_user_ioctl(file, cmd, arg);
- } /* end switch(cmd) */
-
-#ifdef MC_MEM_TRACES
- mobicore_log_read();
-#endif
-
- return (int)ret;
-}
-
-/*
- * mc_fd_read() - This will be called from user space as read(...)
- * @file: file pointer
- * @buffer: buffer where to copy to(userspace)
- * @buffer_len: number of requested data
- * @pos: not used
- *
- * The read function is blocking until a interrupt occurs. In that case the
- * event counter is copied into user space and the function is finished.
- *
- * If OK this function returns the number of copied data otherwise it returns
- * errno
- */
-static ssize_t mc_fd_read(struct file *file, char *buffer, size_t buffer_len,
- loff_t *pos)
-{
- int ret = 0, ssiq_counter;
- struct mc_instance *instance = get_instance(file);
-
- if (WARN(!instance, "No instance data available"))
- return -EFAULT;
-
- /* avoid debug output on non-error, because this is call quite often */
- MCDRV_DBG_VERBOSE(mcd, "enter");
-
- /* only the MobiCore Daemon is allowed to call this function */
- if (WARN_ON(!is_daemon(instance))) {
- MCDRV_DBG_ERROR(mcd, "caller not MobiCore Daemon");
- return -EPERM;
- }
-
- if (buffer_len < sizeof(unsigned int)) {
- MCDRV_DBG_ERROR(mcd, "invalid length");
- return -EINVAL;
- }
-
- for (;;) {
- if (wait_for_completion_interruptible(&ctx.isr_comp)) {
- MCDRV_DBG_VERBOSE(mcd, "read interrupted");
- return -ERESTARTSYS;
- }
-
- ssiq_counter = atomic_read(&ctx.isr_counter);
- MCDRV_DBG_VERBOSE(mcd, "ssiq_counter=%i, ctx.counter=%i",
- ssiq_counter, ctx.evt_counter);
-
- if (ssiq_counter != ctx.evt_counter) {
- /* read data and exit loop without error */
- ctx.evt_counter = ssiq_counter;
- ret = 0;
- break;
- }
-
- /* end loop if non-blocking */
- if (file->f_flags & O_NONBLOCK) {
- MCDRV_DBG_ERROR(mcd, "non-blocking read");
- return -EAGAIN;
- }
-
- if (signal_pending(current)) {
- MCDRV_DBG_VERBOSE(mcd, "received signal.");
- return -ERESTARTSYS;
- }
- }
-
- /* read data and exit loop */
- ret = copy_to_user(buffer, &ctx.evt_counter, sizeof(unsigned int));
-
- if (ret != 0) {
- MCDRV_DBG_ERROR(mcd, "copy_to_user failed");
- return -EFAULT;
- }
-
- ret = sizeof(unsigned int);
-
- return (ssize_t)ret;
-}
-
-/*
- * Initialize a new mobicore API instance object
- *
- * @return Instance or NULL if no allocation was possible.
- */
-struct mc_instance *mc_alloc_instance(void)
-{
- struct mc_instance *instance;
-
- instance = kzalloc(sizeof(*instance), GFP_KERNEL);
- if (instance == NULL)
- return NULL;
-
- /* get a unique ID for this instance (PIDs are not unique) */
- instance->handle = atomic_inc_return(&ctx.instance_counter);
-
- mutex_init(&instance->lock);
-
- return instance;
-}
-
-#if defined(TBASE_CORE_SWITCHER) && defined(DEBUG)
-static ssize_t mc_fd_write(struct file *file, const char __user *buffer,
- size_t buffer_len, loff_t *x)
-{
- uint32_t cpu_new;
- /* we only consider one digit */
- char buf[2];
- struct mc_instance *instance = get_instance(file);
-
- if (WARN(!instance, "No instance data available"))
- return -EFAULT;
-
- /* Invalid data, nothing to do */
- if (buffer_len < 1)
- return -EINVAL;
-
- /* Invalid data, nothing to do */
- if (copy_from_user(buf, buffer, min(sizeof(buf), buffer_len)))
- return -EFAULT;
-
- if (buf[0] == 'n') {
- mc_nsiq();
- /* If it's a digit then switch cores */
- } else if ((buf[0] >= '0') && (buf[0] <= '9')) {
- cpu_new = buf[0] - '0';
- if (cpu_new <= 8) {
- MCDRV_DBG_VERBOSE(mcd, "Set Active Cpu: %d\n", cpu_new);
- mc_switch_core(cpu_new);
- }
- } else {
- return -EINVAL;
- }
-
- return buffer_len;
-}
-#endif
-
-/*
- * Release a mobicore instance object and all objects related to it
- * @instance: instance
- * Returns 0 if Ok or -E ERROR
- */
-int mc_release_instance(struct mc_instance *instance)
-{
- struct mc_buffer *buffer, *tmp;
-
- if (WARN(!instance, "No instance data available"))
- return -EFAULT;
-
- mutex_lock(&instance->lock);
- mc_clear_mmu_tables(instance);
-
- mutex_lock(&ctx.bufs_lock);
- /* release all mapped data */
-
- /* Check if some buffers are orphaned. */
- list_for_each_entry_safe(buffer, tmp, &ctx.cont_bufs, list) {
- /* It's safe here to only call free_buffer() without unmapping
- * because mmap() takes a refcount to the file's fd so only
- * time we end up here is when everything has been unmapped or
- * the process called exit() */
- if (buffer->instance == instance) {
- buffer->instance = NULL;
- free_buffer(buffer);
- }
- }
- mutex_unlock(&ctx.bufs_lock);
-
- mutex_unlock(&instance->lock);
-
- /* release instance context */
- kfree(instance);
-
- return 0;
-}
-
-/*
- * mc_fd_user_open() - Will be called from user space as fd = open(...)
- * A set of internal instance data are created and initialized.
- *
- * @inode
- * @file
- * Returns 0 if OK or -ENOMEM if no allocation was possible.
- */
-static int mc_fd_user_open(struct inode *inode, struct file *file)
-{
- struct mc_instance *instance;
-
- MCDRV_DBG_VERBOSE(mcd, "enter");
-
- instance = mc_alloc_instance();
- if (instance == NULL)
- return -ENOMEM;
-
- /* store instance data reference */
- file->private_data = instance;
-
- return 0;
-}
-
-static int mc_fd_admin_open(struct inode *inode, struct file *file)
-{
- struct mc_instance *instance;
-
- /*
- * The daemon is already set so we can't allow anybody else to open
- * the admin interface.
- */
- if (ctx.daemon_inst) {
- MCDRV_DBG_ERROR(mcd, "Daemon is already connected");
- return -EPERM;
- }
- /* Setup the usual variables */
- if (mc_fd_user_open(inode, file))
- return -ENOMEM;
- instance = get_instance(file);
-
- MCDRV_DBG(mcd, "accept this as MobiCore Daemon");
-
- ctx.daemon_inst = instance;
- ctx.daemon = current;
- instance->admin = true;
- init_completion(&ctx.isr_comp);
- /* init ssiq event counter */
- ctx.evt_counter = atomic_read(&(ctx.isr_counter));
-
- return 0;
-}
-
-/*
- * mc_fd_release() - This function will be called from user space as close(...)
- * The instance data are freed and the associated memory pages are unreserved.
- *
- * @inode
- * @file
- *
- * Returns 0
- */
-static int mc_fd_release(struct inode *inode, struct file *file)
-{
- int ret = 0;
- struct mc_instance *instance = get_instance(file);
-
- if (WARN(!instance, "No instance data available"))
- return -EFAULT;
-
- /* check if daemon closes us. */
- if (is_daemon(instance)) {
- MCDRV_DBG_WARN(mcd, "MobiCore Daemon died");
- ctx.daemon_inst = NULL;
- ctx.daemon = NULL;
- }
-
- ret = mc_release_instance(instance);
-
- /*
- * ret is quite irrelevant here as most apps don't care about the
- * return value from close() and it's quite difficult to recover
- */
- MCDRV_DBG_VERBOSE(mcd, "exit with %d/0x%08X", ret, ret);
-
- return (int)ret;
-}
-
-/*
- * This function represents the interrupt function of the mcDrvModule.
- * It signals by incrementing of an event counter and the start of the read
- * waiting queue, the read function a interrupt has occurred.
- */
-static irqreturn_t mc_ssiq_isr(int intr, void *context)
-{
- /* increment interrupt event counter */
- atomic_inc(&(ctx.isr_counter));
-
- /* signal the daemon */
- complete(&ctx.isr_comp);
-#ifdef MC_MEM_TRACES
- mobicore_log_read();
-#endif
- return IRQ_HANDLED;
-}
-
-/* function table structure of this device driver. */
-static const struct file_operations mc_admin_fops = {
- .owner = THIS_MODULE,
- .open = mc_fd_admin_open,
- .release = mc_fd_release,
- .unlocked_ioctl = mc_fd_admin_ioctl,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = mc_fd_admin_ioctl,
-#endif
- .mmap = mc_fd_mmap,
- .read = mc_fd_read,
-};
-
-/* function table structure of this device driver. */
-static const struct file_operations mc_user_fops = {
- .owner = THIS_MODULE,
- .open = mc_fd_user_open,
- .release = mc_fd_release,
- .unlocked_ioctl = mc_fd_user_ioctl,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = mc_fd_user_ioctl,
-#endif
- .mmap = mc_fd_mmap,
-#if defined(TBASE_CORE_SWITCHER) && defined(DEBUG)
- .write = mc_fd_write,
-#endif
-};
-
-static int create_devices(void)
-{
- int ret = 0;
-
- cdev_init(&mc_admin_cdev, &mc_admin_fops);
- cdev_init(&mc_user_cdev, &mc_user_fops);
-
- mc_device_class = class_create(THIS_MODULE, "mobicore");
- if (IS_ERR(mc_device_class)) {
- MCDRV_DBG_ERROR(mcd, "failed to create device class");
- ret = PTR_ERR(mc_device_class);
- goto out;
- }
-
- ret = alloc_chrdev_region(&mc_dev_admin, 0, MC_DEV_MAX, "mobicore");
- if (ret < 0) {
- MCDRV_DBG_ERROR(mcd, "failed to allocate char dev region");
- goto error;
- }
- mc_dev_user = MKDEV(MAJOR(mc_dev_admin), 1);
-
- MCDRV_DBG_VERBOSE(mcd, "%s: dev %d", "mobicore", MAJOR(mc_dev_admin));
-
- /* First the ADMIN node */
- ret = cdev_add(&mc_admin_cdev, mc_dev_admin, 1);
- if (ret != 0) {
- MCDRV_DBG_ERROR(mcd, "admin device register failed");
- goto error;
- }
- mc_admin_cdev.owner = THIS_MODULE;
- device_create(mc_device_class, NULL, mc_dev_admin, NULL,
- MC_ADMIN_DEVNODE);
-
- /* Then the user node */
-
- ret = cdev_add(&mc_user_cdev, mc_dev_user, 1);
- if (ret != 0) {
- MCDRV_DBG_ERROR(mcd, "user device register failed");
- goto error_unregister;
- }
- mc_user_cdev.owner = THIS_MODULE;
- device_create(mc_device_class, NULL, mc_dev_user, NULL,
- MC_USER_DEVNODE);
-
- goto out;
-error_unregister:
- device_destroy(mc_device_class, mc_dev_admin);
- device_destroy(mc_device_class, mc_dev_user);
-
- cdev_del(&mc_admin_cdev);
- cdev_del(&mc_user_cdev);
- unregister_chrdev_region(mc_dev_admin, MC_DEV_MAX);
-error:
- class_destroy(mc_device_class);
-out:
- return ret;
-}
-
-/*
- * This function is called the kernel during startup or by a insmod command.
- * This device is installed and registered as cdev, then interrupt and
- * queue handling is set up
- */
-static int __init mobicore_init(void)
-{
- int ret = 0;
- dev_set_name(mcd, "mcd");
-
- /* Do not remove or change the following trace.
- * The string "MobiCore" is used to detect if <t-base is in of the image
- */
- dev_info(mcd, "MobiCore Driver, Build: " __TIMESTAMP__ "\n");
- dev_info(mcd, "MobiCore mcDrvModuleApi version is %i.%i\n",
- MCDRVMODULEAPI_VERSION_MAJOR,
- MCDRVMODULEAPI_VERSION_MINOR);
-#ifdef MOBICORE_COMPONENT_BUILD_TAG
- dev_info(mcd, "MobiCore %s\n", MOBICORE_COMPONENT_BUILD_TAG);
-#endif
- /* Hardware does not support ARM TrustZone -> Cannot continue! */
- if (!has_security_extensions()) {
- MCDRV_DBG_ERROR(mcd,
- "Hardware doesn't support ARM TrustZone!");
- return -ENODEV;
- }
-
- /* Running in secure mode -> Cannot load the driver! */
- if (is_secure_mode()) {
- MCDRV_DBG_ERROR(mcd, "Running in secure MODE!");
- return -ENODEV;
- }
-
- ret = mc_fastcall_init(&ctx);
- if (ret)
- goto error;
-
- init_completion(&ctx.isr_comp);
-
- /* initialize event counter for signaling of an IRQ to zero */
- atomic_set(&ctx.isr_counter, 0);
-
- /* set up S-SIQ interrupt handler ************************/
- ret = request_irq(MC_INTR_SSIQ, mc_ssiq_isr, IRQF_TRIGGER_RISING,
- MC_ADMIN_DEVNODE, &ctx);
- if (ret != 0) {
- MCDRV_DBG_ERROR(mcd, "interrupt request failed");
- goto err_req_irq;
- }
-
-#ifdef MC_PM_RUNTIME
- ret = mc_pm_initialize(&ctx);
- if (ret != 0) {
- MCDRV_DBG_ERROR(mcd, "Power Management init failed!");
- goto free_isr;
- }
-#endif
-
- ret = create_devices();
- if (ret != 0)
- goto free_pm;
-
- ret = mc_init_mmu_tables();
-
-#ifdef MC_CRYPTO_CLOCK_MANAGEMENT
- ret = mc_pm_clock_initialize();
-#endif
-
- /*
- * initialize unique number counters which we can use for
- * handles. We start with 1 instead of 0.
- */
- atomic_set(&ctx.buffer_counter, 1);
- atomic_set(&ctx.instance_counter, 1);
-
- /* init list for contiguous buffers */
- INIT_LIST_HEAD(&ctx.cont_bufs);
-
- /* init lock for the buffers list */
- mutex_init(&ctx.bufs_lock);
-
- memset(&ctx.mci_base, 0, sizeof(ctx.mci_base));
- MCDRV_DBG(mcd, "initialized");
- return 0;
-
-free_pm:
-#ifdef MC_PM_RUNTIME
- mc_pm_free();
-free_isr:
-#endif
- free_irq(MC_INTR_SSIQ, &ctx);
-err_req_irq:
- mc_fastcall_destroy();
-error:
- return ret;
-}
-
-/*
- * This function removes this device driver from the Linux device manager .
- */
-static void __exit mobicore_exit(void)
-{
- MCDRV_DBG_VERBOSE(mcd, "enter");
-#ifdef MC_MEM_TRACES
- mobicore_log_free();
-#endif
-
- mc_release_mmu_tables();
-
-#ifdef MC_PM_RUNTIME
- mc_pm_free();
-#endif
-
- device_destroy(mc_device_class, mc_dev_admin);
- device_destroy(mc_device_class, mc_dev_user);
- class_destroy(mc_device_class);
- unregister_chrdev_region(mc_dev_admin, MC_DEV_MAX);
-
- free_irq(MC_INTR_SSIQ, &ctx);
-
- mc_fastcall_destroy();
-
-#ifdef MC_CRYPTO_CLOCK_MANAGEMENT
- mc_pm_clock_finalize();
-#endif
-
- MCDRV_DBG_VERBOSE(mcd, "exit");
-}
-
-bool mc_sleep_ready(void)
-{
-#ifdef MC_PM_RUNTIME
- return mc_pm_sleep_ready();
-#else
- return true;
-#endif
-}
-
-#if defined(MC_CRYPTO_CLOCK_MANAGEMENT) && defined(MC_USE_DEVICE_TREE)
-static int mcd_probe(struct platform_device *pdev)
-{
- mcd->of_node = pdev->dev.of_node;
- mobicore_init();
- return 0;
-}
-
-static int mcd_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
-static int mcd_suspend(struct platform_device *pdev, pm_message_t state)
-{
- return 0;
-}
-
-static int mcd_resume(struct platform_device *pdev)
-{
- return 0;
-}
-
-static struct of_device_id mcd_match[] = {
- {
- .compatible = "qcom,mcd",
- },
- {}
-};
-
-static struct platform_driver mc_plat_driver = {
- .probe = mcd_probe,
- .remove = mcd_remove,
- .suspend = mcd_suspend,
- .resume = mcd_resume,
- .driver = {
- .name = "mcd",
- .owner = THIS_MODULE,
- .of_match_table = mcd_match,
- },
-};
-
-static int mobicore_register(void)
-{
- return platform_driver_register(&mc_plat_driver);
-}
-
-static void mobicore_unregister(void)
-{
- platform_driver_unregister(&mc_plat_driver);
- mobicore_exit();
-}
-
-module_init(mobicore_register);
-module_exit(mobicore_unregister);
-
-#else
-
-module_init(mobicore_init);
-module_exit(mobicore_exit);
-
-#endif
-
-MODULE_AUTHOR("Trustonic Limited");
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("MobiCore driver");
diff --git a/drivers/gud/MobiCoreDriver/main.h b/drivers/gud/MobiCoreDriver/main.h
deleted file mode 100644
index f8f210714c32..000000000000
--- a/drivers/gud/MobiCoreDriver/main.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-#ifndef _MC_MAIN_H_
-#define _MC_MAIN_H_
-
-#include <asm/pgtable.h>
-#include <linux/semaphore.h>
-#include <linux/completion.h>
-#include <linux/mutex.h>
-
-#include "public/mc_linux.h"
-/* Platform specific settings */
-#include "platform.h"
-
-#define MC_VERSION(major, minor) \
- (((major & 0x0000ffff) << 16) | (minor & 0x0000ffff))
-
-/* Instance data for MobiCore Daemon and TLCs. */
-struct mc_instance {
- /* lock for the instance */
- struct mutex lock;
- /* unique handle */
- unsigned int handle;
- bool admin;
-};
-
-/*
- * Contiguous buffer allocated to TLCs.
- * These buffers are uses as world shared memory (wsm) and shared with
- * secure world.
- * The virtual kernel address is added for a simpler search algorithm.
- */
-struct mc_buffer {
- struct list_head list;
- /* unique handle */
- unsigned int handle;
- /* Number of references kept to this buffer */
- atomic_t usage;
- /* virtual Kernel start address */
- void *addr;
- /* virtual Userspace start address */
- void *uaddr;
- /* physical start address */
- phys_addr_t phys;
- /* order of number of pages */
- unsigned int order;
- uint32_t len;
- struct mc_instance *instance;
-};
-
-/* MobiCore Driver Kernel Module context data. */
-struct mc_context {
- /* MobiCore MCI information */
- struct mc_buffer mci_base;
- /* MobiCore MCP buffer */
- struct mc_mcp_buffer *mcp;
- /* event completion */
- struct completion isr_comp;
- /* isr event counter */
- unsigned int evt_counter;
- atomic_t isr_counter;
- /* ever incrementing counters */
- atomic_t buffer_counter;
- atomic_t instance_counter;
- /* pointer to instance of daemon */
- struct mc_instance *daemon_inst;
- /* pointer to instance of daemon */
- struct task_struct *daemon;
- /* General list of contiguous buffers allocated by the kernel */
- struct list_head cont_bufs;
- /* Lock for the list of contiguous buffers */
- struct mutex bufs_lock;
-};
-
-struct mc_sleep_mode {
- uint16_t sleep_req;
- uint16_t ready_to_sleep;
-};
-
-/* MobiCore is idle. No scheduling required. */
-#define SCHEDULE_IDLE 0
-/* MobiCore is non idle, scheduling is required. */
-#define SCHEDULE_NON_IDLE 1
-
-/* MobiCore status flags */
-struct mc_flags {
- /*
- * Scheduling hint: if <> SCHEDULE_IDLE, MobiCore should
- * be scheduled by the NWd
- */
- uint32_t schedule;
- /* State of sleep protocol */
- struct mc_sleep_mode sleep_mode;
- /* Reserved for future use: Must not be interpreted */
- uint32_t rfu[2];
-};
-
-/* MCP buffer structure */
-struct mc_mcp_buffer {
- /* MobiCore Flags */
- struct mc_flags flags;
- uint32_t rfu; /* MCP message buffer - ignore */
-};
-
-/* check if caller is MobiCore Daemon */
-static inline bool is_daemon(struct mc_instance *instance)
-{
- if (!instance)
- return false;
- return instance->admin;
-}
-
-
-/* Initialize a new mobicore API instance object */
-struct mc_instance *mc_alloc_instance(void);
-/* Release a mobicore instance object and all objects related to it */
-int mc_release_instance(struct mc_instance *instance);
-
-/*
- * mc_register_wsm_mmu() - Create a MMU table from a virtual memory buffer which
- * can be vmalloc or user space virtual memory
- */
-int mc_register_wsm_mmu(struct mc_instance *instance,
- void *buffer, uint32_t len,
- uint32_t *handle, phys_addr_t *phys);
-/* Unregister the buffer mapped above */
-int mc_unregister_wsm_mmu(struct mc_instance *instance, uint32_t handle);
-
-/* Allocate one mc_buffer of contiguous space */
-int mc_get_buffer(struct mc_instance *instance,
- struct mc_buffer **buffer, unsigned long len);
-/* Free the buffer allocated above */
-int mc_free_buffer(struct mc_instance *instance, uint32_t handle);
-
-/* Check if the other end of the fd owns instance */
-bool mc_check_owner_fd(struct mc_instance *instance, int32_t fd);
-
-/* Test if sleep is possible */
-bool mc_sleep_ready(void);
-
-#endif /* _MC_MAIN_H_ */
diff --git a/drivers/gud/MobiCoreDriver/mem.c b/drivers/gud/MobiCoreDriver/mem.c
deleted file mode 100644
index 523dd2c49de2..000000000000
--- a/drivers/gud/MobiCoreDriver/mem.c
+++ /dev/null
@@ -1,764 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-/*
- * MobiCore Driver Kernel Module.
- *
- * This module is written as a Linux device driver.
- * This driver represents the command proxy on the lowest layer, from the
- * secure world to the non secure world, and vice versa.
- * This driver is located in the non secure world (Linux).
- * This driver offers IOCTL commands, for access to the secure world, and has
- * the interface from the secure world to the normal world.
- * The access to the driver is possible with a file descriptor,
- * which has to be created by the fd = open(/dev/mobicore) command.
- */
-#include "main.h"
-#include "debug.h"
-#include "mem.h"
-
-#include <linux/highmem.h>
-#include <linux/slab.h>
-#include <linux/kthread.h>
-#include <linux/pagemap.h>
-#include <linux/device.h>
-
-#ifdef LPAE_SUPPORT
-#define MMU_TYPE_PAGE (3 << 0)
-#define MMU_BUFFERABLE (1 << 2) /* AttrIndx[0] */
-#define MMU_CACHEABLE (1 << 3) /* AttrIndx[1] */
-#define MMU_NS (1 << 5)
-#define MMU_AP_RW_ALL (1 << 6) /* AP[2:1], RW, at any privilege level */
-#define MMU_EXT_SHARED (3 << 8) /* SH[1:0], inner shareable */
-#define MMU_EXT_AF (1 << 10) /* Access Flag */
-#define MMU_EXT_NG (1 << 11)
-#define MMU_EXT_XN (((uint64_t)1) << 54) /* XN */
-#else
-#define MMU_TYPE_EXT (3 << 0) /* v5 */
-#define MMU_TYPE_SMALL (2 << 0)
-#define MMU_BUFFERABLE (1 << 2)
-#define MMU_CACHEABLE (1 << 3)
-#define MMU_EXT_AP0 (1 << 4)
-#define MMU_EXT_AP1 (2 << 4)
-#define MMU_EXT_TEX(x) ((x) << 6) /* v5 */
-#define MMU_EXT_SHARED (1 << 10) /* v6 */
-#define MMU_EXT_NG (1 << 11) /* v6 */
-#endif
-
-/* MobiCore memory context data */
-struct mc_mem_context mem_ctx;
-
-static inline void release_page(struct page *page)
-{
- set_bit(PG_dirty, &page->flags);
-
- page_cache_release(page);
-}
-
-static int lock_pages(struct task_struct *task, void *virt_start_page_addr,
- int pages_no, struct page **pages)
-{
- int locked_pages;
-
- /* lock user pages, must hold the mmap_sem to do this. */
- down_read(&(task->mm->mmap_sem));
- locked_pages = get_user_pages(
- task,
- task->mm,
- (unsigned long)virt_start_page_addr,
- pages_no,
- 1, /* write access */
- 0,
- pages,
- NULL);
- up_read(&(task->mm->mmap_sem));
-
- /* check if we could lock all pages. */
- if (locked_pages != pages_no) {
- MCDRV_DBG_ERROR(mcd, "get_user_pages() failed, locked_pages=%d",
- locked_pages);
- if (locked_pages > 0) {
- /* release all locked pages. */
- release_pages(pages, locked_pages, 0);
- }
- return -ENOMEM;
- }
-
- return 0;
-}
-
-/* Get kernel pointer to shared MMU table given a per-process reference */
-static void *get_mmu_table_kernel_virt(struct mc_mmu_table *table)
-{
- if (WARN(!table, "Invalid MMU table"))
- return NULL;
-
- if (WARN(!table->set, "Invalid MMU table set"))
- return NULL;
-
- if (WARN(!table->set->kernel_virt, "Invalid MMU pointer"))
- return NULL;
-
- return &(table->set->kernel_virt->table[table->idx]);
-}
-
-/*
- * Search the list of used MMU tables and return the one with the handle.
- * Assumes the table_lock is taken.
- */
-struct mc_mmu_table *find_mmu_table(unsigned int handle)
-{
- struct mc_mmu_table *table;
-
- list_for_each_entry(table, &mem_ctx.mmu_tables, list) {
- if (table->handle == handle)
- return table;
- }
- return NULL;
-}
-
-/*
- * Allocate a new MMU table store plus MMU_TABLES_PER_PAGE in the MMU free
- * tables list. Assumes the table_lock is already taken by the caller above.
- */
-static int alloc_mmu_table_store(void)
-{
- unsigned long store;
- struct mc_mmu_tables_set *mmutable_set;
- struct mc_mmu_table *mmutable, *mmutable2;
- struct page *page;
- int ret = 0, i;
- /* temp list for holding the MMU tables */
- LIST_HEAD(temp);
-
- store = get_zeroed_page(GFP_KERNEL);
- if (!store)
- return -ENOMEM;
-
- /*
- * Actually, locking is not necessary, because kernel
- * memory is not supposed to get swapped out. But we
- * play safe....
- */
- page = virt_to_page(store);
- set_bit(PG_reserved, &page->flags);
-
- /* add all the descriptors to the free descriptors list */
- mmutable_set = kmalloc(sizeof(*mmutable_set), GFP_KERNEL | __GFP_ZERO);
- if (mmutable_set == NULL) {
- ret = -ENOMEM;
- goto free_store;
- }
- /* initialize */
- mmutable_set->kernel_virt = (void *)store;
- mmutable_set->page = page;
- mmutable_set->phys = virt_to_phys((void *)store);
- /* the set is not yet used */
- atomic_set(&mmutable_set->used_tables, 0);
-
- /* init add to list. */
- INIT_LIST_HEAD(&(mmutable_set->list));
- list_add(&mmutable_set->list, &mem_ctx.mmu_tables_sets);
-
- for (i = 0; i < MMU_TABLES_PER_PAGE; i++) {
- /* allocate a WSM MMU descriptor */
- mmutable = kmalloc(sizeof(*mmutable), GFP_KERNEL | __GFP_ZERO);
- if (mmutable == NULL) {
- ret = -ENOMEM;
- MCDRV_DBG_ERROR(mcd, "out of memory");
- /* Free the full temp list and the store in this case */
- goto free_temp_list;
- }
-
- /* set set reference */
- mmutable->set = mmutable_set;
- mmutable->idx = i;
- mmutable->virt = get_mmu_table_kernel_virt(mmutable);
- mmutable->phys = mmutable_set->phys+i*sizeof(struct mmutable);
- atomic_set(&mmutable->usage, 0);
-
- /* add to temp list. */
- INIT_LIST_HEAD(&mmutable->list);
- list_add_tail(&mmutable->list, &temp);
- }
-
- /*
- * If everything went ok then merge the temp list with the global
- * free list
- */
- list_splice_tail(&temp, &mem_ctx.free_mmu_tables);
- return 0;
-free_temp_list:
- list_for_each_entry_safe(mmutable, mmutable2, &temp, list) {
- kfree(mmutable);
- }
-
- list_del(&mmutable_set->list);
-
-free_store:
- free_page(store);
- return ret;
-}
-
-/* Get a unique handle */
-static uint32_t get_new_table_handle(void)
-{
- uint32_t handle;
- struct mc_mmu_table *table;
- /* assumption mem_ctx.table_lock mutex is locked */
-retry:
- handle = atomic_inc_return(&mem_ctx.table_counter);
- if (handle == 0) {
- atomic_set(&mem_ctx.table_counter, 1);
- handle = 1;
- }
- list_for_each_entry(table, &mem_ctx.mmu_tables, list) {
- if (table->handle == handle)
- goto retry;
- }
-
- return handle;
-}
-
-/*
- * Get a MMU table from the free tables list or allocate a new one and
- * initialize it. Assumes the table_lock is already taken.
- */
-static struct mc_mmu_table *alloc_mmu_table(struct mc_instance *instance)
-{
- int ret = 0;
- struct mc_mmu_table *table = NULL;
-
- if (list_empty(&mem_ctx.free_mmu_tables)) {
- ret = alloc_mmu_table_store();
- if (ret) {
- MCDRV_DBG_ERROR(mcd, "Failed to allocate new store!");
- return ERR_PTR(-ENOMEM);
- }
- /* if it's still empty something wrong has happened */
- if (list_empty(&mem_ctx.free_mmu_tables)) {
- MCDRV_DBG_ERROR(mcd,
- "Free list not updated correctly!");
- return ERR_PTR(-EFAULT);
- }
- }
-
- /* get a WSM MMU descriptor */
- table = list_first_entry(&mem_ctx.free_mmu_tables,
- struct mc_mmu_table, list);
- if (table == NULL) {
- MCDRV_DBG_ERROR(mcd, "out of memory");
- return ERR_PTR(-ENOMEM);
- }
- /* Move it to the used MMU tables list */
- list_move_tail(&table->list, &mem_ctx.mmu_tables);
-
- table->handle = get_new_table_handle();
- table->owner = instance;
-
- atomic_inc(&table->set->used_tables);
- atomic_inc(&table->usage);
-
- MCDRV_DBG_VERBOSE(mcd,
- "chunkPhys=0x%llX, idx=%d",
- (u64)table->set->phys, table->idx);
-
- return table;
-}
-
-/*
- * Frees the object associated with a MMU table. Initially the object is moved
- * to the free tables list, but if all the 4 lists of the store are free
- * then the store is also released.
- * Assumes the table_lock is already taken.
- */
-static void free_mmu_table(struct mc_mmu_table *table)
-{
- struct mc_mmu_tables_set *mmutable_set;
-
- if (WARN(!table, "Invalid table"))
- return;
-
- mmutable_set = table->set;
- if (WARN(!mmutable_set, "Invalid table set"))
- return;
-
- list_move_tail(&table->list, &mem_ctx.free_mmu_tables);
-
- /* if nobody uses this set, we can release it. */
- if (atomic_dec_and_test(&mmutable_set->used_tables)) {
- struct mc_mmu_table *tmp;
-
- /* remove from list */
- list_del(&mmutable_set->list);
- /*
- * All the MMU tables are in the free list for this set
- * so we can just remove them from there
- */
- list_for_each_entry_safe(table, tmp, &mem_ctx.free_mmu_tables,
- list) {
- if (table->set == mmutable_set) {
- list_del(&table->list);
- kfree(table);
- }
- } /* end while */
-
- /*
- * We shouldn't recover from this since it was some data
- * corruption before
- */
- BUG_ON(!mmutable_set->page);
- clear_bit(PG_reserved, &(mmutable_set->page)->flags);
-
-
- BUG_ON(!mmutable_set->kernel_virt);
- free_page((unsigned long)mmutable_set->kernel_virt);
-
- kfree(mmutable_set);
- }
-}
-
-/*
- * Create a MMU table in a WSM container that has been allocates previously.
- * Assumes the table lock is already taken or there is no need to take like
- * when first creating the MMU table the full list is locked.
- *
- * @task pointer to task owning WSM
- * @wsm_buffer user space WSM start
- * @wsm_len WSM length
- * @table Pointer to MMU table details
- */
-static int map_buffer(struct task_struct *task, void *wsm_buffer,
- unsigned int wsm_len, struct mc_mmu_table *table)
-{
- int ret = 0;
- unsigned int i, nr_of_pages;
- /* start address of the 4 KiB page of wsm_buffer */
- void *virt_addr_page;
- struct page *page;
- struct mmutable *mmutable;
- struct page **mmutable_as_array_of_pointers_to_page = NULL;
- /* page offset in wsm buffer */
- unsigned int offset;
-
- if (WARN(!wsm_buffer, "Invalid WSM buffer pointer"))
- return -EINVAL;
-
- if (WARN(wsm_len == 0, "Invalid WSM buffer length"))
- return -EINVAL;
-
- if (WARN(!table, "Invalid mapping table for WSM"))
- return -EINVAL;
-
- /* no size > 1Mib supported */
- if (wsm_len > SZ_1M) {
- MCDRV_DBG_ERROR(mcd, "size > 1 MiB");
- return -EINVAL;
- }
-
- MCDRV_DBG_VERBOSE(mcd, "WSM addr=0x%p, len=0x%08x", wsm_buffer,
- wsm_len);
-
- /* calculate page usage */
- virt_addr_page = (void *)(((unsigned long)(wsm_buffer)) & PAGE_MASK);
- offset = (unsigned int) (((unsigned long)(wsm_buffer)) & (~PAGE_MASK));
- nr_of_pages = PAGE_ALIGN(offset + wsm_len) / PAGE_SIZE;
-
- MCDRV_DBG_VERBOSE(mcd, "virt addr page start=0x%p, pages=%d",
- virt_addr_page, nr_of_pages);
-
- /* MMU table can hold max 1MiB in 256 pages. */
- if ((nr_of_pages * PAGE_SIZE) > SZ_1M) {
- MCDRV_DBG_ERROR(mcd, "WSM paged exceed 1 MiB");
- return -EINVAL;
- }
-
- mmutable = table->virt;
-#if (defined LPAE_SUPPORT) || !(defined CONFIG_ARM64)
- /*
- * We use the memory for the MMU table to hold the pointer
- * and convert them later. This works, as everything comes
- * down to a 32 bit value.
- */
- mmutable_as_array_of_pointers_to_page = (struct page **)mmutable;
-#else
- mmutable_as_array_of_pointers_to_page = kmalloc(
- sizeof(struct page *)*nr_of_pages, GFP_KERNEL | __GFP_ZERO);
- if (mmutable_as_array_of_pointers_to_page == NULL) {
- ret = -ENOMEM;
- goto map_buffer_end;
- }
-#endif
-
- /* Request comes from user space */
- if (task != NULL && !is_vmalloc_addr(wsm_buffer)) {
- /*
- * lock user page in memory, so they do not get swapped
- * out.
- * REV axh: Kernel 2.6.27 added a new get_user_pages_fast()
- * function, maybe it is called fast_gup() in some versions.
- * handle user process doing a fork().
- * Child should not get things.
- * http://osdir.com/ml/linux-media/2009-07/msg00813.html
- * http://lwn.net/Articles/275808/
- */
- ret = lock_pages(task, virt_addr_page, nr_of_pages,
- mmutable_as_array_of_pointers_to_page);
- if (ret != 0) {
- MCDRV_DBG_ERROR(mcd, "lock_user_pages() failed");
- goto map_buffer_end;
- }
- }
- /* Request comes from kernel space(cont buffer) */
- else if (task == NULL && !is_vmalloc_addr(wsm_buffer)) {
- void *uaddr = wsm_buffer;
- for (i = 0; i < nr_of_pages; i++) {
- page = virt_to_page(uaddr);
- if (!page) {
- MCDRV_DBG_ERROR(mcd, "failed to map address");
- return -EINVAL;
- }
- get_page(page);
- mmutable_as_array_of_pointers_to_page[i] = page;
- uaddr += PAGE_SIZE;
- }
- }
- /* Request comes from kernel space(vmalloc buffer) */
- else {
- void *uaddr = wsm_buffer;
- for (i = 0; i < nr_of_pages; i++) {
- page = vmalloc_to_page(uaddr);
- if (!page) {
- MCDRV_DBG_ERROR(mcd, "failed to map address");
- return -EINVAL;
- }
- get_page(page);
- mmutable_as_array_of_pointers_to_page[i] = page;
- uaddr += PAGE_SIZE;
- }
- }
-
- table->pages = nr_of_pages;
-
- /*
- * create MMU Table entries.
- * used_mmutable->table contains a list of page pointers here.
- * For a proper cleanup we have to ensure that the following
- * code either works and used_mmutable contains a valid MMU table
- * - or fails and used_mmutable->table contains the list of page
- * pointers.
- * Any mixed contents will make cleanup difficult.
- * Fill the table in reverse order as the table is used as input and
- * output.
- */
- i = MC_ARM_MMU_TABLE_ENTRIES-1;
- do {
- if (i < nr_of_pages) {
-#ifdef LPAE_SUPPORT
- uint64_t pte;
-#else
- uint32_t pte;
-#endif
- page = mmutable_as_array_of_pointers_to_page[i];
-
- if (!page) {
- MCDRV_DBG_ERROR(mcd, "page address is null");
- return -EFAULT;
- }
- /*
- * create MMU table entry, see ARM MMU docu for details
- * about flags stored in the lowest 12 bits.
- * As a side reference, the Article
- * "ARM's multiply-mapped memory mess"
- * found in the collection at
- * http://lwn.net/Articles/409032/
- * is also worth reading.
- */
- pte = page_to_phys(page);
-#ifdef LPAE_SUPPORT
- pte |= MMU_EXT_XN
- | MMU_EXT_NG
- | MMU_EXT_AF
- | MMU_AP_RW_ALL
- | MMU_NS
- | MMU_CACHEABLE | MMU_BUFFERABLE
- | MMU_TYPE_PAGE;
-#else
- pte |= MMU_EXT_AP1 | MMU_EXT_AP0
- | MMU_CACHEABLE | MMU_BUFFERABLE
- | MMU_TYPE_SMALL | MMU_TYPE_EXT | MMU_EXT_NG;
-#endif /* LPAE_SUPPORT */
- /*
- * Linux uses different mappings for SMP systems(the
- * sharing flag is set for the pte. In order not to
- * confuse things too much in Mobicore make sure the
- * shared buffers have the same flags.
- * This should also be done in SWD side
- */
-#ifdef CONFIG_SMP
-#ifdef LPAE_SUPPORT
- pte |= MMU_EXT_SHARED;
-#else
- pte |= MMU_EXT_SHARED | MMU_EXT_TEX(1);
-#endif /* LPAE_SUPPORT */
-#endif /* CONFIG_SMP */
-
- mmutable->table_entries[i] = pte;
- MCDRV_DBG_VERBOSE(mcd, "MMU entry %d: 0x%llx, virt %p",
- i, (u64)(pte), page);
- } else {
- /* ensure rest of table is empty */
- mmutable->table_entries[i] = 0;
- }
- } while (i-- != 0);
-
-map_buffer_end:
-#if !(defined LPAE_SUPPORT) && (defined CONFIG_ARM64)
- kfree(mmutable_as_array_of_pointers_to_page);
-#endif
- return ret;
-}
-
-/*
- * Remove a MMU table in a WSM container. Afterwards the container may be
- * released. Assumes the table_lock and the lock is taken.
- */
-static void unmap_buffers(struct mc_mmu_table *table)
-{
- struct mmutable *mmutable;
- int i;
-
- if (WARN_ON(!table))
- return;
-
- /* found the table, now release the resources. */
- MCDRV_DBG_VERBOSE(mcd,
- "clear table, phys=0x%llX, nr_of_pages=%d, virt=%p",
- (u64)table->phys, table->pages, table->virt);
-
- mmutable = table->virt;
-
- /* release all locked user space pages */
- for (i = 0; i < table->pages; i++) {
- /* convert physical entries from MMU table to page pointers */
- struct page *page = pte_page(mmutable->table_entries[i]);
- MCDRV_DBG_VERBOSE(mcd, "MMU entry %d: 0x%llx, virt %p", i,
- (u64)(mmutable->table_entries[i]), page);
- BUG_ON(!page);
- release_page(page);
- }
-
- /* remember that all pages have been freed */
- table->pages = 0;
-}
-
-/* Delete a used MMU table. Assumes the table_lock and the lock is taken */
-static void unmap_mmu_table(struct mc_mmu_table *table)
-{
- /* Check if it's not locked by other processes too! */
- if (!atomic_dec_and_test(&table->usage))
- return;
-
- /* release if Nwd and Swd/MC do no longer use it. */
- unmap_buffers(table);
- free_mmu_table(table);
-}
-
-int mc_free_mmu_table(struct mc_instance *instance, uint32_t handle)
-{
- struct mc_mmu_table *table;
- int ret = 0;
-
- if (WARN(!instance, "No instance data available"))
- return -EFAULT;
-
- mutex_lock(&mem_ctx.table_lock);
- table = find_mmu_table(handle);
-
- if (table == NULL) {
- MCDRV_DBG_VERBOSE(mcd, "entry not found");
- ret = -EINVAL;
- goto err_unlock;
- }
- if (instance != table->owner && !is_daemon(instance)) {
- MCDRV_DBG_ERROR(mcd, "instance does no own it");
- ret = -EPERM;
- goto err_unlock;
- }
- /* free table (if no further locks exist) */
- unmap_mmu_table(table);
-err_unlock:
- mutex_unlock(&mem_ctx.table_lock);
-
- return ret;
-}
-
-int mc_lock_mmu_table(struct mc_instance *instance, uint32_t handle)
-{
- int ret = 0;
- struct mc_mmu_table *table = NULL;
-
- if (WARN(!instance, "No instance data available"))
- return -EFAULT;
-
- mutex_lock(&mem_ctx.table_lock);
- table = find_mmu_table(handle);
-
- if (table == NULL) {
- MCDRV_DBG_VERBOSE(mcd, "entry not found %u", handle);
- ret = -EINVAL;
- goto table_err;
- }
- if (instance != table->owner && !is_daemon(instance)) {
- MCDRV_DBG_ERROR(mcd, "instance does no own it");
- ret = -EPERM;
- goto table_err;
- }
-
- /* lock entry */
- atomic_inc(&table->usage);
-table_err:
- mutex_unlock(&mem_ctx.table_lock);
- return ret;
-}
-/*
- * Allocate MMU table and map buffer into it.
- * That is, create respective table entries.
- */
-struct mc_mmu_table *mc_alloc_mmu_table(struct mc_instance *instance,
- struct task_struct *task, void *wsm_buffer, unsigned int wsm_len)
-{
- int ret = 0;
- struct mc_mmu_table *table;
-
- if (WARN(!instance, "No instance data available"))
- return ERR_PTR(-EFAULT);
-
- mutex_lock(&mem_ctx.table_lock);
- table = alloc_mmu_table(instance);
- if (IS_ERR(table)) {
- MCDRV_DBG_ERROR(mcd, "alloc_mmu_table() failed");
- ret = -ENOMEM;
- goto err_no_mem;
- }
-
- /* create the MMU page for the WSM */
- ret = map_buffer(task, wsm_buffer, wsm_len, table);
-
- if (ret != 0) {
- MCDRV_DBG_ERROR(mcd, "map_buffer() failed");
- unmap_mmu_table(table);
- goto err_no_mem;
- }
- MCDRV_DBG_VERBOSE(mcd,
- "mapped buffer %p to table with handle %d @ 0x%llX",
- wsm_buffer, table->handle, (u64)table->phys);
-
- mutex_unlock(&mem_ctx.table_lock);
- return table;
-err_no_mem:
- mutex_unlock(&mem_ctx.table_lock);
- return ERR_PTR(ret);
-}
-
-phys_addr_t mc_find_mmu_table(uint32_t handle, int32_t fd)
-{
- phys_addr_t ret = 0;
- struct mc_mmu_table *table = NULL;
-
- mutex_lock(&mem_ctx.table_lock);
- table = find_mmu_table(handle);
-
- if (table == NULL) {
- MCDRV_DBG_ERROR(mcd, "entry not found %u", handle);
- ret = 0;
- goto table_err;
- }
-
- /* It's safe here not to lock the instance since the owner of
- * the table will be cleared only with the table lock taken */
- if (!mc_check_owner_fd(table->owner, fd)) {
- MCDRV_DBG_ERROR(mcd, "not valid owner %u", handle);
- ret = 0;
- goto table_err;
- }
-
- ret = table->phys;
-table_err:
- mutex_unlock(&mem_ctx.table_lock);
- return ret;
-}
-
-void mc_clean_mmu_tables(void)
-{
- struct mc_mmu_table *table, *tmp;
-
- mutex_lock(&mem_ctx.table_lock);
- /* Check if some WSM is orphaned. */
- list_for_each_entry_safe(table, tmp, &mem_ctx.mmu_tables, list) {
- if (table->owner == NULL) {
- /*MCDRV_DBG(mcd,
- "cleariM MMU: p=0x%llX pages=%d",
- (u64)table->phys,
- table->pages);*/
- unmap_mmu_table(table);
- }
- }
- mutex_unlock(&mem_ctx.table_lock);
-}
-
-void mc_clear_mmu_tables(struct mc_instance *instance)
-{
- struct mc_mmu_table *table, *tmp;
-
- mutex_lock(&mem_ctx.table_lock);
- /* Check if some WSM is still in use. */
- list_for_each_entry_safe(table, tmp, &mem_ctx.mmu_tables, list) {
- if (table->owner == instance) {
- /*MCDRV_DBG(mcd, "release WSM MMU: p=0x%llX pages=%d",
- (u64)table->phys,
- table->pages);*/
- /* unlock app usage and free or mark it as orphan */
- table->owner = NULL;
- unmap_mmu_table(table);
- }
- }
- mutex_unlock(&mem_ctx.table_lock);
-}
-
-int mc_init_mmu_tables(void)
-{
- /* init list for WSM MMU chunks. */
- INIT_LIST_HEAD(&mem_ctx.mmu_tables_sets);
-
- /* MMU table descriptor list. */
- INIT_LIST_HEAD(&mem_ctx.mmu_tables);
-
- /* MMU free table descriptor list. */
- INIT_LIST_HEAD(&mem_ctx.free_mmu_tables);
-
- mutex_init(&mem_ctx.table_lock);
- atomic_set(&mem_ctx.table_counter, 1);
-
- return 0;
-}
-
-void mc_release_mmu_tables(void)
-{
- struct mc_mmu_table *table;
- /* Check if some WSM is still in use. */
- list_for_each_entry(table, &mem_ctx.mmu_tables, list) {
- WARN(1, "WSM MMU still in use: phys=0x%llX ,nr_of_pages=%d",
- (u64)table->phys, table->pages);
- }
-}
diff --git a/drivers/gud/MobiCoreDriver/mem.h b/drivers/gud/MobiCoreDriver/mem.h
deleted file mode 100644
index 10fc2e87cdce..000000000000
--- a/drivers/gud/MobiCoreDriver/mem.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-#ifndef _MC_MEM_H_
-#define _MC_MEM_H_
-
-#ifdef LPAE_SUPPORT
-/*
- * Number of page table entries in one MMU table. This is ARM specific, an
- * MMU table covers 2 MiB by using 512 entries referring to 4KiB pages each.
- */
-#define MC_ARM_MMU_TABLE_ENTRIES 512
-
-/* ARM level 3 (MMU) table with 512 entries. Size: 4k */
-struct mmutable {
- uint64_t table_entries[MC_ARM_MMU_TABLE_ENTRIES];
-};
-
-/* There is 1 table in each page. */
-#define MMU_TABLES_PER_PAGE 1
-#else
-/*
- * MobiCore specific page tables for world shared memory.
- * Linux uses shadow page tables, see arch/arm/include/asm/pgtable-2level.
- * MobiCore uses the default ARM format.
- *
- * Number of page table entries in one MMU table. This is ARM specific, an
- * MMU table covers 1 MiB by using 256 entries referring to 4KiB pages each.
- */
-#define MC_ARM_MMU_TABLE_ENTRIES 256
-
-/* ARM level 2 (MMU) table with 256 entries. Size: 1k */
-struct mmutable {
- uint32_t table_entries[MC_ARM_MMU_TABLE_ENTRIES];
-};
-
-/* There are 4 tables in each page. */
-#define MMU_TABLES_PER_PAGE 4
-#endif
-
-/* Store for four MMU tables in one 4kb page*/
-struct mc_mmu_table_store {
- struct mmutable table[MMU_TABLES_PER_PAGE];
-};
-
-/* Usage and maintenance information about mc_mmu_table_store */
-struct mc_mmu_tables_set {
- struct list_head list;
- /* kernel virtual address */
- struct mc_mmu_table_store *kernel_virt;
- /* physical address */
- phys_addr_t phys;
- /* pointer to page struct */
- struct page *page;
- /* How many pages from this set are used */
- atomic_t used_tables;
-};
-
-/*
- * MMU table allocated to the Daemon or a TLC describing a world shared
- * buffer.
- * When users map a malloc()ed area into SWd, a MMU table is allocated.
- * In addition, the area of maximum 1MB virtual address space is mapped into
- * the MMU table and a handle for this table is returned to the user.
- */
-struct mc_mmu_table {
- struct list_head list;
- /* Table lock */
- struct mutex lock;
- /* handle as communicated to user mode */
- unsigned int handle;
- /* Number of references kept to this MMU table */
- atomic_t usage;
- /* owner of this MMU table */
- struct mc_instance *owner;
- /* set describing where our MMU table is stored */
- struct mc_mmu_tables_set *set;
- /* index into MMU table set */
- unsigned int idx;
- /* size of buffer */
- unsigned int pages;
- /* virtual address*/
- void *virt;
- /* physical address */
- phys_addr_t phys;
-};
-
-/* MobiCore Driver Memory context data. */
-struct mc_mem_context {
- struct mc_instance *daemon_inst;
- /* Backing store for MMU tables */
- struct list_head mmu_tables_sets;
- /* Bookkeeping for used MMU tables */
- struct list_head mmu_tables;
- /* Bookkeeping for free MMU tables */
- struct list_head free_mmu_tables;
- /* semaphore to synchronize access to above lists */
- struct mutex table_lock;
- atomic_t table_counter;
-};
-
-/*
- * Allocate MMU table and map buffer into it.
- * That is, create respective table entries.
- */
-struct mc_mmu_table *mc_alloc_mmu_table(struct mc_instance *instance,
- struct task_struct *task, void *wsm_buffer, unsigned int wsm_len);
-
-/* Delete all the MMU tables associated with an instance */
-void mc_clear_mmu_tables(struct mc_instance *instance);
-
-/* Release all orphaned MMU tables */
-void mc_clean_mmu_tables(void);
-
-/* Delete a used MMU table. */
-int mc_free_mmu_table(struct mc_instance *instance, uint32_t handle);
-
-/*
- * Lock a MMU table - the daemon adds +1 to refcount of the MMU table
- * marking it in use by SWD so it doesn't get released when the TLC dies.
- */
-int mc_lock_mmu_table(struct mc_instance *instance, uint32_t handle);
-
-/* Return the phys address of MMU table. */
-phys_addr_t mc_find_mmu_table(uint32_t handle, int32_t fd);
-/* Release all used MMU tables to Linux memory space */
-void mc_release_mmu_tables(void);
-
-/* Initialize all MMU tables structure */
-int mc_init_mmu_tables(void);
-
-#endif /* _MC_MEM_H_ */
diff --git a/drivers/gud/MobiCoreDriver/ops.c b/drivers/gud/MobiCoreDriver/ops.c
deleted file mode 100644
index 57a075727e1d..000000000000
--- a/drivers/gud/MobiCoreDriver/ops.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-/*
- * MobiCore Driver Kernel Module.
- *
- * This module is written as a Linux device driver.
- * This driver represents the command proxy on the lowest layer, from the
- * secure world to the non secure world, and vice versa.
- * This driver is located in the non secure world (Linux).
- * This driver offers IOCTL commands, for access to the secure world, and has
- * the interface from the secure world to the normal world.
- * The access to the driver is possible with a file descriptor,
- * which has to be created by the fd = open(/dev/mobicore) command.
- */
-#include <linux/kthread.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/workqueue.h>
-#include <linux/cpu.h>
-#include <linux/moduleparam.h>
-
-
-#include "main.h"
-#include "fastcall.h"
-#include "ops.h"
-#include "mem.h"
-#include "pm.h"
-#include "debug.h"
-
-/* MobiCore context data */
-static struct mc_context *ctx;
-#ifdef TBASE_CORE_SWITCHER
-static uint32_t active_cpu;
-
-#ifdef TEST
- /*
- * Normal world <t-base core info for testing.
- */
-
- module_param(active_cpu, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
- MODULE_PARM_DESC(active_cpu, "Active <t-base Core");
-#endif
-
-
-static int mobicore_cpu_callback(struct notifier_block *nfb,
- unsigned long action, void *hcpu);
-static struct notifier_block mobicore_cpu_notifer = {
- .notifier_call = mobicore_cpu_callback,
-};
-#endif
-
-static inline long smc(union fc_generic *fc)
-{
- /* If we request sleep yields must be filtered out as they
- * make no sense */
- if (ctx->mcp)
- if (ctx->mcp->flags.sleep_mode.sleep_req) {
- if (fc->as_in.cmd == MC_SMC_N_YIELD)
- return MC_FC_RET_ERR_INVALID;
- }
- return _smc(fc);
-}
-
-struct fastcall_work {
-#ifdef MC_FASTCALL_WORKER_THREAD
- struct kthread_work work;
-#else
- struct work_struct work;
-#endif
- void *data;
-};
-
-#ifdef MC_FASTCALL_WORKER_THREAD
-static void fastcall_work_func(struct kthread_work *work);
-#else
-static void fastcall_work_func(struct work_struct *work);
-#endif
-
-
-#ifdef MC_FASTCALL_WORKER_THREAD
-
-static struct task_struct *fastcall_thread;
-static DEFINE_KTHREAD_WORKER(fastcall_worker);
-
-bool mc_fastcall(void *data)
-{
- struct fastcall_work fc_work = {
- KTHREAD_WORK_INIT(fc_work.work, fastcall_work_func),
- .data = data,
- };
-
- if (!queue_kthread_work(&fastcall_worker, &fc_work.work))
- return false;
- flush_kthread_work(&fc_work.work);
- return true;
-}
-
-int mc_fastcall_init(struct mc_context *context)
-{
- int ret = 0;
- ctx = context;
-
- fastcall_thread = kthread_create(kthread_worker_fn, &fastcall_worker,
- "mc_fastcall");
- if (IS_ERR(fastcall_thread)) {
- ret = PTR_ERR(fastcall_thread);
- fastcall_thread = NULL;
- MCDRV_DBG_ERROR(mcd, "cannot create fastcall wq (%d)", ret);
- return ret;
- }
-
- wake_up_process(fastcall_thread);
-
- /* this thread MUST run on CPU 0 at startup */
- set_cpus_allowed(fastcall_thread, CPU_MASK_CPU0);
-#ifdef TBASE_CORE_SWITCHER
- register_cpu_notifier(&mobicore_cpu_notifer);
-#endif
- return 0;
-}
-
-void mc_fastcall_destroy(void)
-{
- if (!IS_ERR_OR_NULL(fastcall_thread)) {
- kthread_stop(fastcall_thread);
- fastcall_thread = NULL;
- }
-}
-#else
-
-bool mc_fastcall(void *data)
-{
- struct fastcall_work work = {
- .data = data,
- };
- INIT_WORK(&work.work, fastcall_work_func);
- if (!schedule_work_on(0, &work.work))
- return false;
- flush_work(&work.work);
- return true;
-}
-
-int mc_fastcall_init(struct mc_context *context)
-{
- ctx = context;
- return 0;
-};
-
-void mc_fastcall_destroy(void) {};
-#endif
-
-#ifdef MC_FASTCALL_WORKER_THREAD
-static void fastcall_work_func(struct kthread_work *work)
-#else
-static void fastcall_work_func(struct work_struct *work)
-#endif
-{
- struct fastcall_work *fc_work =
- container_of(work, struct fastcall_work, work);
- union fc_generic *fc_generic = fc_work->data;
-#ifdef TBASE_CORE_SWITCHER
- uint32_t cpu_swap = 0, new_cpu;
- uint32_t cpu_id[] = CPU_IDS;
-#endif
-
-#ifdef MC_CRYPTO_CLOCK_MANAGEMENT
- mc_pm_clock_enable();
-#endif
-
-
- if (fc_generic == NULL)
- return;
-#ifdef TBASE_CORE_SWITCHER
- if (fc_generic->as_in.cmd == MC_FC_SWITCH_CORE) {
- cpu_swap = 1;
- new_cpu = fc_generic->as_in.param[0];
- fc_generic->as_in.param[0] = cpu_id[fc_generic->as_in.param[0]];
- }
-#endif
- smc(fc_work->data);
-#ifdef TBASE_CORE_SWITCHER
- if (cpu_swap) {
- if (fc_generic->as_out.ret == 0) {
- cpumask_t cpu;
- active_cpu = new_cpu;
- MCDRV_DBG(mcd, "CoreSwap ok %d -> %d\n",
- raw_smp_processor_id(), active_cpu);
- cpumask_clear(&cpu);
- cpumask_set_cpu(active_cpu, &cpu);
-#ifdef MC_FASTCALL_WORKER_THREAD
- set_cpus_allowed(fastcall_thread, cpu);
-#endif
- } else {
- MCDRV_DBG(mcd, "CoreSwap failed %d -> %d\n",
- raw_smp_processor_id(),
- fc_generic->as_in.param[0]);
- }
- }
-#endif
-#ifdef MC_CRYPTO_CLOCK_MANAGEMENT
- mc_pm_clock_disable();
-#endif
-}
-
-int mc_info(uint32_t ext_info_id, uint32_t *state, uint32_t *ext_info)
-{
- int ret = 0;
- union mc_fc_info fc_info;
-
- MCDRV_DBG_VERBOSE(mcd, "enter");
-
- memset(&fc_info, 0, sizeof(fc_info));
- fc_info.as_in.cmd = MC_FC_INFO;
- fc_info.as_in.ext_info_id = ext_info_id;
-
- MCDRV_DBG(mcd, "<- cmd=0x%08x, ext_info_id=0x%08x",
- fc_info.as_in.cmd, fc_info.as_in.ext_info_id);
-
- mc_fastcall(&(fc_info.as_generic));
-
- MCDRV_DBG(mcd,
- "-> r=0x%08x ret=0x%08x state=0x%08x ext_info=0x%08x",
- fc_info.as_out.resp,
- fc_info.as_out.ret,
- fc_info.as_out.state,
- fc_info.as_out.ext_info);
-
- ret = convert_fc_ret(fc_info.as_out.ret);
-
- *state = fc_info.as_out.state;
- *ext_info = fc_info.as_out.ext_info;
-
- MCDRV_DBG_VERBOSE(mcd, "exit with %d/0x%08X", ret, ret);
-
- return ret;
-}
-
-#ifdef TBASE_CORE_SWITCHER
-
-uint32_t mc_active_core(void)
-{
- return active_cpu;
-}
-
-int mc_switch_core(uint32_t core_num)
-{
- int32_t ret = 0;
- union mc_fc_swich_core fc_switch_core;
-
- if (!cpu_online(core_num))
- return 1;
-
- MCDRV_DBG_VERBOSE(mcd, "enter\n");
-
- memset(&fc_switch_core, 0, sizeof(fc_switch_core));
- fc_switch_core.as_in.cmd = MC_FC_SWITCH_CORE;
-
- if (core_num < COUNT_OF_CPUS)
- fc_switch_core.as_in.core_id = core_num;
- else
- fc_switch_core.as_in.core_id = 0;
-
- MCDRV_DBG(mcd,
- "<- cmd=0x%08x, core_id=0x%08x\n",
- fc_switch_core.as_in.cmd,
- fc_switch_core.as_in.core_id);
- MCDRV_DBG(mcd,
- "<- core_num=0x%08x, active_cpu=0x%08x\n",
- core_num, active_cpu);
- mc_fastcall(&(fc_switch_core.as_generic));
-
- ret = convert_fc_ret(fc_switch_core.as_out.ret);
-
- MCDRV_DBG_VERBOSE(mcd, "exit with %d/0x%08X\n", ret, ret);
-
- return ret;
-}
-
-void mc_cpu_offfline(int cpu)
-{
- if (active_cpu == cpu) {
- int i;
- /* Chose the first online CPU and switch! */
- for_each_online_cpu(i) {
- if (i == cpu) {
- MCDRV_DBG(mcd, "Skipping CPU %d\n", cpu);
- continue;
- }
- MCDRV_DBG(mcd, "CPU %d is dying, switching to %d\n",
- cpu, i);
- mc_switch_core(i);
- break;
- }
- } else {
- MCDRV_DBG(mcd, "not active CPU, no action taken\n");
- }
-}
-
-static int mobicore_cpu_callback(struct notifier_block *nfb,
- unsigned long action, void *hcpu)
-{
- unsigned int cpu = (unsigned long)hcpu;
-
- switch (action) {
- case CPU_DOWN_PREPARE:
- case CPU_DOWN_PREPARE_FROZEN:
- dev_info(mcd, "Cpu %u is going to die\n", cpu);
- mc_cpu_offfline(cpu);
- break;
- case CPU_DEAD:
- case CPU_DEAD_FROZEN:
- dev_info(mcd, "Cpu %u is dead\n", cpu);
- break;
- }
- return NOTIFY_OK;
-}
-#endif
-
-/* Yield to MobiCore */
-int mc_yield(void)
-{
- int ret = 0;
- union fc_generic yield;
-
- MCDRV_DBG_VERBOSE(mcd, "enter");
- memset(&yield, 0, sizeof(yield));
- yield.as_in.cmd = MC_SMC_N_YIELD;
- mc_fastcall(&yield);
- ret = convert_fc_ret(yield.as_out.ret);
-
- return ret;
-}
-
-/* call common notify */
-int mc_nsiq(void)
-{
- int ret = 0;
- union fc_generic nsiq;
- MCDRV_DBG_VERBOSE(mcd, "enter");
- memset(&nsiq, 0, sizeof(nsiq));
- nsiq.as_in.cmd = MC_SMC_N_SIQ;
- mc_fastcall(&nsiq);
- ret = convert_fc_ret(nsiq.as_out.ret);
- return ret;
-}
-
-/* call common notify */
-int _nsiq(void)
-{
- int ret = 0;
- union fc_generic nsiq;
- MCDRV_DBG_VERBOSE(mcd, "enter");
- memset(&nsiq, 0, sizeof(nsiq));
- nsiq.as_in.cmd = MC_SMC_N_SIQ;
- _smc(&nsiq);
- ret = convert_fc_ret(nsiq.as_out.ret);
- return ret;
-}
-
-/* Call the INIT fastcall to setup MobiCore initialization */
-int mc_init(phys_addr_t base, uint32_t nq_length,
- uint32_t mcp_offset, uint32_t mcp_length)
-{
- int ret = 0;
- union mc_fc_init fc_init;
- uint64_t base_addr = (uint64_t)base;
- uint32_t base_high = (uint32_t)(base_addr >> 32);
-
- MCDRV_DBG_VERBOSE(mcd, "enter");
-
- memset(&fc_init, 0, sizeof(fc_init));
-
- fc_init.as_in.cmd = MC_FC_INIT;
- /* base address of mci buffer 4KB aligned */
- fc_init.as_in.base = (uint32_t)base_addr;
- /* notification buffer start/length [16:16] [start, length] */
- fc_init.as_in.nq_info = ((base_high && 0xFFFF) << 16) |
- (nq_length & 0xFFFF);
- /* mcp buffer start/length [16:16] [start, length] */
- fc_init.as_in.mcp_info = (mcp_offset << 16) | (mcp_length & 0xFFFF);
-
- /*
- * Set KMOD notification queue to start of MCI
- * mciInfo was already set up in mmap
- */
- MCDRV_DBG(mcd,
- "cmd=0x%08x, base=0x%08x,nq_info=0x%08x, mcp_info=0x%08x",
- fc_init.as_in.cmd, fc_init.as_in.base, fc_init.as_in.nq_info,
- fc_init.as_in.mcp_info);
- mc_fastcall(&fc_init.as_generic);
- MCDRV_DBG(mcd, "out cmd=0x%08x, ret=0x%08x", fc_init.as_out.resp,
- fc_init.as_out.ret);
-
- ret = convert_fc_ret(fc_init.as_out.ret);
-
- MCDRV_DBG_VERBOSE(mcd, "exit with %d/0x%08X", ret, ret);
-
- return ret;
-}
-
-/* Return MobiCore driver version */
-uint32_t mc_get_version(void)
-{
- MCDRV_DBG(mcd, "MobiCore driver version is %i.%i",
- MCDRVMODULEAPI_VERSION_MAJOR,
- MCDRVMODULEAPI_VERSION_MINOR);
-
- return MC_VERSION(MCDRVMODULEAPI_VERSION_MAJOR,
- MCDRVMODULEAPI_VERSION_MINOR);
-}
diff --git a/drivers/gud/MobiCoreDriver/ops.h b/drivers/gud/MobiCoreDriver/ops.h
deleted file mode 100644
index 30458a37d120..000000000000
--- a/drivers/gud/MobiCoreDriver/ops.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-#ifndef _MC_OPS_H_
-#define _MC_OPS_H_
-
-#include <linux/workqueue.h>
-#include "fastcall.h"
-
-int mc_yield(void);
-int mc_nsiq(void);
-int _nsiq(void);
-uint32_t mc_get_version(void);
-
-int mc_info(uint32_t ext_info_id, uint32_t *state, uint32_t *ext_info);
-int mc_init(phys_addr_t base, uint32_t nq_length, uint32_t mcp_offset,
- uint32_t mcp_length);
-#ifdef TBASE_CORE_SWITCHER
-int mc_switch_core(uint32_t core_num);
-#endif
-
-bool mc_fastcall(void *data);
-
-int mc_fastcall_init(struct mc_context *context);
-void mc_fastcall_destroy(void);
-
-#endif /* _MC_OPS_H_ */
diff --git a/drivers/gud/MobiCoreDriver/platforms/MSM8960_SURF_STD/platform.h b/drivers/gud/MobiCoreDriver/platforms/MSM8960_SURF_STD/platform.h
deleted file mode 100644
index 81096113a68c..000000000000
--- a/drivers/gud/MobiCoreDriver/platforms/MSM8960_SURF_STD/platform.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2013-2014 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-/*
- * Header file of MobiCore Driver Kernel Module Platform
- * specific structures
- *
- * Internal structures of the McDrvModule
- *
- * Header file the MobiCore Driver Kernel Module,
- * its internal structures and defines.
- */
-#ifndef _MC_PLATFORM_H_
-#define _MC_PLATFORM_H_
-
-/* MobiCore Interrupt for Qualcomm */
-#define MC_INTR_SSIQ 280
-
-/* Use SMC for fastcalls */
-#define MC_SMC_FASTCALL
-
-/*--------------- Implementation -------------- */
-#include <soc/qcom/scm.h>
-
-#if defined(CONFIG_ARCH_APQ8084) || defined(CONFIG_ARCH_MSM8916) || \
- defined(CONFIG_ARCH_MSM8994)
-
- #include <soc/qcom/qseecomi.h>
- #include <linux/slab.h>
- #include <linux/io.h>
- #include <linux/mm.h>
- #include <asm/cacheflush.h>
- #include <linux/errno.h>
-
- #define SCM_MOBIOS_FNID(s, c) (((((s) & 0xFF) << 8) | ((c) & 0xFF)) \
- | 0x33000000)
-
- #define TZ_EXECUTIVE_EXT_ID_PARAM_ID \
- TZ_SYSCALL_CREATE_PARAM_ID_4( \
- TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
- TZ_SYSCALL_PARAM_TYPE_VAL, \
- TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
- TZ_SYSCALL_PARAM_TYPE_VAL)
-
-#endif
-
-/* from following file */
-#define SCM_SVC_MOBICORE 250
-#define SCM_CMD_MOBICORE 1
-
-
-static inline int smc_fastcall(void *fc_generic, size_t size)
-{
-#if defined(CONFIG_ARCH_APQ8084) || defined(CONFIG_ARCH_MSM8916) || \
- defined(CONFIG_ARCH_MSM8994)
- if (is_scm_armv8()) {
- struct scm_desc desc = {0};
- int ret;
- void *scm_buf = NULL;
-
- scm_buf = kzalloc(PAGE_ALIGN(size), GFP_KERNEL);
- if (!scm_buf)
- return -ENOMEM;
- memcpy(scm_buf, fc_generic, size);
- dmac_flush_range(scm_buf, scm_buf + size);
-
- desc.arginfo = TZ_EXECUTIVE_EXT_ID_PARAM_ID;
- desc.args[0] = virt_to_phys(scm_buf);
- desc.args[1] = (u32)size;
- desc.args[2] = virt_to_phys(scm_buf);
- desc.args[3] = (u32)size;
- ret = scm_call2(
- SCM_MOBIOS_FNID(SCM_SVC_MOBICORE, SCM_CMD_MOBICORE),
- &desc);
-
- dmac_flush_range(scm_buf, scm_buf + size);
-
- memcpy(fc_generic, scm_buf, size);
- kfree(scm_buf);
- return ret;
- } else {
-#endif
-
- return scm_call(SCM_SVC_MOBICORE, SCM_CMD_MOBICORE,
- fc_generic, size,
- fc_generic, size);
-#if defined(CONFIG_ARCH_APQ8084) || defined(CONFIG_ARCH_MSM8916) || \
- defined(CONFIG_ARCH_MSM8994)
- }
-#endif
-}
-
-/* Enable mobicore mem traces */
-#define MC_MEM_TRACES
-
-/* Enable the use of vm_unamp instead of the deprecated do_munmap
- * and other 3.7 features
- */
-#define MC_VM_UNMAP
-
-/*
- * Perform crypto clock enable/disable
- */
-#if !defined(CONFIG_ARCH_MSM8960) && !defined(CONFIG_ARCH_MSM8994)
-#define MC_CRYPTO_CLOCK_MANAGEMENT
-#endif
-
-#if defined(CONFIG_ARCH_MSM8916) || defined(CONFIG_ARCH_MSM8909)
-#define MC_USE_DEVICE_TREE
-#endif
-
-#endif /* _MC_PLATFORM_H_ */
diff --git a/drivers/gud/MobiCoreDriver/pm.c b/drivers/gud/MobiCoreDriver/pm.c
deleted file mode 100644
index f89726565946..000000000000
--- a/drivers/gud/MobiCoreDriver/pm.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-/*
- * MobiCore Driver Kernel Module.
- * This module is written as a Linux device driver.
- * This driver represents the command proxy on the lowest layer, from the
- * secure world to the non secure world, and vice versa.
- * This driver is located in the non secure world (Linux).
- * This driver offers IOCTL commands, for access to the secure world, and has
- * the interface from the secure world to the normal world.
- * The access to the driver is possible with a file descriptor,
- * which has to be created by the fd = open(/dev/mobicore) command.
- */
-#include <linux/module.h>
-#include <linux/timer.h>
-#include <linux/suspend.h>
-#include <linux/device.h>
-
-#include "main.h"
-#include "pm.h"
-#include "fastcall.h"
-#include "ops.h"
-#include "logging.h"
-#include "debug.h"
-
-#ifdef MC_CRYPTO_CLOCK_MANAGEMENT
- #include <linux/clk.h>
- #include <linux/err.h>
-
- struct clk *mc_ce_iface_clk = NULL;
- struct clk *mc_ce_core_clk = NULL;
- struct clk *mc_ce_bus_clk = NULL;
-
-#endif /* MC_CRYPTO_CLOCK_MANAGEMENT */
-
-#if defined(MC_CRYPTO_CLOCK_MANAGEMENT) && defined(MC_USE_DEVICE_TREE)
- #include <linux/of.h>
- #define QSEE_CE_CLK_100MHZ 100000000
- struct clk *mc_ce_core_src_clk = NULL;
-#endif /* MC_CRYPTO_CLOCK_MANAGEMENT && MC_USE_DEVICE_TREE */
-
-#ifdef MC_PM_RUNTIME
-
-static struct mc_context *ctx;
-
-static bool sleep_ready(void)
-{
- if (!ctx->mcp)
- return false;
-
- if (!(ctx->mcp->flags.sleep_mode.ready_to_sleep & READY_TO_SLEEP))
- return false;
-
- return true;
-}
-
-static void mc_suspend_handler(struct work_struct *work)
-{
- if (!ctx->mcp)
- return;
-
- ctx->mcp->flags.sleep_mode.sleep_req = REQ_TO_SLEEP;
- _nsiq();
-}
-DECLARE_WORK(suspend_work, mc_suspend_handler);
-
-static inline void dump_sleep_params(struct mc_flags *flags)
-{
- MCDRV_DBG(mcd, "MobiCore IDLE=%d!", flags->schedule);
- MCDRV_DBG(mcd,
- "MobiCore Request Sleep=%d!", flags->sleep_mode.sleep_req);
- MCDRV_DBG(mcd,
- "MobiCore Sleep Ready=%d!", flags->sleep_mode.ready_to_sleep);
-}
-
-static int mc_suspend_notifier(struct notifier_block *nb,
- unsigned long event, void *dummy)
-{
- struct mc_mcp_buffer *mcp = ctx->mcp;
- /* We have noting to say if MobiCore is not initialized */
- if (!mcp)
- return 0;
-
-#ifdef MC_MEM_TRACES
- mobicore_log_read();
-#endif /* MC_MEM_TRACES */
-
- switch (event) {
- case PM_SUSPEND_PREPARE:
- /*
- * Make sure we have finished all the work otherwise
- * we end up in a race condition
- */
- cancel_work_sync(&suspend_work);
- /*
- * We can't go to sleep if MobiCore is not IDLE
- * or not Ready to sleep
- */
- dump_sleep_params(&mcp->flags);
- if (!sleep_ready()) {
- ctx->mcp->flags.sleep_mode.sleep_req = REQ_TO_SLEEP;
- schedule_work_on(0, &suspend_work);
- flush_work(&suspend_work);
- if (!sleep_ready()) {
- dump_sleep_params(&mcp->flags);
- ctx->mcp->flags.sleep_mode.sleep_req = 0;
- MCDRV_DBG_ERROR(mcd, "MobiCore can't SLEEP!");
- return NOTIFY_BAD;
- }
- }
- break;
- case PM_POST_SUSPEND:
- MCDRV_DBG(mcd, "Resume MobiCore system!");
- ctx->mcp->flags.sleep_mode.sleep_req = 0;
- break;
- default:
- break;
- }
- return 0;
-}
-
-static struct notifier_block mc_notif_block = {
- .notifier_call = mc_suspend_notifier,
-};
-
-int mc_pm_initialize(struct mc_context *context)
-{
- int ret = 0;
-
- ctx = context;
-
- ret = register_pm_notifier(&mc_notif_block);
- if (ret)
- MCDRV_DBG_ERROR(mcd, "device pm register failed");
-
- return ret;
-}
-
-int mc_pm_free(void)
-{
- int ret = unregister_pm_notifier(&mc_notif_block);
- if (ret)
- MCDRV_DBG_ERROR(mcd, "device pm unregister failed");
- return ret;
-}
-
-bool mc_pm_sleep_ready(void)
-{
- if (ctx == 0)
- return true;
- return sleep_ready();
-}
-#endif /* MC_PM_RUNTIME */
-
-#ifdef MC_CRYPTO_CLOCK_MANAGEMENT
-
-int mc_pm_clock_initialize(void)
-{
- int ret = 0;
-
-#ifdef MC_USE_DEVICE_TREE
- /* Get core clk src */
- mc_ce_core_src_clk = clk_get(mcd, "core_clk_src");
- if (IS_ERR(mc_ce_core_src_clk)) {
- ret = PTR_ERR(mc_ce_core_src_clk);
- MCDRV_DBG_ERROR(mcd,
- "cannot get core clock src with error: %d",
- ret);
- goto error;
- } else {
- int ce_opp_freq_hz = QSEE_CE_CLK_100MHZ;
-
- if (of_property_read_u32(mcd->of_node,
- "qcom,ce-opp-freq",
- &ce_opp_freq_hz)) {
- ce_opp_freq_hz = QSEE_CE_CLK_100MHZ;
- MCDRV_DBG_ERROR(mcd,
- "cannot get ce clock frequency. Using %d",
- ce_opp_freq_hz);
- }
- ret = clk_set_rate(mc_ce_core_src_clk, ce_opp_freq_hz);
- if (ret) {
- clk_put(mc_ce_core_src_clk);
- mc_ce_core_src_clk = NULL;
- MCDRV_DBG_ERROR(mcd, "cannot set core clock src rate");
- ret = -EIO;
- goto error;
- }
- }
-#endif /* MC_CRYPTO_CLOCK_MANAGEMENT && MC_USE_DEVICE_TREE */
-
- /* Get core clk */
- mc_ce_core_clk = clk_get(mcd, "core_clk");
- if (IS_ERR(mc_ce_core_clk)) {
- ret = PTR_ERR(mc_ce_core_clk);
- MCDRV_DBG_ERROR(mcd, "cannot get core clock");
- goto error;
- }
- /* Get Interface clk */
- mc_ce_iface_clk = clk_get(mcd, "iface_clk");
- if (IS_ERR(mc_ce_iface_clk)) {
- clk_put(mc_ce_core_clk);
- ret = PTR_ERR(mc_ce_iface_clk);
- MCDRV_DBG_ERROR(mcd, "cannot get iface clock");
- goto error;
- }
- /* Get AXI clk */
- mc_ce_bus_clk = clk_get(mcd, "bus_clk");
- if (IS_ERR(mc_ce_bus_clk)) {
- clk_put(mc_ce_iface_clk);
- clk_put(mc_ce_core_clk);
- ret = PTR_ERR(mc_ce_bus_clk);
- MCDRV_DBG_ERROR(mcd, "cannot get AXI bus clock");
- goto error;
- }
-
- MCDRV_DBG(mcd, "obtained crypto clocks");
- return ret;
-
-error:
- mc_ce_core_clk = NULL;
- mc_ce_iface_clk = NULL;
- mc_ce_bus_clk = NULL;
-
- return ret;
-}
-
-void mc_pm_clock_finalize(void)
-{
- if (mc_ce_bus_clk != NULL)
- clk_put(mc_ce_bus_clk);
-
- if (mc_ce_iface_clk != NULL)
- clk_put(mc_ce_iface_clk);
-
- if (mc_ce_core_clk != NULL)
- clk_put(mc_ce_core_clk);
-
-#ifdef MC_USE_DEVICE_TREE
- if (mc_ce_core_src_clk != NULL)
- clk_put(mc_ce_core_src_clk);
-#endif /* MC_CRYPTO_CLOCK_MANAGEMENT && MC_USE_DEVICE_TREE */
-}
-
-int mc_pm_clock_enable(void)
-{
- int rc = 0;
-
- rc = clk_prepare_enable(mc_ce_core_clk);
- if (rc) {
- MCDRV_DBG_ERROR(mcd, "cannot enable clock");
- } else {
- rc = clk_prepare_enable(mc_ce_iface_clk);
- if (rc) {
- clk_disable_unprepare(mc_ce_core_clk);
- MCDRV_DBG_ERROR(mcd, "cannot enable clock");
- } else {
- rc = clk_prepare_enable(mc_ce_bus_clk);
- if (rc) {
- clk_disable_unprepare(mc_ce_iface_clk);
- MCDRV_DBG_ERROR(mcd, "cannot enable clock");
- }
- }
- }
- return rc;
-}
-
-void mc_pm_clock_disable(void)
-{
- if (mc_ce_iface_clk != NULL)
- clk_disable_unprepare(mc_ce_iface_clk);
-
- if (mc_ce_core_clk != NULL)
- clk_disable_unprepare(mc_ce_core_clk);
-
- if (mc_ce_bus_clk != NULL)
- clk_disable_unprepare(mc_ce_bus_clk);
-}
-
-#endif /* MC_CRYPTO_CLOCK_MANAGEMENT */
diff --git a/drivers/gud/MobiCoreDriver/pm.h b/drivers/gud/MobiCoreDriver/pm.h
deleted file mode 100644
index 6581425a71cb..000000000000
--- a/drivers/gud/MobiCoreDriver/pm.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-#ifndef _MC_PM_H_
-#define _MC_PM_H_
-
-#include "main.h"
-#ifdef MC_BL_NOTIFIER
-#include <asm/bL_switcher.h>
-#endif
-
-
-#define NO_SLEEP_REQ 0
-#define REQ_TO_SLEEP 1
-
-#define NORMAL_EXECUTION 0
-#define READY_TO_SLEEP 1
-
-/* How much time after resume the daemon should backoff */
-#define DAEMON_BACKOFF_TIME 500
-
-/* Initialize Power Management */
-int mc_pm_initialize(struct mc_context *context);
-/* Free all Power Management resources*/
-int mc_pm_free(void);
-/* Initialize secure crypto clocks */
-int mc_pm_clock_initialize(void);
-/* Free secure crypto clocks */
-void mc_pm_clock_finalize(void);
-/* Enable secure crypto clocks */
-int mc_pm_clock_enable(void);
-/* Disable secure crypto clocks */
-void mc_pm_clock_disable(void);
-/* Test if sleep is possible */
-bool mc_pm_sleep_ready(void);
-
-#endif /* _MC_PM_H_ */
diff --git a/drivers/gud/MobiCoreDriver/public/mc_kernel_api.h b/drivers/gud/MobiCoreDriver/public/mc_kernel_api.h
deleted file mode 100644
index 96805fda11f1..000000000000
--- a/drivers/gud/MobiCoreDriver/public/mc_kernel_api.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-/*
- * Interface to be used by module MobiCoreKernelAPI.
- */
-#ifndef _MC_KERNEL_API_H_
-#define _MC_KERNEL_API_H_
-
-struct mc_instance;
-
-/*
- * mobicore_open() - Initialize a new MobiCore API instance object
- *
- * Returns a MobiCore Instance or NULL if no allocation was possible.
- */
-struct mc_instance *mobicore_open(void);
-
-/*
- * mobicore_release() - Release a MobiCore instance object
- * @instance: MobiCore instance
- *
- * Returns 0 if Ok or -E ERROR
- */
-int mobicore_release(struct mc_instance *instance);
-
-/*
- * mobicore_allocate_wsm() - Allocate MobiCore WSM
- * @instance: instance data for MobiCore Daemon and TLCs
- * @requested_size: memory size requested in bytes
- * @handle: pointer to handle
- * @kernel_virt_addr: virtual user start address
- *
- * Returns 0 if OK
- */
-int mobicore_allocate_wsm(struct mc_instance *instance,
- unsigned long requested_size, uint32_t *handle,
- void **virt_kernel_addr);
-
-/*
- * mobicore_free() - Free a WSM buffer allocated with mobicore_allocate_wsm
- * @instance: instance data for MobiCore Daemon and TLCs
- * @handle: handle of the buffer
- *
- * Returns 0 if OK
- */
-int mobicore_free_wsm(struct mc_instance *instance, uint32_t handle);
-
-/*
- * mobicore_map_vmem() - Map a virtual memory buffer structure to Mobicore
- * @instance: instance data for MobiCore Daemon and TLCs
- * @addr: address of the buffer (NB it must be kernel virtual!)
- * @len: buffer length (in bytes)
- * @handle: unique handle
- *
- * Returns 0 if no error
- */
-int mobicore_map_vmem(struct mc_instance *instance, void *addr,
- uint32_t len, uint32_t *handle);
-
-/*
- * mobicore_unmap_vmem() - Unmap a virtual memory buffer from MobiCore
- * @instance: instance data for MobiCore Daemon and TLCs
- * @handle: unique handle
- *
- * Returns 0 if no error
- */
-int mobicore_unmap_vmem(struct mc_instance *instance, uint32_t handle);
-
-/*
- * mobicore_sleep_ready() - Test if mobicore can sleep
- *
- * Returns true if mobicore can sleep, false if it can't sleep
- */
-bool mobicore_sleep_ready(void);
-
-
-#endif /* _MC_KERNEL_API_H_ */
diff --git a/drivers/gud/MobiCoreDriver/public/mc_linux.h b/drivers/gud/MobiCoreDriver/public/mc_linux.h
deleted file mode 100644
index d1d8e81893e8..000000000000
--- a/drivers/gud/MobiCoreDriver/public/mc_linux.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (c) 2013-2014 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-
-#ifndef _MC_LINUX_H_
-#define _MC_LINUX_H_
-
-#include "version.h"
-
-#ifndef __KERNEL__
-#include <stdint.h>
-#endif
-
-#define MC_ADMIN_DEVNODE "mobicore"
-#define MC_USER_DEVNODE "mobicore-user"
-
-/*
- * Data exchange structure of the MC_DRV_MODULE_INIT ioctl command.
- * INIT request data to SWD
- */
-struct mc_ioctl_init {
- /* length of notification queue */
- uint32_t nq_length;
- /* mcp buffer start/length [16:16] [start, length] */
- uint32_t mcp_offset;
- /* length of mcp buffer */
- uint32_t mcp_length;
-};
-
-/*
- * Data exchange structure of the MC_DRV_MODULE_INFO ioctl command.
- * INFO request data to the SWD
- */
-struct mc_ioctl_info {
- uint32_t ext_info_id; /* extended info ID */
- uint32_t state; /* state */
- uint32_t ext_info; /* extended info */
-};
-
-/*
- * Data exchange structure of the MC_IO_MAP_WSM and MC_IO_MAP_MCI commands.
- *
- * Allocate a contiguous memory buffer for a process.
- * The physical address can be used as for later calls to mmap.
- * The handle can be used to communicate about this buffer to the Daemon.
- * For MC_IO_MAP_MCI command, the reused field indicates that MCI was set up
- * already. I.e. Daemon was restarted.
- */
-struct mc_ioctl_map {
- uint32_t len; /* Buffer length */
- uint32_t handle; /* WSM handle */
- uint64_t phys_addr; /* physical address of WSM (or 0) */
- uint32_t rfu;
- bool reused; /* if WSM memory was reused, or new allocated */
-};
-
-/*
- * Data exchange structure of the MC_IO_REG_WSM command.
- *
- * Allocates a physical MMU table and maps the buffer into this page.
- * Returns the physical address of the MMU table.
- * The page alignment will be created and the appropriated pSize and pOffsetMMU
- * will be modified to the used values.
- *
- * We assume the 64 bit compatible one to be the default and the
- * 32 bit one to be the compat one but we must serve both of them.
- */
-struct mc_compat_ioctl_reg_wsm {
- uint32_t buffer; /* base address of the virtual address */
- uint32_t len; /* size of the virtual address space */
- uint32_t pid; /* process id */
- uint32_t handle; /* driver handle for locked memory */
- uint64_t table_phys; /* physical address of the MMU table */
-};
-
-struct mc_ioctl_reg_wsm {
- uint64_t buffer; /* base address of the virtual address */
- uint32_t len; /* size of the virtual address space */
- uint32_t pid; /* process id */
- uint32_t handle; /* driver handle for locked memory */
- uint64_t table_phys;/* physical address of the MMU table */
-};
-
-/*
- * Data exchange structure of the MC_IO_RESOLVE_CONT_WSM ioctl command.
- */
-struct mc_ioctl_resolv_cont_wsm {
- /* driver handle for buffer */
- uint32_t handle;
- /* length memory */
- uint32_t length;
- /* base address of memory */
- uint64_t phys;
- /* fd to owner of the buffer */
- int32_t fd;
-};
-
-/*
- * Data exchange structure of the MC_IO_RESOLVE_WSM ioctl command.
- */
-struct mc_ioctl_resolv_wsm {
- /* driver handle for buffer */
- uint32_t handle;
- /* fd to owner of the buffer */
- int32_t fd;
- /* base address of memory */
- uint64_t phys;
-};
-
-
-/*
- * defines for the ioctl mobicore driver module function call from user space.
- */
-/* MobiCore IOCTL magic number */
-#define MC_IOC_MAGIC 'M'
-
-#define MC_IO_INIT _IOWR(MC_IOC_MAGIC, 0, struct mc_ioctl_init)
-#define MC_IO_INFO _IOWR(MC_IOC_MAGIC, 1, struct mc_ioctl_info)
-#define MC_IO_VERSION _IOR(MC_IOC_MAGIC, 2, uint32_t)
-/*
- * ioctl parameter to send the YIELD command to the SWD.
- * Only possible in Privileged Mode.
- * ioctl(fd, MC_DRV_MODULE_YIELD)
- */
-#define MC_IO_YIELD _IO(MC_IOC_MAGIC, 3)
-/*
- * ioctl parameter to send the NSIQ signal to the SWD.
- * Only possible in Privileged Mode
- * ioctl(fd, MC_DRV_MODULE_NSIQ)
- */
-#define MC_IO_NSIQ _IO(MC_IOC_MAGIC, 4)
-/*
- * Free's memory which is formerly allocated by the driver's mmap
- * command. The parameter must be this mmaped address.
- * The internal instance data regarding to this address are deleted as
- * well as each according memory page and its appropriated reserved bit
- * is cleared (ClearPageReserved).
- * Usage: ioctl(fd, MC_DRV_MODULE_FREE, &address) with address being of
- * type long address
- */
-#define MC_IO_FREE _IO(MC_IOC_MAGIC, 5)
-/*
- * Creates a MMU Table of the given base address and the size of the
- * data.
- * Parameter: mc_ioctl_reg_wsm
- *
- * Since the end ID is also based on the size of the structure it is
- * safe to use the same ID(6) for both
- */
-#define MC_IO_REG_WSM _IOWR(MC_IOC_MAGIC, 6, struct mc_ioctl_reg_wsm)
-#define MC_COMPAT_REG_WSM _IOWR(MC_IOC_MAGIC, 6, \
- struct mc_compat_ioctl_reg_wsm)
-
-#define MC_IO_UNREG_WSM _IO(MC_IOC_MAGIC, 7)
-#define MC_IO_LOCK_WSM _IO(MC_IOC_MAGIC, 8)
-#define MC_IO_UNLOCK_WSM _IO(MC_IOC_MAGIC, 9)
-
-/*
- * Allocate contiguous memory for a process for later mapping with mmap.
- * MC_IO_MAP_WSM usual operation, pages are registered in
- * device structure and freed later.
- * MC_IO_MAP_MCI get Instance of MCI, allocates or mmaps
- * the MCI to daemon
- */
-#define MC_IO_MAP_WSM _IOWR(MC_IOC_MAGIC, 11, struct mc_ioctl_map)
-#define MC_IO_MAP_MCI _IOWR(MC_IOC_MAGIC, 12, struct mc_ioctl_map)
-
-/*
- * Clean orphaned WSM buffers. Only available to the daemon and should
- * only be carried out if the TLC crashes or otherwise calls exit() in
- * an unexpected manner.
- * The clean is needed together with the lock/unlock mechanism so the daemon
- * has clear control of the mapped buffers so it can close a Trustlet before
- * release all the WSM buffers, otherwise the Trustlet would be able to write
- * to possibly kernel memory areas
- */
-#define MC_IO_CLEAN_WSM _IO(MC_IOC_MAGIC, 14)
-
-/*
- * Get MMU phys address of a buffer handle allocated to the user.
- * Only available to the daemon.
- */
-#define MC_IO_RESOLVE_WSM _IOWR(MC_IOC_MAGIC, 15, \
- struct mc_ioctl_resolv_wsm)
-
-/*
- * Get the phys address & length of a allocated contiguous buffer.
- * Only available to the daemon */
-#define MC_IO_RESOLVE_CONT_WSM _IOWR(MC_IOC_MAGIC, 16, \
- struct mc_ioctl_resolv_cont_wsm)
-
-/*
- * Setup the mem traces when called.
- * Only available to the daemon */
-#define MC_IO_LOG_SETUP _IO(MC_IOC_MAGIC, 17)
-
-#endif /* _MC_LINUX_H_ */
diff --git a/drivers/gud/MobiCoreDriver/public/version.h b/drivers/gud/MobiCoreDriver/public/version.h
deleted file mode 100644
index a4b216e1aeef..000000000000
--- a/drivers/gud/MobiCoreDriver/public/version.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (c) 2013-2014 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-
-#ifndef _MC_DRV_VERSION_H_
-#define _MC_DRV_VERSION_H_
-
-#define MCDRVMODULEAPI_VERSION_MAJOR 1
-#define MCDRVMODULEAPI_VERSION_MINOR 1
-
-#endif /* _MC_DRV_VERSION_H_ */
diff --git a/drivers/gud/MobiCoreKernelApi/Makefile b/drivers/gud/MobiCoreKernelApi/Makefile
deleted file mode 100644
index 1e2017101a8c..000000000000
--- a/drivers/gud/MobiCoreKernelApi/Makefile
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-# this makefile is called from the kernel make syste
-ifeq ($(MODE),release)
- ccflags-y += -O2 -DNDEBUG
-else # DEBUG
- # "-O" is needed to expand inlines
- ccflags-y += -O -g3 -DDEBUG
-endif # DEBUG/RELEASE
-
-ifdef MOBICORE_CFLAGS
- ccflags-y +=$(MOBICORE_CFLAGS)
-endif
-
-#Set the extra symbols
-ifdef MCDRV_SYMBOLS_FILE
- KBUILD_EXTRA_SYMBOLS=$(MCDRV_SYMBOLS_FILE)
-endif
-
-ifeq ($(PLATFORM), ARM_VE_A9X4_QEMU)
- ccflags-y += -DMC_NETLINK_COMPAT_V37
-endif
-
-ifeq ($(PLATFORM), MSM8974_SURF_STD)
- ccflags-y += -DMC_NETLINK_COMPAT_V37
-endif
-
-ifeq ($(PLATFORM), EXYNOS_5422_STD)
- ccflags-y += -DMC_NETLINK_COMPAT_V37
-endif
-
-ifeq ($(PLATFORM), EXYNOS_5430_STD)
- ccflags-y += -DMC_NETLINK_COMPAT_V37
-endif
-
-ifeq ($(PLATFORM), EXYNOS_7410_STD)
- ccflags-y += -DMC_NETLINK_COMPAT_V37
-endif
-
-ifeq ($(PLATFORM), EXYNOS_5433_STD)
- ccflags-y += -DMC_NETLINK_COMPAT_V37
-endif
-
-ifeq ($(PLATFORM), LGE_ODIN_LPAE)
- ccflags-y += -DMC_NETLINK_COMPAT_V37
-endif
-
-ifeq ($(PLATFORM), MSM8084_SURF_STD)
- ccflags-y += -DMC_NETLINK_COMPAT_V37
-endif
-
-ifeq ($(PLATFORM), MSM8916_SURF_STD)
- ccflags-y += -DMC_NETLINK_COMPAT_V37
-endif
-
-
-#EXTRA_CFLAGS += -DDEBUG -DDEBUG_VERBOSE
-#EXTRA_CFLAGS += -Wno-declaration-after-statement
-ccflags-y += -Wno-declaration-after-statement
-# add our module to kernel.
-obj-m += mcKernelApi.o
-
-mcKernelApi-objs := main.o clientlib.o device.o session.o connection.o
-
-clean:
- rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions \
- Module.markers Module.symvers modules.order
-
-depend .depend dep:
- $(CC) $(CFLAGS) -M *.c > .depend
-
-ifeq (.depend,$(wildcard .depend))
- include .depend
-endif
diff --git a/drivers/gud/MobiCoreKernelApi/build.sh b/drivers/gud/MobiCoreKernelApi/build.sh
deleted file mode 100644
index 86fe1b89548c..000000000000
--- a/drivers/gud/MobiCoreKernelApi/build.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/bash
-
-if [ -z $COMP_PATH_ROOT ]; then
- echo "The build environment is not set!"
- echo "Trying to source setupDrivers.sh automatically!"
- source ../setupDrivers.sh || exit 1
-fi
-
-ROOT_PATH=$(dirname $(readlink -f $BASH_SOURCE))
-# These folders need to be relative to the kernel dir or absolute!
-PLATFORM=EXYNOS_4X12_STD
-CODE_INCLUDE=$(readlink -f $ROOT_PATH/Locals/Code)
-
-MOBICORE_DRIVER=$COMP_PATH_MobiCoreDriverMod
-MOBICORE_DAEMON=$COMP_PATH_MobiCoreDriverLib/Public
-MOBICORE_CFLAGS="-I$MOBICORE_DRIVER/Public -I$MOBICORE_DAEMON -I$COMP_PATH_MobiCore/inc/Mci -I$COMP_PATH_MobiCore/inc -I$CODE_INCLUDE/include -I$CODE_INCLUDE/public"
-MCDRV_SYMBOLS_FILE="$COMP_PATH_ROOT/MobiCoreDriverMod/Locals/Code/Module.symvers"
-
-if [ ! -f $MCDRV_SYMBOLS_FILE ]; then
- echo "Please build the Mobicore Driver Module first!"
- echo "Otherwise you will see warnings of missing symbols"
-fi
-
-# Clean first
-make -C $CODE_INCLUDE clean
-
-make -C $LINUX_PATH \
- MODE=$MODE \
- ARCH=arm \
- CROSS_COMPILE=$CROSS_COMPILE \
- M=$CODE_INCLUDE \
- "MOBICORE_CFLAGS=$MOBICORE_CFLAGS" \
- MCDRV_SYMBOLS_FILE=$MCDRV_SYMBOLS_FILE \
- modules
diff --git a/drivers/gud/MobiCoreKernelApi/clientlib.c b/drivers/gud/MobiCoreKernelApi/clientlib.c
deleted file mode 100644
index 57133805eeb8..000000000000
--- a/drivers/gud/MobiCoreKernelApi/clientlib.c
+++ /dev/null
@@ -1,1068 +0,0 @@
-/*
- * Copyright (c) 2013-2014 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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/module.h>
-#include <linux/init.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/netlink.h>
-#include <net/sock.h>
-#include <net/net_namespace.h>
-#include <linux/list.h>
-
-#include "public/mobicore_driver_api.h"
-#include "public/mobicore_driver_cmd.h"
-#include "include/mcinq.h"
-#include "device.h"
-#include "session.h"
-
-/* device list */
-LIST_HEAD(devices);
-atomic_t device_usage = ATOMIC_INIT(0);
-
-static struct mcore_device_t *resolve_device_id(uint32_t device_id)
-{
- struct mcore_device_t *tmp;
- struct list_head *pos;
-
- /* Get mcore_device_t for device_id */
- list_for_each(pos, &devices) {
- tmp = list_entry(pos, struct mcore_device_t, list);
- if (tmp->device_id == device_id)
- return tmp;
- }
- return NULL;
-}
-
-static void add_device(struct mcore_device_t *device)
-{
- list_add_tail(&(device->list), &devices);
-}
-
-static bool remove_device(uint32_t device_id)
-{
- struct mcore_device_t *tmp;
- struct list_head *pos, *q;
-
- list_for_each_safe(pos, q, &devices) {
- tmp = list_entry(pos, struct mcore_device_t, list);
- if (tmp->device_id == device_id) {
- list_del(pos);
- mcore_device_cleanup(tmp);
- return true;
- }
- }
- return false;
-}
-
-enum mc_result mc_open_device(uint32_t device_id)
-{
- enum mc_result mc_result = MC_DRV_OK;
- struct connection *dev_con = NULL;
-
- MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
-
- do {
- struct mcore_device_t *device = resolve_device_id(device_id);
- if (device != NULL) {
- MCDRV_DBG(mc_kapi,
- "Device %d already opened\n", device_id);
- atomic_inc(&device_usage);
- mc_result = MC_DRV_OK;
- break;
- }
-
- /* Open new connection to device */
- dev_con = connection_new();
- if (dev_con == NULL) {
- mc_result = MC_DRV_ERR_NO_FREE_MEMORY;
- break;
- }
-
- if (!connection_connect(dev_con, MC_DAEMON_PID)) {
- MCDRV_DBG_ERROR(
- mc_kapi,
- "Could not setup netlink connection to PID %u",
- MC_DAEMON_PID);
- mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
- break;
- }
-
- /* Forward device open to the daemon and read result */
- struct mc_drv_cmd_open_device_t mc_drv_cmd_open_device = {
- {
- MC_DRV_CMD_OPEN_DEVICE
- },
- {
- device_id
- }
- };
-
- int len = connection_write_data(
- dev_con,
- &mc_drv_cmd_open_device,
- sizeof(struct mc_drv_cmd_open_device_t));
- if (len < 0) {
- MCDRV_DBG_ERROR(mc_kapi,
- "CMD_OPEN_DEVICE writeCmd failed %d",
- len);
- mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
- break;
- }
-
- struct mc_drv_response_header_t rsp_header;
- memset(&rsp_header, 0, sizeof(rsp_header));
- len = connection_read_datablock(
- dev_con,
- &rsp_header,
- sizeof(rsp_header));
- if (len != sizeof(rsp_header)) {
- MCDRV_DBG_ERROR(mc_kapi,
- "CMD_OPEN_DEVICE readRsp failed %d",
- len);
- mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
- break;
- }
- if (rsp_header.response_id != MC_DRV_RSP_OK) {
- MCDRV_DBG_ERROR(mc_kapi,
- "CMD_OPEN_DEVICE failed, respId=%d",
- rsp_header.response_id);
- switch (rsp_header.response_id) {
- case MC_DRV_RSP_PAYLOAD_LENGTH_ERROR:
- mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
- break;
- case MC_DRV_INVALID_DEVICE_NAME:
- mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
- break;
- case MC_DRV_RSP_DEVICE_ALREADY_OPENED:
- default:
- mc_result = MC_DRV_ERR_INVALID_OPERATION;
- break;
- }
- break;
- }
-
- /* there is no payload to read */
-
- device = mcore_device_create(device_id, dev_con);
- if (device == NULL) {
- mc_result = MC_DRV_ERR_NO_FREE_MEMORY;
- break;
- }
- if (!mcore_device_open(device, MC_DRV_MOD_DEVNODE_FULLPATH)) {
- mcore_device_cleanup(device);
- MCDRV_DBG_ERROR(mc_kapi,
- "could not open device file: %s",
- MC_DRV_MOD_DEVNODE_FULLPATH);
- mc_result = MC_DRV_ERR_INVALID_DEVICE_FILE;
- break;
- }
-
- add_device(device);
- atomic_inc(&device_usage);
-
- } while (false);
-
- if (mc_result != MC_DRV_OK)
- connection_cleanup(dev_con);
-
- return mc_result;
-}
-EXPORT_SYMBOL(mc_open_device);
-
-enum mc_result mc_close_device(uint32_t device_id)
-{
- enum mc_result mc_result = MC_DRV_OK;
-
- MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
-
- do {
- struct mcore_device_t *device = resolve_device_id(device_id);
- if (device == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Device not found");
- mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
- break;
- }
- /* Check if it's not used by other modules */
- if (!atomic_dec_and_test(&device_usage)) {
- mc_result = MC_DRV_OK;
- break;
- }
-
- struct connection *dev_con = device->connection;
-
- /* Return if not all sessions have been closed */
- if (mcore_device_has_sessions(device)) {
- MCDRV_DBG_ERROR(mc_kapi,
- "cannot close with sessions pending");
- mc_result = MC_DRV_ERR_SESSION_PENDING;
- break;
- }
-
- struct mc_drv_cmd_close_device_t mc_drv_cmd_close_device = {
- {
- MC_DRV_CMD_CLOSE_DEVICE
- }
- };
- int len = connection_write_data(
- dev_con,
- &mc_drv_cmd_close_device,
- sizeof(struct mc_drv_cmd_close_device_t));
- /* ignore error, but log details */
- if (len < 0) {
- MCDRV_DBG_ERROR(mc_kapi,
- "CMD_CLOSE_DEVICE writeCmd failed %d",
- len);
- mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
- }
-
- struct mc_drv_response_header_t rsp_header;
- memset(&rsp_header, 0, sizeof(rsp_header));
- len = connection_read_datablock(
- dev_con,
- &rsp_header,
- sizeof(rsp_header));
- if (len != sizeof(rsp_header)) {
- MCDRV_DBG_ERROR(mc_kapi,
- "CMD_CLOSE_DEVICE readResp failed %d",
- len);
- mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
- break;
- }
-
- if (rsp_header.response_id != MC_DRV_RSP_OK) {
- MCDRV_DBG_ERROR(mc_kapi,
- "CMD_CLOSE_DEVICE failed, respId=%d",
- rsp_header.response_id);
- mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
- break;
- }
-
- remove_device(device_id);
-
- } while (false);
-
- return mc_result;
-}
-EXPORT_SYMBOL(mc_close_device);
-
-enum mc_result mc_open_session(struct mc_session_handle *session,
- const struct mc_uuid_t *uuid,
- uint8_t *tci, uint32_t tci_len)
-{
- enum mc_result mc_result = MC_DRV_OK;
-
- MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
-
- do {
- if (session == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Session is null");
- mc_result = MC_DRV_ERR_INVALID_PARAMETER;
- break;
- }
- if (uuid == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "UUID is null");
- mc_result = MC_DRV_ERR_INVALID_PARAMETER;
- break;
- }
- if (tci == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "TCI is null");
- mc_result = MC_DRV_ERR_INVALID_PARAMETER;
- break;
- }
- if (tci_len > MC_MAX_TCI_LEN) {
- MCDRV_DBG_ERROR(mc_kapi, "TCI length is longer than %d",
- MC_MAX_TCI_LEN);
- mc_result = MC_DRV_ERR_INVALID_PARAMETER;
- break;
- }
-
- /* Get the device associated with the given session */
- struct mcore_device_t *device =
- resolve_device_id(session->device_id);
- if (device == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Device not found");
- mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
- break;
- }
- struct connection *dev_con = device->connection;
-
- /* Get the wsm of the given TCI */
- struct wsm *wsm =
- mcore_device_find_contiguous_wsm(device, tci);
- if (wsm == NULL) {
- MCDRV_DBG_ERROR(mc_kapi,
- "Could not resolve TCI address ");
- mc_result = MC_DRV_ERR_INVALID_PARAMETER;
- break;
- }
-
- if (wsm->len < tci_len) {
- MCDRV_DBG_ERROR(mc_kapi,
- "length is more than allocated TCI");
- mc_result = MC_DRV_ERR_INVALID_PARAMETER;
- break;
- }
-
- /* Prepare open session command */
- struct mc_drv_cmd_open_session_t cmd_open_session = {
- {
- MC_DRV_CMD_OPEN_SESSION
- },
- {
- session->device_id,
- *uuid,
- (uint32_t)((uintptr_t)(wsm->virt_addr) & 0xFFF),
- wsm->handle,
- tci_len
- }
- };
-
- /* Transmit command data */
- int len = connection_write_data(dev_con,
- &cmd_open_session,
- sizeof(cmd_open_session));
- if (len != sizeof(cmd_open_session)) {
- MCDRV_DBG_ERROR(mc_kapi,
- "CMD_OPEN_SESSION writeData failed %d",
- len);
- mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
- break;
- }
-
- /* Read command response */
-
- /* read header first */
- struct mc_drv_response_header_t rsp_header;
- memset(&rsp_header, 0, sizeof(rsp_header));
- len = connection_read_datablock(dev_con,
- &rsp_header,
- sizeof(rsp_header));
- if (len != sizeof(rsp_header)) {
- MCDRV_DBG_ERROR(mc_kapi,
- "CMD_OPEN_SESSION readResp failed %d",
- len);
- mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
- break;
- }
-
- if (rsp_header.response_id != MC_DRV_RSP_OK) {
- MCDRV_DBG_ERROR(mc_kapi,
- "CMD_OPEN_SESSION failed, respId=%d",
- rsp_header.response_id);
- switch (rsp_header.response_id) {
- case MC_DRV_RSP_TRUSTLET_NOT_FOUND:
- mc_result = MC_DRV_ERR_INVALID_DEVICE_FILE;
- break;
- case MC_DRV_RSP_PAYLOAD_LENGTH_ERROR:
- case MC_DRV_RSP_DEVICE_NOT_OPENED:
- case MC_DRV_RSP_FAILED:
- default:
- mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
- break;
- }
- break;
- }
-
- /* read payload */
- struct mc_drv_rsp_open_session_payload_t
- rsp_open_session_payload;
- memset(&rsp_open_session_payload, 0,
- sizeof(rsp_open_session_payload));
- len = connection_read_datablock(
- dev_con,
- &rsp_open_session_payload,
- sizeof(rsp_open_session_payload));
- if (len != sizeof(rsp_open_session_payload)) {
- MCDRV_DBG_ERROR(mc_kapi,
- "CMD_OPEN_SESSION readPayload fail %d",
- len);
- mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
- break;
- }
-
- /* Register session with handle */
- session->session_id = rsp_open_session_payload.session_id;
-
- /* Set up second channel for notifications */
- struct connection *session_connection = connection_new();
- if (session_connection == NULL) {
- mc_result = MC_DRV_ERR_NO_FREE_MEMORY;
- break;
- }
-
- if (!connection_connect(session_connection, MC_DAEMON_PID)) {
- MCDRV_DBG_ERROR(
- mc_kapi,
- "Could not setup netlink connection to PID %u",
- MC_DAEMON_PID);
- connection_cleanup(session_connection);
- mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
- break;
- }
-
- /* Write command to use channel for notifications */
- struct mc_drv_cmd_nqconnect_t cmd_nqconnect = {
- {
- MC_DRV_CMD_NQ_CONNECT
- },
- {
- session->device_id,
- session->session_id,
- rsp_open_session_payload.device_session_id,
- rsp_open_session_payload.session_magic
- }
- };
- connection_write_data(session_connection,
- &cmd_nqconnect,
- sizeof(cmd_nqconnect));
-
- /* Read command response, header first */
- len = connection_read_datablock(session_connection,
- &rsp_header,
- sizeof(rsp_header));
- if (len != sizeof(rsp_header)) {
- MCDRV_DBG_ERROR(mc_kapi,
- "CMD_NQ_CONNECT readRsp failed %d",
- len);
- connection_cleanup(session_connection);
- mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
- break;
- }
-
- if (rsp_header.response_id != MC_DRV_RSP_OK) {
- MCDRV_DBG_ERROR(mc_kapi,
- "CMD_NQ_CONNECT failed, respId=%d",
- rsp_header.response_id);
- connection_cleanup(session_connection);
- mc_result = MC_DRV_ERR_NQ_FAILED;
- break;
- }
-
- /* there is no payload. */
-
- /* Session established, new session object must be created */
- if (!mcore_device_create_new_session(device,
- session->session_id,
- session_connection)) {
- connection_cleanup(session_connection);
- mc_result = MC_DRV_ERR_NO_FREE_MEMORY;
- break;
- }
-
- } while (false);
-
- return mc_result;
-}
-EXPORT_SYMBOL(mc_open_session);
-
-enum mc_result mc_close_session(struct mc_session_handle *session)
-{
- enum mc_result mc_result = MC_DRV_OK;
-
- MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
-
- do {
- if (session == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Session is null");
- mc_result = MC_DRV_ERR_INVALID_PARAMETER;
- break;
- }
-
- struct mcore_device_t *device =
- resolve_device_id(session->device_id);
- if (device == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Device not found");
- mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
- break;
- }
- struct connection *dev_con = device->connection;
-
- struct session *nq_session =
- mcore_device_resolve_session_id(device,
- session->session_id);
-
- if (nq_session == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Session not found");
- mc_result = MC_DRV_ERR_UNKNOWN_SESSION;
- break;
- }
-
- /* Write close session command */
- struct mc_drv_cmd_close_session_t cmd_close_session = {
- {
- MC_DRV_CMD_CLOSE_SESSION
- },
- {
- session->session_id,
- }
- };
- connection_write_data(dev_con,
- &cmd_close_session,
- sizeof(cmd_close_session));
-
- /* Read command response */
- struct mc_drv_response_header_t rsp_header;
- memset(&rsp_header, 0, sizeof(rsp_header));
- int len = connection_read_datablock(dev_con,
- &rsp_header,
- sizeof(rsp_header));
- if (len != sizeof(rsp_header)) {
- MCDRV_DBG_ERROR(mc_kapi,
- "CMD_CLOSE_SESSION readRsp failed %d",
- len);
- mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
- break;
- }
-
- if (rsp_header.response_id != MC_DRV_RSP_OK) {
- MCDRV_DBG_ERROR(mc_kapi,
- "CMD_CLOSE_SESSION failed, respId=%d",
- rsp_header.response_id);
- mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
- break;
- }
-
- mcore_device_remove_session(device, session->session_id);
- mc_result = MC_DRV_OK;
-
- } while (false);
-
- return mc_result;
-}
-EXPORT_SYMBOL(mc_close_session);
-
-enum mc_result mc_notify(struct mc_session_handle *session)
-{
- enum mc_result mc_result = MC_DRV_OK;
-
- MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
-
- do {
- if (session == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Session is null");
- mc_result = MC_DRV_ERR_INVALID_PARAMETER;
- break;
- }
-
- struct mcore_device_t *device =
- resolve_device_id(session->device_id);
- if (device == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Device not found");
- mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
- break;
- }
- struct connection *dev_con = device->connection;
-
- struct session *nqsession =
- mcore_device_resolve_session_id(device, session->session_id);
- if (nqsession == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Session not found");
- mc_result = MC_DRV_ERR_UNKNOWN_SESSION;
- break;
- }
-
- struct mc_drv_cmd_notify_t cmd_notify = {
- {
- MC_DRV_CMD_NOTIFY
- },
- {
- session->session_id
- }
- };
-
- connection_write_data(dev_con,
- &cmd_notify,
- sizeof(cmd_notify));
-
- /* Daemon will not return a response */
-
- } while (false);
-
- return mc_result;
-}
-EXPORT_SYMBOL(mc_notify);
-
-enum mc_result mc_wait_notification(struct mc_session_handle *session,
- int32_t timeout)
-{
- enum mc_result mc_result = MC_DRV_OK;
-
- MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
-
- do {
- if (session == NULL) {
- mc_result = MC_DRV_ERR_INVALID_PARAMETER;
- break;
- }
-
- struct mcore_device_t *device =
- resolve_device_id(session->device_id);
- if (device == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Device not found");
- mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
- break;
- }
-
- struct session *nq_session =
- mcore_device_resolve_session_id(device,
- session->session_id);
- if (nq_session == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Session not found");
- mc_result = MC_DRV_ERR_UNKNOWN_SESSION;
- break;
- }
-
- struct connection *nqconnection =
- nq_session->notification_connection;
- uint32_t count = 0;
-
- /* Read notification queue till it's empty */
- for (;;) {
- struct notification notification;
- memset(&notification, 0, sizeof(notification));
- ssize_t num_read =
- connection_read_data(nqconnection,
- &notification,
- sizeof(notification),
- timeout);
- /*
- * Exit on timeout in first run. Later runs have
- * timeout set to 0.
- * -2 means, there is no more data.
- */
- if (count == 0 && num_read == -2) {
- MCDRV_DBG_ERROR(mc_kapi, "read timeout");
- mc_result = MC_DRV_ERR_TIMEOUT;
- break;
- }
- /*
- * After first notification the queue will be
- * drained, Thus we set no timeout for the
- * following reads
- */
- timeout = 0;
-
- if (num_read != sizeof(struct notification)) {
- if (count == 0) {
- /* failure in first read, notify it */
- mc_result = MC_DRV_ERR_NOTIFICATION;
- MCDRV_DBG_ERROR(
- mc_kapi,
- "read notification failed, "
- "%i bytes received", (int)num_read);
- break;
- } else {
- /*
- * Read of the n-th notification
- * failed/timeout. We don't tell the
- * caller, as we got valid notifications
- * before.
- */
- mc_result = MC_DRV_OK;
- break;
- }
- }
-
- count++;
- MCDRV_DBG_VERBOSE(mc_kapi,
- "count=%d, SessionID=%d, Payload=%d",
- count,
- notification.session_id,
- notification.payload);
-
- if (notification.payload != 0) {
- /* Session end point died -> store exit code */
- session_set_error_info(nq_session,
- notification.payload);
-
- mc_result = MC_DRV_INFO_NOTIFICATION;
- break;
- }
- } /* for(;;) */
-
- } while (false);
-
- return mc_result;
-}
-EXPORT_SYMBOL(mc_wait_notification);
-
-enum mc_result mc_malloc_wsm(uint32_t device_id, uint32_t align, uint32_t len,
- uint8_t **wsm, uint32_t wsm_flags)
-{
- enum mc_result mc_result = MC_DRV_ERR_UNKNOWN;
-
- MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
-
- do {
- struct mcore_device_t *device = resolve_device_id(device_id);
- if (device == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Device not found");
- mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
- break;
- }
- if (wsm == NULL) {
- mc_result = MC_DRV_ERR_INVALID_PARAMETER;
- break;
- }
-
- struct wsm *wsm_stack =
- mcore_device_allocate_contiguous_wsm(device, len);
- if (wsm_stack == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Allocation of WSM failed");
- mc_result = MC_DRV_ERR_NO_FREE_MEMORY;
- break;
- }
-
- *wsm = (uint8_t *)wsm_stack->virt_addr;
- mc_result = MC_DRV_OK;
-
- } while (false);
-
- return mc_result;
-}
-EXPORT_SYMBOL(mc_malloc_wsm);
-
-enum mc_result mc_free_wsm(uint32_t device_id, uint8_t *wsm)
-{
- enum mc_result mc_result = MC_DRV_ERR_UNKNOWN;
- struct mcore_device_t *device;
-
-
- MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
-
- do {
- /* Get the device associated wit the given session */
- device = resolve_device_id(device_id);
- if (device == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Device not found");
- mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
- break;
- }
-
- /* find WSM object */
- struct wsm *wsm_stack =
- mcore_device_find_contiguous_wsm(device, wsm);
- if (wsm_stack == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "unknown address");
- mc_result = MC_DRV_ERR_INVALID_PARAMETER;
- break;
- }
-
- /* Free the given virtual address */
- if (!mcore_device_free_contiguous_wsm(device, wsm_stack)) {
- MCDRV_DBG_ERROR(mc_kapi,
- "Free of virtual address failed");
- mc_result = MC_DRV_ERR_FREE_MEMORY_FAILED;
- break;
- }
- mc_result = MC_DRV_OK;
-
- } while (false);
-
- return mc_result;
-}
-EXPORT_SYMBOL(mc_free_wsm);
-
-enum mc_result mc_map(struct mc_session_handle *session_handle, void *buf,
- uint32_t buf_len, struct mc_bulk_map *map_info)
-{
- enum mc_result mc_result = MC_DRV_ERR_UNKNOWN;
-
- MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
-
- do {
- if (session_handle == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "session_handle is null");
- mc_result = MC_DRV_ERR_INVALID_PARAMETER;
- break;
- }
- if (map_info == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "map_info is null");
- mc_result = MC_DRV_ERR_INVALID_PARAMETER;
- break;
- }
- if (buf == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "buf is null");
- mc_result = MC_DRV_ERR_INVALID_PARAMETER;
- break;
- }
-
- /* Determine device the session belongs to */
- struct mcore_device_t *device =
- resolve_device_id(session_handle->device_id);
-
- if (device == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Device not found");
- mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
- break;
- }
- struct connection *dev_con = device->connection;
-
- /* Get session */
- uint32_t session_id = session_handle->session_id;
- struct session *session =
- mcore_device_resolve_session_id(device,
- session_id);
- if (session == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Session not found");
- mc_result = MC_DRV_ERR_UNKNOWN_SESSION;
- break;
- }
-
- /*
- * Register mapped bulk buffer to Kernel Module and keep mapped
- * bulk buffer in mind
- */
- struct bulk_buffer_descriptor *bulk_buf =
- session_add_bulk_buf(session, buf, buf_len);
- if (bulk_buf == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Error mapping bulk buffer");
- mc_result = MC_DRV_ERR_BULK_MAPPING;
- break;
- }
-
- /* Prepare map command */
- uintptr_t offset = (uintptr_t)(bulk_buf->virt_addr) & 0xFFF;
- struct mc_drv_cmd_map_bulk_mem_t mc_drv_cmd_map_bulk_mem = {
- {
- MC_DRV_CMD_MAP_BULK_BUF
- },
- {
- session->session_id,
- bulk_buf->handle,
- 0,
- (uint32_t)offset,
- bulk_buf->len
- }
- };
-
- /* Transmit map command to MobiCore device */
- connection_write_data(dev_con,
- &mc_drv_cmd_map_bulk_mem,
- sizeof(mc_drv_cmd_map_bulk_mem));
-
- /* Read command response */
- struct mc_drv_response_header_t rsp_header;
- memset(&rsp_header, 0, sizeof(rsp_header));
- int len = connection_read_datablock(dev_con,
- &rsp_header,
- sizeof(rsp_header));
- if (len != sizeof(rsp_header)) {
- MCDRV_DBG_ERROR(mc_kapi,
- "CMD_MAP_BULK_BUF readRsp failed %d",
- len);
- mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
- break;
- }
-
- if (rsp_header.response_id != MC_DRV_RSP_OK) {
- MCDRV_DBG_ERROR(mc_kapi,
- "CMD_MAP_BULK_BUF failed, respId=%d",
- rsp_header.response_id);
-
- mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
-
- /*
- * Unregister mapped bulk buffer from Kernel Module and
- * remove mapped bulk buffer from session maintenance
- */
- if (!session_remove_bulk_buf(session, buf)) {
- /* Removing of bulk buffer not possible */
- MCDRV_DBG_ERROR(mc_kapi,
- "Unreg of bulk memory failed");
- }
- break;
- }
-
- struct mc_drv_rsp_map_bulk_mem_payload_t
- rsp_map_bulk_mem_payload;
- memset(&rsp_map_bulk_mem_payload, 0,
- sizeof(rsp_map_bulk_mem_payload));
- connection_read_datablock(dev_con,
- &rsp_map_bulk_mem_payload,
- sizeof(rsp_map_bulk_mem_payload));
-
- /* Set mapping info for Trustlet */
- map_info->secure_virt_addr =
- rsp_map_bulk_mem_payload.secure_virtual_adr;
- map_info->secure_virt_len = buf_len;
- mc_result = MC_DRV_OK;
-
- } while (false);
-
- return mc_result;
-}
-EXPORT_SYMBOL(mc_map);
-
-enum mc_result mc_unmap(struct mc_session_handle *session_handle, void *buf,
- struct mc_bulk_map *map_info)
-{
- enum mc_result mc_result = MC_DRV_ERR_UNKNOWN;
-
- MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
-
- do {
- if (session_handle == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "session_handle is null");
- mc_result = MC_DRV_ERR_INVALID_PARAMETER;
- break;
- }
- if (map_info == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "map_info is null");
- mc_result = MC_DRV_ERR_INVALID_PARAMETER;
- break;
- }
- if (buf == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "buf is null");
- mc_result = MC_DRV_ERR_INVALID_PARAMETER;
- break;
- }
-
- /* Determine device the session belongs to */
- struct mcore_device_t *device =
- resolve_device_id(session_handle->device_id);
- if (device == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Device not found");
- mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
- break;
- }
- struct connection *dev_con = device->connection;
-
- /* Get session */
- uint32_t session_id = session_handle->session_id;
- struct session *session =
- mcore_device_resolve_session_id(device,
- session_id);
- if (session == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Session not found");
- mc_result = MC_DRV_ERR_UNKNOWN_SESSION;
- break;
- }
-
- uint32_t handle = session_find_bulk_buf(session, buf);
- if (handle == 0) {
- MCDRV_DBG_ERROR(mc_kapi, "Buffer not found");
- mc_result = MC_DRV_ERR_BULK_UNMAPPING;
- break;
- }
-
-
- /* Prepare unmap command */
- struct mc_drv_cmd_unmap_bulk_mem_t cmd_unmap_bulk_mem = {
- {
- MC_DRV_CMD_UNMAP_BULK_BUF
- },
- {
- session->session_id,
- handle,
- map_info->secure_virt_addr,
- map_info->secure_virt_len
- }
- };
-
- connection_write_data(dev_con,
- &cmd_unmap_bulk_mem,
- sizeof(cmd_unmap_bulk_mem));
-
- /* Read command response */
- struct mc_drv_response_header_t rsp_header;
- memset(&rsp_header, 0, sizeof(rsp_header));
- int len = connection_read_datablock(dev_con,
- &rsp_header,
- sizeof(rsp_header));
- if (len != sizeof(rsp_header)) {
- MCDRV_DBG_ERROR(mc_kapi,
- "CMD_UNMAP_BULK_BUF readRsp failed %d",
- len);
- mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
- break;
- }
-
- if (rsp_header.response_id != MC_DRV_RSP_OK) {
- MCDRV_DBG_ERROR(mc_kapi,
- "CMD_UNMAP_BULK_BUF failed, respId=%d",
- rsp_header.response_id);
-
- mc_result = MC_DRV_ERR_DAEMON_UNREACHABLE;
- break;
- }
-
- /*struct mc_drv_rsp_unmap_bulk_mem_payload_t
- rsp_unmap_bulk_mem_payload;
- connection_read_datablock(dev_con,
- &rsp_unmap_bulk_mem_payload,
- sizeof(rsp_unmap_bulk_mem_payload));*/
-
- /*
- * Unregister mapped bulk buffer from Kernel Module and
- * remove mapped bulk buffer from session maintenance
- */
- if (!session_remove_bulk_buf(session, buf)) {
- /* Removing of bulk buffer not possible */
- MCDRV_DBG_ERROR(mc_kapi,
- "Unregistering of bulk memory failed");
- mc_result = MC_DRV_ERR_BULK_UNMAPPING;
- break;
- }
-
- mc_result = MC_DRV_OK;
-
- } while (false);
-
- return mc_result;
-}
-EXPORT_SYMBOL(mc_unmap);
-
-enum mc_result mc_get_session_error_code(struct mc_session_handle *session,
- int32_t *last_error)
-{
- enum mc_result mc_result = MC_DRV_OK;
-
- MCDRV_DBG_VERBOSE(mc_kapi, "===%s()===", __func__);
-
- do {
- if (session == NULL || last_error == NULL) {
- mc_result = MC_DRV_ERR_INVALID_PARAMETER;
- break;
- }
-
- /* Get device */
- struct mcore_device_t *device =
- resolve_device_id(session->device_id);
- if (device == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Device not found");
- mc_result = MC_DRV_ERR_UNKNOWN_DEVICE;
- break;
- }
-
- /* Get session */
- uint32_t session_id = session->session_id;
- struct session *nqsession =
- mcore_device_resolve_session_id(device,
- session_id);
- if (nqsession == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Session not found");
- mc_result = MC_DRV_ERR_UNKNOWN_SESSION;
- break;
- }
-
- *last_error = session_get_last_err(nqsession);
-
- } while (false);
-
- return mc_result;
-}
-EXPORT_SYMBOL(mc_get_session_error_code);
-
diff --git a/drivers/gud/MobiCoreKernelApi/common.h b/drivers/gud/MobiCoreKernelApi/common.h
deleted file mode 100644
index b6c404b8b235..000000000000
--- a/drivers/gud/MobiCoreKernelApi/common.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-/*
- * Common data types for use by the MobiCore Kernel API Driver
- */
-#ifndef _MC_KAPI_COMMON_H
-#define _MC_KAPI_COMMON_H
-
-#include "connection.h"
-#include "mcinq.h"
-
-void mcapi_insert_connection(struct connection *connection);
-void mcapi_remove_connection(uint32_t seq);
-unsigned int mcapi_unique_id(void);
-
-#define MC_DAEMON_PID 0xFFFFFFFF
-#define MC_DRV_MOD_DEVNODE_FULLPATH "/dev/mobicore"
-
-/* dummy function helper macro */
-#define DUMMY_FUNCTION() do {} while (0)
-
-/* Found in main.c */
-extern struct device *mc_kapi;
-
-#define MCDRV_ERROR(dev, txt, ...) \
- dev_err(dev, "%s() ### ERROR: " txt, __func__, ##__VA_ARGS__)
-
-#if defined(DEBUG)
-
-/* #define DEBUG_VERBOSE */
-#if defined(DEBUG_VERBOSE)
-#define MCDRV_DBG_VERBOSE MCDRV_DBG
-#else
-#define MCDRV_DBG_VERBOSE(...) DUMMY_FUNCTION()
-#endif
-
-#define MCDRV_DBG(dev, txt, ...) \
- dev_info(dev, "%s(): " txt, __func__, ##__VA_ARGS__)
-
-#define MCDRV_DBG_WARN(dev, txt, ...) \
- dev_warn(dev, "%s() WARNING: " txt, __func__, ##__VA_ARGS__)
-
-#define MCDRV_DBG_ERROR(dev, txt, ...) \
- dev_err(dev, "%s() ### ERROR: " txt, __func__, ##__VA_ARGS__)
-
-#define MCDRV_ASSERT(cond) \
- do { \
- if (unlikely(!(cond))) { \
- panic("mc_kernelapi Assertion failed: %s:%d\n", \
- __FILE__, __LINE__); \
- } \
- } while (0)
-
-#elif defined(NDEBUG)
-
-#define MCDRV_DBG_VERBOSE(...) DUMMY_FUNCTION()
-#define MCDRV_DBG(...) DUMMY_FUNCTION()
-#define MCDRV_DBG_WARN(...) DUMMY_FUNCTION()
-#define MCDRV_DBG_ERROR(...) DUMMY_FUNCTION()
-
-#define MCDRV_ASSERT(...) DUMMY_FUNCTION()
-
-#else
-#error "Define DEBUG or NDEBUG"
-#endif /* [not] defined(DEBUG_MCMODULE) */
-
-#define assert(expr) MCDRV_ASSERT(expr)
-
-#endif /* _MC_KAPI_COMMON_H */
diff --git a/drivers/gud/MobiCoreKernelApi/connection.c b/drivers/gud/MobiCoreKernelApi/connection.c
deleted file mode 100644
index 99e835ff0e9c..000000000000
--- a/drivers/gud/MobiCoreKernelApi/connection.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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/slab.h>
-#include <linux/netlink.h>
-#include <linux/skbuff.h>
-#include <linux/netlink.h>
-#include <linux/semaphore.h>
-#include <linux/time.h>
-#include <net/sock.h>
-#include <net/net_namespace.h>
-
-#include "connection.h"
-#include "common.h"
-
-/* Define the initial state of the Data Available Semaphore */
-#define SEM_NO_DATA_AVAILABLE 0
-
-struct connection *connection_new(void)
-{
- struct connection *conn;
-
- conn = kzalloc(sizeof(*conn), GFP_KERNEL);
- if (conn == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Allocation failure");
- return NULL;
- }
- conn->sequence_magic = mcapi_unique_id();
- mutex_init(&conn->data_lock);
- sema_init(&conn->data_available_sem, SEM_NO_DATA_AVAILABLE);
-
- mcapi_insert_connection(conn);
- return conn;
-}
-
-void connection_cleanup(struct connection *conn)
-{
- if (!conn)
- return;
-
- kfree_skb(conn->skb);
-
- mcapi_remove_connection(conn->sequence_magic);
- kfree(conn);
-}
-
-bool connection_connect(struct connection *conn, pid_t dest)
-{
- /* Nothing to connect */
- conn->peer_pid = dest;
- return true;
-}
-
-size_t connection_read_data_msg(struct connection *conn, void *buffer,
- uint32_t len)
-{
- size_t ret = -1;
- MCDRV_DBG_VERBOSE(mc_kapi,
- "reading connection data %u, connection data left %u",
- len, conn->data_len);
- /* trying to read more than the left data */
- if (len > conn->data_len) {
- ret = conn->data_len;
- memcpy(buffer, conn->data_start, conn->data_len);
- conn->data_len = 0;
- } else {
- ret = len;
- memcpy(buffer, conn->data_start, len);
- conn->data_len -= len;
- conn->data_start += len;
- }
-
- if (conn->data_len == 0) {
- conn->data_start = NULL;
- kfree_skb(conn->skb);
- conn->skb = NULL;
- }
- MCDRV_DBG_VERBOSE(mc_kapi, "read %zu", ret);
- return ret;
-}
-
-size_t connection_read_datablock(struct connection *conn, void *buffer,
- uint32_t len)
-{
- return connection_read_data(conn, buffer, len, -1);
-}
-
-size_t connection_read_data(struct connection *conn, void *buffer, uint32_t len,
- int32_t timeout)
-{
- size_t ret = 0;
-
- MCDRV_ASSERT(buffer != NULL);
- MCDRV_ASSERT(conn->socket_descriptor != NULL);
-
- MCDRV_DBG_VERBOSE(mc_kapi, "read data len = %u for PID = %u",
- len, conn->sequence_magic);
- do {
- /*
- * Wait until data is available or timeout
- * msecs_to_jiffies(-1) -> wait forever for the sem
- */
- if (down_timeout(&(conn->data_available_sem),
- msecs_to_jiffies(timeout))) {
- MCDRV_DBG_VERBOSE(mc_kapi,
- "Timeout reading the data sem");
- ret = -2;
- break;
- }
-
- if (mutex_lock_interruptible(&(conn->data_lock))) {
- MCDRV_DBG_ERROR(mc_kapi,
- "interrupted reading the data sem");
- ret = -1;
- break;
- }
-
- /* Have data, use it */
- if (conn->data_len > 0)
- ret = connection_read_data_msg(conn, buffer, len);
-
- mutex_unlock(&(conn->data_lock));
-
- /* There is still some data left */
- if (conn->data_len > 0)
- up(&conn->data_available_sem);
-
- } while (0);
-
- return ret;
-}
-
-size_t connection_write_data(struct connection *conn, void *buffer,
- uint32_t len)
-{
- struct sk_buff *skb = NULL;
- struct nlmsghdr *nlh;
- int ret = 0;
-
- MCDRV_DBG_VERBOSE(mc_kapi, "buffer length %u from pid %u\n",
- len, conn->sequence_magic);
- do {
- skb = nlmsg_new(NLMSG_SPACE(len), GFP_KERNEL);
- if (!skb) {
- ret = -1;
- break;
- }
-
- nlh = nlmsg_put(skb, 0, conn->sequence_magic, 2,
- NLMSG_LENGTH(len), NLM_F_REQUEST);
- if (!nlh) {
- ret = -1;
- kfree_skb(skb);
- break;
- }
- memcpy(NLMSG_DATA(nlh), buffer, len);
-
- /* netlink_unicast frees skb */
- netlink_unicast(conn->socket_descriptor, skb,
- conn->peer_pid, MSG_DONTWAIT);
- ret = len;
- } while (0);
-
- return ret;
-}
-
-int connection_process(struct connection *conn, struct sk_buff *skb)
-{
- int ret = 0;
- do {
- if (mutex_lock_interruptible(&(conn->data_lock))) {
- MCDRV_DBG_ERROR(mc_kapi,
- "Interrupted getting data semaphore!");
- ret = -1;
- break;
- }
-
- kfree_skb(conn->skb);
-
- /* Get a reference to the incoming skb */
- conn->skb = skb_get(skb);
- if (conn->skb) {
- conn->data_msg = nlmsg_hdr(conn->skb);
- conn->data_len = NLMSG_PAYLOAD(conn->data_msg, 0);
- conn->data_start = NLMSG_DATA(conn->data_msg);
- up(&(conn->data_available_sem));
- }
- mutex_unlock(&(conn->data_lock));
- ret = 0;
- } while (0);
- return ret;
-}
diff --git a/drivers/gud/MobiCoreKernelApi/connection.h b/drivers/gud/MobiCoreKernelApi/connection.h
deleted file mode 100644
index 1b7436635810..000000000000
--- a/drivers/gud/MobiCoreKernelApi/connection.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-#ifndef _MC_KAPI_CONNECTION_H_
-#define _MC_KAPI_CONNECTION_H_
-
-#include <linux/semaphore.h>
-#include <linux/mutex.h>
-
-#include <stddef.h>
-#include <stdbool.h>
-
-struct connection {
- /* Netlink socket */
- struct sock *socket_descriptor;
- /* Random? magic to match requests/answers */
- uint32_t sequence_magic;
-
- struct nlmsghdr *data_msg;
- /* How much connection data is left */
- uint32_t data_len;
- /* Start pointer of remaining data */
- void *data_start;
- struct sk_buff *skb;
-
- /* Data protection lock */
- struct mutex data_lock;
- /* Data protection semaphore */
- struct semaphore data_available_sem;
-
- /* PID address used for local connection */
- pid_t self_pid;
- /* Remote PID for connection */
- pid_t peer_pid;
-
- /* The list param for using the kernel lists */
- struct list_head list;
-};
-
-struct connection *connection_new(void);
-void connection_cleanup(struct connection *conn);
-bool connection_connect(struct connection *conn, pid_t dest);
-size_t connection_read_datablock(struct connection *conn, void *buffer,
- uint32_t len);
-size_t connection_read_data(struct connection *conn, void *buffer,
- uint32_t len, int32_t timeout);
-size_t connection_write_data(struct connection *conn, void *buffer,
- uint32_t len);
-int connection_process(struct connection *conn, struct sk_buff *skb);
-
-#endif /* _MC_KAPI_CONNECTION_H_ */
diff --git a/drivers/gud/MobiCoreKernelApi/device.c b/drivers/gud/MobiCoreKernelApi/device.c
deleted file mode 100644
index e3d54e68c484..000000000000
--- a/drivers/gud/MobiCoreKernelApi/device.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-/*
- * MobiCore client library device management.
- *
- * Device and Trustlet Session management Functions.
- */
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-#include "mc_kernel_api.h"
-#include "public/mobicore_driver_api.h"
-
-#include "device.h"
-#include "common.h"
-
-static struct wsm *wsm_create(void *virt_addr, uint32_t len, uint32_t handle)
-{
- struct wsm *wsm;
-
- wsm = kzalloc(sizeof(*wsm), GFP_KERNEL);
- if (wsm == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Allocation failure");
- return NULL;
- }
- wsm->virt_addr = virt_addr;
- wsm->len = len;
- wsm->handle = handle;
- return wsm;
-}
-
-struct mcore_device_t *mcore_device_create(uint32_t device_id,
- struct connection *connection)
-{
- struct mcore_device_t *dev;
-
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (dev == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Allocation failure");
- return NULL;
- }
- dev->device_id = device_id;
- dev->connection = connection;
-
- INIT_LIST_HEAD(&dev->session_vector);
- INIT_LIST_HEAD(&dev->wsm_mmu_vector);
-
- return dev;
-}
-
-void mcore_device_cleanup(struct mcore_device_t *dev)
-{
- struct session *tmp;
- struct wsm *wsm;
- struct list_head *pos, *q;
-
- /*
- * Delete all session objects. Usually this should not be needed
- * as close_device() requires that all sessions have been closed before.
- */
- list_for_each_safe(pos, q, &dev->session_vector) {
- tmp = list_entry(pos, struct session, list);
- list_del(pos);
- session_cleanup(tmp);
- }
-
- /* Free all allocated WSM descriptors */
- list_for_each_safe(pos, q, &dev->wsm_mmu_vector) {
- wsm = list_entry(pos, struct wsm, list);
- list_del(pos);
- kfree(wsm);
- }
- connection_cleanup(dev->connection);
-
- mcore_device_close(dev);
- kfree(dev);
-}
-
-bool mcore_device_open(struct mcore_device_t *dev, const char *device_name)
-{
- dev->instance = mobicore_open();
- return (dev->instance != NULL);
-}
-
-void mcore_device_close(struct mcore_device_t *dev)
-{
- mobicore_release(dev->instance);
-}
-
-bool mcore_device_has_sessions(struct mcore_device_t *dev)
-{
- return !list_empty(&dev->session_vector);
-}
-
-bool mcore_device_create_new_session(struct mcore_device_t *dev,
- uint32_t session_id,
- struct connection *connection)
-{
- /* Check if session_id already exists */
- if (mcore_device_resolve_session_id(dev, session_id)) {
- MCDRV_DBG_ERROR(mc_kapi,
- " session %u already exists", session_id);
- return false;
- }
- struct session *session =
- session_create(session_id, dev->instance, connection);
- if (session == NULL)
- return false;
- list_add_tail(&(session->list), &(dev->session_vector));
- return true;
-}
-
-bool mcore_device_remove_session(struct mcore_device_t *dev,
- uint32_t session_id)
-{
- bool ret = false;
- struct session *tmp;
- struct list_head *pos, *q;
-
- list_for_each_safe(pos, q, &dev->session_vector) {
- tmp = list_entry(pos, struct session, list);
- if (tmp->session_id == session_id) {
- list_del(pos);
- session_cleanup(tmp);
- ret = true;
- break;
- }
- }
- return ret;
-}
-
-struct session *mcore_device_resolve_session_id(struct mcore_device_t *dev,
- uint32_t session_id)
-{
- struct session *ret = NULL;
- struct session *tmp;
- struct list_head *pos;
-
- /* Get session for session_id */
- list_for_each(pos, &dev->session_vector) {
- tmp = list_entry(pos, struct session, list);
- if (tmp->session_id == session_id) {
- ret = tmp;
- break;
- }
- }
- return ret;
-}
-
-struct wsm *mcore_device_allocate_contiguous_wsm(struct mcore_device_t *dev,
- uint32_t len)
-{
- struct wsm *wsm = NULL;
- do {
- if (len == 0)
- break;
-
- /* Allocate shared memory */
- void *virt_addr;
- uint32_t handle;
- int ret = mobicore_allocate_wsm(dev->instance, len, &handle,
- &virt_addr);
- if (ret != 0)
- break;
-
- /* Register (vaddr) with device */
- wsm = wsm_create(virt_addr, len, handle);
- if (wsm == NULL) {
- mobicore_free_wsm(dev->instance, handle);
- break;
- }
-
- list_add_tail(&(wsm->list), &(dev->wsm_mmu_vector));
-
- } while (0);
-
- return wsm;
-}
-
-bool mcore_device_free_contiguous_wsm(struct mcore_device_t *dev,
- struct wsm *wsm)
-{
- bool ret = false;
- struct wsm *tmp;
- struct list_head *pos;
-
- list_for_each(pos, &dev->wsm_mmu_vector) {
- tmp = list_entry(pos, struct wsm, list);
- if (tmp == wsm) {
- ret = true;
- break;
- }
- }
-
- if (ret) {
- MCDRV_DBG_VERBOSE(mc_kapi,
- "freeWsm virt_addr=0x%p, handle=%d",
- wsm->virt_addr, wsm->handle);
-
- /* ignore return code */
- mobicore_free_wsm(dev->instance, wsm->handle);
-
- list_del(pos);
- kfree(wsm);
- }
- return ret;
-}
-
-struct wsm *mcore_device_find_contiguous_wsm(struct mcore_device_t *dev,
- void *virt_addr)
-{
- struct wsm *wsm;
- struct list_head *pos;
-
- list_for_each(pos, &dev->wsm_mmu_vector) {
- wsm = list_entry(pos, struct wsm, list);
- if (virt_addr == wsm->virt_addr)
- return wsm;
- }
-
- return NULL;
-}
diff --git a/drivers/gud/MobiCoreKernelApi/device.h b/drivers/gud/MobiCoreKernelApi/device.h
deleted file mode 100644
index e73042848e63..000000000000
--- a/drivers/gud/MobiCoreKernelApi/device.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-/*
- * MobiCore client library device management.
- *
- * Device and Trustlet Session management Functions.
- */
-#ifndef _MC_KAPI_DEVICE_H_
-#define _MC_KAPI_DEVICE_H_
-
-#include <linux/list.h>
-
-#include "connection.h"
-#include "session.h"
-#include "wsm.h"
-
-struct mcore_device_t {
- /* MobiCore Trustlet session associated with the device */
- struct list_head session_vector;
- struct list_head wsm_mmu_vector; /* WSM L2 or L3 Table */
-
- uint32_t device_id; /* Device identifier */
- struct connection *connection; /* The device connection */
- struct mc_instance *instance; /* MobiCore Driver instance */
-
- /* The list param for using the kernel lists */
- struct list_head list;
-};
-
-struct mcore_device_t *mcore_device_create(
- uint32_t device_id, struct connection *connection);
-void mcore_device_cleanup(struct mcore_device_t *dev);
-
-
-bool mcore_device_open(struct mcore_device_t *dev, const char *device_name);
-void mcore_device_close(struct mcore_device_t *dev);
-bool mcore_device_has_sessions(struct mcore_device_t *dev);
-bool mcore_device_create_new_session(
- struct mcore_device_t *dev, uint32_t session_id,
- struct connection *connection);
-bool mcore_device_remove_session(
- struct mcore_device_t *dev, uint32_t session_id);
-struct session *mcore_device_resolve_session_id(
- struct mcore_device_t *dev, uint32_t session_id);
-struct wsm *mcore_device_allocate_contiguous_wsm(
- struct mcore_device_t *dev, uint32_t len);
-bool mcore_device_free_contiguous_wsm(
- struct mcore_device_t *dev, struct wsm *wsm);
-struct wsm *mcore_device_find_contiguous_wsm(
- struct mcore_device_t *dev, void *virt_addr);
-
-#endif /* _MC_KAPI_DEVICE_H_ */
diff --git a/drivers/gud/MobiCoreKernelApi/include/mcinq.h b/drivers/gud/MobiCoreKernelApi/include/mcinq.h
deleted file mode 100644
index 30444993b640..000000000000
--- a/drivers/gud/MobiCoreKernelApi/include/mcinq.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-/*
- * Notifications inform the MobiCore runtime environment that information is
- * pending in a WSM buffer.
- *
- * The Trustlet Connector (TLC) and the corresponding Trustlet also utilize
- * this buffer to notify each other about new data within the
- * Trustlet Connector Interface (TCI).
- *
- * The buffer is set up as a queue, which means that more than one
- * notification can be written to the buffer before the switch to the other
- * world is performed. Each side therefore facilitates an incoming and an
- * outgoing queue for communication with the other side.
- *
- * Notifications hold the session ID, which is used to reference the
- * communication partner in the other world.
- * So if, e.g., the TLC in the normal world wants to notify his Trustlet
- * about new data in the TLC buffer
- *
- * Notification queue declarations.
- */
-#ifndef _MCINQ_H_
-#define _MCINQ_H_
-
-/* Minimum and maximum count of elements in the notification queue */
-#define MIN_NQ_ELEM 1 /* Minimum notification queue elements. */
-#define MAX_NQ_ELEM 64 /* Maximum notification queue elements. */
-
-/* Minimum notification length (in bytes). */
-#define MIN_NQ_LEN (MIN_NQ_ELEM * sizeof(notification))
-
-/* Maximum notification length (in bytes). */
-#define MAX_NQ_LEN (MAX_NQ_ELEM * sizeof(notification))
-
-/*
- * MCP session ID is used when directly communicating with the MobiCore
- * (e.g. for starting and stopping of Trustlets).
- */
-#define SID_MCP 0
-/* Invalid session id is returned in case of an error. */
-#define SID_INVALID 0xffffffff
-
-/* Notification data structure. */
-struct notification {
- uint32_t session_id; /* Session ID. */
- int32_t payload; /* Additional notification info */
-};
-
-/*
- * Notification payload codes.
- * 0 indicated a plain simple notification,
- * a positive value is a termination reason from the task,
- * a negative value is a termination reason from MobiCore.
- * Possible negative values are given below.
- */
-enum notification_payload {
- /* task terminated, but exit code is invalid */
- ERR_INVALID_EXIT_CODE = -1,
- /* task terminated due to session end, no exit code available */
- ERR_SESSION_CLOSE = -2,
- /* task terminated due to invalid operation */
- ERR_INVALID_OPERATION = -3,
- /* session ID is unknown */
- ERR_INVALID_SID = -4,
- /* session is not active */
- ERR_SID_NOT_ACTIVE = -5
-};
-
-/*
- * Declaration of the notification queue header.
- * Layout as specified in the data structure specification.
- */
-struct notification_queue_header {
- uint32_t write_cnt; /* Write counter. */
- uint32_t read_cnt; /* Read counter. */
- uint32_t queue_size; /* Queue size. */
-};
-
-/*
- * Queue struct which defines a queue object.
- * The queue struct is accessed by the queue<operation> type of
- * function. elementCnt must be a power of two and the power needs
- * to be smaller than power of uint32_t (obviously 32).
- */
-struct notification_queue {
- /* Queue header. */
- struct notification_queue_header hdr;
- /* Notification elements. */
- struct notification notification[MIN_NQ_ELEM];
-};
-
-#endif /* _MCINQ_H_ */
diff --git a/drivers/gud/MobiCoreKernelApi/include/mcuuid.h b/drivers/gud/MobiCoreKernelApi/include/mcuuid.h
deleted file mode 100644
index eca5191edf8e..000000000000
--- a/drivers/gud/MobiCoreKernelApi/include/mcuuid.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2013-2014 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-#ifndef _MCUUID_H_
-#define _MCUUID_H_
-
-#define UUID_TYPE
-
-/* Universally Unique Identifier (UUID) according to ISO/IEC 11578. */
-struct mc_uuid_t {
- uint8_t value[16]; /* Value of the UUID. */
-};
-
-#endif /* _MCUUID_H_ */
diff --git a/drivers/gud/MobiCoreKernelApi/main.c b/drivers/gud/MobiCoreKernelApi/main.c
deleted file mode 100644
index 405f84058c63..000000000000
--- a/drivers/gud/MobiCoreKernelApi/main.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 2013-2014 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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/module.h>
-#include <linux/init.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/netlink.h>
-#include <linux/kthread.h>
-#include <linux/device.h>
-#include <net/sock.h>
-
-#include <linux/list.h>
-
-#include "connection.h"
-#include "common.h"
-
-#define MC_DAEMON_NETLINK 17
-
-struct mc_kernelapi_ctx {
- struct sock *sk;
- struct list_head peers;
- atomic_t counter;
-};
-
-struct mc_kernelapi_ctx *mod_ctx;
-
-/* Define a MobiCore Kernel API device structure for use with dev_debug() etc */
-struct device_driver mc_kernel_api_name = {
- .name = "mckernelapi"
-};
-
-struct device mc_kernel_api_subname = {
- .init_name = "", /* Set to 'mcapi' at mcapi_init() time */
- .driver = &mc_kernel_api_name
-};
-
-struct device *mc_kapi = &mc_kernel_api_subname;
-
-/* get a unique ID */
-unsigned int mcapi_unique_id(void)
-{
- return (unsigned int)atomic_inc_return(&(mod_ctx->counter));
-}
-
-static struct connection *mcapi_find_connection(uint32_t seq)
-{
- struct connection *tmp;
- struct list_head *pos;
-
- /* Get session for session_id */
- list_for_each(pos, &mod_ctx->peers) {
- tmp = list_entry(pos, struct connection, list);
- if (tmp->sequence_magic == seq)
- return tmp;
- }
-
- return NULL;
-}
-
-void mcapi_insert_connection(struct connection *connection)
-{
- list_add_tail(&(connection->list), &(mod_ctx->peers));
- connection->socket_descriptor = mod_ctx->sk;
-}
-
-void mcapi_remove_connection(uint32_t seq)
-{
- struct connection *tmp;
- struct list_head *pos, *q;
-
- /*
- * Delete all session objects. Usually this should not be needed as
- * closeDevice() requires that all sessions have been closed before.
- */
- list_for_each_safe(pos, q, &mod_ctx->peers) {
- tmp = list_entry(pos, struct connection, list);
- if (tmp->sequence_magic == seq) {
- list_del(pos);
- break;
- }
- }
-}
-
-static int mcapi_process(struct sk_buff *skb, struct nlmsghdr *nlh)
-{
- struct connection *c;
- int seq;
- int ret;
-
- seq = nlh->nlmsg_seq;
- MCDRV_DBG_VERBOSE(mc_kapi, "nlmsg len %d type %d pid 0x%X seq %d\n",
- nlh->nlmsg_len, nlh->nlmsg_type, nlh->nlmsg_pid, seq);
- do {
- c = mcapi_find_connection(seq);
- if (!c) {
- MCDRV_ERROR(mc_kapi,
- "Invalid incoming connection - seq=%u!",
- seq);
- ret = -1;
- break;
- }
-
- /* Pass the buffer to the appropriate connection */
- connection_process(c, skb);
-
- ret = 0;
- } while (false);
- return ret;
-}
-
-static void mcapi_callback(struct sk_buff *skb)
-{
- struct nlmsghdr *nlh = nlmsg_hdr(skb);
- int len = skb->len;
- int err = 0;
-
- while (NLMSG_OK(nlh, len)) {
- err = mcapi_process(skb, nlh);
-
- /* if err or if this message says it wants a response */
- if (err || (nlh->nlmsg_flags & NLM_F_ACK))
- netlink_ack(skb, nlh, err);
-
- nlh = NLMSG_NEXT(nlh, len);
- }
-}
-
-static int __init mcapi_init(void)
-{
- struct netlink_kernel_cfg netlink_cfg;
-
- dev_set_name(mc_kapi, "mcapi");
-
- dev_info(mc_kapi, "Mobicore API module initialized!\n");
-
- netlink_cfg.groups = 0;
- netlink_cfg.flags = 0;
- netlink_cfg.input = mcapi_callback;
- netlink_cfg.cb_mutex = NULL;
- netlink_cfg.bind = NULL;
-
- mod_ctx = kzalloc(sizeof(struct mc_kernelapi_ctx), GFP_KERNEL);
- if (mod_ctx == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Allocation failure");
- return -ENOMEM;
- }
- /* start kernel thread */
- mod_ctx->sk = netlink_kernel_create(&init_net, MC_DAEMON_NETLINK,
- &netlink_cfg);
- if (!mod_ctx->sk) {
- MCDRV_ERROR(mc_kapi, "register of receive handler failed");
- kfree(mod_ctx);
- mod_ctx = NULL;
- return -EFAULT;
- }
-
- INIT_LIST_HEAD(&mod_ctx->peers);
- return 0;
-}
-
-static void __exit mcapi_exit(void)
-{
- dev_info(mc_kapi, "Unloading Mobicore API module.\n");
-
- if (mod_ctx->sk != NULL) {
- netlink_kernel_release(mod_ctx->sk);
- mod_ctx->sk = NULL;
- }
- kfree(mod_ctx);
- mod_ctx = NULL;
-}
-
-module_init(mcapi_init);
-module_exit(mcapi_exit);
-
-MODULE_AUTHOR("Trustonic Limited");
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("MobiCore API driver");
diff --git a/drivers/gud/MobiCoreKernelApi/public/mobicore_driver_api.h b/drivers/gud/MobiCoreKernelApi/public/mobicore_driver_api.h
deleted file mode 100644
index 7bf2a2f66b72..000000000000
--- a/drivers/gud/MobiCoreKernelApi/public/mobicore_driver_api.h
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-/*
- * MobiCore Driver API.
- *
- * The MobiCore (MC) Driver API provides access functions to the MobiCore
- * runtime environment and the contained Trustlets.
- */
-#ifndef _MOBICORE_DRIVER_API_H_
-#define _MOBICORE_DRIVER_API_H_
-
-#define __MC_CLIENT_LIB_API
-
-#include "mcuuid.h"
-
-/*
- * Return values of MobiCore driver functions.
- */
-enum mc_result {
- /* Function call succeeded. */
- MC_DRV_OK = 0,
- /* No notification available. */
- MC_DRV_NO_NOTIFICATION = 1,
- /* Error during notification on communication level. */
- MC_DRV_ERR_NOTIFICATION = 2,
- /* Function not implemented. */
- MC_DRV_ERR_NOT_IMPLEMENTED = 3,
- /* No more resources available. */
- MC_DRV_ERR_OUT_OF_RESOURCES = 4,
- /* Driver initialization failed. */
- MC_DRV_ERR_INIT = 5,
- /* Unknown error. */
- MC_DRV_ERR_UNKNOWN = 6,
- /* The specified device is unknown. */
- MC_DRV_ERR_UNKNOWN_DEVICE = 7,
- /* The specified session is unknown.*/
- MC_DRV_ERR_UNKNOWN_SESSION = 8,
- /* The specified operation is not allowed. */
- MC_DRV_ERR_INVALID_OPERATION = 9,
- /* The response header from the MC is invalid. */
- MC_DRV_ERR_INVALID_RESPONSE = 10,
- /* Function call timed out. */
- MC_DRV_ERR_TIMEOUT = 11,
- /* Can not allocate additional memory. */
- MC_DRV_ERR_NO_FREE_MEMORY = 12,
- /* Free memory failed. */
- MC_DRV_ERR_FREE_MEMORY_FAILED = 13,
- /* Still some open sessions pending. */
- MC_DRV_ERR_SESSION_PENDING = 14,
- /* MC daemon not reachable */
- MC_DRV_ERR_DAEMON_UNREACHABLE = 15,
- /* The device file of the kernel module could not be opened. */
- MC_DRV_ERR_INVALID_DEVICE_FILE = 16,
- /* Invalid parameter. */
- MC_DRV_ERR_INVALID_PARAMETER = 17,
- /* Unspecified error from Kernel Module*/
- MC_DRV_ERR_KERNEL_MODULE = 18,
- /* Error during mapping of additional bulk memory to session. */
- MC_DRV_ERR_BULK_MAPPING = 19,
- /* Error during unmapping of additional bulk memory to session. */
- MC_DRV_ERR_BULK_UNMAPPING = 20,
- /* Notification received, exit code available. */
- MC_DRV_INFO_NOTIFICATION = 21,
- /* Set up of NWd connection failed. */
- MC_DRV_ERR_NQ_FAILED = 22
-};
-
-/*
- * Driver control command.
- */
-enum mc_driver_ctrl {
- /* Return the driver version */
- MC_CTRL_GET_VERSION = 1
-};
-
-/*
- * Structure of Session Handle, includes the Session ID and the Device ID the
- * Session belongs to.
- * The session handle will be used for session-based MobiCore communication.
- * It will be passed to calls which address a communication end point in the
- * MobiCore environment.
- */
-struct mc_session_handle {
- uint32_t session_id; /* MobiCore session ID */
- uint32_t device_id; /* Device ID the session belongs to */
-};
-
-/*
- * Information structure about additional mapped Bulk buffer between the
- * Trustlet Connector (NWd) and the Trustlet (SWd). This structure is
- * initialized from a Trustlet Connector by calling mc_map().
- * In order to use the memory within a Trustlet the Trustlet Connector has to
- * inform the Trustlet with the content of this structure via the TCI.
- */
-struct mc_bulk_map {
- /* The virtual address of the Bulk buffer regarding the address space
- * of the Trustlet, already includes a possible offset! */
- uint32_t secure_virt_addr;
- uint32_t secure_virt_len; /* Length of the mapped Bulk buffer */
-};
-
-/* The default device ID */
-#define MC_DEVICE_ID_DEFAULT 0
-/* Wait infinite for a response of the MC. */
-#define MC_INFINITE_TIMEOUT ((int32_t)(-1))
-/* Do not wait for a response of the MC. */
-#define MC_NO_TIMEOUT 0
-/* TCI/DCI must not exceed 1MiB */
-#define MC_MAX_TCI_LEN 0x100000
-
-/**
- * mc_open_device() - Open a new connection to a MobiCore device.
- * @device_id: Identifier for the MobiCore device to be used.
- * MC_DEVICE_ID_DEFAULT refers to the default device.
- *
- * Initializes all device specific resources required to communicate with a
- * MobiCore instance located on the specified device in the system. If the
- * device does not exist the function will return MC_DRV_ERR_UNKNOWN_DEVICE.
- *
- * Return codes:
- * MC_DRV_OK: operation completed successfully
- * MC_DRV_ERR_INVALID_OPERATION: device already opened
- * MC_DRV_ERR_DAEMON_UNREACHABLE: problems with daemon
- * MC_DRV_ERR_UNKNOWN_DEVICE: device_id unknown
- * MC_DRV_ERR_INVALID_DEVICE_FILE: kernel module under /dev/mobicore
- * cannot be opened
- */
-__MC_CLIENT_LIB_API enum mc_result mc_open_device(uint32_t device_id);
-
-/**
- * mc_close_device() - Close the connection to a MobiCore device.
- * @device_id: Identifier for the MobiCore device.
- *
- * When closing a device, active sessions have to be closed beforehand.
- * Resources associated with the device will be released.
- * The device may be opened again after it has been closed.
- *
- * MC_DEVICE_ID_DEFAULT refers to the default device.
- *
- * Return codes:
- * MC_DRV_OK: operation completed successfully
- * MC_DRV_ERR_UNKNOWN_DEVICE: device id is invalid
- * MC_DRV_ERR_SESSION_PENDING: a session is still open
- * MC_DRV_ERR_DAEMON_UNREACHABLE: problems with daemon occur
- */
-__MC_CLIENT_LIB_API enum mc_result mc_close_device(uint32_t device_id);
-
-/**
- * mc_open_session() - Open a new session to a Trustlet.
- * @session: On success, the session data will be returned
- * @uuid: UUID of the Trustlet to be opened
- * @tci: TCI buffer for communicating with the Trustlet
- * @tci_len: Length of the TCI buffer. Maximum allowed value
- * is MC_MAX_TCI_LEN
- *
- * The Trustlet with the given UUID has to be available in the flash filesystem.
- *
- * Write MCP open message to buffer and notify MobiCore about the availability
- * of a new command.
- *
- * Waits till the MobiCore responses with the new session ID (stored in the MCP
- * buffer).
- *
- * Note that session.device_id has to be the device id of an opened device.
- *
- * Return codes:
- * MC_DRV_OK: operation completed successfully
- * MC_DRV_INVALID_PARAMETER: session parameter is invalid
- * MC_DRV_ERR_UNKNOWN_DEVICE: device id is invalid
- * MC_DRV_ERR_DAEMON_UNREACHABLE: problems with daemon socket occur
- * MC_DRV_ERR_NQ_FAILED: daemon returns an error
- */
-__MC_CLIENT_LIB_API enum mc_result mc_open_session(
- struct mc_session_handle *session, const struct mc_uuid_t *uuid,
- uint8_t *tci, uint32_t tci_len);
-
-/**
- * mc_close_session() - Close a Trustlet session.
- * @session: Session to be closed.
- *
- * Closes the specified MobiCore session. The call will block until the
- * session has been closed.
- *
- * Device device_id has to be opened in advance.
- *
- * Return codes:
- * MC_DRV_OK: operation completed successfully
- * MC_DRV_INVALID_PARAMETER: session parameter is invalid
- * MC_DRV_ERR_UNKNOWN_SESSION: session id is invalid
- * MC_DRV_ERR_UNKNOWN_DEVICE: device id of session is invalid
- * MC_DRV_ERR_DAEMON_UNREACHABLE: problems with daemon occur
- * MC_DRV_ERR_INVALID_DEVICE_FILE: daemon cannot open Trustlet file
- */
-__MC_CLIENT_LIB_API enum mc_result mc_close_session(
- struct mc_session_handle *session);
-
-/**
- * mc_notify() - Notify a session.
- * @session: The session to be notified.
- *
- * Notifies the session end point about available message data.
- * If the session parameter is correct, notify will always succeed.
- * Corresponding errors can only be received by mc_wait_notification().
- *
- * A session has to be opened in advance.
- *
- * Return codes:
- * MC_DRV_OK: operation completed successfully
- * MC_DRV_INVALID_PARAMETER: session parameter is invalid
- * MC_DRV_ERR_UNKNOWN_SESSION: session id is invalid
- * MC_DRV_ERR_UNKNOWN_DEVICE: device id of session is invalid
- */
-__MC_CLIENT_LIB_API enum mc_result mc_notify(struct mc_session_handle *session);
-
-/**
- * mc_wait_notification() - Wait for a notification.
- * @session: The session the notification should correspond to.
- * @timeout: Time in milliseconds to wait
- * (MC_NO_TIMEOUT : direct return, > 0 : milliseconds,
- * MC_INFINITE_TIMEOUT : wait infinitely)
- *
- * Wait for a notification issued by the MobiCore for a specific session.
- * The timeout parameter specifies the number of milliseconds the call will wait
- * for a notification.
- *
- * If the caller passes 0 as timeout value the call will immediately return.
- * If timeout value is below 0 the call will block until a notification for the
- * session has been received.
- *
- * If timeout is below 0, call will block.
- *
- * Caller has to trust the other side to send a notification to wake him up
- * again.
- *
- * Return codes:
- * MC_DRV_OK: operation completed successfully
- * MC_DRV_ERR_TIMEOUT: no notification arrived in time
- * MC_DRV_INFO_NOTIFICATION: a problem with the session was
- * encountered. Get more details with
- * mc_get_session_error_code()
- * MC_DRV_ERR_NOTIFICATION: a problem with the socket occurred
- * MC_DRV_INVALID_PARAMETER: a parameter is invalid
- * MC_DRV_ERR_UNKNOWN_SESSION: session id is invalid
- * MC_DRV_ERR_UNKNOWN_DEVICE: device id of session is invalid
- */
-__MC_CLIENT_LIB_API enum mc_result mc_wait_notification(
- struct mc_session_handle *session, int32_t timeout);
-
-/**
- * mc_malloc_wsm() - Allocate a block of world shared memory (WSM).
- * @device_id: The ID of an opened device to retrieve the WSM from.
- * @align: The alignment (number of pages) of the memory block
- * (e.g. 0x00000001 for 4kb).
- * @len: Length of the block in bytes.
- * @wsm: Virtual address of the world shared memory block.
- * @wsm_flags: Platform specific flags describing the memory to
- * be allocated.
- *
- * The MC driver allocates a contiguous block of memory which can be used as
- * WSM.
- * This implicates that the allocated memory is aligned according to the
- * alignment parameter.
- *
- * Always returns a buffer of size WSM_SIZE aligned to 4K.
- *
- * Align and wsm_flags are currently ignored
- *
- * Return codes:
- * MC_DRV_OK: operation completed successfully
- * MC_DRV_INVALID_PARAMETER: a parameter is invalid
- * MC_DRV_ERR_UNKNOWN_DEVICE: device id is invalid
- * MC_DRV_ERR_NO_FREE_MEMORY: no more contiguous memory is
- * available in this size or for this
- * process
- */
-__MC_CLIENT_LIB_API enum mc_result mc_malloc_wsm(
- uint32_t device_id,
- uint32_t align,
- uint32_t len,
- uint8_t **wsm,
- uint32_t wsm_flags
-);
-
-/**
- * mc_free_wsm() - Free a block of world shared memory (WSM).
- * @device_id: The ID to which the given address belongs
- * @wsm: Address of WSM block to be freed
- *
- * The MC driver will free a block of world shared memory (WSM) previously
- * allocated with mc_malloc_wsm(). The caller has to assure that the address
- * handed over to the driver is a valid WSM address.
- *
- * Return codes:
- * MC_DRV_OK: operation completed successfully
- * MC_DRV_INVALID_PARAMETER: a parameter is invalid
- * MC_DRV_ERR_UNKNOWN_DEVICE: when device id is invalid
- * MC_DRV_ERR_FREE_MEMORY_FAILED: on failure
- */
-__MC_CLIENT_LIB_API enum mc_result mc_free_wsm(uint32_t device_id,
- uint8_t *wsm);
-
-/**
- *mc_map() - Map additional bulk buffer between a Trustlet Connector (TLC)
- * and the Trustlet (TL) for a session
- * @session: Session handle with information of the device_id and
- * the session_id. The given buffer is mapped to the
- * session specified in the sessionHandle
- * @buf: Virtual address of a memory portion (relative to TLC)
- * to be shared with the Trustlet, already includes a
- * possible offset!
- * @len: length of buffer block in bytes.
- * @map_info: Information structure about the mapped Bulk buffer
- * between the TLC (NWd) and the TL (SWd).
- *
- * Memory allocated in user space of the TLC can be mapped as additional
- * communication channel (besides TCI) to the Trustlet. Limitation of the
- * Trustlet memory structure apply: only 6 chunks can be mapped with a maximum
- * chunk size of 1 MiB each.
- *
- * It is up to the application layer (TLC) to inform the Trustlet
- * about the additional mapped bulk memory.
- *
- * Return codes:
- * MC_DRV_OK: operation completed successfully
- * MC_DRV_INVALID_PARAMETER: a parameter is invalid
- * MC_DRV_ERR_UNKNOWN_SESSION: session id is invalid
- * MC_DRV_ERR_UNKNOWN_DEVICE: device id of session is invalid
- * MC_DRV_ERR_DAEMON_UNREACHABLE: problems with daemon occur
- * MC_DRV_ERR_BULK_MAPPING: buf is already uses as bulk buffer or
- * when registering the buffer failed
- */
-__MC_CLIENT_LIB_API enum mc_result mc_map(
- struct mc_session_handle *session, void *buf, uint32_t len,
- struct mc_bulk_map *map_info);
-
-/**
- * mc_unmap() - Remove additional mapped bulk buffer between Trustlet Connector
- * (TLC) and the Trustlet (TL) for a session
- * @session: Session handle with information of the device_id and
- * the session_id. The given buffer is unmapped from the
- * session specified in the sessionHandle.
- * @buf: Virtual address of a memory portion (relative to TLC)
- * shared with the TL, already includes a possible offset!
- * @map_info: Information structure about the mapped Bulk buffer
- * between the TLC (NWd) and the TL (SWd)
- *
- * The bulk buffer will immediately be unmapped from the session context.
- *
- * The application layer (TLC) must inform the TL about unmapping of the
- * additional bulk memory before calling mc_unmap!
- *
- * The clientlib currently ignores the len field in map_info.
- *
- * Return codes:
- * MC_DRV_OK: operation completed successfully
- * MC_DRV_INVALID_PARAMETER: a parameter is invalid
- * MC_DRV_ERR_UNKNOWN_SESSION: session id is invalid
- * MC_DRV_ERR_UNKNOWN_DEVICE: device id of session is invalid
- * MC_DRV_ERR_DAEMON_UNREACHABLE: problems with daemon occur
- * MC_DRV_ERR_BULK_UNMAPPING: buf was not registered earlier
- * or when unregistering failed
- */
-__MC_CLIENT_LIB_API enum mc_result mc_unmap(
- struct mc_session_handle *session, void *buf,
- struct mc_bulk_map *map_info);
-
-/**
- * mc_get_session_error_code() - Get additional error information of the last
- * error that occurred on a session.
- * @session: Session handle with information of the device_id and
- * the session_id
- * @last_error: >0 Trustlet has terminated itself with this value,
- * <0 Trustlet is dead because of an error within the
- * MobiCore (e.g. Kernel exception). See also MCI
- * definition.
- *
- * After the request the stored error code will be deleted.
- *
- * Return codes:
- * MC_DRV_OK: operation completed successfully
- * MC_DRV_INVALID_PARAMETER: a parameter is invalid
- * MC_DRV_ERR_UNKNOWN_SESSION: session id is invalid
- * MC_DRV_ERR_UNKNOWN_DEVICE: device id of session is invalid
- */
-__MC_CLIENT_LIB_API enum mc_result mc_get_session_error_code(
- struct mc_session_handle *session, int32_t *last_error);
-
-#endif /* _MOBICORE_DRIVER_API_H_ */
diff --git a/drivers/gud/MobiCoreKernelApi/public/mobicore_driver_cmd.h b/drivers/gud/MobiCoreKernelApi/public/mobicore_driver_cmd.h
deleted file mode 100644
index 4e6ba0ddf676..000000000000
--- a/drivers/gud/MobiCoreKernelApi/public/mobicore_driver_cmd.h
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-#ifndef _MOBICORE_DRIVER_CMD_H_
-#define _MOBICORE_DRIVER_CMD_H_
-
-#include "mcuuid.h"
-
-enum mc_drv_cmd_t {
- MC_DRV_CMD_PING = 0,
- MC_DRV_CMD_GET_INFO = 1,
- MC_DRV_CMD_OPEN_DEVICE = 2,
- MC_DRV_CMD_CLOSE_DEVICE = 3,
- MC_DRV_CMD_NQ_CONNECT = 4,
- MC_DRV_CMD_OPEN_SESSION = 5,
- MC_DRV_CMD_CLOSE_SESSION = 6,
- MC_DRV_CMD_NOTIFY = 7,
- MC_DRV_CMD_MAP_BULK_BUF = 8,
- MC_DRV_CMD_UNMAP_BULK_BUF = 9
-};
-
-
-enum mc_drv_rsp_t {
- MC_DRV_RSP_OK = 0,
- MC_DRV_RSP_FAILED = 1,
- MC_DRV_RSP_DEVICE_NOT_OPENED = 2,
- MC_DRV_RSP_DEVICE_ALREADY_OPENED = 3,
- MC_DRV_RSP_COMMAND_NOT_ALLOWED = 4,
- MC_DRV_INVALID_DEVICE_NAME = 5,
- MC_DRV_RSP_MAP_BULK_ERRO = 6,
- MC_DRV_RSP_TRUSTLET_NOT_FOUND = 7,
- MC_DRV_RSP_PAYLOAD_LENGTH_ERROR = 8,
-};
-
-
-struct mc_drv_command_header_t {
- uint32_t command_id;
-};
-
-struct mc_drv_response_header_t {
- uint32_t response_id;
-};
-
-#define MC_DEVICE_ID_DEFAULT 0 /* The default device ID */
-
-struct mc_drv_cmd_open_device_payload_t {
- uint32_t device_id;
-};
-
-struct mc_drv_cmd_open_device_t {
- struct mc_drv_command_header_t header;
- struct mc_drv_cmd_open_device_payload_t payload;
-};
-
-
-struct mc_drv_rsp_open_device_payload_t {
- /* empty */
-};
-
-struct mc_drv_rsp_open_device_t {
- struct mc_drv_response_header_t header;
- struct mc_drv_rsp_open_device_payload_t payload;
-};
-
-struct mc_drv_cmd_close_device_t {
- struct mc_drv_command_header_t header;
- /*
- * no payload here because close has none.
- * If we use an empty struct, C++ will count it as 4 bytes.
- * This will write too much into the socket at write(cmd,sizeof(cmd))
- */
-};
-
-
-struct mc_drv_rsp_close_device_payload_t {
- /* empty */
-};
-
-struct mc_drv_rsp_close_device_t {
- struct mc_drv_response_header_t header;
- struct mc_drv_rsp_close_device_payload_t payload;
-};
-
-struct mc_drv_cmd_open_session_payload_t {
- uint32_t device_id;
- struct mc_uuid_t uuid;
- uint32_t tci;
- uint32_t handle;
- uint32_t len;
-};
-
-struct mc_drv_cmd_open_session_t {
- struct mc_drv_command_header_t header;
- struct mc_drv_cmd_open_session_payload_t payload;
-};
-
-
-struct mc_drv_rsp_open_session_payload_t {
- uint32_t session_id;
- uint32_t device_session_id;
- uint32_t session_magic;
-};
-
-struct mc_drv_rsp_open_session_t {
- struct mc_drv_response_header_t header;
- struct mc_drv_rsp_open_session_payload_t payload;
-};
-
-struct mc_drv_cmd_close_session_payload_t {
- uint32_t session_id;
-};
-
-struct mc_drv_cmd_close_session_t {
- struct mc_drv_command_header_t header;
- struct mc_drv_cmd_close_session_payload_t payload;
-};
-
-
-struct mc_drv_rsp_close_session_payload_t {
- /* empty */
-};
-
-struct mc_drv_rsp_close_session_t {
- struct mc_drv_response_header_t header;
- struct mc_drv_rsp_close_session_payload_t payload;
-};
-
-struct mc_drv_cmd_notify_payload_t {
- uint32_t session_id;
-};
-
-struct mc_drv_cmd_notify_t {
- struct mc_drv_command_header_t header;
- struct mc_drv_cmd_notify_payload_t payload;
-};
-
-
-struct mc_drv_rsp_notify_payload_t {
- /* empty */
-};
-
-struct mc_drv_rsp_notify_t {
- struct mc_drv_response_header_t header;
- struct mc_drv_rsp_notify_payload_t payload;
-};
-
-struct mc_drv_cmd_map_bulk_mem_payload_t {
- uint32_t session_id;
- uint32_t handle;
- uint32_t rfu;
- uint32_t offset_payload;
- uint32_t len_bulk_mem;
-};
-
-struct mc_drv_cmd_map_bulk_mem_t {
- struct mc_drv_command_header_t header;
- struct mc_drv_cmd_map_bulk_mem_payload_t payload;
-};
-
-
-struct mc_drv_rsp_map_bulk_mem_payload_t {
- uint32_t session_id;
- uint32_t secure_virtual_adr;
-};
-
-struct mc_drv_rsp_map_bulk_mem_t {
- struct mc_drv_response_header_t header;
- struct mc_drv_rsp_map_bulk_mem_payload_t payload;
-};
-
-struct mc_drv_cmd_unmap_bulk_mem_payload_t {
- uint32_t session_id;
- uint32_t handle;
- uint32_t secure_virtual_adr;
- uint32_t len_bulk_mem;
-};
-
-struct mc_drv_cmd_unmap_bulk_mem_t {
- struct mc_drv_command_header_t header;
- struct mc_drv_cmd_unmap_bulk_mem_payload_t payload;
-};
-
-
-struct mc_drv_rsp_unmap_bulk_mem_payload_t {
- uint32_t response_id;
- uint32_t session_id;
-};
-
-struct mc_drv_rsp_unmap_bulk_mem_t {
- struct mc_drv_response_header_t header;
- struct mc_drv_rsp_unmap_bulk_mem_payload_t payload;
-};
-
-struct mc_drv_cmd_nqconnect_payload_t {
- uint32_t device_id;
- uint32_t session_id;
- uint32_t device_session_id;
- uint32_t session_magic; /* Random data */
-};
-
-struct mc_drv_cmd_nqconnect_t {
- struct mc_drv_command_header_t header;
- struct mc_drv_cmd_nqconnect_payload_t payload;
-};
-
-
-struct mc_drv_rsp_nqconnect_payload_t {
- /* empty; */
-};
-
-struct mc_drv_rsp_nqconnect_t {
- struct mc_drv_response_header_t header;
- struct mc_drv_rsp_nqconnect_payload_t payload;
-};
-
-union mc_drv_command_t {
- struct mc_drv_command_header_t header;
- struct mc_drv_cmd_open_device_t mc_drv_cmd_open_device;
- struct mc_drv_cmd_close_device_t mc_drv_cmd_close_device;
- struct mc_drv_cmd_open_session_t mc_drv_cmd_open_session;
- struct mc_drv_cmd_close_session_t mc_drv_cmd_close_session;
- struct mc_drv_cmd_nqconnect_t mc_drv_cmd_nqconnect;
- struct mc_drv_cmd_notify_t mc_drv_cmd_notify;
- struct mc_drv_cmd_map_bulk_mem_t mc_drv_cmd_map_bulk_mem;
- struct mc_drv_cmd_unmap_bulk_mem_t mc_drv_cmd_unmap_bulk_mem;
-};
-
-union mc_drv_response_t {
- struct mc_drv_response_header_t header;
- struct mc_drv_rsp_open_device_t mc_drv_rsp_open_device;
- struct mc_drv_rsp_close_device_t mc_drv_rsp_close_device;
- struct mc_drv_rsp_open_session_t mc_drv_rsp_open_session;
- struct mc_drv_rsp_close_session_t mc_drv_rsp_close_session;
- struct mc_drv_rsp_nqconnect_t mc_drv_rsp_nqconnect;
- struct mc_drv_rsp_notify_t mc_drv_rsp_notify;
- struct mc_drv_rsp_map_bulk_mem_t mc_drv_rsp_map_bulk_mem;
- struct mc_drv_rsp_unmap_bulk_mem_t mc_drv_rsp_unmap_bulk_mem;
-};
-
-#endif /* _MOBICORE_DRIVER_CMD_H_ */
diff --git a/drivers/gud/MobiCoreKernelApi/session.c b/drivers/gud/MobiCoreKernelApi/session.c
deleted file mode 100644
index 4f14ce904413..000000000000
--- a/drivers/gud/MobiCoreKernelApi/session.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (c) 2013-2014 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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/slab.h>
-#include <linux/device.h>
-#include "mc_kernel_api.h"
-#include "public/mobicore_driver_api.h"
-
-#include "session.h"
-
-struct bulk_buffer_descriptor *bulk_buffer_descriptor_create(
- void *virt_addr, uint32_t len, uint32_t handle)
-{
- struct bulk_buffer_descriptor *desc;
-
- desc = kzalloc(sizeof(*desc), GFP_KERNEL);
- if (desc == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Allocation failure");
- return NULL;
- }
- desc->virt_addr = virt_addr;
- desc->len = len;
- desc->handle = handle;
-
- return desc;
-}
-
-struct session *session_create(
- uint32_t session_id, void *instance, struct connection *connection)
-{
- struct session *session;
-
- session = kzalloc(sizeof(*session), GFP_KERNEL);
- if (session == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Allocation failure");
- return NULL;
- }
- session->session_id = session_id;
- session->instance = instance;
- session->notification_connection = connection;
- session->session_info.last_error = SESSION_ERR_NO;
- session->session_info.state = SESSION_STATE_INITIAL;
-
- INIT_LIST_HEAD(&(session->bulk_buffer_descriptors));
- return session;
-}
-
-void session_cleanup(struct session *session)
-{
- struct bulk_buffer_descriptor *bulk_buf_descr;
- struct list_head *pos, *q;
-
- /* Unmap still mapped buffers */
- list_for_each_safe(pos, q, &session->bulk_buffer_descriptors) {
- bulk_buf_descr =
- list_entry(pos, struct bulk_buffer_descriptor, list);
-
- MCDRV_DBG_VERBOSE(mc_kapi,
- "handle= %d",
- bulk_buf_descr->handle);
-
- /* ignore any error, as we cannot do anything in this case. */
- int ret = mobicore_unmap_vmem(session->instance,
- bulk_buf_descr->handle);
- if (ret != 0)
- MCDRV_DBG_ERROR(mc_kapi,
- "mobicore_unmap_vmem failed: %d", ret);
-
- list_del(pos);
- kfree(bulk_buf_descr);
- }
-
- /* Finally delete notification connection */
- connection_cleanup(session->notification_connection);
- kfree(session);
-}
-
-void session_set_error_info(struct session *session, int32_t err)
-{
- session->session_info.last_error = err;
-}
-
-int32_t session_get_last_err(struct session *session)
-{
- return session->session_info.last_error;
-}
-
-struct bulk_buffer_descriptor *session_add_bulk_buf(struct session *session,
- void *buf, uint32_t len)
-{
- struct bulk_buffer_descriptor *bulk_buf_descr = NULL;
- struct bulk_buffer_descriptor *tmp;
- struct list_head *pos;
-
- /*
- * Search bulk buffer descriptors for existing vAddr
- * At the moment a virtual address can only be added one time
- */
- list_for_each(pos, &session->bulk_buffer_descriptors) {
- tmp = list_entry(pos, struct bulk_buffer_descriptor, list);
- if (tmp->virt_addr == buf)
- return NULL;
- }
-
- do {
- /*
- * Prepare the interface structure for memory registration in
- * Kernel Module
- */
- uint32_t handle;
-
- int ret = mobicore_map_vmem(session->instance, buf, len,
- &handle);
-
- if (ret != 0) {
- MCDRV_DBG_ERROR(mc_kapi,
- "mobicore_map_vmem failed, ret=%d",
- ret);
- break;
- }
-
- MCDRV_DBG_VERBOSE(mc_kapi, "handle=%d", handle);
-
- /* Create new descriptor */
- bulk_buf_descr =
- bulk_buffer_descriptor_create(buf, len, handle);
- if (bulk_buf_descr == NULL) {
- /* Discard the returned value */
- (void)mobicore_unmap_vmem(session->instance, handle);
- break;
- }
-
- /* Add to vector of descriptors */
- list_add_tail(&(bulk_buf_descr->list),
- &(session->bulk_buffer_descriptors));
- } while (0);
-
- return bulk_buf_descr;
-}
-
-bool session_remove_bulk_buf(struct session *session, void *virt_addr)
-{
- bool ret = true;
- struct bulk_buffer_descriptor *bulk_buf = NULL;
- struct bulk_buffer_descriptor *tmp;
- struct list_head *pos, *q;
-
- MCDRV_DBG_VERBOSE(mc_kapi, "Virtual Address = 0x%p",
- virt_addr);
-
- /* Search and remove bulk buffer descriptor */
- list_for_each_safe(pos, q, &session->bulk_buffer_descriptors) {
- tmp = list_entry(pos, struct bulk_buffer_descriptor, list);
- if (tmp->virt_addr == virt_addr) {
- bulk_buf = tmp;
- list_del(pos);
- break;
- }
- }
-
- if (bulk_buf == NULL) {
- MCDRV_DBG_ERROR(mc_kapi, "Virtual Address not found");
- ret = false;
- } else {
- MCDRV_DBG_VERBOSE(mc_kapi, "Wsm handle=%d",
- bulk_buf->handle);
-
- /* ignore any error, as we cannot do anything */
- int ret = mobicore_unmap_vmem(session->instance,
- bulk_buf->handle);
- if (ret != 0)
- MCDRV_DBG_ERROR(mc_kapi,
- "mobicore_unmap_vmem failed: %d", ret);
-
- kfree(bulk_buf);
- }
-
- return ret;
-}
-
-uint32_t session_find_bulk_buf(struct session *session, void *virt_addr)
-{
- struct bulk_buffer_descriptor *tmp;
- struct list_head *pos, *q;
-
- MCDRV_DBG_VERBOSE(mc_kapi, "Virtual Address = 0x%p",
- virt_addr);
-
- /* Search and return buffer descriptor handle */
- list_for_each_safe(pos, q, &session->bulk_buffer_descriptors) {
- tmp = list_entry(pos, struct bulk_buffer_descriptor, list);
- if (tmp->virt_addr == virt_addr)
- return tmp->handle;
- }
-
- return 0;
-}
diff --git a/drivers/gud/MobiCoreKernelApi/session.h b/drivers/gud/MobiCoreKernelApi/session.h
deleted file mode 100644
index 2f7d5a9a0065..000000000000
--- a/drivers/gud/MobiCoreKernelApi/session.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-#ifndef _MC_KAPI_SESSION_H_
-#define _MC_KAPI_SESSION_H_
-
-#include "common.h"
-
-#include <linux/list.h>
-#include "connection.h"
-
-
-struct bulk_buffer_descriptor {
- void *virt_addr; /* The VA of the Bulk buffer */
- uint32_t len; /* Length of the Bulk buffer */
- uint32_t handle;
-
- /* The list param for using the kernel lists*/
- struct list_head list;
-};
-
-struct bulk_buffer_descriptor *bulk_buffer_descriptor_create(
- void *virt_addr,
- uint32_t len,
- uint32_t handle
-);
-
-/*
- * Session states.
- * At the moment not used !!
- */
-enum session_state {
- SESSION_STATE_INITIAL,
- SESSION_STATE_OPEN,
- SESSION_STATE_TRUSTLET_DEAD
-};
-
-#define SESSION_ERR_NO 0 /* No session error */
-
-/*
- * Session information structure.
- * The information structure is used to hold the state of the session, which
- * will limit further actions for the session.
- * Also the last error code will be stored till it's read.
- */
-struct session_information {
- enum session_state state; /* Session state */
- int32_t last_error; /* Last error of session */
-};
-
-
-struct session {
- struct mc_instance *instance;
-
- /* Descriptors of additional bulk buffer of a session */
- struct list_head bulk_buffer_descriptors;
-
- /* Information about session */
- struct session_information session_info;
-
- uint32_t session_id;
- struct connection *notification_connection;
-
- /* The list param for using the kernel lists */
- struct list_head list;
-};
-
-struct session *session_create(
- uint32_t session_id,
- void *instance,
- struct connection *connection
-);
-
-void session_cleanup(struct session *session);
-
-/*
- * session_add_bulk_buf() - Add address information of additional bulk
- * buffer memory to session and register virtual
- * memory in kernel module
- * @session: Session information structure
- * @buf: The virtual address of bulk buffer.
- * @len: Length of bulk buffer.
- *
- * The virtual address can only be added one time. If the virtual
- * address already exist, NULL is returned.
- *
- * On success the actual Bulk buffer descriptor with all address information
- * is returned, NULL if an error occurs.
- */
-struct bulk_buffer_descriptor *session_add_bulk_buf(
- struct session *session, void *buf, uint32_t len);
-
-/*
- * session_remove_bulk_buf() - Remove address information of additional bulk
- * buffer memory from session and unregister
- * virtual memory in kernel module
- * @session: Session information structure
- * @buf: The virtual address of the bulk buffer
- *
- * Returns true on success
- */
-bool session_remove_bulk_buf(struct session *session, void *buf);
-
-
-/*
- * session_find_bulk_buf() - Find the handle of the bulk buffer for this
- * session
- *
- * @session: Session information structure
- * @buf: The virtual address of bulk buffer.
- *
- * On success the actual Bulk buffer handle is returned, 0
- * if an error occurs.
- */
-uint32_t session_find_bulk_buf(struct session *session, void *virt_addr);
-
-/*
- * session_set_error_info() - Set additional error information of the last
- * error that occurred.
- * @session: Session information structure
- * @err: The actual error
- */
-void session_set_error_info(struct session *session, int32_t err);
-
-/*
- * session_get_last_err() - Get additional error information of the last
- * error that occurred.
- * @session: Session information structure
- *
- * After request the information is set to SESSION_ERR_NO.
- *
- * Returns the last stored error code or SESSION_ERR_NO
- */
-int32_t session_get_last_err(struct session *session);
-
-#endif /* _MC_KAPI_SESSION_H_ */
diff --git a/drivers/gud/MobiCoreKernelApi/wsm.h b/drivers/gud/MobiCoreKernelApi/wsm.h
deleted file mode 100644
index b8d4b26c6315..000000000000
--- a/drivers/gud/MobiCoreKernelApi/wsm.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2013 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-/*
- * World shared memory definitions.
- */
-#ifndef _MC_KAPI_WSM_H_
-#define _MC_KAPI_WSM_H_
-
-#include "common.h"
-#include <linux/list.h>
-
-struct wsm {
- void *virt_addr;
- uint32_t len;
- uint32_t handle;
- struct list_head list;
-};
-
-#endif /* _MC_KAPI_WSM_H_ */
diff --git a/drivers/gud/README b/drivers/gud/README
deleted file mode 100644
index 7567b48d01e4..000000000000
--- a/drivers/gud/README
+++ /dev/null
@@ -1,6 +0,0 @@
-t-base is an operating system being shipped with TZBSP
-on msm chipsets. t-base consists of several components in
-the secure world(TrustZone) and non-secure world(linux
-kernel, Android user space). The t-base driver
-communicates with the t-base kernel that exists in
-TrustZone.
diff --git a/drivers/gud/build_tag.h b/drivers/gud/build_tag.h
deleted file mode 100644
index 1689ba84a54d..000000000000
--- a/drivers/gud/build_tag.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2013-2014 TRUSTONIC LIMITED
- * 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 as published by the Free Software Foundation.
- *
- * 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.
- */
-#define MOBICORE_COMPONENT_BUILD_TAG \
- "t-base-Qualcomm-MSM8994-Android-301B-V001"
diff --git a/drivers/gud/setupDrivers.sh b/drivers/gud/setupDrivers.sh
deleted file mode 100644
index 994e83e8d951..000000000000
--- a/drivers/gud/setupDrivers.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-export COMP_PATH_ROOT=$(dirname $(readlink -f $BASH_SOURCE)) #set this to the absolute path of the folder containing this file
-
-# This part has to be set by the customer
-# To be set, absolute path of kernel folder
-export LINUX_PATH=
-# To be set, absolute path! CROSS_COMPILE variable needed by kernel eg /home/user/arm-2009q3/bin/arm-none-linux-gnueabi-
-export CROSS_COMPILE=
-# To be set, build mode debug or release
-export MODE=debug
-# To be set, the absolute path to the Linux Android NDK
-export NDK_PATH=
-
-# Global variables needed by build scripts
-export COMP_PATH_Logwrapper=$COMP_PATH_ROOT/Logwrapper/Out
-export COMP_PATH_MobiCore=$COMP_PATH_ROOT/MobiCore/Out
-export COMP_PATH_MobiCoreDriverMod=$COMP_PATH_ROOT/mobicore_driver/Out
-export COMP_PATH_MobiCoreDriverLib=$COMP_PATH_ROOT/daemon/Out
-export COMP_PATH_AndroidNdkLinux=$NDK_PATH
diff --git a/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c b/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c
index a267a8e4d320..76896f2a5044 100644
--- a/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c
+++ b/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c
@@ -369,6 +369,7 @@ static int msm_fd_open(struct file *file)
ctx->vb2_q.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
ctx->vb2_q.io_modes = VB2_USERPTR;
ctx->vb2_q.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ mutex_init(&ctx->lock);
ret = vb2_queue_init(&ctx->vb2_q);
if (ret < 0) {
dev_err(device->dev, "Error queue init\n");
@@ -411,7 +412,9 @@ static int msm_fd_release(struct file *file)
{
struct fd_ctx *ctx = msm_fd_ctx_from_fh(file->private_data);
+ mutex_lock(&ctx->lock);
vb2_queue_release(&ctx->vb2_q);
+ mutex_unlock(&ctx->lock);
vfree(ctx->stats);
@@ -439,7 +442,9 @@ static unsigned int msm_fd_poll(struct file *file,
struct fd_ctx *ctx = msm_fd_ctx_from_fh(file->private_data);
unsigned int ret;
+ mutex_lock(&ctx->lock);
ret = vb2_poll(&ctx->vb2_q, file, wait);
+ mutex_unlock(&ctx->lock);
if (atomic_read(&ctx->subscribed_for_event)) {
poll_wait(file, &ctx->fh.wait, wait);
@@ -679,9 +684,9 @@ static int msm_fd_reqbufs(struct file *file,
int ret;
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
- mutex_lock(&ctx->fd_device->recovery_lock);
+ mutex_lock(&ctx->lock);
ret = vb2_reqbufs(&ctx->vb2_q, req);
- mutex_unlock(&ctx->fd_device->recovery_lock);
+ mutex_unlock(&ctx->lock);
return ret;
}
@@ -697,9 +702,9 @@ static int msm_fd_qbuf(struct file *file, void *fh,
int ret;
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
- mutex_lock(&ctx->fd_device->recovery_lock);
+ mutex_lock(&ctx->lock);
ret = vb2_qbuf(&ctx->vb2_q, pb);
- mutex_unlock(&ctx->fd_device->recovery_lock);
+ mutex_unlock(&ctx->lock);
return ret;
}
@@ -716,9 +721,9 @@ static int msm_fd_dqbuf(struct file *file,
int ret;
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
- mutex_lock(&ctx->fd_device->recovery_lock);
+ mutex_lock(&ctx->lock);
ret = vb2_dqbuf(&ctx->vb2_q, pb, file->f_flags & O_NONBLOCK);
- mutex_unlock(&ctx->fd_device->recovery_lock);
+ mutex_unlock(&ctx->lock);
return ret;
}
@@ -734,7 +739,9 @@ static int msm_fd_streamon(struct file *file,
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
int ret;
+ mutex_lock(&ctx->lock);
ret = vb2_streamon(&ctx->vb2_q, buf_type);
+ mutex_unlock(&ctx->lock);
if (ret < 0)
dev_err(ctx->fd_device->dev, "Stream on fails\n");
@@ -753,7 +760,9 @@ static int msm_fd_streamoff(struct file *file,
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
int ret;
+ mutex_lock(&ctx->lock);
ret = vb2_streamoff(&ctx->vb2_q, buf_type);
+ mutex_unlock(&ctx->lock);
if (ret < 0)
dev_err(ctx->fd_device->dev, "Stream off fails\n");
@@ -984,15 +993,19 @@ static int msm_fd_s_ctrl(struct file *file, void *fh, struct v4l2_control *a)
a->value = ctx->format.size->work_size;
break;
case V4L2_CID_FD_WORK_MEMORY_FD:
+ mutex_lock(&ctx->fd_device->recovery_lock);
if (ctx->work_buf.handle)
msm_fd_hw_unmap_buffer(&ctx->work_buf);
if (a->value >= 0) {
ret = msm_fd_hw_map_buffer(&ctx->mem_pool,
a->value, &ctx->work_buf);
- if (ret < 0)
+ if (ret < 0) {
+ mutex_unlock(&ctx->fd_device->recovery_lock);
return ret;
+ }
}
+ mutex_unlock(&ctx->fd_device->recovery_lock);
break;
default:
return -EINVAL;
diff --git a/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.h b/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.h
index 2f54f42a323d..6d9830954953 100644
--- a/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.h
+++ b/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.h
@@ -156,6 +156,7 @@ struct fd_ctx {
struct msm_fd_mem_pool mem_pool;
struct msm_fd_stats *stats;
struct msm_fd_buf_handle work_buf;
+ struct mutex lock;
};
/*
diff --git a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c
index c102461cad30..b96d7be1e18d 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c
@@ -425,11 +425,13 @@ static long msm_ois_subdev_ioctl(struct v4l2_subdev *sd,
pr_err("o_ctrl->i2c_client.i2c_func_tbl NULL\n");
return -EINVAL;
} else {
+ mutex_lock(o_ctrl->ois_mutex);
rc = msm_ois_power_down(o_ctrl);
if (rc < 0) {
pr_err("%s:%d OIS Power down failed\n",
__func__, __LINE__);
}
+ mutex_unlock(o_ctrl->ois_mutex);
return msm_ois_close(sd, NULL);
}
default:
diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
index a393c054ff20..d42356e8c45c 100644
--- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, 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
@@ -734,6 +734,8 @@ static int __init msm_vidc_init(void)
if (rc) {
dprintk(VIDC_ERR,
"Failed to register platform driver\n");
+ msm_vidc_debugfs_deinit_drv();
+ debugfs_remove_recursive(vidc_driver->debugfs_root);
kfree(vidc_driver);
vidc_driver = NULL;
}
@@ -744,6 +746,7 @@ static int __init msm_vidc_init(void)
static void __exit msm_vidc_exit(void)
{
platform_driver_unregister(&msm_vidc_driver);
+ msm_vidc_debugfs_deinit_drv();
debugfs_remove_recursive(vidc_driver->debugfs_root);
kfree(vidc_driver);
vidc_driver = NULL;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 3cb3d97e6eff..5f16b9db45dd 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -1404,7 +1404,6 @@ static void cleanup_instance(struct msm_vidc_inst *inst)
msm_comm_smem_free(inst, inst->extradata_handle);
debugfs_remove_recursive(inst->debugfs_root);
-
mutex_lock(&inst->pending_getpropq.lock);
WARN_ON(!list_empty(&inst->pending_getpropq.list)
&& (msm_vidc_debug & VIDC_INFO));
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
index ece325d9e120..9dc22d89f16a 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, 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
@@ -30,45 +30,15 @@ int msm_vidc_sys_idle_indicator = 0x0;
u32 msm_vidc_firmware_unload_delay = 15000;
int msm_vidc_thermal_mitigation_disabled = 0x0;
-struct debug_buffer {
- char ptr[MAX_DBG_BUF_SIZE];
- char *curr;
- u32 filled_size;
-};
-
-static struct debug_buffer dbg_buf;
-
-#define INIT_DBG_BUF(__buf) ({ \
- __buf.curr = __buf.ptr;\
- __buf.filled_size = 0; \
-})
+static struct mutex debugfs_lock;
#define DYNAMIC_BUF_OWNER(__binfo) ({ \
atomic_read(&__binfo->ref_count) == 2 ? "video driver" : "firmware";\
})
-static int core_info_open(struct inode *inode, struct file *file)
+static int vidc_debug_core_show(struct seq_file *s, void *unused)
{
- file->private_data = inode->i_private;
- return 0;
-}
-
-static u32 write_str(struct debug_buffer *buffer, const char *fmt, ...)
-{
- va_list args;
- u32 size;
- va_start(args, fmt);
- size = vscnprintf(buffer->curr, MAX_DBG_BUF_SIZE - 1, fmt, args);
- va_end(args);
- buffer->curr += size;
- buffer->filled_size += size;
- return size;
-}
-
-static ssize_t core_info_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct msm_vidc_core *core = file->private_data;
+ struct msm_vidc_core *core = s->private;
struct hfi_device *hdev;
struct hal_fw_info fw_info;
int i = 0, rc = 0;
@@ -77,37 +47,46 @@ static ssize_t core_info_read(struct file *file, char __user *buf,
dprintk(VIDC_ERR, "Invalid params, core: %pK\n", core);
return 0;
}
+
+ mutex_lock(&debugfs_lock);
hdev = core->device;
- INIT_DBG_BUF(dbg_buf);
- write_str(&dbg_buf, "===============================\n");
- write_str(&dbg_buf, "CORE %d: 0x%pK\n", core->id, core);
- write_str(&dbg_buf, "===============================\n");
- write_str(&dbg_buf, "Core state: %d\n", core->state);
+
+ seq_puts(s, "===============================\n");
+ seq_printf(s, "CORE %d: %pK\n", core->id, core);
+ seq_puts(s, "===============================\n");
+ seq_printf(s, "Core state: %d\n", core->state);
rc = call_hfi_op(hdev, get_fw_info, hdev->hfi_device_data, &fw_info);
if (rc) {
dprintk(VIDC_WARN, "Failed to read FW info\n");
goto err_fw_info;
}
- write_str(&dbg_buf, "FW version : %s\n", &fw_info.version);
- write_str(&dbg_buf, "base addr: 0x%x\n", fw_info.base_addr);
- write_str(&dbg_buf, "register_base: 0x%x\n", fw_info.register_base);
- write_str(&dbg_buf, "register_size: %u\n", fw_info.register_size);
- write_str(&dbg_buf, "irq: %u\n", fw_info.irq);
+ seq_printf(s, "FW version : %s\n", fw_info.version);
+ seq_printf(s, "base addr: %pa\n", &fw_info.base_addr);
+ seq_printf(s, "register_base: %pa\n", &fw_info.register_base);
+ seq_printf(s, "register_size: %u\n", fw_info.register_size);
+ seq_printf(s, "irq: %u\n", fw_info.irq);
err_fw_info:
for (i = SYS_MSG_START; i < SYS_MSG_END; i++) {
- write_str(&dbg_buf, "completions[%d]: %s\n", i,
+ seq_printf(s, "completions[%d]: %s\n", i,
completion_done(&core->completions[SYS_MSG_INDEX(i)]) ?
"pending" : "done");
}
- return simple_read_from_buffer(buf, count, ppos,
- dbg_buf.ptr, dbg_buf.filled_size);
+ mutex_unlock(&debugfs_lock);
+ return 0;
+}
+
+static int vidc_debug_core_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, vidc_debug_core_show, inode->i_private);
}
static const struct file_operations core_info_fops = {
- .open = core_info_open,
- .read = core_info_read,
+ .open = vidc_debug_core_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
static int trigger_ssr_open(struct inode *inode, struct file *file)
@@ -139,7 +118,10 @@ static const struct file_operations ssr_fops = {
struct dentry *msm_vidc_debugfs_init_drv(void)
{
- struct dentry *dir = debugfs_create_dir("msm_vidc", NULL);
+ struct dentry *dir = NULL;
+
+ mutex_init(&debugfs_lock);
+ dir = debugfs_create_dir("msm_vidc", NULL);
if (IS_ERR_OR_NULL(dir)) {
dir = NULL;
goto failed_create_dir;
@@ -222,6 +204,11 @@ failed_create_dir:
return NULL;
}
+void msm_vidc_debugfs_deinit_drv(void)
+{
+ mutex_destroy(&debugfs_lock);
+}
+
struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core,
struct dentry *parent)
{
@@ -238,6 +225,7 @@ struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core,
dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n");
goto failed_create_dir;
}
+
if (!debugfs_create_file("info", S_IRUGO, dir, core, &core_info_fops)) {
dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
goto failed_create_dir;
@@ -251,13 +239,32 @@ failed_create_dir:
return dir;
}
-static int inst_info_open(struct inode *inode, struct file *file)
+static struct msm_vidc_inst *get_inst(struct msm_vidc_inst *inst)
{
- file->private_data = inode->i_private;
- return 0;
+ struct msm_vidc_core *core = NULL;
+ struct msm_vidc_inst *temp, *ret = NULL;
+
+ if (!inst)
+ return NULL;
+
+ mutex_lock(&vidc_driver->lock);
+ list_for_each_entry(core, &vidc_driver->cores, list) {
+ mutex_lock(&core->lock);
+ list_for_each_entry(temp, &core->instances, list)
+ if (temp == inst) {
+ ret = inst;
+ break;
+ }
+ mutex_unlock(&core->lock);
+ if (ret != NULL)
+ break;
+ }
+ mutex_unlock(&vidc_driver->lock);
+ return ret;
}
-static int publish_unreleased_reference(struct msm_vidc_inst *inst)
+static int publish_unreleased_reference(struct msm_vidc_inst *inst,
+ struct seq_file *s)
{
struct buffer_info *temp = NULL;
@@ -267,121 +274,141 @@ static int publish_unreleased_reference(struct msm_vidc_inst *inst)
}
if (inst->buffer_mode_set[CAPTURE_PORT] == HAL_BUFFER_MODE_DYNAMIC) {
- write_str(&dbg_buf, "Pending buffer references:\n");
+ seq_puts(s, "Pending buffer references\n");
mutex_lock(&inst->registeredbufs.lock);
list_for_each_entry(temp, &inst->registeredbufs.list, list) {
if (temp->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
!temp->inactive && atomic_read(&temp->ref_count)) {
- write_str(&dbg_buf,
- "\tpending buffer: 0x%lx fd[0] = %d ref_count = %d held by: %s\n",
- temp->device_addr[0],
- temp->fd[0],
- atomic_read(&temp->ref_count),
- DYNAMIC_BUF_OWNER(temp));
+ seq_printf(s,
+ "\tpending buffer: %pad fd[0] = %d ref_count = %d held by: %s\n",
+ &temp->device_addr[0],
+ temp->fd[0],
+ atomic_read(&temp->ref_count),
+ DYNAMIC_BUF_OWNER(temp));
}
}
mutex_unlock(&inst->registeredbufs.lock);
}
+
return 0;
}
-static ssize_t inst_info_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
+static int vidc_debug_inst_show(struct seq_file *s, void *unused)
{
- struct msm_vidc_inst *inst = file->private_data;
+ struct msm_vidc_inst *inst = get_inst(s->private);
int i, j;
+
if (!inst) {
- dprintk(VIDC_ERR, "Invalid params, core: %pK\n", inst);
- return 0;
+ dprintk(VIDC_ERR, "Instance deleted\n");
+ return -EINVAL;
}
- INIT_DBG_BUF(dbg_buf);
- write_str(&dbg_buf, "===============================\n");
- write_str(&dbg_buf, "INSTANCE: 0x%pK (%s)\n", inst,
+
+ mutex_lock(&debugfs_lock);
+ seq_puts(s, "==============================\n");
+ seq_printf(s, "INSTANCE: %pK (%s)\n", inst,
inst->session_type == MSM_VIDC_ENCODER ? "Encoder" : "Decoder");
- write_str(&dbg_buf, "===============================\n");
- write_str(&dbg_buf, "core: 0x%pK\n", inst->core);
- write_str(&dbg_buf, "height: %d\n", inst->prop.height[CAPTURE_PORT]);
- write_str(&dbg_buf, "width: %d\n", inst->prop.width[CAPTURE_PORT]);
- write_str(&dbg_buf, "fps: %d\n", inst->prop.fps);
- write_str(&dbg_buf, "state: %d\n", inst->state);
- write_str(&dbg_buf, "secure: %d\n", !!(inst->flags & VIDC_SECURE));
- write_str(&dbg_buf, "-----------Formats-------------\n");
+ seq_puts(s, "==============================\n");
+ seq_printf(s, "core: %pK\n", inst->core);
+ seq_printf(s, "height: %d\n", inst->prop.height[CAPTURE_PORT]);
+ seq_printf(s, "width: %d\n", inst->prop.width[CAPTURE_PORT]);
+ seq_printf(s, "fps: %d\n", inst->prop.fps);
+ seq_printf(s, "state: %d\n", inst->state);
+ seq_printf(s, "secure: %d\n", !!(inst->flags & VIDC_SECURE));
+ seq_puts(s, "-----------Formats-------------\n");
for (i = 0; i < MAX_PORT_NUM; i++) {
- write_str(&dbg_buf, "capability: %s\n", i == OUTPUT_PORT ?
+ seq_printf(s, "capability: %s\n",
+ i == OUTPUT_PORT ? "Output" : "Capture");
+ seq_printf(s, "name : %s\n", inst->fmts[i]->name);
+ seq_printf(s, "planes : %d\n", inst->fmts[i]->num_planes);
+ seq_printf(s, "type: %s\n", inst->fmts[i]->type == OUTPUT_PORT ?
"Output" : "Capture");
- write_str(&dbg_buf, "name : %s\n", inst->fmts[i]->name);
- write_str(&dbg_buf, "planes : %d\n", inst->fmts[i]->num_planes);
- write_str(
- &dbg_buf, "type: %s\n", inst->fmts[i]->type == OUTPUT_PORT ?
- "Output" : "Capture");
+
switch (inst->buffer_mode_set[i]) {
case HAL_BUFFER_MODE_STATIC:
- write_str(&dbg_buf, "buffer mode : %s\n", "static");
+ seq_printf(s, "buffer mode : %s\n", "static");
break;
case HAL_BUFFER_MODE_RING:
- write_str(&dbg_buf, "buffer mode : %s\n", "ring");
+ seq_printf(s, "buffer mode : %s\n", "ring");
break;
case HAL_BUFFER_MODE_DYNAMIC:
- write_str(&dbg_buf, "buffer mode : %s\n", "dynamic");
+ seq_printf(s, "buffer mode : %s\n", "dynamic");
break;
default:
- write_str(&dbg_buf, "buffer mode : unsupported\n");
+ seq_puts(s, "buffer mode : unsupported\n");
}
- write_str(&dbg_buf, "count: %u\n",
+ seq_printf(s, "count: %u\n",
inst->bufq[i].vb2_bufq.num_buffers);
for (j = 0; j < inst->fmts[i]->num_planes; j++)
- write_str(&dbg_buf, "size for plane %d: %u\n", j,
+ seq_printf(s, "size for plane %d: %u\n", j,
inst->bufq[i].vb2_bufq.plane_sizes[j]);
if (i < MAX_PORT_NUM - 1)
- write_str(&dbg_buf, "\n");
+ seq_puts(s, "\n");
}
- write_str(&dbg_buf, "-------------------------------\n");
+ seq_puts(s, "-------------------------------\n");
for (i = SESSION_MSG_START; i < SESSION_MSG_END; i++) {
- write_str(&dbg_buf, "completions[%d]: %s\n", i,
+ seq_printf(s, "completions[%d]: %s\n", i,
completion_done(&inst->completions[SESSION_MSG_INDEX(i)]) ?
"pending" : "done");
}
- write_str(&dbg_buf, "ETB Count: %d\n", inst->count.etb);
- write_str(&dbg_buf, "EBD Count: %d\n", inst->count.ebd);
- write_str(&dbg_buf, "FTB Count: %d\n", inst->count.ftb);
- write_str(&dbg_buf, "FBD Count: %d\n", inst->count.fbd);
- publish_unreleased_reference(inst);
+ seq_printf(s, "ETB Count: %d\n", inst->count.etb);
+ seq_printf(s, "EBD Count: %d\n", inst->count.ebd);
+ seq_printf(s, "FTB Count: %d\n", inst->count.ftb);
+ seq_printf(s, "FBD Count: %d\n", inst->count.fbd);
+
+ publish_unreleased_reference(inst, s);
+ mutex_unlock(&debugfs_lock);
+ return 0;
+}
- return simple_read_from_buffer(buf, count, ppos,
- dbg_buf.ptr, dbg_buf.filled_size);
+static int vidc_debug_inst_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, vidc_debug_inst_show, inode->i_private);
}
static const struct file_operations inst_info_fops = {
- .open = inst_info_open,
- .read = inst_info_read,
+ .open = vidc_debug_inst_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst,
struct dentry *parent)
{
- struct dentry *dir = NULL;
+ struct dentry *dir = NULL, *info = NULL;
char debugfs_name[MAX_DEBUGFS_NAME];
+
if (!inst) {
- dprintk(VIDC_ERR, "Invalid params, inst: %pK\n", inst);
- goto failed_create_dir;
+ dprintk(VIDC_ERR, "Invalid params, inst: %p\n", inst);
+ goto exit;
}
snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%pK", inst);
- dir = debugfs_create_dir(debugfs_name, parent);
+
if (!dir) {
dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n");
- goto failed_create_dir;
+ goto exit;
}
- if (!debugfs_create_file("info", S_IRUGO, dir, inst, &inst_info_fops)) {
+
+ info = debugfs_create_file("info", 0444, dir,
+ inst, &inst_info_fops);
+ if (!info) {
dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
- goto failed_create_dir;
+ goto failed_create_file;
}
+
+ dir->d_inode->i_private = info->d_inode->i_private;
inst->debug.pdata[FRAME_PROCESSING].sampling = true;
-failed_create_dir:
+ return dir;
+
+failed_create_file:
+ debugfs_remove_recursive(dir);
+ dir = NULL;
+exit:
return dir;
}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.h b/drivers/media/platform/msm/vidc/msm_vidc_debug.h
index 5080915bba2a..7c2d0c29f7a0 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 2017 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
@@ -112,6 +112,7 @@ extern int msm_vidc_thermal_mitigation_disabled;
struct dentry *msm_vidc_debugfs_init_drv(void);
+void msm_vidc_debugfs_deinit_drv(void);
struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core,
struct dentry *parent);
struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst,
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 1d230c5ec6e9..2debc49187f0 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -20,6 +20,13 @@
#include <media/v4l2-dev.h>
#include <media/v4l2-ioctl.h>
+#define convert_in_user(srcptr, dstptr) \
+({ \
+ typeof(*srcptr) val; \
+ \
+ get_user(val, srcptr) || put_user(val, dstptr); \
+})
+
static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
long ret = -ENOIOCTLCMD;
@@ -45,27 +52,45 @@ struct v4l2_window32 {
compat_caddr_t bitmap;
};
-static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
+static int bufsize_v4l2_window32(struct v4l2_window32 __user *up)
+{
+ __u32 clipcount;
+
+ if (get_user(clipcount, &up->clipcount))
+ return -EFAULT;
+ if (clipcount > 2048)
+ return -EINVAL;
+ return clipcount * sizeof(struct v4l2_clip);
+}
+
+static int get_v4l2_window32(struct v4l2_window __user *kp, struct
+ v4l2_window32 __user *up, void __user *aux_buf, int aux_space)
{
+ __u32 clipcount;
+
if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_window32)) ||
- copy_from_user(&kp->w, &up->w, sizeof(up->w)) ||
- get_user(kp->field, &up->field) ||
- get_user(kp->chromakey, &up->chromakey) ||
- get_user(kp->clipcount, &up->clipcount))
+ copy_in_user(&kp->w, &up->w, sizeof(up->w)) ||
+ convert_in_user(&up->field, &kp->field) ||
+ convert_in_user(&up->chromakey, &kp->chromakey) ||
+ get_user(clipcount, &up->clipcount) ||
+ put_user(clipcount, &kp->clipcount))
return -EFAULT;
- if (kp->clipcount > 2048)
+ if (clipcount > 2048)
return -EINVAL;
- if (kp->clipcount) {
+ if (clipcount) {
struct v4l2_clip32 __user *uclips;
struct v4l2_clip __user *kclips;
- int n = kp->clipcount;
+ int n = clipcount;
compat_caddr_t p;
if (get_user(p, &up->clips))
return -EFAULT;
uclips = compat_ptr(p);
- kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip));
- kp->clips = kclips;
+ if (aux_space < n * sizeof(struct v4l2_clip))
+ return -EFAULT;
+ kclips = aux_buf;
+ if (put_user(kclips, &kp->clips))
+ return -EFAULT;
while (--n >= 0) {
if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
return -EFAULT;
@@ -74,75 +99,77 @@ static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user
uclips += 1;
kclips += 1;
}
- } else
- kp->clips = NULL;
+ } else {
+ if (put_user(NULL, &kp->clips))
+ return -EFAULT;
+ }
return 0;
}
-static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
+static int put_v4l2_window32(struct v4l2_window __user *kp, struct v4l2_window32 __user *up)
{
- if (copy_to_user(&up->w, &kp->w, sizeof(kp->w)) ||
- put_user(kp->field, &up->field) ||
- put_user(kp->chromakey, &up->chromakey) ||
- put_user(kp->clipcount, &up->clipcount))
- return -EFAULT;
+ if (copy_in_user(&up->w, &kp->w, sizeof(kp->w)) ||
+ convert_in_user(&kp->field, &up->field) ||
+ convert_in_user(&kp->chromakey, &up->chromakey) ||
+ convert_in_user(&kp->clipcount, &up->clipcount))
+ return -EFAULT;
return 0;
}
-static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
+static inline int get_v4l2_pix_format(struct v4l2_pix_format __user *kp, struct v4l2_pix_format __user *up)
{
- if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format)))
+ if (copy_in_user(kp, up, sizeof(struct v4l2_pix_format)))
return -EFAULT;
return 0;
}
-static inline int get_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp,
+static inline int get_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane __user *kp,
struct v4l2_pix_format_mplane __user *up)
{
- if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format_mplane)))
+ if (copy_in_user(kp, up, sizeof(struct v4l2_pix_format_mplane)))
return -EFAULT;
return 0;
}
-static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
+static inline int put_v4l2_pix_format(struct v4l2_pix_format __user *kp, struct v4l2_pix_format __user *up)
{
- if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))
+ if (copy_in_user(up, kp, sizeof(struct v4l2_pix_format)))
return -EFAULT;
return 0;
}
-static inline int put_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp,
+static inline int put_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane __user *kp,
struct v4l2_pix_format_mplane __user *up)
{
- if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format_mplane)))
+ if (copy_in_user(up, kp, sizeof(struct v4l2_pix_format_mplane)))
return -EFAULT;
return 0;
}
-static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
+static inline int get_v4l2_vbi_format(struct v4l2_vbi_format __user *kp, struct v4l2_vbi_format __user *up)
{
- if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)))
+ if (copy_in_user(kp, up, sizeof(struct v4l2_vbi_format)))
return -EFAULT;
return 0;
}
-static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
+static inline int put_v4l2_vbi_format(struct v4l2_vbi_format __user *kp, struct v4l2_vbi_format __user *up)
{
- if (copy_to_user(up, kp, sizeof(struct v4l2_vbi_format)))
+ if (copy_in_user(up, kp, sizeof(struct v4l2_vbi_format)))
return -EFAULT;
return 0;
}
-static inline int get_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format *kp, struct v4l2_sliced_vbi_format __user *up)
+static inline int get_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format __user *kp, struct v4l2_sliced_vbi_format __user *up)
{
- if (copy_from_user(kp, up, sizeof(struct v4l2_sliced_vbi_format)))
+ if (copy_in_user(kp, up, sizeof(struct v4l2_sliced_vbi_format)))
return -EFAULT;
return 0;
}
-static inline int put_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format *kp, struct v4l2_sliced_vbi_format __user *up)
+static inline int put_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format __user *kp, struct v4l2_sliced_vbi_format __user *up)
{
- if (copy_to_user(up, kp, sizeof(struct v4l2_sliced_vbi_format)))
+ if (copy_in_user(up, kp, sizeof(struct v4l2_sliced_vbi_format)))
return -EFAULT;
return 0;
}
@@ -176,12 +203,31 @@ struct v4l2_create_buffers32 {
__u32 reserved[8];
};
-static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int __bufsize_v4l2_format32(struct v4l2_format32 __user *up)
+{
+ __u32 type;
+
+ if (get_user(type, &up->type))
+ return -EFAULT;
+
+ switch (type) {
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
+ return bufsize_v4l2_window32(&up->fmt.win);
+ default:
+ return 0;
+ }
+}
+
+static int __get_v4l2_format32(struct v4l2_format __user *kp, struct
+ v4l2_format32 __user *up, void __user *aux_buf, int aux_space)
{
- if (get_user(kp->type, &up->type))
+ __u32 type;
+
+ if (get_user(type, &up->type) || put_user(type, &kp->type))
return -EFAULT;
- switch (kp->type) {
+ switch (type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
@@ -191,7 +237,7 @@ static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __us
&up->fmt.pix_mp);
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- return get_v4l2_window32(&kp->fmt.win, &up->fmt.win);
+ return get_v4l2_window32(&kp->fmt.win, &up->fmt.win, aux_buf, aux_space);
case V4L2_BUF_TYPE_VBI_CAPTURE:
case V4L2_BUF_TYPE_VBI_OUTPUT:
return get_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);
@@ -205,24 +251,46 @@ static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __us
}
}
-static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int bufsize_v4l2_format32(struct v4l2_format32 __user *up)
+{
+ if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)))
+ return -EFAULT;
+ return __bufsize_v4l2_format32(up);
+}
+
+static int get_v4l2_format32(struct v4l2_format __user *kp, struct
+ v4l2_format32 __user *up, void __user *aux_buf, int aux_space)
{
if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)))
return -EFAULT;
- return __get_v4l2_format32(kp, up);
+ return __get_v4l2_format32(kp, up, aux_buf, aux_space);
+}
+
+static int bufsize_v4l2_create32(struct v4l2_create_buffers32 __user *up)
+{
+ if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)))
+ return -EFAULT;
+ return __bufsize_v4l2_format32(&up->format);
}
-static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+static int get_v4l2_create32(struct v4l2_create_buffers __user *kp, struct
+ v4l2_create_buffers32 __user *up, void __user *aux_buf,
+ int aux_space)
{
if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
- copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format)))
+ copy_in_user(kp, up, offsetof(struct v4l2_create_buffers32, format)))
return -EFAULT;
- return __get_v4l2_format32(&kp->format, &up->format);
+ return __get_v4l2_format32(&kp->format, &up->format, aux_buf, aux_space);
}
-static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int __put_v4l2_format32(struct v4l2_format __user *kp, struct v4l2_format32 __user *up)
{
- switch (kp->type) {
+ __u32 type;
+
+ if (get_user(type, &kp->type))
+ return -EFAULT;
+
+ switch (type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
@@ -246,7 +314,7 @@ static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __us
}
}
-static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int put_v4l2_format32(struct v4l2_format __user *kp, struct v4l2_format32 __user *up)
{
if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
put_user(kp->type, &up->type))
@@ -254,10 +322,10 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
return __put_v4l2_format32(kp, up);
}
-static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+static int put_v4l2_create32(struct v4l2_create_buffers __user *kp, struct v4l2_create_buffers32 __user *up)
{
if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
- copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format.fmt)))
+ copy_in_user(up, kp, offsetof(struct v4l2_create_buffers32, format.fmt)))
return -EFAULT;
return __put_v4l2_format32(&kp->format, &up->format);
}
@@ -271,24 +339,24 @@ struct v4l2_standard32 {
__u32 reserved[4];
};
-static int get_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
+static int get_v4l2_standard32(struct v4l2_standard __user *kp, struct v4l2_standard32 __user *up)
{
/* other fields are not set by the user, nor used by the driver */
if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_standard32)) ||
- get_user(kp->index, &up->index))
+ convert_in_user(&up->index, &kp->index))
return -EFAULT;
return 0;
}
-static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
+static int put_v4l2_standard32(struct v4l2_standard __user *kp, struct v4l2_standard32 __user *up)
{
if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard32)) ||
- put_user(kp->index, &up->index) ||
- copy_to_user(up->id, &kp->id, sizeof(__u64)) ||
- copy_to_user(up->name, kp->name, 24) ||
- copy_to_user(&up->frameperiod, &kp->frameperiod, sizeof(kp->frameperiod)) ||
- put_user(kp->framelines, &up->framelines) ||
- copy_to_user(up->reserved, kp->reserved, 4 * sizeof(__u32)))
+ convert_in_user(&kp->index, &up->index) ||
+ copy_in_user(up->id, &kp->id, sizeof(__u64)) ||
+ copy_in_user(up->name, kp->name, 24) ||
+ copy_in_user(&up->frameperiod, &kp->frameperiod, sizeof(kp->frameperiod)) ||
+ convert_in_user(&kp->framelines, &up->framelines) ||
+ copy_in_user(up->reserved, kp->reserved, 4 * sizeof(__u32)))
return -EFAULT;
return 0;
}
@@ -331,7 +399,6 @@ struct v4l2_buffer32 {
static int get_v4l2_plane32(struct v4l2_plane *up, struct v4l2_plane32 *up32,
enum v4l2_memory memory)
{
- void __user *up_pln;
compat_long_t p;
if (copy_in_user(up, up32, 2 * sizeof(__u32)) ||
@@ -344,10 +411,9 @@ static int get_v4l2_plane32(struct v4l2_plane *up, struct v4l2_plane32 *up32,
return -EFAULT;
if (memory == V4L2_MEMORY_USERPTR) {
- if (get_user(p, &up32->m.userptr))
- return -EFAULT;
- up_pln = compat_ptr(p);
- if (put_user((unsigned long)up_pln, &up->m.userptr))
+ if (get_user(p, &up32->m.userptr) ||
+ put_user((unsigned long) compat_ptr(p),
+ &up->m.userptr))
return -EFAULT;
} else if (memory == V4L2_MEMORY_DMABUF) {
if (copy_in_user(&up->m.fd, &up32->m.fd, sizeof(int)))
@@ -386,8 +452,34 @@ static int put_v4l2_plane32(struct v4l2_plane *up, struct v4l2_plane32 *up32,
return 0;
}
-static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
+static int bufsize_v4l2_buffer32(struct v4l2_buffer32 __user *up)
{
+ __u32 type;
+ __u32 length;
+
+ if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_buffer32)) ||
+ get_user(type, &up->type) ||
+ get_user(length, &up->length))
+ return -EFAULT;
+
+ if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
+ if (length > VIDEO_MAX_PLANES)
+ return -EINVAL;
+
+ /* We don't really care if userspace decides to kill itself
+ * by passing a very big length value
+ */
+ return length * sizeof(struct v4l2_plane);
+ }
+ return 0;
+}
+
+static int get_v4l2_buffer32(struct v4l2_buffer __user *kp, struct
+ v4l2_buffer32 __user *up, void __user *aux_buf, int aux_space)
+{
+ __u32 type;
+ __u32 length;
+ enum v4l2_memory memory;
struct v4l2_plane32 __user *uplane32;
struct v4l2_plane __user *uplane;
compat_caddr_t p;
@@ -395,40 +487,40 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
int ret;
if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_buffer32)) ||
- get_user(kp->index, &up->index) ||
- get_user(kp->type, &up->type) ||
- get_user(kp->flags, &up->flags) ||
- get_user(kp->memory, &up->memory))
+ convert_in_user(&up->index, &kp->index) ||
+ get_user(type, &up->type) ||
+ put_user(type, &kp->type) ||
+ convert_in_user(&up->flags, &kp->flags) ||
+ get_user(memory, &up->memory) ||
+ put_user(memory, &kp->memory) ||
+ convert_in_user(&up->length, &kp->length) ||
+ get_user(length, &up->length) ||
+ put_user(length, &kp->length))
return -EFAULT;
- if (V4L2_TYPE_IS_OUTPUT(kp->type))
- if (get_user(kp->bytesused, &up->bytesused) ||
- get_user(kp->field, &up->field) ||
- get_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
- get_user(kp->timestamp.tv_usec,
- &up->timestamp.tv_usec))
+ if (V4L2_TYPE_IS_OUTPUT(type))
+ if (convert_in_user(&up->bytesused, &kp->bytesused) ||
+ convert_in_user(&up->field, &kp->field) ||
+ convert_in_user(&up->timestamp.tv_sec, &kp->timestamp.tv_sec) ||
+ convert_in_user(&up->timestamp.tv_usec,
+ &kp->timestamp.tv_usec))
return -EFAULT;
- if (V4L2_TYPE_IS_PRIVATE(kp->type)) {
+ if (V4L2_TYPE_IS_PRIVATE(type)) {
compat_long_t tmp;
- if (get_user(kp->length, &up->length) ||
- get_user(tmp, &up->m.userptr))
+ if (get_user(tmp, &up->m.userptr) ||
+ put_user((unsigned long) compat_ptr(tmp),
+ &kp->m.userptr))
return -EFAULT;
-
- kp->m.userptr = (unsigned long)compat_ptr(tmp);
}
- if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
- if (get_user(kp->length, &up->length))
- return -EFAULT;
-
- num_planes = kp->length;
+ if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
+ num_planes = length;
if (num_planes == 0) {
- kp->m.planes = NULL;
/* num_planes == 0 is legal, e.g. when userspace doesn't
* need planes array on DQBUF*/
- return 0;
+ return put_user(NULL, &kp->m.planes);
}
if (get_user(p, &up->m.planes))
@@ -441,41 +533,44 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
/* We don't really care if userspace decides to kill itself
* by passing a very big num_planes value */
- uplane = compat_alloc_user_space(num_planes *
- sizeof(struct v4l2_plane));
- kp->m.planes = uplane;
+ if (aux_space < num_planes * sizeof(struct v4l2_plane))
+ return -EFAULT;
+
+ uplane = aux_buf;
+ if (put_user((__force struct v4l2_plane *)uplane,
+ &kp->m.planes))
+ return -EFAULT;
while (--num_planes >= 0) {
- ret = get_v4l2_plane32(uplane, uplane32, kp->memory);
+ ret = get_v4l2_plane32(uplane, uplane32, memory);
if (ret)
return ret;
++uplane;
++uplane32;
}
} else {
- switch (kp->memory) {
+ switch (memory) {
case V4L2_MEMORY_MMAP:
- if (get_user(kp->length, &up->length) ||
- get_user(kp->m.offset, &up->m.offset))
+ if (convert_in_user(&up->m.offset, &kp->m.offset))
return -EFAULT;
break;
case V4L2_MEMORY_USERPTR:
{
- compat_long_t tmp;
-
- if (get_user(kp->length, &up->length) ||
- get_user(tmp, &up->m.userptr))
- return -EFAULT;
+ compat_long_t tmp;
- kp->m.userptr = (unsigned long)compat_ptr(tmp);
+ if (get_user(tmp, &up->m.userptr) ||
+ put_user((unsigned long)
+ compat_ptr(tmp),
+ &kp->m.userptr))
+ return -EFAULT;
}
break;
case V4L2_MEMORY_OVERLAY:
- if (get_user(kp->m.offset, &up->m.offset))
+ if (convert_in_user(&up->m.offset, &kp->m.offset))
return -EFAULT;
break;
case V4L2_MEMORY_DMABUF:
- if (get_user(kp->m.fd, &up->m.fd))
+ if (convert_in_user(&up->m.fd, &kp->m.fd))
return -EFAULT;
break;
}
@@ -484,8 +579,11 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
return 0;
}
-static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
+static int put_v4l2_buffer32(struct v4l2_buffer __user *kp, struct v4l2_buffer32 __user *up)
{
+ __u32 type;
+ __u32 length;
+ enum v4l2_memory memory;
struct v4l2_plane32 __user *uplane32;
struct v4l2_plane __user *uplane;
compat_caddr_t p;
@@ -493,63 +591,65 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
int ret;
if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_buffer32)) ||
- put_user(kp->index, &up->index) ||
- put_user(kp->type, &up->type) ||
- put_user(kp->flags, &up->flags) ||
- put_user(kp->memory, &up->memory))
+ convert_in_user(&kp->index, &up->index) ||
+ get_user(type, &kp->type) ||
+ put_user(type, &up->type) ||
+ convert_in_user(&kp->flags, &up->flags) ||
+ get_user(memory, &kp->memory) ||
+ put_user(memory, &up->memory))
return -EFAULT;
- if (put_user(kp->bytesused, &up->bytesused) ||
- put_user(kp->field, &up->field) ||
- put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
- put_user(kp->timestamp.tv_usec, &up->timestamp.tv_usec) ||
- copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode)) ||
- put_user(kp->sequence, &up->sequence) ||
- put_user(kp->reserved2, &up->reserved2) ||
- put_user(kp->reserved, &up->reserved))
+ if (convert_in_user(&kp->bytesused, &up->bytesused) ||
+ convert_in_user(&kp->field, &up->field) ||
+ convert_in_user(&kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
+ convert_in_user(&kp->timestamp.tv_usec, &up->timestamp.tv_usec) ||
+ copy_in_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode)) ||
+ convert_in_user(&kp->sequence, &up->sequence) ||
+ convert_in_user(&kp->reserved2, &up->reserved2) ||
+ convert_in_user(&kp->reserved, &up->reserved) ||
+ get_user(length, &kp->length) ||
+ put_user(length, &up->length))
return -EFAULT;
- if (V4L2_TYPE_IS_PRIVATE(kp->type)) {
- if (put_user(kp->length, &up->length) ||
- put_user(kp->m.userptr, &up->m.userptr))
+ if (V4L2_TYPE_IS_PRIVATE(type)) {
+ if (convert_in_user(&kp->m.userptr, &up->m.userptr))
return -EFAULT;
}
- if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
- num_planes = kp->length;
+ if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
+ num_planes = length;
if (num_planes == 0)
return 0;
- uplane = kp->m.planes;
+ if (get_user(uplane, ((__force struct v4l2_plane __user **)&kp->m.planes)))
+ return -EFAULT;
if (get_user(p, &up->m.planes))
return -EFAULT;
uplane32 = compat_ptr(p);
while (--num_planes >= 0) {
- ret = put_v4l2_plane32(uplane, uplane32, kp->memory);
+ ret = put_v4l2_plane32(uplane, uplane32, memory);
if (ret)
return ret;
++uplane;
++uplane32;
}
} else {
- switch (kp->memory) {
+ switch (memory) {
case V4L2_MEMORY_MMAP:
- if (put_user(kp->length, &up->length) ||
- put_user(kp->m.offset, &up->m.offset))
+ if (convert_in_user(&kp->m.offset, &up->m.offset))
return -EFAULT;
break;
case V4L2_MEMORY_USERPTR:
- if (put_user(kp->length, &up->length) ||
- put_user(kp->m.userptr, &up->m.userptr))
+ if (convert_in_user(&kp->m.userptr, &up->m.userptr))
return -EFAULT;
break;
case V4L2_MEMORY_OVERLAY:
- if (put_user(kp->m.offset, &up->m.offset))
+ if (convert_in_user(&kp->m.offset, &up->m.offset))
return -EFAULT;
break;
case V4L2_MEMORY_DMABUF:
- if (put_user(kp->m.fd, &up->m.fd))
+ if (convert_in_user(&kp->m.fd, &up->m.fd))
return -EFAULT;
break;
}
@@ -565,30 +665,31 @@ struct v4l2_framebuffer32 {
struct v4l2_pix_format fmt;
};
-static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up)
+static int get_v4l2_framebuffer32(struct v4l2_framebuffer __user *kp, struct v4l2_framebuffer32 __user *up)
{
- u32 tmp;
+ compat_caddr_t tmp;
if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_framebuffer32)) ||
get_user(tmp, &up->base) ||
- get_user(kp->capability, &up->capability) ||
- get_user(kp->flags, &up->flags))
+ put_user((__force void *)compat_ptr(tmp), &kp->base) ||
+ convert_in_user(&up->capability, &kp->capability) ||
+ convert_in_user(&up->flags, &kp->flags) ||
+ get_v4l2_pix_format(&kp->fmt, &up->fmt))
return -EFAULT;
- kp->base = compat_ptr(tmp);
- get_v4l2_pix_format(&kp->fmt, &up->fmt);
return 0;
}
-static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up)
+static int put_v4l2_framebuffer32(struct v4l2_framebuffer __user *kp, struct v4l2_framebuffer32 __user *up)
{
- u32 tmp = (u32)((unsigned long)kp->base);
+ void *base;
if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_framebuffer32)) ||
- put_user(tmp, &up->base) ||
- put_user(kp->capability, &up->capability) ||
- put_user(kp->flags, &up->flags))
+ get_user(base, &kp->base) ||
+ put_user(ptr_to_compat(base), &up->base) ||
+ convert_in_user(&kp->capability, &up->capability) ||
+ convert_in_user(&kp->flags, &up->flags) ||
+ put_v4l2_pix_format(&kp->fmt, &up->fmt))
return -EFAULT;
- put_v4l2_pix_format(&kp->fmt, &up->fmt);
return 0;
}
@@ -605,16 +706,16 @@ struct v4l2_input32 {
/* The 64-bit v4l2_input struct has extra padding at the end of the struct.
Otherwise it is identical to the 32-bit version. */
-static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up)
+static inline int get_v4l2_input32(struct v4l2_input __user *kp, struct v4l2_input32 __user *up)
{
- if (copy_from_user(kp, up, sizeof(struct v4l2_input32)))
+ if (copy_in_user(kp, up, sizeof(struct v4l2_input32)))
return -EFAULT;
return 0;
}
-static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up)
+static inline int put_v4l2_input32(struct v4l2_input __user *kp, struct v4l2_input32 __user *up)
{
- if (copy_to_user(up, kp, sizeof(struct v4l2_input32)))
+ if (copy_in_user(up, kp, sizeof(struct v4l2_input32)))
return -EFAULT;
return 0;
}
@@ -655,33 +756,50 @@ static inline int ctrl_is_pointer(u32 id)
}
}
-static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up)
+static int bufsize_v4l2_ext_controls32(struct v4l2_ext_controls32 __user *up)
+{
+ __u32 count;
+
+ if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_ext_controls32)) ||
+ get_user(count, &up->count))
+ return -EFAULT;
+ if (count > V4L2_CID_MAX_CTRLS)
+ return -EINVAL;
+ return count * sizeof(struct v4l2_ext_control);
+}
+
+static int get_v4l2_ext_controls32(struct v4l2_ext_controls __user *kp, struct
+ v4l2_ext_controls32 __user *up, void __user *aux_buf,
+ int aux_space)
{
struct v4l2_ext_control32 __user *ucontrols;
struct v4l2_ext_control __user *kcontrols;
- int n;
+ __u32 count;
+ unsigned int n;
compat_caddr_t p;
if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_ext_controls32)) ||
- get_user(kp->ctrl_class, &up->ctrl_class) ||
- get_user(kp->count, &up->count) ||
- get_user(kp->error_idx, &up->error_idx) ||
- copy_from_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
+ convert_in_user(&up->ctrl_class, &kp->ctrl_class) ||
+ get_user(count, &up->count) ||
+ put_user(count, &kp->count) ||
+ convert_in_user(&up->error_idx, &kp->error_idx) ||
+ copy_in_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
return -EFAULT;
- n = kp->count;
- if (n == 0) {
- kp->controls = NULL;
- return 0;
- }
+ if (count == 0)
+ return put_user(NULL, &kp->controls);
if (get_user(p, &up->controls))
return -EFAULT;
ucontrols = compat_ptr(p);
if (!access_ok(VERIFY_READ, ucontrols,
- n * sizeof(struct v4l2_ext_control32)))
+ count * sizeof(struct v4l2_ext_control32)))
return -EFAULT;
- kcontrols = compat_alloc_user_space(n * sizeof(struct v4l2_ext_control));
- kp->controls = kcontrols;
- while (--n >= 0) {
+ if (aux_space < count * sizeof(struct v4l2_ext_control))
+ return -EFAULT;
+ kcontrols = aux_buf;
+ if (put_user((__force struct v4l2_ext_control *)kcontrols,
+ &kp->controls))
+ return -EFAULT;
+ for (n = 0; n < count; n++) {
if (copy_in_user(kcontrols, ucontrols, sizeof(*ucontrols)))
return -EFAULT;
if (ctrl_is_pointer(kcontrols->id)) {
@@ -699,30 +817,33 @@ static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
return 0;
}
-static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up)
+static int put_v4l2_ext_controls32(struct v4l2_ext_controls __user *kp, struct v4l2_ext_controls32 __user *up)
{
struct v4l2_ext_control32 __user *ucontrols;
- struct v4l2_ext_control __user *kcontrols = kp->controls;
- int n = kp->count;
+ struct v4l2_ext_control __user *kcontrols;
+ __u32 count;
+ unsigned int n;
compat_caddr_t p;
if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_ext_controls32)) ||
- put_user(kp->ctrl_class, &up->ctrl_class) ||
- put_user(kp->count, &up->count) ||
- put_user(kp->error_idx, &up->error_idx) ||
- copy_to_user(up->reserved, kp->reserved, sizeof(up->reserved)))
+ get_user(kcontrols, &kp->controls) ||
+ convert_in_user(&kp->ctrl_class, &up->ctrl_class) ||
+ get_user(count, &kp->count) ||
+ put_user(count, &up->count) ||
+ convert_in_user(&kp->error_idx, &up->error_idx) ||
+ copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)))
return -EFAULT;
- if (!kp->count)
+ if (!count)
return 0;
if (get_user(p, &up->controls))
return -EFAULT;
ucontrols = compat_ptr(p);
if (!access_ok(VERIFY_WRITE, ucontrols,
- n * sizeof(struct v4l2_ext_control32)))
+ count * sizeof(struct v4l2_ext_control32)))
return -EFAULT;
- while (--n >= 0) {
+ for (n = 0; n < count; n++) {
unsigned size = sizeof(*ucontrols);
/* Do not modify the pointer when copying a pointer control.
@@ -753,16 +874,17 @@ struct v4l2_event32 {
__u32 reserved[8];
};
-static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *up)
+static int put_v4l2_event32(struct v4l2_event __user *kp, struct v4l2_event32 __user *up)
{
if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_event32)) ||
- put_user(kp->type, &up->type) ||
- copy_to_user(&up->u, &kp->u, sizeof(kp->u)) ||
- put_user(kp->pending, &up->pending) ||
- put_user(kp->sequence, &up->sequence) ||
- put_compat_timespec(&kp->timestamp, &up->timestamp) ||
- put_user(kp->id, &up->id) ||
- copy_to_user(up->reserved, kp->reserved, 8 * sizeof(__u32)))
+ convert_in_user(&kp->type, &up->type) ||
+ copy_in_user(&up->u, &kp->u, sizeof(kp->u)) ||
+ convert_in_user(&kp->pending, &up->pending) ||
+ convert_in_user(&kp->sequence, &up->sequence) ||
+ convert_in_user(&kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
+ convert_in_user(&kp->timestamp.tv_nsec, &up->timestamp.tv_nsec) ||
+ convert_in_user(&kp->id, &up->id) ||
+ copy_in_user(up->reserved, kp->reserved, 8 * sizeof(__u32)))
return -EFAULT;
return 0;
}
@@ -775,31 +897,32 @@ struct v4l2_subdev_edid32 {
compat_caddr_t edid;
};
-static int get_v4l2_subdev_edid32(struct v4l2_subdev_edid *kp, struct v4l2_subdev_edid32 __user *up)
+static int get_v4l2_subdev_edid32(struct v4l2_subdev_edid __user *kp, struct v4l2_subdev_edid32 __user *up)
{
- u32 tmp;
+ compat_uptr_t tmp;
if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_subdev_edid32)) ||
- get_user(kp->pad, &up->pad) ||
- get_user(kp->start_block, &up->start_block) ||
- get_user(kp->blocks, &up->blocks) ||
+ convert_in_user(&up->pad, &kp->pad) ||
+ convert_in_user(&up->start_block, &kp->start_block) ||
+ convert_in_user(&up->blocks, &kp->blocks) ||
get_user(tmp, &up->edid) ||
- copy_from_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
+ put_user(compat_ptr(tmp), &kp->edid) ||
+ copy_in_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
return -EFAULT;
- kp->edid = compat_ptr(tmp);
return 0;
}
-static int put_v4l2_subdev_edid32(struct v4l2_subdev_edid *kp, struct v4l2_subdev_edid32 __user *up)
+static int put_v4l2_subdev_edid32(struct v4l2_subdev_edid __user *kp, struct v4l2_subdev_edid32 __user *up)
{
- u32 tmp = (u32)((unsigned long)kp->edid);
+ void *edid;
if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_subdev_edid32)) ||
- put_user(kp->pad, &up->pad) ||
- put_user(kp->start_block, &up->start_block) ||
- put_user(kp->blocks, &up->blocks) ||
- put_user(tmp, &up->edid) ||
- copy_to_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
+ convert_in_user(&kp->pad, &up->pad) ||
+ convert_in_user(&kp->start_block, &up->start_block) ||
+ convert_in_user(&kp->blocks, &up->blocks) ||
+ get_user(edid, &kp->edid) ||
+ put_user(ptr_to_compat(edid), &up->edid) ||
+ copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)))
return -EFAULT;
return 0;
}
@@ -832,22 +955,37 @@ static int put_v4l2_subdev_edid32(struct v4l2_subdev_edid *kp, struct v4l2_subde
#define VIDIOC_G_OUTPUT32 _IOR ('V', 46, s32)
#define VIDIOC_S_OUTPUT32 _IOWR('V', 47, s32)
+/*
+ * Note that these macros contain return statements to avoid the need for the
+ * "caller" to check return values.
+ */
+#define ALLOC_USER_SPACE(size) \
+({ \
+ void __user *up_native; \
+ up_native = compat_alloc_user_space(size); \
+ if (!up_native) \
+ return -ENOMEM; \
+ if (clear_user(up_native, size)) \
+ return -EFAULT; \
+ up_native; \
+})
+
+#define ALLOC_AND_GET(bufsizefunc, getfunc, structname) \
+ do { \
+ aux_space = bufsizefunc(up); \
+ if (aux_space < 0) \
+ return aux_space; \
+ up_native = ALLOC_USER_SPACE(sizeof(struct structname) + aux_space); \
+ aux_buf = up_native + sizeof(struct structname); \
+ err = getfunc(up_native, up, aux_buf, aux_space); \
+ } while (0)
+
static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
- union {
- struct v4l2_format v2f;
- struct v4l2_buffer v2b;
- struct v4l2_framebuffer v2fb;
- struct v4l2_input v2i;
- struct v4l2_standard v2s;
- struct v4l2_ext_controls v2ecs;
- struct v4l2_event v2ev;
- struct v4l2_create_buffers v2crt;
- struct v4l2_subdev_edid v2edid;
- unsigned long vx;
- int vi;
- } karg;
void __user *up = compat_ptr(arg);
+ void __user *up_native = NULL;
+ void __user *aux_buf;
+ int aux_space;
int compatible_arg = 1;
long err = 0;
@@ -886,30 +1024,35 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
case VIDIOC_STREAMOFF:
case VIDIOC_S_INPUT:
case VIDIOC_S_OUTPUT:
- err = get_user(karg.vi, (s32 __user *)up);
+ up_native = ALLOC_USER_SPACE(sizeof(unsigned __user));
+ if (convert_in_user((compat_uint_t __user *)up,
+ (unsigned __user *) up_native))
+ return -EFAULT;
compatible_arg = 0;
break;
case VIDIOC_G_INPUT:
case VIDIOC_G_OUTPUT:
+ up_native = ALLOC_USER_SPACE(sizeof(unsigned __user));
compatible_arg = 0;
break;
case VIDIOC_SUBDEV_G_EDID:
case VIDIOC_SUBDEV_S_EDID:
- err = get_v4l2_subdev_edid32(&karg.v2edid, up);
+ up_native = ALLOC_USER_SPACE(sizeof(struct v4l2_subdev_edid));
+ err = get_v4l2_subdev_edid32(up_native, up);
compatible_arg = 0;
break;
case VIDIOC_G_FMT:
case VIDIOC_S_FMT:
case VIDIOC_TRY_FMT:
- err = get_v4l2_format32(&karg.v2f, up);
+ ALLOC_AND_GET(bufsize_v4l2_format32, get_v4l2_format32, v4l2_format);
compatible_arg = 0;
break;
case VIDIOC_CREATE_BUFS:
- err = get_v4l2_create32(&karg.v2crt, up);
+ ALLOC_AND_GET(bufsize_v4l2_create32, get_v4l2_create32, v4l2_create_buffers);
compatible_arg = 0;
break;
@@ -917,36 +1060,41 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
case VIDIOC_QUERYBUF:
case VIDIOC_QBUF:
case VIDIOC_DQBUF:
- err = get_v4l2_buffer32(&karg.v2b, up);
+ ALLOC_AND_GET(bufsize_v4l2_buffer32, get_v4l2_buffer32, v4l2_buffer);
compatible_arg = 0;
break;
case VIDIOC_S_FBUF:
- err = get_v4l2_framebuffer32(&karg.v2fb, up);
+ up_native = ALLOC_USER_SPACE(sizeof(struct v4l2_framebuffer));
+ err = get_v4l2_framebuffer32(up_native, up);
compatible_arg = 0;
break;
case VIDIOC_G_FBUF:
+ up_native = ALLOC_USER_SPACE(sizeof(struct v4l2_framebuffer));
compatible_arg = 0;
break;
case VIDIOC_ENUMSTD:
- err = get_v4l2_standard32(&karg.v2s, up);
+ up_native = ALLOC_USER_SPACE(sizeof(struct v4l2_standard));
+ err = get_v4l2_standard32(up_native, up);
compatible_arg = 0;
break;
case VIDIOC_ENUMINPUT:
- err = get_v4l2_input32(&karg.v2i, up);
+ up_native = ALLOC_USER_SPACE(sizeof(struct v4l2_input));
+ err = get_v4l2_input32(up_native, up);
compatible_arg = 0;
break;
case VIDIOC_G_EXT_CTRLS:
case VIDIOC_S_EXT_CTRLS:
case VIDIOC_TRY_EXT_CTRLS:
- err = get_v4l2_ext_controls32(&karg.v2ecs, up);
+ ALLOC_AND_GET(bufsize_v4l2_ext_controls32, get_v4l2_ext_controls32, v4l2_ext_controls);
compatible_arg = 0;
break;
case VIDIOC_DQEVENT:
+ up_native = ALLOC_USER_SPACE(sizeof(struct v4l2_event));
compatible_arg = 0;
break;
}
@@ -955,13 +1103,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
if (compatible_arg)
err = native_ioctl(file, cmd, (unsigned long)up);
- else {
- mm_segment_t old_fs = get_fs();
-
- set_fs(KERNEL_DS);
- err = native_ioctl(file, cmd, (unsigned long)&karg);
- set_fs(old_fs);
- }
+ else
+ err = native_ioctl(file, cmd, (unsigned long)up_native);
/* Special case: even after an error we need to put the
results back for these ioctls since the error_idx will
@@ -970,7 +1113,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
case VIDIOC_G_EXT_CTRLS:
case VIDIOC_S_EXT_CTRLS:
case VIDIOC_TRY_EXT_CTRLS:
- if (put_v4l2_ext_controls32(&karg.v2ecs, up))
+ if (put_v4l2_ext_controls32(up_native, up))
err = -EFAULT;
break;
}
@@ -982,44 +1125,45 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
case VIDIOC_S_OUTPUT:
case VIDIOC_G_INPUT:
case VIDIOC_G_OUTPUT:
- err = put_user(((s32)karg.vi), (s32 __user *)up);
+ err = convert_in_user(((unsigned __user *)up_native),
+ (compat_uint_t __user *)up);
break;
case VIDIOC_G_FBUF:
- err = put_v4l2_framebuffer32(&karg.v2fb, up);
+ err = put_v4l2_framebuffer32(up_native, up);
break;
case VIDIOC_DQEVENT:
- err = put_v4l2_event32(&karg.v2ev, up);
+ err = put_v4l2_event32(up_native, up);
break;
case VIDIOC_SUBDEV_G_EDID:
case VIDIOC_SUBDEV_S_EDID:
- err = put_v4l2_subdev_edid32(&karg.v2edid, up);
+ err = put_v4l2_subdev_edid32(up_native, up);
break;
case VIDIOC_G_FMT:
case VIDIOC_S_FMT:
case VIDIOC_TRY_FMT:
- err = put_v4l2_format32(&karg.v2f, up);
+ err = put_v4l2_format32(up_native, up);
break;
case VIDIOC_CREATE_BUFS:
- err = put_v4l2_create32(&karg.v2crt, up);
+ err = put_v4l2_create32(up_native, up);
break;
case VIDIOC_QUERYBUF:
case VIDIOC_QBUF:
case VIDIOC_DQBUF:
- err = put_v4l2_buffer32(&karg.v2b, up);
+ err = put_v4l2_buffer32(up_native, up);
break;
case VIDIOC_ENUMSTD:
- err = put_v4l2_standard32(&karg.v2s, up);
+ err = put_v4l2_standard32(up_native, up);
break;
case VIDIOC_ENUMINPUT:
- err = put_v4l2_input32(&karg.v2i, up);
+ err = put_v4l2_input32(up_native, up);
break;
}
return err;
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 5afbcb1800c2..cb6365f7f4d5 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -4680,11 +4680,21 @@ static int __qseecom_qteec_issue_cmd(struct qseecom_dev_handle *data,
int ret = 0;
uint32_t reqd_len_sb_in = 0;
struct sglist_info *table = data->sglistinfo_ptr;
+ void *req_ptr = NULL;
+ void *resp_ptr = NULL;
ret = __qseecom_qteec_validate_msg(data, req);
if (ret)
return ret;
+ req_ptr = req->req_ptr;
+ resp_ptr = req->resp_ptr;
+
+ req->req_ptr = (void *)__qseecom_uvirt_to_kvirt(data,
+ (uintptr_t)req->req_ptr);
+ req->resp_ptr = (void *)__qseecom_uvirt_to_kvirt(data,
+ (uintptr_t)req->resp_ptr);
+
if ((cmd_id == QSEOS_TEE_OPEN_SESSION) ||
(cmd_id == QSEOS_TEE_REQUEST_CANCELLATION)) {
ret = __qseecom_update_qteec_req_buf(
@@ -4700,10 +4710,10 @@ static int __qseecom_qteec_issue_cmd(struct qseecom_dev_handle *data,
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);
+ (uintptr_t)req_ptr);
ireq.req_len = req->req_len;
ireq.resp_ptr = (uint32_t)__qseecom_uvirt_to_kphys(data,
- (uintptr_t)req->resp_ptr);
+ (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;
diff --git a/drivers/platform/msm/ipa/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_qmi_service.c
index 53d3a3b535d1..3383e8d5cc4d 100644
--- a/drivers/platform/msm/ipa/ipa_qmi_service.c
+++ b/drivers/platform/msm/ipa/ipa_qmi_service.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2017, 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
@@ -50,6 +50,7 @@ static bool is_load_uc;
static uint32_t ipa_wan_platform;
struct ipa_qmi_context *ipa_qmi_ctx;
static bool workqueues_stopped;
+struct mutex ipa_qmi_lock;
/* QMI A5 service */
@@ -494,12 +495,17 @@ int qmi_filter_request_send(struct ipa_install_fltr_rule_req_msg_v01 *req)
req->filter_spec_list_len);
}
- /* cache the qmi_filter_request */
- memcpy(&(ipa_qmi_ctx->ipa_install_fltr_rule_req_msg_cache[
- ipa_qmi_ctx->num_ipa_install_fltr_rule_req_msg]),
- req, sizeof(struct ipa_install_fltr_rule_req_msg_v01));
- ipa_qmi_ctx->num_ipa_install_fltr_rule_req_msg++;
- ipa_qmi_ctx->num_ipa_install_fltr_rule_req_msg %= 10;
+ mutex_lock(&ipa_qmi_lock);
+ if (ipa_qmi_ctx != NULL) {
+ /* cache the qmi_filter_request */
+ memcpy(&(ipa_qmi_ctx->ipa_install_fltr_rule_req_msg_cache[
+ ipa_qmi_ctx->num_ipa_install_fltr_rule_req_msg]),
+ req,
+ sizeof(struct ipa_install_fltr_rule_req_msg_v01));
+ ipa_qmi_ctx->num_ipa_install_fltr_rule_req_msg++;
+ ipa_qmi_ctx->num_ipa_install_fltr_rule_req_msg %= 10;
+ }
+ mutex_unlock(&ipa_qmi_lock);
req_desc.max_msg_len = QMI_IPA_INSTALL_FILTER_RULE_REQ_MAX_MSG_LEN_V01;
req_desc.msg_id = QMI_IPA_INSTALL_FILTER_RULE_REQ_V01;
@@ -639,12 +645,17 @@ int qmi_filter_notify_send(struct ipa_fltr_installed_notif_req_msg_v01 *req)
return -EINVAL;
}
- /* cache the qmi_filter_request */
- memcpy(&(ipa_qmi_ctx->ipa_fltr_installed_notif_req_msg_cache[
- ipa_qmi_ctx->num_ipa_fltr_installed_notif_req_msg]),
- req, sizeof(struct ipa_fltr_installed_notif_req_msg_v01));
- ipa_qmi_ctx->num_ipa_fltr_installed_notif_req_msg++;
- ipa_qmi_ctx->num_ipa_fltr_installed_notif_req_msg %= 10;
+ mutex_lock(&ipa_qmi_lock);
+ if (ipa_qmi_ctx != NULL) {
+ /* cache the qmi_filter_request */
+ memcpy(&(ipa_qmi_ctx->ipa_fltr_installed_notif_req_msg_cache[
+ ipa_qmi_ctx->num_ipa_fltr_installed_notif_req_msg]),
+ req,
+ sizeof(struct ipa_fltr_installed_notif_req_msg_v01));
+ ipa_qmi_ctx->num_ipa_fltr_installed_notif_req_msg++;
+ ipa_qmi_ctx->num_ipa_fltr_installed_notif_req_msg %= 10;
+ }
+ mutex_unlock(&ipa_qmi_lock);
req_desc.max_msg_len =
QMI_IPA_FILTER_INSTALLED_NOTIF_REQ_MAX_MSG_LEN_V01;
@@ -979,3 +990,13 @@ void ipa_qmi_stop_workqueues(void)
cancel_delayed_work(&work_svc_arrive);
cancel_delayed_work(&work_svc_exit);
}
+
+void ipa_qmi_init(void)
+{
+ mutex_init(&ipa_qmi_lock);
+}
+
+void ipa_qmi_cleanup(void)
+{
+ mutex_destroy(&ipa_qmi_lock);
+}
diff --git a/drivers/platform/msm/ipa/ipa_qmi_service.h b/drivers/platform/msm/ipa/ipa_qmi_service.h
index 7a265a152a00..07c987767fae 100644
--- a/drivers/platform/msm/ipa/ipa_qmi_service.h
+++ b/drivers/platform/msm/ipa/ipa_qmi_service.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2017, 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
@@ -56,6 +56,10 @@ struct rmnet_mux_val {
uint32_t hdr_hdl;
};
+void ipa_qmi_init(void);
+
+void ipa_qmi_cleanup(void);
+
int ipa_qmi_service_init(bool load_uc, uint32_t wan_platform_type);
void ipa_qmi_service_exit(void);
diff --git a/drivers/platform/msm/ipa/rmnet_ipa.c b/drivers/platform/msm/ipa/rmnet_ipa.c
index 0d6fb3319469..ba5426fd0e85 100644
--- a/drivers/platform/msm/ipa/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/rmnet_ipa.c
@@ -2056,6 +2056,9 @@ static int __init ipa_wwan_init(void)
atomic_set(&is_initialized, 0);
atomic_set(&is_ssr, 0);
mutex_init(&add_mux_channel_lock);
+
+ ipa_qmi_init();
+
/* Register for Modem SSR */
subsys = subsys_notif_register_notifier(SUBSYS_MODEM, &ssr_notifier);
if (!IS_ERR(subsys))
@@ -2066,6 +2069,7 @@ static int __init ipa_wwan_init(void)
static void __exit ipa_wwan_cleanup(void)
{
+ ipa_qmi_cleanup();
mutex_destroy(&add_mux_channel_lock);
platform_driver_unregister(&rmnet_ipa_driver);
}
diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c
index 390855c4c804..c69d7c6a1360 100755..100644
--- a/drivers/power/reset/msm-poweroff.c
+++ b/drivers/power/reset/msm-poweroff.c
@@ -128,6 +128,7 @@ static bool get_dload_mode(void)
return dload_mode_enabled;
}
+#if 0
static void enable_emergency_dload_mode(void)
{
int ret;
@@ -157,6 +158,7 @@ static void enable_emergency_dload_mode(void)
if (ret)
pr_err("Failed to set secure EDLOAD mode: %d\n", ret);
}
+#endif
static int dload_set(const char *val, struct kernel_param *kp)
{
@@ -317,8 +319,10 @@ static void msm_restart_prepare(const char *cmd)
if (!ret)
__raw_writel(0x6f656d00 | (code & 0xff),
restart_reason);
+#if 0
} else if (!strncmp(cmd, "edl", 3)) {
enable_emergency_dload_mode();
+#endif
} else {
__raw_writel(0x77665501, restart_reason);
}
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 9a600f05ab57..f40dbef23c31 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -382,6 +382,9 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
struct sg_header *old_hdr = NULL;
int retval = 0;
+ if (unlikely(segment_eq(get_fs(), KERNEL_DS)))
+ return -EINVAL;
+
if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
return -ENXIO;
SCSI_LOG_TIMEOUT(3, printk("sg_read: %s, count=%d\n",
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 3b890ab8411f..623622e295dd 100755
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -469,7 +469,7 @@ static struct ion_handle *pass_to_user(struct ion_handle *handle)
/* Must hold the client lock */
static int user_ion_handle_put_nolock(struct ion_handle *handle)
{
- int ret;
+ int ret = 0;
if (--handle->user_ref_count == 0)
ret = ion_handle_put_nolock(handle);
diff --git a/drivers/video/msm/mdss/mdss_hdmi_edid.c b/drivers/video/msm/mdss/mdss_hdmi_edid.c
index fad94862c309..a82b12b3a0b8 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_edid.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_edid.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2017, 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
@@ -212,9 +212,11 @@ static ssize_t hdmi_edid_sysfs_wta_res_info(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int rc, page_id;
+ u32 i = 0, j, page;
ssize_t ret = strnlen(buf, PAGE_SIZE);
struct hdmi_edid_ctrl *edid_ctrl =
hdmi_get_featuredata_from_sysfs_dev(dev, HDMI_TX_FEAT_EDID);
+ struct msm_hdmi_mode_timing_info info = {0};
if (!edid_ctrl) {
DEV_ERR("%s: invalid input\n", __func__);
@@ -227,7 +229,22 @@ static ssize_t hdmi_edid_sysfs_wta_res_info(struct device *dev,
return rc;
}
- edid_ctrl->page_id = page_id;
+ if (page_id > MSM_HDMI_INIT_RES_PAGE) {
+ page = MSM_HDMI_INIT_RES_PAGE;
+ while (page < page_id) {
+ j = 1;
+ while (sizeof(info) * j < PAGE_SIZE) {
+ i++;
+ j++;
+ }
+ page++;
+ }
+ }
+
+ if (i < HDMI_VFRMT_MAX)
+ edid_ctrl->page_id = page_id;
+ else
+ DEV_ERR("%s: invalid page id\n", __func__);
DEV_DBG("%s: %d\n", __func__, edid_ctrl->page_id);
return ret;
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 41ca5cd50044..5c6bfa77ba35 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -3916,10 +3916,11 @@ static int mdss_fb_get_metadata(struct msm_fb_data_type *mfd,
ret = mdss_fb_get_hw_caps(mfd, &metadata->data.caps);
break;
case metadata_op_get_ion_fd:
- if (mfd->fb_ion_handle) {
+ if (mfd->fb_ion_handle && mfd->fb_ion_client) {
get_dma_buf(mfd->fbmem_buf);
metadata->data.fbmem_ionfd =
- dma_buf_fd(mfd->fbmem_buf, 0);
+ ion_share_dma_buf_fd(mfd->fb_ion_client,
+ mfd->fb_ion_handle);
if (metadata->data.fbmem_ionfd < 0) {
dma_buf_put(mfd->fbmem_buf);
pr_err("fd allocation failed. fd = %d\n",
diff --git a/fs/dcache.c b/fs/dcache.c
index 25c0a1b5f6c0..69d12b2647ed 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -238,6 +238,43 @@ static void d_free(struct dentry *dentry)
call_rcu(&dentry->d_u.d_rcu, __d_free);
}
+void take_dentry_name_snapshot(struct name_snapshot *name, struct dentry *dentry)
+{
+ spin_lock(&dentry->d_lock);
+ if (unlikely(dname_external(dentry))) {
+ u32 len;
+ char *p;
+
+ for (;;) {
+ len = dentry->d_name.len;
+ spin_unlock(&dentry->d_lock);
+
+ p = kmalloc(len + 1, GFP_KERNEL | __GFP_NOFAIL);
+
+ spin_lock(&dentry->d_lock);
+ if (dentry->d_name.len <= len)
+ break;
+ kfree(p);
+ }
+ memcpy(p, dentry->d_name.name, dentry->d_name.len + 1);
+ spin_unlock(&dentry->d_lock);
+
+ name->name = p;
+ } else {
+ memcpy(name->inline_name, dentry->d_iname, DNAME_INLINE_LEN);
+ spin_unlock(&dentry->d_lock);
+ name->name = name->inline_name;
+ }
+}
+EXPORT_SYMBOL(take_dentry_name_snapshot);
+
+void release_dentry_name_snapshot(struct name_snapshot *name)
+{
+ if (unlikely(name->name != name->inline_name))
+ kfree(name->name);
+}
+EXPORT_SYMBOL(release_dentry_name_snapshot);
+
/**
* dentry_rcuwalk_barrier - invalidate in-progress rcu-walk lookups
* @dentry: the target dentry
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 5397ca6a2097..ff066c69a376 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -602,7 +602,7 @@ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
{
int error;
struct dentry *dentry = NULL, *trap;
- const char *old_name;
+ struct name_snapshot old_name;
trap = lock_rename(new_dir, old_dir);
/* Source or destination directories don't exist? */
@@ -617,19 +617,19 @@ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
if (IS_ERR(dentry) || dentry == trap || dentry->d_inode)
goto exit;
- old_name = fsnotify_oldname_init(old_dentry->d_name.name);
+ take_dentry_name_snapshot(&old_name, old_dentry);
error = simple_rename(old_dir->d_inode, old_dentry, new_dir->d_inode,
dentry);
if (error) {
- fsnotify_oldname_free(old_name);
+ release_dentry_name_snapshot(&old_name);
goto exit;
}
d_move(old_dentry, dentry);
- fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name,
+ fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name.name,
S_ISDIR(old_dentry->d_inode->i_mode),
NULL, old_dentry);
- fsnotify_oldname_free(old_name);
+ release_dentry_name_snapshot(&old_name);
unlock_rename(new_dir, old_dir);
dput(dentry);
return old_dentry;
diff --git a/fs/namei.c b/fs/namei.c
index 5778b514e1c8..3d48d1193ddb 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3881,7 +3881,7 @@ int vfs_rename2(struct vfsmount *mnt,
{
int error;
int is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
- const unsigned char *old_name;
+ struct name_snapshot old_name;
if (old_dentry->d_inode == new_dentry->d_inode)
return 0;
@@ -3900,16 +3900,16 @@ int vfs_rename2(struct vfsmount *mnt,
if (!old_dir->i_op->rename)
return -EPERM;
- old_name = fsnotify_oldname_init(old_dentry->d_name.name);
+ take_dentry_name_snapshot(&old_name, old_dentry);
if (is_dir)
error = vfs_rename_dir(mnt, old_dir,old_dentry,new_dir,new_dentry);
else
error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
if (!error)
- fsnotify_move(old_dir, new_dir, old_name, is_dir,
+ fsnotify_move(old_dir, new_dir, old_name.name, is_dir,
new_dentry->d_inode, old_dentry);
- fsnotify_oldname_free(old_name);
+ take_dentry_name_snapshot(&old_name, old_dentry);
return error;
}
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 4bb21d67d9b1..aaba571cdfb0 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -105,16 +105,20 @@ int __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
if (unlikely(!fsnotify_inode_watches_children(p_inode)))
__fsnotify_update_child_dentry_flags(p_inode);
else if (p_inode->i_fsnotify_mask & mask) {
+ struct name_snapshot name;
+
/* we are notifying a parent so come up with the new mask which
* specifies these are events which came from a child. */
mask |= FS_EVENT_ON_CHILD;
+ take_dentry_name_snapshot(&name, dentry);
if (path)
ret = fsnotify(p_inode, mask, path, FSNOTIFY_EVENT_PATH,
- dentry->d_name.name, 0);
+ name.name, 0);
else
ret = fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE,
- dentry->d_name.name, 0);
+ name.name, 0);
+ release_dentry_name_snapshot(&name);
}
dput(parent);
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index df1f7093a0ab..3d34f05c189f 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -430,4 +430,11 @@ static inline bool d_is_negative(const struct dentry *dentry)
extern int sysctl_vfs_cache_pressure;
+struct name_snapshot {
+ const char *name;
+ char inline_name[DNAME_INLINE_LEN];
+};
+void take_dentry_name_snapshot(struct name_snapshot *, struct dentry *);
+void release_dentry_name_snapshot(struct name_snapshot *);
+
#endif /* __LINUX_DCACHE_H */
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
index 661c0aeef1c4..bfd4c93193cb 100644
--- a/include/linux/fsnotify.h
+++ b/include/linux/fsnotify.h
@@ -310,35 +310,4 @@ static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid)
}
}
-#if defined(CONFIG_FSNOTIFY) /* notify helpers */
-
-/*
- * fsnotify_oldname_init - save off the old filename before we change it
- */
-static inline const unsigned char *fsnotify_oldname_init(const unsigned char *name)
-{
- return kstrdup(name, GFP_KERNEL);
-}
-
-/*
- * fsnotify_oldname_free - free the name we got from fsnotify_oldname_init
- */
-static inline void fsnotify_oldname_free(const unsigned char *old_name)
-{
- kfree(old_name);
-}
-
-#else /* CONFIG_FSNOTIFY */
-
-static inline const char *fsnotify_oldname_init(const unsigned char *name)
-{
- return NULL;
-}
-
-static inline void fsnotify_oldname_free(const unsigned char *old_name)
-{
-}
-
-#endif /* CONFIG_FSNOTIFY */
-
#endif /* _LINUX_FS_NOTIFY_H */
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index e430b1abcd2f..e387e6719fa2 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -32,6 +32,7 @@
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/hci_core.h>
#include "bnep.h"
@@ -539,6 +540,9 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
BT_DBG("");
+ if (!l2cap_is_socket(sock))
+ return -EBADFD;
+
baswap((void *) dst, &bt_sk(sock->sk)->dst);
baswap((void *) src, &bt_sk(sock->sk)->src);
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c
index e0a6ebf2baa6..84460f623fc8 100644
--- a/net/bluetooth/cmtp/core.c
+++ b/net/bluetooth/cmtp/core.c
@@ -334,6 +334,9 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
BT_DBG("");
+ if (!l2cap_is_socket(sock))
+ return -EBADFD;
+
session = kzalloc(sizeof(struct cmtp_session), GFP_KERNEL);
if (!session)
return -ENOMEM;
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 0641d14bc423..2e782cc32169 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -65,6 +65,7 @@ struct snd_timer_user {
int qtail;
int qused;
int queue_size;
+ bool disconnected;
struct snd_timer_read *queue;
struct snd_timer_tread *tqueue;
spinlock_t qlock;
@@ -215,11 +216,13 @@ static void snd_timer_check_master(struct snd_timer_instance *master)
slave->slave_id == master->slave_id) {
list_move_tail(&slave->open_list, &master->slave_list_head);
spin_lock_irq(&slave_active_lock);
+ spin_lock(&master->timer->lock);
slave->master = master;
slave->timer = master->timer;
if (slave->flags & SNDRV_TIMER_IFLG_RUNNING)
list_add_tail(&slave->active_list,
&master->slave_active_head);
+ spin_unlock(&master->timer->lock);
spin_unlock_irq(&slave_active_lock);
}
}
@@ -287,6 +290,9 @@ int snd_timer_open(struct snd_timer_instance **ti,
mutex_unlock(&register_mutex);
return -ENOMEM;
}
+ /* take a card refcount for safe disconnection */
+ if (timer->card)
+ get_device(timer->card->card_dev);
timeri->slave_class = tid->dev_sclass;
timeri->slave_id = slave_id;
if (list_empty(&timer->open_list_head) && timer->hw.open)
@@ -298,9 +304,6 @@ int snd_timer_open(struct snd_timer_instance **ti,
return 0;
}
-static int _snd_timer_stop(struct snd_timer_instance *timeri,
- int keep_flag, int event);
-
/*
* close a timer instance
*/
@@ -341,19 +344,25 @@ int snd_timer_close(struct snd_timer_instance *timeri)
spin_unlock_irq(&timer->lock);
mutex_lock(&register_mutex);
list_del(&timeri->open_list);
- if (timer && list_empty(&timer->open_list_head) &&
+ if (list_empty(&timer->open_list_head) &&
timer->hw.close)
timer->hw.close(timer);
/* remove slave links */
+ spin_lock_irq(&slave_active_lock);
+ spin_lock(&timer->lock);
list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head,
open_list) {
- spin_lock_irq(&slave_active_lock);
- _snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION);
list_move_tail(&slave->open_list, &snd_timer_slave_list);
slave->master = NULL;
slave->timer = NULL;
- spin_unlock_irq(&slave_active_lock);
+ list_del_init(&slave->ack_list);
+ list_del_init(&slave->active_list);
}
+ spin_unlock(&timer->lock);
+ spin_unlock_irq(&slave_active_lock);
+ /* release a card refcount for safe disconnection */
+ if (timer->card)
+ put_device(timer->card->card_dev);
mutex_unlock(&register_mutex);
}
out:
@@ -383,7 +392,6 @@ unsigned long snd_timer_resolution(struct snd_timer_instance *timeri)
static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
{
struct snd_timer *timer;
- unsigned long flags;
unsigned long resolution = 0;
struct snd_timer_instance *ts;
struct timespec tstamp;
@@ -407,97 +415,111 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
return;
if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
return;
- spin_lock_irqsave(&timer->lock, flags);
list_for_each_entry(ts, &ti->slave_active_head, active_list)
if (ts->ccallback)
- ts->ccallback(ti, event + 100, &tstamp, resolution);
- spin_unlock_irqrestore(&timer->lock, flags);
+ ts->ccallback(ts, event + 100, &tstamp, resolution);
}
-static int snd_timer_start1(struct snd_timer *timer, struct snd_timer_instance *timeri,
- unsigned long sticks)
+/* start/continue a master timer */
+static int snd_timer_start1(struct snd_timer_instance *timeri,
+ bool start, unsigned long ticks)
{
+ struct snd_timer *timer;
+ int result;
+ unsigned long flags;
+
+ timer = timeri->timer;
+ if (!timer)
+ return -EINVAL;
+
+ spin_lock_irqsave(&timer->lock, flags);
+ if (timer->card && timer->card->shutdown) {
+ result = -ENODEV;
+ goto unlock;
+ }
+ if (timeri->flags & (SNDRV_TIMER_IFLG_RUNNING |
+ SNDRV_TIMER_IFLG_START)) {
+ result = -EBUSY;
+ goto unlock;
+ }
+
+ if (start)
+ timeri->ticks = timeri->cticks = ticks;
+ else if (!timeri->cticks)
+ timeri->cticks = 1;
+ timeri->pticks = 0;
+
list_move_tail(&timeri->active_list, &timer->active_list_head);
if (timer->running) {
if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
goto __start_now;
timer->flags |= SNDRV_TIMER_FLG_RESCHED;
timeri->flags |= SNDRV_TIMER_IFLG_START;
- return 1; /* delayed start */
+ result = 1; /* delayed start */
} else {
- timer->sticks = sticks;
+ if (start)
+ timer->sticks = ticks;
timer->hw.start(timer);
__start_now:
timer->running++;
timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
- return 0;
+ result = 0;
}
+ snd_timer_notify1(timeri, start ? SNDRV_TIMER_EVENT_START :
+ SNDRV_TIMER_EVENT_CONTINUE);
+ unlock:
+ spin_unlock_irqrestore(&timer->lock, flags);
+ return result;
}
-static int snd_timer_start_slave(struct snd_timer_instance *timeri)
+/* start/continue a slave timer */
+static int snd_timer_start_slave(struct snd_timer_instance *timeri,
+ bool start)
{
unsigned long flags;
spin_lock_irqsave(&slave_active_lock, flags);
+ if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) {
+ spin_unlock_irqrestore(&slave_active_lock, flags);
+ return -EBUSY;
+ }
timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
- if (timeri->master)
+ if (timeri->master && timeri->timer) {
+ spin_lock(&timeri->timer->lock);
list_add_tail(&timeri->active_list,
&timeri->master->slave_active_head);
+ snd_timer_notify1(timeri, start ? SNDRV_TIMER_EVENT_START :
+ SNDRV_TIMER_EVENT_CONTINUE);
+ spin_unlock(&timeri->timer->lock);
+ }
spin_unlock_irqrestore(&slave_active_lock, flags);
return 1; /* delayed start */
}
-/*
- * start the timer instance
- */
-int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks)
-{
- struct snd_timer *timer;
- int result = -EINVAL;
- unsigned long flags;
-
- if (timeri == NULL || ticks < 1)
- return -EINVAL;
- if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
- result = snd_timer_start_slave(timeri);
- snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
- return result;
- }
- timer = timeri->timer;
- if (timer == NULL)
- return -EINVAL;
- spin_lock_irqsave(&timer->lock, flags);
- timeri->ticks = timeri->cticks = ticks;
- timeri->pticks = 0;
- result = snd_timer_start1(timer, timeri, ticks);
- spin_unlock_irqrestore(&timer->lock, flags);
- snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
- return result;
-}
-
-static int _snd_timer_stop(struct snd_timer_instance * timeri,
- int keep_flag, int event)
+/* stop/pause a master timer */
+static int snd_timer_stop1(struct snd_timer_instance *timeri, bool stop)
{
struct snd_timer *timer;
+ int result = 0;
unsigned long flags;
- if (snd_BUG_ON(!timeri))
- return -ENXIO;
-
- if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
- if (!keep_flag) {
- spin_lock_irqsave(&slave_active_lock, flags);
- timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
- spin_unlock_irqrestore(&slave_active_lock, flags);
- }
- goto __end;
- }
timer = timeri->timer;
if (!timer)
return -EINVAL;
spin_lock_irqsave(&timer->lock, flags);
+ if (!(timeri->flags & (SNDRV_TIMER_IFLG_RUNNING |
+ SNDRV_TIMER_IFLG_START))) {
+ result = -EBUSY;
+ goto unlock;
+ }
list_del_init(&timeri->ack_list);
list_del_init(&timeri->active_list);
+ if (timer->card && timer->card->shutdown)
+ goto unlock;
+ if (stop) {
+ timeri->cticks = timeri->ticks;
+ timeri->pticks = 0;
+ }
if ((timeri->flags & SNDRV_TIMER_IFLG_RUNNING) &&
!(--timer->running)) {
timer->hw.stop(timer);
@@ -510,38 +532,61 @@ static int _snd_timer_stop(struct snd_timer_instance * timeri,
}
}
}
- if (!keep_flag)
- timeri->flags &=
- ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
+ timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
+ snd_timer_notify1(timeri, stop ? SNDRV_TIMER_EVENT_STOP :
+ SNDRV_TIMER_EVENT_CONTINUE);
+ unlock:
spin_unlock_irqrestore(&timer->lock, flags);
- __end:
- if (event != SNDRV_TIMER_EVENT_RESOLUTION)
- snd_timer_notify1(timeri, event);
+ return result;
+}
+
+/* stop/pause a slave timer */
+static int snd_timer_stop_slave(struct snd_timer_instance *timeri, bool stop)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&slave_active_lock, flags);
+ if (!(timeri->flags & SNDRV_TIMER_IFLG_RUNNING)) {
+ spin_unlock_irqrestore(&slave_active_lock, flags);
+ return -EBUSY;
+ }
+ timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
+ if (timeri->timer) {
+ spin_lock(&timeri->timer->lock);
+ list_del_init(&timeri->ack_list);
+ list_del_init(&timeri->active_list);
+ snd_timer_notify1(timeri, stop ? SNDRV_TIMER_EVENT_STOP :
+ SNDRV_TIMER_EVENT_CONTINUE);
+ spin_unlock(&timeri->timer->lock);
+ }
+ spin_unlock_irqrestore(&slave_active_lock, flags);
return 0;
}
/*
+ * start the timer instance
+ */
+int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks)
+{
+ if (timeri == NULL || ticks < 1)
+ return -EINVAL;
+ if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
+ return snd_timer_start_slave(timeri, true);
+ else
+ return snd_timer_start1(timeri, true, ticks);
+}
+
+/*
* stop the timer instance.
*
* do not call this from the timer callback!
*/
int snd_timer_stop(struct snd_timer_instance *timeri)
{
- struct snd_timer *timer;
- unsigned long flags;
- int err;
-
- err = _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_STOP);
- if (err < 0)
- return err;
- timer = timeri->timer;
- if (!timer)
- return -EINVAL;
- spin_lock_irqsave(&timer->lock, flags);
- timeri->cticks = timeri->ticks;
- timeri->pticks = 0;
- spin_unlock_irqrestore(&timer->lock, flags);
- return 0;
+ if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
+ return snd_timer_stop_slave(timeri, true);
+ else
+ return snd_timer_stop1(timeri, true);
}
/*
@@ -549,25 +594,10 @@ int snd_timer_stop(struct snd_timer_instance *timeri)
*/
int snd_timer_continue(struct snd_timer_instance *timeri)
{
- struct snd_timer *timer;
- int result = -EINVAL;
- unsigned long flags;
-
- if (timeri == NULL)
- return result;
if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
- return snd_timer_start_slave(timeri);
- timer = timeri->timer;
- if (! timer)
- return -EINVAL;
- spin_lock_irqsave(&timer->lock, flags);
- if (!timeri->cticks)
- timeri->cticks = 1;
- timeri->pticks = 0;
- result = snd_timer_start1(timer, timeri, timer->sticks);
- spin_unlock_irqrestore(&timer->lock, flags);
- snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_CONTINUE);
- return result;
+ return snd_timer_start_slave(timeri, false);
+ else
+ return snd_timer_start1(timeri, false, 0);
}
/*
@@ -575,7 +605,10 @@ int snd_timer_continue(struct snd_timer_instance *timeri)
*/
int snd_timer_pause(struct snd_timer_instance * timeri)
{
- return _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_PAUSE);
+ if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
+ return snd_timer_stop_slave(timeri, false);
+ else
+ return snd_timer_stop1(timeri, false);
}
/*
@@ -623,6 +656,9 @@ static void snd_timer_tasklet(unsigned long arg)
unsigned long resolution, ticks;
unsigned long flags;
+ if (timer->card && timer->card->shutdown)
+ return;
+
spin_lock_irqsave(&timer->lock, flags);
/* now process all callbacks */
while (!list_empty(&timer->sack_list_head)) {
@@ -663,6 +699,9 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
if (timer == NULL)
return;
+ if (timer->card && timer->card->shutdown)
+ return;
+
spin_lock_irqsave(&timer->lock, flags);
/* remember the current resolution */
@@ -875,11 +914,28 @@ static int snd_timer_dev_register(struct snd_device *dev)
return 0;
}
+/* just for reference in snd_timer_dev_disconnect() below */
+static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
+ int event, struct timespec *tstamp,
+ unsigned long resolution);
+
static int snd_timer_dev_disconnect(struct snd_device *device)
{
struct snd_timer *timer = device->device_data;
+ struct snd_timer_instance *ti;
+
mutex_lock(&register_mutex);
list_del_init(&timer->device_list);
+ /* wake up pending sleepers */
+ list_for_each_entry(ti, &timer->open_list_head, open_list) {
+ /* FIXME: better to have a ti.disconnect() op */
+ if (ti->ccallback == snd_timer_user_ccallback) {
+ struct snd_timer_user *tu = ti->callback_data;
+
+ tu->disconnected = true;
+ wake_up(&tu->qchange_sleep);
+ }
+ }
mutex_unlock(&register_mutex);
return 0;
}
@@ -890,6 +946,8 @@ void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstam
unsigned long resolution = 0;
struct snd_timer_instance *ti, *ts;
+ if (timer->card && timer->card->shutdown)
+ return;
if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE))
return;
if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_MSTART ||
@@ -1050,6 +1108,8 @@ static void snd_timer_proc_read(struct snd_info_entry *entry,
mutex_lock(&register_mutex);
list_for_each_entry(timer, &snd_timer_list, device_list) {
+ if (timer->card && timer->card->shutdown)
+ continue;
switch (timer->tmr_class) {
case SNDRV_TIMER_CLASS_GLOBAL:
snd_iprintf(buffer, "G%i: ", timer->tmr_device);
@@ -1855,6 +1915,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
{
struct snd_timer_user *tu;
long result = 0, unit;
+ int qhead;
int err = 0;
tu = file->private_data;
@@ -1867,7 +1928,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) {
err = -EAGAIN;
- break;
+ goto _error;
}
set_current_state(TASK_INTERRUPTIBLE);
@@ -1882,40 +1943,39 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
remove_wait_queue(&tu->qchange_sleep, &wait);
+ if (tu->disconnected) {
+ err = -ENODEV;
+ goto _error;
+ }
if (signal_pending(current)) {
err = -ERESTARTSYS;
- break;
+ goto _error;
}
}
+ qhead = tu->qhead++;
+ tu->qhead %= tu->queue_size;
spin_unlock_irq(&tu->qlock);
- if (err < 0)
- goto _error;
if (tu->tread) {
- if (copy_to_user(buffer, &tu->tqueue[tu->qhead++],
- sizeof(struct snd_timer_tread))) {
+ if (copy_to_user(buffer, &tu->tqueue[qhead],
+ sizeof(struct snd_timer_tread)))
err = -EFAULT;
- goto _error;
- }
} else {
- if (copy_to_user(buffer, &tu->queue[tu->qhead++],
- sizeof(struct snd_timer_read))) {
+ if (copy_to_user(buffer, &tu->queue[qhead],
+ sizeof(struct snd_timer_read)))
err = -EFAULT;
- goto _error;
- }
}
- tu->qhead %= tu->queue_size;
-
- result += unit;
- buffer += unit;
-
spin_lock_irq(&tu->qlock);
tu->qused--;
+ if (err < 0)
+ goto _error;
+ result += unit;
+ buffer += unit;
}
- spin_unlock_irq(&tu->qlock);
_error:
+ spin_unlock_irq(&tu->qlock);
mutex_unlock(&tu->ioctl_lock);
return result > 0 ? result : err;
}
@@ -1932,6 +1992,8 @@ static unsigned int snd_timer_user_poll(struct file *file, poll_table * wait)
mask = 0;
if (tu->qused)
mask |= POLLIN | POLLRDNORM;
+ if (tu->disconnected)
+ mask |= POLLERR;
return mask;
}
diff --git a/sound/soc/msm/qdsp6v2/audio_cal_utils.c b/sound/soc/msm/qdsp6v2/audio_cal_utils.c
index 2b9df4cecbdc..5b1656cba047 100644
--- a/sound/soc/msm/qdsp6v2/audio_cal_utils.c
+++ b/sound/soc/msm/qdsp6v2/audio_cal_utils.c
@@ -604,7 +604,9 @@ done:
return cal_block;
err:
kfree(cal_block->cal_info);
+ cal_block->cal_info = NULL;
kfree(cal_block->client_info);
+ cal_block->client_info = NULL;
kfree(cal_block);
cal_block = NULL;
return cal_block;