Skip to content

Commit 871035e

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

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
@@ -666,6 +666,104 @@ static umf_result_t os_allocation_merge(void *provider, void *lowPtr,
666666
return UMF_RESULT_SUCCESS;
667667
}
668668

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

689787
umf_memory_provider_ops_t *umfOsMemoryProviderOps(void) {
690788
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
@@ -146,3 +146,25 @@ int os_purge(void *addr, size_t length, int advice) {
146146
void os_strerror(int errnum, char *buf, size_t buflen) {
147147
strerror_r(errnum, buf, buflen);
148148
}
149+
150+
int os_getpid(void) { return getpid(); }
151+
152+
int os_duplicate_fd(int pid, int fd) {
153+
// SYS_pidfd_open is supported since Linux 5.3
154+
// SYS_pidfd_getfd is supported since Linux 5.6
155+
#if defined(__NR_pidfd_open) && defined(__NR_pidfd_getfd)
156+
int pid_fd = syscall(SYS_pidfd_open, pid, 0);
157+
if (pid_fd == -1) {
158+
return -1;
159+
}
160+
161+
int fd_dup = syscall(SYS_pidfd_getfd, pid_fd, fd, 0);
162+
close(pid_fd);
163+
return fd_dup;
164+
#else
165+
(void)pid; // unused
166+
(void)fd; // unused
167+
return -1; // unsupported
168+
// TODO: find another way
169+
#endif /* defined(__NR_pidfd_open) && defined(__NR_pidfd_getfd) */
170+
}

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)