Home | History | Annotate | Download | only in lib
      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:
     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 
     52   const vsoc_device_region& region_desc() const { return region_desc_; }
     53 
     54   // Returns the size of the entire region, including the signal tables.
     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.
     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>
     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:
    107   RegionControl() {}
    108   void* region_base_{};
    109   vsoc_device_region region_desc_{};
    110 };
    111 }  // namespace vsoc
    112