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