From 1cd52053c7f1366f4b5e3300e8c8a5dce2709da4 Mon Sep 17 00:00:00 2001 From: Lorenzo Stoakes Date: Mon, 27 Jun 2016 13:36:58 +0100 Subject: [PATCH] khronos: Use vchiq_get_client_id to determine global PID. (#315) PID namespacing breaks VCHIQ as it uses PIDs as unique identifiers for VCHIQ services, meaning messages sent from userland will contain a different ID than the one expected by the GPU. This patch addresses the problem uses the existing GET_CLIENT_ID ioctl to retrieve the global PID as seen by the kernel rather than using the process's reported PID. --- interface/khronos/common/khrn_client.c | 4 ++-- interface/khronos/common/khrn_client_rpc.h | 2 ++ .../khronos/common/linux/khrn_client_platform_linux.c | 4 +++- interface/khronos/common/linux/khrn_client_rpc_linux.c | 7 ++++++- interface/khronos/egl/egl_client_surface.c | 4 ++-- interface/khronos/ext/egl_khr_sync_client.c | 2 +- 6 files changed, 16 insertions(+), 7 deletions(-) diff --git a/interface/khronos/common/khrn_client.c b/interface/khronos/common/khrn_client.c index e38a85f..ef4babd 100644 --- a/interface/khronos/common/khrn_client.c +++ b/interface/khronos/common/khrn_client.c @@ -372,7 +372,7 @@ static uint32_t convert_gltype(EGL_CONTEXT_TYPE_T type) void client_send_make_current(CLIENT_THREAD_STATE_T *thread) { - uint64_t pid = khronos_platform_get_process_id(); + uint64_t pid = rpc_get_client_id(thread); uint32_t gltype = thread->opengl.context ? convert_gltype(thread->opengl.context->type) : 0; EGL_GL_CONTEXT_ID_T servergl = thread->opengl.context ? thread->opengl.context->servercontext : EGL_SERVER_NO_GL_CONTEXT; EGL_SURFACE_ID_T servergldraw = thread->opengl.draw ? thread->opengl.draw->serverbuffer : EGL_SERVER_NO_SURFACE; @@ -553,7 +553,7 @@ void client_library_send_make_current(const KHRONOS_FUNC_TABLE_T *func_table) CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE(); if (thread->opengl.context || thread->openvg.context) { - uint64_t pid = khronos_platform_get_process_id(); + uint64_t pid = rpc_get_client_id(thread); uint32_t gltype = thread->opengl.context ? convert_gltype(thread->opengl.context->type) : 0; EGL_GL_CONTEXT_ID_T servergl = thread->opengl.context ? thread->opengl.context->servercontext : EGL_SERVER_NO_GL_CONTEXT; EGL_SURFACE_ID_T servergldraw = thread->opengl.draw ? thread->opengl.draw->serverbuffer : EGL_SERVER_NO_SURFACE; diff --git a/interface/khronos/common/khrn_client_rpc.h b/interface/khronos/common/khrn_client_rpc.h index 418aa67..dc4351d 100644 --- a/interface/khronos/common/khrn_client_rpc.h +++ b/interface/khronos/common/khrn_client_rpc.h @@ -350,6 +350,8 @@ extern void rpc_flush(CLIENT_THREAD_STATE_T *thread); extern void rpc_high_priority_begin(CLIENT_THREAD_STATE_T *thread); extern void rpc_high_priority_end(CLIENT_THREAD_STATE_T *thread); +extern uint64_t rpc_get_client_id(CLIENT_THREAD_STATE_T *thread); + static INLINE uint32_t rpc_pad_ctrl(uint32_t len) { return (len + 0x3) & ~0x3; } static INLINE uint32_t rpc_pad_bulk(uint32_t len) { return len; } diff --git a/interface/khronos/common/linux/khrn_client_platform_linux.c b/interface/khronos/common/linux/khrn_client_platform_linux.c index 9d43d15..1ccb7a0 100644 --- a/interface/khronos/common/linux/khrn_client_platform_linux.c +++ b/interface/khronos/common/linux/khrn_client_platform_linux.c @@ -77,7 +77,9 @@ VCOS_STATUS_T khronos_platform_semaphore_create(PLATFORM_SEMAPHORE_T *sem, int n uint64_t khronos_platform_get_process_id() { - return vcos_process_id_current(); + CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE(); + + return rpc_get_client_id(thread); } static bool process_attached = false; diff --git a/interface/khronos/common/linux/khrn_client_rpc_linux.c b/interface/khronos/common/linux/khrn_client_rpc_linux.c index 8e586c3..5ad01c0 100644 --- a/interface/khronos/common/linux/khrn_client_rpc_linux.c +++ b/interface/khronos/common/linux/khrn_client_rpc_linux.c @@ -113,7 +113,7 @@ VCHIQ_STATUS_T khan_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header, // TODO should be able to remove this eventually. // If incoming message is not addressed to this process, then ignore it. // Correct process should then pick it up. - uint64_t pid = khronos_platform_get_process_id(); + uint64_t pid = vchiq_get_client_id(handle); if((msg[0] != (uint32_t) pid) || (msg[1] != (uint32_t) (pid >> 32))) { printf("khan_callback: message for wrong process; pid = %X, msg pid = %X\n", @@ -521,3 +521,8 @@ void rpc_call8_makecurrent(CLIENT_THREAD_STATE_T *thread, uint32_t id, uint32_t RPC_CALL8(eglIntMakeCurrent_impl, thread, EGLINTMAKECURRENT_ID, p0, p1, p2, p3, p4, p5, p6, p7); } } + +uint64_t rpc_get_client_id(CLIENT_THREAD_STATE_T *thread) +{ + return vchiq_get_client_id(get_handle(thread)); +} diff --git a/interface/khronos/egl/egl_client_surface.c b/interface/khronos/egl/egl_client_surface.c index 0fa1fd1..6846dfa 100644 --- a/interface/khronos/egl/egl_client_surface.c +++ b/interface/khronos/egl/egl_client_surface.c @@ -424,7 +424,7 @@ EGL_SURFACE_T *egl_surface_create( surface->avail_buffers_valid = 0; if (surface->buffers > 1) { - uint64_t pid = khronos_platform_get_process_id(); + uint64_t pid = rpc_get_client_id(thread); int sem[3] = { (int)pid, (int)(pid >> 32), (int)name }; if (khronos_platform_semaphore_create(&surface->avail_buffers, sem, surface->buffers) == KHR_SUCCESS) surface->avail_buffers_valid = 1; @@ -458,7 +458,7 @@ EGL_SURFACE_T *egl_surface_create( sem_name = KHRN_NO_SEMAPHORE; #ifndef KHRONOS_EGL_PLATFORM_OPENWFC if (surface->buffers > 1) { - uint64_t pid = khronos_platform_get_process_id(); + uint64_t pid = rpc_get_client_id(thread); int sem[3]; sem[0] = (int)pid; sem[1] = (int)(pid >> 32); sem[2] = (int)name; diff --git a/interface/khronos/ext/egl_khr_sync_client.c b/interface/khronos/ext/egl_khr_sync_client.c index 0390d05..f05e221 100644 --- a/interface/khronos/ext/egl_khr_sync_client.c +++ b/interface/khronos/ext/egl_khr_sync_client.c @@ -73,7 +73,7 @@ static EGL_SYNC_T *egl_sync_create(EGLSyncKHR sync, EGLenum type, { CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE(); EGL_SYNC_T *sync_ptr = (EGL_SYNC_T *)khrn_platform_malloc(sizeof(EGL_SYNC_T), "EGL_SYNC_T"); - uint64_t pid = khronos_platform_get_process_id(); + uint64_t pid = rpc_get_client_id(thread); uint32_t sem; if (!sync_ptr)