Skip to content

Commit 9f8f85f

Browse files
committed
Implement IPC hooks in OS memory provider
Signed-off-by: Lukasz Dorau <lukasz.dorau@intel.com>
1 parent e1b2357 commit 9f8f85f

File tree

4 files changed

+137
-5
lines changed

4 files changed

+137
-5
lines changed

src/provider/provider_os_memory.c

Lines changed: 103 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,104 @@ static umf_result_t os_allocation_merge(void *provider, void *lowPtr,
657657
return UMF_RESULT_SUCCESS;
658658
}
659659

660+
typedef struct os_ipc_data_t {
661+
int pid;
662+
int fd;
663+
size_t fd_offset;
664+
size_t size;
665+
} os_ipc_data_t;
666+
667+
static umf_result_t os_get_ipc_handle_size(void *provider, size_t *size) {
668+
if (provider == NULL || size == NULL) {
669+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
670+
}
671+
672+
*size = sizeof(os_ipc_data_t);
673+
return UMF_RESULT_SUCCESS;
674+
}
675+
676+
static umf_result_t os_get_ipc_handle(void *provider, const void *ptr,
677+
size_t size, void *providerIpcData) {
678+
if (provider == NULL || providerIpcData == NULL) {
679+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
680+
}
681+
682+
os_memory_provider_t *os_provider = (os_memory_provider_t *)provider;
683+
684+
void *value = critnib_get(os_provider->ptr_off, (uintptr_t)ptr);
685+
if (value == NULL) {
686+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
687+
}
688+
689+
os_ipc_data_t *os_ipc_data = (os_ipc_data_t *)providerIpcData;
690+
os_ipc_data->pid = os_getpid();
691+
os_ipc_data->fd = os_provider->fd;
692+
os_ipc_data->fd_offset = (size_t)value;
693+
os_ipc_data->size = size;
694+
695+
return UMF_RESULT_SUCCESS;
696+
}
697+
698+
static umf_result_t os_put_ipc_handle(void *provider, void *providerIpcData) {
699+
if (provider == NULL || providerIpcData == NULL) {
700+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
701+
}
702+
703+
os_memory_provider_t *os_provider = (os_memory_provider_t *)provider;
704+
os_ipc_data_t *os_ipc_data = (os_ipc_data_t *)providerIpcData;
705+
706+
if (os_ipc_data->fd != os_provider->fd || os_ipc_data->pid != os_getpid()) {
707+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
708+
}
709+
710+
return UMF_RESULT_SUCCESS;
711+
}
712+
713+
static umf_result_t os_open_ipc_handle(void *provider, void *providerIpcData,
714+
void **ptr) {
715+
if (provider == NULL || providerIpcData == NULL || ptr == NULL) {
716+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
717+
}
718+
719+
os_memory_provider_t *os_provider = (os_memory_provider_t *)provider;
720+
os_ipc_data_t *os_ipc_data = (os_ipc_data_t *)providerIpcData;
721+
722+
int fd = os_duplicate_fd(os_ipc_data->pid, os_ipc_data->fd);
723+
if (fd == -1) {
724+
LOG_PERR("duplicating file descriptor failed");
725+
return UMF_RESULT_ERROR_UNKNOWN;
726+
}
727+
728+
*ptr = os_mmap(NULL, os_ipc_data->size, os_provider->protection,
729+
os_provider->flag, fd, os_ipc_data->fd_offset);
730+
if (*ptr == NULL) {
731+
os_store_last_native_error(UMF_OS_RESULT_ERROR_ALLOC_FAILED, errno);
732+
LOG_PERR("memory mapping failed");
733+
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
734+
}
735+
736+
return UMF_RESULT_SUCCESS;
737+
}
738+
739+
static umf_result_t os_close_ipc_handle(void *provider, void *ptr,
740+
size_t size) {
741+
if (provider == NULL || ptr == NULL) {
742+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
743+
}
744+
745+
errno = 0;
746+
int ret = os_munmap(ptr, size);
747+
// ignore error when size == 0
748+
if (ret && (size > 0)) {
749+
os_store_last_native_error(UMF_OS_RESULT_ERROR_FREE_FAILED, errno);
750+
LOG_PERR("memory unmapping failed");
751+
752+
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
753+
}
754+
755+
return UMF_RESULT_SUCCESS;
756+
}
757+
660758
static umf_memory_provider_ops_t UMF_OS_MEMORY_PROVIDER_OPS = {
661759
.version = UMF_VERSION_CURRENT,
662760
.initialize = os_initialize,
@@ -671,11 +769,11 @@ static umf_memory_provider_ops_t UMF_OS_MEMORY_PROVIDER_OPS = {
671769
.ext.purge_force = os_purge_force,
672770
.ext.allocation_merge = os_allocation_merge,
673771
.ext.allocation_split = os_allocation_split,
674-
.ipc.get_ipc_handle_size = NULL,
675-
.ipc.get_ipc_handle = NULL,
676-
.ipc.put_ipc_handle = NULL,
677-
.ipc.open_ipc_handle = NULL,
678-
.ipc.close_ipc_handle = NULL};
772+
.ipc.get_ipc_handle_size = os_get_ipc_handle_size,
773+
.ipc.get_ipc_handle = os_get_ipc_handle,
774+
.ipc.put_ipc_handle = os_put_ipc_handle,
775+
.ipc.open_ipc_handle = os_open_ipc_handle,
776+
.ipc.close_ipc_handle = os_close_ipc_handle};
679777

680778
umf_memory_provider_ops_t *umfOsMemoryProviderOps(void) {
681779
return &UMF_OS_MEMORY_PROVIDER_OPS;

src/provider/provider_os_memory_internal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ size_t os_get_page_size(void);
4545

4646
void os_strerror(int errnum, char *buf, size_t buflen);
4747

48+
int os_getpid(void);
49+
50+
int os_duplicate_fd(int pid, int fd);
51+
4852
#ifdef __cplusplus
4953
}
5054
#endif

src/provider/provider_os_memory_linux.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,25 @@ int os_purge(void *addr, size_t length, int advice) {
123123
void os_strerror(int errnum, char *buf, size_t buflen) {
124124
strerror_r(errnum, buf, buflen);
125125
}
126+
127+
int os_getpid(void) { return getpid(); }
128+
129+
int os_duplicate_fd(int pid, int fd) {
130+
// SYS_pidfd_open is supported since Linux 5.3
131+
// SYS_pidfd_getfd is supported since Linux 5.6
132+
#if defined(__NR_pidfd_open) && defined(__NR_pidfd_getfd)
133+
int pid_fd = syscall(SYS_pidfd_open, pid, 0);
134+
if (pid_fd == -1) {
135+
return -1;
136+
}
137+
138+
int fd_dup = syscall(SYS_pidfd_getfd, pid_fd, fd, 0);
139+
close(pid_fd);
140+
return fd_dup;
141+
#else
142+
(void)pid; // unused
143+
(void)fd; // unused
144+
return -1; // unsupported
145+
// TODO: find another way
146+
#endif /* defined(__NR_pidfd_open) && defined(__NR_pidfd_getfd) */
147+
}

src/provider/provider_os_memory_windows.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,11 @@ size_t os_get_page_size(void) {
112112
void os_strerror(int errnum, char *buf, size_t buflen) {
113113
strerror_s(buf, buflen, errnum);
114114
}
115+
116+
int os_getpid(void) { return GetCurrentProcessId(); }
117+
118+
int os_duplicate_fd(int pid, int fd) {
119+
(void)pid; // unused
120+
(void)fd; // unused
121+
return -1; // unsupported
122+
}

0 commit comments

Comments
 (0)