• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #pragma once
2 
3 /*
4  * Copyright (C) 2017 The Android Open Source Project
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #include <sys/mman.h>
20 #include <stdint.h>
21 #include <memory>
22 #include "uapi/vsoc_shm.h"
23 
24 namespace vsoc {
25 
26 /**
27  * Base class for side-specific utility functions that work on regions.
28  * The methods in this class do not assume that the region is mapped in memory.
29  * This makes is appropriate for ManagedRegions and certain low-level tests
30  * of VSoC shared memory. Most other users will want to use TypedRegions with
31  * a defined RegionLayout.
32  *
33  * This class is not directly instantiable because it must be specialized with
34  * additional fields for the host and guest.
35  */
36 class RegionControl {
37  public:
~RegionControl()38   virtual ~RegionControl() {
39     if (region_base_) {
40       munmap(region_base_, region_size());
41     }
42     region_base_ = nullptr;
43   }
44 
45 #if defined(CUTTLEFISH_HOST)
46   static std::shared_ptr<RegionControl> Open(const char* region_name,
47                                              const char* domain);
48 #else
49   static std::shared_ptr<RegionControl> Open(const char* region_name);
50 #endif
51 
region_desc()52   const vsoc_device_region& region_desc() const { return region_desc_; }
53 
54   // Returns the size of the entire region, including the signal tables.
region_size()55   uint32_t region_size() const {
56     return region_desc_.region_end_offset - region_desc_.region_begin_offset;
57   }
58 
59   // Returns the size of the region that is usable for region-specific data.
region_data_size()60   uint32_t region_data_size() const {
61     return region_size() - region_desc_.offset_of_region_data;
62   }
63 
64   // Creates a FdScopedPermission. Returns the file descriptor or -1 on
65   // failure. FdScopedPermission is not supported on the host, so -1 is
66   // always returned there.
67   virtual int CreateFdScopedPermission(const char* managed_region_name,
68                                        uint32_t owner_offset,
69                                        uint32_t owned_value,
70                                        uint32_t begin_offset,
71                                        uint32_t end_offset) = 0;
72 
73   // Interrupt our peer, causing it to scan the outgoing_signal_table
74   virtual bool InterruptPeer() = 0;
75 
76   // Wake the local signal table scanner. Primarily used during shutdown
77   virtual void InterruptSelf() = 0;
78 
79   // Maps the entire region at an address, returning a pointer to the mapping
80   virtual void* Map() = 0;
81 
82   // Wait for an interrupt from our peer
83   virtual void WaitForInterrupt() = 0;
84 
85   // Signals local waiters at the given region offset.
86   // Defined only on the guest.
87   // Return value is negative on error.
88   virtual int SignalSelf(uint32_t offset) = 0;
89 
90   // Waits for a signal at the given region offset.
91   // Defined only on the guest.
92   // Return value is negative on error. The number of false wakes is returned
93   // on success.
94   virtual int WaitForSignal(uint32_t offset, uint32_t expected_value) = 0;
95 
96   template <typename T>
region_offset_to_pointer(uint32_t offset)97   T* region_offset_to_pointer(uint32_t offset) {
98     if (offset > region_size()) {
99       LOG(FATAL) << __FUNCTION__ << ": " << offset << " not in region @"
100                  << region_base_;
101     }
102     return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(region_base_) +
103                                 offset);
104   }
105 
106  protected:
RegionControl()107   RegionControl() {}
108   void* region_base_{};
109   vsoc_device_region region_desc_{};
110 };
111 }  // namespace vsoc
112