summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/soc/qcom/hab/hab.c19
-rw-r--r--drivers/soc/qcom/hab/hab.h2
-rw-r--r--drivers/soc/qcom/hab/hab_mem_linux.c24
-rw-r--r--drivers/soc/qcom/hab/hab_mimex.c21
-rw-r--r--drivers/soc/qcom/hab/hab_msg.c15
-rw-r--r--drivers/soc/qcom/hab/hab_pchan.c5
-rw-r--r--drivers/soc/qcom/hab/hab_qvm.c28
-rw-r--r--drivers/soc/qcom/hab/hab_qvm.h1
-rw-r--r--drivers/soc/qcom/hab/qvm_comm.c1
9 files changed, 106 insertions, 10 deletions
diff --git a/drivers/soc/qcom/hab/hab.c b/drivers/soc/qcom/hab/hab.c
index cd79432b4816..040730d63a83 100644
--- a/drivers/soc/qcom/hab/hab.c
+++ b/drivers/soc/qcom/hab/hab.c
@@ -78,6 +78,7 @@ struct uhab_context *hab_ctx_alloc(int kernel)
kref_init(&ctx->refcount);
ctx->import_ctx = habmem_imp_hyp_open();
if (!ctx->import_ctx) {
+ pr_err("habmem_imp_hyp_open failed\n");
kfree(ctx);
return NULL;
}
@@ -155,6 +156,7 @@ struct virtual_channel *frontend_open(struct uhab_context *ctx,
dev = find_hab_device(mm_id);
if (dev == NULL) {
+ pr_err("HAB device %d is not initialized\n", mm_id);
ret = -EINVAL;
goto err;
}
@@ -168,6 +170,7 @@ struct virtual_channel *frontend_open(struct uhab_context *ctx,
vchan = hab_vchan_alloc(ctx, pchan);
if (!vchan) {
+ pr_err("vchan alloc failed\n");
ret = -ENOMEM;
goto err;
}
@@ -195,6 +198,7 @@ struct virtual_channel *frontend_open(struct uhab_context *ctx,
hab_open_request_free(recv_request);
vchan->session_id = open_id;
+ pr_debug("vchan->session_id:%d\n", vchan->session_id);
/* Send Ack sequence */
hab_open_request_init(&request, HAB_PAYLOAD_TYPE_ACK, pchan,
@@ -230,6 +234,7 @@ struct virtual_channel *backend_listen(struct uhab_context *ctx,
dev = find_hab_device(mm_id);
if (dev == NULL) {
+ pr_err("failed to find dev based on id %d\n", mm_id);
ret = -EINVAL;
goto err;
}
@@ -259,6 +264,7 @@ struct virtual_channel *backend_listen(struct uhab_context *ctx,
vchan->otherend_id = otherend_vchan_id;
vchan->session_id = open_id;
+ pr_debug("vchan->session_id:%d\n", vchan->session_id);
/* Send Init-Ack sequence */
hab_open_request_init(&request, HAB_PAYLOAD_TYPE_INIT_ACK,
@@ -291,6 +297,7 @@ struct virtual_channel *backend_listen(struct uhab_context *ctx,
hab_pchan_put(pchan);
return vchan;
err:
+ pr_err("listen on mmid %d failed\n", mm_id);
if (vchan)
hab_vchan_put(vchan);
if (pchan)
@@ -396,6 +403,9 @@ int hab_vchan_open(struct uhab_context *ctx,
struct virtual_channel *vchan = NULL;
struct hab_device *dev;
+ pr_debug("Open mmid=%d, loopback mode=%d, loopback num=%d\n",
+ mmid, hab_driver.b_loopback, hab_driver.loopback_num);
+
if (!vcid)
return -EINVAL;
@@ -424,8 +434,13 @@ int hab_vchan_open(struct uhab_context *ctx,
}
}
- if (IS_ERR(vchan))
+ if (IS_ERR(vchan)) {
+ pr_err("vchan open failed over mmid=%d\n", mmid);
return PTR_ERR(vchan);
+ }
+
+ pr_debug("vchan id %x, remote id %x\n",
+ vchan->id, vchan->otherend_id);
write_lock(&ctx->ctx_lock);
list_add_tail(&vchan->node, &ctx->vchannels);
@@ -718,6 +733,8 @@ static int hab_release(struct inode *inodep, struct file *filep)
if (!ctx)
return 0;
+ pr_debug("inode %pK, filep %pK\n", inodep, filep);
+
write_lock(&ctx->ctx_lock);
list_for_each_entry_safe(vchan, tmp, &ctx->vchannels, node) {
diff --git a/drivers/soc/qcom/hab/hab.h b/drivers/soc/qcom/hab/hab.h
index a2901f940a5d..19a8584edd35 100644
--- a/drivers/soc/qcom/hab/hab.h
+++ b/drivers/soc/qcom/hab/hab.h
@@ -13,7 +13,7 @@
#ifndef __HAB_H
#define __HAB_H
-#define pr_fmt(fmt) "hab: " fmt
+#define pr_fmt(fmt) "|hab:%s:%d|" fmt, __func__, __LINE__
#include <linux/types.h>
diff --git a/drivers/soc/qcom/hab/hab_mem_linux.c b/drivers/soc/qcom/hab/hab_mem_linux.c
index a69a7571a0f6..ecc3f52a6662 100644
--- a/drivers/soc/qcom/hab/hab_mem_linux.c
+++ b/drivers/soc/qcom/hab/hab_mem_linux.c
@@ -74,8 +74,12 @@ static int habmem_get_dma_pages(unsigned long address,
int fd;
vma = find_vma(current->mm, address);
- if (!vma || !vma->vm_file)
+ if (!vma || !vma->vm_file) {
+ pr_err("cannot find vma\n");
goto err;
+ }
+
+ pr_debug("vma flags %lx\n", vma->vm_flags);
/* Look for the fd that matches this the vma file */
fd = iterate_fd(current->files, 0, match_file, vma->vm_file);
@@ -104,6 +108,7 @@ static int habmem_get_dma_pages(unsigned long address,
for_each_sg(sg_table->sgl, s, sg_table->nents, i) {
page = sg_page(s);
+ pr_debug("sgl length %d\n", s->length);
for (j = page_offset; j < (s->length >> PAGE_SHIFT); j++) {
pages[rc] = nth_page(page, j);
@@ -318,6 +323,9 @@ long habmem_imp_hyp_map(void *imp_ctx,
kfree(pglist);
pr_err("%ld pages vmap failed\n", pglist->npages);
return -ENOMEM;
+ } else {
+ pr_debug("%ld pages vmap pass, return %pK\n",
+ pglist->npages, pglist->kva);
}
pglist->uva = NULL;
@@ -332,6 +340,7 @@ long habmem_imp_hyp_map(void *imp_ctx,
list_add_tail(&pglist->list, &priv->imp_list);
priv->cnt++;
write_unlock(&priv->implist_lock);
+ pr_debug("index returned %llx\n", *index);
return 0;
}
@@ -349,6 +358,9 @@ long habmm_imp_hyp_unmap(void *imp_ctx,
write_lock(&priv->implist_lock);
list_for_each_entry_safe(pglist, tmp, &priv->imp_list, list) {
+ pr_debug("node pglist %pK, kernel %d, pg_index %llx\n",
+ pglist, pglist->kernel, pg_index);
+
if (kernel) {
if (pglist->kva == (void *)((uintptr_t)index))
found = 1;
@@ -370,6 +382,9 @@ long habmm_imp_hyp_unmap(void *imp_ctx,
return -EINVAL;
}
+ pr_debug("detach pglist %pK, index %llx, kernel %d, list cnt %d\n",
+ pglist, pglist->index, pglist->kernel, priv->cnt);
+
if (kernel)
if (pglist->kva)
vunmap(pglist->kva);
@@ -405,6 +420,8 @@ static int hab_map_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
return VM_FAULT_SIGBUS;
}
+ pr_debug("Fault page index %d\n", page_idx);
+
page = pglist->pages[page_idx];
get_page(page);
vmf->page = page;
@@ -434,6 +451,9 @@ int habmem_imp_hyp_mmap(struct file *filp, struct vm_area_struct *vma)
struct pages_list *pglist;
int bfound = 0;
+ pr_debug("mmap request start %lX, len %ld, index %lX\n",
+ vma->vm_start, length, vma->vm_pgoff);
+
read_lock(&imp_ctx->implist_lock);
list_for_each_entry(pglist, &imp_ctx->imp_list, list) {
if (pglist->index == vma->vm_pgoff) {
@@ -444,7 +464,7 @@ int habmem_imp_hyp_mmap(struct file *filp, struct vm_area_struct *vma)
read_unlock(&imp_ctx->implist_lock);
if (!bfound) {
- pr_err("Failed to find pglist vm_pgoff: %d\n", vma->vm_pgoff);
+ pr_err("Failed to find pglist vm_pgoff: %ld\n", vma->vm_pgoff);
return -EINVAL;
}
diff --git a/drivers/soc/qcom/hab/hab_mimex.c b/drivers/soc/qcom/hab/hab_mimex.c
index 453bf2d93f4c..67601590908e 100644
--- a/drivers/soc/qcom/hab/hab_mimex.c
+++ b/drivers/soc/qcom/hab/hab_mimex.c
@@ -229,6 +229,8 @@ int hab_mem_export(struct uhab_context *ctx,
if (!ctx || !param || param->sizebytes > HAB_MAX_EXPORT_SIZE)
return -EINVAL;
+ pr_debug("vc %X, mem size %d\n", param->vcid, param->sizebytes);
+
vchan = hab_get_vchan_fromvcid(param->vcid, ctx);
if (!vchan || !vchan->pchan) {
ret = -ENODEV;
@@ -304,7 +306,10 @@ int hab_mem_unexport(struct uhab_context *ctx,
return -EINVAL;
ret = habmem_hyp_revoke(exp->payload, exp->payload_count);
-
+ if (ret) {
+ pr_err("Error found in revoke grant with ret %d", ret);
+ return ret;
+ }
habmem_remove_export(exp);
return ret;
}
@@ -336,6 +341,10 @@ int hab_mem_import(struct uhab_context *ctx,
return ret;
}
+ pr_debug("call map id: %d pcnt %d remote_dom %d 1st_ref:0x%X\n",
+ exp->export_id, exp->payload_count, exp->domid_local,
+ *((uint32_t *)exp->payload));
+
ret = habmem_imp_hyp_map(ctx->import_ctx,
exp->payload,
exp->payload_count,
@@ -350,6 +359,8 @@ int hab_mem_import(struct uhab_context *ctx,
exp->domid_local, *((uint32_t *)exp->payload));
return ret;
}
+ pr_debug("import index %llx, kva %llx, kernel %d\n",
+ exp->import_index, param->kva, kernel);
param->index = exp->import_index;
param->kva = (uint64_t)exp->kva;
@@ -374,6 +385,9 @@ int hab_mem_unimport(struct uhab_context *ctx,
list_del(&exp->node);
ctx->import_total--;
found = 1;
+
+ pr_debug("found id:%d payload cnt:%d kernel:%d\n",
+ exp->export_id, exp->payload_count, kernel);
break;
}
}
@@ -386,7 +400,10 @@ int hab_mem_unimport(struct uhab_context *ctx,
exp->import_index,
exp->payload_count,
kernel);
-
+ if (ret) {
+ pr_err("unmap fail id:%d pcnt:%d kernel:%d\n",
+ exp->export_id, exp->payload_count, kernel);
+ }
param->kva = (uint64_t)exp->kva;
kfree(exp);
}
diff --git a/drivers/soc/qcom/hab/hab_msg.c b/drivers/soc/qcom/hab/hab_msg.c
index 470f10e53dd7..700239a25652 100644
--- a/drivers/soc/qcom/hab/hab_msg.c
+++ b/drivers/soc/qcom/hab/hab_msg.c
@@ -126,6 +126,11 @@ static int hab_receive_create_export_ack(struct physical_channel *pchan,
sizebytes) != sizebytes)
return -EIO;
+ pr_debug("receive export id %d, local vc %X, vd remote %X\n",
+ ack_recvd->ack.export_id,
+ ack_recvd->ack.vcid_local,
+ ack_recvd->ack.vcid_remote);
+
spin_lock_bh(&ctx->expq_lock);
list_add_tail(&ack_recvd->node, &ctx->exp_rxq);
spin_unlock_bh(&ctx->expq_lock);
@@ -235,6 +240,10 @@ void hab_msg_recv(struct physical_channel *pchan,
break;
case HAB_PAYLOAD_TYPE_CLOSE:
+ /* remote request close */
+ pr_debug("remote side request close\n");
+ pr_debug(" vchan id %X, other end %X, session %d\n",
+ vchan->id, vchan->otherend_id, session_id);
hab_vchan_stop(vchan);
break;
@@ -254,6 +263,12 @@ void hab_msg_recv(struct physical_channel *pchan,
break;
default:
+ pr_err("unknown msg is received\n");
+ pr_err("payload type %d, vchan id %x\n",
+ payload_type, vchan_id);
+ pr_err("sizebytes %zx, session %d\n",
+ sizebytes, session_id);
+
break;
}
if (vchan)
diff --git a/drivers/soc/qcom/hab/hab_pchan.c b/drivers/soc/qcom/hab/hab_pchan.c
index f99437bcb6a6..36bc29b7bd0c 100644
--- a/drivers/soc/qcom/hab/hab_pchan.c
+++ b/drivers/soc/qcom/hab/hab_pchan.c
@@ -66,8 +66,11 @@ hab_pchan_find_domid(struct hab_device *dev, int dom_id)
if (pchan->dom_id == dom_id || dom_id == HABCFG_VMID_DONT_CARE)
break;
- if (pchan->dom_id != dom_id && dom_id != HABCFG_VMID_DONT_CARE)
+ if (pchan->dom_id != dom_id && dom_id != HABCFG_VMID_DONT_CARE) {
+ pr_err("dom_id mismatch requested %d, existing %d\n",
+ dom_id, pchan->dom_id);
pchan = NULL;
+ }
if (pchan && !kref_get_unless_zero(&pchan->refcount))
pchan = NULL;
diff --git a/drivers/soc/qcom/hab/hab_qvm.c b/drivers/soc/qcom/hab/hab_qvm.c
index ce99b9ef1774..fec06cbbd0c7 100644
--- a/drivers/soc/qcom/hab/hab_qvm.c
+++ b/drivers/soc/qcom/hab/hab_qvm.c
@@ -93,11 +93,14 @@ static uint64_t get_guest_factory_paddr(struct qvm_channel *dev,
{
int i;
+ pr_debug("name = %s, factory paddr = 0x%lx, irq %d, pages %d\n",
+ name, factory_addr, irq, pages);
dev->guest_factory = (struct guest_shm_factory *)factory_addr;
if (dev->guest_factory->signature != GUEST_SHM_SIGNATURE) {
- pr_err("shmem factory signature incorrect: %ld != %llu\n",
- GUEST_SHM_SIGNATURE, dev->guest_factory->signature);
+ pr_err("signature error: %ld != %llu, factory addr %lx\n",
+ GUEST_SHM_SIGNATURE, dev->guest_factory->signature,
+ factory_addr);
return 0;
}
@@ -119,7 +122,11 @@ static uint64_t get_guest_factory_paddr(struct qvm_channel *dev,
return 0;
}
- pr_debug("shm creation size %x\n", dev->guest_factory->size);
+ pr_debug("shm creation size %x, paddr=%llx, vector %d, dev %pK\n",
+ dev->guest_factory->size,
+ dev->guest_factory->shmem,
+ dev->guest_intr,
+ dev);
dev->factory_addr = factory_addr;
dev->irq = irq;
@@ -135,6 +142,8 @@ static int create_dispatcher(struct physical_channel *pchan)
tasklet_init(&dev->task, physical_channel_rx_dispatch,
(unsigned long) pchan);
+ pr_debug("request_irq: irq = %d, pchan name = %s",
+ dev->irq, pchan->name);
ret = request_irq(dev->irq, shm_irq_handler, IRQF_SHARED,
pchan->name, pchan);
@@ -152,6 +161,8 @@ void hab_pipe_reset(struct physical_channel *pchan)
pipe_ep = hab_pipe_init(dev->pipe, PIPE_SHMEM_SIZE,
pchan->is_be ? 0 : 1);
+ if (dev->pipe_ep != pipe_ep)
+ pr_warn("The pipe endpoint must not change\n");
}
/*
@@ -180,6 +191,9 @@ int habhyp_commdev_alloc(void **commdev, int is_be, char *name,
int total_pages;
struct page **pages;
+ pr_debug("habhyp_commdev_alloc: pipe_alloc_size is %d\n",
+ pipe_alloc_size);
+
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
@@ -193,6 +207,8 @@ int habhyp_commdev_alloc(void **commdev, int is_be, char *name,
pipe_alloc_pages);
qvm_priv->curr++;
if (qvm_priv->curr > qvm_priv->probe_cnt) {
+ pr_err("factory setting %d overflow probed cnt %d\n",
+ qvm_priv->curr, qvm_priv->probe_cnt);
ret = -1;
goto err;
}
@@ -215,11 +231,17 @@ int habhyp_commdev_alloc(void **commdev, int is_be, char *name,
}
shmdata = (char *)dev->guest_ctrl + PAGE_SIZE;
+
+ pr_debug("ctrl page 0x%llx mapped at 0x%pK, idx %d\n",
+ paddr, dev->guest_ctrl, dev->guest_ctrl->idx);
+ pr_debug("data buffer mapped at 0x%pK\n", shmdata);
dev->idx = dev->guest_ctrl->idx;
kfree(pages);
dev->pipe = (struct hab_pipe *) shmdata;
+ pr_debug("\"%s\": pipesize %d, addr 0x%pK, be %d\n", name,
+ pipe_alloc_size, dev->pipe, is_be);
dev->pipe_ep = hab_pipe_init(dev->pipe, PIPE_SHMEM_SIZE,
is_be ? 0 : 1);
/* newly created pchan is added to mmid device list */
diff --git a/drivers/soc/qcom/hab/hab_qvm.h b/drivers/soc/qcom/hab/hab_qvm.h
index df1a217d5323..b483f4c21331 100644
--- a/drivers/soc/qcom/hab/hab_qvm.h
+++ b/drivers/soc/qcom/hab/hab_qvm.h
@@ -30,6 +30,7 @@ struct qvm_channel {
struct tasklet_struct task;
struct guest_shm_factory *guest_factory;
struct guest_shm_control *guest_ctrl;
+ /* cached guest ctrl idx value to prevent trap when accessed */
uint32_t idx;
int channel;
diff --git a/drivers/soc/qcom/hab/qvm_comm.c b/drivers/soc/qcom/hab/qvm_comm.c
index 108720888407..41e34be9ac21 100644
--- a/drivers/soc/qcom/hab/qvm_comm.c
+++ b/drivers/soc/qcom/hab/qvm_comm.c
@@ -21,6 +21,7 @@ static inline void habhyp_notify(void *commdev)
dev->guest_ctrl->notify = ~0;
}
+/* this is only used to read payload, never the head! */
int physical_channel_read(struct physical_channel *pchan,
void *payload,
size_t read_size)