diff options
author | Aurora pro automerger <aurora-pro-automerger@google.com> | 2023-02-02 11:46:21 +0000 |
---|---|---|
committer | davidchiang <davidchiang@google.com> | 2023-02-02 12:17:17 +0000 |
commit | 51c89d9e9a7664ff4068fa1405fca5a5fe60aac0 (patch) | |
tree | 8fa3c34a8dee0d30896f6efc3effa8f86d313e42 /gcip-kernel-driver/drivers | |
parent | 8a4b0d93e1f8b9ae23fb476eef4d43f18bc3cc1d (diff) | |
download | gs201-51c89d9e9a7664ff4068fa1405fca5a5fe60aac0.tar.gz |
gxp: [Copybara Auto Merge] Merge branch 'gs201-u' into 'android13-gs-pixel-5.10-udc'android-u-preview-2_r0.4android-u-preview-2_r0.3android-gs-pantah-5.10-u-preview-2android-gs-bluejay-5.10-u-preview-2
gcip: use v*alloc without node
GCIP_MAIN_REV_ID: e48d8c14dff78d70064f93e5faee61c17b0479c2
gxp: create debug dir root earlier on probe
gxp: fix code style/formatting issues
gxp: Implement debug dump handling for mcu mode
Bug: 265092842
gcip: fix code style/formatting issues
GCIP_HEADERS_REV_ID: 8f57799df52bf60cb1805ab5e9ee48034bb139c8
gcip: expose config size calculation to header
Bug: 265605775
gcip: sync RKCI codes with fw
gcip: update comments of gcip_dma_fence_init
Bug: 264220687
gcip: add to_gcip_fence to gcip-dma-fence
Bug: 264220687 (repeat)
gcip: fix GCIP_DMA_FENCE_LIST_UNLOCK
Bug: 258876786
gcip: correct path of gcip-dma-fence.h
Bug: 258876786 (repeat)
gcip: add gcip-dma-fence.h
Bug: 258876786 (repeat)
gcip: introduce firmware crash type
Bug: 237739631
GCIP_HEADERS_REV_ID: 0a85dc4b06195de6efa46e2ca314548f07f30097
gxp: move core config region to second half of buf
gxp: boot status and doorbell for suspend/resume
Bug: 265742153
gxp: set VD and core config region
Bug: 265742153 (repeat)
gxp: use core cfg region for firmware handshake
Bug: 265742153 (repeat)
gxp: boot with virt_core on per-VD config method
Bug: 265742153 (repeat)
gxp: only map fwdata region in legacy protocol
Bug: 265742153 (repeat)
gxp: populate system config on fw data create
Bug: 265742153 (repeat)
gxp: flush SGT after map iova sgt
Bug: 265564221
gxp: remove gxp_vd_phys_core_list
gxp: signal eventfd when client is invalidated
Bug: 264830822
gxp: introduce GXP_(UN)REGISTER_INVALIDATED_EVENTFD ioctl
Bug: 264830822 (repeat)
gxp: add create/destroy app legacy functions
Bug: 265742153 (repeat)
gxp: pass vd to fw_data_create_app
Bug: 265742153 (repeat)
gxp: add structures for new app config
Bug: 265742153 (repeat)
gxp: add sys_cfg mapping support
Bug: 265605775 (repeat)
gxp: all chips/modes have shared region
Bug: 265605775 (repeat)
gxp: map config regions per image config
Bug: 265605775 (repeat)
gxp: set shared_buf vaddr
Bug: 265605775 (repeat)
gxp: map image config NS mappings
Bug: 265564221 (repeat)
gxp: use per VD scratchpad region
Bug: 261797596
gxp: conditionally map FW image region
Bug: 265105395
gxp: add lock_class_key to struct client
gxp: add image config parser to VD
Bug: 265105395 (repeat)
gxp: record image config on firmware requested
Bug: 265105395 (repeat)
gxp: add missing up_read in gxp_debugfs_mailbox
gxp: implement vd invalidation
Bug: 264831024
gxp: pass timeout_ms to gxp_pm_is_blk_down
gxp: set is_firmware_requested on SysFS FW load
gxp: set SSMT to bypass in MCU mode
Bug: 264950137
Revert "gxp: fetch segment boundaries from ELF header"
gxp: add gcip_dma_fence_manager to gxp_dev
Bug: 258876786 (repeat)
gxp: add gxp-dma-fence support
Bug: 258876786 (repeat)
gxp: introduce GXP_NAME macro
gxp: return vdid on VD allocation ioctl
Bug: 264827584
gxp: add VDID support
Bug: 264827584 (repeat)
gxp: remove a cleanup TODO from vd.h
gxp: add refcount to virtual device
Bug: 264739996
gxp: add sync fence interfaces
Bug: 258876786 (repeat)
gxp: detach vd->domain when the state is invalid
Bug: 263830035
gxp: call vd_block_unready when failed to run core fw
Bug: 263830035 (repeat)
gxp: apply clang-format to gxp-vd.c
Bug: 263830035 (repeat)
gxp: allow debugfs mailbox only with valid vd
Bug: 264629015
gxp: add debugfs_client to client_list
Bug: 264629015 (repeat)
gxp: hold vd_semaphore only when direct mode
Bug: 263830035 (repeat)
gxp: fix vd_semaphore locking
Bug: 263215610
gxp: revert VD state on after_vd_block_ready fail
Bug: 263215610 (repeat)
gcip: conditionally zero the non-contiguous region
gcip: expose config size calculation to header
Bug: 265605775 (repeat)
gcip: Use strscpy instead of memcpy
gcip: enhance image config NS mapping decoding
Bug: 265565307
gcip: don't fail dma_fence_init on long name
Bug: 264220687 (repeat)
gcip: implement gcip_dma_fence_show
Bug: 264220687 (repeat)
gcip: implement DMA fence status and signal
Bug: 264220687 (repeat)
gcip: add gcip-dma-fence.c
Bug: 258876786 (repeat)
GCIP_MAIN_REV_ID: 0a2e7b7e345705db78c8108890781cbe5c8c4eb7
GitOrigin-RevId: 277fffe779cbaf54c2d811928835e9a5ec67e832
Change-Id: Ied761f3000df6a44856db9438d21afd9b3ccb9aa
Diffstat (limited to 'gcip-kernel-driver/drivers')
-rw-r--r-- | gcip-kernel-driver/drivers/gcip/Makefile | 10 | ||||
-rw-r--r-- | gcip-kernel-driver/drivers/gcip/gcip-alloc-helper.c | 6 | ||||
-rw-r--r-- | gcip-kernel-driver/drivers/gcip/gcip-dma-fence.c | 196 | ||||
-rw-r--r-- | gcip-kernel-driver/drivers/gcip/gcip-image-config.c | 42 |
4 files changed, 219 insertions, 35 deletions
diff --git a/gcip-kernel-driver/drivers/gcip/Makefile b/gcip-kernel-driver/drivers/gcip/Makefile index c3424ee..ab68776 100644 --- a/gcip-kernel-driver/drivers/gcip/Makefile +++ b/gcip-kernel-driver/drivers/gcip/Makefile @@ -6,8 +6,14 @@ CONFIG_GCIP ?= m obj-$(CONFIG_GCIP) += gcip.o -gcip-objs := gcip-alloc-helper.o gcip-domain-pool.o gcip-firmware.o \ - gcip-image-config.o gcip-kci.o gcip-mailbox.o gcip-mem-pool.o \ +gcip-objs := gcip-alloc-helper.o \ + gcip-dma-fence.o \ + gcip-domain-pool.o \ + gcip-firmware.o \ + gcip-image-config.o \ + gcip-kci.o \ + gcip-mailbox.o \ + gcip-mem-pool.o \ gcip-telemetry.o CURRENT_DIR=$(dir $(abspath $(lastword $(MAKEFILE_LIST)))) diff --git a/gcip-kernel-driver/drivers/gcip/gcip-alloc-helper.c b/gcip-kernel-driver/drivers/gcip/gcip-alloc-helper.c index 33c95e2..85af8e5 100644 --- a/gcip-kernel-driver/drivers/gcip/gcip-alloc-helper.c +++ b/gcip-kernel-driver/drivers/gcip/gcip-alloc-helper.c @@ -7,6 +7,7 @@ #include <asm/page.h> #include <linux/device.h> +#include <linux/gfp.h> #include <linux/mm_types.h> #include <linux/scatterlist.h> #include <linux/slab.h> @@ -47,7 +48,10 @@ struct sg_table *gcip_alloc_noncontiguous(struct device *dev, size_t size, gfp_t size = PAGE_ALIGN(size); count = size >> PAGE_SHIFT; - mem = vzalloc_node(size, dev_to_node(dev)); + if (gfp & __GFP_ZERO) + mem = vzalloc(size); + else + mem = vmalloc(size); if (!mem) { dev_err(dev, "GCIP noncontiguous alloc size=%#zx failed", size); goto err_free_sh; diff --git a/gcip-kernel-driver/drivers/gcip/gcip-dma-fence.c b/gcip-kernel-driver/drivers/gcip/gcip-dma-fence.c new file mode 100644 index 0000000..4f83670 --- /dev/null +++ b/gcip-kernel-driver/drivers/gcip/gcip-dma-fence.c @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * GCIP support of DMA fences. + * + * Copyright (C) 2023 Google LLC + */ + +#include <linux/bitops.h> +#include <linux/device.h> +#include <linux/dma-fence.h> +#include <linux/err.h> +#include <linux/file.h> +#include <linux/ktime.h> +#include <linux/list.h> +#include <linux/seq_file.h> +#include <linux/spinlock.h> +#include <linux/string.h> +#include <linux/sync_file.h> +#include <linux/time.h> + +#include <gcip/gcip-dma-fence.h> + +#define to_gfence(fence) container_of(fence, struct gcip_dma_fence, fence) + +static int _gcip_dma_fence_signal(struct dma_fence *fence, int error, bool ignore_signaled) +{ + int ret; + + if (error > 0) + error = -error; + if (unlikely(error < -MAX_ERRNO)) + return -EINVAL; + + spin_lock_irq(fence->lock); + /* don't signal fence twice */ + if (unlikely(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))) { + ret = ignore_signaled ? 0 : -EBUSY; + goto out_unlock; + } + if (error) + dma_fence_set_error(fence, error); + ret = dma_fence_signal_locked(fence); + +out_unlock: + spin_unlock_irq(fence->lock); + return ret; +} + +static const char *sync_status_str(int status) +{ + if (status < 0) + return "error"; + if (status > 0) + return "signaled"; + return "active"; +} + +struct gcip_dma_fence_manager *gcip_dma_fence_manager_create(struct device *dev) +{ + struct gcip_dma_fence_manager *mgr = devm_kzalloc(dev, sizeof(*mgr), GFP_KERNEL); + + if (!mgr) + return ERR_PTR(-ENOMEM); + + INIT_LIST_HEAD(&mgr->fence_list_head); + spin_lock_init(&mgr->fence_list_lock); + mgr->dev = dev; + + return mgr; +} + +const char *gcip_dma_fence_get_timeline_name(struct dma_fence *fence) +{ + struct gcip_dma_fence *gfence = to_gfence(fence); + + return gfence->timeline_name; +} + +bool gcip_dma_fence_always_true(struct dma_fence *fence) +{ + return true; +} + +int gcip_dma_fence_init(struct gcip_dma_fence_manager *mgr, struct gcip_dma_fence *gfence, + struct gcip_dma_fence_data *data) +{ + unsigned long flags; + int fd; + struct sync_file *sync_file; + int ret; + + strscpy(gfence->timeline_name, data->timeline_name, GCIP_FENCE_TIMELINE_NAME_LEN); + + spin_lock_init(&gfence->lock); + INIT_LIST_HEAD(&gfence->fence_list); + gfence->mgr = mgr; + + dma_fence_init(&gfence->fence, data->ops, &gfence->lock, dma_fence_context_alloc(1), + data->seqno); + GCIP_DMA_FENCE_LIST_LOCK(mgr, flags); + list_add_tail(&gfence->fence_list, &mgr->fence_list_head); + GCIP_DMA_FENCE_LIST_UNLOCK(mgr, flags); + + if (data->after_init) { + ret = data->after_init(gfence); + if (ret) { + dev_err(mgr->dev, "DMA fence init failed on after_init: %d", ret); + goto err_put_fence; + } + } + fd = get_unused_fd_flags(O_CLOEXEC); + if (fd < 0) { + ret = fd; + dev_err(mgr->dev, "Failed to get FD: %d", ret); + goto err_put_fence; + } + sync_file = sync_file_create(&gfence->fence); + if (!sync_file) { + dev_err(mgr->dev, "Failed to create sync file"); + ret = -ENOMEM; + goto err_put_fd; + } + /* sync_file holds the reference to fence, so we can drop our reference. */ + dma_fence_put(&gfence->fence); + + fd_install(fd, sync_file->file); + data->fence = fd; + return 0; + +err_put_fd: + put_unused_fd(fd); +err_put_fence: + dma_fence_put(&gfence->fence); + return ret; +} + +void gcip_dma_fence_exit(struct gcip_dma_fence *gfence) +{ + unsigned long flags; + + GCIP_DMA_FENCE_LIST_LOCK(gfence->mgr, flags); + list_del(&gfence->fence_list); + GCIP_DMA_FENCE_LIST_UNLOCK(gfence->mgr, flags); +} + +int gcip_dma_fence_status(int fence, int *status) +{ + struct dma_fence *fencep; + + fencep = sync_file_get_fence(fence); + if (!fencep) + return -EBADF; + *status = dma_fence_get_status(fencep); + dma_fence_put(fencep); + return 0; +} + +int gcip_dma_fence_signal(int fence, int error, bool ignore_signaled) +{ + struct dma_fence *fencep; + int ret; + + fencep = sync_file_get_fence(fence); + if (!fencep) + return -EBADF; + ret = _gcip_dma_fence_signal(fencep, error, ignore_signaled); + dma_fence_put(fencep); + return ret; +} + +int gcip_dma_fenceptr_signal(struct gcip_dma_fence *gfence, int error, bool ignore_signaled) +{ + return _gcip_dma_fence_signal(&gfence->fence, error, ignore_signaled); +} + +void gcip_dma_fence_show(struct gcip_dma_fence *gfence, struct seq_file *s) +{ + struct dma_fence *fence = &gfence->fence; + + spin_lock_irq(&gfence->lock); + + seq_printf(s, "%s-%s %llu-%llu %s", fence->ops->get_driver_name(fence), + fence->ops->get_timeline_name(fence), fence->context, fence->seqno, + sync_status_str(dma_fence_get_status_locked(fence))); + + if (test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags)) { + struct timespec64 ts = ktime_to_timespec64(fence->timestamp); + + seq_printf(s, " @%lld.%09ld", (s64)ts.tv_sec, ts.tv_nsec); + } + + if (fence->error) + seq_printf(s, " err=%d", fence->error); + + spin_unlock_irq(&gfence->lock); +} diff --git a/gcip-kernel-driver/drivers/gcip/gcip-image-config.c b/gcip-kernel-driver/drivers/gcip/gcip-image-config.c index 312bbdc..62acd0b 100644 --- a/gcip-kernel-driver/drivers/gcip/gcip-image-config.c +++ b/gcip-kernel-driver/drivers/gcip/gcip-image-config.c @@ -12,28 +12,6 @@ #include <gcip/gcip-image-config.h> -#define ADDR_SHIFT 12 -#define SIZE_MODE_BIT BIT(ADDR_SHIFT - 1) -#define SECURE_SIZE_MASK (SIZE_MODE_BIT - 1u) -#define NS_SIZE_MASK (BIT(ADDR_SHIFT) - 1u) -#define ADDR_MASK ~(BIT(ADDR_SHIFT) - 1u) - -/* used by ns_iommu_mappings */ -#define CONFIG_TO_MBSIZE(a) (((a) & NS_SIZE_MASK) << 20) - -/* used by iommu_mappings */ -static inline __u32 config_to_size(__u32 cfg) -{ - __u32 page_size; - - if (cfg & SIZE_MODE_BIT) - page_size = cfg & SECURE_SIZE_MASK; - else - page_size = BIT(cfg & SECURE_SIZE_MASK); - - return page_size << PAGE_SHIFT; -} - static int setup_iommu_mappings(struct gcip_image_config_parser *parser, struct gcip_image_config *config) { @@ -49,8 +27,8 @@ static int setup_iommu_mappings(struct gcip_image_config_parser *parser, ret = -EIO; goto err; } - size = config_to_size(config->iommu_mappings[i].image_config_value); - paddr = config->iommu_mappings[i].image_config_value & ADDR_MASK; + size = gcip_config_to_size(config->iommu_mappings[i].image_config_value); + paddr = config->iommu_mappings[i].image_config_value & GCIP_IMG_CFG_ADDR_MASK; dev_dbg(parser->dev, "Image config adding IOMMU mapping: %pad -> %pap", &daddr, &paddr); @@ -74,7 +52,7 @@ static int setup_iommu_mappings(struct gcip_image_config_parser *parser, err: while (i--) { daddr = config->iommu_mappings[i].virt_address; - size = config_to_size(config->iommu_mappings[i].image_config_value); + size = gcip_config_to_size(config->iommu_mappings[i].image_config_value); parser->ops->unmap(parser->data, daddr, size, GCIP_IMAGE_CONFIG_FLAGS_SECURE); } return ret; @@ -89,7 +67,7 @@ static void clear_iommu_mappings(struct gcip_image_config_parser *parser, for (i = config->num_iommu_mappings - 1; i >= 0; i--) { daddr = config->iommu_mappings[i].virt_address; - size = config_to_size(config->iommu_mappings[i].image_config_value); + size = gcip_config_to_size(config->iommu_mappings[i].image_config_value); dev_dbg(parser->dev, "Image config removing IOMMU mapping: %pad size=%#lx", &daddr, size); parser->ops->unmap(parser->data, daddr, size, GCIP_IMAGE_CONFIG_FLAGS_SECURE); @@ -105,13 +83,13 @@ static int setup_ns_iommu_mappings(struct gcip_image_config_parser *parser, phys_addr_t paddr = 0; for (i = 0; i < config->num_ns_iommu_mappings; i++) { - daddr = config->ns_iommu_mappings[i] & ADDR_MASK; + daddr = config->ns_iommu_mappings[i] & GCIP_IMG_CFG_ADDR_MASK; if (unlikely(!daddr)) { dev_warn(parser->dev, "Invalid config, device address is zero"); ret = -EIO; goto err; } - size = CONFIG_TO_MBSIZE(config->ns_iommu_mappings[i]); + size = gcip_ns_config_to_size(config->ns_iommu_mappings[i]); dev_dbg(parser->dev, "Image config adding NS IOMMU mapping: %pad -> %pap", &daddr, &paddr); if (unlikely(daddr + size <= daddr || paddr + size <= paddr)) { @@ -128,8 +106,8 @@ static int setup_ns_iommu_mappings(struct gcip_image_config_parser *parser, err: while (i--) { - size = CONFIG_TO_MBSIZE(config->ns_iommu_mappings[i]); - daddr = config->ns_iommu_mappings[i] & ADDR_MASK; + size = gcip_ns_config_to_size(config->ns_iommu_mappings[i]); + daddr = config->ns_iommu_mappings[i] & GCIP_IMG_CFG_ADDR_MASK; parser->ops->unmap(parser->data, daddr, size, 0); } return ret; @@ -143,8 +121,8 @@ static void clear_ns_iommu_mappings(struct gcip_image_config_parser *parser, int i; for (i = config->num_ns_iommu_mappings - 1; i >= 0; i--) { - size = CONFIG_TO_MBSIZE(config->ns_iommu_mappings[i]); - daddr = config->ns_iommu_mappings[i] & ADDR_MASK; + size = gcip_ns_config_to_size(config->ns_iommu_mappings[i]); + daddr = config->ns_iommu_mappings[i] & GCIP_IMG_CFG_ADDR_MASK; dev_dbg(parser->dev, "Image config removing NS IOMMU mapping: %pad size=%#lx", &daddr, size); parser->ops->unmap(parser->data, daddr, size, 0); |