Loading core/java/com/android/internal/os/ZygoteInit.java +2 −1 Original line number Diff line number Diff line Loading @@ -173,12 +173,13 @@ public class ZygoteInit { } native private static void nativePreloadAppProcessHALs(); native private static void nativePreloadOpenGL(); private static void preloadOpenGL() { String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER); if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false) && (driverPackageName == null || driverPackageName.isEmpty())) { EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); nativePreloadOpenGL(); } } Loading core/jni/com_android_internal_os_ZygoteInit.cpp +37 −0 Original line number Diff line number Diff line Loading @@ -16,21 +16,58 @@ #define LOG_TAG "Zygote" #include <EGL/egl.h> #include <ui/GraphicBufferMapper.h> #include "core_jni_helpers.h" namespace { // Shadow call stack (SCS) is a security mitigation that uses a separate stack // (the SCS) for return addresses. In versions of Android newer than P, the // compiler cooperates with the system to ensure that the SCS address is always // stored in register x18, as long as the app was compiled with a new enough // compiler and does not use features that rely on SP-HALs (this restriction is // because the SP-HALs might not preserve x18 due to potentially having been // compiled with an old compiler as a consequence of Treble; it generally means // that the app must be a system app without a UI). This struct is used to // temporarily store the address on the stack while preloading the SP-HALs, so // that such apps can use the same zygote as everything else. struct ScopedSCSExit { #ifdef __aarch64__ void* scs; ScopedSCSExit() { __asm__ __volatile__("str x18, [%0]" ::"r"(&scs)); } ~ScopedSCSExit() { __asm__ __volatile__("ldr x18, [%0]; str xzr, [%0]" ::"r"(&scs)); } #else // Silence unused variable warnings in non-SCS builds. ScopedSCSExit() {} ~ScopedSCSExit() {} #endif }; void android_internal_os_ZygoteInit_nativePreloadAppProcessHALs(JNIEnv* env, jclass) { ScopedSCSExit x; android::GraphicBufferMapper::preloadHal(); // Add preloading here for other HALs that are (a) always passthrough, and // (b) loaded by most app processes. } void android_internal_os_ZygoteInit_nativePreloadOpenGL(JNIEnv* env, jclass) { ScopedSCSExit x; eglGetDisplay(EGL_DEFAULT_DISPLAY); } const JNINativeMethod gMethods[] = { { "nativePreloadAppProcessHALs", "()V", (void*)android_internal_os_ZygoteInit_nativePreloadAppProcessHALs }, { "nativePreloadOpenGL", "()V", (void*)android_internal_os_ZygoteInit_nativePreloadOpenGL }, }; } // anonymous namespace Loading Loading
core/java/com/android/internal/os/ZygoteInit.java +2 −1 Original line number Diff line number Diff line Loading @@ -173,12 +173,13 @@ public class ZygoteInit { } native private static void nativePreloadAppProcessHALs(); native private static void nativePreloadOpenGL(); private static void preloadOpenGL() { String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER); if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false) && (driverPackageName == null || driverPackageName.isEmpty())) { EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); nativePreloadOpenGL(); } } Loading
core/jni/com_android_internal_os_ZygoteInit.cpp +37 −0 Original line number Diff line number Diff line Loading @@ -16,21 +16,58 @@ #define LOG_TAG "Zygote" #include <EGL/egl.h> #include <ui/GraphicBufferMapper.h> #include "core_jni_helpers.h" namespace { // Shadow call stack (SCS) is a security mitigation that uses a separate stack // (the SCS) for return addresses. In versions of Android newer than P, the // compiler cooperates with the system to ensure that the SCS address is always // stored in register x18, as long as the app was compiled with a new enough // compiler and does not use features that rely on SP-HALs (this restriction is // because the SP-HALs might not preserve x18 due to potentially having been // compiled with an old compiler as a consequence of Treble; it generally means // that the app must be a system app without a UI). This struct is used to // temporarily store the address on the stack while preloading the SP-HALs, so // that such apps can use the same zygote as everything else. struct ScopedSCSExit { #ifdef __aarch64__ void* scs; ScopedSCSExit() { __asm__ __volatile__("str x18, [%0]" ::"r"(&scs)); } ~ScopedSCSExit() { __asm__ __volatile__("ldr x18, [%0]; str xzr, [%0]" ::"r"(&scs)); } #else // Silence unused variable warnings in non-SCS builds. ScopedSCSExit() {} ~ScopedSCSExit() {} #endif }; void android_internal_os_ZygoteInit_nativePreloadAppProcessHALs(JNIEnv* env, jclass) { ScopedSCSExit x; android::GraphicBufferMapper::preloadHal(); // Add preloading here for other HALs that are (a) always passthrough, and // (b) loaded by most app processes. } void android_internal_os_ZygoteInit_nativePreloadOpenGL(JNIEnv* env, jclass) { ScopedSCSExit x; eglGetDisplay(EGL_DEFAULT_DISPLAY); } const JNINativeMethod gMethods[] = { { "nativePreloadAppProcessHALs", "()V", (void*)android_internal_os_ZygoteInit_nativePreloadAppProcessHALs }, { "nativePreloadOpenGL", "()V", (void*)android_internal_os_ZygoteInit_nativePreloadOpenGL }, }; } // anonymous namespace Loading