blob: 890a1cbfd0f55dd57de594c8d5d3f8eff85c325c [file] [log] [blame]
Yahan Zhou41050592016-07-28 16:31:59 -07001/*
2* Copyright (C) 2016 The Android Open Source Project
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*/
16
Yilong Li46669082020-01-14 16:22:57 -080017#include "ProcessPipe.h"
Gurchetan Singh8ed85562023-09-06 16:56:28 -070018
19#include <errno.h>
20#include <log/log.h>
21#include <pthread.h>
22#include <qemu_pipe_bp.h>
23
Yilong Li2b3e1782020-10-22 12:21:45 -070024#include "HostConnection.h"
Yahan Zhoue8cf63d2016-09-22 12:33:50 -070025#include "renderControl_enc.h"
Roman Kiryanov04cdd7b2020-04-28 13:22:29 -070026
Gurchetan Singh8ed85562023-09-06 16:56:28 -070027#ifndef __Fuchsia__
Lingfeng Yang9c26ebf2019-12-30 09:14:49 -080028
29#include "VirtioGpuPipeStream.h"
30static VirtioGpuPipeStream* sVirtioGpuPipeStream = 0;
Gurchetan Singh6adffbd2022-03-16 19:22:19 -070031static int sStreamHandle = -1;
Lingfeng Yang9c26ebf2019-12-30 09:14:49 -080032
33#endif // !__Fuchsia__
David Reveman5e2e8422019-05-02 15:48:15 -040034
Gurchetan Singh8ed85562023-09-06 16:56:28 -070035static QEMU_PIPE_HANDLE sProcPipe = 0;
Yahan Zhou41050592016-07-28 16:31:59 -070036// sProcUID is a unique ID per process assigned by the host.
37// It is different from getpid().
38static uint64_t sProcUID = 0;
Gurchetan Singh8ed85562023-09-06 16:56:28 -070039static HostConnectionType sConnType = HOST_CONNECTION_VIRTIO_GPU_PIPE;
Yahan Zhou41050592016-07-28 16:31:59 -070040
Lingfeng Yang77fdf252021-01-22 17:48:00 -080041static uint32_t* sSeqnoPtr = 0;
42
43// Meant to be called only once per process.
Gurchetan Singh8ed85562023-09-06 16:56:28 -070044static void initSeqno(void) {
Lingfeng Yang77fdf252021-01-22 17:48:00 -080045 // So why do we reinitialize here? It's for testing purposes only;
46 // we have a unit test that exercise the case where this sequence
47 // number is reset as a result of guest process kill.
48 if (sSeqnoPtr) delete sSeqnoPtr;
49 sSeqnoPtr = new uint32_t;
50 *sSeqnoPtr = 0;
51}
52
C Stout5a3a4222023-11-14 16:31:56 -080053namespace {
54
55static std::mutex sNeedInitMutex;
56static bool sNeedInit = true;
57
58} // namespace
59
Gurchetan Singh8ed85562023-09-06 16:56:28 -070060#ifndef __Fuchsia__
Lingfeng Yang9c26ebf2019-12-30 09:14:49 -080061
62static void sQemuPipeInit() {
Yahan Zhou41050592016-07-28 16:31:59 -070063 sProcPipe = qemu_pipe_open("GLProcessPipe");
Lingfeng Yange38d15c2018-09-24 16:24:01 -070064 if (!qemu_pipe_valid(sProcPipe)) {
Yahan Zhou41050592016-07-28 16:31:59 -070065 sProcPipe = 0;
66 ALOGW("Process pipe failed");
67 return;
68 }
69 // Send a confirmation int to the host
70 int32_t confirmInt = 100;
Roman Kiryanov6e05b7f2020-10-16 14:25:52 -070071 if (qemu_pipe_write_fully(sProcPipe, &confirmInt, sizeof(confirmInt))) { // failed
Lingfeng Yange38d15c2018-09-24 16:24:01 -070072 qemu_pipe_close(sProcPipe);
Yahan Zhou41050592016-07-28 16:31:59 -070073 sProcPipe = 0;
74 ALOGW("Process pipe failed");
75 return;
76 }
77
78 // Ask the host for per-process unique ID
Roman Kiryanov6e05b7f2020-10-16 14:25:52 -070079 if (qemu_pipe_read_fully(sProcPipe, &sProcUID, sizeof(sProcUID))) {
Lingfeng Yange38d15c2018-09-24 16:24:01 -070080 qemu_pipe_close(sProcPipe);
Yahan Zhou41050592016-07-28 16:31:59 -070081 sProcPipe = 0;
82 sProcUID = 0;
83 ALOGW("Process pipe failed");
84 return;
85 }
86}
87
C Stout5a3a4222023-11-14 16:31:56 -080088#endif // !__Fuchsia__
Jason Macnakaca4cdb2023-06-14 12:57:10 -070089
Gurchetan Singh99288832023-09-07 09:40:10 -070090static void processPipeDoInit(uint32_t noRenderControlEnc) {
Lingfeng Yang77fdf252021-01-22 17:48:00 -080091 initSeqno();
92
Gurchetan Singh99288832023-09-07 09:40:10 -070093 // No need to setup auxiliary pipe stream in this case
94 if (noRenderControlEnc) return;
95
C Stout5a3a4222023-11-14 16:31:56 -080096#if defined(__Fuchsia__)
97 // Note: sProcUID is not initialized.
98 ALOGE("Fuchsia: requires noRenderControlEnc");
99 abort();
100#else
Lingfeng Yang9c26ebf2019-12-30 09:14:49 -0800101 switch (sConnType) {
102 // TODO: Move those over too
103 case HOST_CONNECTION_QEMU_PIPE:
104 case HOST_CONNECTION_ADDRESS_SPACE:
Lingfeng Yang9c26ebf2019-12-30 09:14:49 -0800105 sQemuPipeInit();
106 break;
Lingfeng Yang667e8ee2020-05-27 14:10:11 -0700107 case HOST_CONNECTION_VIRTIO_GPU_PIPE:
108 case HOST_CONNECTION_VIRTIO_GPU_ADDRESS_SPACE: {
Gurchetan Singh6adffbd2022-03-16 19:22:19 -0700109 sVirtioGpuPipeStream = new VirtioGpuPipeStream(4096, sStreamHandle);
Lingfeng Yang9c26ebf2019-12-30 09:14:49 -0800110 sProcUID = sVirtioGpuPipeStream->initProcessPipe();
111 break;
112 }
113 }
C Stout5a3a4222023-11-14 16:31:56 -0800114#endif
Lingfeng Yang9c26ebf2019-12-30 09:14:49 -0800115}
Lingfeng Yang9c26ebf2019-12-30 09:14:49 -0800116
Gurchetan Singh99288832023-09-07 09:40:10 -0700117bool processPipeInit(int streamHandle, HostConnectionType connType, uint32_t noRenderControlEnc) {
Lingfeng Yang9c26ebf2019-12-30 09:14:49 -0800118 sConnType = connType;
Yilong Li7907feb2022-04-01 15:54:46 -0700119#ifndef __Fuchsia__
Gurchetan Singh6adffbd2022-03-16 19:22:19 -0700120 sStreamHandle = streamHandle;
Yilong Li7907feb2022-04-01 15:54:46 -0700121#endif // !__Fuchsia
Jason Macnakaca4cdb2023-06-14 12:57:10 -0700122
123 {
124 std::lock_guard<std::mutex> lock(sNeedInitMutex);
125
126 if (sNeedInit) {
127 sNeedInit = false;
Gurchetan Singh99288832023-09-07 09:40:10 -0700128 processPipeDoInit(noRenderControlEnc);
129
130 if (noRenderControlEnc) {
131 return true;
132 }
Jason Macnakaca4cdb2023-06-14 12:57:10 -0700133
Gurchetan Singh8ed85562023-09-06 16:56:28 -0700134#ifndef __Fuchsia__
Jason Macnakaca4cdb2023-06-14 12:57:10 -0700135 if (!sProcPipe && !sVirtioGpuPipeStream) {
136 return false;
137 }
138#endif
139 }
140 }
141
Yahan Zhoue8cf63d2016-09-22 12:33:50 -0700142 return true;
Lingfeng Yang88c170c2016-11-30 00:52:35 +0000143}
Lingfeng Yangc49d89d2020-08-20 12:33:04 -0700144
145uint64_t getPuid() {
146 return sProcUID;
147}
Lingfeng Yang25bca5a2020-10-21 09:52:10 -0700148
149void processPipeRestart() {
Jason Macnakaca4cdb2023-06-14 12:57:10 -0700150 std::lock_guard<std::mutex> lock(sNeedInitMutex);
151
Lingfeng Yang25bca5a2020-10-21 09:52:10 -0700152 ALOGW("%s: restarting process pipe\n", __func__);
153 bool isPipe = false;
154
155 switch (sConnType) {
156 // TODO: Move those over too
157 case HOST_CONNECTION_QEMU_PIPE:
158 case HOST_CONNECTION_ADDRESS_SPACE:
Lingfeng Yang25bca5a2020-10-21 09:52:10 -0700159 isPipe = true;
160 break;
161 case HOST_CONNECTION_VIRTIO_GPU_PIPE:
162 case HOST_CONNECTION_VIRTIO_GPU_ADDRESS_SPACE: {
163 isPipe = false;
164 break;
165 }
166 }
167
168 sProcUID = 0;
169
170 if (isPipe) {
171 if (qemu_pipe_valid(sProcPipe)) {
172 qemu_pipe_close(sProcPipe);
173 sProcPipe = 0;
174 }
175 } else {
C Stout5a3a4222023-11-14 16:31:56 -0800176#ifndef __Fuchsia__
Jason Macnak843b84b2023-05-19 14:19:25 -0700177 if (sVirtioGpuPipeStream) {
178 delete sVirtioGpuPipeStream;
179 sVirtioGpuPipeStream = nullptr;
180 }
C Stout5a3a4222023-11-14 16:31:56 -0800181#endif
Lingfeng Yang25bca5a2020-10-21 09:52:10 -0700182 }
183
Jason Macnak459dd872023-09-13 08:27:41 -0700184 if (sConnType == HOST_CONNECTION_VIRTIO_GPU_PIPE ||
185 sConnType == HOST_CONNECTION_VIRTIO_GPU_ADDRESS_SPACE) {
186 VirtGpuDevice::resetInstance();
187 }
Lingfeng Yang25bca5a2020-10-21 09:52:10 -0700188
Jason Macnak459dd872023-09-13 08:27:41 -0700189 sNeedInit = true;
Jason Macnak843b84b2023-05-19 14:19:25 -0700190}
191
Lingfeng Yang25bca5a2020-10-21 09:52:10 -0700192void refreshHostConnection() {
193 HostConnection* hostConn = HostConnection::get();
194 ExtendedRCEncoderContext* rcEnc = hostConn->rcEncoder();
195 rcEnc->rcSetPuid(rcEnc, sProcUID);
196}
Lingfeng Yang77fdf252021-01-22 17:48:00 -0800197
198uint32_t* getSeqnoPtrForProcess() {
199 // It's assumed process pipe state has already been initialized.
200 return sSeqnoPtr;
201}