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