Skip to content

Commit e90d911

Browse files
Vamsi Krishna Gattupalligregkh
authored andcommitted
misc: fastrpc: Add support to secure memory map
This patch adds support to secure memory allocations for DSP. It repurposes the reserved field in struct fastrpc_invoke_args to add attributes to invoke request, for example to setup a secure memory map for dsp. Secure memory is assigned to DSP Virtual Machine IDs using Qualcomm SCM calls. Signed-off-by: Vamsi Krishna Gattupalli <[email protected]> Signed-off-by: Srinivas Kandagatla <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 87ccc14 commit e90d911

File tree

3 files changed

+61
-10
lines changed

3 files changed

+61
-10
lines changed

drivers/misc/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ config QCOM_FASTRPC
259259
depends on ARCH_QCOM || COMPILE_TEST
260260
depends on RPMSG
261261
select DMA_SHARED_BUFFER
262+
select QCOM_SCM
262263
help
263264
Provides a communication mechanism that allows for clients to
264265
make remote method invocations across processor boundary to

drivers/misc/fastrpc.c

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/rpmsg.h>
1818
#include <linux/scatterlist.h>
1919
#include <linux/slab.h>
20+
#include <linux/qcom_scm.h>
2021
#include <uapi/misc/fastrpc.h>
2122

2223
#define ADSP_DOMAIN_ID (0)
@@ -25,6 +26,7 @@
2526
#define CDSP_DOMAIN_ID (3)
2627
#define FASTRPC_DEV_MAX 4 /* adsp, mdsp, slpi, cdsp*/
2728
#define FASTRPC_MAX_SESSIONS 13 /*12 compute, 1 cpz*/
29+
#define FASTRPC_MAX_VMIDS 16
2830
#define FASTRPC_ALIGN 128
2931
#define FASTRPC_MAX_FDLIST 16
3032
#define FASTRPC_MAX_CRCLIST 64
@@ -195,6 +197,7 @@ struct fastrpc_map {
195197
void *va;
196198
u64 len;
197199
u64 raddr;
200+
u32 attr;
198201
struct kref refcount;
199202
};
200203

@@ -232,6 +235,9 @@ struct fastrpc_session_ctx {
232235
struct fastrpc_channel_ctx {
233236
int domain_id;
234237
int sesscount;
238+
int vmcount;
239+
u32 perms;
240+
struct qcom_scm_vmperm vmperms[FASTRPC_MAX_VMIDS];
235241
struct rpmsg_device *rpdev;
236242
struct fastrpc_session_ctx session[FASTRPC_MAX_SESSIONS];
237243
spinlock_t lock;
@@ -279,6 +285,20 @@ static void fastrpc_free_map(struct kref *ref)
279285
map = container_of(ref, struct fastrpc_map, refcount);
280286

281287
if (map->table) {
288+
if (map->attr & FASTRPC_ATTR_SECUREMAP) {
289+
struct qcom_scm_vmperm perm;
290+
int err = 0;
291+
292+
perm.vmid = QCOM_SCM_VMID_HLOS;
293+
perm.perm = QCOM_SCM_PERM_RWX;
294+
err = qcom_scm_assign_mem(map->phys, map->size,
295+
&(map->fl->cctx->vmperms[0].vmid), &perm, 1);
296+
if (err) {
297+
dev_err(map->fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d",
298+
map->phys, map->size, err);
299+
return;
300+
}
301+
}
282302
dma_buf_unmap_attachment(map->attach, map->table,
283303
DMA_BIDIRECTIONAL);
284304
dma_buf_detach(map->buf, map->attach);
@@ -655,7 +675,7 @@ static const struct dma_buf_ops fastrpc_dma_buf_ops = {
655675
};
656676

657677
static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
658-
u64 len, struct fastrpc_map **ppmap)
678+
u64 len, u32 attr, struct fastrpc_map **ppmap)
659679
{
660680
struct fastrpc_session_ctx *sess = fl->sctx;
661681
struct fastrpc_map *map = NULL;
@@ -697,6 +717,22 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
697717
map->len = len;
698718
kref_init(&map->refcount);
699719

720+
if (attr & FASTRPC_ATTR_SECUREMAP) {
721+
/*
722+
* If subsystem VMIDs are defined in DTSI, then do
723+
* hyp_assign from HLOS to those VM(s)
724+
*/
725+
unsigned int perms = BIT(QCOM_SCM_VMID_HLOS);
726+
727+
map->attr = attr;
728+
err = qcom_scm_assign_mem(map->phys, (u64)map->size, &perms,
729+
fl->cctx->vmperms, fl->cctx->vmcount);
730+
if (err) {
731+
dev_err(sess->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d",
732+
map->phys, map->size, err);
733+
goto map_err;
734+
}
735+
}
700736
spin_lock(&fl->lock);
701737
list_add_tail(&map->node, &fl->maps);
702738
spin_unlock(&fl->lock);
@@ -781,16 +817,13 @@ static int fastrpc_create_maps(struct fastrpc_invoke_ctx *ctx)
781817
int i, err;
782818

783819
for (i = 0; i < ctx->nscalars; ++i) {
784-
/* Make sure reserved field is set to 0 */
785-
if (ctx->args[i].reserved)
786-
return -EINVAL;
787820

788821
if (ctx->args[i].fd == 0 || ctx->args[i].fd == -1 ||
789822
ctx->args[i].length == 0)
790823
continue;
791824

792825
err = fastrpc_map_create(ctx->fl, ctx->args[i].fd,
793-
ctx->args[i].length, &ctx->maps[i]);
826+
ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]);
794827
if (err) {
795828
dev_err(dev, "Error Creating map %d\n", err);
796829
return -EINVAL;
@@ -1124,7 +1157,7 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl,
11241157
fl->pd = USER_PD;
11251158

11261159
if (init.filelen && init.filefd) {
1127-
err = fastrpc_map_create(fl, init.filefd, init.filelen, &map);
1160+
err = fastrpc_map_create(fl, init.filefd, init.filelen, 0, &map);
11281161
if (err)
11291162
goto err;
11301163
}
@@ -1233,7 +1266,6 @@ static int fastrpc_release_current_dsp_process(struct fastrpc_user *fl)
12331266
args[0].ptr = (u64)(uintptr_t) &tgid;
12341267
args[0].length = sizeof(tgid);
12351268
args[0].fd = -1;
1236-
args[0].reserved = 0;
12371269
sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_RELEASE, 1, 0);
12381270

12391271
return fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE,
@@ -1381,7 +1413,6 @@ static int fastrpc_init_attach(struct fastrpc_user *fl, int pd)
13811413
args[0].ptr = (u64)(uintptr_t) &tgid;
13821414
args[0].length = sizeof(tgid);
13831415
args[0].fd = -1;
1384-
args[0].reserved = 0;
13851416
sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_ATTACH, 1, 0);
13861417
fl->pd = pd;
13871418

@@ -1954,9 +1985,10 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
19541985
{
19551986
struct device *rdev = &rpdev->dev;
19561987
struct fastrpc_channel_ctx *data;
1957-
int i, err, domain_id = -1;
1988+
int i, err, domain_id = -1, vmcount;
19581989
const char *domain;
19591990
bool secure_dsp;
1991+
unsigned int vmids[FASTRPC_MAX_VMIDS];
19601992

19611993
err = of_property_read_string(rdev->of_node, "label", &domain);
19621994
if (err) {
@@ -1976,10 +2008,25 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
19762008
return -EINVAL;
19772009
}
19782010

2011+
vmcount = of_property_read_variable_u32_array(rdev->of_node,
2012+
"qcom,vmids", &vmids[0], 0, FASTRPC_MAX_VMIDS);
2013+
if (vmcount < 0)
2014+
vmcount = 0;
2015+
else if (!qcom_scm_is_available())
2016+
return -EPROBE_DEFER;
2017+
19792018
data = kzalloc(sizeof(*data), GFP_KERNEL);
19802019
if (!data)
19812020
return -ENOMEM;
19822021

2022+
if (vmcount) {
2023+
data->vmcount = vmcount;
2024+
data->perms = BIT(QCOM_SCM_VMID_HLOS);
2025+
for (i = 0; i < data->vmcount; i++) {
2026+
data->vmperms[i].vmid = vmids[i];
2027+
data->vmperms[i].perm = QCOM_SCM_PERM_RWX;
2028+
}
2029+
}
19832030

19842031
secure_dsp = !(of_property_read_bool(rdev->of_node, "qcom,non-secure-domain"));
19852032
data->secure = secure_dsp;

include/uapi/misc/fastrpc.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,14 @@ enum fastrpc_proc_attr {
6363
FASTRPC_MODE_PRIVILEGED = (1 << 6),
6464
};
6565

66+
/* Fastrpc attribute for memory protection of buffers */
67+
#define FASTRPC_ATTR_SECUREMAP (1)
68+
6669
struct fastrpc_invoke_args {
6770
__u64 ptr;
6871
__u64 length;
6972
__s32 fd;
70-
__u32 reserved;
73+
__u32 attr;
7174
};
7275

7376
struct fastrpc_invoke {

0 commit comments

Comments
 (0)