From 7c177596a885b8a1a9b346863164b543071081cb Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Wed, 10 Jun 2020 19:44:35 -0700 Subject: [PATCH 1/7] soc: qcom: guestvm_loader: Wait for ready state before start The ready state gives clients in the primary vm a chance to share resources before the vm is started and set to running state. This window is currently missing because guestvm_loader starts the vm directly after subsystem_get(). Make the guestvm boot code wait for the HH_RM_VM_STATUS_READY callback before starting the vm. This allows drivers that need to share resources a chance to do so instead of racing with guestvm_loader. Drivers can register with the rm notifier chain at a higher priority than 0 to be called first. This change can eventually be replaced by a separate driver or notifier chain managed by guestvm_loader to provide better synchronization methods compared to notifier chain priority. Change-Id: I0fb3c5c41957381b31fa652deec0d6d51a41e6ef Signed-off-by: Chris Lew --- drivers/soc/qcom/guestvm_loader.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/soc/qcom/guestvm_loader.c b/drivers/soc/qcom/guestvm_loader.c index 7eb0e0e10b47..6aaa090ab3f0 100644 --- a/drivers/soc/qcom/guestvm_loader.c +++ b/drivers/soc/qcom/guestvm_loader.c @@ -3,6 +3,7 @@ * Copyright (c) 2020, The Linux Foundation. All rights reserved. */ +#include #include #include #include @@ -31,6 +32,7 @@ static struct kobj_type guestvm_kobj_type = { struct guestvm_loader_private { struct notifier_block guestvm_nb; + struct completion vm_start; struct kobject vm_loader_kobj; struct device *dev; char vm_name[MAX_LEN]; @@ -82,6 +84,7 @@ static int guestvm_loader_nb_handler(struct notifier_block *this, vm_status_payload->vmid, ret); return NOTIFY_DONE; } + complete_all(&priv->vm_start); break; case HH_RM_VM_STATUS_RUNNING: break; @@ -129,6 +132,8 @@ static ssize_t guestvm_loader_start(struct kobject *kobj, priv->vm_loaded = NULL; return ret; } + if (wait_for_completion_interruptible(&priv->vm_start)) + dev_err(priv->dev, "VM start completion interrupted\n"); priv->vm_status = HH_RM_VM_STATUS_RUNNING; ret = hh_rm_vm_start(priv->vmid); @@ -184,6 +189,7 @@ static int guestvm_loader_probe(struct platform_device *pdev) goto error_return; } + init_completion(&priv->vm_start); priv->guestvm_nb.notifier_call = guestvm_loader_nb_handler; ret = hh_rm_register_notifier(&priv->guestvm_nb); if (ret) @@ -207,8 +213,10 @@ static int guestvm_loader_remove(struct platform_device *pdev) { struct guestvm_loader_private *priv = platform_get_drvdata(pdev); - if (priv->vm_loaded) + if (priv->vm_loaded) { subsystem_put(priv->vm_loaded); + init_completion(&priv->vm_start); + } if (kobject_name(&priv->vm_loader_kobj) != NULL) { kobject_del(&priv->vm_loader_kobj); From 0fc1e59781edc145012da19408cb55ea35988a3e Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Thu, 11 Jun 2020 00:00:39 -0700 Subject: [PATCH 2/7] neuron: ch_haven: Read peer name from device tree Add support for the primary vm to read the vm peer name from device tree. This information is needed to share memory to the peer vm. Change-Id: I9a38370c8b80480bcdd0988c515adf64b36f99c1 Signed-off-by: Chris Lew --- net/neuron/channel/ch_haven_recv.c | 9 ++++++++- net/neuron/channel/ch_haven_send.c | 9 ++++++++- net/neuron/channel/ch_mq_shmem_common.h | 2 ++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/net/neuron/channel/ch_haven_recv.c b/net/neuron/channel/ch_haven_recv.c index 47f0a6568436..b58af7a8e860 100644 --- a/net/neuron/channel/ch_haven_recv.c +++ b/net/neuron/channel/ch_haven_recv.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "ch_mq_shmem_common.h" @@ -335,10 +336,16 @@ static int channel_hh_map_memory(struct neuron_mq_data_priv *priv, return -ENXIO; } - if (of_property_read_bool(dev->of_node, "qcom,primary")) + if (of_property_read_bool(dev->of_node, "qcom,primary")) { memset(priv->base, 0, sizeof(struct neuron_shmem_channel_header)); + ret = of_property_read_u32(dev->of_node, "peer-name", + &priv->peer_name); + if (ret) + priv->peer_name = HH_SELF_VM; + } + return 0; } diff --git a/net/neuron/channel/ch_haven_send.c b/net/neuron/channel/ch_haven_send.c index 43ceb3387c16..1fb4b41e690f 100644 --- a/net/neuron/channel/ch_haven_send.c +++ b/net/neuron/channel/ch_haven_send.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "ch_mq_shmem_common.h" @@ -320,10 +321,16 @@ static int channel_hh_map_memory(struct neuron_mq_data_priv *priv, return -ENXIO; } - if (of_property_read_bool(dev->of_node, "qcom,primary")) + if (of_property_read_bool(dev->of_node, "qcom,primary")) { memset(priv->base, 0, sizeof(struct neuron_shmem_channel_header)); + ret = of_property_read_u32(dev->of_node, "peer-name", + &priv->peer_name); + if (ret) + priv->peer_name = HH_SELF_VM; + } + return 0; } diff --git a/net/neuron/channel/ch_mq_shmem_common.h b/net/neuron/channel/ch_mq_shmem_common.h index 3a74e81703e0..b4b163b237cc 100644 --- a/net/neuron/channel/ch_mq_shmem_common.h +++ b/net/neuron/channel/ch_mq_shmem_common.h @@ -76,6 +76,8 @@ struct neuron_mq_data_priv { atomic64_t virq_payload; /* A counter to calculate the interrupt received. */ u32 interrupt_counter; + /* name of peer vm */ + u32 peer_name; /* haven tx doorbell descriptor */ void *tx_dbl; /* haven rx doorbell descriptor */ From 6826400d8d50c590e4be51cd09d42a81ae4d9b2a Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Thu, 11 Jun 2020 12:05:44 -0700 Subject: [PATCH 3/7] neuron: ch_haven: Store haven label for future use Store the haven label so it can be used for other haven resources such as attaching it to memparcels that are shared. Change-Id: I90717bc7d158fb73ecb4442ede3c5d476f3d2045 Signed-off-by: Chris Lew --- net/neuron/channel/ch_haven_recv.c | 13 +++++++------ net/neuron/channel/ch_haven_send.c | 13 +++++++------ net/neuron/channel/ch_mq_shmem_common.h | 2 ++ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/net/neuron/channel/ch_haven_recv.c b/net/neuron/channel/ch_haven_recv.c index b58af7a8e860..ae50c5a72aa6 100644 --- a/net/neuron/channel/ch_haven_recv.c +++ b/net/neuron/channel/ch_haven_recv.c @@ -365,6 +365,12 @@ static int channel_hh_probe(struct neuron_channel *cdev) return -ENOMEM; priv->dev = cdev; + ret = of_property_read_u32(node, "haven-label", &priv->haven_label); + if (ret) { + dev_err(dev, "failed to read label info %d\n", ret); + return ret; + } + ret = channel_hh_map_memory(priv, dev); if (ret) { dev_err(dev, "failed to map memory %d\n", ret); @@ -372,12 +378,7 @@ static int channel_hh_probe(struct neuron_channel *cdev) } /* Get outgoing haven doorbell information */ - ret = of_property_read_u32(node, "haven-label", &dbl_label); - if (ret) { - dev_err(dev, "failed to read label info %d\n", ret); - goto fail_tx_dbl; - } - + dbl_label = priv->haven_label; priv->tx_dbl = hh_dbl_tx_register(dbl_label); if (IS_ERR_OR_NULL(priv->tx_dbl)) { ret = PTR_ERR(priv->tx_dbl); diff --git a/net/neuron/channel/ch_haven_send.c b/net/neuron/channel/ch_haven_send.c index 1fb4b41e690f..4b0c2d44621c 100644 --- a/net/neuron/channel/ch_haven_send.c +++ b/net/neuron/channel/ch_haven_send.c @@ -350,17 +350,18 @@ static int channel_hh_probe(struct neuron_channel *cdev) return -ENOMEM; priv->dev = cdev; + ret = of_property_read_u32(node, "haven-label", &priv->haven_label); + if (ret) { + dev_err(dev, "failed to read label info %d\n", ret); + return ret; + } + ret = channel_hh_map_memory(priv, dev); if (ret) return ret; /* Get outgoing haven doorbell information */ - ret = of_property_read_u32(node, "haven-label", &dbl_label); - if (ret) { - dev_err(dev, "failed to read label info %d\n", ret); - goto fail_tx_dbl; - } - + dbl_label = priv->haven_label; priv->tx_dbl = hh_dbl_tx_register(dbl_label); if (IS_ERR_OR_NULL(priv->tx_dbl)) { ret = PTR_ERR(priv->tx_dbl); diff --git a/net/neuron/channel/ch_mq_shmem_common.h b/net/neuron/channel/ch_mq_shmem_common.h index b4b163b237cc..10f3381ce590 100644 --- a/net/neuron/channel/ch_mq_shmem_common.h +++ b/net/neuron/channel/ch_mq_shmem_common.h @@ -78,6 +78,8 @@ struct neuron_mq_data_priv { u32 interrupt_counter; /* name of peer vm */ u32 peer_name; + /* label to get haven resources like doorbell and shm */ + u32 haven_label; /* haven tx doorbell descriptor */ void *tx_dbl; /* haven rx doorbell descriptor */ From 66af98dc3f166a24fae4e6a09e512656e0fa72c9 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Thu, 11 Jun 2020 13:11:33 -0700 Subject: [PATCH 4/7] neuron: ch_haven: Add memory sharing support The carved out or allocated memory may not be configured to be accessible by both the owner and consumer vms. Add support to share memory through hyp_assign_phy() and assign a label to the resultant memparcel through hh_rm_mem_qcom_lookup_sgl(). This sharing sequence should only be done by the owner of the reserved memory region. Currently we indicate this with the qcom,primary tag in device tree. Change-Id: Idf5658ab4cf0d1c022f6b919914a8e782318c8d7 Signed-off-by: Chris Lew --- net/neuron/channel/ch_haven_recv.c | 81 +++++++++++++++++++++++++ net/neuron/channel/ch_haven_send.c | 79 ++++++++++++++++++++++++ net/neuron/channel/ch_mq_shmem_common.h | 4 ++ 3 files changed, 164 insertions(+) diff --git a/net/neuron/channel/ch_haven_recv.c b/net/neuron/channel/ch_haven_recv.c index ae50c5a72aa6..b14525587664 100644 --- a/net/neuron/channel/ch_haven_recv.c +++ b/net/neuron/channel/ch_haven_recv.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "ch_mq_shmem_common.h" #define CHANNEL_VERSION NEURON_SHMEM_CHANNEL_V1 @@ -295,6 +296,82 @@ static int channel_sync_thread(void *data) return 0; } +static int channel_hh_share_mem(struct neuron_mq_data_priv *priv, + hh_vmid_t self, hh_vmid_t peer) +{ + u32 src_vmlist[1] = {self}; + int dst_vmlist[2] = {self, peer}; + int dst_perms[2] = {PERM_READ | PERM_WRITE, PERM_READ | PERM_WRITE}; + struct hh_acl_desc *acl; + struct hh_sgl_desc *sgl; + int ret; + + ret = hyp_assign_phys(priv->buffer.start, resource_size(&priv->buffer), + src_vmlist, 1, + dst_vmlist, dst_perms, 2); + if (ret) { + pr_err("hyp_assign_phys failed addr=%x size=%u err=%d\n", + priv->buffer.start, resource_size(&priv->buffer), ret); + return ret; + } + + acl = kzalloc(offsetof(struct hh_acl_desc, acl_entries[2]), GFP_KERNEL); + if (!acl) + return -ENOMEM; + sgl = kzalloc(offsetof(struct hh_sgl_desc, sgl_entries[1]), GFP_KERNEL); + if (!sgl) { + kfree(acl); + return -ENOMEM; + } + + acl->n_acl_entries = 2; + acl->acl_entries[0].vmid = (u16)self; + acl->acl_entries[0].perms = HH_RM_ACL_R | HH_RM_ACL_W; + acl->acl_entries[1].vmid = (u16)peer; + acl->acl_entries[1].perms = HH_RM_ACL_R | HH_RM_ACL_W; + + sgl->n_sgl_entries = 1; + sgl->sgl_entries[0].ipa_base = priv->buffer.start; + sgl->sgl_entries[0].size = resource_size(&priv->buffer); + ret = hh_rm_mem_qcom_lookup_sgl(HH_RM_MEM_TYPE_NORMAL, + priv->haven_label, + acl, sgl, NULL, + &priv->shm_memparcel); + kfree(acl); + kfree(sgl); + + return ret; +} + +static int channel_hh_rm_cb(struct notifier_block *nb, unsigned long cmd, + void *data) +{ + struct hh_rm_notif_vm_status_payload *vm_status_payload; + struct neuron_mq_data_priv *priv; + hh_vmid_t peer_vmid; + hh_vmid_t self_vmid; + + priv = container_of(nb, struct neuron_mq_data_priv, rm_nb); + + if (cmd != HH_RM_NOTIF_VM_STATUS) + return NOTIFY_DONE; + + vm_status_payload = data; + if (vm_status_payload->vm_status != HH_RM_VM_STATUS_READY) + return NOTIFY_DONE; + if (hh_rm_get_vmid(priv->peer_name, &peer_vmid)) + return NOTIFY_DONE; + if (hh_rm_get_vmid(HH_PRIMARY_VM, &self_vmid)) + return NOTIFY_DONE; + if (peer_vmid != vm_status_payload->vmid) + return NOTIFY_DONE; + + if (channel_hh_share_mem(priv, self_vmid, peer_vmid)) + pr_err("%s: failed to share memory\n", __func__); + + return NOTIFY_DONE; +} + static int channel_hh_map_memory(struct neuron_mq_data_priv *priv, struct device *dev) { @@ -344,6 +421,10 @@ static int channel_hh_map_memory(struct neuron_mq_data_priv *priv, &priv->peer_name); if (ret) priv->peer_name = HH_SELF_VM; + + priv->rm_nb.notifier_call = channel_hh_rm_cb; + priv->rm_nb.priority = INT_MAX; + hh_rm_register_notifier(&priv->rm_nb); } return 0; diff --git a/net/neuron/channel/ch_haven_send.c b/net/neuron/channel/ch_haven_send.c index 4b0c2d44621c..da6238371c63 100644 --- a/net/neuron/channel/ch_haven_send.c +++ b/net/neuron/channel/ch_haven_send.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "ch_mq_shmem_common.h" #define CHANNEL_VERSION NEURON_SHMEM_CHANNEL_V1 @@ -280,6 +281,80 @@ static int channel_sync_thread(void *data) return 0; } +static int channel_hh_share_mem(struct neuron_mq_data_priv *priv, + hh_vmid_t self, hh_vmid_t peer) +{ + u32 src_vmlist[1] = {self}; + int dst_vmlist[2] = {self, peer}; + int dst_perms[2] = {PERM_READ | PERM_WRITE, PERM_READ | PERM_WRITE}; + struct hh_acl_desc *acl; + struct hh_sgl_desc *sgl; + int ret; + + ret = hyp_assign_phys(priv->buffer.start, resource_size(&priv->buffer), + src_vmlist, 1, + dst_vmlist, dst_perms, 2); + if (ret) { + pr_err("hyp_assign_phys failed addr=%x size=%u err=%d\n", + priv->buffer.start, resource_size(&priv->buffer), ret); + return ret; + } + + acl = kzalloc(offsetof(struct hh_acl_desc, acl_entries[2]), GFP_KERNEL); + if (!acl) + return -ENOMEM; + sgl = kzalloc(offsetof(struct hh_sgl_desc, sgl_entries[1]), GFP_KERNEL); + if (!sgl) { + kfree(acl); + return -ENOMEM; + } + + acl->n_acl_entries = 2; + acl->acl_entries[0].vmid = (u16)self; + acl->acl_entries[0].perms = HH_RM_ACL_R | HH_RM_ACL_W; + acl->acl_entries[1].vmid = (u16)peer; + acl->acl_entries[1].perms = HH_RM_ACL_R | HH_RM_ACL_W; + + sgl->n_sgl_entries = 1; + sgl->sgl_entries[0].ipa_base = priv->buffer.start; + sgl->sgl_entries[0].size = resource_size(&priv->buffer); + ret = hh_rm_mem_qcom_lookup_sgl(HH_RM_MEM_TYPE_NORMAL, + priv->haven_label, + acl, sgl, NULL, + &priv->shm_memparcel); + kfree(acl); + kfree(sgl); + + return ret; +} + +static int channel_hh_rm_cb(struct notifier_block *nb, unsigned long cmd, + void *data) +{ + struct hh_rm_notif_vm_status_payload *vm_status_payload = data; + struct neuron_mq_data_priv *priv; + hh_vmid_t peer_vmid; + hh_vmid_t self_vmid; + + priv = container_of(nb, struct neuron_mq_data_priv, rm_nb); + if (cmd != HH_RM_NOTIF_VM_STATUS) + return NOTIFY_DONE; + + if (vm_status_payload->vm_status != HH_RM_VM_STATUS_READY) + return NOTIFY_DONE; + if (hh_rm_get_vmid(priv->peer_name, &peer_vmid)) + return NOTIFY_DONE; + if (hh_rm_get_vmid(HH_PRIMARY_VM, &self_vmid)) + return NOTIFY_DONE; + if (peer_vmid != vm_status_payload->vmid) + return NOTIFY_DONE; + + if (channel_hh_share_mem(priv, self_vmid, peer_vmid)) + pr_err("%s: failed to share memory\n", __func__); + + return NOTIFY_DONE; +} + static int channel_hh_map_memory(struct neuron_mq_data_priv *priv, struct device *dev) { @@ -329,6 +404,10 @@ static int channel_hh_map_memory(struct neuron_mq_data_priv *priv, &priv->peer_name); if (ret) priv->peer_name = HH_SELF_VM; + + priv->rm_nb.notifier_call = channel_hh_rm_cb; + priv->rm_nb.priority = INT_MAX; + hh_rm_register_notifier(&priv->rm_nb); } return 0; diff --git a/net/neuron/channel/ch_mq_shmem_common.h b/net/neuron/channel/ch_mq_shmem_common.h index 10f3381ce590..7b9b90f2f590 100644 --- a/net/neuron/channel/ch_mq_shmem_common.h +++ b/net/neuron/channel/ch_mq_shmem_common.h @@ -84,6 +84,10 @@ struct neuron_mq_data_priv { void *tx_dbl; /* haven rx doorbell descriptor */ void *rx_dbl; + /* memparcel handle after assigning label to shared memory */ + u32 shm_memparcel; + /* haven rm status notifier block */ + struct notifier_block rm_nb; /* pointer to the device structure */ struct neuron_channel *dev; /* shared memory mapped address */ From d5e3b87efb812dcdce8b42fcb30c9e25f745d9f0 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Thu, 11 Jun 2020 17:49:10 -0700 Subject: [PATCH 5/7] neuron: ch_haven: Add support for svm device tree format The secondary vm device tree will have a different format than the primary vm. Try parsing the node as a secondary vm node if the shared-buffer region does not exist. Change-Id: Id794a1b21507329f4e16f1335a17a2262ecabd5a Signed-off-by: Chris Lew --- net/neuron/channel/ch_haven_recv.c | 38 ++++++++++++++++++++++++++++-- net/neuron/channel/ch_haven_send.c | 38 ++++++++++++++++++++++++++++-- 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/net/neuron/channel/ch_haven_recv.c b/net/neuron/channel/ch_haven_recv.c index b14525587664..1422491b9bde 100644 --- a/net/neuron/channel/ch_haven_recv.c +++ b/net/neuron/channel/ch_haven_recv.c @@ -372,6 +372,37 @@ static int channel_hh_rm_cb(struct notifier_block *nb, unsigned long cmd, return NOTIFY_DONE; } +static struct device_node * +channel_hh_svm_of_parse(struct neuron_mq_data_priv *priv, struct device *dev) +{ + const char *compat = "qcom,neuron-channel-haven-shmem-gen"; + struct device_node *np = NULL; + struct device_node *shm_np; + u32 label; + int ret; + + while ((np = of_find_compatible_node(np, NULL, compat))) { + ret = of_property_read_u32(np, "qcom,label", &label); + if (ret) { + of_node_put(np); + continue; + } + if (label == priv->haven_label) + break; + + of_node_put(np); + } + if (!np) + return NULL; + + shm_np = of_parse_phandle(np, "memory-region", 0); + if (!shm_np) + dev_err(dev, "cant parse svm shared mem node!\n"); + + of_node_put(np); + return shm_np; +} + static int channel_hh_map_memory(struct neuron_mq_data_priv *priv, struct device *dev) { @@ -382,8 +413,11 @@ static int channel_hh_map_memory(struct neuron_mq_data_priv *priv, np = of_parse_phandle(dev->of_node, "shared-buffer", 0); if (!np) { - dev_err(dev, "shared-buffer node missing!\n"); - return -EINVAL; + np = channel_hh_svm_of_parse(priv, dev); + if (!np) { + dev_err(dev, "cant parse shared mem node!\n"); + return -EINVAL; + } } ret = of_address_to_resource(np, 0, &priv->buffer); diff --git a/net/neuron/channel/ch_haven_send.c b/net/neuron/channel/ch_haven_send.c index da6238371c63..7947be558dce 100644 --- a/net/neuron/channel/ch_haven_send.c +++ b/net/neuron/channel/ch_haven_send.c @@ -355,6 +355,37 @@ static int channel_hh_rm_cb(struct notifier_block *nb, unsigned long cmd, return NOTIFY_DONE; } +static struct device_node * +channel_hh_svm_of_parse(struct neuron_mq_data_priv *priv, struct device *dev) +{ + const char *compat = "qcom,neuron-channel-haven-shmem-gen"; + struct device_node *np = NULL; + struct device_node *shm_np; + u32 label; + int ret; + + while ((np = of_find_compatible_node(np, NULL, compat))) { + ret = of_property_read_u32(np, "qcom,label", &label); + if (ret) { + of_node_put(np); + continue; + } + if (label == priv->haven_label) + break; + + of_node_put(np); + } + if (!np) + return NULL; + + shm_np = of_parse_phandle(np, "memory-region", 0); + if (!shm_np) + dev_err(dev, "cant parse svm shared mem node!\n"); + + of_node_put(np); + return shm_np; +} + static int channel_hh_map_memory(struct neuron_mq_data_priv *priv, struct device *dev) { @@ -365,8 +396,11 @@ static int channel_hh_map_memory(struct neuron_mq_data_priv *priv, np = of_parse_phandle(dev->of_node, "shared-buffer", 0); if (!np) { - dev_err(dev, "shared-buffer node missing!\n"); - return -EINVAL; + np = channel_hh_svm_of_parse(priv, dev); + if (!np) { + dev_err(dev, "cant parse shared mem node!\n"); + return -EINVAL; + } } ret = of_address_to_resource(np, 0, &priv->buffer); From 394a2675b82123923ea24f0f8e9a796f4d11bce6 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Thu, 11 Jun 2020 19:00:47 -0700 Subject: [PATCH 6/7] net: qrtr: haven: Store haven label Store the haven label so it can be used for other haven resources such as attaching the label to memparcels that the qrtr haven driver creates. Change-Id: I78c8bea71666c35db393191131389867d39f7566 Signed-off-by: Chris Lew --- net/qrtr/haven.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/net/qrtr/haven.c b/net/qrtr/haven.c index fc39f96c6b01..30bdaadaa3d6 100644 --- a/net/qrtr/haven.c +++ b/net/qrtr/haven.c @@ -40,6 +40,7 @@ struct haven_pipe { * @base: Base of the shared fifo. * @size: fifo size. * @master: primary vm indicator. + * @label: label for haven resources * @tx_dbl: doorbell for tx notifications. * @rx_dbl: doorbell for rx notifications. * @tx_pipe: TX haven specific info. @@ -54,6 +55,7 @@ struct qrtr_haven_dev { size_t size; bool master; + u32 label; void *tx_dbl; void *rx_dbl; @@ -328,18 +330,19 @@ static int qrtr_haven_probe(struct platform_device *pdev) if (!qdev->buf) return -ENOMEM; + ret = of_property_read_u32(node, "haven-label", &qdev->label); + if (ret) { + dev_err(qdev->dev, "failed to read label info %d\n", ret); + return ret; + } qdev->master = of_property_read_bool(node, "qcom,master"); ret = qrtr_haven_map_memory(qdev); if (ret) return ret; - ret = of_property_read_u32(node, "haven-label", &dbl_label); - if (ret) { - dev_err(qdev->dev, "failed to read label info %d\n", ret); - return ret; - } qrtr_haven_fifo_init(qdev); + dbl_label = qdev->label; qdev->tx_dbl = hh_dbl_tx_register(dbl_label); if (IS_ERR_OR_NULL(qdev->tx_dbl)) { ret = PTR_ERR(qdev->tx_dbl); From 026bc864e74cffdea7061d66d53d74f682eaba95 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Fri, 12 Jun 2020 14:52:29 -0700 Subject: [PATCH 7/7] net: qrtr: haven: Read peer name from device tree Add support for the primary vm to read the vm peer name from device tree. This information is needed to share memory to the peer vm. Change-Id: Ied71d254975e08dcf6c1c51f49687aceced141a9 Signed-off-by: Chris Lew --- net/qrtr/haven.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/net/qrtr/haven.c b/net/qrtr/haven.c index 30bdaadaa3d6..15ad2fd0fd48 100644 --- a/net/qrtr/haven.c +++ b/net/qrtr/haven.c @@ -40,6 +40,7 @@ struct haven_pipe { * @base: Base of the shared fifo. * @size: fifo size. * @master: primary vm indicator. + * @peer_name: name of vm peer. * @label: label for haven resources * @tx_dbl: doorbell for tx notifications. * @rx_dbl: doorbell for rx notifications. @@ -54,6 +55,7 @@ struct qrtr_haven_dev { void *base; size_t size; bool master; + u32 peer_name; u32 label; void *tx_dbl; @@ -336,12 +338,19 @@ static int qrtr_haven_probe(struct platform_device *pdev) return ret; } qdev->master = of_property_read_bool(node, "qcom,master"); + ret = qrtr_haven_map_memory(qdev); if (ret) return ret; qrtr_haven_fifo_init(qdev); + if (qdev->master) { + ret = of_property_read_u32(node, "peer-name", &qdev->peer_name); + if (ret) + qdev->peer_name = HH_SELF_VM; + } + dbl_label = qdev->label; qdev->tx_dbl = hh_dbl_tx_register(dbl_label); if (IS_ERR_OR_NULL(qdev->tx_dbl)) {