Skip to content

Instantly share code, notes, and snippets.

@dividuum
Created March 5, 2025 14:46
Show Gist options
  • Select an option

  • Save dividuum/da0a9a7038b592898ea269f19917e438 to your computer and use it in GitHub Desktop.

Select an option

Save dividuum/da0a9a7038b592898ea269f19917e438 to your computer and use it in GitHub Desktop.
// 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