1 // Copyright 2016 The Fuchsia Authors
2 //
3 // Use of this source code is governed by a MIT-style
4 // license that can be found in the LICENSE file or at
5 // https://opensource.org/licenses/MIT
6
7 #include <vm/vm_address_region.h>
8
9 #include "vm_priv.h"
10 #include <assert.h>
11 #include <err.h>
12 #include <fbl/auto_call.h>
13 #include <inttypes.h>
14 #include <string.h>
15 #include <trace.h>
16 #include <vm/vm.h>
17 #include <vm/vm_aspace.h>
18 #include <zircon/types.h>
19
20 #define LOCAL_TRACE MAX(VM_GLOBAL_TRACE, 0)
21
VmAddressRegionOrMapping(vaddr_t base,size_t size,uint32_t flags,VmAspace * aspace,VmAddressRegion * parent)22 VmAddressRegionOrMapping::VmAddressRegionOrMapping(
23 vaddr_t base, size_t size, uint32_t flags,
24 VmAspace* aspace, VmAddressRegion* parent)
25 : state_(LifeCycleState::NOT_READY), base_(base), size_(size),
26 flags_(flags), aspace_(aspace), parent_(parent) {
27 LTRACEF("%p\n", this);
28 }
29
Destroy()30 zx_status_t VmAddressRegionOrMapping::Destroy() {
31 canary_.Assert();
32
33 Guard<fbl::Mutex> guard{aspace_->lock()};
34 if (state_ != LifeCycleState::ALIVE) {
35 return ZX_ERR_BAD_STATE;
36 }
37
38 return DestroyLocked();
39 }
40
~VmAddressRegionOrMapping()41 VmAddressRegionOrMapping::~VmAddressRegionOrMapping() {
42 LTRACEF("%p\n", this);
43
44 if (state_ == LifeCycleState::ALIVE) {
45 Destroy();
46 }
47
48 DEBUG_ASSERT(!subregion_list_node_.InContainer());
49 }
50
IsAliveLocked() const51 bool VmAddressRegionOrMapping::IsAliveLocked() const {
52 canary_.Assert();
53 DEBUG_ASSERT(aspace_->lock()->lock().IsHeld());
54 return state_ == LifeCycleState::ALIVE;
55 }
56
as_vm_address_region()57 fbl::RefPtr<VmAddressRegion> VmAddressRegionOrMapping::as_vm_address_region() {
58 canary_.Assert();
59 if (is_mapping()) {
60 return nullptr;
61 }
62 return fbl::RefPtr<VmAddressRegion>(static_cast<VmAddressRegion*>(this));
63 }
64
as_vm_mapping()65 fbl::RefPtr<VmMapping> VmAddressRegionOrMapping::as_vm_mapping() {
66 canary_.Assert();
67 if (!is_mapping()) {
68 return nullptr;
69 }
70 return fbl::RefPtr<VmMapping>(static_cast<VmMapping*>(this));
71 }
72
is_valid_mapping_flags(uint arch_mmu_flags)73 bool VmAddressRegionOrMapping::is_valid_mapping_flags(uint arch_mmu_flags) {
74 if (!(flags_ & VMAR_FLAG_CAN_MAP_READ) && (arch_mmu_flags & ARCH_MMU_FLAG_PERM_READ)) {
75 return false;
76 }
77 if (!(flags_ & VMAR_FLAG_CAN_MAP_WRITE) && (arch_mmu_flags & ARCH_MMU_FLAG_PERM_WRITE)) {
78 return false;
79 }
80 if (!(flags_ & VMAR_FLAG_CAN_MAP_EXECUTE) && (arch_mmu_flags & ARCH_MMU_FLAG_PERM_EXECUTE)) {
81 return false;
82 }
83 return true;
84 }
85
AllocatedPages() const86 size_t VmAddressRegionOrMapping::AllocatedPages() const {
87 Guard<fbl::Mutex> guard{aspace_->lock()};
88 if (state_ != LifeCycleState::ALIVE) {
89 return 0;
90 }
91 return AllocatedPagesLocked();
92 }
93