blob: bf91b7d8f85d512188a16adc3b2845ae888a3cac [file] [log] [blame]
// Copyright 2016 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
#ifndef ZIRCON_KERNEL_OBJECT_INCLUDE_OBJECT_VM_OBJECT_DISPATCHER_H_
#define ZIRCON_KERNEL_OBJECT_INCLUDE_OBJECT_VM_OBJECT_DISPATCHER_H_
#include <lib/user_copy/user_iovec.h>
#include <lib/user_copy/user_ptr.h>
#include <sys/types.h>
#include <zircon/rights.h>
#include <zircon/types.h>
#include <fbl/canary.h>
#include <object/dispatcher.h>
#include <object/handle.h>
#include <vm/vm_object.h>
class VmObjectDispatcher final : public SoloDispatcher<VmObjectDispatcher, ZX_DEFAULT_VMO_RIGHTS>,
public VmObjectChildObserver {
public:
enum class InitialMutability { kMutable, kImmutable };
static zx_status_t parse_create_syscall_flags(uint32_t flags, uint32_t* out_flags);
static zx_status_t Create(fbl::RefPtr<VmObject> vmo, uint64_t content_size,
InitialMutability initial_mutability,
KernelHandle<VmObjectDispatcher>* handle, zx_rights_t* rights) {
return Create(ktl::move(vmo), content_size, ZX_KOID_INVALID, initial_mutability, handle,
rights);
}
static zx_status_t Create(fbl::RefPtr<VmObject> vmo, uint64_t content_size, zx_koid_t pager_koid,
InitialMutability initial_mutability,
KernelHandle<VmObjectDispatcher>* handle, zx_rights_t* rights);
~VmObjectDispatcher() final;
// VmObjectChildObserver implementation.
void OnZeroChild() final;
void OnOneChild() final;
// SoloDispatcher implementation.
zx_obj_type_t get_type() const final { return ZX_OBJ_TYPE_VMO; }
void get_name(char out_name[ZX_MAX_NAME_LEN]) const final;
zx_status_t set_name(const char* name, size_t len) final;
// Dispatcher implementation.
void on_zero_handles() final;
// VmObjectDispatcher own methods.
zx_status_t Read(VmAspace* current_aspace, user_out_ptr<char> user_data, size_t length,
uint64_t offset);
zx_status_t ReadVector(VmAspace* current_aspace, user_out_iovec_t user_data, size_t length,
uint64_t offset);
zx_status_t Write(VmAspace* current_aspace, user_in_ptr<const char> user_data, size_t length,
uint64_t offset);
zx_status_t WriteVector(VmAspace* current_aspace, user_in_iovec_t user_data, size_t length,
uint64_t offset);
zx_status_t SetSize(uint64_t);
zx_status_t GetSize(uint64_t* size);
zx_status_t RangeOp(uint32_t op, uint64_t offset, uint64_t size, user_inout_ptr<void> buffer,
size_t buffer_size, zx_rights_t rights);
zx_status_t CreateChild(uint32_t options, uint64_t offset, uint64_t size, bool copy_name,
fbl::RefPtr<VmObject>* child_vmo);
zx_status_t SetMappingCachePolicy(uint32_t cache_policy);
zx_info_vmo_t GetVmoInfo();
zx_status_t SetContentSize(uint64_t);
uint64_t GetContentSize() const;
// Returns the actual content size after attempting to resize the VMO to fit
// the requested content size.
uint64_t ExpandContentIfNeeded(uint64_t requested_content_size, uint64_t zero_until_offset);
const fbl::RefPtr<VmObject>& vmo() const { return vmo_; }
zx_koid_t pager_koid() const { return pager_koid_; }
private:
explicit VmObjectDispatcher(fbl::RefPtr<VmObject> vmo, uint64_t size, zx_koid_t pager_koid,
InitialMutability initial_mutability);
// The 'const' here is load bearing; we give a raw pointer to
// ourselves to |vmo_| so we have to ensure we don't reset vmo_
// except during destruction.
fbl::RefPtr<VmObject> const vmo_;
// The size of the content stored in the VMO in bytes.
uint64_t content_size_ TA_GUARDED(get_lock()) = 0u;
// The koid of the related pager object, or ZX_KOID_INVALID if
// there is no related pager.
const zx_koid_t pager_koid_;
// Indicates whether the VMO was immutable at creation time.
const InitialMutability initial_mutability_;
};
zx_info_vmo_t VmoToInfoEntry(const VmObject* vmo, bool is_handle, zx_rights_t handle_rights);
#endif // ZIRCON_KERNEL_OBJECT_INCLUDE_OBJECT_VM_OBJECT_DISPATCHER_H_