From dbd7b967af4d89166db07325a42c816501662ef5 Mon Sep 17 00:00:00 2001 From: Ryan Macnak Date: Tue, 20 Jun 2023 19:28:18 +0000 Subject: [PATCH] [fuchsia] Plumbing for the VMEX resource. TEST=ci Change-Id: I2e812e6eef2a3c6f91aec955609ece2ca4df15a1 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/308805 Reviewed-by: Liam Appelbe Commit-Queue: Ryan Macnak --- build/fuchsia/fuchsia_ffi_test_component.cmx | 2 +- build/fuchsia/fuchsia_test_component.cmx | 2 +- runtime/bin/BUILD.gn | 30 ++++++++++++++++---- runtime/bin/analyze_snapshot.cc | 3 ++ runtime/bin/gen_snapshot.cc | 3 ++ runtime/bin/main_impl.cc | 7 +++++ runtime/bin/platform.h | 4 +++ runtime/bin/platform_fuchsia.cc | 15 ++++++++++ runtime/bin/run_vm_tests.cc | 3 ++ runtime/include/dart_api.h | 15 +++++++++- runtime/vm/dart.cc | 4 +++ runtime/vm/virtual_memory.h | 8 ++++++ runtime/vm/virtual_memory_fuchsia.cc | 9 ++++-- runtime/vm/virtual_memory_posix.cc | 2 ++ runtime/vm/virtual_memory_win.cc | 2 ++ 15 files changed, 98 insertions(+), 11 deletions(-) diff --git a/build/fuchsia/fuchsia_ffi_test_component.cmx b/build/fuchsia/fuchsia_ffi_test_component.cmx index 45ba3977835..7727c9c5fac 100644 --- a/build/fuchsia/fuchsia_ffi_test_component.cmx +++ b/build/fuchsia/fuchsia_ffi_test_component.cmx @@ -5,7 +5,6 @@ "sandbox": { "features": [ "config-data", - "deprecated-ambient-replace-as-executable", "isolated-cache-storage", "isolated-persistent-storage", "isolated-temp", @@ -16,6 +15,7 @@ "fuchsia.device.NameProvider", "fuchsia.feedback.CrashReporter", "fuchsia.intl.PropertyProvider", + "fuchsia.kernel.VmexResource", "fuchsia.logger.LogSink", "fuchsia.net.name.Lookup", "fuchsia.posix.socket.Provider", diff --git a/build/fuchsia/fuchsia_test_component.cmx b/build/fuchsia/fuchsia_test_component.cmx index 45ba3977835..7727c9c5fac 100644 --- a/build/fuchsia/fuchsia_test_component.cmx +++ b/build/fuchsia/fuchsia_test_component.cmx @@ -5,7 +5,6 @@ "sandbox": { "features": [ "config-data", - "deprecated-ambient-replace-as-executable", "isolated-cache-storage", "isolated-persistent-storage", "isolated-temp", @@ -16,6 +15,7 @@ "fuchsia.device.NameProvider", "fuchsia.feedback.CrashReporter", "fuchsia.intl.PropertyProvider", + "fuchsia.kernel.VmexResource", "fuchsia.logger.LogSink", "fuchsia.net.name.Lookup", "fuchsia.posix.socket.Provider", diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn index f9cca383791..eac51ec0247 100644 --- a/runtime/bin/BUILD.gn +++ b/runtime/bin/BUILD.gn @@ -319,13 +319,22 @@ template("build_gen_snapshot_dart_io") { if (is_fuchsia) { if (using_fuchsia_gn_sdk) { - deps += [ "$fuchsia_sdk_root/fidl/fuchsia.io" ] + deps += [ + "$fuchsia_sdk_root/fidl/fuchsia.io", + "$fuchsia_sdk_root/fidl/fuchsia.kernel", + ] public_deps = [ "$fuchsia_sdk_root/pkg/fdio" ] } else if (using_fuchsia_sdk) { - deps += [ "$fuchsia_sdk_root/fidl:fuchsia.io" ] + deps += [ + "$fuchsia_sdk_root/fidl:fuchsia.io", + "$fuchsia_sdk_root/fidl:fuchsia.kernel", + ] public_deps = [ "$fuchsia_sdk_root/pkg:fdio" ] } else { - deps += [ "//sdk/fidl/fuchsia.io:fuchsia.io_hlcpp" ] + deps += [ + "//sdk/fidl/fuchsia.io:fuchsia.io_hlcpp", + "//sdk/fidl/fuchsia.kernel:fuchsia.kernel_hlcpp", + ] public_deps = [ "//sdk/lib/fdio" ] } } @@ -431,13 +440,22 @@ template("dart_io") { if (is_fuchsia) { if (using_fuchsia_gn_sdk) { - deps += [ "$fuchsia_sdk_root/fidl/fuchsia.io" ] + deps += [ + "$fuchsia_sdk_root/fidl/fuchsia.io", + "$fuchsia_sdk_root/fidl/fuchsia.kernel", + ] public_deps = [ "$fuchsia_sdk_root/pkg/fdio" ] } else if (using_fuchsia_sdk) { - deps += [ "$fuchsia_sdk_root/fidl:fuchsia.io" ] + deps += [ + "$fuchsia_sdk_root/fidl:fuchsia.io", + "$fuchsia_sdk_root/fidl:fuchsia.kernel", + ] public_deps = [ "$fuchsia_sdk_root/pkg:fdio" ] } else { - deps += [ "//sdk/fidl/fuchsia.io:fuchsia.io_hlcpp" ] + deps += [ + "//sdk/fidl/fuchsia.io:fuchsia.io_hlcpp", + "//sdk/fidl/fuchsia.kernel:fuchsia.kernel_hlcpp", + ] public_deps = [ "//sdk/lib/fdio" ] } } diff --git a/runtime/bin/analyze_snapshot.cc b/runtime/bin/analyze_snapshot.cc index e1435d67293..423d40b4abc 100644 --- a/runtime/bin/analyze_snapshot.cc +++ b/runtime/bin/analyze_snapshot.cc @@ -199,6 +199,9 @@ int RunAnalyzer(int argc, char** argv) { init_params.file_write = DartUtils::WriteFile; init_params.file_close = DartUtils::CloseFile; init_params.entropy_source = DartUtils::EntropySource; +#if defined(DART_HOST_OS_FUCHSIA) + init_params.vmex_resource = Platform::GetVMEXResource(); +#endif error = Dart_Initialize(&init_params); if (error != nullptr) { diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc index 463c1e78a64..b87c246e8b3 100644 --- a/runtime/bin/gen_snapshot.cc +++ b/runtime/bin/gen_snapshot.cc @@ -905,6 +905,9 @@ int main(int argc, char** argv) { init_params.file_close = DartUtils::CloseFile; init_params.entropy_source = DartUtils::EntropySource; init_params.start_kernel_isolate = false; +#if defined(DART_HOST_OS_FUCHSIA) + init_params.vmex_resource = Platform::GetVMEXResource(); +#endif std::unique_ptr mapped_vm_snapshot_data; std::unique_ptr mapped_vm_snapshot_instructions; diff --git a/runtime/bin/main_impl.cc b/runtime/bin/main_impl.cc index fab20ae21aa..c87917425ce 100644 --- a/runtime/bin/main_impl.cc +++ b/runtime/bin/main_impl.cc @@ -1355,6 +1355,13 @@ void main(int argc, char** argv) { } #else init_params.start_kernel_isolate = false; +#endif +#if defined(DART_HOST_OS_FUCHSIA) +#if defined(DART_PRECOMPILED_RUNTIME) + init_params.vmex_resource = ZX_HANDLE_INVALID; +#else + init_params.vmex_resource = Platform::GetVMEXResource(); +#endif #endif error = Dart_Initialize(&init_params); diff --git a/runtime/bin/platform.h b/runtime/bin/platform.h index 24fadff85e6..2b840e0ad63 100644 --- a/runtime/bin/platform.h +++ b/runtime/bin/platform.h @@ -102,6 +102,10 @@ class Platform { static void SetCoreDumpResourceLimit(int value); +#if defined(DART_HOST_OS_FUCHSIA) + static zx_handle_t GetVMEXResource(); +#endif + private: // The path to the executable. static const char* executable_name_; diff --git a/runtime/bin/platform_fuchsia.cc b/runtime/bin/platform_fuchsia.cc index fd54eace48a..945404ff659 100644 --- a/runtime/bin/platform_fuchsia.cc +++ b/runtime/bin/platform_fuchsia.cc @@ -7,6 +7,9 @@ #include "bin/platform.h" +#include +#include +#include #include #include #include @@ -161,6 +164,18 @@ void Platform::SetCoreDumpResourceLimit(int value) { // Not supported. } +zx_handle_t Platform::GetVMEXResource() { + zx::resource vmex_resource; + fuchsia::kernel::VmexResourceSyncPtr vmex_resource_svc; + zx_status_t status = fdio_service_connect( + "/svc/fuchsia.kernel.VmexResource", + vmex_resource_svc.NewRequest().TakeChannel().release()); + ASSERT(status == ZX_OK); + status = vmex_resource_svc->Get(&vmex_resource); + ASSERT(status == ZX_OK); + return vmex_resource.release(); +} + } // namespace bin } // namespace dart diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc index f23c9c45e3c..20f31f6faff 100644 --- a/runtime/bin/run_vm_tests.cc +++ b/runtime/bin/run_vm_tests.cc @@ -392,6 +392,9 @@ static int Main(int argc, const char** argv) { init_params.file_write = dart::bin::DartUtils::WriteFile; init_params.file_close = dart::bin::DartUtils::CloseFile; init_params.start_kernel_isolate = start_kernel_isolate; +#if defined(DART_HOST_OS_FUCHSIA) + init_params.vmex_resource = dart::bin::Platform::GetVMEXResource(); +#endif error = Dart::Init(&init_params); if (error != nullptr) { Syslog::PrintErr("Failed to initialize VM: %s\n", error); diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h index c66ebfe6eea..99dde6f9d2e 100644 --- a/runtime/include/dart_api.h +++ b/runtime/include/dart_api.h @@ -25,6 +25,10 @@ #include #include +#if defined(__Fuchsia__) +#include +#endif + #ifdef __cplusplus #define DART_EXTERN_C extern "C" #else @@ -849,7 +853,7 @@ typedef Dart_Handle (*Dart_GetVMServiceAssetsArchive)(void); * The current version of the Dart_InitializeFlags. Should be incremented every * time Dart_InitializeFlags changes in a binary incompatible way. */ -#define DART_INITIALIZE_PARAMS_CURRENT_VERSION (0x00000007) +#define DART_INITIALIZE_PARAMS_CURRENT_VERSION (0x00000008) /** Forward declaration */ struct Dart_CodeObserver; @@ -992,6 +996,15 @@ typedef struct { * Kernel blob unregistration callback function. See Dart_UnregisterKernelBlobCallback. */ Dart_UnregisterKernelBlobCallback unregister_kernel_blob; + +#if defined(__Fuchsia__) + /** + * The resource needed to use zx_vmo_replace_as_executable. Can be + * ZX_HANDLE_INVALID if the process has ambient-replace-as-executable or if + * executable memory is not needed (e.g., this is an AOT runtime). + */ + zx_handle_t vmex_resource; +#endif } Dart_InitializeParams; /** diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc index 9e9046f613c..c55f7ef0770 100644 --- a/runtime/vm/dart.cc +++ b/runtime/vm/dart.cc @@ -309,7 +309,11 @@ char* Dart::DartInit(const Dart_InitializeParams* params) { NOT_IN_PRODUCT(CodeObservers::RegisterExternal(*params->code_observer)); } start_time_micros_ = OS::GetCurrentMonotonicMicros(); +#if defined(DART_HOST_OS_FUCHSIA) + VirtualMemory::Init(params->vmex_resource); +#else VirtualMemory::Init(); +#endif #if defined(DART_PRECOMPILED_RUNTIME) && defined(DART_TARGET_OS_LINUX) if (VirtualMemory::PageSize() > kElfPageSize) { diff --git a/runtime/vm/virtual_memory.h b/runtime/vm/virtual_memory.h index fc0f13d5727..439bfda8505 100644 --- a/runtime/vm/virtual_memory.h +++ b/runtime/vm/virtual_memory.h @@ -10,6 +10,10 @@ #include "vm/globals.h" #include "vm/memory_region.h" +#if defined(DART_HOST_OS_FUCHSIA) +#include +#endif + namespace dart { class VirtualMemory { @@ -31,7 +35,11 @@ class VirtualMemory { intptr_t size() const { return region_.size(); } intptr_t AliasOffset() const { return alias_.start() - region_.start(); } +#if defined(DART_HOST_OS_FUCHSIA) + static void Init(zx_handle_t vmex_resource); +#else static void Init(); +#endif static void Cleanup(); // Returns true if dual mapping is enabled. diff --git a/runtime/vm/virtual_memory_fuchsia.cc b/runtime/vm/virtual_memory_fuchsia.cc index c91d6909b1f..1babc89fee4 100644 --- a/runtime/vm/virtual_memory_fuchsia.cc +++ b/runtime/vm/virtual_memory_fuchsia.cc @@ -43,6 +43,7 @@ uword VirtualMemory::page_size_ = 0; static zx_handle_t compressed_heap_vmar_ = ZX_HANDLE_INVALID; static uword compressed_heap_base_ = 0; #endif // defined(DART_COMPRESSED_POINTERS) +static zx_handle_t vmex_resource_ = ZX_HANDLE_INVALID; intptr_t VirtualMemory::CalculatePageSize() { const intptr_t page_size = getpagesize(); @@ -51,7 +52,7 @@ intptr_t VirtualMemory::CalculatePageSize() { return page_size; } -void VirtualMemory::Init() { +void VirtualMemory::Init(zx_handle_t vmex_resource) { if (FLAG_old_gen_heap_size < 0 || FLAG_old_gen_heap_size > kMaxAddrSpaceMB) { OS::PrintErr( "warning: value specified for --old_gen_heap_size %d is larger than" @@ -89,9 +90,13 @@ void VirtualMemory::Init() { #endif // defined(DART_COMPRESSED_POINTERS) page_size_ = CalculatePageSize(); + vmex_resource_ = vmex_resource; } void VirtualMemory::Cleanup() { + vmex_resource_ = ZX_HANDLE_INVALID; + page_size_ = 0; + #if defined(DART_COMPRESSED_POINTERS) zx_vmar_destroy(compressed_heap_vmar_); compressed_heap_vmar_ = ZX_HANDLE_INVALID; @@ -176,7 +181,7 @@ VirtualMemory* VirtualMemory::AllocateAligned(intptr_t size, if (is_executable) { // Add ZX_RIGHT_EXECUTE permission to VMO, so it can be mapped // into memory as executable (now or later). - status = zx_vmo_replace_as_executable(vmo, ZX_HANDLE_INVALID, &vmo); + status = zx_vmo_replace_as_executable(vmo, vmex_resource_, &vmo); if (status != ZX_OK) { LOG_ERR("zx_vmo_replace_as_executable() failed: %s\n", zx_status_get_string(status)); diff --git a/runtime/vm/virtual_memory_posix.cc b/runtime/vm/virtual_memory_posix.cc index 05173b229a4..b6962931b12 100644 --- a/runtime/vm/virtual_memory_posix.cc +++ b/runtime/vm/virtual_memory_posix.cc @@ -250,6 +250,8 @@ void VirtualMemory::Init() { } void VirtualMemory::Cleanup() { + page_size_ = 0; + #if defined(DART_COMPRESSED_POINTERS) delete compressed_heap_; compressed_heap_ = nullptr; diff --git a/runtime/vm/virtual_memory_win.cc b/runtime/vm/virtual_memory_win.cc index f422bb06036..5ee12cd046f 100644 --- a/runtime/vm/virtual_memory_win.cc +++ b/runtime/vm/virtual_memory_win.cc @@ -82,6 +82,8 @@ void VirtualMemory::Init() { } void VirtualMemory::Cleanup() { + page_size_ = 0; + #if defined(DART_COMPRESSED_POINTERS) delete compressed_heap_; compressed_heap_ = nullptr;