1 // Copyright 2020 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
15 #include "AndroidPipe.h"
16 #include "android_pipe_base.h"
17
18 #include "aemu/base/Optional.h"
19 #include "aemu/base/StringFormat.h"
20 #include "aemu/base/files/MemStream.h"
21 #include "aemu/base/synchronization/Lock.h"
22 #include "android_pipe_device.h"
23 #include "android_pipe_host.h"
24 #include "host-common/GfxstreamFatalError.h"
25 #include "DeviceContextRunner.h"
26 #include "VmLock.h"
27
28 #include <algorithm>
29 #include <memory>
30 #include <string>
31 #include <vector>
32 #include <unordered_set>
33
34 #include <assert.h>
35 #include <string.h>
36
37 #define DEBUG 0
38
39 #if DEBUG >= 1
40 #include <stdio.h>
41 #define D(...) fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n")
42 #else
43 #define D(...) (void)0
44 #endif
45
46 #if DEBUG >= 2
47 #define DD(...) fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n")
48 #else
49 #define DD(...) (void)0
50 #endif
51
52 #define E(...) fprintf(stderr, "ERROR:" __VA_ARGS__), fprintf(stderr, "\n")
53
getPipeHwFuncs(const void * hwPipe)54 static const AndroidPipeHwFuncs* getPipeHwFuncs(const void* hwPipe) {
55 return *static_cast<const AndroidPipeHwFuncs* const *>(hwPipe);
56 }
57
58 using namespace android::base;
59
60 using AndroidPipe = android::AndroidPipe;
61 using BaseStream = android::base::Stream;
62 using CStream = ::Stream;
63 using OptionalString = android::base::Optional<std::string>;
64 using Service = android::AndroidPipe::Service;
65 using ServiceList = std::vector<std::unique_ptr<Service>>;
66 using VmLock = android::VmLock;
67 using android::base::MemStream;
68 using android::base::StringFormat;
69 using emugl::ABORT_REASON_OTHER;
70 using emugl::FatalError;
71
asBaseStream(CStream * stream)72 static BaseStream* asBaseStream(CStream* stream) {
73 return reinterpret_cast<BaseStream*>(stream);
74 }
75
76 #define CHECK_VM_STATE_LOCK() (void)0
77 // b/294378605: Need to implement VM_STATE_LOCK and VM_STATE_UNLOCK for qemu. We leave this empty
78 // for now since qemu provides its own implementation of AndroidPipe.cpp.
79 #define VM_STATE_LOCK() (void)0
80 #define VM_STATE_UNLOCK() (void)0
81
82 namespace android {
83
84 namespace {
85
isPipeOptional(const std::string & name)86 static bool isPipeOptional(const std::string& name) {
87 return name == "OffworldPipe";
88 }
89
90 // Write an optional string |str| to |stream|. |str| can be null. Use
91 // readOptionalString() to read it back later.
writeOptionalString(BaseStream * stream,const char * str)92 static void writeOptionalString(BaseStream* stream, const char* str) {
93 if (str) {
94 stream->putByte(1);
95 stream->putString(str);
96 } else {
97 stream->putByte(0);
98 }
99 }
100
101 // Read an optional string from |stream|. If the result is not constructed
102 // (i.e. equals to false), this means the original |str| parameter was null.
readOptionalString(BaseStream * stream)103 static OptionalString readOptionalString(BaseStream* stream) {
104 if (stream->getByte()) {
105 return OptionalString(stream->getString());
106 }
107 return OptionalString();
108 }
109
110 // forward
111 Service* findServiceByName(const char* name);
112
113 // Implementation of a special AndroidPipe class used to model the state
114 // of a pipe connection before the service name has been written to the
115 // file descriptor by the guest. The most important method is onGuestSend()
116 // which will detect when this happens.
117 class ConnectorPipe : public AndroidPipe {
118 public:
ConnectorPipe(void * hwPipe,Service * service)119 ConnectorPipe(void* hwPipe, Service* service)
120 : AndroidPipe(hwPipe, service) {
121 DD("%s: Creating new ConnectorPipe hwpipe=%p", __FUNCTION__, mHwPipe);
122 }
123
onGuestClose(PipeCloseReason reason)124 virtual void onGuestClose(PipeCloseReason reason) override {
125 // nothing to do here
126 DD("%s: closing ConnectorPipe hwpipe=%p prematurily (reason=%d)!",
127 __func__, mHwPipe, (int)reason);
128 }
129
onGuestPoll() const130 virtual unsigned onGuestPoll() const override {
131 // A connector always want to receive data.
132 DD("%s: polling hwpipe=%p", __FUNCTION__, mHwPipe);
133 return PIPE_POLL_OUT;
134 }
135
onGuestRecv(AndroidPipeBuffer * buffers,int numBuffers)136 virtual int onGuestRecv(AndroidPipeBuffer* buffers,
137 int numBuffers) override {
138 // This pipe never wants to write to the guest, so getting there
139 // is an error since PIPE_WAKE_IN is never signaled.
140 DD("%s: trying to receive data from hwpipe=%p", __FUNCTION__, mHwPipe);
141 return PIPE_ERROR_IO;
142 }
143
144 // TECHNICAL NOTE: This function reads data from the guest until it
145 // finds a zero-terminated C-string. After that it parses it to find
146 // a registered service corresponding to one of the allowed formats
147 // (see below). In case of success, this creates a new AndroidPipe
148 // instance and calls AndroidPipeHwFuncs::resetPipe() to associate it with
149 // the current hardware-side |mHwPipe|, then *deletes* the current
150 // instance! In case of error (e.g. invalid service name, or error during
151 // initialization), PIPE_ERROR_INVAL will be returned, otherwise, the
152 // number of bytes accepted from the guest is returned.
onGuestSend(const AndroidPipeBuffer * buffers,int numBuffers,void ** newPipePtr)153 virtual int onGuestSend(const AndroidPipeBuffer* buffers,
154 int numBuffers,
155 void** newPipePtr) override {
156 int result = 0;
157 size_t avail = kBufferSize - mPos;
158 bool foundZero = false;
159 for (; !foundZero && avail > 0 && numBuffers > 0;
160 buffers++, numBuffers--) {
161 const uint8_t* data = buffers[0].data;
162 size_t count = std::min(avail, buffers[0].size);
163 // Read up to |count| bytes, stopping after the first zero.
164 size_t n = 0;
165 while (n < count) {
166 uint8_t byte = data[n++];
167 mBuffer[mPos++] = (char) byte;
168 if (!byte) {
169 foundZero = true;
170 break;
171 }
172 }
173 result += static_cast<int>(n);
174 avail -= n;
175 }
176 DD("%s: receiving %d connection bytes from hwpipe=%p", __FUNCTION__,
177 result, mHwPipe);
178
179 if (!foundZero) {
180 if (avail == 0) {
181 DD("%s: service name buffer full, force-closing connection",
182 __FUNCTION__);
183 return PIPE_ERROR_IO;
184 }
185 // Still waiting for terminating zero.
186 DD("%s: still waiting for terminating zero!", __FUNCTION__);
187 return result;
188 }
189
190 // Acceptable formats for the connection string are:
191 //
192 // pipe:<name>
193 // pipe:<name>:<arguments>
194 //
195 char* pipeName;
196 char* pipeArgs;
197
198 D("%s: connector: '%s'", __FUNCTION__, mBuffer);
199 if (memcmp(mBuffer, "pipe:", 5) != 0) {
200 // Nope, we don't handle these for now.
201 D("%s: Unknown pipe connection: '%s'", __FUNCTION__, mBuffer);
202 return PIPE_ERROR_INVAL;
203 }
204
205 pipeName = mBuffer + 5;
206 pipeArgs = strchr(pipeName, ':');
207
208 Service* svc = nullptr;
209
210 // As a special case, if the service name is as:
211 // qemud:<name>
212 // qemud:<name>:args
213 //
214 // First look for a registered pipe service named "qemud:<name>"
215 // and if not found, fallback to "qemud" only.
216 //
217 // This is useful to support qemud services that are now served
218 // by a dedicated (and faster) pipe service, e.g. 'qemud:adb'
219 // as currently implemented by QEMU2 (and soon by QEMU1).
220 static const char kQemudPrefix[] = "qemud:";
221 const size_t kQemudPrefixSize = sizeof(kQemudPrefix) - 1U;
222
223 if (!::strncmp(pipeName, kQemudPrefix, kQemudPrefixSize)) {
224 assert(pipeArgs == pipeName + kQemudPrefixSize - 1);
225 char* pipeArgs2 = strchr(pipeArgs + 1, ':');
226 if (pipeArgs2) {
227 *pipeArgs2 = '\0';
228 }
229 svc = findServiceByName(pipeName);
230 if (svc) {
231 pipeArgs = pipeArgs2;
232 } else if (pipeArgs2) {
233 // Restore colon.
234 *pipeArgs2 = ':';
235 }
236 }
237 if (pipeArgs) {
238 *pipeArgs++ = '\0';
239 if (!pipeArgs) {
240 pipeArgs = NULL;
241 }
242 }
243
244 if (!svc) {
245 svc = findServiceByName(pipeName);
246 }
247
248 if (!svc) {
249 D("%s: Unknown server with name %s!", __FUNCTION__, pipeName);
250 return PIPE_ERROR_INVAL;
251 }
252
253 AndroidPipe* newPipe = svc->create(mHwPipe, pipeArgs, mFlags);
254 if (!newPipe) {
255 D("%s: Initialization failed for %s pipe!", __FUNCTION__, pipeName);
256 return PIPE_ERROR_INVAL;
257 }
258
259 // Swap your host-side pipe instance with this one weird trick!
260 D("%s: starting new pipe %p (swapping %p) for service %s",
261 __FUNCTION__,
262 newPipe,
263 mHwPipe,
264 pipeName);
265
266 newPipe->setFlags(mFlags);
267 *newPipePtr = newPipe;
268 delete this;
269
270 return result;
271 }
272
onGuestWantWakeOn(int wakeFlags)273 virtual void onGuestWantWakeOn(int wakeFlags) override {
274 // nothing to do here
275 DD("%s: signaling wakeFlags=%d for hwpipe=%p", __FUNCTION__, wakeFlags,
276 mHwPipe);
277 }
278
onSave(BaseStream * stream)279 virtual void onSave(BaseStream* stream) override {
280 DD("%s: saving connector state for hwpipe=%p", __FUNCTION__, mHwPipe);
281 stream->putBe32(mPos);
282 stream->write(mBuffer, mPos);
283 }
284
onLoad(BaseStream * stream)285 bool onLoad(BaseStream* stream) {
286 DD("%s: loading connector state for hwpipe=%p", __FUNCTION__, mHwPipe);
287 int32_t len = stream->getBe32();
288 if (len < 0 || len > kBufferSize) {
289 D("%s: invalid length %d (expected 0 <= len <= %d)", __FUNCTION__,
290 static_cast<int>(len), kBufferSize);
291 return false;
292 }
293 mPos = (int)len;
294 int ret = (int)stream->read(mBuffer, mPos);
295 DD("%s: read %d bytes (%d expected)", __FUNCTION__, ret, mPos);
296 return (ret == mPos);
297 }
298
299 private:
300 static constexpr int kBufferSize = 128;
301 char mBuffer[kBufferSize];
302 int mPos = 0;
303 };
304
305 // Associated AndroidPipe::Service class for ConnectorPipe instances.
306 class ConnectorService : public Service {
307 public:
ConnectorService()308 ConnectorService() : Service("<connector>") {}
309
create(void * hwPipe,const char * args,enum AndroidPipeFlags flags)310 AndroidPipe* create(void* hwPipe, const char* args,
311 enum AndroidPipeFlags flags) override {
312 return new ConnectorPipe(hwPipe, this);
313 }
314
canLoad() const315 virtual bool canLoad() const override { return true; }
316
load(void * hwPipe,const char * args,BaseStream * stream)317 virtual AndroidPipe* load(void* hwPipe,
318 const char* args,
319 BaseStream* stream) override {
320 ConnectorPipe* pipe = new ConnectorPipe(hwPipe, this);
321 if (!pipe->onLoad(stream)) {
322 delete pipe;
323 return nullptr;
324 }
325 return pipe;
326 }
327 };
328
329 // A helper class used to send signalWake() and closeFromHost() commands to
330 // the device thread, depending on the threading mode setup by the emulation
331 // engine.
332 struct PipeWakeCommand {
333 void* hwPipe;
334 int wakeFlags;
335 };
336
337 class PipeWaker final : public DeviceContextRunner<PipeWakeCommand> {
338 public:
signalWake(void * hwPipe,int wakeFlags)339 void signalWake(void* hwPipe, int wakeFlags) {
340 queueDeviceOperation({ hwPipe, wakeFlags });
341 }
closeFromHost(void * hwPipe)342 void closeFromHost(void* hwPipe) {
343 signalWake(hwPipe, PIPE_WAKE_CLOSED);
344 }
abortPending(void * hwPipe)345 void abortPending(void* hwPipe) {
346 removeAllPendingOperations([hwPipe](const PipeWakeCommand& cmd) {
347 return cmd.hwPipe == hwPipe;
348 });
349 }
abortAllPending()350 void abortAllPending() {
351 removeAllPendingOperations([](const PipeWakeCommand& cmd) {
352 return true;
353 });
354 }
355
getPendingFlags(void * hwPipe) const356 int getPendingFlags(void* hwPipe) const {
357 int flags = 0;
358 forEachPendingOperation([hwPipe, &flags](const PipeWakeCommand& cmd) {
359 if (cmd.hwPipe == hwPipe) {
360 flags |= cmd.wakeFlags;
361 }
362 });
363 return flags;
364 }
365
366 private:
performDeviceOperation(const PipeWakeCommand & wake_cmd)367 virtual void performDeviceOperation(const PipeWakeCommand& wake_cmd) {
368 void* hwPipe = wake_cmd.hwPipe;
369 int flags = wake_cmd.wakeFlags;
370
371 // Not used when in virtio mode.
372 if (flags & PIPE_WAKE_CLOSED) {
373 getPipeHwFuncs(hwPipe)->closeFromHost(hwPipe);
374 } else {
375 getPipeHwFuncs(hwPipe)->signalWake(hwPipe, flags);
376 }
377 }
378 };
379
380 struct Globals {
381 ServiceList services;
382 ConnectorService connectorService;
383 PipeWaker pipeWaker;
384
385 // Searches for a service position in the |services| list and returns the
386 // index. |startPosHint| is a _hint_ and suggests where to start from.
387 // Returns the index of the service or -1 if there's no |name| service.
findServicePositionByNameandroid::__anon7fee7eb60111::Globals388 int findServicePositionByName(const char* name,
389 const int startPosHint = 0) const {
390 const auto searchByNameFunc =
391 [name](const std::unique_ptr<Service>& service) {
392 return service->name() == name;
393 };
394
395 // First, try to search starting from the hint position.
396 auto end = services.end();
397 auto it = std::find_if(services.begin() + startPosHint, end,
398 searchByNameFunc);
399
400 // If there was a hint that didn't help, continue searching from the
401 // beginning of the contatiner to check the rest of it.
402 if (it == end && startPosHint > 0) {
403 end = services.begin() + startPosHint;
404 it = std::find_if(services.begin(), end, searchByNameFunc);
405 }
406
407 return it == end ? -1 : it - services.begin();
408 }
409
loadServiceByNameandroid::__anon7fee7eb60111::Globals410 Service* loadServiceByName(BaseStream* stream) {
411 OptionalString serviceName = readOptionalString(stream);
412 if (!serviceName) {
413 DD("%s: no name (assuming connector state)", __FUNCTION__);
414 return &connectorService;
415 }
416 DD("%s: found [%s]", __FUNCTION__, serviceName->c_str());
417 return findServiceByName(serviceName->c_str());
418 }
419 };
420
sGlobals()421 static Globals* sGlobals() { static Globals* g = new Globals; return g; }
422
findServiceByName(const char * name)423 Service* findServiceByName(const char* name) {
424 const int pos = sGlobals()->findServicePositionByName(name);
425 return pos < 0 ? nullptr : sGlobals()->services[pos].get();
426 }
427
loadPipeFromStreamCommon(BaseStream * stream,void * hwPipe,Service * service,char * pForceClose)428 AndroidPipe* loadPipeFromStreamCommon(BaseStream* stream,
429 void* hwPipe,
430 Service* service,
431 char* pForceClose) {
432 *pForceClose = 0;
433
434 OptionalString args = readOptionalString(stream);
435 AndroidPipe* pipe = nullptr;
436 if (service->canLoad()) {
437 DD("%s: loading state for [%s] hwpipe=%p", __FUNCTION__,
438 service->name().c_str(), hwPipe);
439 pipe = service->load(hwPipe, args ? args->c_str() : nullptr, stream);
440 if (!pipe) {
441 *pForceClose = 1;
442 }
443 } else {
444 DD("%s: force-closing hwpipe=%p", __FUNCTION__, hwPipe);
445 *pForceClose = 1;
446 }
447
448 const int pendingFlags = stream->getBe32();
449 if (pendingFlags && pipe && !*pForceClose) {
450 if (!hwPipe) {
451 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
452 << "fatal: AndroidPipe [" << pipe->name() << "] hwPipe is NULL(flags = 0x"
453 << std::hex << unsigned(pendingFlags) << " )";
454 }
455 sGlobals()->pipeWaker.signalWake(hwPipe, pendingFlags);
456 DD("%s: singalled wake flags %d for pipe hwpipe=%p", __func__,
457 pendingFlags, hwPipe);
458 }
459
460 return pipe;
461 }
462
463 } // namespace
464
465 // static
initThreading(VmLock * vmLock)466 void AndroidPipe::initThreading(VmLock* vmLock) {
467 // TODO: Make this work in qemu with the actual goldfish pipe device.
468 // In virtio land, this won't be needed, so include trivial timer interface.
469 sGlobals()->pipeWaker.init(vmLock, {
470 // installFunc
471 [](DeviceContextRunner<PipeWakeCommand>* dcr, std::function<void()> installedFunc) {
472 (void)dcr;
473 (void)installedFunc;
474 },
475 // uninstallFunc
476 [](DeviceContextRunner<PipeWakeCommand>* dcr) {
477 (void)dcr;
478 },
479 // startWithTimeoutFunc
480 [](DeviceContextRunner<PipeWakeCommand>* dcr, uint64_t timeout) {
481 (void)dcr;
482 (void)timeout;
483 }
484 });
485 }
486
~AndroidPipe()487 AndroidPipe::~AndroidPipe() {
488 DD("%s: for hwpipe=%p (host %p '%s')", __FUNCTION__, mHwPipe, this,
489 mService->name().c_str());
490 }
491
492 // static
add(std::unique_ptr<Service> service)493 void AndroidPipe::Service::add(std::unique_ptr<Service> service) {
494 DD("Adding new pipe service '%s' this=%p", service->name().c_str(),
495 service.get());
496 sGlobals()->services.push_back(std::move(service));
497 }
498
499 // static
resetAll()500 void AndroidPipe::Service::resetAll() {
501 DD("Resetting all pipe services");
502 sGlobals()->services.clear();
503 }
504
signalWake(int wakeFlags)505 void AndroidPipe::signalWake(int wakeFlags) {
506 // i.e., pipe not using normal pipe device
507 if (mFlags) return;
508 if (!mHwPipe) {
509 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
510 << "AndroidPipe [" << name() << "]: hwPipe is NULL (flags = 0x" << std::hex
511 << unsigned(wakeFlags) << ")";
512 }
513 sGlobals()->pipeWaker.signalWake(mHwPipe, wakeFlags);
514 }
515
closeFromHost()516 void AndroidPipe::closeFromHost() {
517 // i.e., pipe not using normal pipe device
518 if (mFlags) return;
519 if (!mHwPipe) {
520 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
521 << "AndroidPipe [" << name() << "]: hwPipe is NULL";
522 }
523 sGlobals()->pipeWaker.closeFromHost(mHwPipe);
524 }
525
abortPendingOperation()526 void AndroidPipe::abortPendingOperation() {
527 // i.e., pipe not using normal pipe device
528 if (mFlags) return;
529
530 if (!mHwPipe) {
531 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
532 << "AndroidPipe [" << name() << "]: hwPipe is NULL";
533 }
534 sGlobals()->pipeWaker.abortPending(mHwPipe);
535 }
536
saveToStream(BaseStream * stream)537 void AndroidPipe::saveToStream(BaseStream* stream) {
538 // First, write service name.
539 if (mService == &sGlobals()->connectorService) {
540 // A connector pipe
541 stream->putByte(0);
542 } else {
543 // A regular service pipe.
544 stream->putByte(1);
545 stream->putString(mService->name());
546 }
547
548 MemStream pipeStream;
549 writeOptionalString(&pipeStream, mArgs.c_str());
550
551 // Save pipe-specific state now.
552 if (mService->canLoad()) {
553 mService->savePipe(this, &pipeStream);
554 }
555
556 // Save the pending wake or close operations as well.
557 const int pendingFlags = sGlobals()->pipeWaker.getPendingFlags(mHwPipe);
558 pipeStream.putBe32(pendingFlags);
559
560 pipeStream.save(stream);
561 }
562
563 // static
loadFromStream(BaseStream * stream,void * hwPipe,char * pForceClose)564 AndroidPipe* AndroidPipe::loadFromStream(BaseStream* stream,
565 void* hwPipe,
566 char* pForceClose) {
567 Service* service = sGlobals()->loadServiceByName(stream);
568 // Always load the pipeStream, it allows us to safely skip loading streams.
569 MemStream pipeStream;
570 pipeStream.load(stream);
571
572 if (!service) {
573 return nullptr;
574 }
575 return loadPipeFromStreamCommon(&pipeStream, hwPipe, service, pForceClose);
576 }
577
578 // static
loadFromStreamLegacy(BaseStream * stream,void * hwPipe,uint64_t * pChannel,unsigned char * pWakes,unsigned char * pClosed,char * pForceClose)579 AndroidPipe* AndroidPipe::loadFromStreamLegacy(BaseStream* stream,
580 void* hwPipe,
581 uint64_t* pChannel,
582 unsigned char* pWakes,
583 unsigned char* pClosed,
584 char* pForceClose) {
585 Service* service = sGlobals()->loadServiceByName(stream);
586 // Always load the pipeStream, it allows us to safely skip loading streams.
587 MemStream pipeStream;
588 pipeStream.load(stream);
589
590 if (!service) {
591 return nullptr;
592 }
593 *pChannel = pipeStream.getBe64();
594 *pWakes = pipeStream.getByte();
595 *pClosed = pipeStream.getByte();
596
597 return loadPipeFromStreamCommon(&pipeStream, hwPipe, service, pForceClose);
598 }
599
600 } // namespace android
601
602 // API for the virtual device.
603
android_pipe_reset_services()604 void android_pipe_reset_services() {
605 AndroidPipe::Service::resetAll();
606 }
607
android_pipe_guest_open(void * hwpipe)608 void* android_pipe_guest_open(void* hwpipe) {
609 CHECK_VM_STATE_LOCK();
610 DD("%s: Creating new connector pipe for hwpipe=%p", __FUNCTION__, hwpipe);
611 return android::sGlobals()->connectorService.create(hwpipe, nullptr, (AndroidPipeFlags)0);
612 }
613
android_pipe_guest_open_with_flags(void * hwpipe,uint32_t flags)614 void* android_pipe_guest_open_with_flags(void* hwpipe, uint32_t flags) {
615 CHECK_VM_STATE_LOCK();
616 DD("%s: Creating new connector pipe for hwpipe=%p", __FUNCTION__, hwpipe);
617 auto pipe =
618 android::sGlobals()->connectorService.create(hwpipe, nullptr, (AndroidPipeFlags)flags);
619 pipe->setFlags((AndroidPipeFlags)flags);
620 return pipe;
621 }
622
android_pipe_guest_close(void * internalPipe,PipeCloseReason reason)623 void android_pipe_guest_close(void* internalPipe, PipeCloseReason reason) {
624 CHECK_VM_STATE_LOCK();
625 auto pipe = static_cast<android::AndroidPipe*>(internalPipe);
626 if (pipe) {
627 D("%s: host=%p [%s] reason=%d", __FUNCTION__, pipe, pipe->name(),
628 (int)reason);
629 pipe->abortPendingOperation();
630 pipe->onGuestClose(reason);
631 }
632 }
633
634 template <class Func>
forEachServiceToStream(CStream * stream,Func && func)635 static void forEachServiceToStream(CStream* stream, Func&& func) {
636 BaseStream* const bs = asBaseStream(stream);
637 bs->putBe16(android::sGlobals()->services.size());
638 for (const auto& service : android::sGlobals()->services) {
639 bs->putString(service->name());
640
641 // Write to the pipeStream first so that we know the length and can
642 // enable skipping loading specific pipes on load, see isPipeOptional.
643 MemStream pipeStream;
644 func(service.get(), &pipeStream);
645 pipeStream.save(bs);
646 }
647 }
648
649 template <class Func>
forEachServiceFromStream(CStream * stream,Func && func)650 static void forEachServiceFromStream(CStream* stream, Func&& func) {
651 const auto& services = android::sGlobals()->services;
652 BaseStream* const bs = asBaseStream(stream);
653 const int count = bs->getBe16();
654 int servicePos = -1;
655 std::unordered_set<Service*> missingServices;
656 for (const auto& service : services) {
657 missingServices.insert(service.get());
658 }
659 for (int i = 0; i < count; ++i) {
660 const auto name = bs->getString();
661 servicePos = android::sGlobals()->findServicePositionByName(
662 name.c_str(), servicePos + 1);
663
664 // Always load the pipeStream, so that if the pipe is missing it does
665 // not corrupt the next pipe.
666 MemStream pipeStream;
667 pipeStream.load(bs);
668
669 if (servicePos >= 0) {
670 const auto& service = services[servicePos];
671 func(service.get(), &pipeStream);
672 missingServices.erase(service.get());
673 } else if (android::isPipeOptional(name)) {
674 D("%s: Skipping optional pipe %s\n", __FUNCTION__, name.c_str());
675 } else {
676 assert(false && "Service for snapshot pipe does not exist");
677 E("%s: Could not load pipe %s, service does not exist\n",
678 __FUNCTION__, name.c_str());
679 }
680 }
681
682 // Now call the same function for all services that weren't in the snapshot.
683 // Pass |nullptr| instead of the stream pointer to make sure they know
684 // that while we're loading from a snapshot these services aren't part
685 // of it.
686 for (const auto service : missingServices) {
687 func(service, nullptr);
688 }
689 }
690
android_pipe_guest_pre_load(CStream * stream)691 void android_pipe_guest_pre_load(CStream* stream) {
692 CHECK_VM_STATE_LOCK();
693 // We may not call qemu_set_irq() until the snapshot is loaded.
694 android::sGlobals()->pipeWaker.abortAllPending();
695 android::sGlobals()->pipeWaker.setContextRunMode(
696 android::ContextRunMode::DeferAlways);
697 forEachServiceFromStream(stream, [](Service* service, BaseStream* bs) {
698 if (service->canLoad()) {
699 service->preLoad(bs);
700 }
701 });
702 }
703
android_pipe_guest_post_load(CStream * stream)704 void android_pipe_guest_post_load(CStream* stream) {
705 CHECK_VM_STATE_LOCK();
706 forEachServiceFromStream(stream, [](Service* service, BaseStream* bs) {
707 if (service->canLoad()) {
708 service->postLoad(bs);
709 }
710 });
711 // Restore the regular handling of pipe interrupt requests.
712 android::sGlobals()->pipeWaker.setContextRunMode(
713 android::ContextRunMode::DeferIfNotLocked);
714 }
715
android_pipe_guest_pre_save(CStream * stream)716 void android_pipe_guest_pre_save(CStream* stream) {
717 CHECK_VM_STATE_LOCK();
718 forEachServiceToStream(stream, [](Service* service, BaseStream* bs) {
719 if (service->canLoad()) {
720 service->preSave(bs);
721 }
722 });
723 }
724
android_pipe_guest_post_save(CStream * stream)725 void android_pipe_guest_post_save(CStream* stream) {
726 CHECK_VM_STATE_LOCK();
727 forEachServiceToStream(stream, [](Service* service, BaseStream* bs) {
728 if (service->canLoad()) {
729 service->postSave(bs);
730 }
731 });
732 }
733
android_pipe_guest_save(void * internalPipe,CStream * stream)734 void android_pipe_guest_save(void* internalPipe, CStream* stream) {
735 CHECK_VM_STATE_LOCK();
736 auto pipe = static_cast<android::AndroidPipe*>(internalPipe);
737 DD("%s: host=%p [%s]", __FUNCTION__, pipe, pipe->name());
738 pipe->saveToStream(asBaseStream(stream));
739 }
740
android_pipe_guest_load(CStream * stream,void * hwPipe,char * pForceClose)741 void* android_pipe_guest_load(CStream* stream,
742 void* hwPipe,
743 char* pForceClose) {
744 CHECK_VM_STATE_LOCK();
745 DD("%s: hwpipe=%p", __FUNCTION__, hwPipe);
746 return AndroidPipe::loadFromStream(asBaseStream(stream), hwPipe,
747 pForceClose);
748 }
749
android_pipe_guest_load_legacy(CStream * stream,void * hwPipe,uint64_t * pChannel,unsigned char * pWakes,unsigned char * pClosed,char * pForceClose)750 void* android_pipe_guest_load_legacy(CStream* stream,
751 void* hwPipe,
752 uint64_t* pChannel,
753 unsigned char* pWakes,
754 unsigned char* pClosed,
755 char* pForceClose) {
756 CHECK_VM_STATE_LOCK();
757 DD("%s: hwpipe=%p", __FUNCTION__, hwPipe);
758 return android::AndroidPipe::loadFromStreamLegacy(asBaseStream(stream),
759 hwPipe, pChannel, pWakes,
760 pClosed, pForceClose);
761 }
762
android_pipe_guest_poll(void * internalPipe)763 unsigned android_pipe_guest_poll(void* internalPipe) {
764 CHECK_VM_STATE_LOCK();
765 auto pipe = static_cast<AndroidPipe*>(internalPipe);
766 DD("%s: host=%p [%s]", __FUNCTION__, pipe, pipe->name());
767 return pipe->onGuestPoll();
768 }
769
android_pipe_guest_recv(void * internalPipe,AndroidPipeBuffer * buffers,int numBuffers)770 int android_pipe_guest_recv(void* internalPipe,
771 AndroidPipeBuffer* buffers,
772 int numBuffers) {
773 CHECK_VM_STATE_LOCK();
774 auto pipe = static_cast<AndroidPipe*>(internalPipe);
775 // Note that pipe may be deleted during this call, so it's not safe to
776 // access pipe after this point.
777 return pipe->onGuestRecv(buffers, numBuffers);
778 }
779
android_pipe_wait_guest_recv(void * internalPipe)780 void android_pipe_wait_guest_recv(void* internalPipe) {
781 CHECK_VM_STATE_LOCK();
782 auto pipe = static_cast<AndroidPipe*>(internalPipe);
783 VM_STATE_UNLOCK();
784 pipe->waitGuestRecv();
785 VM_STATE_LOCK();
786 }
787
android_pipe_guest_send(void ** internalPipe,const AndroidPipeBuffer * buffers,int numBuffers)788 int android_pipe_guest_send(void** internalPipe,
789 const AndroidPipeBuffer* buffers,
790 int numBuffers) {
791 CHECK_VM_STATE_LOCK();
792 auto pipe = static_cast<AndroidPipe*>(*internalPipe);
793 // Note that pipe may be deleted during this call, so it's not safe to
794 // access pipe after this point.
795 return pipe->onGuestSend(buffers, numBuffers, internalPipe);
796 }
797
android_pipe_wait_guest_send(void * internalPipe)798 void android_pipe_wait_guest_send(void* internalPipe) {
799 CHECK_VM_STATE_LOCK();
800 auto pipe = static_cast<AndroidPipe*>(internalPipe);
801 VM_STATE_UNLOCK();
802 pipe->waitGuestSend();
803 VM_STATE_LOCK();
804 }
805
android_pipe_guest_wake_on(void * internalPipe,unsigned wakes)806 void android_pipe_guest_wake_on(void* internalPipe, unsigned wakes) {
807 CHECK_VM_STATE_LOCK();
808 auto pipe = static_cast<AndroidPipe*>(internalPipe);
809 pipe->onGuestWantWakeOn(wakes);
810 }
811
812 // API implemented by the virtual device.
android_pipe_host_close(void * hwpipe)813 void android_pipe_host_close(void* hwpipe) {
814 auto pipe = static_cast<android::AndroidPipe*>(hwpipe);
815 D("%s: host=%p [%s]", __FUNCTION__, pipe, pipe->name());
816 android::sGlobals()->pipeWaker.closeFromHost(pipe);
817 }
818
android_pipe_host_signal_wake(void * hwpipe,unsigned flags)819 void android_pipe_host_signal_wake(void* hwpipe, unsigned flags) {
820 android::sGlobals()->pipeWaker.signalWake(hwpipe, flags);
821 }
822
823 // Not used when in virtio mode.
android_pipe_get_id(void * hwpipe)824 int android_pipe_get_id(void* hwpipe) {
825 return getPipeHwFuncs(hwpipe)->getPipeId(hwpipe);
826 }
827
828 static std::vector<std::pair<void*(*)(int), const char*>> lookup_by_id_callbacks;
829
android_pipe_append_lookup_by_id_callback(void * (* cb)(int),const char * tag)830 void android_pipe_append_lookup_by_id_callback(void*(*cb)(int), const char* tag) {
831 lookup_by_id_callbacks.push_back({cb, tag});
832 }
833
android_pipe_lookup_by_id(const int id)834 void* android_pipe_lookup_by_id(const int id) {
835 void* hwPipeFound = nullptr;
836 const char* tagFound = "(null)";
837
838 for (const auto &cb : lookup_by_id_callbacks) {
839 void* hwPipe = (*cb.first)(id);
840 if (hwPipe) {
841 if (hwPipeFound) {
842 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
843 << "Pipe id (" << id << ") is not unique, at least two pipes are found: `"
844 << tagFound << "` and `" << cb.second << "`";
845 } else {
846 hwPipeFound = hwPipe;
847 tagFound = cb.second;
848 }
849 }
850 }
851
852 return hwPipeFound;
853 }
854