1 // Copyright 2019 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #pragma once
15 
16 #include "aemu/base/Compiler.h"
17 #include "aemu/base/containers/StaticMap.h"
18 #include "aemu/base/export.h"
19 #include "aemu/base/ManagedDescriptor.hpp"
20 #include "vm_operations.h"
21 
22 #include <atomic>
23 
24 #include <inttypes.h>
25 #include <unordered_map>
26 #include <optional>
27 
28 // A global mapping from opaque host memory IDs to host virtual
29 // addresses/sizes.  This is so that the guest doesn't have to know the host
30 // virtual address to be able to map them. However, we do also provide a
31 // mechanism for obtaining the offsets into page for such buffers (as the guest
32 // does need to know those).
33 //
34 // This is currently used only in conjunction with virtio-gpu-next and Vulkan /
35 // address space device, though there are possible other consumers of this, so
36 // it becomes a global object. It exports methods into VmOperations.
37 
38 using android::base::ManagedDescriptor;
39 
40 namespace android {
41 namespace emulation {
42 
43 #define STREAM_MEM_HANDLE_TYPE_OPAQUE_FD 0x1
44 #define STREAM_MEM_HANDLE_TYPE_DMABUF 0x2
45 #define STREAM_MEM_HANDLE_TYPE_OPAQUE_WIN32 0x3
46 #define STREAM_MEM_HANDLE_TYPE_SHM 0x4
47 #define STREAM_MEM_HANDLE_TYPE_ZIRCON 0x5
48 #define STREAM_FENCE_HANDLE_TYPE_OPAQUE_FD 0x6
49 #define STREAM_FENCE_HANDLE_TYPE_SYNC_FD 0x7
50 #define STREAM_FENCE_HANDLE_TYPE_OPAQUE_WIN32 0x8
51 #define STREAM_FENCE_HANDLE_TYPE_ZIRCON 0x9
52 
53 struct VulkanInfo {
54     uint32_t memoryIndex;
55     uint8_t deviceUUID[16];
56     uint8_t driverUUID[16];
57 };
58 
59 struct ManagedDescriptorInfo {
60     ManagedDescriptor descriptor;
61     uint32_t handleType;
62     uint32_t caching;
63     std::optional<VulkanInfo> vulkanInfoOpt;
64 };
65 
66 class HostmemIdMapping {
67 public:
68     HostmemIdMapping() = default;
69 
70     AEMU_EXPORT static HostmemIdMapping* get();
71 
72     using Id = uint64_t;
73     using Entry = HostmemEntry;
74 
75     static const Id kInvalidHostmemId;
76 
77     // Returns kInvalidHostmemId if hva or size is 0.
78     AEMU_EXPORT Id add(const struct MemEntry *entry);
79 
80     // No-op if kInvalidHostmemId or a nonexistent entry
81     // is referenced.
82     AEMU_EXPORT void remove(Id id);
83 
84     void addMapping(Id id, const struct MemEntry *entry);
85     void addDescriptorInfo(Id id, ManagedDescriptor descriptor, uint32_t handleType,
86                            uint32_t caching, std::optional<VulkanInfo> vulkanInfoOpt);
87 
88     std::optional<ManagedDescriptorInfo> removeDescriptorInfo(Id id);
89 
90     // If id == kInvalidHostmemId or not found in map,
91     // returns entry with id == kInvalidHostmemId,
92     // hva == 0, and size == 0.
93     AEMU_EXPORT Entry get(Id id) const;
94 
95     // Restores to starting state where there are no entries.
96     AEMU_EXPORT void clear();
97 
98 private:
99     std::atomic<Id> mCurrentId {1};
100     base::StaticMap<Id, Entry> mEntries;
101     std::unordered_map<Id, ManagedDescriptor> mDescriptors;
102     std::unordered_map<Id, ManagedDescriptorInfo> mDescriptorInfos;
103     DISALLOW_COPY_ASSIGN_AND_MOVE(HostmemIdMapping);
104 };
105 
106 } // namespace android
107 } // namespace emulation
108 
109 // C interface for use with vm operations
110 extern "C" {
111 
112 AEMU_EXPORT uint64_t android_emulation_hostmem_register(const struct MemEntry *entry);
113 AEMU_EXPORT void android_emulation_hostmem_unregister(uint64_t id);
114 AEMU_EXPORT HostmemEntry android_emulation_hostmem_get_info(uint64_t id);
115 
116 } // extern "C"
117