Merge changes Ic338a341,I022fb301 into main
* changes:
Remove unused fs-verity signature
Stop using fs-verity signature
diff --git a/apex/Android.bp b/apex/Android.bp
index fedcfcd..7ef2c79 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -106,6 +106,7 @@
],
host_required: [
"vm_shell",
+ "prepare_device_vfio",
],
apps: [
"EmptyPayloadApp",
@@ -136,6 +137,12 @@
installable: false,
}
+sh_binary_host {
+ name: "prepare_device_vfio",
+ src: "prepare_device_vfio.sh",
+ filename: "prepare_device_vfio.sh",
+}
+
// Virt apex needs a custom signer for its payload
python_binary_host {
name: "sign_virt_apex",
diff --git a/apex/prepare_device_vfio.sh b/apex/prepare_device_vfio.sh
new file mode 100755
index 0000000..de2d502
--- /dev/null
+++ b/apex/prepare_device_vfio.sh
@@ -0,0 +1,176 @@
+#!/bin/bash
+
+# Copyright 2023 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# prepare_device_vfio.sh: prepares a device for VFIO assignment by binding a VFIO driver to it
+
+adb="${ADB:="adb"}" # ADB command to use
+vfio_dir="/dev/vfio"
+platform_bus="/sys/bus/platform"
+vfio_reset_required="/sys/module/vfio_platform/parameters/reset_required"
+vfio_noiommu_param="/sys/module/vfio/parameters/enable_unsafe_noiommu_mode"
+vfio_unsafe_interrupts_param="/sys/module/vfio_iommu_type1/parameters/allow_unsafe_interrupts"
+
+function print_help() {
+ echo "prepare_device_vfio.sh prepares a device for VFIO assignment"
+ echo ""
+ echo " Usage:"
+ echo " $0 DEVICE_NAME"
+ echo " Prepare device DEVICE_NAME for VFIO assignment."
+ echo ""
+ echo " help - prints this help message"
+}
+
+function cmd() {
+ $adb shell $@
+}
+
+function tcmd() {
+ trap "echo \"Error: adb shell command '$@' failed\" ; exit 1" ERR
+ $adb shell $@
+}
+
+function ensure_root() {
+ # Check user id
+ if [ $(cmd "id -u") != 0 ]; then
+ read -p "Must run as root; restart ADBD? [y/n] " answer
+ case $answer in
+ [Yy]* )
+ $adb root && $adb wait-for-device && sleep 3 || exit 1
+ ;;
+ * )
+ exit 1
+ esac
+ fi
+}
+
+function check_vfio() {
+ cmd "[ -c $vfio_dir/vfio ]"
+ if [ $? -ne 0 ]; then
+ echo "cannot find $vfio_dir/vfio"
+ exit 1
+ fi
+
+ cmd "[ -d $platform_bus/drivers/vfio-platform ]"
+ if [ $? -ne 0 ]; then
+ echo "VFIO-platform is not supported"
+ exit 1
+ fi
+}
+
+function check_device() {
+ cmd "[ -d $device_sys ]"
+ if [ $? -ne 0 ]; then
+ echo "no device $device ($device_sys)"
+ exit 1
+ fi
+}
+
+function get_device_iommu_group() {
+ local group=$(cmd "basename \$(readlink \"$device_sys/iommu_group\")")
+ if [ $? -eq 0 ]; then
+ echo $group
+ else
+ echo ""
+ fi
+}
+
+function misc_setup() {
+ # VFIO NOIOMMU check
+ if [ -z "$group" ]; then
+ echo "$device_sys does not have an IOMMU group - setting $vfio_noiommu_param"
+ tcmd "echo y > \"$vfio_noiommu_param\""
+ fi
+
+ # Disable SELinux to allow virtualizationmanager and crosvm to access sysfs
+ echo "[*WARN*] setenforce=0: SELinux is disabled"
+ tcmd "setenforce 0"
+
+ # Samsung IOMMU does not report interrupt remapping support, so enable unsafe uinterrupts
+ if [ -n "$group" ]; then
+ local iommu_drv=$(cmd "basename \$(readlink \"$device_sys/iommu/device/driver\")")
+ if [ "$iommu_drv" = "samsung-sysmmu-v9" ]; then
+ tcmd "echo y > \"$vfio_unsafe_interrupts_param\""
+ fi
+ fi
+}
+
+function bind_vfio_driver() {
+ # Check if non-VFIO driver is currently bound, ie unbinding is needed
+ cmd "[ -e \"$device_driver\" ] && \
+ [ ! \$(basename \$(readlink \"$device_driver\")) = \"vfio-platform\" ]"
+ if [ $? -eq 0 ]; then
+ # Unbind current driver
+ tcmd "echo \"$device\" > \"$device_driver/unbind\""
+ fi
+
+ # Bind to VFIO driver
+ cmd "[ ! -e \"$device_driver\" ]"
+ if [ $? -eq 0 ]; then
+ # Bind vfio-platform driver
+ tcmd "echo \"vfio-platform\" > \"$device_sys/driver_override\""
+ tcmd "echo \"$device\" > \"$platform_bus/drivers_probe\""
+ sleep 2
+ fi
+}
+
+function verify_vfio_driver() {
+ # Verify new VFIO file structure
+ group=$(get_device_iommu_group)
+ if [ -z "$group" ]; then
+ echo "cannot setup VFIO-NOIOMMU for $device_sys"
+ exit 1
+ fi
+
+ cmd "[ ! -c \"$vfio_dir/$group\" ] || \
+ [ ! -e \"$device_driver\" ] || \
+ [ ! \$(basename \$(readlink \"$device_driver\")) = \"vfio-platform\" ]"
+ if [ $? -eq 0 ]; then
+ echo "could not bind $device to VFIO platform driver"
+
+ if [ $(cmd "cat $vfio_reset_required") = Y ]; then
+ echo "VFIO device reset handler must be registered. Either unset $vfio_reset_required, \
+or register a reset handler for $device_sys"
+ fi
+ exit 1
+ fi
+}
+
+function prepare_device() {
+ device="$1"
+ device_sys="/sys/bus/platform/devices/$device"
+ device_driver="$device_sys/driver"
+
+ ensure_root
+ check_vfio
+ check_device
+ group=$(get_device_iommu_group)
+ misc_setup
+
+ bind_vfio_driver
+ verify_vfio_driver
+
+ echo "Device: $device_sys"
+ echo "IOMMU group: $group"
+ echo "VFIO group file: $vfio_dir/$group"
+ echo "Ready!"
+}
+
+cmd=$1
+
+case $cmd in
+ ""|help) print_help ;;
+ *) prepare_device "$cmd" $@ ;;
+esac
diff --git a/apkdmverity/Android.bp b/apkdmverity/Android.bp
index fae7e99..8429263 100644
--- a/apkdmverity/Android.bp
+++ b/apkdmverity/Android.bp
@@ -40,7 +40,7 @@
name: "apkdmverity.test",
defaults: [
"apkdmverity.defaults",
- "ignorabletest.defaults",
+ "rdroidtest.defaults",
],
test_suites: ["general-tests"],
compile_multilib: "first",
diff --git a/apkdmverity/src/main.rs b/apkdmverity/src/main.rs
index 55953a9..d9e9e2b 100644
--- a/apkdmverity/src/main.rs
+++ b/apkdmverity/src/main.rs
@@ -153,12 +153,12 @@
}
#[cfg(test)]
-ignorabletest::test_main!();
+rdroidtest::test_main!();
#[cfg(test)]
mod tests {
use crate::*;
- use ignorabletest::test;
+ use rdroidtest::test;
use std::fs::{File, OpenOptions};
use std::io::Write;
use std::ops::Deref;
diff --git a/authfs/src/fusefs.rs b/authfs/src/fusefs.rs
index 87bdffc..bddf2c3 100644
--- a/authfs/src/fusefs.rs
+++ b/authfs/src/fusefs.rs
@@ -386,7 +386,8 @@
}
cfg_if::cfg_if! {
- if #[cfg(all(target_arch = "aarch64", target_pointer_width = "64"))] {
+ if #[cfg(all(any(target_arch = "aarch64", target_arch = "riscv64"),
+ target_pointer_width = "64"))] {
fn blk_size() -> libc::c_int { CHUNK_SIZE as libc::c_int }
} else {
fn blk_size() -> libc::c_long { CHUNK_SIZE as libc::c_long }
diff --git a/libs/devicemapper/Android.bp b/libs/devicemapper/Android.bp
index b7cdedc..29f2f5f 100644
--- a/libs/devicemapper/Android.bp
+++ b/libs/devicemapper/Android.bp
@@ -33,7 +33,7 @@
name: "libdm_rust.test",
defaults: [
"libdm_rust.defaults",
- "ignorabletest.defaults",
+ "rdroidtest.defaults",
],
test_suites: ["general-tests"],
rustlibs: [
diff --git a/libs/devicemapper/src/lib.rs b/libs/devicemapper/src/lib.rs
index 0170795..868ac5a 100644
--- a/libs/devicemapper/src/lib.rs
+++ b/libs/devicemapper/src/lib.rs
@@ -233,13 +233,13 @@
}
#[cfg(test)]
-ignorabletest::test_main!();
+rdroidtest::test_main!();
#[cfg(test)]
mod tests {
use super::*;
use crypt::{CipherType, DmCryptTargetBuilder};
- use ignorabletest::test;
+ use rdroidtest::test;
use rustutils::system_properties;
use std::fs::{read, File, OpenOptions};
use std::io::Write;
diff --git a/libs/ignorabletest/Android.bp b/libs/ignorabletest/Android.bp
deleted file mode 100644
index 4ae89af..0000000
--- a/libs/ignorabletest/Android.bp
+++ /dev/null
@@ -1,36 +0,0 @@
-rust_library {
- name: "libignorabletest",
- host_supported: true,
- crate_name: "ignorabletest",
- cargo_env_compat: true,
- cargo_pkg_version: "0.1.0",
- srcs: ["src/lib.rs"],
- edition: "2021",
- rustlibs: [
- "liblibtest_mimic",
- "liblinkme",
- "liblog_rust",
- "liblogger",
- ],
- proc_macros: ["libpaste"],
- apex_available: [
- "//apex_available:platform",
- "//apex_available:anyapex",
- ],
-}
-
-rust_defaults {
- name: "ignorabletest.defaults",
- test_harness: false,
- cfgs: ["test"],
- rustlibs: [
- "libignorabletest",
- "liblinkme",
- ],
- // Without this flag we get linker errors saying to add it. See
- // https://github.com/dtolnay/linkme/issues/49 and related issues.
- ld_flags: [
- "-z",
- "nostart-stop-gc",
- ],
-}
diff --git a/libs/ignorabletest/README.md b/libs/ignorabletest/README.md
deleted file mode 100644
index 77140bd..0000000
--- a/libs/ignorabletest/README.md
+++ /dev/null
@@ -1,66 +0,0 @@
-# ignorabletest
-
-This is a custom Rust test harness which allows tests to be ignored at runtime based on arbitrary
-criteria. The built-in Rust test harness only allows tests to be ignored at compile time, but this
-is often not enough on Android, where we want to ignore tests based on system properties or other
-characteristics of the device on which the test is being run, which are not known at build time.
-
-## Usage
-
-Unfortunately without the built-in support that rustc provides to the standard test harness, this
-one is slightly more cumbersome to use. Firstly, add it to the `rust_test` build rule in your
-`Android.bp` by adding the defaults provided:
-
-```soong
-rust_test {
- name: "mycrate.test",
- defaults: ["ignorabletest.defaults"],
- // ...
-}
-```
-
-If you are testing a binary that has a `main` function, you'll need to remove it from the test
-build:
-
-```rust
-#[cfg(not(test))]
-fn main() {
- // ...
-}
-```
-
-(If you're testing a library or anything else which doesn't have a `main` function, you don't need
-to worry about this.)
-
-Each test case should be marked with the `ignorabletest::test!` macro, rather than the standard
-`#[test]` attribute:
-
-```rust
-use ignorabletest::test;
-
-test!(one_plus_one);
-fn one_plus_one {
- assert_eq!(1 + 1, 2);
-}
-```
-
-To ignore a test, you can add an `ignore_if` clause with a boolean expression:
-
-```rust
-use ignorabletest::test;
-
-test!(clap_hands, ignore_if: !feeling_happy());
-fn clap_hands {
- assert!(HANDS.clap().is_ok());
-}
-```
-
-Somewhere in your main module, you need to use the `test_main` macro to generate an entry point for
-the test harness:
-
-```rust
-#[cfg(test)]
-ignorabletest::test_main!();
-```
-
-You can then run your tests as usual with `atest`.
diff --git a/libs/ignorabletest/src/lib.rs b/libs/ignorabletest/src/lib.rs
deleted file mode 100644
index c7243e6..0000000
--- a/libs/ignorabletest/src/lib.rs
+++ /dev/null
@@ -1,57 +0,0 @@
-//! Test harness which supports ignoring tests at runtime.
-
-pub mod runner;
-
-#[doc(hidden)]
-pub use libtest_mimic as _libtest_mimic;
-#[doc(hidden)]
-pub use linkme as _linkme;
-#[doc(hidden)]
-pub use paste as _paste;
-
-/// Macro to generate the main function for the test harness.
-#[macro_export]
-macro_rules! test_main {
- () => {
- #[cfg(test)]
- fn main() {
- ignorabletest::runner::main()
- }
- };
-}
-
-/// Macro to generate a wrapper function for a single test.
-///
-/// # Usage
-///
-/// ```
-/// test!(test_string_equality);
-/// fn test_string_equality() {
-/// assert_eq!("", "");
-/// }
-/// ```
-#[macro_export]
-macro_rules! test {
- ($test_name:ident) => {
- $crate::_paste::paste!(
- #[$crate::_linkme::distributed_slice($crate::runner::IGNORABLETEST_TESTS)]
- fn [< __test_ $test_name >]() -> $crate::_libtest_mimic::Trial {
- $crate::_libtest_mimic::Trial::test(
- ::std::stringify!($test_name),
- move || ignorabletest::runner::run($test_name),
- )
- }
- );
- };
- ($test_name:ident, ignore_if: $ignore_expr:expr) => {
- $crate::_paste::paste!(
- #[$crate::_linkme::distributed_slice($crate::runner::IGNORABLETEST_TESTS)]
- fn [< __test_ $test_name >]() -> $crate::_libtest_mimic::Trial {
- $crate::_libtest_mimic::Trial::test(
- ::std::stringify!($test_name),
- move || ignorabletest::runner::run($test_name),
- ).with_ignored_flag($ignore_expr)
- }
- );
- };
-}
diff --git a/libs/ignorabletest/src/runner.rs b/libs/ignorabletest/src/runner.rs
deleted file mode 100644
index fdac406..0000000
--- a/libs/ignorabletest/src/runner.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-//! Test runner.
-
-use core::ops::{Deref, FnOnce};
-use libtest_mimic::{Arguments, Failed, Trial};
-use linkme::distributed_slice;
-use log::Level;
-use std::env;
-
-/// Command-line arguments to ignore, because they are not supported by libtest-mimic.
-const IGNORED_ARGS: [&str; 2] = ["-Zunstable-options", "--report-time"];
-
-/// The collection of all tests to run.
-#[doc(hidden)]
-#[distributed_slice]
-pub static IGNORABLETEST_TESTS: [fn() -> Trial] = [..];
-
-/// Runs all tests.
-pub fn main() {
- logger::init(logger::Config::default().with_min_level(Level::Debug));
- let args = Arguments::from_iter(env::args().filter(|arg| !IGNORED_ARGS.contains(&arg.deref())));
- let tests = IGNORABLETEST_TESTS.iter().map(|test| test()).collect();
- libtest_mimic::run(&args, tests).exit();
-}
-
-/// Runs the given test.
-pub fn run(test: impl FnOnce()) -> Result<(), Failed> {
- test();
- Ok(())
-}
diff --git a/microdroid/kdump/Android.bp b/microdroid/kdump/Android.bp
index cc681a7..b9a18fe 100644
--- a/microdroid/kdump/Android.bp
+++ b/microdroid/kdump/Android.bp
@@ -18,6 +18,9 @@
static_executable: true,
installable: false,
compile_multilib: "64",
+ sanitize: {
+ hwaddress: false, // HWASAN setup fails when run as init process
+ },
}
android_filesystem {
diff --git a/vmbase/src/memory/mod.rs b/vmbase/src/memory/mod.rs
index 898aa10..2f72fc4 100644
--- a/vmbase/src/memory/mod.rs
+++ b/vmbase/src/memory/mod.rs
@@ -23,10 +23,12 @@
pub use error::MemoryTrackerError;
pub use page_table::PageTable;
pub use shared::{
- alloc_shared, dealloc_shared, handle_permission_fault, handle_translation_fault, MemoryRange,
- MemoryTracker, MEMORY,
+ handle_permission_fault, handle_translation_fault, MemoryRange, MemoryTracker, MEMORY,
};
pub use util::{
- flush, flushed_zeroize, min_dcache_line_size, page_4kb_of, phys_to_virt, virt_to_phys,
- PAGE_SIZE, SIZE_128KB, SIZE_2MB, SIZE_4KB, SIZE_4MB, SIZE_64KB,
+ flush, flushed_zeroize, min_dcache_line_size, page_4kb_of, PAGE_SIZE, SIZE_128KB, SIZE_2MB,
+ SIZE_4KB, SIZE_4MB, SIZE_64KB,
};
+
+pub(crate) use shared::{alloc_shared, dealloc_shared};
+pub(crate) use util::{phys_to_virt, virt_to_phys};
diff --git a/vmbase/src/memory/shared.rs b/vmbase/src/memory/shared.rs
index 173c0ec..064fb6d 100644
--- a/vmbase/src/memory/shared.rs
+++ b/vmbase/src/memory/shared.rs
@@ -27,6 +27,7 @@
use alloc::vec::Vec;
use buddy_system_allocator::{FrameAllocator, LockedFrameAllocator};
use core::alloc::Layout;
+use core::cmp::max;
use core::mem::size_of;
use core::num::NonZeroUsize;
use core::ops::Range;
@@ -343,7 +344,7 @@
/// Allocates a memory range of at least the given size and alignment that is shared with the host.
/// Returns a pointer to the buffer.
-pub fn alloc_shared(layout: Layout) -> hyp::Result<NonNull<u8>> {
+pub(crate) fn alloc_shared(layout: Layout) -> hyp::Result<NonNull<u8>> {
assert_ne!(layout.size(), 0);
let Some(buffer) = try_shared_alloc(layout) else {
handle_alloc_error(layout);
@@ -359,7 +360,11 @@
if let Some(buffer) = shared_pool.alloc_aligned(layout) {
Some(NonNull::new(buffer as _).unwrap())
} else if let Some(shared_memory) = SHARED_MEMORY.lock().as_mut() {
- shared_memory.refill(&mut shared_pool, layout);
+ // Adjusts the layout size to the max of the next power of two and the alignment,
+ // as this is the actual size of the memory allocated in `alloc_aligned()`.
+ let size = max(layout.size().next_power_of_two(), layout.align());
+ let refill_layout = Layout::from_size_align(size, layout.align()).unwrap();
+ shared_memory.refill(&mut shared_pool, refill_layout);
shared_pool.alloc_aligned(layout).map(|buffer| NonNull::new(buffer as _).unwrap())
} else {
None
@@ -374,7 +379,7 @@
///
/// The memory must have been allocated by `alloc_shared` with the same layout, and not yet
/// deallocated.
-pub unsafe fn dealloc_shared(vaddr: NonNull<u8>, layout: Layout) -> hyp::Result<()> {
+pub(crate) unsafe fn dealloc_shared(vaddr: NonNull<u8>, layout: Layout) -> hyp::Result<()> {
SHARED_POOL.get().unwrap().lock().dealloc_aligned(vaddr.as_ptr() as usize, layout);
trace!("Deallocated shared buffer at {vaddr:?} with {layout:?}");
diff --git a/vmbase/src/memory/util.rs b/vmbase/src/memory/util.rs
index 48d4c55..2b75414 100644
--- a/vmbase/src/memory/util.rs
+++ b/vmbase/src/memory/util.rs
@@ -88,7 +88,7 @@
///
/// As we use identity mapping for everything, this is just a cast, but it's useful to use it to be
/// explicit about where we are converting from virtual to physical address.
-pub fn virt_to_phys(vaddr: NonNull<u8>) -> usize {
+pub(crate) fn virt_to_phys(vaddr: NonNull<u8>) -> usize {
vaddr.as_ptr() as _
}
@@ -96,6 +96,6 @@
/// physical address.
///
/// Panics if `paddr` is 0.
-pub fn phys_to_virt(paddr: usize) -> NonNull<u8> {
+pub(crate) fn phys_to_virt(paddr: usize) -> NonNull<u8> {
NonNull::new(paddr as _).unwrap()
}