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