diff --git a/init/Android.bp b/init/Android.bp index 419948454..12ca15ae3 100644 --- a/init/Android.bp +++ b/init/Android.bp @@ -463,7 +463,7 @@ cc_binary { name: "init_first_stage.microdroid", defaults: [ "avf_build_flags_cc", - "init_first_stage_defaults" + "init_first_stage_defaults", ], cflags: ["-DMICRODROID=1"], installable: false, diff --git a/init/block_dev_initializer.cpp b/init/block_dev_initializer.cpp index 05e00edfd..a686d0513 100644 --- a/init/block_dev_initializer.cpp +++ b/init/block_dev_initializer.cpp @@ -132,11 +132,19 @@ bool BlockDevInitializer::InitDevices(std::set devices) { bool BlockDevInitializer::InitDmDevice(const std::string& device) { const std::string device_name(basename(device.c_str())); const std::string syspath = "/sys/block/" + device_name; + return InitDevice(syspath, device_name); +} + +bool BlockDevInitializer::InitPlatformDevice(const std::string& dev_name) { + return InitDevice("/sys/devices/platform", dev_name); +} + +bool BlockDevInitializer::InitDevice(const std::string& syspath, const std::string& device_name) { bool found = false; - auto uevent_callback = [&device_name, &device, this, &found](const Uevent& uevent) { + auto uevent_callback = [&device_name, this, &found](const Uevent& uevent) { if (uevent.device_name == device_name) { - LOG(VERBOSE) << "Creating device-mapper device : " << device; + LOG(VERBOSE) << "Creating device : " << device_name; device_handler_->HandleUevent(uevent); found = true; return ListenerAction::kStop; @@ -146,13 +154,13 @@ bool BlockDevInitializer::InitDmDevice(const std::string& device) { uevent_listener_.RegenerateUeventsForPath(syspath, uevent_callback); if (!found) { - LOG(INFO) << "dm device '" << device << "' not found in /sys, waiting for its uevent"; + LOG(INFO) << "device '" << device_name << "' not found in /sys, waiting for its uevent"; Timer t; uevent_listener_.Poll(uevent_callback, 10s); - LOG(INFO) << "wait for dm device '" << device << "' returned after " << t; + LOG(INFO) << "wait for device '" << device_name << "' returned after " << t; } if (!found) { - LOG(ERROR) << "dm device '" << device << "' not found after polling timeout"; + LOG(ERROR) << "device '" << device_name << "' not found after polling timeout"; return false; } return true; diff --git a/init/block_dev_initializer.h b/init/block_dev_initializer.h index ec39ce084..d5b1f6006 100644 --- a/init/block_dev_initializer.h +++ b/init/block_dev_initializer.h @@ -24,6 +24,7 @@ namespace android { namespace init { +// TODO: should this be renamed to FirstStageDevInitialize? class BlockDevInitializer final { public: BlockDevInitializer(); @@ -32,11 +33,13 @@ class BlockDevInitializer final { bool InitDmUser(const std::string& name); bool InitDevices(std::set devices); bool InitDmDevice(const std::string& device); + bool InitPlatformDevice(const std::string& device); private: ListenerAction HandleUevent(const Uevent& uevent, std::set* devices); bool InitMiscDevice(const std::string& name); + bool InitDevice(const std::string& syspath, const std::string& device); std::unique_ptr device_handler_; UeventListener uevent_listener_; diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp index c0b928139..836d536c9 100644 --- a/init/first_stage_mount.cpp +++ b/init/first_stage_mount.cpp @@ -16,6 +16,7 @@ #include "first_stage_mount.h" +#include #include #include #include @@ -33,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -272,6 +274,11 @@ bool FirstStageMountVBootV2::DoFirstStageMount() { return true; } +// TODO: should this be in a library in packages/modules/Virtualization first_stage_init links? +static bool IsMicrodroidStrictBoot() { + return access("/proc/device-tree/chosen/avf,strict-boot", F_OK) == 0; +} + bool FirstStageMountVBootV2::InitDevices() { std::set devices; GetSuperDeviceName(&devices); @@ -283,6 +290,14 @@ bool FirstStageMountVBootV2::InitDevices() { return false; } + if (IsMicrodroid() && android::virtualization::IsOpenDiceChangesFlagEnabled()) { + if (IsMicrodroidStrictBoot()) { + if (!block_dev_init_.InitPlatformDevice("open-dice0")) { + return false; + } + } + } + if (IsDmLinearEnabled()) { auto super_symlink = "/dev/block/by-name/"s + super_partition_name_; if (!android::base::Realpath(super_symlink, &super_path_)) { @@ -527,9 +542,48 @@ bool FirstStageMountVBootV2::TrySwitchSystemAsRoot() { return true; } +static bool MaybeDeriveMicrodroidVendorDiceNode(Fstab* fstab) { + std::optional microdroid_vendor_block_dev; + for (auto entry = fstab->begin(); entry != fstab->end(); entry++) { + if (entry->mount_point == "/vendor") { + microdroid_vendor_block_dev.emplace(entry->blk_device); + break; + } + } + if (!microdroid_vendor_block_dev.has_value()) { + LOG(VERBOSE) << "No microdroid vendor partition to mount"; + return true; + } + // clang-format off + const std::array args = { + "/system/bin/derive_microdroid_vendor_dice_node", + "--dice-driver", "/dev/open-dice0", + "--microdroid-vendor-disk-image", microdroid_vendor_block_dev->data(), + "--output", "/microdroid_resources/dice_chain.raw", + }; + // clang-format-on + // ForkExecveAndWaitForCompletion calls waitpid to wait for the fork-ed process to finish. + // The first_stage_console adds SA_NOCLDWAIT flag to the SIGCHLD handler, which means that + // waitpid will always return -ECHLD. Here we re-register a default handler, so that waitpid + // works. + LOG(INFO) << "Deriving dice node for microdroid vendor partition"; + signal(SIGCHLD, SIG_DFL); + if (!ForkExecveAndWaitForCompletion(args[0], (char**)args.data())) { + LOG(ERROR) << "Failed to derive microdroid vendor dice node"; + return false; + } + return true; +} + bool FirstStageMountVBootV2::MountPartitions() { if (!TrySwitchSystemAsRoot()) return false; + if (IsMicrodroid() && android::virtualization::IsOpenDiceChangesFlagEnabled()) { + if (!MaybeDeriveMicrodroidVendorDiceNode(&fstab_)) { + return false; + } + } + if (!SkipMountingPartitions(&fstab_, true /* verbose */)) return false; for (auto current = fstab_.begin(); current != fstab_.end();) {