mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 09:11:26 +03:00
video: tegra: nvmap: Add new heap for VI mempool
- The VI is allowed to access the whole of the Guest VM currently as it is a stage-2 SMMU device. Hence it can read and write to any memory. This may lead to breach of confidentiality and integrity. In order to restrict the VI from accessing the whole VM, a mempool is being created by HV that would restrict access to VI to just the mempool memory. - In nvmap, we have some special rules for IVM carveout like if user specify IVM carveout to allocate from, then if first IVM carveout does not have sufficient memory then nvmap tries to allocate from next IVM carveout. We don't want these rules applicable for VI mempool heap, hence only carveout initialization part would remain similar to IVM carveouts but rest of the operations would be performed normally like any other carveout. - Add DT binding doc for VI-carveout. Bug 4648721 Change-Id: Ib40415a4c80da908654c86162c1cd4b50b33ef31 Signed-off-by: Ketan Patil <ketanp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3196238 Reviewed-by: Pritesh Raithatha <praithatha@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
# Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms and conditions of the GNU General Public License,
|
||||
# version 2, as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
# more details.
|
||||
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/vi-carveout/nvidia,vi-carveout.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Nvidia VI Carveout
|
||||
|
||||
maintainers:
|
||||
- Ketan Patil
|
||||
|
||||
description: |
|
||||
This schema defines the properties for the NVIDIA VI carveout (mempool) memory
|
||||
node. The reference to this DT node should be added memory-region in tegra carveout
|
||||
to create the VI carveout.
|
||||
|
||||
select:
|
||||
properties:
|
||||
compatible:
|
||||
minItems: 1
|
||||
maxItems: 1
|
||||
items:
|
||||
enum:
|
||||
- nvidia,vi_carveout
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
properties:
|
||||
ivm:
|
||||
description: |
|
||||
A phandle to the tegra-hv node followed by the mempool id.
|
||||
items:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
items:
|
||||
- $ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
- $ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
|
||||
status:
|
||||
description: |
|
||||
The status of the carveouts node.
|
||||
enum:
|
||||
- okay
|
||||
- disabled
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- ivm
|
||||
|
||||
examples:
|
||||
- |
|
||||
vi-carveout {
|
||||
compatible = "nvidia,vi_carveout";
|
||||
ivm = <&tegra_hv 3>;
|
||||
status = "okay";
|
||||
};
|
||||
@@ -6,15 +6,16 @@
|
||||
|
||||
#include <linux/miscdevice.h>
|
||||
|
||||
#define NVMAP_HEAP_IOVMM (1ul<<30)
|
||||
#define NVMAP_HEAP_IOVMM (1ul << 30)
|
||||
/* common carveout heaps */
|
||||
#define NVMAP_HEAP_CARVEOUT_VPR (1ul<<28)
|
||||
#define NVMAP_HEAP_CARVEOUT_TSEC (1ul<<27)
|
||||
#define NVMAP_HEAP_CARVEOUT_VIDMEM (1ul<<26)
|
||||
#define NVMAP_HEAP_CARVEOUT_GPU (1ul << 3)
|
||||
#define NVMAP_HEAP_CARVEOUT_FSI (1ul<<2)
|
||||
#define NVMAP_HEAP_CARVEOUT_IVM (1ul<<1)
|
||||
#define NVMAP_HEAP_CARVEOUT_GENERIC (1ul<<0)
|
||||
#define NVMAP_HEAP_CARVEOUT_VPR (1ul << 28)
|
||||
#define NVMAP_HEAP_CARVEOUT_TSEC (1ul << 27)
|
||||
#define NVMAP_HEAP_CARVEOUT_VIDMEM (1ul << 26)
|
||||
#define NVMAP_HEAP_CARVEOUT_VI (1ul << 4)
|
||||
#define NVMAP_HEAP_CARVEOUT_GPU (1ul << 3)
|
||||
#define NVMAP_HEAP_CARVEOUT_FSI (1ul << 2)
|
||||
#define NVMAP_HEAP_CARVEOUT_IVM (1ul << 1)
|
||||
#define NVMAP_HEAP_CARVEOUT_GENERIC (1ul << 0)
|
||||
|
||||
#define NVMAP_HEAP_CARVEOUT_MASK (NVMAP_HEAP_IOVMM - 1)
|
||||
|
||||
|
||||
@@ -91,12 +91,14 @@ static struct nvmap_platform_carveout nvmap_carveouts[] = {
|
||||
.size = 0,
|
||||
.numa_node_id = 0,
|
||||
},
|
||||
/* Need uninitialized entries for IVM carveouts */
|
||||
[5] = {
|
||||
.name = NULL,
|
||||
.usage_mask = NVMAP_HEAP_CARVEOUT_IVM,
|
||||
.name = "vimem",
|
||||
.usage_mask = NVMAP_HEAP_CARVEOUT_VI,
|
||||
.base = 0,
|
||||
.size = 0,
|
||||
.numa_node_id = 0,
|
||||
},
|
||||
/* Need uninitialized entries for IVM carveouts */
|
||||
[6] = {
|
||||
.name = NULL,
|
||||
.usage_mask = NVMAP_HEAP_CARVEOUT_IVM,
|
||||
@@ -112,11 +114,16 @@ static struct nvmap_platform_carveout nvmap_carveouts[] = {
|
||||
.usage_mask = NVMAP_HEAP_CARVEOUT_IVM,
|
||||
.numa_node_id = 0,
|
||||
},
|
||||
[9] = {
|
||||
.name = NULL,
|
||||
.usage_mask = NVMAP_HEAP_CARVEOUT_IVM,
|
||||
.numa_node_id = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static struct nvmap_platform_data nvmap_data = {
|
||||
.carveouts = nvmap_carveouts,
|
||||
.nr_carveouts = 5,
|
||||
.nr_carveouts = 6,
|
||||
};
|
||||
|
||||
static struct nvmap_platform_carveout *nvmap_get_carveout_pdata(const char *name)
|
||||
@@ -149,12 +156,21 @@ static int __init nvmap_populate_ivm_carveout(struct device *dev)
|
||||
struct tegra_hv_ivm_cookie *ivm;
|
||||
unsigned long long id;
|
||||
unsigned int guestid, result;
|
||||
bool is_vi_heap;
|
||||
|
||||
if (!of_phandle_iterator_init(&it, dev->of_node, "memory-region", NULL, 0)) {
|
||||
while (!of_phandle_iterator_next(&it) && it.node) {
|
||||
if (of_device_is_available(it.node) &&
|
||||
of_device_is_compatible(it.node, "nvidia,ivm_carveout") > 0) {
|
||||
co = nvmap_get_carveout_pdata("nvidia,ivm_carveout");
|
||||
is_vi_heap = false;
|
||||
if (of_device_is_available(it.node)) {
|
||||
if (of_device_is_compatible(it.node, "nvidia,ivm_carveout") > 0) {
|
||||
co = nvmap_get_carveout_pdata("nvidia,ivm_carveout");
|
||||
} else if (of_device_is_compatible(it.node,
|
||||
"nvidia,vi_carveout") > 0) {
|
||||
co = nvmap_get_carveout_pdata("vimem");
|
||||
is_vi_heap = true;
|
||||
} else
|
||||
continue;
|
||||
|
||||
if (!co) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
@@ -198,25 +214,29 @@ static int __init nvmap_populate_ivm_carveout(struct device *dev)
|
||||
/* See if this VM can allocate (or just create handle from ID)
|
||||
* generated by peer partition
|
||||
*/
|
||||
prop = of_get_property(it.node, "alloc", NULL);
|
||||
if (!prop) {
|
||||
pr_err("failed to read alloc property\n");
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
if (!is_vi_heap) {
|
||||
prop = of_get_property(it.node, "alloc", NULL);
|
||||
if (!prop) {
|
||||
pr_err("failed to read alloc property\n");
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
name = kzalloc(32, GFP_KERNEL);
|
||||
if (!name) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
name = kzalloc(32, GFP_KERNEL);
|
||||
if (!name) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
co->can_alloc = of_read_number(prop, 1);
|
||||
co->is_ivm = true;
|
||||
sprintf(name, "ivm%02u%02u%02d", co->vmid, co->peer, co->can_alloc);
|
||||
pr_info("IVM carveout IPA:%p, size=%zu, peer vmid=%u, name=%s\n",
|
||||
(void *)(uintptr_t)co->base, co->size, co->peer, name);
|
||||
co->name = name;
|
||||
co->can_alloc = of_read_number(prop, 1);
|
||||
co->is_ivm = true;
|
||||
sprintf(name, "ivm%02u%02u%02d", co->vmid, co->peer,
|
||||
co->can_alloc);
|
||||
pr_info("IVM carveout IPA:%p, size=%zu, peer vmid=%u,"
|
||||
"name=%s\n", (void *)(uintptr_t)co->base, co->size,
|
||||
co->peer, name);
|
||||
co->name = name;
|
||||
}
|
||||
|
||||
if (check_add_overflow(nvmap_data.nr_carveouts, 1U, &result)) {
|
||||
co->name = NULL;
|
||||
@@ -226,12 +246,12 @@ static int __init nvmap_populate_ivm_carveout(struct device *dev)
|
||||
}
|
||||
|
||||
nvmap_data.nr_carveouts = result;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
(void)tegra_hv_mempool_unreserve(ivm);
|
||||
co->base = 0;
|
||||
co->peer = 0;
|
||||
co->size = 0;
|
||||
@@ -381,7 +401,8 @@ int __init nvmap_init(struct platform_device *pdev)
|
||||
if (!of_phandle_iterator_init(&it, np, "memory-region", NULL, 0)) {
|
||||
while (!of_phandle_iterator_next(&it) && it.node) {
|
||||
if (of_device_is_available(it.node) &&
|
||||
!of_device_is_compatible(it.node, "nvidia,ivm_carveout")) {
|
||||
!of_device_is_compatible(it.node, "nvidia,ivm_carveout") &&
|
||||
!of_device_is_compatible(it.node, "nvidia,vi_carveout")) {
|
||||
rmem2 = of_reserved_mem_lookup(it.node);
|
||||
if (!rmem2) {
|
||||
if (!of_property_read_string(it.node, "compatible", &compp))
|
||||
|
||||
Reference in New Issue
Block a user