aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/remoteproc.txt136
-rw-r--r--drivers/remoteproc/Kconfig3
-rw-r--r--drivers/remoteproc/Makefile2
-rw-r--r--drivers/remoteproc/omap_remoteproc.c11
-rw-r--r--drivers/remoteproc/remoteproc_core.c532
-rw-r--r--drivers/remoteproc/remoteproc_internal.h6
-rw-r--r--drivers/remoteproc/remoteproc_virtio.c (renamed from drivers/remoteproc/remoteproc_rpmsg.c)162
-rw-r--r--drivers/rpmsg/virtio_rpmsg_bus.c46
-rw-r--r--include/linux/remoteproc.h339
9 files changed, 793 insertions, 444 deletions
diff --git a/Documentation/remoteproc.txt b/Documentation/remoteproc.txt
index 23ff7349ffe7..70a048cd3fa3 100644
--- a/Documentation/remoteproc.txt
+++ b/Documentation/remoteproc.txt
@@ -20,6 +20,11 @@ platform-specific remoteproc drivers only need to provide a few low-level
20handlers, and then all rpmsg drivers will then just work 20handlers, and then all rpmsg drivers will then just work
21(for more information about the virtio-based rpmsg bus and its drivers, 21(for more information about the virtio-based rpmsg bus and its drivers,
22please read Documentation/rpmsg.txt). 22please read Documentation/rpmsg.txt).
23Registration of other types of virtio devices is now also possible. Firmwares
24just need to publish what kind of virtio devices do they support, and then
25remoteproc will add those devices. This makes it possible to reuse the
26existing virtio drivers with remote processor backends at a minimal development
27cost.
23 28
242. User API 292. User API
25 30
@@ -136,8 +141,6 @@ int dummy_rproc_example(struct rproc *my_rproc)
136 If found, those virtio devices will be created and added, so as a result 141 If found, those virtio devices will be created and added, so as a result
137 of registering this remote processor, additional virtio drivers might get 142 of registering this remote processor, additional virtio drivers might get
138 probed. 143 probed.
139 Currently, though, we only support a single RPMSG virtio vdev per remote
140 processor.
141 144
142 int rproc_unregister(struct rproc *rproc) 145 int rproc_unregister(struct rproc *rproc)
143 - Unregister a remote processor, and decrement its refcount. 146 - Unregister a remote processor, and decrement its refcount.
@@ -174,7 +177,7 @@ struct rproc_ops {
174}; 177};
175 178
176Every remoteproc implementation should at least provide the ->start and ->stop 179Every remoteproc implementation should at least provide the ->start and ->stop
177handlers. If rpmsg functionality is also desired, then the ->kick handler 180handlers. If rpmsg/virtio functionality is also desired, then the ->kick handler
178should be provided as well. 181should be provided as well.
179 182
180The ->start() handler takes an rproc handle and should then power on the 183The ->start() handler takes an rproc handle and should then power on the
@@ -221,43 +224,52 @@ resource entries that publish the existence of supported features
221or configurations by the remote processor, such as trace buffers and 224or configurations by the remote processor, such as trace buffers and
222supported virtio devices (and their configurations). 225supported virtio devices (and their configurations).
223 226
224Currently the resource table is just an array of: 227The resource table begins with this header:
225 228
226/** 229/**
227 * struct fw_resource - describes an entry from the resource section 230 * struct resource_table - firmware resource table header
231 * @ver: version number
232 * @num: number of resource entries
233 * @reserved: reserved (must be zero)
234 * @offset: array of offsets pointing at the various resource entries
235 *
236 * The header of the resource table, as expressed by this structure,
237 * contains a version number (should we need to change this format in the
238 * future), the number of available resource entries, and their offsets
239 * in the table.
240 */
241struct resource_table {
242 u32 ver;
243 u32 num;
244 u32 reserved[2];
245 u32 offset[0];
246} __packed;
247
248Immediately following this header are the resource entries themselves,
249each of which begins with the following resource entry header:
250
251/**
252 * struct fw_rsc_hdr - firmware resource entry header
228 * @type: resource type 253 * @type: resource type
229 * @id: index number of the resource 254 * @data: resource data
230 * @da: device address of the resource 255 *
231 * @pa: physical address of the resource 256 * Every resource entry begins with a 'struct fw_rsc_hdr' header providing
232 * @len: size, in bytes, of the resource 257 * its @type. The content of the entry itself will immediately follow
233 * @flags: properties of the resource, e.g. iommu protection required 258 * this header, and it should be parsed according to the resource type.
234 * @reserved: must be 0 atm
235 * @name: name of resource
236 */ 259 */
237struct fw_resource { 260struct fw_rsc_hdr {
238 u32 type; 261 u32 type;
239 u32 id; 262 u8 data[0];
240 u64 da;
241 u64 pa;
242 u32 len;
243 u32 flags;
244 u8 reserved[16];
245 u8 name[48];
246} __packed; 263} __packed;
247 264
248Some resources entries are mere announcements, where the host is informed 265Some resources entries are mere announcements, where the host is informed
249of specific remoteproc configuration. Other entries require the host to 266of specific remoteproc configuration. Other entries require the host to
250do something (e.g. reserve a requested resource) and possibly also reply 267do something (e.g. allocate a system resource). Sometimes a negotiation
251by overwriting a member inside 'struct fw_resource' with info about the 268is expected, where the firmware requests a resource, and once allocated,
252allocated resource. 269the host should provide back its details (e.g. address of an allocated
253 270memory region).
254Different resource entries use different members of this struct,
255with different meanings. This is pretty limiting and error-prone,
256so the plan is to move to variable-length TLV-based resource entries,
257where each resource will begin with a type and length fields, followed by
258its own specific structure.
259 271
260Here are the resource types that are currently being used: 272Here are the various resource types that are currently supported:
261 273
262/** 274/**
263 * enum fw_resource_type - types of resource entries 275 * enum fw_resource_type - types of resource entries
@@ -266,59 +278,45 @@ Here are the resource types that are currently being used:
266 * memory region. 278 * memory region.
267 * @RSC_DEVMEM: request to iommu_map a memory-based peripheral. 279 * @RSC_DEVMEM: request to iommu_map a memory-based peripheral.
268 * @RSC_TRACE: announces the availability of a trace buffer into which 280 * @RSC_TRACE: announces the availability of a trace buffer into which
269 * the remote processor will be writing logs. In this case, 281 * the remote processor will be writing logs.
270 * 'da' indicates the device address where logs are written to, 282 * @RSC_VDEV: declare support for a virtio device, and serve as its
271 * and 'len' is the size of the trace buffer. 283 * virtio header.
272 * @RSC_VRING: request for allocation of a virtio vring (address should 284 * @RSC_LAST: just keep this one at the end
273 * be indicated in 'da', and 'len' should contain the number 285 *
274 * of buffers supported by the vring). 286 * Please note that these values are used as indices to the rproc_handle_rsc
275 * @RSC_VIRTIO_DEV: announces support for a virtio device, and serves as 287 * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to
276 * the virtio header. 'da' contains the virtio device 288 * check the validity of an index before the lookup table is accessed, so
277 * features, 'pa' holds the virtio guest features (host 289 * please update it as needed.
278 * will write them here after they're negotiated), 'len'
279 * holds the virtio status, and 'flags' holds the virtio
280 * device id (currently only VIRTIO_ID_RPMSG is supported).
281 */ 290 */
282enum fw_resource_type { 291enum fw_resource_type {
283 RSC_CARVEOUT = 0, 292 RSC_CARVEOUT = 0,
284 RSC_DEVMEM = 1, 293 RSC_DEVMEM = 1,
285 RSC_TRACE = 2, 294 RSC_TRACE = 2,
286 RSC_VRING = 3, 295 RSC_VDEV = 3,
287 RSC_VIRTIO_DEV = 4, 296 RSC_LAST = 4,
288 RSC_VIRTIO_CFG = 5,
289}; 297};
290 298
291Most of the resource entries share the basic idea of address/length 299For more details regarding a specific resource type, please see its
292negotiation with the host: the firmware usually asks for memory 300dedicated structure in include/linux/remoteproc.h.
293of size 'len' bytes, and the host needs to allocate it and provide
294the device/physical address (when relevant) in 'da'/'pa' respectively.
295
296If the firmware is compiled with hard coded device addresses, and
297can't handle dynamically allocated 'da' values, then the 'da' field
298will contain the expected device addresses (today we actually only support
299this scheme, as there aren't yet any use cases for dynamically allocated
300device addresses).
301 301
302We also expect that platform-specific resource entries will show up 302We also expect that platform-specific resource entries will show up
303at some point. When that happens, we could easily add a new RSC_PLAFORM 303at some point. When that happens, we could easily add a new RSC_PLATFORM
304type, and hand those resources to the platform-specific rproc driver to handle. 304type, and hand those resources to the platform-specific rproc driver to handle.
305 305
3067. Virtio and remoteproc 3067. Virtio and remoteproc
307 307
308The firmware should provide remoteproc information about virtio devices 308The firmware should provide remoteproc information about virtio devices
309that it supports, and their configurations: a RSC_VIRTIO_DEV resource entry 309that it supports, and their configurations: a RSC_VDEV resource entry
310should specify the virtio device id, and subsequent RSC_VRING resource entries 310should specify the virtio device id (as in virtio_ids.h), virtio features,
311should indicate the vring size (i.e. how many buffers do they support) and 311virtio config space, vrings information, etc.
312where should they be mapped (i.e. which device address). Note: the alignment 312
313between the consumer and producer parts of the vring is assumed to be 4096. 313When a new remote processor is registered, the remoteproc framework
314 314will look for its resource table and will register the virtio devices
315At this point we only support a single virtio rpmsg device per remote 315it supports. A firmware may support any number of virtio devices, and
316processor, but the plan is to remove this limitation. In addition, once we 316of any type (a single remote processor can also easily support several
317move to TLV-based resource table, the plan is to have a single RSC_VIRTIO 317rpmsg virtio devices this way, if desired).
318entry per supported virtio device, which will include the virtio header, 318
319the vrings information and the virtio config space. 319Of course, RSC_VDEV resource entries are only good enough for static
320
321Of course, RSC_VIRTIO resource entries are only good enough for static
322allocation of virtio devices. Dynamic allocations will also be made possible 320allocation of virtio devices. Dynamic allocations will also be made possible
323using the rpmsg bus (similar to how we already do dynamic allocations of 321using the rpmsg bus (similar to how we already do dynamic allocations of
324rpmsg channels; read more about it in rpmsg.txt). 322rpmsg channels; read more about it in rpmsg.txt).
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 25fc4ccbc2ea..24d880e78ec6 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -8,11 +8,10 @@ config REMOTEPROC
8config OMAP_REMOTEPROC 8config OMAP_REMOTEPROC
9 tristate "OMAP remoteproc support" 9 tristate "OMAP remoteproc support"
10 depends on ARCH_OMAP4 10 depends on ARCH_OMAP4
11 select OMAP_IOMMU 11 depends on OMAP_IOMMU
12 select REMOTEPROC 12 select REMOTEPROC
13 select OMAP_MBOX_FWK 13 select OMAP_MBOX_FWK
14 select RPMSG 14 select RPMSG
15 default m
16 help 15 help
17 Say y here to support OMAP's remote processors (dual M3 16 Say y here to support OMAP's remote processors (dual M3
18 and DSP on OMAP4) via the remote processor framework. 17 and DSP on OMAP4) via the remote processor framework.
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index df0897f69e16..5445d9b23294 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -5,5 +5,5 @@
5obj-$(CONFIG_REMOTEPROC) += remoteproc.o 5obj-$(CONFIG_REMOTEPROC) += remoteproc.o
6remoteproc-y := remoteproc_core.o 6remoteproc-y := remoteproc_core.o
7remoteproc-y += remoteproc_debugfs.o 7remoteproc-y += remoteproc_debugfs.o
8remoteproc-y += remoteproc_rpmsg.o 8remoteproc-y += remoteproc_virtio.o
9obj-$(CONFIG_OMAP_REMOTEPROC) += omap_remoteproc.o 9obj-$(CONFIG_OMAP_REMOTEPROC) += omap_remoteproc.o
diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c
index aa3ce52dc65e..69425c4e86f3 100644
--- a/drivers/remoteproc/omap_remoteproc.c
+++ b/drivers/remoteproc/omap_remoteproc.c
@@ -80,16 +80,7 @@ static int omap_rproc_mbox_callback(struct notifier_block *this,
80 dev_info(dev, "received echo reply from %s\n", name); 80 dev_info(dev, "received echo reply from %s\n", name);
81 break; 81 break;
82 default: 82 default:
83 /* ignore vq indices which are too large to be valid */ 83 /* msg contains the index of the triggered vring */
84 if (msg >= 2) {
85 dev_warn(dev, "invalid mbox msg: 0x%x\n", msg);
86 break;
87 }
88
89 /*
90 * At this point, 'msg' contains the index of the vring
91 * which was just triggered.
92 */
93 if (rproc_vq_interrupt(oproc->rproc, msg) == IRQ_NONE) 84 if (rproc_vq_interrupt(oproc->rproc, msg) == IRQ_NONE)
94 dev_dbg(dev, "no message was found in vqid %d\n", msg); 85 dev_dbg(dev, "no message was found in vqid %d\n", msg);
95 } 86 }
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 729911b67a9a..ee15c68fb519 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -52,8 +52,8 @@ static void klist_rproc_put(struct klist_node *n);
52 * We need this in order to support name-based lookups (needed by the 52 * We need this in order to support name-based lookups (needed by the
53 * rproc_get_by_name()). 53 * rproc_get_by_name()).
54 * 54 *
55 * That said, we don't use rproc_get_by_name() anymore within the rpmsg 55 * That said, we don't use rproc_get_by_name() at this point.
56 * framework. The use cases that do require its existence should be 56 * The use cases that do require its existence should be
57 * scrutinized, and hopefully migrated to rproc_boot() using device-based 57 * scrutinized, and hopefully migrated to rproc_boot() using device-based
58 * binding. 58 * binding.
59 * 59 *
@@ -63,9 +63,8 @@ static void klist_rproc_put(struct klist_node *n);
63static DEFINE_KLIST(rprocs, klist_rproc_get, klist_rproc_put); 63static DEFINE_KLIST(rprocs, klist_rproc_get, klist_rproc_put);
64 64
65typedef int (*rproc_handle_resources_t)(struct rproc *rproc, 65typedef int (*rproc_handle_resources_t)(struct rproc *rproc,
66 struct fw_resource *rsc, int len); 66 struct resource_table *table, int len);
67typedef int (*rproc_handle_resource_t)(struct rproc *rproc, 67typedef int (*rproc_handle_resource_t)(struct rproc *rproc, void *, int avail);
68 struct fw_resource *rsc);
69 68
70/* 69/*
71 * This is the IOMMU fault handler we register with the IOMMU API 70 * This is the IOMMU fault handler we register with the IOMMU API
@@ -280,145 +279,182 @@ rproc_load_segments(struct rproc *rproc, const u8 *elf_data, size_t len)
280 return ret; 279 return ret;
281} 280}
282 281
283/** 282static int
284 * rproc_handle_virtio_hdr() - handle a virtio header resource 283__rproc_handle_vring(struct rproc_vdev *rvdev, struct fw_rsc_vdev *rsc, int i)
285 * @rproc: the remote processor
286 * @rsc: the resource descriptor
287 *
288 * The existence of this virtio hdr resource entry means that the firmware
289 * of this @rproc supports this virtio device.
290 *
291 * Currently we support only a single virtio device of type VIRTIO_ID_RPMSG,
292 * but the plan is to remove this limitation and support any number
293 * of virtio devices (and of any type). We'll also add support for dynamically
294 * adding (and removing) virtio devices over the rpmsg bus, but small
295 * firmwares that doesn't want to get involved with rpmsg will be able
296 * to simple use the resource table for this.
297 *
298 * At this point this virtio header entry is rather simple: it just
299 * announces the virtio device id and the supported virtio device features.
300 * The plan though is to extend this to include the vring information and
301 * the virtio config space, too (but first, some resource table overhaul
302 * is needed: move from fixed-sized to variable-length TLV entries).
303 *
304 * For now, the 'flags' member of the resource entry contains the virtio
305 * device id, the 'da' member contains the device features, and 'pa' is
306 * where we need to store the guest features once negotiation completes.
307 * As usual, the 'id' member of this resource contains the index of this
308 * resource type (i.e. is this the first virtio hdr entry, the 2nd, ...).
309 *
310 * Returns 0 on success, or an appropriate error code otherwise
311 */
312static int rproc_handle_virtio_hdr(struct rproc *rproc, struct fw_resource *rsc)
313{ 284{
314 struct rproc_vdev *rvdev; 285 struct rproc *rproc = rvdev->rproc;
286 struct device *dev = rproc->dev;
287 struct fw_rsc_vdev_vring *vring = &rsc->vring[i];
288 dma_addr_t dma;
289 void *va;
290 int ret, size, notifyid;
291
292 dev_dbg(dev, "vdev rsc: vring%d: da %x, qsz %d, align %d\n",
293 i, vring->da, vring->num, vring->align);
315 294
316 /* we only support VIRTIO_ID_RPMSG devices for now */ 295 /* make sure reserved bytes are zeroes */
317 if (rsc->flags != VIRTIO_ID_RPMSG) { 296 if (vring->reserved) {
318 dev_warn(rproc->dev, "unsupported vdev: %d\n", rsc->flags); 297 dev_err(dev, "vring rsc has non zero reserved bytes\n");
319 return -EINVAL; 298 return -EINVAL;
320 } 299 }
321 300
322 /* we only support a single vdev per rproc for now */ 301 /* verify queue size and vring alignment are sane */
323 if (rsc->id || rproc->rvdev) { 302 if (!vring->num || !vring->align) {
324 dev_warn(rproc->dev, "redundant vdev entry: %s\n", rsc->name); 303 dev_err(dev, "invalid qsz (%d) or alignment (%d)\n",
304 vring->num, vring->align);
325 return -EINVAL; 305 return -EINVAL;
326 } 306 }
327 307
328 rvdev = kzalloc(sizeof(struct rproc_vdev), GFP_KERNEL); 308 /* actual size of vring (in bytes) */
329 if (!rvdev) 309 size = PAGE_ALIGN(vring_size(vring->num, vring->align));
310
311 if (!idr_pre_get(&rproc->notifyids, GFP_KERNEL)) {
312 dev_err(dev, "idr_pre_get failed\n");
330 return -ENOMEM; 313 return -ENOMEM;
314 }
331 315
332 /* remember the device features */ 316 /*
333 rvdev->dfeatures = rsc->da; 317 * Allocate non-cacheable memory for the vring. In the future
318 * this call will also configure the IOMMU for us
319 */
320 va = dma_alloc_coherent(dev, size, &dma, GFP_KERNEL);
321 if (!va) {
322 dev_err(dev, "dma_alloc_coherent failed\n");
323 return -EINVAL;
324 }
334 325
335 rproc->rvdev = rvdev; 326 /* assign an rproc-wide unique index for this vring */
336 rvdev->rproc = rproc; 327 /* TODO: assign a notifyid for rvdev updates as well */
328 ret = idr_get_new(&rproc->notifyids, &rvdev->vring[i], &notifyid);
329 if (ret) {
330 dev_err(dev, "idr_get_new failed: %d\n", ret);
331 dma_free_coherent(dev, size, va, dma);
332 return ret;
333 }
334
335 /* let the rproc know the da and notifyid of this vring */
336 /* TODO: expose this to remote processor */
337 vring->da = dma;
338 vring->notifyid = notifyid;
339
340 dev_dbg(dev, "vring%d: va %p dma %x size %x idr %d\n", i, va,
341 dma, size, notifyid);
342
343 rvdev->vring[i].len = vring->num;
344 rvdev->vring[i].align = vring->align;
345 rvdev->vring[i].va = va;
346 rvdev->vring[i].dma = dma;
347 rvdev->vring[i].notifyid = notifyid;
348 rvdev->vring[i].rvdev = rvdev;
337 349
338 return 0; 350 return 0;
339} 351}
340 352
353static void __rproc_free_vrings(struct rproc_vdev *rvdev, int i)
354{
355 struct rproc *rproc = rvdev->rproc;
356
357 for (i--; i > 0; i--) {
358 struct rproc_vring *rvring = &rvdev->vring[i];
359 int size = PAGE_ALIGN(vring_size(rvring->len, rvring->align));
360
361 dma_free_coherent(rproc->dev, size, rvring->va, rvring->dma);
362 idr_remove(&rproc->notifyids, rvring->notifyid);
363 }
364}
365
341/** 366/**
342 * rproc_handle_vring() - handle a vring fw resource 367 * rproc_handle_vdev() - handle a vdev fw resource
343 * @rproc: the remote processor 368 * @rproc: the remote processor
344 * @rsc: the vring resource descriptor 369 * @rsc: the vring resource descriptor
345 * 370 * @avail: size of available data (for sanity checking the image)
346 * This resource entry requires allocation of non-cacheable memory 371 *
347 * for a virtio vring. Currently we only support two vrings per remote 372 * This resource entry requests the host to statically register a virtio
348 * processor, required for the virtio rpmsg device. 373 * device (vdev), and setup everything needed to support it. It contains
349 * 374 * everything needed to make it possible: the virtio device id, virtio
350 * The 'len' member of @rsc should contain the number of buffers this vring 375 * device features, vrings information, virtio config space, etc...
351 * support and 'da' should either contain the device address where 376 *
352 * the remote processor is expecting the vring, or indicate that 377 * Before registering the vdev, the vrings are allocated from non-cacheable
353 * dynamically allocation of the vring's device address is supported. 378 * physically contiguous memory. Currently we only support two vrings per
354 * 379 * remote processor (temporary limitation). We might also want to consider
355 * Note: 'da' is currently not handled. This will be revised when the generic 380 * doing the vring allocation only later when ->find_vqs() is invoked, and
356 * iommu-based DMA API will arrive, or a dynanic & non-iommu use case show 381 * then release them upon ->del_vqs().
357 * up. Meanwhile, statically-addressed iommu-based images should use 382 *
358 * RSC_DEVMEM resource entries to map their require 'da' to the physical 383 * Note: @da is currently not really handled correctly: we dynamically
359 * address of their base CMA region. 384 * allocate it using the DMA API, ignoring requested hard coded addresses,
385 * and we don't take care of any required IOMMU programming. This is all
386 * going to be taken care of when the generic iommu-based DMA API will be
387 * merged. Meanwhile, statically-addressed iommu-based firmware images should
388 * use RSC_DEVMEM resource entries to map their required @da to the physical
389 * address of their base CMA region (ouch, hacky!).
360 * 390 *
361 * Returns 0 on success, or an appropriate error code otherwise 391 * Returns 0 on success, or an appropriate error code otherwise
362 */ 392 */
363static int rproc_handle_vring(struct rproc *rproc, struct fw_resource *rsc) 393static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc,
394 int avail)
364{ 395{
365 struct device *dev = rproc->dev; 396 struct device *dev = rproc->dev;
366 struct rproc_vdev *rvdev = rproc->rvdev; 397 struct rproc_vdev *rvdev;
367 dma_addr_t dma; 398 int i, ret;
368 int size, id = rsc->id;
369 void *va;
370 399
371 /* no vdev is in place ? */ 400 /* make sure resource isn't truncated */
372 if (!rvdev) { 401 if (sizeof(*rsc) + rsc->num_of_vrings * sizeof(struct fw_rsc_vdev_vring)
373 dev_err(dev, "vring requested without a virtio dev entry\n"); 402 + rsc->config_len > avail) {
403 dev_err(rproc->dev, "vdev rsc is truncated\n");
374 return -EINVAL; 404 return -EINVAL;
375 } 405 }
376 406
377 /* the firmware must provide the expected queue size */ 407 /* make sure reserved bytes are zeroes */
378 if (!rsc->len) { 408 if (rsc->reserved[0] || rsc->reserved[1]) {
379 dev_err(dev, "missing expected queue size\n"); 409 dev_err(dev, "vdev rsc has non zero reserved bytes\n");
380 return -EINVAL; 410 return -EINVAL;
381 } 411 }
382 412
383 /* we currently support two vrings per rproc (for rx and tx) */ 413 dev_dbg(dev, "vdev rsc: id %d, dfeatures %x, cfg len %d, %d vrings\n",
384 if (id >= ARRAY_SIZE(rvdev->vring)) { 414 rsc->id, rsc->dfeatures, rsc->config_len, rsc->num_of_vrings);
385 dev_err(dev, "%s: invalid vring id %d\n", rsc->name, id);
386 return -EINVAL;
387 }
388 415
389 /* have we already allocated this vring id ? */ 416 /* we currently support only two vrings per rvdev */
390 if (rvdev->vring[id].len) { 417 if (rsc->num_of_vrings > ARRAY_SIZE(rvdev->vring)) {
391 dev_err(dev, "%s: duplicated id %d\n", rsc->name, id); 418 dev_err(dev, "too many vrings: %d\n", rsc->num_of_vrings);
392 return -EINVAL; 419 return -EINVAL;
393 } 420 }
394 421
395 /* actual size of vring (in bytes) */ 422 rvdev = kzalloc(sizeof(struct rproc_vdev), GFP_KERNEL);
396 size = PAGE_ALIGN(vring_size(rsc->len, AMP_VRING_ALIGN)); 423 if (!rvdev)
397
398 /*
399 * Allocate non-cacheable memory for the vring. In the future
400 * this call will also configure the IOMMU for us
401 */
402 va = dma_alloc_coherent(dev, size, &dma, GFP_KERNEL);
403 if (!va) {
404 dev_err(dev, "dma_alloc_coherent failed\n");
405 return -ENOMEM; 424 return -ENOMEM;
425
426 rvdev->rproc = rproc;
427
428 /* allocate the vrings */
429 for (i = 0; i < rsc->num_of_vrings; i++) {
430 ret = __rproc_handle_vring(rvdev, rsc, i);
431 if (ret)
432 goto free_vrings;
406 } 433 }
407 434
408 dev_dbg(dev, "vring%d: va %p dma %x qsz %d ring size %x\n", id, va, 435 /* remember the device features */
409 dma, rsc->len, size); 436 rvdev->dfeatures = rsc->dfeatures;
437
438 list_add_tail(&rvdev->node, &rproc->rvdevs);
410 439
411 rvdev->vring[id].len = rsc->len; 440 /* it is now safe to add the virtio device */
412 rvdev->vring[id].va = va; 441 ret = rproc_add_virtio_dev(rvdev, rsc->id);
413 rvdev->vring[id].dma = dma; 442 if (ret)
443 goto free_vrings;
414 444
415 return 0; 445 return 0;
446
447free_vrings:
448 __rproc_free_vrings(rvdev, i);
449 kfree(rvdev);
450 return ret;
416} 451}
417 452
418/** 453/**
419 * rproc_handle_trace() - handle a shared trace buffer resource 454 * rproc_handle_trace() - handle a shared trace buffer resource
420 * @rproc: the remote processor 455 * @rproc: the remote processor
421 * @rsc: the trace resource descriptor 456 * @rsc: the trace resource descriptor
457 * @avail: size of available data (for sanity checking the image)
422 * 458 *
423 * In case the remote processor dumps trace logs into memory, 459 * In case the remote processor dumps trace logs into memory,
424 * export it via debugfs. 460 * export it via debugfs.
@@ -430,13 +466,25 @@ static int rproc_handle_vring(struct rproc *rproc, struct fw_resource *rsc)
430 * 466 *
431 * Returns 0 on success, or an appropriate error code otherwise 467 * Returns 0 on success, or an appropriate error code otherwise
432 */ 468 */
433static int rproc_handle_trace(struct rproc *rproc, struct fw_resource *rsc) 469static int rproc_handle_trace(struct rproc *rproc, struct fw_rsc_trace *rsc,
470 int avail)
434{ 471{
435 struct rproc_mem_entry *trace; 472 struct rproc_mem_entry *trace;
436 struct device *dev = rproc->dev; 473 struct device *dev = rproc->dev;
437 void *ptr; 474 void *ptr;
438 char name[15]; 475 char name[15];
439 476
477 if (sizeof(*rsc) > avail) {
478 dev_err(rproc->dev, "trace rsc is truncated\n");
479 return -EINVAL;
480 }
481
482 /* make sure reserved bytes are zeroes */
483 if (rsc->reserved) {
484 dev_err(dev, "trace rsc has non zero reserved bytes\n");
485 return -EINVAL;
486 }
487
440 /* what's the kernel address of this resource ? */ 488 /* what's the kernel address of this resource ? */
441 ptr = rproc_da_to_va(rproc, rsc->da, rsc->len); 489 ptr = rproc_da_to_va(rproc, rsc->da, rsc->len);
442 if (!ptr) { 490 if (!ptr) {
@@ -469,7 +517,7 @@ static int rproc_handle_trace(struct rproc *rproc, struct fw_resource *rsc)
469 517
470 rproc->num_traces++; 518 rproc->num_traces++;
471 519
472 dev_dbg(dev, "%s added: va %p, da 0x%llx, len 0x%x\n", name, ptr, 520 dev_dbg(dev, "%s added: va %p, da 0x%x, len 0x%x\n", name, ptr,
473 rsc->da, rsc->len); 521 rsc->da, rsc->len);
474 522
475 return 0; 523 return 0;
@@ -479,6 +527,7 @@ static int rproc_handle_trace(struct rproc *rproc, struct fw_resource *rsc)
479 * rproc_handle_devmem() - handle devmem resource entry 527 * rproc_handle_devmem() - handle devmem resource entry
480 * @rproc: remote processor handle 528 * @rproc: remote processor handle
481 * @rsc: the devmem resource entry 529 * @rsc: the devmem resource entry
530 * @avail: size of available data (for sanity checking the image)
482 * 531 *
483 * Remote processors commonly need to access certain on-chip peripherals. 532 * Remote processors commonly need to access certain on-chip peripherals.
484 * 533 *
@@ -499,7 +548,8 @@ static int rproc_handle_trace(struct rproc *rproc, struct fw_resource *rsc)
499 * and not allow firmwares to request access to physical addresses that 548 * and not allow firmwares to request access to physical addresses that
500 * are outside those ranges. 549 * are outside those ranges.
501 */ 550 */
502static int rproc_handle_devmem(struct rproc *rproc, struct fw_resource *rsc) 551static int rproc_handle_devmem(struct rproc *rproc, struct fw_rsc_devmem *rsc,
552 int avail)
503{ 553{
504 struct rproc_mem_entry *mapping; 554 struct rproc_mem_entry *mapping;
505 int ret; 555 int ret;
@@ -508,6 +558,17 @@ static int rproc_handle_devmem(struct rproc *rproc, struct fw_resource *rsc)
508 if (!rproc->domain) 558 if (!rproc->domain)
509 return -EINVAL; 559 return -EINVAL;
510 560
561 if (sizeof(*rsc) > avail) {
562 dev_err(rproc->dev, "devmem rsc is truncated\n");
563 return -EINVAL;
564 }
565
566 /* make sure reserved bytes are zeroes */
567 if (rsc->reserved) {
568 dev_err(rproc->dev, "devmem rsc has non zero reserved bytes\n");
569 return -EINVAL;
570 }
571
511 mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); 572 mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
512 if (!mapping) { 573 if (!mapping) {
513 dev_err(rproc->dev, "kzalloc mapping failed\n"); 574 dev_err(rproc->dev, "kzalloc mapping failed\n");
@@ -531,7 +592,7 @@ static int rproc_handle_devmem(struct rproc *rproc, struct fw_resource *rsc)
531 mapping->len = rsc->len; 592 mapping->len = rsc->len;
532 list_add_tail(&mapping->node, &rproc->mappings); 593 list_add_tail(&mapping->node, &rproc->mappings);
533 594
534 dev_dbg(rproc->dev, "mapped devmem pa 0x%llx, da 0x%llx, len 0x%x\n", 595 dev_dbg(rproc->dev, "mapped devmem pa 0x%x, da 0x%x, len 0x%x\n",
535 rsc->pa, rsc->da, rsc->len); 596 rsc->pa, rsc->da, rsc->len);
536 597
537 return 0; 598 return 0;
@@ -545,6 +606,7 @@ out:
545 * rproc_handle_carveout() - handle phys contig memory allocation requests 606 * rproc_handle_carveout() - handle phys contig memory allocation requests
546 * @rproc: rproc handle 607 * @rproc: rproc handle
547 * @rsc: the resource entry 608 * @rsc: the resource entry
609 * @avail: size of available data (for image validation)
548 * 610 *
549 * This function will handle firmware requests for allocation of physically 611 * This function will handle firmware requests for allocation of physically
550 * contiguous memory regions. 612 * contiguous memory regions.
@@ -558,7 +620,8 @@ out:
558 * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB 620 * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
559 * pressure is important; it may have a substantial impact on performance. 621 * pressure is important; it may have a substantial impact on performance.
560 */ 622 */
561static int rproc_handle_carveout(struct rproc *rproc, struct fw_resource *rsc) 623static int rproc_handle_carveout(struct rproc *rproc,
624 struct fw_rsc_carveout *rsc, int avail)
562{ 625{
563 struct rproc_mem_entry *carveout, *mapping; 626 struct rproc_mem_entry *carveout, *mapping;
564 struct device *dev = rproc->dev; 627 struct device *dev = rproc->dev;
@@ -566,6 +629,20 @@ static int rproc_handle_carveout(struct rproc *rproc, struct fw_resource *rsc)
566 void *va; 629 void *va;
567 int ret; 630 int ret;
568 631
632 if (sizeof(*rsc) > avail) {
633 dev_err(rproc->dev, "carveout rsc is truncated\n");
634 return -EINVAL;
635 }
636
637 /* make sure reserved bytes are zeroes */
638 if (rsc->reserved) {
639 dev_err(dev, "carveout rsc has non zero reserved bytes\n");
640 return -EINVAL;
641 }
642
643 dev_dbg(dev, "carveout rsc: da %x, pa %x, len %x, flags %x\n",
644 rsc->da, rsc->pa, rsc->len, rsc->flags);
645
569 mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); 646 mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
570 if (!mapping) { 647 if (!mapping) {
571 dev_err(dev, "kzalloc mapping failed\n"); 648 dev_err(dev, "kzalloc mapping failed\n");
@@ -624,7 +701,7 @@ static int rproc_handle_carveout(struct rproc *rproc, struct fw_resource *rsc)
624 mapping->len = rsc->len; 701 mapping->len = rsc->len;
625 list_add_tail(&mapping->node, &rproc->mappings); 702 list_add_tail(&mapping->node, &rproc->mappings);
626 703
627 dev_dbg(dev, "carveout mapped 0x%llx to 0x%x\n", rsc->da, dma); 704 dev_dbg(dev, "carveout mapped 0x%x to 0x%x\n", rsc->da, dma);
628 705
629 /* 706 /*
630 * Some remote processors might need to know the pa 707 * Some remote processors might need to know the pa
@@ -665,36 +742,44 @@ free_mapping:
665 * enum fw_resource_type. 742 * enum fw_resource_type.
666 */ 743 */
667static rproc_handle_resource_t rproc_handle_rsc[] = { 744static rproc_handle_resource_t rproc_handle_rsc[] = {
668 [RSC_CARVEOUT] = rproc_handle_carveout, 745 [RSC_CARVEOUT] = (rproc_handle_resource_t)rproc_handle_carveout,
669 [RSC_DEVMEM] = rproc_handle_devmem, 746 [RSC_DEVMEM] = (rproc_handle_resource_t)rproc_handle_devmem,
670 [RSC_TRACE] = rproc_handle_trace, 747 [RSC_TRACE] = (rproc_handle_resource_t)rproc_handle_trace,
671 [RSC_VRING] = rproc_handle_vring, 748 [RSC_VDEV] = NULL, /* VDEVs were handled upon registrarion */
672 [RSC_VIRTIO_DEV] = NULL, /* handled early upon registration */
673}; 749};
674 750
675/* handle firmware resource entries before booting the remote processor */ 751/* handle firmware resource entries before booting the remote processor */
676static int 752static int
677rproc_handle_boot_rsc(struct rproc *rproc, struct fw_resource *rsc, int len) 753rproc_handle_boot_rsc(struct rproc *rproc, struct resource_table *table, int len)
678{ 754{
679 struct device *dev = rproc->dev; 755 struct device *dev = rproc->dev;
680 rproc_handle_resource_t handler; 756 rproc_handle_resource_t handler;
681 int ret = 0; 757 int ret = 0, i;
758
759 for (i = 0; i < table->num; i++) {
760 int offset = table->offset[i];
761 struct fw_rsc_hdr *hdr = (void *)table + offset;
762 int avail = len - offset - sizeof(*hdr);
763 void *rsc = (void *)hdr + sizeof(*hdr);
764
765 /* make sure table isn't truncated */
766 if (avail < 0) {
767 dev_err(dev, "rsc table is truncated\n");
768 return -EINVAL;
769 }
682 770
683 for (; len >= sizeof(*rsc); rsc++, len -= sizeof(*rsc)) { 771 dev_dbg(dev, "rsc: type %d\n", hdr->type);
684 dev_dbg(dev, "rsc: type %d, da 0x%llx, pa 0x%llx, len 0x%x, "
685 "id %d, name %s, flags %x\n", rsc->type, rsc->da,
686 rsc->pa, rsc->len, rsc->id, rsc->name, rsc->flags);
687 772
688 if (rsc->type >= RSC_LAST) { 773 if (hdr->type >= RSC_LAST) {
689 dev_warn(dev, "unsupported resource %d\n", rsc->type); 774 dev_warn(dev, "unsupported resource %d\n", hdr->type);
690 continue; 775 continue;
691 } 776 }
692 777
693 handler = rproc_handle_rsc[rsc->type]; 778 handler = rproc_handle_rsc[hdr->type];
694 if (!handler) 779 if (!handler)
695 continue; 780 continue;
696 781
697 ret = handler(rproc, rsc); 782 ret = handler(rproc, rsc, avail);
698 if (ret) 783 if (ret)
699 break; 784 break;
700 } 785 }
@@ -704,47 +789,64 @@ rproc_handle_boot_rsc(struct rproc *rproc, struct fw_resource *rsc, int len)
704 789
705/* handle firmware resource entries while registering the remote processor */ 790/* handle firmware resource entries while registering the remote processor */
706static int 791static int
707rproc_handle_virtio_rsc(struct rproc *rproc, struct fw_resource *rsc, int len) 792rproc_handle_virtio_rsc(struct rproc *rproc, struct resource_table *table, int len)
708{ 793{
709 struct device *dev = rproc->dev; 794 struct device *dev = rproc->dev;
710 int ret = -ENODEV; 795 int ret = 0, i;
796
797 for (i = 0; i < table->num; i++) {
798 int offset = table->offset[i];
799 struct fw_rsc_hdr *hdr = (void *)table + offset;
800 int avail = len - offset - sizeof(*hdr);
801 struct fw_rsc_vdev *vrsc;
802
803 /* make sure table isn't truncated */
804 if (avail < 0) {
805 dev_err(dev, "rsc table is truncated\n");
806 return -EINVAL;
807 }
808
809 dev_dbg(dev, "%s: rsc type %d\n", __func__, hdr->type);
810
811 if (hdr->type != RSC_VDEV)
812 continue;
813
814 vrsc = (struct fw_rsc_vdev *)hdr->data;
711 815
712 for (; len >= sizeof(*rsc); rsc++, len -= sizeof(*rsc)) 816 ret = rproc_handle_vdev(rproc, vrsc, avail);
713 if (rsc->type == RSC_VIRTIO_DEV) { 817 if (ret)
714 dev_dbg(dev, "found vdev %d/%s features %llx\n",
715 rsc->flags, rsc->name, rsc->da);
716 ret = rproc_handle_virtio_hdr(rproc, rsc);
717 break; 818 break;
718 } 819 }
719 820
720 return ret; 821 return ret;
721} 822}
722 823
723/** 824/**
724 * rproc_handle_resources() - find and handle the resource table 825 * rproc_find_rsc_table() - find the resource table
725 * @rproc: the rproc handle 826 * @rproc: the rproc handle
726 * @elf_data: the content of the ELF firmware image 827 * @elf_data: the content of the ELF firmware image
727 * @len: firmware size (in bytes) 828 * @len: firmware size (in bytes)
728 * @handler: function that should be used to handle the resource table 829 * @tablesz: place holder for providing back the table size
729 * 830 *
730 * This function finds the resource table inside the remote processor's 831 * This function finds the resource table inside the remote processor's
731 * firmware, and invoke a user-supplied handler with it (we have two 832 * firmware. It is used both upon the registration of @rproc (in order
732 * possible handlers: one is invoked upon registration of @rproc, 833 * to look for and register the supported virito devices), and when the
733 * in order to register the supported virito devices, and the other is 834 * @rproc is booted.
734 * invoked when @rproc is actually booted). 835 *
735 * 836 * Returns the pointer to the resource table if it is found, and write its
736 * Currently this function fails if a resource table doesn't exist. 837 * size into @tablesz. If a valid table isn't found, NULL is returned
737 * This restriction will be removed when we'll start supporting remote 838 * (and @tablesz isn't set).
738 * processors that don't need a resource table.
739 */ 839 */
740static int rproc_handle_resources(struct rproc *rproc, const u8 *elf_data, 840static struct resource_table *
741 size_t len, rproc_handle_resources_t handler) 841rproc_find_rsc_table(struct rproc *rproc, const u8 *elf_data, size_t len,
742 842 int *tablesz)
743{ 843{
744 struct elf32_hdr *ehdr; 844 struct elf32_hdr *ehdr;
745 struct elf32_shdr *shdr; 845 struct elf32_shdr *shdr;
746 const char *name_table; 846 const char *name_table;
747 int i, ret = -EINVAL; 847 struct device *dev = rproc->dev;
848 struct resource_table *table = NULL;
849 int i;
748 850
749 ehdr = (struct elf32_hdr *)elf_data; 851 ehdr = (struct elf32_hdr *)elf_data;
750 shdr = (struct elf32_shdr *)(elf_data + ehdr->e_shoff); 852 shdr = (struct elf32_shdr *)(elf_data + ehdr->e_shoff);
@@ -752,24 +854,50 @@ static int rproc_handle_resources(struct rproc *rproc, const u8 *elf_data,
752 854
753 /* look for the resource table and handle it */ 855 /* look for the resource table and handle it */
754 for (i = 0; i < ehdr->e_shnum; i++, shdr++) { 856 for (i = 0; i < ehdr->e_shnum; i++, shdr++) {
755 if (!strcmp(name_table + shdr->sh_name, ".resource_table")) { 857 int size = shdr->sh_size;
756 struct fw_resource *table = (struct fw_resource *) 858 int offset = shdr->sh_offset;
757 (elf_data + shdr->sh_offset); 859
860 if (strcmp(name_table + shdr->sh_name, ".resource_table"))
861 continue;
758 862
759 if (shdr->sh_offset + shdr->sh_size > len) { 863 table = (struct resource_table *)(elf_data + offset);
760 dev_err(rproc->dev,
761 "truncated fw: need 0x%x avail 0x%x\n",
762 shdr->sh_offset + shdr->sh_size, len);
763 ret = -EINVAL;
764 }
765 864
766 ret = handler(rproc, table, shdr->sh_size); 865 /* make sure we have the entire table */
866 if (offset + size > len) {
867 dev_err(dev, "resource table truncated\n");
868 return NULL;
869 }
767 870
768 break; 871 /* make sure table has at least the header */
872 if (sizeof(struct resource_table) > size) {
873 dev_err(dev, "header-less resource table\n");
874 return NULL;
875 }
876
877 /* we don't support any version beyond the first */
878 if (table->ver != 1) {
879 dev_err(dev, "unsupported fw ver: %d\n", table->ver);
880 return NULL;
881 }
882
883 /* make sure reserved bytes are zeroes */
884 if (table->reserved[0] || table->reserved[1]) {
885 dev_err(dev, "non zero reserved bytes\n");
886 return NULL;
887 }
888
889 /* make sure the offsets array isn't truncated */
890 if (table->num * sizeof(table->offset[0]) +
891 sizeof(struct resource_table) > size) {
892 dev_err(dev, "resource table incomplete\n");
893 return NULL;
769 } 894 }
895
896 *tablesz = shdr->sh_size;
897 break;
770 } 898 }
771 899
772 return ret; 900 return table;
773} 901}
774 902
775/** 903/**
@@ -777,14 +905,12 @@ static int rproc_handle_resources(struct rproc *rproc, const u8 *elf_data,
777 * @rproc: rproc handle 905 * @rproc: rproc handle
778 * 906 *
779 * This function will free all resources acquired for @rproc, and it 907 * This function will free all resources acquired for @rproc, and it
780 * is called when @rproc shuts down, or just failed booting. 908 * is called whenever @rproc either shuts down or fails to boot.
781 */ 909 */
782static void rproc_resource_cleanup(struct rproc *rproc) 910static void rproc_resource_cleanup(struct rproc *rproc)
783{ 911{
784 struct rproc_mem_entry *entry, *tmp; 912 struct rproc_mem_entry *entry, *tmp;
785 struct device *dev = rproc->dev; 913 struct device *dev = rproc->dev;
786 struct rproc_vdev *rvdev = rproc->rvdev;
787 int i;
788 914
789 /* clean up debugfs trace entries */ 915 /* clean up debugfs trace entries */
790 list_for_each_entry_safe(entry, tmp, &rproc->traces, node) { 916 list_for_each_entry_safe(entry, tmp, &rproc->traces, node) {
@@ -794,23 +920,6 @@ static void rproc_resource_cleanup(struct rproc *rproc)
794 kfree(entry); 920 kfree(entry);
795 } 921 }
796 922
797 /* free the coherent memory allocated for the vrings */
798 for (i = 0; rvdev && i < ARRAY_SIZE(rvdev->vring); i++) {
799 int qsz = rvdev->vring[i].len;
800 void *va = rvdev->vring[i].va;
801 int dma = rvdev->vring[i].dma;
802
803 /* virtqueue size is expressed in number of buffers supported */
804 if (qsz) {
805 /* how many bytes does this vring really occupy ? */
806 int size = PAGE_ALIGN(vring_size(qsz, AMP_VRING_ALIGN));
807
808 dma_free_coherent(rproc->dev, size, va, dma);
809
810 rvdev->vring[i].len = 0;
811 }
812 }
813
814 /* clean up carveout allocations */ 923 /* clean up carveout allocations */
815 list_for_each_entry_safe(entry, tmp, &rproc->carveouts, node) { 924 list_for_each_entry_safe(entry, tmp, &rproc->carveouts, node) {
816 dma_free_coherent(dev, entry->len, entry->va, entry->dma); 925 dma_free_coherent(dev, entry->len, entry->va, entry->dma);
@@ -840,6 +949,7 @@ static int rproc_fw_sanity_check(struct rproc *rproc, const struct firmware *fw)
840 const char *name = rproc->firmware; 949 const char *name = rproc->firmware;
841 struct device *dev = rproc->dev; 950 struct device *dev = rproc->dev;
842 struct elf32_hdr *ehdr; 951 struct elf32_hdr *ehdr;
952 char class;
843 953
844 if (!fw) { 954 if (!fw) {
845 dev_err(dev, "failed to load %s\n", name); 955 dev_err(dev, "failed to load %s\n", name);
@@ -853,6 +963,13 @@ static int rproc_fw_sanity_check(struct rproc *rproc, const struct firmware *fw)
853 963
854 ehdr = (struct elf32_hdr *)fw->data; 964 ehdr = (struct elf32_hdr *)fw->data;
855 965
966 /* We only support ELF32 at this point */
967 class = ehdr->e_ident[EI_CLASS];
968 if (class != ELFCLASS32) {
969 dev_err(dev, "Unsupported class: %d\n", class);
970 return -EINVAL;
971 }
972
856 /* We assume the firmware has the same endianess as the host */ 973 /* We assume the firmware has the same endianess as the host */
857# ifdef __LITTLE_ENDIAN 974# ifdef __LITTLE_ENDIAN
858 if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) { 975 if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) {
@@ -894,7 +1011,8 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
894 struct device *dev = rproc->dev; 1011 struct device *dev = rproc->dev;
895 const char *name = rproc->firmware; 1012 const char *name = rproc->firmware;
896 struct elf32_hdr *ehdr; 1013 struct elf32_hdr *ehdr;
897 int ret; 1014 struct resource_table *table;
1015 int ret, tablesz;
898 1016
899 ret = rproc_fw_sanity_check(rproc, fw); 1017 ret = rproc_fw_sanity_check(rproc, fw);
900 if (ret) 1018 if (ret)
@@ -921,9 +1039,13 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
921 */ 1039 */
922 rproc->bootaddr = ehdr->e_entry; 1040 rproc->bootaddr = ehdr->e_entry;
923 1041
1042 /* look for the resource table */
1043 table = rproc_find_rsc_table(rproc, fw->data, fw->size, &tablesz);
1044 if (!table)
1045 goto clean_up;
1046
924 /* handle fw resources which are required to boot rproc */ 1047 /* handle fw resources which are required to boot rproc */
925 ret = rproc_handle_resources(rproc, fw->data, fw->size, 1048 ret = rproc_handle_boot_rsc(rproc, table, tablesz);
926 rproc_handle_boot_rsc);
927 if (ret) { 1049 if (ret) {
928 dev_err(dev, "Failed to process resources: %d\n", ret); 1050 dev_err(dev, "Failed to process resources: %d\n", ret);
929 goto clean_up; 1051 goto clean_up;
@@ -966,22 +1088,19 @@ clean_up:
966static void rproc_fw_config_virtio(const struct firmware *fw, void *context) 1088static void rproc_fw_config_virtio(const struct firmware *fw, void *context)
967{ 1089{
968 struct rproc *rproc = context; 1090 struct rproc *rproc = context;
969 struct device *dev = rproc->dev; 1091 struct resource_table *table;
970 int ret; 1092 int ret, tablesz;
971 1093
972 if (rproc_fw_sanity_check(rproc, fw) < 0) 1094 if (rproc_fw_sanity_check(rproc, fw) < 0)
973 goto out; 1095 goto out;
974 1096
975 /* does the fw supports any virtio devices ? */ 1097 /* look for the resource table */
976 ret = rproc_handle_resources(rproc, fw->data, fw->size, 1098 table = rproc_find_rsc_table(rproc, fw->data, fw->size, &tablesz);
977 rproc_handle_virtio_rsc); 1099 if (!table)
978 if (ret) {
979 dev_info(dev, "No fw virtio device was found\n");
980 goto out; 1100 goto out;
981 }
982 1101
983 /* add the virtio device (currently only rpmsg vdevs are supported) */ 1102 /* look for virtio devices and register them */
984 ret = rproc_add_rpmsg_vdev(rproc); 1103 ret = rproc_handle_virtio_rsc(rproc, table, tablesz);
985 if (ret) 1104 if (ret)
986 goto out; 1105 goto out;
987 1106
@@ -1146,13 +1265,23 @@ EXPORT_SYMBOL(rproc_shutdown);
1146void rproc_release(struct kref *kref) 1265void rproc_release(struct kref *kref)
1147{ 1266{
1148 struct rproc *rproc = container_of(kref, struct rproc, refcount); 1267 struct rproc *rproc = container_of(kref, struct rproc, refcount);
1268 struct rproc_vdev *rvdev, *rvtmp;
1149 1269
1150 dev_info(rproc->dev, "removing %s\n", rproc->name); 1270 dev_info(rproc->dev, "removing %s\n", rproc->name);
1151 1271
1152 rproc_delete_debug_dir(rproc); 1272 rproc_delete_debug_dir(rproc);
1153 1273
1154 /* at this point no one holds a reference to rproc anymore */ 1274 /* clean up remote vdev entries */
1155 kfree(rproc); 1275 list_for_each_entry_safe(rvdev, rvtmp, &rproc->rvdevs, node) {
1276 __rproc_free_vrings(rvdev, RVDEV_NUM_VRINGS);
1277 list_del(&rvdev->node);
1278 }
1279
1280 /*
1281 * At this point no one holds a reference to rproc anymore,
1282 * so we can directly unroll rproc_alloc()
1283 */
1284 rproc_free(rproc);
1156} 1285}
1157 1286
1158/* will be called when an rproc is added to the rprocs klist */ 1287/* will be called when an rproc is added to the rprocs klist */
@@ -1196,7 +1325,7 @@ static struct rproc *next_rproc(struct klist_iter *i)
1196 * use rproc_put() to decrement it back once rproc isn't needed anymore. 1325 * use rproc_put() to decrement it back once rproc isn't needed anymore.
1197 * 1326 *
1198 * Note: currently this function (and its counterpart rproc_put()) are not 1327 * Note: currently this function (and its counterpart rproc_put()) are not
1199 * used anymore by the rpmsg subsystem. We need to scrutinize the use cases 1328 * being used. We need to scrutinize the use cases
1200 * that still need them, and see if we can migrate them to use the non 1329 * that still need them, and see if we can migrate them to use the non
1201 * name-based boot/shutdown interface. 1330 * name-based boot/shutdown interface.
1202 */ 1331 */
@@ -1271,11 +1400,8 @@ EXPORT_SYMBOL(rproc_put);
1271 * firmware. 1400 * firmware.
1272 * 1401 *
1273 * If found, those virtio devices will be created and added, so as a result 1402 * If found, those virtio devices will be created and added, so as a result
1274 * of registering this remote processor, additional virtio drivers will be 1403 * of registering this remote processor, additional virtio drivers might be
1275 * probed. 1404 * probed.
1276 *
1277 * Currently, though, we only support a single RPMSG virtio vdev per remote
1278 * processor.
1279 */ 1405 */
1280int rproc_register(struct rproc *rproc) 1406int rproc_register(struct rproc *rproc)
1281{ 1407{
@@ -1298,7 +1424,7 @@ int rproc_register(struct rproc *rproc)
1298 1424
1299 /* 1425 /*
1300 * We must retrieve early virtio configuration info from 1426 * We must retrieve early virtio configuration info from
1301 * the firmware (e.g. whether to register a virtio rpmsg device, 1427 * the firmware (e.g. whether to register a virtio device,
1302 * what virtio features does it support, ...). 1428 * what virtio features does it support, ...).
1303 * 1429 *
1304 * We're initiating an asynchronous firmware loading, so we can 1430 * We're initiating an asynchronous firmware loading, so we can
@@ -1367,9 +1493,12 @@ struct rproc *rproc_alloc(struct device *dev, const char *name,
1367 1493
1368 mutex_init(&rproc->lock); 1494 mutex_init(&rproc->lock);
1369 1495
1496 idr_init(&rproc->notifyids);
1497
1370 INIT_LIST_HEAD(&rproc->carveouts); 1498 INIT_LIST_HEAD(&rproc->carveouts);
1371 INIT_LIST_HEAD(&rproc->mappings); 1499 INIT_LIST_HEAD(&rproc->mappings);
1372 INIT_LIST_HEAD(&rproc->traces); 1500 INIT_LIST_HEAD(&rproc->traces);
1501 INIT_LIST_HEAD(&rproc->rvdevs);
1373 1502
1374 rproc->state = RPROC_OFFLINE; 1503 rproc->state = RPROC_OFFLINE;
1375 1504
@@ -1389,6 +1518,9 @@ EXPORT_SYMBOL(rproc_alloc);
1389 */ 1518 */
1390void rproc_free(struct rproc *rproc) 1519void rproc_free(struct rproc *rproc)
1391{ 1520{
1521 idr_remove_all(&rproc->notifyids);
1522 idr_destroy(&rproc->notifyids);
1523
1392 kfree(rproc); 1524 kfree(rproc);
1393} 1525}
1394EXPORT_SYMBOL(rproc_free); 1526EXPORT_SYMBOL(rproc_free);
@@ -1415,18 +1547,22 @@ EXPORT_SYMBOL(rproc_free);
1415 */ 1547 */
1416int rproc_unregister(struct rproc *rproc) 1548int rproc_unregister(struct rproc *rproc)
1417{ 1549{
1550 struct rproc_vdev *rvdev;
1551
1418 if (!rproc) 1552 if (!rproc)
1419 return -EINVAL; 1553 return -EINVAL;
1420 1554
1421 /* if rproc is just being registered, wait */ 1555 /* if rproc is just being registered, wait */
1422 wait_for_completion(&rproc->firmware_loading_complete); 1556 wait_for_completion(&rproc->firmware_loading_complete);
1423 1557
1424 /* was an rpmsg vdev created ? */ 1558 /* clean up remote vdev entries */
1425 if (rproc->rvdev) 1559 list_for_each_entry(rvdev, &rproc->rvdevs, node)
1426 rproc_remove_rpmsg_vdev(rproc); 1560 rproc_remove_virtio_dev(rvdev);
1427 1561
1428 klist_remove(&rproc->node); 1562 /* the rproc is downref'ed as soon as it's removed from the klist */
1563 klist_del(&rproc->node);
1429 1564
1565 /* the rproc will only be released after its refcount drops to zero */
1430 kref_put(&rproc->refcount, rproc_release); 1566 kref_put(&rproc->refcount, rproc_release);
1431 1567
1432 return 0; 1568 return 0;
diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h
index 8b2fc40e92d0..9f336d6bdef3 100644
--- a/drivers/remoteproc/remoteproc_internal.h
+++ b/drivers/remoteproc/remoteproc_internal.h
@@ -28,9 +28,9 @@ struct rproc;
28void rproc_release(struct kref *kref); 28void rproc_release(struct kref *kref);
29irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int vq_id); 29irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int vq_id);
30 30
31/* from remoteproc_rpmsg.c */ 31/* from remoteproc_virtio.c */
32int rproc_add_rpmsg_vdev(struct rproc *); 32int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id);
33void rproc_remove_rpmsg_vdev(struct rproc *rproc); 33void rproc_remove_virtio_dev(struct rproc_vdev *rvdev);
34 34
35/* from remoteproc_debugfs.c */ 35/* from remoteproc_debugfs.c */
36void rproc_remove_trace_file(struct dentry *tfile); 36void rproc_remove_trace_file(struct dentry *tfile);
diff --git a/drivers/remoteproc/remoteproc_rpmsg.c b/drivers/remoteproc/remoteproc_virtio.c
index 4f73e811bb80..ecf612130750 100644
--- a/drivers/remoteproc/remoteproc_rpmsg.c
+++ b/drivers/remoteproc/remoteproc_virtio.c
@@ -19,7 +19,6 @@
19 19
20#include <linux/export.h> 20#include <linux/export.h>
21#include <linux/remoteproc.h> 21#include <linux/remoteproc.h>
22#include <linux/rpmsg.h>
23#include <linux/virtio.h> 22#include <linux/virtio.h>
24#include <linux/virtio_config.h> 23#include <linux/virtio_config.h>
25#include <linux/virtio_ids.h> 24#include <linux/virtio_ids.h>
@@ -30,45 +29,41 @@
30 29
31#include "remoteproc_internal.h" 30#include "remoteproc_internal.h"
32 31
33/**
34 * struct rproc_virtio_vq_info - virtqueue state
35 * @vq_id: a unique index of this virtqueue (unique for this @rproc)
36 * @rproc: handle to the remote processor
37 *
38 * Such a struct will be maintained for every virtqueue we're
39 * using to communicate with the remote processor
40 */
41struct rproc_virtio_vq_info {
42 __u16 vq_id;
43 struct rproc *rproc;
44};
45
46/* kick the remote processor, and let it know which virtqueue to poke at */ 32/* kick the remote processor, and let it know which virtqueue to poke at */
47static void rproc_virtio_notify(struct virtqueue *vq) 33static void rproc_virtio_notify(struct virtqueue *vq)
48{ 34{
49 struct rproc_virtio_vq_info *rpvq = vq->priv; 35 struct rproc_vring *rvring = vq->priv;
50 struct rproc *rproc = rpvq->rproc; 36 struct rproc *rproc = rvring->rvdev->rproc;
37 int notifyid = rvring->notifyid;
51 38
52 dev_dbg(rproc->dev, "kicking vq id: %d\n", rpvq->vq_id); 39 dev_dbg(rproc->dev, "kicking vq index: %d\n", notifyid);
53 40
54 rproc->ops->kick(rproc, rpvq->vq_id); 41 rproc->ops->kick(rproc, notifyid);
55} 42}
56 43
57/** 44/**
58 * rproc_vq_interrupt() - tell remoteproc that a virtqueue is interrupted 45 * rproc_vq_interrupt() - tell remoteproc that a virtqueue is interrupted
59 * @rproc: handle to the remote processor 46 * @rproc: handle to the remote processor
60 * @vq_id: index of the signalled virtqueue 47 * @notifyid: index of the signalled virtqueue (unique per this @rproc)
61 * 48 *
62 * This function should be called by the platform-specific rproc driver, 49 * This function should be called by the platform-specific rproc driver,
63 * when the remote processor signals that a specific virtqueue has pending 50 * when the remote processor signals that a specific virtqueue has pending
64 * messages available. 51 * messages available.
65 * 52 *
66 * Returns IRQ_NONE if no message was found in the @vq_id virtqueue, 53 * Returns IRQ_NONE if no message was found in the @notifyid virtqueue,
67 * and otherwise returns IRQ_HANDLED. 54 * and otherwise returns IRQ_HANDLED.
68 */ 55 */
69irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int vq_id) 56irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int notifyid)
70{ 57{
71 return vring_interrupt(0, rproc->rvdev->vq[vq_id]); 58 struct rproc_vring *rvring;
59
60 dev_dbg(rproc->dev, "vq index %d is interrupted\n", notifyid);
61
62 rvring = idr_find(&rproc->notifyids, notifyid);
63 if (!rvring || !rvring->vq)
64 return IRQ_NONE;
65
66 return vring_interrupt(0, rvring->vq);
72} 67}
73EXPORT_SYMBOL(rproc_vq_interrupt); 68EXPORT_SYMBOL(rproc_vq_interrupt);
74 69
@@ -77,60 +72,60 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
77 void (*callback)(struct virtqueue *vq), 72 void (*callback)(struct virtqueue *vq),
78 const char *name) 73 const char *name)
79{ 74{
75 struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
80 struct rproc *rproc = vdev_to_rproc(vdev); 76 struct rproc *rproc = vdev_to_rproc(vdev);
81 struct rproc_vdev *rvdev = rproc->rvdev; 77 struct rproc_vring *rvring;
82 struct rproc_virtio_vq_info *rpvq;
83 struct virtqueue *vq; 78 struct virtqueue *vq;
84 void *addr; 79 void *addr;
85 int ret, len; 80 int len, size;
86 81
87 rpvq = kmalloc(sizeof(*rpvq), GFP_KERNEL); 82 /* we're temporarily limited to two virtqueues per rvdev */
88 if (!rpvq) 83 if (id >= ARRAY_SIZE(rvdev->vring))
89 return ERR_PTR(-ENOMEM); 84 return ERR_PTR(-EINVAL);
85
86 rvring = &rvdev->vring[id];
90 87
91 rpvq->rproc = rproc; 88 addr = rvring->va;
92 rpvq->vq_id = id; 89 len = rvring->len;
93 90
94 addr = rvdev->vring[id].va; 91 /* zero vring */
95 len = rvdev->vring[id].len; 92 size = vring_size(len, rvring->align);
93 memset(addr, 0, size);
96 94
97 dev_dbg(rproc->dev, "vring%d: va %p qsz %d\n", id, addr, len); 95 dev_dbg(rproc->dev, "vring%d: va %p qsz %d notifyid %d\n",
96 id, addr, len, rvring->notifyid);
98 97
99 /* 98 /*
100 * Create the new vq, and tell virtio we're not interested in 99 * Create the new vq, and tell virtio we're not interested in
101 * the 'weak' smp barriers, since we're talking with a real device. 100 * the 'weak' smp barriers, since we're talking with a real device.
102 */ 101 */
103 vq = vring_new_virtqueue(len, AMP_VRING_ALIGN, vdev, false, addr, 102 vq = vring_new_virtqueue(len, rvring->align, vdev, false, addr,
104 rproc_virtio_notify, callback, name); 103 rproc_virtio_notify, callback, name);
105 if (!vq) { 104 if (!vq) {
106 dev_err(rproc->dev, "vring_new_virtqueue %s failed\n", name); 105 dev_err(rproc->dev, "vring_new_virtqueue %s failed\n", name);
107 ret = -ENOMEM; 106 return ERR_PTR(-ENOMEM);
108 goto free_rpvq;
109 } 107 }
110 108
111 rvdev->vq[id] = vq; 109 rvring->vq = vq;
112 vq->priv = rpvq; 110 vq->priv = rvring;
113 111
114 return vq; 112 return vq;
115
116free_rpvq:
117 kfree(rpvq);
118 return ERR_PTR(ret);
119} 113}
120 114
121static void rproc_virtio_del_vqs(struct virtio_device *vdev) 115static void rproc_virtio_del_vqs(struct virtio_device *vdev)
122{ 116{
123 struct virtqueue *vq, *n; 117 struct virtqueue *vq, *n;
124 struct rproc *rproc = vdev_to_rproc(vdev); 118 struct rproc *rproc = vdev_to_rproc(vdev);
119 struct rproc_vring *rvring;
120
121 /* power down the remote processor before deleting vqs */
122 rproc_shutdown(rproc);
125 123
126 list_for_each_entry_safe(vq, n, &vdev->vqs, list) { 124 list_for_each_entry_safe(vq, n, &vdev->vqs, list) {
127 struct rproc_virtio_vq_info *rpvq = vq->priv; 125 rvring = vq->priv;
126 rvring->vq = NULL;
128 vring_del_virtqueue(vq); 127 vring_del_virtqueue(vq);
129 kfree(rpvq);
130 } 128 }
131
132 /* power down the remote processor */
133 rproc_shutdown(rproc);
134} 129}
135 130
136static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs, 131static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs,
@@ -141,17 +136,6 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs,
141 struct rproc *rproc = vdev_to_rproc(vdev); 136 struct rproc *rproc = vdev_to_rproc(vdev);
142 int i, ret; 137 int i, ret;
143 138
144 /* we maintain two virtqueues per remote processor (for RX and TX) */
145 if (nvqs != 2)
146 return -EINVAL;
147
148 /* boot the remote processor */
149 ret = rproc_boot(rproc);
150 if (ret) {
151 dev_err(rproc->dev, "rproc_boot() failed %d\n", ret);
152 goto error;
153 }
154
155 for (i = 0; i < nvqs; ++i) { 139 for (i = 0; i < nvqs; ++i) {
156 vqs[i] = rp_find_vq(vdev, i, callbacks[i], names[i]); 140 vqs[i] = rp_find_vq(vdev, i, callbacks[i], names[i]);
157 if (IS_ERR(vqs[i])) { 141 if (IS_ERR(vqs[i])) {
@@ -160,6 +144,13 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs,
160 } 144 }
161 } 145 }
162 146
147 /* now that the vqs are all set, boot the remote processor */
148 ret = rproc_boot(rproc);
149 if (ret) {
150 dev_err(rproc->dev, "rproc_boot() failed %d\n", ret);
151 goto error;
152 }
153
163 return 0; 154 return 0;
164 155
165error: 156error:
@@ -170,7 +161,7 @@ error:
170/* 161/*
171 * We don't support yet real virtio status semantics. 162 * We don't support yet real virtio status semantics.
172 * 163 *
173 * The plan is to provide this via the VIRTIO HDR resource entry 164 * The plan is to provide this via the VDEV resource entry
174 * which is part of the firmware: this way the remote processor 165 * which is part of the firmware: this way the remote processor
175 * will be able to access the status values as set by us. 166 * will be able to access the status values as set by us.
176 */ 167 */
@@ -181,7 +172,7 @@ static u8 rproc_virtio_get_status(struct virtio_device *vdev)
181 172
182static void rproc_virtio_set_status(struct virtio_device *vdev, u8 status) 173static void rproc_virtio_set_status(struct virtio_device *vdev, u8 status)
183{ 174{
184 dev_dbg(&vdev->dev, "new status: %d\n", status); 175 dev_dbg(&vdev->dev, "status: %d\n", status);
185} 176}
186 177
187static void rproc_virtio_reset(struct virtio_device *vdev) 178static void rproc_virtio_reset(struct virtio_device *vdev)
@@ -192,15 +183,14 @@ static void rproc_virtio_reset(struct virtio_device *vdev)
192/* provide the vdev features as retrieved from the firmware */ 183/* provide the vdev features as retrieved from the firmware */
193static u32 rproc_virtio_get_features(struct virtio_device *vdev) 184static u32 rproc_virtio_get_features(struct virtio_device *vdev)
194{ 185{
195 struct rproc *rproc = vdev_to_rproc(vdev); 186 struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
196 187
197 /* we only support a single vdev device for now */ 188 return rvdev->dfeatures;
198 return rproc->rvdev->dfeatures;
199} 189}
200 190
201static void rproc_virtio_finalize_features(struct virtio_device *vdev) 191static void rproc_virtio_finalize_features(struct virtio_device *vdev)
202{ 192{
203 struct rproc *rproc = vdev_to_rproc(vdev); 193 struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
204 194
205 /* Give virtio_ring a chance to accept features */ 195 /* Give virtio_ring a chance to accept features */
206 vring_transport_features(vdev); 196 vring_transport_features(vdev);
@@ -214,7 +204,7 @@ static void rproc_virtio_finalize_features(struct virtio_device *vdev)
214 * fixed as part of a small resource table overhaul and then an 204 * fixed as part of a small resource table overhaul and then an
215 * extension of the virtio resource entries. 205 * extension of the virtio resource entries.
216 */ 206 */
217 rproc->rvdev->gfeatures = vdev->features[0]; 207 rvdev->gfeatures = vdev->features[0];
218} 208}
219 209
220static struct virtio_config_ops rproc_virtio_config_ops = { 210static struct virtio_config_ops rproc_virtio_config_ops = {
@@ -244,26 +234,25 @@ static void rproc_vdev_release(struct device *dev)
244} 234}
245 235
246/** 236/**
247 * rproc_add_rpmsg_vdev() - create an rpmsg virtio device 237 * rproc_add_virtio_dev() - register an rproc-induced virtio device
248 * @rproc: the rproc handle 238 * @rvdev: the remote vdev
249 * 239 *
250 * This function is called if virtio rpmsg support was found in the 240 * This function registers a virtio device. This vdev's partent is
251 * firmware of the remote processor. 241 * the rproc device.
252 * 242 *
253 * Today we only support creating a single rpmsg vdev (virtio device), 243 * Returns 0 on success or an appropriate error value otherwise.
254 * but the plan is to remove this limitation. At that point this interface
255 * will be revised/extended.
256 */ 244 */
257int rproc_add_rpmsg_vdev(struct rproc *rproc) 245int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id)
258{ 246{
247 struct rproc *rproc = rvdev->rproc;
259 struct device *dev = rproc->dev; 248 struct device *dev = rproc->dev;
260 struct rproc_vdev *rvdev = rproc->rvdev; 249 struct virtio_device *vdev = &rvdev->vdev;
261 int ret; 250 int ret;
262 251
263 rvdev->vdev.id.device = VIRTIO_ID_RPMSG, 252 vdev->id.device = id,
264 rvdev->vdev.config = &rproc_virtio_config_ops, 253 vdev->config = &rproc_virtio_config_ops,
265 rvdev->vdev.dev.parent = dev; 254 vdev->dev.parent = dev;
266 rvdev->vdev.dev.release = rproc_vdev_release; 255 vdev->dev.release = rproc_vdev_release;
267 256
268 /* 257 /*
269 * We're indirectly making a non-temporary copy of the rproc pointer 258 * We're indirectly making a non-temporary copy of the rproc pointer
@@ -275,25 +264,26 @@ int rproc_add_rpmsg_vdev(struct rproc *rproc)
275 */ 264 */
276 kref_get(&rproc->refcount); 265 kref_get(&rproc->refcount);
277 266
278 ret = register_virtio_device(&rvdev->vdev); 267 ret = register_virtio_device(vdev);
279 if (ret) { 268 if (ret) {
280 kref_put(&rproc->refcount, rproc_release); 269 kref_put(&rproc->refcount, rproc_release);
281 dev_err(dev, "failed to register vdev: %d\n", ret); 270 dev_err(dev, "failed to register vdev: %d\n", ret);
271 goto out;
282 } 272 }
283 273
274 dev_info(dev, "registered %s (type %d)\n", dev_name(&vdev->dev), id);
275
276out:
284 return ret; 277 return ret;
285} 278}
286 279
287/** 280/**
288 * rproc_remove_rpmsg_vdev() - remove an rpmsg vdev device 281 * rproc_remove_virtio_dev() - remove an rproc-induced virtio device
289 * @rproc: the rproc handle 282 * @rvdev: the remote vdev
290 * 283 *
291 * This function is called whenever @rproc is removed _iff_ an rpmsg 284 * This function unregisters an existing virtio device.
292 * vdev was created beforehand.
293 */ 285 */
294void rproc_remove_rpmsg_vdev(struct rproc *rproc) 286void rproc_remove_virtio_dev(struct rproc_vdev *rvdev)
295{ 287{
296 struct rproc_vdev *rvdev = rproc->rvdev;
297
298 unregister_virtio_device(&rvdev->vdev); 288 unregister_virtio_device(&rvdev->vdev);
299} 289}
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
index 8980ac2cc546..75506ec2840e 100644
--- a/drivers/rpmsg/virtio_rpmsg_bus.c
+++ b/drivers/rpmsg/virtio_rpmsg_bus.c
@@ -290,22 +290,36 @@ struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *rpdev,
290EXPORT_SYMBOL(rpmsg_create_ept); 290EXPORT_SYMBOL(rpmsg_create_ept);
291 291
292/** 292/**
293 * rpmsg_destroy_ept() - destroy an existing rpmsg endpoint 293 * __rpmsg_destroy_ept() - destroy an existing rpmsg endpoint
294 * @vrp: virtproc which owns this ept
294 * @ept: endpoing to destroy 295 * @ept: endpoing to destroy
295 * 296 *
296 * Should be used by drivers to destroy an rpmsg endpoint previously 297 * An internal function which destroy an ept without assuming it is
297 * created with rpmsg_create_ept(). 298 * bound to an rpmsg channel. This is needed for handling the internal
299 * name service endpoint, which isn't bound to an rpmsg channel.
300 * See also __rpmsg_create_ept().
298 */ 301 */
299void rpmsg_destroy_ept(struct rpmsg_endpoint *ept) 302static void
303__rpmsg_destroy_ept(struct virtproc_info *vrp, struct rpmsg_endpoint *ept)
300{ 304{
301 struct virtproc_info *vrp = ept->rpdev->vrp;
302
303 mutex_lock(&vrp->endpoints_lock); 305 mutex_lock(&vrp->endpoints_lock);
304 idr_remove(&vrp->endpoints, ept->addr); 306 idr_remove(&vrp->endpoints, ept->addr);
305 mutex_unlock(&vrp->endpoints_lock); 307 mutex_unlock(&vrp->endpoints_lock);
306 308
307 kfree(ept); 309 kfree(ept);
308} 310}
311
312/**
313 * rpmsg_destroy_ept() - destroy an existing rpmsg endpoint
314 * @ept: endpoing to destroy
315 *
316 * Should be used by drivers to destroy an rpmsg endpoint previously
317 * created with rpmsg_create_ept().
318 */
319void rpmsg_destroy_ept(struct rpmsg_endpoint *ept)
320{
321 __rpmsg_destroy_ept(ept->rpdev->vrp, ept);
322}
309EXPORT_SYMBOL(rpmsg_destroy_ept); 323EXPORT_SYMBOL(rpmsg_destroy_ept);
310 324
311/* 325/*
@@ -764,6 +778,16 @@ static void rpmsg_recv_done(struct virtqueue *rvq)
764 print_hex_dump(KERN_DEBUG, "rpmsg_virtio RX: ", DUMP_PREFIX_NONE, 16, 1, 778 print_hex_dump(KERN_DEBUG, "rpmsg_virtio RX: ", DUMP_PREFIX_NONE, 16, 1,
765 msg, sizeof(*msg) + msg->len, true); 779 msg, sizeof(*msg) + msg->len, true);
766 780
781 /*
782 * We currently use fixed-sized buffers, so trivially sanitize
783 * the reported payload length.
784 */
785 if (len > RPMSG_BUF_SIZE ||
786 msg->len > (len - sizeof(struct rpmsg_hdr))) {
787 dev_warn(dev, "inbound msg too big: (%d, %d)\n", len, msg->len);
788 return;
789 }
790
767 /* use the dst addr to fetch the callback of the appropriate user */ 791 /* use the dst addr to fetch the callback of the appropriate user */
768 mutex_lock(&vrp->endpoints_lock); 792 mutex_lock(&vrp->endpoints_lock);
769 ept = idr_find(&vrp->endpoints, msg->dst); 793 ept = idr_find(&vrp->endpoints, msg->dst);
@@ -774,7 +798,8 @@ static void rpmsg_recv_done(struct virtqueue *rvq)
774 else 798 else
775 dev_warn(dev, "msg received with no recepient\n"); 799 dev_warn(dev, "msg received with no recepient\n");
776 800
777 sg_init_one(&sg, msg, sizeof(*msg) + len); 801 /* publish the real size of the buffer */
802 sg_init_one(&sg, msg, RPMSG_BUF_SIZE);
778 803
779 /* add the buffer back to the remote processor's virtqueue */ 804 /* add the buffer back to the remote processor's virtqueue */
780 err = virtqueue_add_buf(vrp->rvq, &sg, 0, 1, msg, GFP_KERNEL); 805 err = virtqueue_add_buf(vrp->rvq, &sg, 0, 1, msg, GFP_KERNEL);
@@ -891,8 +916,8 @@ static int rpmsg_probe(struct virtio_device *vdev)
891 if (!bufs_va) 916 if (!bufs_va)
892 goto vqs_del; 917 goto vqs_del;
893 918
894 dev_dbg(&vdev->dev, "buffers: va %p, dma 0x%x\n", bufs_va, 919 dev_dbg(&vdev->dev, "buffers: va %p, dma 0x%llx\n", bufs_va,
895 vrp->bufs_dma); 920 (unsigned long long)vrp->bufs_dma);
896 921
897 /* half of the buffers is dedicated for RX */ 922 /* half of the buffers is dedicated for RX */
898 vrp->rbufs = bufs_va; 923 vrp->rbufs = bufs_va;
@@ -964,6 +989,9 @@ static void __devexit rpmsg_remove(struct virtio_device *vdev)
964 if (ret) 989 if (ret)
965 dev_warn(&vdev->dev, "can't remove rpmsg device: %d\n", ret); 990 dev_warn(&vdev->dev, "can't remove rpmsg device: %d\n", ret);
966 991
992 if (vrp->ns_ept)
993 __rpmsg_destroy_ept(vrp, vrp->ns_ept);
994
967 idr_remove_all(&vrp->endpoints); 995 idr_remove_all(&vrp->endpoints);
968 idr_destroy(&vrp->endpoints); 996 idr_destroy(&vrp->endpoints);
969 997
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index ada4cb063dfe..f1ffabb978d3 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -41,48 +41,54 @@
41#include <linux/mutex.h> 41#include <linux/mutex.h>
42#include <linux/virtio.h> 42#include <linux/virtio.h>
43#include <linux/completion.h> 43#include <linux/completion.h>
44 44#include <linux/idr.h>
45/*
46 * The alignment between the consumer and producer parts of the vring.
47 * Note: this is part of the "wire" protocol. If you change this, you need
48 * to update your peers too.
49 */
50#define AMP_VRING_ALIGN (4096)
51 45
52/** 46/**
53 * struct fw_resource - describes an entry from the resource section 47 * struct resource_table - firmware resource table header
54 * @type: resource type 48 * @ver: version number
55 * @id: index number of the resource 49 * @num: number of resource entries
56 * @da: device address of the resource 50 * @reserved: reserved (must be zero)
57 * @pa: physical address of the resource 51 * @offset: array of offsets pointing at the various resource entries
58 * @len: size, in bytes, of the resource
59 * @flags: properties of the resource, e.g. iommu protection required
60 * @reserved: must be 0 atm
61 * @name: name of resource
62 * 52 *
63 * The remote processor firmware should contain a "resource table": 53 * A resource table is essentially a list of system resources required
64 * array of 'struct fw_resource' entries. 54 * by the remote processor. It may also include configuration entries.
55 * If needed, the remote processor firmware should contain this table
56 * as a dedicated ".resource_table" ELF section.
65 * 57 *
66 * Some resources entries are mere announcements, where the host is informed 58 * Some resources entries are mere announcements, where the host is informed
67 * of specific remoteproc configuration. Other entries require the host to 59 * of specific remoteproc configuration. Other entries require the host to
68 * do something (e.g. reserve a requested resource) and possibly also reply 60 * do something (e.g. allocate a system resource). Sometimes a negotiation
69 * by overwriting a member inside 'struct fw_resource' with info about the 61 * is expected, where the firmware requests a resource, and once allocated,
70 * allocated resource. 62 * the host should provide back its details (e.g. address of an allocated
71 * 63 * memory region).
72 * Different resource entries use different members of this struct, 64 *
73 * with different meanings. This is pretty limiting and error-prone, 65 * The header of the resource table, as expressed by this structure,
74 * so the plan is to move to variable-length TLV-based resource entries, 66 * contains a version number (should we need to change this format in the
75 * where each resource type will have its own structure. 67 * future), the number of available resource entries, and their offsets
68 * in the table.
69 *
70 * Immediately following this header are the resource entries themselves,
71 * each of which begins with a resource entry header (as described below).
76 */ 72 */
77struct fw_resource { 73struct resource_table {
74 u32 ver;
75 u32 num;
76 u32 reserved[2];
77 u32 offset[0];
78} __packed;
79
80/**
81 * struct fw_rsc_hdr - firmware resource entry header
82 * @type: resource type
83 * @data: resource data
84 *
85 * Every resource entry begins with a 'struct fw_rsc_hdr' header providing
86 * its @type. The content of the entry itself will immediately follow
87 * this header, and it should be parsed according to the resource type.
88 */
89struct fw_rsc_hdr {
78 u32 type; 90 u32 type;
79 u32 id; 91 u8 data[0];
80 u64 da;
81 u64 pa;
82 u32 len;
83 u32 flags;
84 u8 reserved[16];
85 u8 name[48];
86} __packed; 92} __packed;
87 93
88/** 94/**
@@ -92,30 +98,13 @@ struct fw_resource {
92 * memory region. 98 * memory region.
93 * @RSC_DEVMEM: request to iommu_map a memory-based peripheral. 99 * @RSC_DEVMEM: request to iommu_map a memory-based peripheral.
94 * @RSC_TRACE: announces the availability of a trace buffer into which 100 * @RSC_TRACE: announces the availability of a trace buffer into which
95 * the remote processor will be writing logs. In this case, 101 * the remote processor will be writing logs.
96 * 'da' indicates the device address where logs are written to, 102 * @RSC_VDEV: declare support for a virtio device, and serve as its
97 * and 'len' is the size of the trace buffer. 103 * virtio header.
98 * @RSC_VRING: request for allocation of a virtio vring (address should
99 * be indicated in 'da', and 'len' should contain the number
100 * of buffers supported by the vring).
101 * @RSC_VIRTIO_DEV: this entry declares about support for a virtio device,
102 * and serves as the virtio header. 'da' holds the
103 * the virtio device features, 'pa' holds the virtio guest
104 * features, 'len' holds the virtio status, and 'flags' holds
105 * the virtio id (currently only VIRTIO_ID_RPMSG is supported).
106 * @RSC_LAST: just keep this one at the end 104 * @RSC_LAST: just keep this one at the end
107 * 105 *
108 * Most of the resource entries share the basic idea of address/length 106 * For more details regarding a specific resource type, please see its
109 * negotiation with the host: the firmware usually asks (on behalf of the 107 * dedicated structure below.
110 * remote processor that will soon be booted with it) for memory
111 * of size 'len' bytes, and the host needs to allocate it and provide
112 * the device/physical address (when relevant) in 'da'/'pa' respectively.
113 *
114 * If the firmware is compiled with hard coded device addresses, and
115 * can't handle dynamically allocated 'da' values, then the 'da' field
116 * will contain the expected device addresses (today we actually only support
117 * this scheme, as there aren't yet any use cases for dynamically allocated
118 * device addresses).
119 * 108 *
120 * Please note that these values are used as indices to the rproc_handle_rsc 109 * Please note that these values are used as indices to the rproc_handle_rsc
121 * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to 110 * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to
@@ -126,11 +115,197 @@ enum fw_resource_type {
126 RSC_CARVEOUT = 0, 115 RSC_CARVEOUT = 0,
127 RSC_DEVMEM = 1, 116 RSC_DEVMEM = 1,
128 RSC_TRACE = 2, 117 RSC_TRACE = 2,
129 RSC_VRING = 3, 118 RSC_VDEV = 3,
130 RSC_VIRTIO_DEV = 4, 119 RSC_LAST = 4,
131 RSC_LAST = 5,
132}; 120};
133 121
122#define FW_RSC_ADDR_ANY (0xFFFFFFFFFFFFFFFF)
123
124/**
125 * struct fw_rsc_carveout - physically contiguous memory request
126 * @da: device address
127 * @pa: physical address
128 * @len: length (in bytes)
129 * @flags: iommu protection flags
130 * @reserved: reserved (must be zero)
131 * @name: human-readable name of the requested memory region
132 *
133 * This resource entry requests the host to allocate a physically contiguous
134 * memory region.
135 *
136 * These request entries should precede other firmware resource entries,
137 * as other entries might request placing other data objects inside
138 * these memory regions (e.g. data/code segments, trace resource entries, ...).
139 *
140 * Allocating memory this way helps utilizing the reserved physical memory
141 * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
142 * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
143 * pressure is important; it may have a substantial impact on performance.
144 *
145 * If the firmware is compiled with static addresses, then @da should specify
146 * the expected device address of this memory region. If @da is set to
147 * FW_RSC_ADDR_ANY, then the host will dynamically allocate it, and then
148 * overwrite @da with the dynamically allocated address.
149 *
150 * We will always use @da to negotiate the device addresses, even if it
151 * isn't using an iommu. In that case, though, it will obviously contain
152 * physical addresses.
153 *
154 * Some remote processors needs to know the allocated physical address
155 * even if they do use an iommu. This is needed, e.g., if they control
156 * hardware accelerators which access the physical memory directly (this
157 * is the case with OMAP4 for instance). In that case, the host will
158 * overwrite @pa with the dynamically allocated physical address.
159 * Generally we don't want to expose physical addresses if we don't have to
160 * (remote processors are generally _not_ trusted), so we might want to
161 * change this to happen _only_ when explicitly required by the hardware.
162 *
163 * @flags is used to provide IOMMU protection flags, and @name should
164 * (optionally) contain a human readable name of this carveout region
165 * (mainly for debugging purposes).
166 */
167struct fw_rsc_carveout {
168 u32 da;
169 u32 pa;
170 u32 len;
171 u32 flags;
172 u32 reserved;
173 u8 name[32];
174} __packed;
175
176/**
177 * struct fw_rsc_devmem - iommu mapping request
178 * @da: device address
179 * @pa: physical address
180 * @len: length (in bytes)
181 * @flags: iommu protection flags
182 * @reserved: reserved (must be zero)
183 * @name: human-readable name of the requested region to be mapped
184 *
185 * This resource entry requests the host to iommu map a physically contiguous
186 * memory region. This is needed in case the remote processor requires
187 * access to certain memory-based peripherals; _never_ use it to access
188 * regular memory.
189 *
190 * This is obviously only needed if the remote processor is accessing memory
191 * via an iommu.
192 *
193 * @da should specify the required device address, @pa should specify
194 * the physical address we want to map, @len should specify the size of
195 * the mapping and @flags is the IOMMU protection flags. As always, @name may
196 * (optionally) contain a human readable name of this mapping (mainly for
197 * debugging purposes).
198 *
199 * Note: at this point we just "trust" those devmem entries to contain valid
200 * physical addresses, but this isn't safe and will be changed: eventually we
201 * want remoteproc implementations to provide us ranges of physical addresses
202 * the firmware is allowed to request, and not allow firmwares to request
203 * access to physical addresses that are outside those ranges.
204 */
205struct fw_rsc_devmem {
206 u32 da;
207 u32 pa;
208 u32 len;
209 u32 flags;
210 u32 reserved;
211 u8 name[32];
212} __packed;
213
214/**
215 * struct fw_rsc_trace - trace buffer declaration
216 * @da: device address
217 * @len: length (in bytes)
218 * @reserved: reserved (must be zero)
219 * @name: human-readable name of the trace buffer
220 *
221 * This resource entry provides the host information about a trace buffer
222 * into which the remote processor will write log messages.
223 *
224 * @da specifies the device address of the buffer, @len specifies
225 * its size, and @name may contain a human readable name of the trace buffer.
226 *
227 * After booting the remote processor, the trace buffers are exposed to the
228 * user via debugfs entries (called trace0, trace1, etc..).
229 */
230struct fw_rsc_trace {
231 u32 da;
232 u32 len;
233 u32 reserved;
234 u8 name[32];
235} __packed;
236
237/**
238 * struct fw_rsc_vdev_vring - vring descriptor entry
239 * @da: device address
240 * @align: the alignment between the consumer and producer parts of the vring
241 * @num: num of buffers supported by this vring (must be power of two)
242 * @notifyid is a unique rproc-wide notify index for this vring. This notify
243 * index is used when kicking a remote processor, to let it know that this
244 * vring is triggered.
245 * @reserved: reserved (must be zero)
246 *
247 * This descriptor is not a resource entry by itself; it is part of the
248 * vdev resource type (see below).
249 *
250 * Note that @da should either contain the device address where
251 * the remote processor is expecting the vring, or indicate that
252 * dynamically allocation of the vring's device address is supported.
253 */
254struct fw_rsc_vdev_vring {
255 u32 da;
256 u32 align;
257 u32 num;
258 u32 notifyid;
259 u32 reserved;
260} __packed;
261
262/**
263 * struct fw_rsc_vdev - virtio device header
264 * @id: virtio device id (as in virtio_ids.h)
265 * @notifyid is a unique rproc-wide notify index for this vdev. This notify
266 * index is used when kicking a remote processor, to let it know that the
267 * status/features of this vdev have changes.
268 * @dfeatures specifies the virtio device features supported by the firmware
269 * @gfeatures is a place holder used by the host to write back the
270 * negotiated features that are supported by both sides.
271 * @config_len is the size of the virtio config space of this vdev. The config
272 * space lies in the resource table immediate after this vdev header.
273 * @status is a place holder where the host will indicate its virtio progress.
274 * @num_of_vrings indicates how many vrings are described in this vdev header
275 * @reserved: reserved (must be zero)
276 * @vring is an array of @num_of_vrings entries of 'struct fw_rsc_vdev_vring'.
277 *
278 * This resource is a virtio device header: it provides information about
279 * the vdev, and is then used by the host and its peer remote processors
280 * to negotiate and share certain virtio properties.
281 *
282 * By providing this resource entry, the firmware essentially asks remoteproc
283 * to statically allocate a vdev upon registration of the rproc (dynamic vdev
284 * allocation is not yet supported).
285 *
286 * Note: unlike virtualization systems, the term 'host' here means
287 * the Linux side which is running remoteproc to control the remote
288 * processors. We use the name 'gfeatures' to comply with virtio's terms,
289 * though there isn't really any virtualized guest OS here: it's the host
290 * which is responsible for negotiating the final features.
291 * Yeah, it's a bit confusing.
292 *
293 * Note: immediately following this structure is the virtio config space for
294 * this vdev (which is specific to the vdev; for more info, read the virtio
295 * spec). the size of the config space is specified by @config_len.
296 */
297struct fw_rsc_vdev {
298 u32 id;
299 u32 notifyid;
300 u32 dfeatures;
301 u32 gfeatures;
302 u32 config_len;
303 u8 status;
304 u8 num_of_vrings;
305 u8 reserved[2];
306 struct fw_rsc_vdev_vring vring[0];
307} __packed;
308
134/** 309/**
135 * struct rproc_mem_entry - memory entry descriptor 310 * struct rproc_mem_entry - memory entry descriptor
136 * @va: virtual address 311 * @va: virtual address
@@ -144,7 +319,7 @@ struct rproc_mem_entry {
144 void *va; 319 void *va;
145 dma_addr_t dma; 320 dma_addr_t dma;
146 int len; 321 int len;
147 u64 da; 322 u32 da;
148 void *priv; 323 void *priv;
149 struct list_head node; 324 struct list_head node;
150}; 325};
@@ -206,7 +381,8 @@ enum rproc_state {
206 * @mappings: list of iommu mappings we initiated, needed on shutdown 381 * @mappings: list of iommu mappings we initiated, needed on shutdown
207 * @firmware_loading_complete: marks e/o asynchronous firmware loading 382 * @firmware_loading_complete: marks e/o asynchronous firmware loading
208 * @bootaddr: address of first instruction to boot rproc with (optional) 383 * @bootaddr: address of first instruction to boot rproc with (optional)
209 * @rvdev: virtio device (we only support a single rpmsg virtio device for now) 384 * @rvdevs: list of remote virtio devices
385 * @notifyids: idr for dynamically assigning rproc-wide unique notify ids
210 */ 386 */
211struct rproc { 387struct rproc {
212 struct klist_node node; 388 struct klist_node node;
@@ -226,24 +402,50 @@ struct rproc {
226 struct list_head carveouts; 402 struct list_head carveouts;
227 struct list_head mappings; 403 struct list_head mappings;
228 struct completion firmware_loading_complete; 404 struct completion firmware_loading_complete;
229 u64 bootaddr; 405 u32 bootaddr;
406 struct list_head rvdevs;
407 struct idr notifyids;
408};
409
410/* we currently support only two vrings per rvdev */
411#define RVDEV_NUM_VRINGS 2
412
413/**
414 * struct rproc_vring - remoteproc vring state
415 * @va: virtual address
416 * @dma: dma address
417 * @len: length, in bytes
418 * @da: device address
419 * @align: vring alignment
420 * @notifyid: rproc-specific unique vring index
421 * @rvdev: remote vdev
422 * @vq: the virtqueue of this vring
423 */
424struct rproc_vring {
425 void *va;
426 dma_addr_t dma;
427 int len;
428 u32 da;
429 u32 align;
430 int notifyid;
230 struct rproc_vdev *rvdev; 431 struct rproc_vdev *rvdev;
432 struct virtqueue *vq;
231}; 433};
232 434
233/** 435/**
234 * struct rproc_vdev - remoteproc state for a supported virtio device 436 * struct rproc_vdev - remoteproc state for a supported virtio device
437 * @node: list node
235 * @rproc: the rproc handle 438 * @rproc: the rproc handle
236 * @vdev: the virio device 439 * @vdev: the virio device
237 * @vq: the virtqueues for this vdev
238 * @vring: the vrings for this vdev 440 * @vring: the vrings for this vdev
239 * @dfeatures: virtio device features 441 * @dfeatures: virtio device features
240 * @gfeatures: virtio guest features 442 * @gfeatures: virtio guest features
241 */ 443 */
242struct rproc_vdev { 444struct rproc_vdev {
445 struct list_head node;
243 struct rproc *rproc; 446 struct rproc *rproc;
244 struct virtio_device vdev; 447 struct virtio_device vdev;
245 struct virtqueue *vq[2]; 448 struct rproc_vring vring[RVDEV_NUM_VRINGS];
246 struct rproc_mem_entry vring[2];
247 unsigned long dfeatures; 449 unsigned long dfeatures;
248 unsigned long gfeatures; 450 unsigned long gfeatures;
249}; 451};
@@ -261,9 +463,14 @@ int rproc_unregister(struct rproc *rproc);
261int rproc_boot(struct rproc *rproc); 463int rproc_boot(struct rproc *rproc);
262void rproc_shutdown(struct rproc *rproc); 464void rproc_shutdown(struct rproc *rproc);
263 465
466static inline struct rproc_vdev *vdev_to_rvdev(struct virtio_device *vdev)
467{
468 return container_of(vdev, struct rproc_vdev, vdev);
469}
470
264static inline struct rproc *vdev_to_rproc(struct virtio_device *vdev) 471static inline struct rproc *vdev_to_rproc(struct virtio_device *vdev)
265{ 472{
266 struct rproc_vdev *rvdev = container_of(vdev, struct rproc_vdev, vdev); 473 struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
267 474
268 return rvdev->rproc; 475 return rvdev->rproc;
269} 476}