blob: cee149b880b5cccb21e65c6de7e1c29ac6751e31 [file]
// Copyright 2026 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <zircon/types.h>
#include <kernel/ffi.h>
#include <ktl/utility.h>
#include <vm/vm_address_region.h>
#include <vm/vm_address_region_ffi.h>
#include <vm/vm_object.h>
// TODO(https://fxbug.dev/537458631): Remove the annotations once cross-language inlining works.
extern "C" {
FFI_ALWAYS_INLINE void cpp_vm_mapping_free(VmMapping* mapping) { delete mapping; }
FFI_ALWAYS_INLINE void* cpp_vm_mapping_state(VmMapping* mapping) {
return &mapping->opaque_storage_;
}
FFI_ALWAYS_INLINE zx_status_t cpp_vm_mapping_destroy(VmMapping* mapping) {
return mapping->Destroy();
}
FFI_ALWAYS_INLINE zx_status_t cpp_vm_mapping_map_range(VmMapping* mapping, size_t offset,
size_t len, bool commit,
bool ignore_existing) {
return mapping->MapRange(offset, len, commit, ignore_existing);
}
FFI_ALWAYS_INLINE zx_status_t cpp_vm_mapping_debug_unmap(VmMapping* mapping, vaddr_t base,
size_t size) {
return mapping->DebugUnmap(base, size);
}
FFI_ALWAYS_INLINE zx_status_t cpp_vm_mapping_debug_protect(VmMapping* mapping, vaddr_t base,
size_t size,
arch_mmu_flags_t new_arch_mmu_flags) {
return mapping->DebugProtect(base, size, new_arch_mmu_flags);
}
FFI_ALWAYS_INLINE zx_status_t cpp_vm_mapping_enumerate_protection_ranges_locked(
const VmMapping* mapping, vaddr_t base, size_t size,
cpp_vm_mapping_enumerate_protection_ranges_cb cb, void* ctx) TA_NO_THREAD_SAFETY_ANALYSIS {
return mapping->EnumerateProtectionRangesLocked(
base, size, [cb, ctx](vaddr_t base, size_t len, arch_mmu_flags_t flags) {
return cb(ctx, base, len, flags);
});
}
FFI_ALWAYS_INLINE VmMapping::FlagsRange cpp_vm_mapping_arch_mmu_flags_range_locked(
const VmMapping* mapping, vaddr_t offset) {
AssertHeld(mapping->lock_ref());
return mapping->arch_mmu_flags_range_locked(offset);
}
FFI_ALWAYS_INLINE zx_status_t cpp_vm_mapping_force_writable(VmMapping* mapping,
VmMapping** out_mapping) {
auto result = mapping->ForceWritable();
if (result.is_error()) {
return result.error_value();
}
auto res = *result;
*out_mapping = fbl::ExportToRawPtr(&res);
return ZX_OK;
}
FFI_ALWAYS_INLINE void cpp_vm_mapping_mark_mergeable(VmMapping* mapping) {
VmMapping::MarkMergeable(fbl::ImportFromRawPtr(mapping));
}
FFI_ALWAYS_INLINE arch_mmu_flags_t cpp_vm_mapping_arch_mmu_flags_locked(
const VmMapping* mapping, vaddr_t offset) TA_NO_THREAD_SAFETY_ANALYSIS {
return mapping->arch_mmu_flags_locked(offset);
}
FFI_ALWAYS_INLINE zx_status_t cpp_vm_mapping_page_fault_locked(
VmMapping* mapping, vaddr_t va, uint32_t pf_flags, size_t additional_pages,
MultiPageRequest* page_request, uint32_t* out_mapped) TA_NO_THREAD_SAFETY_ANALYSIS {
auto [status, mapped] = mapping->PageFaultLocked(va, pf_flags, additional_pages, page_request);
*out_mapped = mapped;
return status;
}
} // extern "C"