diff --git a/0001-docs-update-readme.md-for-building-via-musl-toolchai.patch b/0001-docs-update-readme.md-for-building-via-musl-toolchai.patch deleted file mode 100644 index b534afc2c3bba2f85b22f175187aeac9fc6ed5fd..0000000000000000000000000000000000000000 --- a/0001-docs-update-readme.md-for-building-via-musl-toolchai.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 54d88e2b9061cc1846d435e99aa6b474d7282b5f Mon Sep 17 00:00:00 2001 -From: Zhigang Wang -Date: Fri, 7 May 2021 18:26:19 +0800 -Subject: [PATCH] docs: update readme.md for building via musl toolchain - -Signed-off-by: Zhigang Wang ---- - README.md | 33 +++++++++++++++++++++++---------- - 1 file changed, 23 insertions(+), 10 deletions(-) - -diff --git a/README.md b/README.md -index ca9b146..fa361f3 100644 ---- a/README.md -+++ b/README.md -@@ -1,16 +1,24 @@ - # StratoVirt --StratoVirt is an enterprise-level virtualization platform for cloud data centers in the computing industry. It implements a set of architecture that supports three scenarios: virtual machines, containers, and serverless. StratoVirt has key technological competitive advantages in light weight and low noise, software and hardware coordination, and Rust language-level security. -+StratoVirt is an enterprise-level virtualization platform for cloud data centers -+in the computing industry. It implements a set of architecture that supports -+three scenarios: virtual machines, containers, and serverless computing. - --StratoVirt reserves interface and design for importing more features, even standard virtualization. -+StratoVirt has competitive advantages in light weight and low noise, software -+and hardware coordination, and Rust language-level security. -+ -+StratoVirt reserves interface and design for importing more features, even -+evaluates to standard virtualization. - - ## How to start - - ### Preparation - Before building StratoVirt, make sure that Rust language and Cargo have already --been installed. If not, you can find installation guidance from the following link: -+been installed. If not, you can find installation guidance via following link: - - https://www.rust-lang.org/tools/install - -+And it will get smaller memory overhead if you prepare musl toolchain for rust. -+ - ### Build StratoVirt - To build StratoVirt, clone the project and build it first: - ```sh -@@ -39,18 +47,21 @@ $ ./target/release/stratovirt \ - -serial stdio - ``` - --The detailed guidance of making rootfs, compiling kernel and building StratoVirt can be found --in [StratoVirt QuickStart](./docs/quickstart.md). -+The detailed guidance of making rootfs, compiling kernel and building StratoVirt -+can be found in [StratoVirt QuickStart](./docs/quickstart.md). - --StratoVirt supports much more features, the detailed guidance can be found in [Configuration Guidebook](docs/config_guidebook.md). -+StratoVirt supports much more features, the detailed guidance can be found in -+[Configuration Guidebook](docs/config_guidebook.md). - - ## Design - --To get more details about StratoVirt's core architecture design, refer to [StratoVirt design](./docs/design.md). -+To get more details about StratoVirt's core architecture design, refer to -+[StratoVirt design](./docs/design.md). - - ## How to contribute --We welcome new contributors! And we are happy to provide guidance and help for new contributors. --StratoVirt follows Rust formatting conventions, which can be found at: -+We welcome new contributors! And we are happy to provide guidance and help for -+new contributors. StratoVirt follows Rust formatting conventions, which can be -+found at: - - https://github.com/rust-dev-tools/fmt-rfcs/tree/master/guide - https://github.com/rust-lang/rust-clippy -@@ -59,7 +70,9 @@ You can get more information about StratoVirt at: - - https://gitee.com/openeuler/stratovirt/wikis - --If you find a bug or have some ideas, please send an email to the [virt mailing list](https://mailweb.openeuler.org/postorius/lists/virt.openeuler.org/) or submit an [issue](https://gitee.com/openeuler/stratovirt/issues). -+If you find a bug or have some ideas, please send an email to the -+[virt mailing list](https://mailweb.openeuler.org/postorius/lists/virt.openeuler.org/) -+or submit an [issue](https://gitee.com/openeuler/stratovirt/issues). - - ## Licensing - StratoVirt is licensed under the Mulan PSL v2. --- -2.25.1 - diff --git a/0001-fix-spelling-errors-in-project.patch b/0001-fix-spelling-errors-in-project.patch new file mode 100644 index 0000000000000000000000000000000000000000..ab3f64d5ae0ec17f20d4ac6cc4febd590b5d2799 --- /dev/null +++ b/0001-fix-spelling-errors-in-project.patch @@ -0,0 +1,449 @@ +From 515c87cad45e324286b36b6c2f3d7f8319092a1e Mon Sep 17 00:00:00 2001 +From: DBJ <974658390@qq.com> +Date: Fri, 13 Aug 2021 02:20:28 -0700 +Subject: [PATCH 1/8] fix spelling errors in project + +--- + address_space/src/address_space.rs | 2 +- + boot_loader/src/x86_64/standard_boot/elf.rs | 2 +- + cpu/src/lib.rs | 8 ++++---- + devices/src/interrupt_controller/aarch64/state.rs | 2 +- + devices/src/legacy/fwcfg.rs | 6 +++--- + devices/src/legacy/pl011.rs | 2 +- + devices/src/legacy/rtc.rs | 6 +++--- + docs/config_guidebook.md | 6 +++--- + docs/design.md | 2 +- + docs/interconnect_with_libvirt.md | 2 +- + hypervisor/src/kvm/interrupt.rs | 2 +- + machine/src/micro_vm/mod.rs | 4 ++-- + machine/src/standard_vm/aarch64/mod.rs | 2 +- + migration/src/manager.rs | 4 ++-- + migration/src/snapshot.rs | 4 ++-- + ozone/src/syscall.rs | 2 +- + tests/hydropper/monitor/monitor_thread.py | 2 +- + .../microvm/functional/test_microvm_concurrency.py | 4 ++-- + tests/hydropper/utils/session.py | 2 +- + tests/hydropper/utils/utils_qmp.py | 2 +- + vfio/src/vfio_dev.rs | 8 ++++---- + virtio/src/queue.rs | 2 +- + virtio/src/virtio_mmio.rs | 2 +- + 23 files changed, 39 insertions(+), 39 deletions(-) + +diff --git a/address_space/src/address_space.rs b/address_space/src/address_space.rs +index c182281..85bf71f 100644 +--- a/address_space/src/address_space.rs ++++ b/address_space/src/address_space.rs +@@ -307,7 +307,7 @@ impl AddressSpace { + }) + } + +- /// Return the end address fo memory according to all Ram regions in AddressSpace. ++ /// Return the end address of memory according to all Ram regions in AddressSpace. + pub fn memory_end_address(&self) -> GuestAddress { + self.flat_view + .load() +diff --git a/boot_loader/src/x86_64/standard_boot/elf.rs b/boot_loader/src/x86_64/standard_boot/elf.rs +index 481b876..a76e789 100644 +--- a/boot_loader/src/x86_64/standard_boot/elf.rs ++++ b/boot_loader/src/x86_64/standard_boot/elf.rs +@@ -79,7 +79,7 @@ impl Elf64Header { + bail!("Invalid magic in ELF header"); + } + if self.e_ident[EI_DATA] != ELFDATA2LSB { +- bail!("Big endian ELF file is not suppored"); ++ bail!("Big endian ELF file is not supported"); + } + if self.e_ident[EI_CLASS] != ELFCLASS64 { + bail!("Only 64-bit ELF image is supported"); +diff --git a/cpu/src/lib.rs b/cpu/src/lib.rs +index 41e143f..cb1a41b 100644 +--- a/cpu/src/lib.rs ++++ b/cpu/src/lib.rs +@@ -494,7 +494,7 @@ impl CPUInterface for CPU { + .chain_err(|| "Some error occurred in guest shutdown")?; + } else { + error!( +- "Vcpu{} recevied unexpected system event with type 0x{:x}, flags 0x{:x}", ++ "Vcpu{} received unexpected system event with type 0x{:x}, flags 0x{:x}", + self.id(), + event, + flags +@@ -569,11 +569,11 @@ impl CPUThreadWorker { + } + + register_signal_handler(VCPU_EXIT_SIGNAL, handle_signal) +- .chain_err(|| "Failed to registe VCPU_EXIT_SIGNAL signal.")?; ++ .chain_err(|| "Failed to register VCPU_EXIT_SIGNAL signal.")?; + register_signal_handler(VCPU_PAUSE_SIGNAL, handle_signal) +- .chain_err(|| "Failed to registe VCPU_PAUSE_SIGNAL signal.")?; ++ .chain_err(|| "Failed to register VCPU_PAUSE_SIGNAL signal.")?; + register_signal_handler(VCPU_TASK_SIGNAL, handle_signal) +- .chain_err(|| "Failed to registe VCPU_TASK_SIGNAL signal.")?; ++ .chain_err(|| "Failed to register VCPU_TASK_SIGNAL signal.")?; + + Ok(()) + } +diff --git a/devices/src/interrupt_controller/aarch64/state.rs b/devices/src/interrupt_controller/aarch64/state.rs +index e1b05b6..d4da00b 100644 +--- a/devices/src/interrupt_controller/aarch64/state.rs ++++ b/devices/src/interrupt_controller/aarch64/state.rs +@@ -75,7 +75,7 @@ const ICC_CTLR_EL1: u64 = 0xc664; + const ICC_SRE_EL1: u64 = 0xc665; + const ICC_IGRPEN0_EL1: u64 = 0xc666; + const ICC_IGRPEN1_EL1: u64 = 0xc667; +-/// GICv3 CPU interface control regiter pribits[8:10] ++/// GICv3 CPU interface control register pribits[8:10] + const ICC_CTLR_EL1_PRIBITS_MASK: u64 = 0x700; + const ICC_CTLR_EL1_PRIBITS_SHIFT: u64 = 0x8; + +diff --git a/devices/src/legacy/fwcfg.rs b/devices/src/legacy/fwcfg.rs +index ed41581..34c1375 100644 +--- a/devices/src/legacy/fwcfg.rs ++++ b/devices/src/legacy/fwcfg.rs +@@ -365,7 +365,7 @@ impl FwCfgCommon { + ); + }; + +- // unwrap is safe bacause the count of arch_entries and entries is initialized ++ // unwrap is safe because the count of arch_entries and entries is initialized + // as `FW_CFG_FILE_FIRST + FW_CFG_FILE_SLOTS_DFLT`, which is equal to the return + // value of `max_entry` function. + if self.is_arch_local() { +@@ -1402,7 +1402,7 @@ mod test { + fwcfg_dev.lock().unwrap().read(&mut read_data, base, offset); + assert_eq!(read_data, sig_entry_data); + +- // Failed to write beacuse of offset overflow. ++ // Failed to write because of offset overflow. + let write_data = vec![0x0_u8]; + let offset = 0x18; + let f_back = fwcfg_dev.lock().unwrap().write(&write_data, base, offset); +@@ -1442,7 +1442,7 @@ mod test { + fwcfg_dev.lock().unwrap().read(&mut read_data, base, offset); + assert_eq!(read_data, sig_entry_data); + +- // Failed to write beacuse of offset overflow. ++ // Failed to write because of offset overflow. + let write_data = vec![0x0_u8]; + let offset = 0x0c; + let f_back = fwcfg_dev.lock().unwrap().write(&write_data, base, offset); +diff --git a/devices/src/legacy/pl011.rs b/devices/src/legacy/pl011.rs +index fa063c3..133487e 100644 +--- a/devices/src/legacy/pl011.rs ++++ b/devices/src/legacy/pl011.rs +@@ -74,7 +74,7 @@ pub struct PL011State { + ibrd: u32, + /// Fractional Baud Rate Register. + fbrd: u32, +- /// Interrut FIFO Level Select Register. ++ /// Interrupt FIFO Level Select Register. + ifl: u32, + /// Identifier Register. Length is 8. + id: [u8; 8], +diff --git a/devices/src/legacy/rtc.rs b/devices/src/legacy/rtc.rs +index 0b5e4aa..6241e68 100644 +--- a/devices/src/legacy/rtc.rs ++++ b/devices/src/legacy/rtc.rs +@@ -36,7 +36,7 @@ const RTC_MINUTES: u8 = 0x02; + const RTC_MINUTES_ALARM: u8 = 0x03; + const RTC_HOURS: u8 = 0x04; + const RTC_HOURS_ARARM: u8 = 0x05; +-const RTC_DAY_OF_WEAK: u8 = 0x06; ++const RTC_DAY_OF_WEEK: u8 = 0x06; + const RTC_DAY_OF_MONTH: u8 = 0x07; + const RTC_MONTH: u8 = 0x08; + const RTC_YEAR: u8 = 0x09; +@@ -61,7 +61,7 @@ const CMOS_MEM_ABOVE_4GB: (u8, u8, u8) = (0x5B, 0x5C, 0x5D); + fn get_utc_time() -> libc::tm { + let time_val: libc::time_t = 0_i64; + +- // Safe bacause `libc::time` only get time. ++ // Safe because `libc::time` only get time. + unsafe { libc::time(time_val as *mut i64) }; + + let mut dest_tm = libc::tm { +@@ -177,7 +177,7 @@ impl RTC { + RTC_HOURS => { + data[0] = bin_to_bcd(tm.tm_hour as u8); + } +- RTC_DAY_OF_WEAK => { ++ RTC_DAY_OF_WEEK => { + data[0] = bin_to_bcd((tm.tm_wday + 1) as u8); + } + RTC_DAY_OF_MONTH => { +diff --git a/docs/config_guidebook.md b/docs/config_guidebook.md +index 6d118ec..6a5cda7 100644 +--- a/docs/config_guidebook.md ++++ b/docs/config_guidebook.md +@@ -124,7 +124,7 @@ If you want to use initrd as rootfs, `root=/dev/ram` and `rdinit=/bin/sh` must b + ## 2. Device Configuration + + For machine type "microvm", only virtio-mmio and legacy devices are supported. +-Maximum number of user createable devices is 11 on x86_64 and 160 on aarch64. ++Maximum number of user creatable devices is 11 on x86_64 and 160 on aarch64. + + For standard VM (machine type "q35" on x86_64, and "virt" on aarch64) , virtio-pci devices are supported instead of virtio-mmio + devices. As for now pci bridges are not implemented yet, there is currently only one +@@ -829,7 +829,7 @@ About the arguments: + * `netns` : path to a existed network namespace. + * `source` : path to the source file, such as `rootfs` and `vmlinux`. + * `clean-resource` : a flag to clean resource. +-* `--` : these two dashes are used to splite args, the args followed are used to launched StratoVirt. ++* `--` : these two dashes are used to split args, the args followed are used to launched StratoVirt. + + ### 5.2 Example + As ozone uses a directory to mount as a root directory, after ozone is launched, the directory "/srv/zozne/{exec_file}/{name}" will be created. (Where, `exec_file` is the executable binary file, usually it is `stratovirt`, while `name` is the name of ozone, it is given by users, but the length of it should be no more than 255 bytes.) In order to run ozone normally, please make sure that the directory "/srv/zozne/{exec_file}/{name}" does not exists before launching ozone. +@@ -874,7 +874,7 @@ $ ./ozone \ + ``` + + ## 6. Libvirt +-Libvirt launchs StratoVirt by creating cmdlines. But some of these commands ++Libvirt launches StratoVirt by creating cmdlines. But some of these commands + such as: cpu, overcommit, uuid, no-user-config, nodefaults, sandbox, msg, rtc, no-shutdown, + nographic, realtime, display, usb, mem-prealloc and boot, are not supported by StratoVirt. + To launch StratoVirt from libvirt successfully, StratoVirt needs to put these arguments into +diff --git a/docs/design.md b/docs/design.md +index 4ffdd16..537d256 100644 +--- a/docs/design.md ++++ b/docs/design.md +@@ -45,6 +45,6 @@ The following figure shows StratoVirt's core architecture which consist of three + + - Only the Linux operating system is supported; The recommended kernel version is 4.19; + - Only Linux is supported as the client operating system, and the recommended kernel version is 4.19; +-- StratoVirt is fullly tested on openEuler; ++- StratoVirt is fully tested on openEuler; + - Supports a maximum of 254 CPUs; + +diff --git a/docs/interconnect_with_libvirt.md b/docs/interconnect_with_libvirt.md +index a448bb5..d5205ed 100644 +--- a/docs/interconnect_with_libvirt.md ++++ b/docs/interconnect_with_libvirt.md +@@ -20,7 +20,7 @@ CPU topology is not supported, please configure the number of VCPUs only. + ``` + 4 + ``` +-- Archtecture: ++- Architecture: + + Optional value of `arch` are: `aarch64` and `x86_64`. On X86 platform, supported machine is `q35`; on aarch 64 platform, supported machine is `virt`. + ``` +diff --git a/hypervisor/src/kvm/interrupt.rs b/hypervisor/src/kvm/interrupt.rs +index 45799f9..675d25c 100644 +--- a/hypervisor/src/kvm/interrupt.rs ++++ b/hypervisor/src/kvm/interrupt.rs +@@ -103,7 +103,7 @@ impl IrqRouteTable { + #[cfg(target_arch = "x86_64")] + pub fn init_irq_route_table(&mut self) { + // On x86, use `kvm_create_irqchip` to create an interrupt +- // controller module in the kernel. It creates a virual PIC, a virtual ioapic, ++ // controller module in the kernel. It creates a virtual PIC, a virtual ioapic, + // and sets up future vcpus to have a local APIC. IRQ routing for GSIs 0-15 is set + // to both PIC and IOAPIC. GSI 16-23 only go to the IOAPIC. + for i in 0..IOAPIC_NUM_PINS { +diff --git a/machine/src/micro_vm/mod.rs b/machine/src/micro_vm/mod.rs +index ea92164..f48a6dc 100644 +--- a/machine/src/micro_vm/mod.rs ++++ b/machine/src/micro_vm/mod.rs +@@ -659,7 +659,7 @@ impl MachineOps for LightMachine { + let index = MMIO_REPLACEABLE_BLK_NR + self.replaceable_info.net_count; + if index >= MMIO_REPLACEABLE_BLK_NR + MMIO_REPLACEABLE_NET_NR { + bail!( +- "A maximum of {} net replaceble devices are supported.", ++ "A maximum of {} net replaceable devices are supported.", + MMIO_REPLACEABLE_NET_NR + ); + } +@@ -677,7 +677,7 @@ impl MachineOps for LightMachine { + let device_cfg = parse_blk(vm_config, cfg_args)?; + if self.replaceable_info.block_count >= MMIO_REPLACEABLE_BLK_NR { + bail!( +- "A maximum of {} block replaceble devices are supported.", ++ "A maximum of {} block replaceable devices are supported.", + MMIO_REPLACEABLE_BLK_NR + ); + } +diff --git a/machine/src/standard_vm/aarch64/mod.rs b/machine/src/standard_vm/aarch64/mod.rs +index ee66bc9..54c103c 100644 +--- a/machine/src/standard_vm/aarch64/mod.rs ++++ b/machine/src/standard_vm/aarch64/mod.rs +@@ -179,7 +179,7 @@ impl StdMachineOps for StdMachine { + let pcihost_root = PciHostRoot::new(root_bus); + pcihost_root + .realize() +- .chain_err(|| "Faile to realize pcihost root device.")?; ++ .chain_err(|| "Failed to realize pcihost root device.")?; + + Ok(()) + } +diff --git a/migration/src/manager.rs b/migration/src/manager.rs +index 35ed975..480b59b 100644 +--- a/migration/src/manager.rs ++++ b/migration/src/manager.rs +@@ -21,7 +21,7 @@ use super::status::MigrationStatus; + use util::byte_code::ByteCode; + + lazy_static! { +- /// Glocal MigrationMananger to manage all migration combined interface. ++ /// Glocal MigrationManager to manage all migration combined interface. + pub(crate) static ref MIGRATION_MANAGER: Arc = Arc::new(MigrationManager { + entry: Arc::new(RwLock::new(BTreeMap::::new())), + desc_db: Arc::new(RwLock::new(HashMap::::new())), +@@ -135,7 +135,7 @@ pub enum MigrationEntry { + /// This structure is to manage all resource during migration. + /// It is also the only way to call on `MIGRATION_MANAGER`. + pub struct MigrationManager { +- /// The map offers the deivce_id and combined migratable device entry. ++ /// The map offers the device_id and combined migratable device entry. + pub(crate) entry: Arc>>, + /// The map offers the device type and its device state describe structure. + pub(crate) desc_db: Arc>>, +diff --git a/migration/src/snapshot.rs b/migration/src/snapshot.rs +index 470ea63..edea8ce 100644 +--- a/migration/src/snapshot.rs ++++ b/migration/src/snapshot.rs +@@ -94,7 +94,7 @@ impl MigrationManager { + /// # Notes + /// + /// Offers a interface for restore snapshot functions. This function will make VM +- /// back to the state restored in snapshot file incluing both device and memory. ++ /// back to the state restored in snapshot file including both device and memory. + /// + /// # Argument + /// +@@ -126,7 +126,7 @@ impl MigrationManager { + bail!("Invalid device state snapshot file"); + } + +- Self::load_memory(&mut memory_file).chain_err(|| "Failed to load snpashot memory")?; ++ Self::load_memory(&mut memory_file).chain_err(|| "Failed to load snapshot memory")?; + let snapshot_desc_db = + Self::load_descriptor_db(&mut device_state_file, device_state_header.desc_len) + .chain_err(|| "Failed to load device descriptor db")?; +diff --git a/ozone/src/syscall.rs b/ozone/src/syscall.rs +index 2627642..936661f 100644 +--- a/ozone/src/syscall.rs ++++ b/ozone/src/syscall.rs +@@ -140,7 +140,7 @@ pub fn set_host_name(host_name: &str) -> Result<()> { + /// + /// # Arguments + /// +-/// * `fd` - File descriptor refering to one of magic links in a /proc/[pid]/ns/ directory. ++/// * `fd` - File descriptor referring to one of magic links in a /proc/[pid]/ns/ directory. + /// * `nstype` - Namespace type. + pub fn setns(fd: i32, nstype: i32) -> Result<()> { + SyscallResult { +diff --git a/tests/hydropper/monitor/monitor_thread.py b/tests/hydropper/monitor/monitor_thread.py +index daad97d..5921ecf 100644 +--- a/tests/hydropper/monitor/monitor_thread.py ++++ b/tests/hydropper/monitor/monitor_thread.py +@@ -25,7 +25,7 @@ class MonitorThread(threading.Thread): + items = dict() + + def __init__(self): +- """Construtor""" ++ """Constructor""" + super(MonitorThread, self).__init__() + self.state_lock = threading.Lock() + self._state = 'init' +diff --git a/tests/hydropper/testcases/microvm/functional/test_microvm_concurrency.py b/tests/hydropper/testcases/microvm/functional/test_microvm_concurrency.py +index ded87ad..73de004 100644 +--- a/tests/hydropper/testcases/microvm/functional/test_microvm_concurrency.py ++++ b/tests/hydropper/testcases/microvm/functional/test_microvm_concurrency.py +@@ -20,10 +20,10 @@ def test_microvm_concurrency(microvms): + """ + Test multi microvms start: + +- 1) Set each VM vcpu_count = 4, then launch it and comfirm vcpu count is 4. ++ 1) Set each VM vcpu_count = 4, then launch it and confirm vcpu count is 4. + And increase _succ_sum. + 2) Execute step 1 concurrency by threads. +- 3) Comfirm each VM is execute successffully by _succ_sum ++ 3) Confirm each VM is execute successffully by _succ_sum + + Note: You can modify CONCURRENT_QUANTITY tag in config/config.ini to set vm quantity. + """ +diff --git a/tests/hydropper/utils/session.py b/tests/hydropper/utils/session.py +index 1eb3bad..bb9036f 100644 +--- a/tests/hydropper/utils/session.py ++++ b/tests/hydropper/utils/session.py +@@ -152,7 +152,7 @@ class ConsoleManager(): + LOG.debug("Got 'Warning added RSA to known host list") + continue + except aexpect.ExpectTimeoutError as err: +- # send a empty line to avoid unexpect login timeout ++ # send a empty line to avoid unexpected login timeout + # because some message from linux kernel maybe impact match + if not last_chance: + time.sleep(0.5) +diff --git a/tests/hydropper/utils/utils_qmp.py b/tests/hydropper/utils/utils_qmp.py +index 8acefed..7d0527d 100644 +--- a/tests/hydropper/utils/utils_qmp.py ++++ b/tests/hydropper/utils/utils_qmp.py +@@ -9,7 +9,7 @@ + # KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO + # NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + # See the Mulan PSL v2 for more details. +-"""Some qmp fuctions""" ++"""Some qmp functions""" + + import re + from utils.exception import QMPError +diff --git a/vfio/src/vfio_dev.rs b/vfio/src/vfio_dev.rs +index 0603d49..30f7d5a 100644 +--- a/vfio/src/vfio_dev.rs ++++ b/vfio/src/vfio_dev.rs +@@ -464,13 +464,13 @@ impl VfioDevice { + .iter() + .collect::() + .read_link() +- .chain_err(|| "Invaild iommu group path")?; ++ .chain_err(|| "Invalid iommu group path")?; + let group_name = iommu_group + .file_name() +- .chain_err(|| "Invaild iommu group name")?; ++ .chain_err(|| "Invalid iommu group name")?; + let mut group_id = 0; + if let Some(n) = group_name.to_str() { +- group_id = n.parse::().chain_err(|| "Invaild iommu group id")?; ++ group_id = n.parse::().chain_err(|| "Invalid iommu group id")?; + } + + let mut groups = container.groups.lock().unwrap(); +@@ -489,7 +489,7 @@ impl VfioDevice { + fn vfio_get_device(group: &VfioGroup, name: &Path) -> Result { + let mut dev_name: &str = ""; + if let Some(n) = name.file_name() { +- dev_name = n.to_str().chain_err(|| "Invaild device path")?; ++ dev_name = n.to_str().chain_err(|| "Invalid device path")?; + } + let path: CString = CString::new(dev_name.as_bytes()) + .chain_err(|| "Failed to convert device name to CString type of data")?; +diff --git a/virtio/src/queue.rs b/virtio/src/queue.rs +index 9979b5c..6ac137c 100644 +--- a/virtio/src/queue.rs ++++ b/virtio/src/queue.rs +@@ -68,7 +68,7 @@ pub struct QueueConfig { + pub ready: bool, + /// Interrupt vector index of the queue for msix + pub vector: u16, +- /// The next index which can be poped in the available vring. ++ /// The next index which can be popped in the available vring. + next_avail: u16, + /// The next index which can be pushed in the used vring. + next_used: u16, +diff --git a/virtio/src/virtio_mmio.rs b/virtio/src/virtio_mmio.rs +index 099015f..ad9b32a 100644 +--- a/virtio/src/virtio_mmio.rs ++++ b/virtio/src/virtio_mmio.rs +@@ -80,7 +80,7 @@ const VENDOR_ID: u32 = 0; + const MMIO_MAGIC_VALUE: u32 = 0x7472_6976; + const MMIO_VERSION: u32 = 2; + +-/// The maximun of virtio queue within a virtio device. ++/// The maximum of virtio queue within a virtio device. + const MAXIMUM_NR_QUEUES: usize = 8; + + /// HostNotifyInfo includes the info needed for notifying backend from guest. +-- +2.25.1 + diff --git a/0002-docs-turn-on-the-option-switch-of-virtio-rng-for-x86.patch b/0002-docs-turn-on-the-option-switch-of-virtio-rng-for-x86.patch deleted file mode 100644 index 96c3be48efbc81344fdedcd87f440da8de21462a..0000000000000000000000000000000000000000 --- a/0002-docs-turn-on-the-option-switch-of-virtio-rng-for-x86.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 6aed6d53acb4a86f7304b800c08cdfb5ffbba83d Mon Sep 17 00:00:00 2001 -From: Fei Xu -Date: Sat, 8 May 2021 11:38:34 +0800 -Subject: [PATCH] docs: turn on the option switch of virtio rng for x86_64 - kernel configuration and add guest kernel configuration for virtio rng in - config_guidebook.md - -Signed-off-by: Fei Xu ---- - docs/config_guidebook.md | 5 +++++ - docs/kernel_config/config_openeuler_4.19_x86_64 | 5 ++++- - docs/kernel_config/config_openeuler_5.10_x86_64 | 5 ++++- - 3 files changed, 13 insertions(+), 2 deletions(-) - -diff --git a/docs/config_guidebook.md b/docs/config_guidebook.md -index f31ec92..4f96aaa 100644 ---- a/docs/config_guidebook.md -+++ b/docs/config_guidebook.md -@@ -414,6 +414,10 @@ This feature can prevent OOM occur in guest. - ### 2.8 Virtio-rng - Virtio rng is a paravirtualized random number generator device, it provides a hardware rng device to the guest. - -+If you want use it, need: -+ -+* Guest kernel config: CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_VIA=y CONFIG_HW_RANDOM_VIRTIO=y -+ - Only two property is supported for virtio-rng. - * random_file: the path of character device generates with random number in host - * bytes_per_sec: the number of bytes that the character device generates with a random number per second, -@@ -429,6 +433,7 @@ it should satisfy `64<=bytes_per_sec<1000000000` - "bytes_per_sec": 1000000 - }, - } -+``` - - ## 3. StratoVirt Management - -diff --git a/docs/kernel_config/config_openeuler_4.19_x86_64 b/docs/kernel_config/config_openeuler_4.19_x86_64 -index f3e1ad9..a4545ea 100644 ---- a/docs/kernel_config/config_openeuler_4.19_x86_64 -+++ b/docs/kernel_config/config_openeuler_4.19_x86_64 -@@ -1302,7 +1302,10 @@ CONFIG_SERIAL_CORE_CONSOLE=y - CONFIG_HVC_DRIVER=y - CONFIG_VIRTIO_CONSOLE=y - # CONFIG_IPMI_HANDLER is not set --# CONFIG_HW_RANDOM is not set -+CONFIG_HW_RANDOM=y -+# CONFIG_HW_RANDOM_TIMERIOMEM is not set -+CONFIG_HW_RANDOM_VIA=y -+CONFIG_HW_RANDOM_VIRTIO=y - # CONFIG_NVRAM is not set - # CONFIG_MWAVE is not set - # CONFIG_RAW_DRIVER is not set -diff --git a/docs/kernel_config/config_openeuler_5.10_x86_64 b/docs/kernel_config/config_openeuler_5.10_x86_64 -index 71e3480..5ff42d2 100644 ---- a/docs/kernel_config/config_openeuler_5.10_x86_64 -+++ b/docs/kernel_config/config_openeuler_5.10_x86_64 -@@ -1369,7 +1369,10 @@ CONFIG_HVC_DRIVER=y - # CONFIG_SERIAL_DEV_BUS is not set - CONFIG_VIRTIO_CONSOLE=y - # CONFIG_IPMI_HANDLER is not set --# CONFIG_HW_RANDOM is not set -+CONFIG_HW_RANDOM=y -+# CONFIG_HW_RANDOM_TIMERIOMEM is not set -+CONFIG_HW_RANDOM_VIA=y -+CONFIG_HW_RANDOM_VIRTIO=y - # CONFIG_MWAVE is not set - # CONFIG_DEVMEM is not set - # CONFIG_DEVKMEM is not set --- -2.25.1 - diff --git a/0002-migration-fix-an-error-during-migration-interface-on.patch b/0002-migration-fix-an-error-during-migration-interface-on.patch new file mode 100644 index 0000000000000000000000000000000000000000..6274b1ee248bed09b7afc1af21e28cb347b1903b --- /dev/null +++ b/0002-migration-fix-an-error-during-migration-interface-on.patch @@ -0,0 +1,104 @@ +From 7c9db6a2e3082b41af3e62b241d49553f5bb8492 Mon Sep 17 00:00:00 2001 +From: Wei Gao +Date: Wed, 18 Aug 2021 14:30:08 +0800 +Subject: [PATCH 2/8] migration: fix an error during migration interface on + aarch64. + +Change the order of GICv3 device register to the end. Because it rely on +vcpu_init if boot with multi vcpu. + +Signed-off-by: Wei Gao +--- + .../src/interrupt_controller/aarch64/gicv3.rs | 3 ++- + hypervisor/src/kvm/mod.rs | 1 + + machine/src/lib.rs | 2 +- + migration/src/manager.rs | 16 ++++++++++++---- + 4 files changed, 16 insertions(+), 6 deletions(-) + +diff --git a/devices/src/interrupt_controller/aarch64/gicv3.rs b/devices/src/interrupt_controller/aarch64/gicv3.rs +index 3303b32..6559e73 100644 +--- a/devices/src/interrupt_controller/aarch64/gicv3.rs ++++ b/devices/src/interrupt_controller/aarch64/gicv3.rs +@@ -389,13 +389,14 @@ impl GICDevice for GICv3 { + gic_conf: &GICConfig, + ) -> Result> { + let gicv3 = Arc::new(GICv3::new(gic_conf)?); +- MigrationManager::register_device_instance(GICv3State::descriptor(), gicv3.clone()); + if gicv3.its_dev.is_some() { + MigrationManager::register_device_instance( + GICv3ItsState::descriptor(), + gicv3.its_dev.as_ref().unwrap().clone(), ++ true, + ); + } ++ MigrationManager::register_device_instance(GICv3State::descriptor(), gicv3.clone(), true); + + Ok(gicv3) + } +diff --git a/hypervisor/src/kvm/mod.rs b/hypervisor/src/kvm/mod.rs +index 5b5be94..19193db 100644 +--- a/hypervisor/src/kvm/mod.rs ++++ b/hypervisor/src/kvm/mod.rs +@@ -60,6 +60,7 @@ impl KVMFds { + migration::MigrationManager::register_device_instance( + state::KvmDeviceState::descriptor(), + Arc::new(state::KvmDevice {}), ++ false, + ); + + kvm_fds +diff --git a/machine/src/lib.rs b/machine/src/lib.rs +index 8a095b3..9eb3039 100644 +--- a/machine/src/lib.rs ++++ b/machine/src/lib.rs +@@ -233,7 +233,7 @@ pub trait MachineOps { + )); + cpus.push(cpu.clone()); + +- MigrationManager::register_device_instance(cpu::ArchCPU::descriptor(), cpu); ++ MigrationManager::register_device_instance(cpu::ArchCPU::descriptor(), cpu, false); + } + + if let Some(boot_config) = boot_cfg { +diff --git a/migration/src/manager.rs b/migration/src/manager.rs +index 480b59b..7ec4767 100644 +--- a/migration/src/manager.rs ++++ b/migration/src/manager.rs +@@ -162,14 +162,22 @@ impl MigrationManager { + /// + /// * `device_desc` - The `DeviceStateDesc` of device instance. + /// * `entry` - Device instance with migratable interface. +- pub fn register_device_instance(device_desc: DeviceStateDesc, device_entry: Arc) +- where ++ /// * `reverse` - Register device in order or in the reverse order. ++ pub fn register_device_instance( ++ device_desc: DeviceStateDesc, ++ device_entry: Arc, ++ reverse: bool, ++ ) where + T: MigrationHook + Sync + Send + 'static, + { + Self::register_device_desc(device_desc); + + let entry = MigrationEntry::Safe(device_entry); +- let nr_entry = Self::entry_db_len(); ++ let nr_entry = if reverse { ++ !0 - Self::entry_db_len() ++ } else { ++ Self::entry_db_len() ++ }; + + MIGRATION_MANAGER + .entry +@@ -333,7 +341,7 @@ mod tests { + let device_v2 = Arc::new(DeviceV2::default()); + let device_v2_mutex = Arc::new(Mutex::new(DeviceV2::default())); + +- MigrationManager::register_device_instance(DeviceV1State::descriptor(), device_v1); ++ MigrationManager::register_device_instance(DeviceV1State::descriptor(), device_v1, false); + MigrationManager::register_memory_instance(device_v2); + MigrationManager::register_device_instance_mutex( + DeviceV2State::descriptor(), +-- +2.25.1 + diff --git a/0003-doc-fix-an-uncorrect-link-for-build_guide-in-quickst.patch b/0003-doc-fix-an-uncorrect-link-for-build_guide-in-quickst.patch deleted file mode 100644 index 7b3eeb849c4f06fb5434be1c471543cd197d84e9..0000000000000000000000000000000000000000 --- a/0003-doc-fix-an-uncorrect-link-for-build_guide-in-quickst.patch +++ /dev/null @@ -1,41 +0,0 @@ -From d14ed26839876832318aedfc638628d23091f2f4 Mon Sep 17 00:00:00 2001 -From: Wei Gao -Date: Mon, 17 May 2021 09:32:50 +0800 -Subject: [PATCH] doc: fix an uncorrect link for `build_guide` in - `quickstart.md`. - -Signed-off-by: Wei Gao ---- - docs/boot_source.md | 2 +- - docs/quickstart.md | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/docs/boot_source.md b/docs/boot_source.md -index a4e4389..22b2935 100644 ---- a/docs/boot_source.md -+++ b/docs/boot_source.md -@@ -65,7 +65,7 @@ Rootfs image is a file system image. An EXT4-format image with `/sbin/init` can - - ```shell - $ arch=`uname -m` -- $ wget http://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/$arch/alpine-minirootfs-3.13.0-$arch.tar.gz -O alpine-minirootfs.tar.gz -+ $ wget http://dl-cdn.alpinelinux.org/alpine/v3.13/releases/$arch/alpine-minirootfs-3.13.0-$arch.tar.gz -O alpine-minirootfs.tar.gz - $ tar -zxvf alpine-minirootfs.tar.gz - $ rm alpine-minirootfs.tar.gz - ``` -diff --git a/docs/quickstart.md b/docs/quickstart.md -index 842c3ca..5a2b194 100644 ---- a/docs/quickstart.md -+++ b/docs/quickstart.md -@@ -26,7 +26,7 @@ $ sudo yum install stratovirt - - Now you can find StratoVirt binary with path: `/usr/bin/stratovirt`. - --If you'd like to build StratoVirt yourself, you should check out the [build_guide](../build_guide.md). -+If you'd like to build StratoVirt yourself, you should check out the [build_guide](./build_guide.md). - - ## 3. Running StratoVirt - --- -2.25.1 - diff --git a/0003-migration-fix-an-errors-during-the-PL011-device-stat.patch b/0003-migration-fix-an-errors-during-the-PL011-device-stat.patch new file mode 100644 index 0000000000000000000000000000000000000000..982fa7137a9da1b048f5bc7b760a778be481aeef --- /dev/null +++ b/0003-migration-fix-an-errors-during-the-PL011-device-stat.patch @@ -0,0 +1,29 @@ +From 79a5a58e74e28c175ee836bda60090cf511f893d Mon Sep 17 00:00:00 2001 +From: Wei Gao +Date: Wed, 18 Aug 2021 15:30:33 +0800 +Subject: [PATCH 3/8] migration: fix an errors during the PL011 device state + restore. + +This bug is leaded by commit d24f510cf271f144084266ff292db7e94c004b53. +Add the function to register device again. + +Signed-off-by: Wei Gao +--- + devices/src/legacy/pl011.rs | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/devices/src/legacy/pl011.rs b/devices/src/legacy/pl011.rs +index 133487e..65bf64b 100644 +--- a/devices/src/legacy/pl011.rs ++++ b/devices/src/legacy/pl011.rs +@@ -172,6 +172,7 @@ impl PL011 { + param_type: "earlycon".to_string(), + value: format!("pl011,mmio,0x{:08x}", region_base), + }); ++ MigrationManager::register_device_instance_mutex(PL011State::descriptor(), dev.clone()); + let locked_dev = dev.lock().unwrap(); + locked_dev.chardev.lock().unwrap().set_input_callback(&dev); + EventLoop::update_event( +-- +2.25.1 + diff --git a/0004-machine-standard_vm-fix-inappropriate-file-open-perm.patch b/0004-machine-standard_vm-fix-inappropriate-file-open-perm.patch new file mode 100644 index 0000000000000000000000000000000000000000..3357d6b35e026b32fa7d1d692ea63d34de4ec5b5 --- /dev/null +++ b/0004-machine-standard_vm-fix-inappropriate-file-open-perm.patch @@ -0,0 +1,122 @@ +From 22362ed8a2d865e0b84bb20615eb1415086eb713 Mon Sep 17 00:00:00 2001 +From: Jiajie Li +Date: Wed, 18 Aug 2021 11:18:45 +0800 +Subject: [PATCH 4/8] machine/standard_vm: fix inappropriate file open + permissions + +For PFlash device, code file is read-only and vars file is +readable and writable. So using right permissions to open +these two files. + +Signed-off-by: Jiajie Li +--- + machine/src/standard_vm/aarch64/mod.rs | 9 ++++----- + machine/src/standard_vm/mod.rs | 17 ++++++++++++++++- + machine/src/standard_vm/x86_64/mod.rs | 8 +++----- + 3 files changed, 23 insertions(+), 11 deletions(-) + +diff --git a/machine/src/standard_vm/aarch64/mod.rs b/machine/src/standard_vm/aarch64/mod.rs +index 54c103c..d3c8670 100644 +--- a/machine/src/standard_vm/aarch64/mod.rs ++++ b/machine/src/standard_vm/aarch64/mod.rs +@@ -44,9 +44,9 @@ use virtio::{qmp_balloon, qmp_query_balloon}; + use vmm_sys_util::eventfd::EventFd; + + use super::{AcpiBuilder, StdMachineOps}; +-use crate::errors::Result as MachineResult; + use crate::errors::{ErrorKind, Result}; + use crate::MachineOps; ++use crate::{errors::Result as MachineResult, standard_vm::open_pflash_file}; + use pci_host_root::PciHostRoot; + use syscall::syscall_whitelist; + +@@ -397,6 +397,7 @@ impl MachineOps for StdMachine { + + /// Add pflash device. + fn add_pflash_device(&mut self, configs: &[PFlashConfig]) -> Result<()> { ++ use super::errors::ErrorKind as StdErrorKind; + use crate::errors::ResultExt; + + let mut configs_vec = configs.to_vec(); +@@ -407,10 +408,8 @@ impl MachineOps for StdMachine { + for i in 0..=1 { + let (fd, read_only) = if i < configs_vec.len() { + let config = &configs_vec[i]; +- let fd = std::fs::OpenOptions::new() +- .read(true) +- .write(true) +- .open(config.path_on_host.clone())?; ++ let fd = open_pflash_file(&config.path_on_host, config.unit) ++ .chain_err(|| StdErrorKind::OpenFileErr(config.path_on_host.clone()))?; + (Some(fd), config.read_only) + } else { + (None, false) +diff --git a/machine/src/standard_vm/mod.rs b/machine/src/standard_vm/mod.rs +index 5ba7929..ff469c3 100644 +--- a/machine/src/standard_vm/mod.rs ++++ b/machine/src/standard_vm/mod.rs +@@ -39,12 +39,15 @@ pub mod errors { + InitPCIeHostErr { + display("Failed to init PCIe host.") + } ++ OpenFileErr(path: String) { ++ display("Failed to open file: {}.", path) ++ } + } + } + } + +-use std::mem::size_of; + use std::sync::{Arc, Mutex}; ++use std::{fs::File, mem::size_of}; + + #[cfg(target_arch = "x86_64")] + use acpi::AcpiGenericAddress; +@@ -61,6 +64,18 @@ use aarch64::{LayoutEntryType, MEM_LAYOUT}; + #[cfg(target_arch = "x86_64")] + use x86_64::{LayoutEntryType, MEM_LAYOUT}; + ++fn open_pflash_file(file_name: &str, unit: usize) -> Result { ++ let fd = if unit == 0 { ++ std::fs::OpenOptions::new().read(true).open(file_name)? ++ } else { ++ std::fs::OpenOptions::new() ++ .read(true) ++ .write(true) ++ .open(file_name)? ++ }; ++ Ok(fd) ++} ++ + trait StdMachineOps: AcpiBuilder { + fn init_pci_host(&self) -> Result<()>; + +diff --git a/machine/src/standard_vm/x86_64/mod.rs b/machine/src/standard_vm/x86_64/mod.rs +index 0cb2b63..1c29703 100644 +--- a/machine/src/standard_vm/x86_64/mod.rs ++++ b/machine/src/standard_vm/x86_64/mod.rs +@@ -49,7 +49,7 @@ use vmm_sys_util::eventfd::EventFd; + use super::errors::{ErrorKind, Result}; + use super::{AcpiBuilder, StdMachineOps}; + use crate::errors::{ErrorKind as MachineErrorKind, Result as MachineResult}; +-use crate::MachineOps; ++use crate::{standard_vm::open_pflash_file, MachineOps}; + use mch::Mch; + use syscall::syscall_whitelist; + use util::byte_code::ByteCode; +@@ -398,10 +398,8 @@ impl MachineOps for StdMachine { + // of current PFlash device. + let mut flash_end: u64 = MEM_LAYOUT[LayoutEntryType::MemAbove4g as usize].0; + for config in configs_vec { +- let mut fd = std::fs::OpenOptions::new() +- .read(true) +- .write(true) +- .open(config.path_on_host.clone())?; ++ let mut fd = open_pflash_file(&config.path_on_host, config.unit) ++ .chain_err(|| ErrorKind::OpenFileErr(config.path_on_host.clone()))?; + let pfl_size = fd.metadata().unwrap().len(); + + if config.unit == 0 { +-- +2.25.1 + diff --git a/0004-update-rootfs-disk-image-description-in-README.ch.md.patch b/0004-update-rootfs-disk-image-description-in-README.ch.md.patch deleted file mode 100644 index cf1fed2bc15e355351f94b828fc16ccd9a79ca45..0000000000000000000000000000000000000000 --- a/0004-update-rootfs-disk-image-description-in-README.ch.md.patch +++ /dev/null @@ -1,25 +0,0 @@ -From cb7bc20a6a9f09d50f5021aef2332c20efa7c457 Mon Sep 17 00:00:00 2001 -From: KuhnChen -Date: Mon, 17 May 2021 16:42:01 +0800 -Subject: [PATCH] update rootfs disk image description in README.ch.md - ---- - README.ch.md | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/README.ch.md b/README.ch.md -index 2637baf..50aec7b 100644 ---- a/README.ch.md -+++ b/README.ch.md -@@ -22,7 +22,7 @@ $ cargo build --release - ### 运行软件 - 为了快速上手StratoVirt,需要准备 - * PE格式或bzImage格式(仅x86_64)的Linux内核镜像 --* EXT4格式的rootfs镜像 -+* ext4文件系统,raw格式rootfs的镜像 - - 可以通过以下链接获取我们准备好的linux内核镜像和rootfs镜像: - --- -2.25.1 - diff --git a/0005-kernel_config-update-kernel-config-5.10-on-aarch64-p.patch b/0005-kernel_config-update-kernel-config-5.10-on-aarch64-p.patch new file mode 100644 index 0000000000000000000000000000000000000000..30211d3aaa6584037056cb6d66361da3f8422c42 --- /dev/null +++ b/0005-kernel_config-update-kernel-config-5.10-on-aarch64-p.patch @@ -0,0 +1,55 @@ +From cde02263b76a88407b23d0ca2e06f244c45dec42 Mon Sep 17 00:00:00 2001 +From: Wei Gao +Date: Thu, 19 Aug 2021 20:13:42 +0800 +Subject: [PATCH 5/8] kernel_config: update kernel config 5.10 on aarch64 + platform. + +1. Turn on memory hotplug feature. + +Signed-off-by: Wei Gao +--- + docs/kernel_config/micro_vm/kernel_config_5.10_aarch64 | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/docs/kernel_config/micro_vm/kernel_config_5.10_aarch64 b/docs/kernel_config/micro_vm/kernel_config_5.10_aarch64 +index d9deb7a..bbd016f 100644 +--- a/docs/kernel_config/micro_vm/kernel_config_5.10_aarch64 ++++ b/docs/kernel_config/micro_vm/kernel_config_5.10_aarch64 +@@ -698,7 +698,9 @@ CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y + CONFIG_SPARSEMEM_VMEMMAP=y + CONFIG_HAVE_FAST_GUP=y + CONFIG_ARCH_KEEP_MEMBLOCK=y +-# CONFIG_MEMORY_HOTPLUG is not set ++CONFIG_MEMORY_ISOLATION=y ++CONFIG_MEMORY_HOTPLUG=y ++CONFIG_MEMORY_HOTPLUG_SPARSE=y + CONFIG_SPLIT_PTLOCK_CPUS=4 + CONFIG_MEMORY_BALLOON=y + # CONFIG_COMPACTION is not set +@@ -1767,6 +1769,7 @@ CONFIG_COMMON_CLK=y + # CONFIG_CLK_QORIQ is not set + # CONFIG_COMMON_CLK_XGENE is not set + # CONFIG_COMMON_CLK_FIXED_MMIO is not set ++# CONFIG_MCHP_CLK_PFSOC is not set + # CONFIG_HWSPINLOCK is not set + + # +@@ -2072,6 +2075,8 @@ CONFIG_INIT_STACK_NONE=y + # CONFIG_INIT_ON_FREE_DEFAULT_ON is not set + # end of Memory initialization + # end of Kernel hardening options ++ ++# CONFIG_SECURITY_BOOT_INIT is not set + # end of Security options + + CONFIG_CRYPTO=y +@@ -2431,4 +2436,4 @@ CONFIG_CC_HAS_SANCOV_TRACE_PC=y + # CONFIG_RUNTIME_TESTING_MENU is not set + # CONFIG_MEMTEST is not set + # end of Kernel Testing and Coverage +-# end of Kernel hacking +\ No newline at end of file ++# end of Kernel hacking +-- +2.25.1 + diff --git a/0005-update-rootfs-disk-image-description-in-README.md.patch b/0005-update-rootfs-disk-image-description-in-README.md.patch deleted file mode 100644 index 6d399e978d46de8de793404529bdc70962a7ebee..0000000000000000000000000000000000000000 --- a/0005-update-rootfs-disk-image-description-in-README.md.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 3bd60055b7b34edbc67e8f46e34e2153a165569e Mon Sep 17 00:00:00 2001 -From: KuhnChen -Date: Mon, 17 May 2021 17:41:17 +0800 -Subject: [PATCH] update rootfs disk image description in README.md. - ---- - README.md | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/README.md b/README.md -index fa361f3..44f4bcd 100644 ---- a/README.md -+++ b/README.md -@@ -31,7 +31,7 @@ Now you can find StratoVirt binary in `target/release/stratovirt`. - ### Run a VM with StratoVirt - To run StratoVirt quickly, requires - * A PE or bzImage (only x86_64) format Linux kernel --* An EXT4-format rootfs image -+* An EXT4 filesystem, raw format rootfs disk image - - You can get kernel and rootfs image from the following link: - --- -2.25.1 - diff --git a/0006-StratoVirt-clear-clippy-warnings-for-updating-rust-1.patch b/0006-StratoVirt-clear-clippy-warnings-for-updating-rust-1.patch deleted file mode 100644 index c06460bc055f861c4c163327733bd699604319f1..0000000000000000000000000000000000000000 --- a/0006-StratoVirt-clear-clippy-warnings-for-updating-rust-1.patch +++ /dev/null @@ -1,880 +0,0 @@ -From ed34a5a14129691ff62122405071192e7ce9180e Mon Sep 17 00:00:00 2001 -From: Fei Xu -Date: Tue, 25 May 2021 09:13:30 +0800 -Subject: [PATCH] StratoVirt: clear clippy warnings for updating rust 1.51.0 - -Signed-off-by: Fei Xu ---- - address_space/src/region.rs | 1 + - boot_loader/src/lib.rs | 1 + - boot_loader/src/x86_64/mptable.rs | 2 + - cpu/src/aarch64/mod.rs | 34 ++++++++-------- - cpu/src/lib.rs | 8 +++- - cpu/src/x86_64/mod.rs | 2 + - devices/src/interrupt_controller/mod.rs | 2 + - devices/src/legacy/pl031.rs | 3 +- - machine_manager/src/qmp/mod.rs | 27 ++++++------- - machine_manager/src/qmp/qmp_schema.rs | 52 +++++++++++++------------ - machine_manager/src/socket.rs | 1 + - micro_vm/src/lib.rs | 22 ++++++----- - util/src/aio/libaio.rs | 14 +++---- - util/src/aio/mod.rs | 8 ++-- - util/src/arg_parser.rs | 20 +++++----- - util/src/device_tree.rs | 1 + - util/src/logger.rs | 6 +-- - virtio/src/balloon.rs | 4 +- - virtio/src/block.rs | 11 +++--- - virtio/src/net.rs | 2 +- - virtio/src/vhost/kernel/net.rs | 2 +- - virtio/src/vhost/kernel/vsock.rs | 3 +- - 22 files changed, 119 insertions(+), 107 deletions(-) - -diff --git a/address_space/src/region.rs b/address_space/src/region.rs -index 86f807c..235b195 100644 ---- a/address_space/src/region.rs -+++ b/address_space/src/region.rs -@@ -18,6 +18,7 @@ use crate::errors::{ErrorKind, Result, ResultExt}; - use crate::{AddressRange, AddressSpace, FileBackend, GuestAddress, HostMemMapping, RegionOps}; - - /// Types of Region. -+#[allow(clippy::upper_case_acronyms)] - #[derive(Debug, PartialEq, Eq, Copy, Clone)] - pub enum RegionType { - /// Ram type. -diff --git a/boot_loader/src/lib.rs b/boot_loader/src/lib.rs -index 2687377..4be04be 100644 ---- a/boot_loader/src/lib.rs -+++ b/boot_loader/src/lib.rs -@@ -78,6 +78,7 @@ extern crate log; - #[macro_use] - extern crate error_chain; - -+#[allow(clippy::upper_case_acronyms)] - #[cfg(target_arch = "aarch64")] - mod aarch64; - #[cfg(target_arch = "x86_64")] -diff --git a/boot_loader/src/x86_64/mptable.rs b/boot_loader/src/x86_64/mptable.rs -index b8b7bf6..9d0d3f0 100644 ---- a/boot_loader/src/x86_64/mptable.rs -+++ b/boot_loader/src/x86_64/mptable.rs -@@ -163,6 +163,7 @@ impl BusEntry { - } - - #[repr(C)] -+#[allow(clippy::upper_case_acronyms)] - #[derive(Debug, Default, Copy, Clone)] - pub struct IOApicEntry { - type_: u8, -@@ -189,6 +190,7 @@ impl IOApicEntry { - } - - #[repr(C)] -+#[allow(clippy::upper_case_acronyms)] - #[derive(Debug, Default, Copy, Clone)] - pub struct IOInterruptEntry { - type_: u8, -diff --git a/cpu/src/aarch64/mod.rs b/cpu/src/aarch64/mod.rs -index ef4c912..d717912 100644 ---- a/cpu/src/aarch64/mod.rs -+++ b/cpu/src/aarch64/mod.rs -@@ -62,62 +62,62 @@ pub enum Arm64CoreRegs { - USER_FPSIMD_STATE_RES(usize), - } - --#[allow(clippy::zero_ptr)] --impl Into for Arm64CoreRegs { -- fn into(self) -> u64 { -+impl From for u64 { -+ fn from(elem: Arm64CoreRegs) -> u64 { - let register_size; -- let regid = match self { -+ let regid; -+ match elem { - Arm64CoreRegs::KVM_USER_PT_REGS => { - register_size = KVM_REG_SIZE_U64; -- offset_of!(kvm_regs, regs) -+ regid = offset_of!(kvm_regs, regs) - } - Arm64CoreRegs::KVM_SP_EL1 => { - register_size = KVM_REG_SIZE_U64; -- offset_of!(kvm_regs, sp_el1) -+ regid = offset_of!(kvm_regs, sp_el1) - } - Arm64CoreRegs::KVM_ELR_EL1 => { - register_size = KVM_REG_SIZE_U64; -- offset_of!(kvm_regs, elr_el1) -+ regid = offset_of!(kvm_regs, elr_el1) - } - Arm64CoreRegs::KVM_SPSR(idx) if idx < KVM_NR_SPSR as usize => { - register_size = KVM_REG_SIZE_U64; -- offset_of!(kvm_regs, spsr) + idx * 8 -+ regid = offset_of!(kvm_regs, spsr) + idx * 8 - } - Arm64CoreRegs::KVM_USER_FPSIMD_STATE => { - register_size = KVM_REG_SIZE_U64; -- offset_of!(kvm_regs, fp_regs) -+ regid = offset_of!(kvm_regs, fp_regs) - } - Arm64CoreRegs::USER_PT_REG_REGS(idx) if idx < 31 => { - register_size = KVM_REG_SIZE_U64; -- offset_of!(kvm_regs, regs, user_pt_regs, regs) + idx * 8 -+ regid = offset_of!(kvm_regs, regs, user_pt_regs, regs) + idx * 8 - } - Arm64CoreRegs::USER_PT_REG_SP => { - register_size = KVM_REG_SIZE_U64; -- offset_of!(kvm_regs, regs, user_pt_regs, sp) -+ regid = offset_of!(kvm_regs, regs, user_pt_regs, sp) - } - Arm64CoreRegs::USER_PT_REG_PC => { - register_size = KVM_REG_SIZE_U64; -- offset_of!(kvm_regs, regs, user_pt_regs, pc) -+ regid = offset_of!(kvm_regs, regs, user_pt_regs, pc) - } - Arm64CoreRegs::USER_PT_REG_PSTATE => { - register_size = KVM_REG_SIZE_U64; -- offset_of!(kvm_regs, regs, user_pt_regs, pstate) -+ regid = offset_of!(kvm_regs, regs, user_pt_regs, pstate) - } - Arm64CoreRegs::USER_FPSIMD_STATE_VREGS(idx) if idx < 32 => { - register_size = KVM_REG_SIZE_U128; -- offset_of!(kvm_regs, fp_regs, user_fpsimd_state, vregs) + idx * 16 -+ regid = offset_of!(kvm_regs, fp_regs, user_fpsimd_state, vregs) + idx * 16 - } - Arm64CoreRegs::USER_FPSIMD_STATE_FPSR => { - register_size = KVM_REG_SIZE_U32; -- offset_of!(kvm_regs, fp_regs, user_fpsimd_state, fpsr) -+ regid = offset_of!(kvm_regs, fp_regs, user_fpsimd_state, fpsr) - } - Arm64CoreRegs::USER_FPSIMD_STATE_FPCR => { - register_size = KVM_REG_SIZE_U32; -- offset_of!(kvm_regs, fp_regs, user_fpsimd_state, fpcr) -+ regid = offset_of!(kvm_regs, fp_regs, user_fpsimd_state, fpcr) - } - Arm64CoreRegs::USER_FPSIMD_STATE_RES(idx) if idx < 2 => { - register_size = 128; -- offset_of!(kvm_regs, fp_regs, user_fpsimd_state, __reserved) + idx * 8 -+ regid = offset_of!(kvm_regs, fp_regs, user_fpsimd_state, __reserved) + idx * 8 - } - _ => panic!("No such Register"), - }; -diff --git a/cpu/src/lib.rs b/cpu/src/lib.rs -index b32c709..eb489dc 100644 ---- a/cpu/src/lib.rs -+++ b/cpu/src/lib.rs -@@ -37,6 +37,7 @@ extern crate machine_manager; - #[macro_use] - extern crate util; - -+#[allow(clippy::upper_case_acronyms)] - #[cfg(target_arch = "aarch64")] - mod aarch64; - #[cfg(target_arch = "x86_64")] -@@ -164,6 +165,7 @@ thread_local! { - } - - /// Trait to handle `CPU` lifetime. -+#[allow(clippy::upper_case_acronyms)] - pub trait CPUInterface { - /// Realize `CPU` structure, set registers value for `CPU`. - fn realize(&self, vm_fd: &Arc, boot: &CPUBootConfig) -> Result<()>; -@@ -198,6 +200,7 @@ pub trait CPUInterface { - } - - /// `CPU` is a wrapper around creating and using a kvm-based VCPU. -+#[allow(clippy::upper_case_acronyms)] - pub struct CPU { - /// ID of this virtual CPU, `0` means this cpu is primary `CPU`. - id: u8, -@@ -417,11 +420,11 @@ impl CPUInterface for CPU { - } - - if QmpChannel::is_connected() { -- let shutdown_msg = schema::SHUTDOWN { -+ let shutdown_msg = schema::Shutdown { - guest: true, - reason: "guest-shutdown".to_string(), - }; -- event!(SHUTDOWN; shutdown_msg); -+ event!(Shutdown; shutdown_msg); - } - - Ok(()) -@@ -513,6 +516,7 @@ impl CPUInterface for CPU { - } - - /// The struct to handle events in cpu thread. -+#[allow(clippy::upper_case_acronyms)] - struct CPUThreadWorker { - thread_cpu: Arc, - } -diff --git a/cpu/src/x86_64/mod.rs b/cpu/src/x86_64/mod.rs -index 2880778..83635d4 100644 ---- a/cpu/src/x86_64/mod.rs -+++ b/cpu/src/x86_64/mod.rs -@@ -42,6 +42,7 @@ const MSR_LIST: &[u32] = &[ - const MSR_IA32_MISC_ENABLE: u32 = 0x01a0; - const MSR_IA32_MISC_ENABLE_FAST_STRING: u64 = 0x1; - -+#[allow(clippy::upper_case_acronyms)] - #[derive(Default)] - /// X86 CPU booting configure information - pub struct X86CPUBootConfig { -@@ -61,6 +62,7 @@ pub struct X86CPUBootConfig { - pub pml4_start: u64, - } - -+#[allow(clippy::upper_case_acronyms)] - #[derive(Default, Copy, Clone)] - pub struct X86CPU { - id: u32, -diff --git a/devices/src/interrupt_controller/mod.rs b/devices/src/interrupt_controller/mod.rs -index 2a00aa8..123c552 100644 ---- a/devices/src/interrupt_controller/mod.rs -+++ b/devices/src/interrupt_controller/mod.rs -@@ -23,6 +23,8 @@ - //! ## Platform Support - //! - //! - `aarch64` -+ -+#[allow(clippy::upper_case_acronyms)] - #[cfg(target_arch = "aarch64")] - mod aarch64; - -diff --git a/devices/src/legacy/pl031.rs b/devices/src/legacy/pl031.rs -index 9eefa2b..023c04a 100644 ---- a/devices/src/legacy/pl031.rs -+++ b/devices/src/legacy/pl031.rs -@@ -51,6 +51,7 @@ const RTC_ICR: u64 = 0x1c; - const RTC_PERIPHERAL_ID: [u8; 8] = [0x31, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1]; - - /// Pl031 structure. -+#[allow(clippy::upper_case_acronyms)] - pub struct PL031 { - /// Match register value. - mr: u32, -@@ -131,7 +132,7 @@ impl PL031 { - impl SysBusDevOps for PL031 { - /// Read data from registers by guest. - fn read(&mut self, data: &mut [u8], _base: GuestAddress, offset: u64) -> bool { -- if offset >= 0xFE0 && offset < 0x1000 { -+ if (0xFE0..0x1000).contains(&offset) { - let value = u32::from(RTC_PERIPHERAL_ID[((offset - 0xFE0) >> 2) as usize]); - match data.len() { - 1 => data[0] = value as u8, -diff --git a/machine_manager/src/qmp/mod.rs b/machine_manager/src/qmp/mod.rs -index a680512..d86c3b4 100644 ---- a/machine_manager/src/qmp/mod.rs -+++ b/machine_manager/src/qmp/mod.rs -@@ -70,9 +70,9 @@ static mut QMP_CHANNEL: Option> = None; - /// #[macro_use] - /// use machine_manager::qmp::*; - /// --/// event!(SHUTDOWN; shutdown_msg); --/// event!(STOP); --/// event!(RESUME); -+/// event!(Shutdown; shutdown_msg); -+/// event!(Stop); -+/// event!(Resume); - /// ``` - #[macro_export] - macro_rules! event { -@@ -364,11 +364,11 @@ pub fn handle_qmp( - - // handle shutdown command - if shutdown_flag { -- let shutdown_msg = schema::SHUTDOWN { -+ let shutdown_msg = schema::Shutdown { - guest: false, - reason: "host-qmp-quit".to_string(), - }; -- event!(SHUTDOWN; shutdown_msg); -+ event!(Shutdown; shutdown_msg); - TempCleaner::clean(); - - std::io::stdin() -@@ -497,10 +497,7 @@ impl QmpChannel { - /// - /// * `name` - Name of file descriptor. - pub fn get_fd(name: &str) -> Option { -- match Self::inner().fds.read().unwrap().get(name) { -- Some(fd) => Some(*fd), -- None => None, -- } -+ Self::inner().fds.read().unwrap().get(name).copied() - } - - /// Send a `QmpEvent` to client. -@@ -603,7 +600,7 @@ mod tests { - r#"{"event":"STOP","data":{},"timestamp":{"seconds":1575531524,"microseconds":91519}}"#; - let qmp_event: schema::QmpEvent = serde_json::from_str(&event_json).unwrap(); - match qmp_event { -- schema::QmpEvent::STOP { -+ schema::QmpEvent::Stop { - data: _, - timestamp: _, - } => { -@@ -646,12 +643,12 @@ mod tests { - QmpChannel::bind_writer(SocketRWHandler::new(socket.get_stream_fd())); - - // 1.send no-content event -- event!(STOP); -+ event!(Stop); - let length = client.read(&mut buffer).unwrap(); - let qmp_event: schema::QmpEvent = - serde_json::from_str(&(String::from_utf8_lossy(&buffer[..length]))).unwrap(); - match qmp_event { -- schema::QmpEvent::STOP { -+ schema::QmpEvent::Stop { - data: _, - timestamp: _, - } => { -@@ -661,16 +658,16 @@ mod tests { - } - - // 2.send with-content event -- let shutdown_event = schema::SHUTDOWN { -+ let shutdown_event = schema::Shutdown { - guest: true, - reason: "guest-shutdown".to_string(), - }; -- event!(SHUTDOWN; shutdown_event); -+ event!(Shutdown; shutdown_event); - let length = client.read(&mut buffer).unwrap(); - let qmp_event: schema::QmpEvent = - serde_json::from_str(&(String::from_utf8_lossy(&buffer[..length]))).unwrap(); - match qmp_event { -- schema::QmpEvent::SHUTDOWN { data, timestamp: _ } => { -+ schema::QmpEvent::Shutdown { data, timestamp: _ } => { - assert_eq!(data.guest, true); - assert_eq!(data.reason, "guest-shutdown".to_string()); - } -diff --git a/machine_manager/src/qmp/qmp_schema.rs b/machine_manager/src/qmp/qmp_schema.rs -index 340945e..c02ecbf 100644 ---- a/machine_manager/src/qmp/qmp_schema.rs -+++ b/machine_manager/src/qmp/qmp_schema.rs -@@ -19,6 +19,7 @@ pub use serde_json::Value as Any; - use crate::qmp::{Command, Empty, Event, TimeStamp}; - - /// A error enum for qmp -+#[allow(clippy::upper_case_acronyms)] - #[derive(Debug, Clone, Serialize, Deserialize)] - pub enum QmpErrorClass { - #[serde(rename = "GenericError")] -@@ -538,6 +539,7 @@ impl Command for query_hotpluggable_cpus { - } - } - -+#[allow(clippy::upper_case_acronyms)] - #[derive(Default, Debug, Clone, Serialize, Deserialize)] - pub struct HotpluggableCPU { - #[serde(rename = "type")] -@@ -772,7 +774,7 @@ impl Command for getfd { - } - } - --/// SHUTDOWN -+/// Shutdown - /// - /// Emitted when the virtual machine has shut down, indicating that StratoVirt is - /// about to exit. -@@ -783,7 +785,7 @@ impl Command for getfd { - /// will not exit, and a STOP event will eventually follow the SHUTDOWN event - #[derive(Debug, Clone, Serialize, Deserialize)] - #[serde(deny_unknown_fields)] --pub struct SHUTDOWN { -+pub struct Shutdown { - /// If true, the shutdown was triggered by a guest request (such as - /// a guest-initiated ACPI shutdown request or other hardware-specific - /// action) rather than a host request (such as sending StratoVirt a SIGINT). -@@ -792,16 +794,16 @@ pub struct SHUTDOWN { - pub reason: String, - } - --impl Event for SHUTDOWN { -+impl Event for Shutdown { - const NAME: &'static str = "SHUTDOWN"; - } - --/// RESET -+/// Reset - /// - /// Emitted when the virtual machine is reset - #[derive(Debug, Clone, Serialize, Deserialize)] - #[serde(deny_unknown_fields)] --pub struct RESET { -+pub struct Reset { - /// If true, the reset was triggered by a guest request (such as - /// a guest-initiated ACPI reboot request or other hardware-specific action - /// ) rather than a host request (such as the QMP command system_reset). -@@ -809,33 +811,33 @@ pub struct RESET { - pub guest: bool, - } - --impl Event for RESET { -+impl Event for Reset { - const NAME: &'static str = "RESET"; - } - --/// STOP -+/// Stop - /// - /// Emitted when the virtual machine is stopped - #[derive(Debug, Clone, Serialize, Deserialize, Default)] - #[serde(deny_unknown_fields)] --pub struct STOP {} -+pub struct Stop {} - --impl Event for STOP { -+impl Event for Stop { - const NAME: &'static str = "STOP"; - } - --/// RESUME -+/// Resume - /// - /// Emitted when the virtual machine resumes execution - #[derive(Debug, Clone, Serialize, Deserialize, Default)] - #[serde(deny_unknown_fields)] --pub struct RESUME {} -+pub struct Resume {} - --impl Event for RESUME { -+impl Event for Resume { - const NAME: &'static str = "RESUME"; - } - --/// DEVICE_DELETED -+/// DeviceDeleted - /// - /// Emitted whenever the device removal completion is acknowledged by the guest. - /// At this point, it's safe to reuse the specified device ID. Device removal can -@@ -851,7 +853,7 @@ impl Event for RESUME { - /// ``` - #[derive(Debug, Clone, Serialize, Deserialize)] - #[serde(deny_unknown_fields)] --pub struct DEVICE_DELETED { -+pub struct DeviceDeleted { - /// Device name. - #[serde(rename = "device", default, skip_serializing_if = "Option::is_none")] - pub device: Option, -@@ -860,7 +862,7 @@ pub struct DEVICE_DELETED { - pub path: String, - } - --impl Event for DEVICE_DELETED { -+impl Event for DeviceDeleted { - const NAME: &'static str = "DEVICE_DELETED"; - } - -@@ -868,31 +870,31 @@ impl Event for DEVICE_DELETED { - #[serde(tag = "event")] - pub enum QmpEvent { - #[serde(rename = "SHUTDOWN")] -- SHUTDOWN { -- data: SHUTDOWN, -+ Shutdown { -+ data: Shutdown, - timestamp: TimeStamp, - }, - #[serde(rename = "RESET")] -- RESET { data: RESET, timestamp: TimeStamp }, -+ Reset { data: Reset, timestamp: TimeStamp }, - #[serde(rename = "STOP")] -- STOP { -+ Stop { - #[serde(default)] -- data: STOP, -+ data: Stop, - timestamp: TimeStamp, - }, - #[serde(rename = "RESUME")] -- RESUME { -+ Resume { - #[serde(default)] -- data: RESUME, -+ data: Resume, - timestamp: TimeStamp, - }, - #[serde(rename = "DEVICE_DELETED")] -- DEVICE_DELETED { -- data: DEVICE_DELETED, -+ DeviceDeleted { -+ data: DeviceDeleted, - timestamp: TimeStamp, - }, - #[serde(rename = "BALLOON_CHANGED")] -- BALLOON_CHANGED { -+ BalloonChanged { - data: BalloonInfo, - timestamp: TimeStamp, - }, -diff --git a/machine_manager/src/socket.rs b/machine_manager/src/socket.rs -index 37dd176..d7b1205 100644 ---- a/machine_manager/src/socket.rs -+++ b/machine_manager/src/socket.rs -@@ -330,6 +330,7 @@ impl SocketStream { - /// Ok(()) - /// } - /// ``` -+#[allow(clippy::upper_case_acronyms)] - pub struct SocketRWHandler { - /// Socket fd to read and write message - socket_fd: RawFd, -diff --git a/micro_vm/src/lib.rs b/micro_vm/src/lib.rs -index 6380e43..7188f21 100644 ---- a/micro_vm/src/lib.rs -+++ b/micro_vm/src/lib.rs -@@ -270,16 +270,19 @@ impl LightMachine { - /// On x86_64, there is a gap ranged from (4G - 768M) to 4G, which will be skipped. - fn arch_ram_ranges(mem_size: u64) -> Vec<(u64, u64)> { - // ranges is the vector of (start_addr, size) -- let mut ranges = Vec::<(u64, u64)>::new(); -+ #[allow(unused_mut)] -+ let mut ranges; - - #[cfg(target_arch = "aarch64")] -- ranges.push((MEM_LAYOUT[LayoutEntryType::Mem as usize].0, mem_size)); -- -+ { -+ let mem_start = MEM_LAYOUT[LayoutEntryType::Mem as usize].0; -+ ranges = vec![(mem_start, mem_size)]; -+ } - #[cfg(target_arch = "x86_64")] - { - let gap_start = MEM_LAYOUT[LayoutEntryType::MemBelow4g as usize].0 - + MEM_LAYOUT[LayoutEntryType::MemBelow4g as usize].1; -- ranges.push((0, std::cmp::min(gap_start, mem_size))); -+ ranges = vec![(0, std::cmp::min(gap_start, mem_size))]; - if mem_size > gap_start { - let gap_end = MEM_LAYOUT[LayoutEntryType::MemAbove4g as usize].0; - ranges.push((gap_end, mem_size - gap_start)); -@@ -976,7 +979,7 @@ impl LightMachine { - impl MachineLifecycle for LightMachine { - fn pause(&self) -> bool { - if self.notify_lifecycle(KvmVmState::Running, KvmVmState::Paused) { -- event!(STOP); -+ event!(Stop); - - true - } else { -@@ -989,7 +992,7 @@ impl MachineLifecycle for LightMachine { - return false; - } - -- event!(RESUME); -+ event!(Resume); - - true - } -@@ -1268,11 +1271,11 @@ impl DeviceInterface for LightMachine { - fn device_del(&self, device_id: String) -> Response { - match self.del_replaceable_device(&device_id) { - Ok(path) => { -- let block_del_event = qmp_schema::DEVICE_DELETED { -+ let block_del_event = qmp_schema::DeviceDeleted { - device: Some(device_id), - path, - }; -- event!(DEVICE_DELETED; block_del_event); -+ event!(DeviceDeleted; block_del_event); - - Response::create_empty_response() - } -@@ -1548,6 +1551,7 @@ fn generate_virtio_devices_node(fdt: &mut Vec, res: &SysRes) -> util::errors - } - - /// Trait that helps to generate all nodes in device-tree. -+#[allow(clippy::upper_case_acronyms)] - #[cfg(target_arch = "aarch64")] - trait CompileFDTHelper { - /// Function that helps to generate cpu nodes. -@@ -1578,7 +1582,7 @@ impl CompileFDTHelper for LightMachine { - let clster = format!("/cpus/cpu-map/cluster{}", cluster); - device_tree::add_sub_node(fdt, &clster)?; - -- for i in 0..2 as u32 { -+ for i in 0..2_u32 { - let sub_cluster = format!("{}/cluster{}", clster, i); - device_tree::add_sub_node(fdt, &sub_cluster)?; - -diff --git a/util/src/aio/libaio.rs b/util/src/aio/libaio.rs -index b07a699..b7e4d33 100644 ---- a/util/src/aio/libaio.rs -+++ b/util/src/aio/libaio.rs -@@ -43,13 +43,13 @@ pub struct IoCb { - #[allow(non_camel_case_types)] - #[derive(Copy, Clone)] - pub enum IoCmd { -- PREAD = 0, -- PWRITE = 1, -- FSYNC = 2, -- FDSYNC = 3, -- NOOP = 6, -- PREADV = 7, -- PWRITEV = 8, -+ Pread = 0, -+ Pwrite = 1, -+ Fsync = 2, -+ Fdsync = 3, -+ Noop = 6, -+ Preadv = 7, -+ Pwritev = 8, - } - - #[repr(C)] -diff --git a/util/src/aio/mod.rs b/util/src/aio/mod.rs -index f0b0401..e5b5e01 100644 ---- a/util/src/aio/mod.rs -+++ b/util/src/aio/mod.rs -@@ -46,7 +46,7 @@ impl AioCb { - AioCb { - last_aio: true, - file_fd: 0, -- opcode: IoCmd::NOOP, -+ opcode: IoCmd::Noop, - iovec: Vec::new(), - offset: 0, - process: false, -@@ -155,7 +155,7 @@ impl Aio { - - pub fn rw_sync(&mut self, cb: AioCb) -> Result<()> { - let ret = match cb.opcode { -- IoCmd::PREADV => { -+ IoCmd::Preadv => { - let mut r = 0; - let mut off = cb.offset; - for iov in cb.iovec.iter() { -@@ -164,7 +164,7 @@ impl Aio { - } - r - } -- IoCmd::PWRITEV => { -+ IoCmd::Pwritev => { - let mut r = 0; - let mut off = cb.offset; - for iov in cb.iovec.iter() { -@@ -173,7 +173,7 @@ impl Aio { - } - r - } -- IoCmd::FDSYNC => raw_datasync(cb.file_fd)?, -+ IoCmd::Fdsync => raw_datasync(cb.file_fd)?, - _ => -1, - }; - (self.complete_func)(&cb, ret); -diff --git a/util/src/arg_parser.rs b/util/src/arg_parser.rs -index 9240a22..de051ae 100644 ---- a/util/src/arg_parser.rs -+++ b/util/src/arg_parser.rs -@@ -34,11 +34,11 @@ type ArgsMap = BTreeMap>; - #[derive(PartialEq, Debug)] - pub enum HelpType { - /// Argument as a Flag. -- FLAGS, -+ Flags, - /// Argument as a Option. -- OPTION, -+ Optional, - /// Argument will not output in help message. -- HIDDEN, -+ Hidden, - } - - /// Structure to store `ArgParser` information, which contains a command line -@@ -222,13 +222,13 @@ impl<'a> ArgParser<'a> { - for arg in self.args.values() { - let (help_str, help_type) = (*arg).help_message(); - match help_type { -- HelpType::FLAGS => { -+ HelpType::Flags => { - output_flags.push(help_str); - } -- HelpType::OPTION => { -+ HelpType::Optional => { - output_options.push(help_str); - } -- HelpType::HIDDEN => {} -+ HelpType::Hidden => {} - } - } - -@@ -452,7 +452,7 @@ impl<'a> Arg<'a> { - /// Produce help message for argument. - fn help_message(&self) -> (String, HelpType) { - if self.hiddable { -- (String::new(), HelpType::HIDDEN) -+ (String::new(), HelpType::Hidden) - } else if self.short.is_some() { - let font_str = format!( - "{}{}{}, {}{}", -@@ -465,7 +465,7 @@ impl<'a> Arg<'a> { - let mut help_str = format!("{}{}", TWENTY_FOUT_BLANK, self.help.unwrap_or("")); - let font_offset = font_str.len(); - help_str.replace_range(..font_offset, &font_str); -- (help_str, HelpType::FLAGS) -+ (help_str, HelpType::Flags) - } else { - let font_str = if self.values.is_some() { - format!( -@@ -497,7 +497,7 @@ impl<'a> Arg<'a> { - } else { - help_str.replace_range(..font_offset, &font_str); - } -- (help_str, HelpType::OPTION) -+ (help_str, HelpType::Optional) - } - } - -@@ -766,7 +766,7 @@ mod tests { - assert_eq!(arg.value.as_ref().unwrap(), "vm1"); - - let (help_msg, help_type) = arg.help_message(); -- assert_eq!(help_type, HelpType::FLAGS); -+ assert_eq!(help_type, HelpType::Flags); - assert_eq!( - help_msg, - format!( -diff --git a/util/src/device_tree.rs b/util/src/device_tree.rs -index 59f9642..120fd7c 100644 ---- a/util/src/device_tree.rs -+++ b/util/src/device_tree.rs -@@ -209,6 +209,7 @@ pub fn dump_dtb(fdt: &[u8], file_path: &str) { - } - - /// Trait for devices to be added to the Flattened Device Tree. -+#[allow(clippy::upper_case_acronyms)] - pub trait CompileFDT { - /// function to generate fdt node - /// -diff --git a/util/src/logger.rs b/util/src/logger.rs -index 015c9ab..da155b4 100644 ---- a/util/src/logger.rs -+++ b/util/src/logger.rs -@@ -89,11 +89,7 @@ pub fn init_vm_logger( - level: Option, - logfile: Option>, - ) -> Result<(), log::SetLoggerError> { -- let buffer = match logfile { -- Some(x) => Some(Mutex::new(x)), -- None => None, -- }; -- -+ let buffer = logfile.map(Mutex::new); - let logger = VmLogger { - level: level.unwrap_or(Level::Info), - handler: buffer, -diff --git a/virtio/src/balloon.rs b/virtio/src/balloon.rs -index 167cbe0..86af9b1 100644 ---- a/virtio/src/balloon.rs -+++ b/virtio/src/balloon.rs -@@ -511,7 +511,7 @@ impl BalloonIoHandler { - let msg = BalloonInfo { - actual: ram_size - balloon_size, - }; -- event!(BALLOON_CHANGED; msg); -+ event!(BalloonChanged; msg); - } - - /// Get the memory size of balloon. -@@ -687,7 +687,7 @@ impl Balloon { - let msg = BalloonInfo { - actual: self.get_guest_memory_size(), - }; -- event!(BALLOON_CHANGED; msg); -+ event!(BalloonChanged; msg); - Ok(()) - } - -diff --git a/virtio/src/block.rs b/virtio/src/block.rs -index 70f50c6..4377fda 100644 ---- a/virtio/src/block.rs -+++ b/virtio/src/block.rs -@@ -258,7 +258,7 @@ impl Request { - let mut aiocb = AioCb { - last_aio, - file_fd: disk.as_raw_fd(), -- opcode: IoCmd::NOOP, -+ opcode: IoCmd::Noop, - iovec: Vec::new(), - offset: (self.out_header.sector << SECTOR_SHIFT) as usize, - process: true, -@@ -276,7 +276,7 @@ impl Request { - - match self.out_header.request_type { - VIRTIO_BLK_T_IN => { -- aiocb.opcode = IoCmd::PREADV; -+ aiocb.opcode = IoCmd::Preadv; - if direct { - (*aio).as_mut().rw_aio(aiocb).chain_err(|| { - "Failed to process block request for reading asynchronously" -@@ -288,7 +288,7 @@ impl Request { - } - } - VIRTIO_BLK_T_OUT => { -- aiocb.opcode = IoCmd::PWRITEV; -+ aiocb.opcode = IoCmd::Pwritev; - if direct { - (*aio).as_mut().rw_aio(aiocb).chain_err(|| { - "Failed to process block request for writing asynchronously" -@@ -300,7 +300,7 @@ impl Request { - } - } - VIRTIO_BLK_T_FLUSH => { -- aiocb.opcode = IoCmd::FDSYNC; -+ aiocb.opcode = IoCmd::Fdsync; - (*aio) - .as_mut() - .rw_sync(aiocb) -@@ -843,8 +843,7 @@ impl VirtioDevice for Block { - return Err(ErrorKind::DevConfigOverflow(offset, config_len as u64).into()); - } - -- self.config_space[(offset as usize)..(offset as usize + data_len)] -- .copy_from_slice(&data[..]); -+ self.config_space[(offset as usize)..(offset as usize + data_len)].copy_from_slice(data); - - Ok(()) - } -diff --git a/virtio/src/net.rs b/virtio/src/net.rs -index 41b68cd..43545f5 100644 ---- a/virtio/src/net.rs -+++ b/virtio/src/net.rs -@@ -638,7 +638,7 @@ impl VirtioDevice for Net { - return Err(ErrorKind::DevConfigOverflow(offset, config_len as u64).into()); - } - -- config_slice[(offset as usize)..(offset as usize + data_len)].copy_from_slice(&data[..]); -+ config_slice[(offset as usize)..(offset as usize + data_len)].copy_from_slice(data); - - Ok(()) - } -diff --git a/virtio/src/vhost/kernel/net.rs b/virtio/src/vhost/kernel/net.rs -index 1251ede..45221b9 100644 ---- a/virtio/src/vhost/kernel/net.rs -+++ b/virtio/src/vhost/kernel/net.rs -@@ -205,7 +205,7 @@ impl VirtioDevice for Net { - return Err(ErrorKind::DevConfigOverflow(offset, config_len as u64).into()); - } - -- config_slice[(offset as usize)..(offset as usize + data_len)].copy_from_slice(&data[..]); -+ config_slice[(offset as usize)..(offset as usize + data_len)].copy_from_slice(data); - - Ok(()) - } -diff --git a/virtio/src/vhost/kernel/vsock.rs b/virtio/src/vhost/kernel/vsock.rs -index c464149..979670f 100644 ---- a/virtio/src/vhost/kernel/vsock.rs -+++ b/virtio/src/vhost/kernel/vsock.rs -@@ -162,8 +162,7 @@ impl VirtioDevice for Vsock { - return Err(ErrorKind::DevConfigOverflow(offset, config_len as u64).into()); - } - -- self.config_space[(offset as usize)..(offset as usize + data_len)] -- .copy_from_slice(&data[..]); -+ self.config_space[(offset as usize)..(offset as usize + data_len)].copy_from_slice(data); - - Ok(()) - } --- -2.25.1 - diff --git a/0006-syscall-add-syscall-newfstatat-in-x86_64-unknown-lin.patch b/0006-syscall-add-syscall-newfstatat-in-x86_64-unknown-lin.patch new file mode 100644 index 0000000000000000000000000000000000000000..497f2f022db5ae0df9eeeb7a1c32d5469d1851fa --- /dev/null +++ b/0006-syscall-add-syscall-newfstatat-in-x86_64-unknown-lin.patch @@ -0,0 +1,99 @@ +From 2a70e217561e64f460e95d4d89d145fc615f12ec Mon Sep 17 00:00:00 2001 +From: Qi Xi +Date: Fri, 20 Aug 2021 15:43:00 +0800 +Subject: [PATCH 6/8] syscall: add syscall "newfstatat" in + x86_64-unknown-linux-gnu target + +When we run stratovirt, built with GNU toolchain on x86 platform, and +use serial port for IO, it will be blocked. The bug is caused by when +it is the first time for rtc device to call "libc::gmtime_r" after +seccomp taking effect, it will use the syscall "newfstatat" which is +not in the syscall whitelist. + +The bug is fixed by adding "newfstatat" to syscall whitelist with +x86_64-unknown-linux-gnu target. + +Signed-off-by: Qi Xi +--- + docs/config_guidebook.md | 18 +++++++++++++++--- + machine/src/micro_vm/syscall.rs | 4 +++- + machine/src/standard_vm/x86_64/syscall.rs | 4 +++- + 3 files changed, 21 insertions(+), 5 deletions(-) + +diff --git a/docs/config_guidebook.md b/docs/config_guidebook.md +index 6a5cda7..72b4c7e 100644 +--- a/docs/config_guidebook.md ++++ b/docs/config_guidebook.md +@@ -679,10 +679,22 @@ And you can also restore StratoVirt's **pid number** to a file by: + ### 4.2 Seccomp + + StratoVirt use [seccomp(2)](https://man7.org/linux/man-pages/man2/seccomp.2.html) to limit the syscalls +-in StratoVirt process by default. StratoVirt use only 40 syscalls in x86_64 (39 syscalls in aarch64) after running. +-It will make a slight influence on performance to StratoVirt. If you want to disable seccomp, you can +-run StratoVirt with `-disable-seccomp`. ++in StratoVirt process by default. It will make a slight influence on performance to StratoVirt. ++* X86_64 + ++| Number of Syscalls | GNU Toolchain | MUSL Toolchain | ++| :----------------: | :-----------: | :------------: | ++| Micro_vm | 41 | 41 | ++| Standard_vm | 46 | 43 | ++ ++* AArch64 ++ ++| Number of Syscalls | GNU Toolchain | MUSL Toolchain | ++| :----------------: | :-----------: | :------------: | ++| Micro_vm | 39 | 40 | ++| Standard_vm | 43 | 42 | ++ ++If you want to disable seccomp, you can run StratoVirt with `-disable-seccomp`. + ```shell + # cmdline + -disable-seccomp +diff --git a/machine/src/micro_vm/syscall.rs b/machine/src/micro_vm/syscall.rs +index eb52df6..ddc9023 100644 +--- a/machine/src/micro_vm/syscall.rs ++++ b/machine/src/micro_vm/syscall.rs +@@ -92,7 +92,7 @@ ioctl_iowr_nr!(KVM_GET_REG_LIST, KVMIO, 0xb0, kvm_reg_list); + /// + /// # Notes + /// This allowlist limit syscall with: +-/// * x86_64-unknown-gnu: 40 syscalls ++/// * x86_64-unknown-gnu: 41 syscalls + /// * x86_64-unknown-musl: 41 syscalls + /// * aarch64-unknown-gnu: 39 syscalls + /// * aarch64-unknown-musl: 40 syscalls +@@ -153,6 +153,8 @@ pub fn syscall_whitelist() -> Vec { + BpfRule::new(libc::SYS_statx), + #[cfg(all(target_env = "musl", target_arch = "x86_64"))] + BpfRule::new(libc::SYS_stat), ++ #[cfg(all(target_env = "gnu", target_arch = "x86_64"))] ++ BpfRule::new(libc::SYS_newfstatat), + #[cfg(all(target_env = "musl", target_arch = "aarch64"))] + BpfRule::new(libc::SYS_newfstatat), + #[cfg(target_arch = "x86_64")] +diff --git a/machine/src/standard_vm/x86_64/syscall.rs b/machine/src/standard_vm/x86_64/syscall.rs +index d794c78..dddeb8a 100644 +--- a/machine/src/standard_vm/x86_64/syscall.rs ++++ b/machine/src/standard_vm/x86_64/syscall.rs +@@ -78,7 +78,7 @@ ioctl_iowr_nr!(KVM_GET_MSRS, KVMIO, 0x88, kvm_msrs); + /// + /// # Notes + /// This allowlist limit syscall with: +-/// * x86_64-unknown-gnu: 45 syscalls ++/// * x86_64-unknown-gnu: 46 syscalls + /// * x86_64-unknown-musl: 43 syscalls + /// To reduce performance losses, the syscall rules is ordered by frequency. + pub fn syscall_whitelist() -> Vec { +@@ -132,6 +132,8 @@ pub fn syscall_whitelist() -> Vec { + BpfRule::new(libc::SYS_gettid), + BpfRule::new(libc::SYS_getpid), + BpfRule::new(libc::SYS_fstat), ++ #[cfg(all(target_env = "gnu"))] ++ BpfRule::new(libc::SYS_newfstatat), + BpfRule::new(libc::SYS_pread64), + BpfRule::new(libc::SYS_pwrite64), + BpfRule::new(libc::SYS_statx), +-- +2.25.1 + diff --git a/0007-testcases-virtio_blk-decrease-hot-plugged-blk-number.patch b/0007-testcases-virtio_blk-decrease-hot-plugged-blk-number.patch deleted file mode 100644 index 3c03fefe1c7672098145c6114bfdbf987b507f5b..0000000000000000000000000000000000000000 --- a/0007-testcases-virtio_blk-decrease-hot-plugged-blk-number.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 9d9625192d5aebb4d2bc668cabf36ceb1abf3824 Mon Sep 17 00:00:00 2001 -From: Zhu huankai -Date: Wed, 12 May 2021 15:00:29 +0800 -Subject: [PATCH] testcases:virtio_blk: decrease hot plugged blk number - -stratovirt supports only 4 block devices to hot plugged at present. - -Signed-off-by: Zhu huankai ---- - .../microvm/functional/test_microvm_virtio_blk.py | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/tests/hydropper/testcases/microvm/functional/test_microvm_virtio_blk.py b/tests/hydropper/testcases/microvm/functional/test_microvm_virtio_blk.py -index d93fe78..dea710d 100644 ---- a/tests/hydropper/testcases/microvm/functional/test_microvm_virtio_blk.py -+++ b/tests/hydropper/testcases/microvm/functional/test_microvm_virtio_blk.py -@@ -66,14 +66,14 @@ def test_microvm_virtio_blk_at_dt(test_session_root_path, microvm, testtimes): - """ - Test virtio-blk hotplug and unplug: - -- 1) Generate 5 temp disks and add them to test_vm. -+ 1) Generate 3 temp disks and add them to test_vm. - 2) Assert disks' name and size as expect. - 3) Delete temp disks from test_vm. - 4) Assert temp disks are deleted. - """ - test_vm = microvm - test_vm.launch() -- disknum = 5 -+ disknum = 3 - disklist = [] - for index in range(disknum): - temp_disk = os.path.join(test_session_root_path, "test_image%d" % (index + 1)) -@@ -90,7 +90,7 @@ def test_microvm_virtio_blk_at_dt(test_session_root_path, microvm, testtimes): - blkinfo = test_vm.get_lsblk_info() - logging.debug("blkinfo is %s", blkinfo) - -- for devid in ["vdb", "vdc", "vdd", "vde", "vdf"]: -+ for devid in ["vdb", "vdc", "vdd"]: - assert devid in blkinfo - assert blkinfo[devid]["size"] == "16M" - -@@ -100,7 +100,7 @@ def test_microvm_virtio_blk_at_dt(test_session_root_path, microvm, testtimes): - index += 1 - - blkinfo = test_vm.get_lsblk_info() -- for devid in ["vdb", "vdc", "vdd", "vde", "vdf"]: -+ for devid in ["vdb", "vdc", "vdd"]: - assert devid not in blkinfo - - @pytest.mark.acceptance --- -2.25.1 - diff --git a/0007-vfio-fix-the-problem-of-dma-mapping-failed.patch b/0007-vfio-fix-the-problem-of-dma-mapping-failed.patch new file mode 100644 index 0000000000000000000000000000000000000000..39b58b71482ccb031e2cb0beb03a13e4cd71d117 --- /dev/null +++ b/0007-vfio-fix-the-problem-of-dma-mapping-failed.patch @@ -0,0 +1,228 @@ +From 023dde42b55a58c7a41293566e95a0fc94efa2c6 Mon Sep 17 00:00:00 2001 +From: "Xinle.Guo" +Date: Thu, 19 Aug 2021 20:48:25 +0800 +Subject: [PATCH 7/8] vfio: fix the problem of dma mapping failed + +Failed to use libvirt to manager more than two vfio devices. +The reason is that creating a container for every vfio device, +the process stratovirt uses more than the memory locked limit. + +Signed-off-by: Xinle.Guo +--- + machine/src/lib.rs | 24 +++++++++++------------- + vfio/src/vfio_dev.rs | 25 +++++++++++++++---------- + vfio/src/vfio_pci.rs | 31 ++++++++++++++++++------------- + 3 files changed, 44 insertions(+), 36 deletions(-) + +diff --git a/machine/src/lib.rs b/machine/src/lib.rs +index 9eb3039..8ba0ba3 100644 +--- a/machine/src/lib.rs ++++ b/machine/src/lib.rs +@@ -121,7 +121,7 @@ use devices::legacy::FwCfgOps; + #[cfg(target_arch = "aarch64")] + use devices::InterruptController; + use hypervisor::KVM_FDS; +-use kvm_ioctls::{DeviceFd, VcpuFd}; ++use kvm_ioctls::VcpuFd; + use machine_manager::config::{ + get_pci_bdf, parse_balloon, parse_blk, parse_net, parse_rng_dev, parse_root_port, parse_vfio, + parse_virtconsole, parse_virtio_serial, parse_vsock, MachineMemConfig, PFlashConfig, PciBdf, +@@ -132,7 +132,7 @@ use machine_manager::machine::{KvmVmState, MachineInterface}; + use migration::MigrationManager; + use util::loop_context::{EventNotifier, NotifierCallback, NotifierOperation}; + use util::seccomp::{BpfRule, SeccompOpt, SyscallFilter}; +-use vfio::vfio_pci::create_vfio_device; ++use vfio::vfio_pci::create_vfio_container; + use vfio::{VfioContainer, VfioPciDevice}; + use virtio::{balloon_allow_list, Balloon, Block, Console, Rng, VirtioMmioDevice, VirtioPciDevice}; + use vmm_sys_util::epoll::EventSet; +@@ -478,13 +478,8 @@ pub trait MachineOps { + &mut self, + vm_config: &VmConfig, + cfg_args: &str, +- dev_fd: Arc, ++ container: Arc, + ) -> Result<()> { +- let sys_mem = self.get_sys_mem().clone(); +- let container = Arc::new( +- VfioContainer::new(dev_fd, &sys_mem).chain_err(|| "Failed to create vfio container")?, +- ); +- + let device_cfg: VfioConfig = parse_vfio(vm_config, cfg_args)?; + let path = "/sys/bus/pci/devices/".to_string() + &device_cfg.host; + let name = device_cfg.id; +@@ -543,10 +538,7 @@ pub trait MachineOps { + .chain_err(|| ErrorKind::AddDevErr("pflash".to_string()))?; + } + +- // Create an emulated kvm device that is used for VFIO. It should be created only once. +- // See the kernel docs for `KVM_CREATE_DEVICE` to get more info. +- let vfio_dev = create_vfio_device().chain_err(|| "Failed to create kvm device for VFIO")?; +- ++ let mut container: Option> = None; + for dev in &cloned_vm_config.devices { + let cfg_args = dev.1.as_str(); + match dev.0.as_str() { +@@ -581,7 +573,13 @@ pub trait MachineOps { + self.add_virtio_rng(vm_config, cfg_args)?; + } + "vfio-pci" => { +- self.add_vfio_device(&vm_config, cfg_args, vfio_dev.clone())?; ++ if container.is_none() { ++ container = Some( ++ create_vfio_container(self.get_sys_mem().clone()) ++ .chain_err(|| "Failed to create vfio container")?, ++ ); ++ } ++ self.add_vfio_device(&vm_config, cfg_args, container.clone().unwrap())?; + } + _ => { + bail!("Unsupported device: {:?}", dev.0.as_str()); +diff --git a/vfio/src/vfio_dev.rs b/vfio/src/vfio_dev.rs +index 30f7d5a..93922ba 100644 +--- a/vfio/src/vfio_dev.rs ++++ b/vfio/src/vfio_dev.rs +@@ -96,8 +96,8 @@ pub struct VfioMemoryRegion { + pub memory_size: u64, + // Host virtual address. + pub userspace_addr: u64, +- // No flags specified for now. +- flags_padding: u64, ++ // IOMMU mapped flag. ++ pub iommu_mapped: bool, + } + + /// `VfioMemInfo` structure contains pinning pages information. If any pages need to be zapped from +@@ -131,7 +131,7 @@ impl VfioMemInfo { + guest_phys_addr, + memory_size, + userspace_addr, +- flags_padding: 0_u64, ++ iommu_mapped: false, + }); + + Ok(()) +@@ -150,7 +150,7 @@ impl VfioMemInfo { + guest_phys_addr: fr.addr_range.base.raw_value(), + memory_size: fr.addr_range.size, + userspace_addr: hva + fr.offset_in_region, +- flags_padding: 0_u64, ++ iommu_mapped: false, + }; + let mut mem_regions = self.regions.lock().unwrap(); + for (index, mr) in mem_regions.iter().enumerate() { +@@ -378,9 +378,11 @@ impl VfioGroup { + return Err(ErrorKind::VfioIoctl("VFIO_GROUP_SET_CONTAINER".to_string(), ret).into()); + } + +- if let Err(e) = container.set_iommu(vfio::VFIO_TYPE1v2_IOMMU) { +- unsafe { ioctl_with_ref(&self.group, VFIO_GROUP_UNSET_CONTAINER(), &raw_fd) }; +- return Err(e).chain_err(|| "Failed to set IOMMU"); ++ if container.groups.lock().unwrap().is_empty() { ++ if let Err(e) = container.set_iommu(vfio::VFIO_TYPE1v2_IOMMU) { ++ unsafe { ioctl_with_ref(&self.group, VFIO_GROUP_UNSET_CONTAINER(), &raw_fd) }; ++ return Err(e).chain_err(|| "Failed to set IOMMU"); ++ } + } + + if let Err(e) = container.kvm_device_add_group(&self.group.as_raw_fd()) { +@@ -473,15 +475,18 @@ impl VfioDevice { + group_id = n.parse::().chain_err(|| "Invalid iommu group id")?; + } + +- let mut groups = container.groups.lock().unwrap(); +- if let Some(g) = groups.get(&group_id) { ++ if let Some(g) = container.groups.lock().unwrap().get(&group_id) { + return Ok(g.clone()); + } + let group = Arc::new(VfioGroup::new(group_id)?); + group + .connect_container(&container) + .chain_err(|| "Fail to connect container")?; +- groups.insert(group_id, group.clone()); ++ container ++ .groups ++ .lock() ++ .unwrap() ++ .insert(group_id, group.clone()); + + Ok(group) + } +diff --git a/vfio/src/vfio_pci.rs b/vfio/src/vfio_pci.rs +index 5cc674a..7bec445 100644 +--- a/vfio/src/vfio_pci.rs ++++ b/vfio/src/vfio_pci.rs +@@ -19,13 +19,12 @@ use std::sync::{Arc, Mutex, Weak}; + use byteorder::{ByteOrder, LittleEndian}; + use error_chain::ChainedError; + use kvm_bindings::{kvm_create_device, kvm_device_type_KVM_DEV_TYPE_VFIO}; +-use kvm_ioctls::DeviceFd; + use vfio_bindings::bindings::vfio; + use vmm_sys_util::eventfd::EventFd; + use vmm_sys_util::ioctl::ioctl_with_mut_ref; + + use super::errors::{ErrorKind, Result, ResultExt}; +-use address_space::{FileBackend, GuestAddress, HostMemMapping, Region, RegionOps}; ++use address_space::{AddressSpace, FileBackend, GuestAddress, HostMemMapping, Region, RegionOps}; + use hypervisor::{MsiVector, KVM_FDS}; + #[cfg(target_arch = "aarch64")] + use pci::config::SECONDARY_BUS_NUM; +@@ -380,7 +379,7 @@ impl VfioPciDevice { + .register_bar(i as usize, bar_region, vfio_bar.region_type, false, size); + } + +- self.map_guest_memory()?; ++ self.do_dma_map()?; + + Ok(()) + } +@@ -569,14 +568,17 @@ impl VfioPciDevice { + } + + /// Add all guest memory regions into IOMMU table. +- fn map_guest_memory(&mut self) -> Result<()> { ++ fn do_dma_map(&mut self) -> Result<()> { + let container = &self.vfio_device.container; +- let regions = container.vfio_mem_info.regions.lock().unwrap(); +- +- for r in regions.iter() { +- container +- .vfio_dma_map(r.guest_phys_addr, r.memory_size, r.userspace_addr) +- .chain_err(|| "Failed to add guest memory region map into IOMMU table")?; ++ let mut regions = container.vfio_mem_info.regions.lock().unwrap(); ++ ++ for r in regions.iter_mut() { ++ if !r.iommu_mapped { ++ container ++ .vfio_dma_map(r.guest_phys_addr, r.memory_size, r.userspace_addr) ++ .chain_err(|| "Failed to add guest memory region map into IOMMU table")?; ++ r.iommu_mapped = true; ++ } + } + Ok(()) + } +@@ -872,7 +874,7 @@ fn get_irq_rawfds(gsi_msi_routes: &[GsiMsiRoute]) -> Vec { + rawfds + } + +-pub fn create_vfio_device() -> Result> { ++pub fn create_vfio_container(sys_mem: Arc) -> Result> { + let mut vfio_device = kvm_create_device { + type_: kvm_device_type_KVM_DEV_TYPE_VFIO, + fd: 0, +@@ -884,7 +886,10 @@ pub fn create_vfio_device() -> Result> { + .as_ref() + .unwrap() + .create_device(&mut vfio_device) +- .chain_err(|| "Failed to create VFIO type KVM device")?; ++ .chain_err(|| "Failed to create kvm device for VFIO")?; + +- Ok(Arc::new(dev_fd)) ++ Ok(Arc::new( ++ VfioContainer::new(Arc::new(dev_fd), &sys_mem) ++ .chain_err(|| "Failed to create vfio container")?, ++ )) + } +-- +2.25.1 + diff --git a/0008-testscases-vmlife-decrease-test-blk-number.patch b/0008-testscases-vmlife-decrease-test-blk-number.patch deleted file mode 100644 index 5655c50301114289fafe43f0e04d692e148d576f..0000000000000000000000000000000000000000 --- a/0008-testscases-vmlife-decrease-test-blk-number.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 922431085a748e5420190782d138df5482095904 Mon Sep 17 00:00:00 2001 -From: Zhu huankai -Date: Wed, 12 May 2021 16:05:20 +0800 -Subject: [PATCH] testscases/vmlife: decrease test blk number - -stratovirt supports only 4 block devices at present. - -Signed-off-by: Zhu huankai ---- - .../testcases/microvm/functional/test_microvm_vmlife.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/hydropper/testcases/microvm/functional/test_microvm_vmlife.py b/tests/hydropper/testcases/microvm/functional/test_microvm_vmlife.py -index 6e015a3..ff9bc00 100644 ---- a/tests/hydropper/testcases/microvm/functional/test_microvm_vmlife.py -+++ b/tests/hydropper/testcases/microvm/functional/test_microvm_vmlife.py -@@ -30,7 +30,7 @@ def test_microvm_start(microvm, vcpu_count, memsize, vnetnums): - logging.debug("current vmhwinfo is %s", vmhwinfo) - assert vmhwinfo["cpu"]["vcpu_count"] == vcpu_count - assert vmhwinfo["mem"]["memsize"] > (memsize * 1024 * 90 / 100) -- assert len(vmhwinfo["virtio"]["virtio_blk"]) == 6 -+ assert len(vmhwinfo["virtio"]["virtio_blk"]) == 4 - assert len(vmhwinfo["virtio"]["virtio_net"]) == 2 - assert len(vmhwinfo["virtio"]["virtio_console"]) == 1 - test_vm.shutdown() --- -2.25.1 - diff --git a/0008-virtio-fix-dev_id-initialization-for-virtio-pci-and-.patch b/0008-virtio-fix-dev_id-initialization-for-virtio-pci-and-.patch new file mode 100644 index 0000000000000000000000000000000000000000..7a28031f8f2571e314e1daceeceb7b22e33fcbc5 --- /dev/null +++ b/0008-virtio-fix-dev_id-initialization-for-virtio-pci-and-.patch @@ -0,0 +1,614 @@ +From 4ba032f8967c660b8eafb3adaf9b44b95474c7c3 Mon Sep 17 00:00:00 2001 +From: Ming Yang +Date: Wed, 11 Aug 2021 14:52:26 +0800 +Subject: [PATCH 8/8] virtio: fix dev_id initialization for virtio-pci and vfio + device on aarch64 platform + +On aarch64 platform, dev_id information is necessary for virtio-pci device +to send msix. + +This commit fixes the dev_id initialization in virtio_pci transport module, +and set dev_id information according to the number of bus where the device +is attached to. + +Signed-off-by: Ming Yang +--- + pci/src/config.rs | 2 + + pci/src/msix.rs | 63 ++++++++++++++------ + pci/src/root_port.rs | 10 +--- + vfio/src/vfio_pci.rs | 34 +++++++---- + virtio/src/virtio_pci.rs | 123 ++++++++++++++++++++++++--------------- + 5 files changed, 150 insertions(+), 82 deletions(-) + +diff --git a/pci/src/config.rs b/pci/src/config.rs +index d7bd348..873fe7a 100644 +--- a/pci/src/config.rs ++++ b/pci/src/config.rs +@@ -221,6 +221,7 @@ pub enum RegionType { + } + + /// Registered bar. ++#[derive(Clone)] + pub struct Bar { + region_type: RegionType, + address: u64, +@@ -266,6 +267,7 @@ pub enum PcieDevType { + } + + /// Configuration space of PCI/PCIe device. ++#[derive(Clone)] + pub struct PciConfig { + /// Configuration space data. + pub config: Vec, +diff --git a/pci/src/msix.rs b/pci/src/msix.rs +index 2831af4..5c04575 100644 +--- a/pci/src/msix.rs ++++ b/pci/src/msix.rs +@@ -10,16 +10,19 @@ + // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + // See the Mulan PSL v2 for more details. + +-use std::sync::{Arc, Mutex}; ++use std::sync::atomic::{AtomicU16, Ordering}; ++use std::sync::{Arc, Mutex, Weak}; + + use address_space::{GuestAddress, Region, RegionOps}; + use hypervisor::{MsiVector, KVM_FDS}; + use migration::{DeviceStateDesc, FieldDesc, MigrationHook, MigrationManager, StateTransfer}; + use util::{byte_code::ByteCode, num_ops::round_up}; + +-use crate::config::{CapId, PciConfig, RegionType}; ++use crate::config::{CapId, PciConfig, RegionType, SECONDARY_BUS_NUM}; + use crate::errors::{Result, ResultExt}; +-use crate::{le_read_u16, le_read_u32, le_read_u64, le_write_u16, le_write_u32, le_write_u64}; ++use crate::{ ++ le_read_u16, le_read_u32, le_read_u64, le_write_u16, le_write_u32, le_write_u64, PciBus, ++}; + + pub const MSIX_TABLE_ENTRY_SIZE: u16 = 16; + pub const MSIX_TABLE_SIZE_MAX: u16 = 0x7ff; +@@ -71,7 +74,7 @@ pub struct Msix { + pub func_masked: bool, + pub enabled: bool, + pub msix_cap_offset: u16, +- pub dev_id: u16, ++ pub dev_id: Arc, + } + + impl Msix { +@@ -90,7 +93,7 @@ impl Msix { + func_masked: true, + enabled: true, + msix_cap_offset, +- dev_id, ++ dev_id: Arc::new(AtomicU16::new(dev_id)), + }; + msix.mask_all_vectors(); + msix +@@ -148,7 +151,11 @@ impl Msix { + le_write_u64(&mut self.pba, offset, old_val & pending_bit).unwrap(); + } + +- fn register_memory_region(msix: Arc>, region: &Region, dev_id: u16) -> Result<()> { ++ fn register_memory_region( ++ msix: Arc>, ++ region: &Region, ++ dev_id: Arc, ++ ) -> Result<()> { + let locked_msix = msix.lock().unwrap(); + let table_size = locked_msix.table.len() as u64; + let pba_size = locked_msix.pba.len() as u64; +@@ -170,7 +177,7 @@ impl Msix { + let is_masked: bool = locked_msix.is_vector_masked(vector); + if was_masked && !is_masked { + locked_msix.clear_pending_vector(vector); +- locked_msix.notify(vector, dev_id); ++ locked_msix.notify(vector, dev_id.load(Ordering::Acquire)); + } + + true +@@ -264,7 +271,7 @@ impl StateTransfer for Msix { + state.func_masked = self.func_masked; + state.enabled = self.enabled; + state.msix_cap_offset = self.msix_cap_offset; +- state.dev_id = self.dev_id; ++ state.dev_id = self.dev_id.load(Ordering::Acquire); + + Ok(state.as_bytes().to_vec()) + } +@@ -280,7 +287,7 @@ impl StateTransfer for Msix { + self.func_masked = msix_state.func_masked; + self.enabled = msix_state.enabled; + self.msix_cap_offset = msix_state.msix_cap_offset; +- self.dev_id = msix_state.dev_id; ++ self.dev_id = Arc::new(AtomicU16::new(msix_state.dev_id)); + + Ok(()) + } +@@ -318,7 +325,7 @@ impl MigrationHook for Msix { + msg_data: msg.data, + masked: false, + #[cfg(target_arch = "aarch64")] +- dev_id: self.dev_id as u32, ++ dev_id: self.dev_id.load(Ordering::Acquire) as u32, + }; + if let Err(e) = locked_irq_table.add_msi_route(allocated_gsi, msi_vector) { + bail!("Failed to add msi route to global irq routing table: {}", e); +@@ -330,7 +337,7 @@ impl MigrationHook for Msix { + + if self.is_vector_pending(vector) { + self.clear_pending_vector(vector); +- send_msix(msg, self.dev_id); ++ send_msix(msg, self.dev_id.load(Ordering::Acquire)); + } + } + } +@@ -377,7 +384,12 @@ fn send_msix(msg: Message, dev_id: u16) { + } + + /// MSI-X initialization. +-pub fn init_msix(bar_id: usize, vector_nr: u32, config: &mut PciConfig, dev_id: u16) -> Result<()> { ++pub fn init_msix( ++ bar_id: usize, ++ vector_nr: u32, ++ config: &mut PciConfig, ++ dev_id: Arc, ++) -> Result<()> { + if vector_nr > MSIX_TABLE_SIZE_MAX as u32 + 1 { + bail!("Too many msix vectors."); + } +@@ -401,7 +413,7 @@ pub fn init_msix(bar_id: usize, vector_nr: u32, config: &mut PciConfig, dev_id: + table_size, + pba_size, + msix_cap_offset as u16, +- dev_id, ++ dev_id.load(Ordering::Acquire), + ))); + let bar_size = ((table_size + pba_size) as u64).next_power_of_two(); + let region = Region::init_container_region(bar_size); +@@ -415,6 +427,17 @@ pub fn init_msix(bar_id: usize, vector_nr: u32, config: &mut PciConfig, dev_id: + Ok(()) + } + ++pub fn update_dev_id(parent_bus: &Weak>, devfn: u8, dev_id: &Arc) { ++ let bus_num = parent_bus ++ .upgrade() ++ .unwrap() ++ .lock() ++ .unwrap() ++ .number(SECONDARY_BUS_NUM as usize); ++ let device_id = ((bus_num as u16) << 8) | (devfn as u16); ++ dev_id.store(device_id, Ordering::Release); ++} ++ + #[cfg(test)] + mod tests { + use super::*; +@@ -425,9 +448,15 @@ mod tests { + let mut pci_config = PciConfig::new(PCI_CONFIG_SPACE_SIZE, 2); + + // Too many vectors. +- assert!(init_msix(0, MSIX_TABLE_SIZE_MAX as u32 + 2, &mut pci_config, 0).is_err()); +- +- init_msix(1, 2, &mut pci_config, 0).unwrap(); ++ assert!(init_msix( ++ 0, ++ MSIX_TABLE_SIZE_MAX as u32 + 2, ++ &mut pci_config, ++ Arc::new(AtomicU16::new(0)) ++ ) ++ .is_err()); ++ ++ init_msix(1, 2, &mut pci_config, Arc::new(AtomicU16::new(0))).unwrap(); + let msix_cap_start = 64_u8; + assert_eq!(pci_config.last_cap_end, 64 + MSIX_CAP_SIZE as u16); + // Capabilities pointer +@@ -492,7 +521,7 @@ mod tests { + #[test] + fn test_write_config() { + let mut pci_config = PciConfig::new(PCI_CONFIG_SPACE_SIZE, 2); +- init_msix(0, 2, &mut pci_config, 0).unwrap(); ++ init_msix(0, 2, &mut pci_config, Arc::new(AtomicU16::new(0))).unwrap(); + let msix = pci_config.msix.as_ref().unwrap(); + let mut locked_msix = msix.lock().unwrap(); + locked_msix.enabled = false; +diff --git a/pci/src/root_port.rs b/pci/src/root_port.rs +index ba1b5f7..948e31d 100644 +--- a/pci/src/root_port.rs ++++ b/pci/src/root_port.rs +@@ -10,6 +10,7 @@ + // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + // See the Mulan PSL v2 for more details. + ++use std::sync::atomic::AtomicU16; + use std::sync::{Arc, Mutex, Weak}; + + use address_space::Region; +@@ -117,13 +118,8 @@ impl PciDevOps for RootPort { + config_space[PREF_MEMORY_LIMIT as usize] = PREF_MEM_RANGE_64BIT; + self.config + .add_pcie_cap(self.devfn, self.port_num, PcieDevType::RootPort as u8)?; +- #[cfg(target_arch = "aarch64")] +- { +- self.dev_id = self.set_dev_id(0, self.devfn); +- init_msix(0, 1, &mut self.config, self.dev_id)?; +- } +- #[cfg(target_arch = "x86_64")] +- init_msix(0, 1, &mut self.config, 0)?; ++ ++ init_msix(0, 1, &mut self.config, Arc::new(AtomicU16::new(0)))?; + + let parent_bus = self.parent_bus.upgrade().unwrap(); + let mut locked_parent_bus = parent_bus.lock().unwrap(); +diff --git a/vfio/src/vfio_pci.rs b/vfio/src/vfio_pci.rs +index 5cc674a..640ff20 100644 +--- a/vfio/src/vfio_pci.rs ++++ b/vfio/src/vfio_pci.rs +@@ -14,6 +14,7 @@ use std::collections::HashMap; + use std::mem::size_of; + use std::os::unix::io::{AsRawFd, RawFd}; + use std::path::Path; ++use std::sync::atomic::{AtomicU16, Ordering}; + use std::sync::{Arc, Mutex, Weak}; + + use byteorder::{ByteOrder, LittleEndian}; +@@ -36,9 +37,9 @@ use pci::config::{ + }; + use pci::errors::Result as PciResult; + use pci::msix::{ +- is_msix_enabled, Msix, MSIX_CAP_CONTROL, MSIX_CAP_ENABLE, MSIX_CAP_FUNC_MASK, MSIX_CAP_ID, +- MSIX_CAP_SIZE, MSIX_CAP_TABLE, MSIX_TABLE_BIR, MSIX_TABLE_ENTRY_SIZE, MSIX_TABLE_OFFSET, +- MSIX_TABLE_SIZE_MAX, ++ is_msix_enabled, update_dev_id, Msix, MSIX_CAP_CONTROL, MSIX_CAP_ENABLE, MSIX_CAP_FUNC_MASK, ++ MSIX_CAP_ID, MSIX_CAP_SIZE, MSIX_CAP_TABLE, MSIX_TABLE_BIR, MSIX_TABLE_ENTRY_SIZE, ++ MSIX_TABLE_OFFSET, MSIX_TABLE_SIZE_MAX, + }; + use pci::{ + le_read_u16, le_read_u32, le_write_u16, le_write_u32, ranges_overlap, PciBus, PciDevOps, +@@ -93,7 +94,7 @@ pub struct VfioPciDevice { + // Maintains a list of GSI with irqfds that are registered to kvm. + gsi_msi_routes: Arc>>, + devfn: u8, +- dev_id: u16, ++ dev_id: Arc, + name: String, + parent_bus: Weak>, + } +@@ -119,7 +120,7 @@ impl VfioPciDevice { + vfio_bars: Arc::new(Mutex::new(Vec::with_capacity(PCI_NUM_BARS as usize))), + gsi_msi_routes: Arc::new(Mutex::new(Vec::new())), + devfn, +- dev_id: 0, ++ dev_id: Arc::new(AtomicU16::new(0)), + name, + parent_bus, + }) +@@ -404,7 +405,7 @@ impl VfioPciDevice { + table_size, + table_size / 128, + cap_offset as u16, +- self.dev_id, ++ self.dev_id.load(Ordering::Acquire), + ))); + self.pci_config.msix = Some(msix.clone()); + +@@ -418,6 +419,9 @@ impl VfioPciDevice { + + let cloned_dev = self.vfio_device.clone(); + let cloned_gsi_routes = self.gsi_msi_routes.clone(); ++ let parent_bus = self.parent_bus.clone(); ++ let dev_id = self.dev_id.clone(); ++ let devfn = self.devfn; + let write = move |data: &[u8], _: GuestAddress, offset: u64| -> bool { + let mut locked_msix = msix.lock().unwrap(); + locked_msix.table[offset as usize..(offset as usize + data.len())] +@@ -429,13 +433,15 @@ impl VfioPciDevice { + } + + let entry = locked_msix.get_message(vector as u16); ++ ++ update_dev_id(&parent_bus, devfn, &dev_id); + let msix_vector = MsiVector { + msg_addr_lo: entry.address_lo, + msg_addr_hi: entry.address_hi, + msg_data: entry.data, + masked: false, + #[cfg(target_arch = "aarch64")] +- dev_id: locked_msix.dev_id as u32, ++ dev_id: dev_id.load(Ordering::Acquire) as u32, + }; + + let mut locked_gsi_routes = cloned_gsi_routes.lock().unwrap(); +@@ -707,7 +713,7 @@ impl PciDevOps for VfioPciDevice { + .lock() + .unwrap() + .number(SECONDARY_BUS_NUM as usize); +- self.dev_id = self.set_dev_id(bus_num, self.devfn); ++ self.dev_id = Arc::new(AtomicU16::new(self.set_dev_id(bus_num, self.devfn))); + } + + self.msix_info = Some(PciResultExt::chain_err(self.get_msix_info(), || { +@@ -799,7 +805,8 @@ impl PciDevOps for VfioPciDevice { + } + + if ranges_overlap(offset, end, COMMAND as usize, COMMAND as usize + 4) { +- self.pci_config.write(offset, data, self.dev_id); ++ self.pci_config ++ .write(offset, data, self.dev_id.load(Ordering::Acquire)); + + if le_read_u32(&self.pci_config.config, offset).unwrap() & COMMAND_MEMORY_SPACE as u32 + != 0 +@@ -822,7 +829,8 @@ impl PciDevOps for VfioPciDevice { + } + } + } else if ranges_overlap(offset, end, BAR_0 as usize, (BAR_5 as usize) + REG_SIZE) { +- self.pci_config.write(offset, data, self.dev_id); ++ self.pci_config ++ .write(offset, data, self.dev_id.load(Ordering::Acquire)); + + if size == 4 && LittleEndian::read_u32(data) != 0xffff_ffff { + let parent_bus = self.parent_bus.upgrade().unwrap(); +@@ -838,7 +846,8 @@ impl PciDevOps for VfioPciDevice { + } + } else if ranges_overlap(offset, end, cap_offset, cap_offset + MSIX_CAP_SIZE as usize) { + let was_enable = is_msix_enabled(cap_offset, &self.pci_config.config); +- self.pci_config.write(offset, data, self.dev_id); ++ self.pci_config ++ .write(offset, data, self.dev_id.load(Ordering::Acquire)); + let is_enable = is_msix_enabled(cap_offset, &self.pci_config.config); + + if !was_enable && is_enable { +@@ -853,7 +862,8 @@ impl PciDevOps for VfioPciDevice { + } + } + } else { +- self.pci_config.write(offset, data, self.dev_id); ++ self.pci_config ++ .write(offset, data, self.dev_id.load(Ordering::Acquire)); + } + } + +diff --git a/virtio/src/virtio_pci.rs b/virtio/src/virtio_pci.rs +index 03645dc..aaf009e 100644 +--- a/virtio/src/virtio_pci.rs ++++ b/virtio/src/virtio_pci.rs +@@ -24,6 +24,7 @@ use pci::config::{ + VENDOR_ID, + }; + use pci::errors::{ErrorKind, Result as PciResult, ResultExt}; ++use pci::msix::update_dev_id; + use pci::{config::PciConfig, init_msix, le_write_u16, ranges_overlap, PciBus, PciDevOps}; + use util::byte_code::ByteCode; + use vmm_sys_util::eventfd::EventFd; +@@ -459,13 +460,14 @@ pub struct VirtioPciState { + } + + /// Virtio-PCI device structure ++#[derive(Clone)] + pub struct VirtioPciDevice { + /// Name of this device + name: String, + /// The entity of virtio device + device: Arc>, + /// Device id +- dev_id: u16, ++ dev_id: Arc, + /// Devfn + devfn: u8, + /// If this device is activated or not. +@@ -500,7 +502,7 @@ impl VirtioPciDevice { + VirtioPciDevice { + name, + device, +- dev_id: 0_u16, ++ dev_id: Arc::new(AtomicU16::new(0)), + devfn, + device_activated: Arc::new(AtomicBool::new(false)), + sys_mem, +@@ -518,7 +520,7 @@ impl VirtioPciDevice { + fn assign_interrupt_cb(&mut self) { + let cloned_common_cfg = self.common_config.clone(); + let cloned_msix = self.config.msix.clone(); +- let dev_id = self.dev_id; ++ let dev_id = self.dev_id.clone(); + let cb = Arc::new(Box::new( + move |int_type: &VirtioInterruptType, queue: Option<&Queue>| { + let vector = match int_type { +@@ -533,7 +535,9 @@ impl VirtioPciDevice { + }; + + if let Some(msix) = &cloned_msix { +- msix.lock().unwrap().notify(vector, dev_id); ++ msix.lock() ++ .unwrap() ++ .notify(vector, dev_id.load(Ordering::Acquire)); + } else { + bail!("Failed to send interrupt, msix does not exist"); + } +@@ -618,14 +622,7 @@ impl VirtioPciDevice { + true + }; + +- let cloned_virtio_dev = self.device.clone(); +- let cloned_common_cfg = self.common_config.clone(); +- let cloned_virtio_queue = self.queues.clone(); +- let cloned_activated_flag = self.device_activated.clone(); +- let cloned_notify_evts = self.notify_eventfds.clone(); +- let cloned_sys_mem = self.sys_mem.clone(); +- let cloned_int_cb = self.interrupt_cb.clone(); +- let cloned_msix = self.config.msix.as_ref().unwrap().clone(); ++ let cloned_pci_device = self.clone(); + let common_write = move |data: &[u8], _addr: GuestAddress, offset: u64| -> bool { + let value = match data.len() { + 1 => data[0] as u32, +@@ -639,13 +636,18 @@ impl VirtioPciDevice { + return false; + } + }; +- let old_dev_status = cloned_common_cfg.lock().unwrap().device_status; ++ let old_dev_status = cloned_pci_device ++ .common_config ++ .lock() ++ .unwrap() ++ .device_status; + +- if let Err(e) = cloned_common_cfg.lock().unwrap().write_common_config( +- &cloned_virtio_dev, +- offset, +- value, +- ) { ++ if let Err(e) = cloned_pci_device ++ .common_config ++ .lock() ++ .unwrap() ++ .write_common_config(&cloned_pci_device.device.clone(), offset, value) ++ { + error!( + "Failed to read common config of virtio-pci device, error is {}", + e.display_chain(), +@@ -653,21 +655,29 @@ impl VirtioPciDevice { + return false; + } + +- if !cloned_activated_flag.load(Ordering::Acquire) +- && cloned_common_cfg.lock().unwrap().check_device_status( +- CONFIG_STATUS_ACKNOWLEDGE +- | CONFIG_STATUS_DRIVER +- | CONFIG_STATUS_DRIVER_OK +- | CONFIG_STATUS_FEATURES_OK, +- CONFIG_STATUS_FAILED, +- ) ++ if !cloned_pci_device.device_activated.load(Ordering::Acquire) ++ && cloned_pci_device ++ .common_config ++ .lock() ++ .unwrap() ++ .check_device_status( ++ CONFIG_STATUS_ACKNOWLEDGE ++ | CONFIG_STATUS_DRIVER ++ | CONFIG_STATUS_DRIVER_OK ++ | CONFIG_STATUS_FEATURES_OK, ++ CONFIG_STATUS_FAILED, ++ ) + { +- let queue_type = cloned_common_cfg.lock().unwrap().queue_type; +- let queues_config = &cloned_common_cfg.lock().unwrap().queues_config; +- let mut locked_queues = cloned_virtio_queue.lock().unwrap(); ++ let queue_type = cloned_pci_device.common_config.lock().unwrap().queue_type; ++ let queues_config = &cloned_pci_device ++ .common_config ++ .lock() ++ .unwrap() ++ .queues_config; ++ let mut locked_queues = cloned_pci_device.queues.lock().unwrap(); + for q_config in queues_config.iter() { + let queue = Queue::new(*q_config, queue_type).unwrap(); +- if !queue.is_valid(&cloned_sys_mem) { ++ if !queue.is_valid(&cloned_pci_device.sys_mem) { + error!("Failed to activate device: Invalid queue"); + return false; + } +@@ -675,10 +685,10 @@ impl VirtioPciDevice { + locked_queues.push(arc_queue.clone()); + } + +- let queue_evts = cloned_notify_evts.clone().events; +- if let Some(cb) = cloned_int_cb.clone() { +- if let Err(e) = cloned_virtio_dev.lock().unwrap().activate( +- cloned_sys_mem.clone(), ++ let queue_evts = cloned_pci_device.notify_eventfds.clone().events; ++ if let Some(cb) = cloned_pci_device.interrupt_cb.clone() { ++ if let Err(e) = cloned_pci_device.device.lock().unwrap().activate( ++ cloned_pci_device.sys_mem.clone(), + cb, + &locked_queues, + queue_evts, +@@ -689,20 +699,43 @@ impl VirtioPciDevice { + error!("Failed to activate device: No interrupt callback"); + return false; + } +- cloned_activated_flag.store(true, Ordering::Release); ++ cloned_pci_device ++ .device_activated ++ .store(true, Ordering::Release); ++ ++ update_dev_id( ++ &cloned_pci_device.parent_bus, ++ cloned_pci_device.devfn, ++ &cloned_pci_device.dev_id, ++ ); + } + +- if old_dev_status != 0 && cloned_common_cfg.lock().unwrap().device_status == 0 { +- let mut locked_queues = cloned_virtio_queue.lock().unwrap(); ++ if old_dev_status != 0 ++ && cloned_pci_device ++ .common_config ++ .lock() ++ .unwrap() ++ .device_status ++ == 0 ++ { ++ let mut locked_queues = cloned_pci_device.queues.lock().unwrap(); + locked_queues.clear(); +- cloned_activated_flag.store(false, Ordering::Release); ++ cloned_pci_device ++ .device_activated ++ .store(false, Ordering::Release); ++ let cloned_msix = cloned_pci_device.config.msix.as_ref().unwrap().clone(); + cloned_msix.lock().unwrap().reset(); +- if let Err(e) = cloned_virtio_dev.lock().unwrap().reset() { ++ if let Err(e) = cloned_pci_device.device.lock().unwrap().reset() { + error!( + "Failed to reset virtio device, error is {}", + e.display_chain() + ); + } ++ update_dev_id( ++ &cloned_pci_device.parent_bus, ++ cloned_pci_device.devfn, ++ &cloned_pci_device.dev_id, ++ ); + } + + true +@@ -874,15 +907,12 @@ impl PciDevOps for VirtioPciDevice { + self.modern_mem_region_map(notify_cap)?; + + let nvectors = self.device.lock().unwrap().queue_num() + 1; +- #[cfg(target_arch = "aarch64")] +- { +- self.dev_id = self.set_dev_id(0, self.devfn); +- } ++ + init_msix( + VIRTIO_PCI_MSIX_BAR_IDX as usize, + nvectors as u32, + &mut self.config, +- self.dev_id, ++ self.dev_id.clone(), + )?; + + self.assign_interrupt_cb(); +@@ -950,7 +980,8 @@ impl PciDevOps for VirtioPciDevice { + return; + } + +- self.config.write(offset, data, self.dev_id); ++ self.config ++ .write(offset, data, self.dev_id.clone().load(Ordering::Acquire)); + if ranges_overlap( + offset, + end, +@@ -1388,7 +1419,7 @@ mod tests { + VIRTIO_PCI_MSIX_BAR_IDX as usize, + virtio_pci.device.lock().unwrap().queue_num() as u32 + 1, + &mut virtio_pci.config, +- virtio_pci.dev_id, ++ virtio_pci.dev_id.clone(), + ) + .unwrap(); + // Prepare valid queue config +-- +2.25.1 + diff --git a/0009-README-update-readme.patch b/0009-README-update-readme.patch deleted file mode 100644 index fc4a9bfa0daad8d4ab2b1ffd6faeb4e4135fbcc8..0000000000000000000000000000000000000000 --- a/0009-README-update-readme.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 6caa22c9928e2450032c1359922e4e87e1e798ce Mon Sep 17 00:00:00 2001 -From: Zhu Huankai -Date: Tue, 18 May 2021 10:11:48 +0800 -Subject: [PATCH] README: update readme - -Update Preparation and add Log module. - -Signed-off-by: Zhu Huankai ---- - tests/hydropper/README.cn.md | 34 ++++++++++++++++++++++++++-------- - tests/hydropper/README.md | 30 ++++++++++++++++++++++++------ - 2 files changed, 50 insertions(+), 14 deletions(-) - -diff --git a/tests/hydropper/README.cn.md b/tests/hydropper/README.cn.md -index 8d397cf..c74493d 100644 ---- a/tests/hydropper/README.cn.md -+++ b/tests/hydropper/README.cn.md -@@ -3,9 +3,10 @@ hydropper是一个基于pytest的轻量级测试框架,在其基础上封装 - - ## 如何开始 - -- - ### 环境准备 --requirements.txt里面包含了python3依赖包。 -+1. 请确保你的openEuler系统已经安装python3。 -+ -+2. requirements.txt里面包含了hydropper的依赖包。 - - - pytest>5.0.0 - - aexpect>1.5.0 -@@ -13,15 +14,26 @@ requirements.txt里面包含了python3依赖包。 - - 你可以通过下面的命令来安装这些包: - ```sh --$ pip install -r config/requirements.txt -+$ pip3 install -r requirements.txt - ``` - --网络依赖包: -+3. 请在你的openEuler系统上安装下列网络依赖包,以支持用例执行: -+ - ```sh - $ yum install nmap - $ yum install iperf3 - ``` - -+4. 网络配置(可参考以下模板): -+ -+```sh -+brctl addbr strato_br0 -+ifconfig strato_br0 up -+ifconfig strato_br0 1.1.1.1 -+``` -+ -+5. 构建测试镜像请参考 docs/IMAGE_BUILD.md。 -+ - ### 参数配置 - 请在config目录下的config.ini里配置参数和对应路径,通常的用例都需要配置好kernel和rootfs: - ```ini -@@ -39,16 +51,17 @@ STRATOVIRT_ROOTFS = /path/to/rootfs - - 请在config.ini中配置好IP_PREFIX和IP_3RD,这两项表示虚拟机IPv4地址的前24位, - 最后8位会由hydropper来自动配置。请注意虚拟机需要和主机在同一网段。 -+ - ```ini - [network.params] - # such as 'IP_PREFIX.xxx.xxx' --IP_PREFIX = xxx.xxx -+IP_PREFIX = 1.1 - # such as 'xxx.xxx.IP_3RD.xxx' --IP_3RD = xxx -+IP_3RD = 1 - ``` - - ### 运行测试用例 --你可以hydropper目录下通过以下的命令来执行用例: -+你可以在hydropper目录下通过以下的命令来执行用例: - ```sh - # 执行所有用例 - $ pytest -@@ -95,4 +108,9 @@ def test_microvm_xxx(microvm): - test_vm = microvm - test_vm.basic_config(vcpu_count=4, mem_size='4G') - test_vm.launch() --``` -\ No newline at end of file -+``` -+ -+### 日志 -+ -+- pytest默认日志路径:/var/log/pytest.log -+- stratovirt默认日志路径:/var/log/stratovirt -\ No newline at end of file -diff --git a/tests/hydropper/README.md b/tests/hydropper/README.md -index 3bdb169..a44ab42 100644 ---- a/tests/hydropper/README.md -+++ b/tests/hydropper/README.md -@@ -5,7 +5,9 @@ Hydropper is a lightweight test framework based on pytest. It encapsulates virtu - - - ### Preparation --The requirements.txt file contains the Python3 dependency package. -+1. Ensure that python3 has been installed on your openEuler system. -+ -+2. The requirements.txt file contains the Python3 dependency package. - - - pytest>5.0.0 - - aexpect>1.5.0 -@@ -13,15 +15,25 @@ The requirements.txt file contains the Python3 dependency package. - - You can install these packages by running the following commands: - ```sh --$ pip install -r config/requirements.txt -+$ pip3 install -r requirements.txt - ``` - --Network dependency package: -+3. Network dependency package: - ```sh - $ yum install nmap - $ yum install iperf3 - ``` - -+4. Network configuration(template) -+ -+```sh -+brctl addbr strato_br0 -+ifconfig strato_br0 up -+ifconfig strato_br0 1.1.1.1 -+``` -+ -+5. For details about how to build a test image, see docs/IMAGE_BUILD.md. -+ - ### Parameter configuration - Set parameters and corresponding paths in the config/config.ini. Generally, the kernel and rootfs must be configured for test cases. - ```ini -@@ -41,12 +53,13 @@ Configure IP_PREFIX and IP_3RD in the "config.ini" file, - which indicate the first 24 bits of the VM IPv4 address, - The last 8 bits are automatically configured by the hydropper. - Note that the VM and the host must be in the same network segment. -+ - ```ini - [network.params] - # such as 'IP_PREFIX.xxx.xxx' --IP_PREFIX = xxx.xxx -+IP_PREFIX = 1.1 - # such as 'xxx.xxx.IP_3RD.xxx' --IP_3RD = xxx -+IP_3RD = 1 - ``` - - ### Run testcases -@@ -97,4 +110,9 @@ def test_microvm_xxx(microvm): - test_vm = microvm - test_vm.basic_config(vcpu_count=4, mem_size='4G') - test_vm.launch() --``` -\ No newline at end of file -+``` -+ -+### Log -+ -+- pytest default log path: /var/log/pytest.log -+- stratovirt default log path: /var/log/stratovirt -\ No newline at end of file --- -2.25.1 - diff --git a/0010-docs-add-IMAGE_BUILD.md.patch b/0010-docs-add-IMAGE_BUILD.md.patch deleted file mode 100644 index fffd430392a989a3d1d6060a122d80eb2f570acf..0000000000000000000000000000000000000000 --- a/0010-docs-add-IMAGE_BUILD.md.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 74a0d73ae3658e075bf946e2e90e0d6a9785ac3c Mon Sep 17 00:00:00 2001 -From: Zhu Huankai -Date: Tue, 18 May 2021 10:27:52 +0800 -Subject: [PATCH] docs: add IMAGE_BUILD.md - -This markdown tells users how to build a test image. - -Signed-off-by: Zhu Huankai ---- - tests/hydropper/docs/IMAGE_BUILD.md | 54 +++++++++++++++++++++++++++++ - 1 file changed, 54 insertions(+) - create mode 100644 tests/hydropper/docs/IMAGE_BUILD.md - -diff --git a/tests/hydropper/docs/IMAGE_BUILD.md b/tests/hydropper/docs/IMAGE_BUILD.md -new file mode 100644 -index 0000000..1e29fb2 ---- /dev/null -+++ b/tests/hydropper/docs/IMAGE_BUILD.md -@@ -0,0 +1,54 @@ -+# 构建测试镜像 -+ -+1. 请于openEuler官网,下载所需版本的stratovirt_img和vmlinux.bin。(以下以openEuler-21.03-stratovirt-x86_64.img为例) -+ -+- 地址:https://openeuler.org/zh/download/ -+ -+2. 扩容镜像 -+ -+- 创建一个2G大小的空镜像文件extend.img -+ -+ ```shell -+ dd if=/dev/zero of=extend.img bs=50M count=40 -+ ``` -+ -+- 扩容stratovirt_img -+ -+ ```shell -+ cat extend.img >> openEuler-21.03-stratovirt-x86_64.img -+ ``` -+ -+- 调整文件系统大小 -+ -+ ```shell -+ e2fsck -f openEuler-21.03-stratovirt-x86_64.img && resize2fs openEuler-21.03-stratovirt-x86_64.img -+ ``` -+ -+3. 添加依赖包 -+ -+- 挂载镜像 -+ -+ ```shell -+ mount openEuler-21.03-stratovirt-x86_64.img /mnt -+ ``` -+ -+- 配置在线yum源,请参考: [开发环境准备.md](https://gitee.com/openeuler/docs/blob/stable2-21.03/docs/zh/docs/ApplicationDev/开发环境准备.md)。由于stratovirt_img内没有vi等编辑工具,建议先在主机上创建文件openEuler.repo,并配置好yum源,完成后将openEuler.repo拷贝到镜像内。 -+ -+ ```shell -+ cp ./openEuler.repo /mnt/etc/yum.repos.d -+ ``` -+ -+- 进入镜像挂载目录,通过yum命令安装依赖包。 -+ -+ ```shell -+ cd /mnt -+ chroot . -+ yum -y install openSSH -+ ``` -+ -+- 离开当前目录后,使用umount命令卸载镜像。 -+ -+ ```shell -+ exit -+ umount /mnt -+ ``` --- -2.25.1 - diff --git a/0011-util-fdt-implement-basic-fdt-API.patch b/0011-util-fdt-implement-basic-fdt-API.patch deleted file mode 100644 index 62a2e54a1b67dceecde6e9fa2f4ba29bcae7ba62..0000000000000000000000000000000000000000 --- a/0011-util-fdt-implement-basic-fdt-API.patch +++ /dev/null @@ -1,908 +0,0 @@ -From 792248c876ba6f3ef4fa1e6c05c7e9a157ec5528 Mon Sep 17 00:00:00 2001 -From: Jiajie Li -Date: Wed, 23 Jun 2021 14:46:57 +0800 -Subject: [PATCH 1/5] util/fdt: implement basic fdt API - -This series of patches is for rust update to version >= 1.47. -Because the higher version of rust compile Stratovirt with -aarch64-unkonwn-linux-musl target, will get error like below: - -``` - note: /usr/lib/gcc/aarch64-linux-gnu/libfdt.a(fdt_sw.o): In function `fdt_property': - (.text+0x4d4): undefined reference to `__stack_chk_guard' - (.text+0x4e0): undefined reference to `__stack_chk_guard' - (.text+0x518): undefined reference to `__stack_chk_guard' - (.text+0x530): undefined reference to `__stack_chk_fail' -``` - -Rust community recommand to use vm-fdt(https://github.com/rust-vmm/vm-fdt) -to fix this problem. But this project is not released to crate.io for now. -So add basic implementation of fdt API. - -Signed-off-by: Jiajie Li ---- - Cargo.lock | 295 ++++++++++++++++++++++++----------------------- - util/Cargo.toml | 1 + - util/src/fdt.rs | 300 ++++++++++++++++++++++++++++++++++++++++++++++++ - util/src/lib.rs | 26 +++++ - 4 files changed, 474 insertions(+), 148 deletions(-) - create mode 100644 util/src/fdt.rs - -diff --git a/Cargo.lock b/Cargo.lock -index bf866cf..3bd4bdf 100644 ---- a/Cargo.lock -+++ b/Cargo.lock -@@ -4,364 +4,363 @@ - name = "StratoVirt" - version = "0.3.0" - dependencies = [ -- "error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", -- "kvm-ioctls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", -- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", -- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", -- "machine_manager 0.3.0", -- "micro_vm 0.3.0", -- "util 0.3.0", -- "virtio 0.3.0", -- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -+ "error-chain", -+ "kvm-ioctls", -+ "libc", -+ "log", -+ "machine_manager", -+ "micro_vm", -+ "util", -+ "virtio", -+ "vmm-sys-util", - ] - - [[package]] - name = "addr2line" - version = "0.12.1" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "a49806b9dadc843c61e7c97e72490ad7f7220ae249012fbda9ad0609457c0543" - dependencies = [ -- "gimli 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", -+ "gimli", - ] - - [[package]] - name = "address_space" - version = "0.3.0" - dependencies = [ -- "error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", -- "kvm-bindings 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -- "kvm-ioctls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", -- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", -- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", -- "machine_manager 0.3.0", -- "util 0.3.0", -- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -+ "error-chain", -+ "kvm-bindings", -+ "kvm-ioctls", -+ "libc", -+ "log", -+ "machine_manager", -+ "util", -+ "vmm-sys-util", - ] - - [[package]] - name = "adler32" - version = "1.1.0" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d" - - [[package]] - name = "backtrace" - version = "0.3.49" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "05100821de9e028f12ae3d189176b41ee198341eb8f369956407fea2f5cc666c" - dependencies = [ -- "addr2line 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", -- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", -- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", -- "miniz_oxide 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -- "object 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", -- "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", -+ "addr2line", -+ "cfg-if", -+ "libc", -+ "miniz_oxide", -+ "object", -+ "rustc-demangle", - ] - - [[package]] - name = "bitflags" - version = "1.2.1" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" - - [[package]] - name = "boot_loader" - version = "0.3.0" - dependencies = [ -- "address_space 0.3.0", -- "error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", -- "kvm-bindings 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -- "kvm-ioctls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", -- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", -- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", -- "util 0.3.0", -- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -+ "address_space", -+ "error-chain", -+ "kvm-bindings", -+ "kvm-ioctls", -+ "libc", -+ "log", -+ "util", -+ "vmm-sys-util", - ] - - [[package]] - name = "byteorder" - version = "1.3.4" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" - - [[package]] - name = "cfg-if" - version = "0.1.10" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - - [[package]] - name = "cpu" - version = "0.3.0" - dependencies = [ -- "error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", -- "kvm-bindings 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -- "kvm-ioctls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", -- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", -- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", -- "machine_manager 0.3.0", -- "util 0.3.0", -- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -+ "error-chain", -+ "kvm-bindings", -+ "kvm-ioctls", -+ "libc", -+ "log", -+ "machine_manager", -+ "util", -+ "vmm-sys-util", - ] - - [[package]] - name = "devices" - version = "0.3.0" - dependencies = [ -- "address_space 0.3.0", -- "boot_loader 0.3.0", -- "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", -- "error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", -- "kvm-bindings 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -- "kvm-ioctls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", -- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", -- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", -- "machine_manager 0.3.0", -- "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", -- "sysbus 0.3.0", -- "util 0.3.0", -- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -+ "address_space", -+ "boot_loader", -+ "byteorder", -+ "error-chain", -+ "kvm-bindings", -+ "kvm-ioctls", -+ "libc", -+ "log", -+ "machine_manager", -+ "serde", -+ "sysbus", -+ "util", -+ "vmm-sys-util", - ] - - [[package]] - name = "error-chain" - version = "0.12.4" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" - dependencies = [ -- "backtrace 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)", -- "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", -+ "backtrace", -+ "version_check", - ] - - [[package]] - name = "gimli" - version = "0.21.0" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "bcc8e0c9bce37868955864dbecd2b1ab2bdf967e6f28066d65aaac620444b65c" - - [[package]] - name = "itoa" - version = "0.4.5" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" - - [[package]] - name = "kvm-bindings" - version = "0.3.0" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "8f1c07667561c3d12d77342baf28ca5d0f8c3ea2160778485640ec84a4571da2" - dependencies = [ -- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -+ "vmm-sys-util", - ] - - [[package]] - name = "kvm-ioctls" - version = "0.6.0" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "158d15da895bddca8223fa31dc9e8b9317bdc2fbc4635dea8dd575fc40dae37f" - dependencies = [ -- "kvm-bindings 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", -- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -+ "kvm-bindings", -+ "libc", -+ "vmm-sys-util", - ] - - [[package]] - name = "libc" - version = "0.2.71" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" - - [[package]] - name = "log" - version = "0.4.8" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" - dependencies = [ -- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", -+ "cfg-if", - ] - - [[package]] - name = "machine_manager" - version = "0.3.0" - dependencies = [ -- "error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", -- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", -- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", -- "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", -- "serde_json 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)", -- "util 0.3.0", -- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -+ "error-chain", -+ "libc", -+ "log", -+ "serde", -+ "serde_json", -+ "util", -+ "vmm-sys-util", - ] - - [[package]] - name = "micro_vm" - version = "0.3.0" - dependencies = [ -- "address_space 0.3.0", -- "boot_loader 0.3.0", -- "cpu 0.3.0", -- "devices 0.3.0", -- "error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", -- "kvm-bindings 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -- "kvm-ioctls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", -- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", -- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", -- "machine_manager 0.3.0", -- "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", -- "serde_json 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)", -- "sysbus 0.3.0", -- "util 0.3.0", -- "virtio 0.3.0", -- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -+ "address_space", -+ "boot_loader", -+ "cpu", -+ "devices", -+ "error-chain", -+ "kvm-bindings", -+ "kvm-ioctls", -+ "libc", -+ "log", -+ "machine_manager", -+ "serde", -+ "serde_json", -+ "sysbus", -+ "util", -+ "virtio", -+ "vmm-sys-util", - ] - - [[package]] - name = "miniz_oxide" - version = "0.3.7" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" - dependencies = [ -- "adler32 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -+ "adler32", - ] - - [[package]] - name = "object" - version = "0.20.0" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5" - - [[package]] - name = "proc-macro2" - version = "1.0.18" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" - dependencies = [ -- "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -+ "unicode-xid", - ] - - [[package]] - name = "quote" - version = "1.0.7" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" - dependencies = [ -- "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", -+ "proc-macro2", - ] - - [[package]] - name = "rustc-demangle" - version = "0.1.16" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" - - [[package]] - name = "ryu" - version = "1.0.5" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" - - [[package]] - name = "serde" - version = "1.0.114" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3" - dependencies = [ -- "serde_derive 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", -+ "serde_derive", - ] - - [[package]] - name = "serde_derive" - version = "1.0.114" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e" - dependencies = [ -- "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", -- "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", -- "syn 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", -+ "proc-macro2", -+ "quote", -+ "syn", - ] - - [[package]] - name = "serde_json" - version = "1.0.55" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "ec2c5d7e739bc07a3e73381a39d61fdb5f671c60c1df26a130690665803d8226" - dependencies = [ -- "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", -- "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", -- "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", -+ "itoa", -+ "ryu", -+ "serde", - ] - - [[package]] - name = "syn" - version = "1.0.37" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "239f255b9e3429350f188c27b807fc9920a15eb9145230ff1a7d054c08fec319" - dependencies = [ -- "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", -- "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", -- "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -+ "proc-macro2", -+ "quote", -+ "unicode-xid", - ] - - [[package]] - name = "sysbus" - version = "0.3.0" - dependencies = [ -- "address_space 0.3.0", -- "error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", -- "kvm-ioctls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", -- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", -- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -+ "address_space", -+ "error-chain", -+ "kvm-ioctls", -+ "log", -+ "vmm-sys-util", - ] - - [[package]] - name = "unicode-xid" - version = "0.2.0" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" - - [[package]] - name = "util" - version = "0.3.0" - dependencies = [ -- "error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", -- "kvm-bindings 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -- "kvm-ioctls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", -- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", -- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", -- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -+ "byteorder", -+ "error-chain", -+ "kvm-bindings", -+ "kvm-ioctls", -+ "libc", -+ "log", -+ "vmm-sys-util", - ] - - [[package]] - name = "version_check" - version = "0.9.2" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" - - [[package]] - name = "virtio" - version = "0.3.0" - dependencies = [ -- "address_space 0.3.0", -- "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", -- "error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", -- "kvm-ioctls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", -- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", -- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", -- "machine_manager 0.3.0", -- "serde_json 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)", -- "sysbus 0.3.0", -- "util 0.3.0", -- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -+ "address_space", -+ "byteorder", -+ "error-chain", -+ "kvm-ioctls", -+ "libc", -+ "log", -+ "machine_manager", -+ "serde_json", -+ "sysbus", -+ "util", -+ "vmm-sys-util", - ] - - [[package]] - name = "vmm-sys-util" - version = "0.7.0" - source = "registry+https://github.com/rust-lang/crates.io-index" -+checksum = "d1cdd1d72e262bbfb014de65ada24c1ac50e10a2e3b1e8ec052df188c2ee5dfa" - dependencies = [ -- "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", -+ "bitflags", -+ "libc", - ] -- --[metadata] --"checksum addr2line 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a49806b9dadc843c61e7c97e72490ad7f7220ae249012fbda9ad0609457c0543" --"checksum adler32 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d" --"checksum backtrace 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)" = "05100821de9e028f12ae3d189176b41ee198341eb8f369956407fea2f5cc666c" --"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" --"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" --"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" --"checksum error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" --"checksum gimli 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc8e0c9bce37868955864dbecd2b1ab2bdf967e6f28066d65aaac620444b65c" --"checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" --"checksum kvm-bindings 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1c07667561c3d12d77342baf28ca5d0f8c3ea2160778485640ec84a4571da2" --"checksum kvm-ioctls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "158d15da895bddca8223fa31dc9e8b9317bdc2fbc4635dea8dd575fc40dae37f" --"checksum libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)" = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" --"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" --"checksum miniz_oxide 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" --"checksum object 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5" --"checksum proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" --"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" --"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" --"checksum ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" --"checksum serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)" = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3" --"checksum serde_derive 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)" = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e" --"checksum serde_json 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)" = "ec2c5d7e739bc07a3e73381a39d61fdb5f671c60c1df26a130690665803d8226" --"checksum syn 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "239f255b9e3429350f188c27b807fc9920a15eb9145230ff1a7d054c08fec319" --"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" --"checksum version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" --"checksum vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d1cdd1d72e262bbfb014de65ada24c1ac50e10a2e3b1e8ec052df188c2ee5dfa" -diff --git a/util/Cargo.toml b/util/Cargo.toml -index 21d9764..a4a7f97 100644 ---- a/util/Cargo.toml -+++ b/util/Cargo.toml -@@ -14,3 +14,4 @@ kvm-ioctls = "0.6.0" - libc = "0.2.71" - log = { version = "0.4.8", features = ["std"]} - vmm-sys-util = "0.7.0" -+byteorder = "1.3.4" -diff --git a/util/src/fdt.rs b/util/src/fdt.rs -new file mode 100644 -index 0000000..2fdab44 ---- /dev/null -+++ b/util/src/fdt.rs -@@ -0,0 +1,300 @@ -+// Copyright (c) 2020 Huawei Technologies Co.,Ltd. All rights reserved. -+// -+// StratoVirt is licensed under Mulan PSL v2. -+// You can use this software according to the terms and conditions of the Mulan -+// PSL v2. -+// You may obtain a copy of Mulan PSL v2 at: -+// http://license.coscl.org.cn/MulanPSL2 -+// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -+// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -+// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -+// See the Mulan PSL v2 for more details. -+ -+use std::mem::size_of; -+ -+use crate::errors::{ErrorKind, Result, ResultExt}; -+use byteorder::{BigEndian, ByteOrder}; -+ -+pub const CLK_PHANDLE: u32 = 1; -+pub const GIC_PHANDLE: u32 = 2; -+pub const GIC_ITS_PHANDLE: u32 = 3; -+pub const CPU_PHANDLE_START: u32 = 10; -+ -+pub const GIC_FDT_IRQ_TYPE_SPI: u32 = 0; -+pub const GIC_FDT_IRQ_TYPE_PPI: u32 = 1; -+pub const IRQ_TYPE_EDGE_RISING: u32 = 1; -+pub const IRQ_TYPE_LEVEL_HIGH: u32 = 4; -+ -+pub const FDT_MAX_SIZE: u32 = 0x1_0000; -+ -+// Magic number in fdt header(big-endian). -+const FDT_MAGIC: u32 = 0xd00dfeed; -+// Fdt Header default information. -+const FDT_HEADER_SIZE: usize = 40; -+const FDT_VERSION: u32 = 17; -+const FDT_LAST_COMP_VERSION: u32 = 16; -+// Beginning token type of structure block. -+const FDT_BEGIN_NODE: u32 = 0x00000001; -+const FDT_END_NODE: u32 = 0x00000002; -+const FDT_PROP: u32 = 0x00000003; -+const FDT_END: u32 = 0x00000009; -+// Memory reservation block alignment. -+const MEM_RESERVE_ALIGNMENT: usize = 8; -+// Structure block alignment. -+const STRUCTURE_BLOCK_ALIGNMENT: usize = 4; -+ -+/// FdtBuilder structure. -+pub struct FdtBuilder { -+ /// The header of flattened device tree. -+ fdt_header: Vec, -+ /// The memory reservation block of flattened device tree. -+ /// It provides the client program with a list of areas -+ /// in physical memory which are reserved. -+ mem_reserve: Vec, -+ /// The structure block of flattened device tree. -+ /// It describes the structure and contents of the tree. -+ structure_blk: Vec, -+ /// The strings block of flattened device tree. -+ /// It contains strings representing all the property names used in the tree. -+ strings_blk: Vec, -+ /// The physical ID of the system’s boot CPU. -+ boot_cpuid_phys: u32, -+ /// The depth of nested node. -+ subnode_depth: u32, -+ /// Is there a open node or not. -+ begin_node: bool, -+} -+ -+/// FdtReserveEntry structure. -+#[derive(Clone, Debug)] -+pub struct FdtReserveEntry { -+ /// The address of reserved memory. -+ /// On 32-bit CPUs the upper 32-bits of the value are ignored. -+ address: u64, -+ /// The size of reserved memory. -+ size: u64, -+} -+ -+fn check_mem_reserve_overlap(mem_reservations: &[FdtReserveEntry]) -> bool { -+ if mem_reservations.len() <= 1 { -+ return true; -+ } -+ -+ let mut mem_reser = mem_reservations.to_vec(); -+ mem_reser.sort_by_key(|m| m.address); -+ -+ for i in 0..(mem_reser.len() - 1) { -+ if mem_reser[i].address + mem_reser[i].size > mem_reser[i + 1].address { -+ return false; -+ } -+ } -+ true -+} -+ -+// If there is null character in string, return false. -+fn check_string_legality(s: &str) -> bool { -+ !s.contains('\0') -+} -+ -+impl Default for FdtBuilder { -+ fn default() -> Self { -+ Self { -+ fdt_header: vec![0_u8; FDT_HEADER_SIZE], -+ mem_reserve: Vec::new(), -+ structure_blk: Vec::new(), -+ strings_blk: Vec::new(), -+ boot_cpuid_phys: 0, -+ subnode_depth: 0, -+ begin_node: false, -+ } -+ } -+} -+ -+impl FdtBuilder { -+ pub fn new() -> Self { -+ FdtBuilder::default() -+ } -+ -+ pub fn finish(mut self) -> Result> { -+ if self.subnode_depth > 0 { -+ return Err(ErrorKind::NodeUnclosed(self.subnode_depth).into()); -+ } -+ self.structure_blk -+ .extend_from_slice(&FDT_END.to_be_bytes()[..]); -+ -+ // According to the spec, mem_reserve blocks shall be ended -+ // with an entry where both address and size are equal to 0. -+ self.mem_reserve.extend_from_slice(&0_u64.to_be_bytes()); -+ self.mem_reserve.extend_from_slice(&0_u64.to_be_bytes()); -+ -+ // Fill fdt header. -+ let total_size = FDT_HEADER_SIZE -+ + self.mem_reserve.len() -+ + self.structure_blk.len() -+ + self.strings_blk.len(); -+ let off_dt_struct = FDT_HEADER_SIZE + self.mem_reserve.len(); -+ let off_dt_strings = FDT_HEADER_SIZE + self.mem_reserve.len() + self.structure_blk.len(); -+ let off_mem_rsvmap = FDT_HEADER_SIZE; -+ -+ BigEndian::write_u32(&mut self.fdt_header[0..4], FDT_MAGIC); -+ BigEndian::write_u32(&mut self.fdt_header[4..8], total_size as u32); -+ BigEndian::write_u32(&mut self.fdt_header[8..12], off_dt_struct as u32); -+ BigEndian::write_u32(&mut self.fdt_header[12..16], off_dt_strings as u32); -+ BigEndian::write_u32(&mut self.fdt_header[16..20], off_mem_rsvmap as u32); -+ BigEndian::write_u32(&mut self.fdt_header[20..24], FDT_VERSION); -+ BigEndian::write_u32(&mut self.fdt_header[24..28], FDT_LAST_COMP_VERSION); -+ BigEndian::write_u32(&mut self.fdt_header[28..32], self.boot_cpuid_phys); -+ BigEndian::write_u32(&mut self.fdt_header[32..36], self.strings_blk.len() as u32); -+ BigEndian::write_u32( -+ &mut self.fdt_header[36..40], -+ self.structure_blk.len() as u32, -+ ); -+ -+ self.fdt_header.extend_from_slice(&self.mem_reserve); -+ self.fdt_header.extend_from_slice(&self.structure_blk); -+ self.fdt_header.extend_from_slice(&self.strings_blk); -+ Ok(self.fdt_header) -+ } -+ -+ pub fn add_mem_reserve(&mut self, mem_reservations: &[FdtReserveEntry]) -> Result<()> { -+ if !check_mem_reserve_overlap(mem_reservations) { -+ return Err(ErrorKind::MemReserveOverlap.into()); -+ } -+ -+ for mem_reser in mem_reservations { -+ self.mem_reserve -+ .extend_from_slice(&mem_reser.address.to_be_bytes()); -+ self.mem_reserve -+ .extend_from_slice(&mem_reser.size.to_be_bytes()); -+ } -+ self.align_structure_blk(MEM_RESERVE_ALIGNMENT); -+ -+ Ok(()) -+ } -+ -+ pub fn begin_node(&mut self, node_name: &str) -> Result { -+ if !check_string_legality(node_name) { -+ return Err(ErrorKind::IllegalString(node_name.to_string()).into()); -+ } -+ -+ self.structure_blk -+ .extend_from_slice(&FDT_BEGIN_NODE.to_be_bytes()[..]); -+ if node_name.is_empty() { -+ self.structure_blk -+ .extend_from_slice(&0_u32.to_be_bytes()[..]); -+ } else { -+ let mut val_array = node_name.as_bytes().to_vec(); -+ // The node’s name string should end with null('\0'). -+ val_array.push(0x0_u8); -+ self.structure_blk.extend_from_slice(&val_array); -+ } -+ self.align_structure_blk(STRUCTURE_BLOCK_ALIGNMENT); -+ self.subnode_depth += 1; -+ self.begin_node = true; -+ Ok(self.subnode_depth) -+ } -+ -+ pub fn end_node(&mut self, begin_node_depth: u32) -> Result<()> { -+ if begin_node_depth != self.subnode_depth { -+ return Err(ErrorKind::NodeDepthMismatch(begin_node_depth, self.subnode_depth).into()); -+ } -+ -+ self.structure_blk -+ .extend_from_slice(&FDT_END_NODE.to_be_bytes()[..]); -+ self.subnode_depth -= 1; -+ self.begin_node = false; -+ Ok(()) -+ } -+ -+ pub fn set_boot_cpuid_phys(&mut self, boot_cpuid: u32) { -+ self.boot_cpuid_phys = boot_cpuid; -+ } -+ -+ pub fn set_property_string(&mut self, prop: &str, val: &str) -> Result<()> { -+ let mut val_array = val.as_bytes().to_vec(); -+ // The string property should end with null('\0'). -+ val_array.push(0x0_u8); -+ self.set_property(prop, &val_array) -+ .chain_err(|| ErrorKind::SetPropertyErr("string".to_string())) -+ } -+ -+ pub fn set_property_u32(&mut self, prop: &str, val: u32) -> Result<()> { -+ self.set_property(prop, &val.to_be_bytes()[..]) -+ .chain_err(|| ErrorKind::SetPropertyErr("u32".to_string())) -+ } -+ -+ pub fn set_property_u64(&mut self, prop: &str, val: u64) -> Result<()> { -+ self.set_property(prop, &val.to_be_bytes()[..]) -+ .chain_err(|| ErrorKind::SetPropertyErr("u64".to_string())) -+ } -+ -+ pub fn set_property_array_u32(&mut self, prop: &str, array: &[u32]) -> Result<()> { -+ let mut prop_array = Vec::with_capacity(array.len() * size_of::()); -+ for element in array { -+ prop_array.extend_from_slice(&element.to_be_bytes()[..]); -+ } -+ self.set_property(prop, &prop_array) -+ .chain_err(|| ErrorKind::SetPropertyErr("u32 array".to_string())) -+ } -+ -+ pub fn set_property_array_u64(&mut self, prop: &str, array: &[u64]) -> Result<()> { -+ let mut prop_array = Vec::with_capacity(array.len() * size_of::()); -+ for element in array { -+ prop_array.extend_from_slice(&element.to_be_bytes()[..]); -+ } -+ self.set_property(prop, &prop_array) -+ .chain_err(|| ErrorKind::SetPropertyErr("u64 array".to_string())) -+ } -+ -+ pub fn set_property(&mut self, property_name: &str, property_val: &[u8]) -> Result<()> { -+ if !check_string_legality(property_name) { -+ return Err(ErrorKind::IllegalString(property_name.to_string()).into()); -+ } -+ -+ if !self.begin_node { -+ return Err(ErrorKind::IllegelPropertyPos.into()); -+ } -+ -+ let len = property_val.len() as u32; -+ let nameoff = self.strings_blk.len() as u32; -+ self.structure_blk -+ .extend_from_slice(&FDT_PROP.to_be_bytes()[..]); -+ self.structure_blk.extend_from_slice(&len.to_be_bytes()[..]); -+ self.structure_blk -+ .extend_from_slice(&nameoff.to_be_bytes()[..]); -+ self.structure_blk.extend_from_slice(property_val); -+ self.align_structure_blk(STRUCTURE_BLOCK_ALIGNMENT); -+ -+ self.strings_blk.extend_from_slice(property_name.as_bytes()); -+ // These strings in strings block should end with null('\0'). -+ self.strings_blk.extend_from_slice("\0".as_bytes()); -+ -+ Ok(()) -+ } -+ -+ fn align_structure_blk(&mut self, alignment: usize) { -+ let remainder = self.structure_blk.len() % alignment; -+ if remainder != 0 { -+ self.structure_blk -+ .extend(vec![0_u8; (alignment - remainder) as usize]); -+ } -+ } -+} -+ -+/// Trait for devices to be added to the Flattened Device Tree. -+#[allow(clippy::upper_case_acronyms)] -+pub trait CompileFDT { -+ /// function to generate fdt node -+ /// -+ /// # Arguments -+ /// -+ /// * `fdt` - the FdtBuilder to be filled. -+ fn generate_fdt_node(&self, fdt: &mut FdtBuilder) -> Result<()>; -+} -+ -+pub fn dump_dtb(fdt: &[u8], file_path: &str) { -+ use std::fs::File; -+ use std::io::Write; -+ let mut f = File::create(file_path).unwrap(); -+ f.write_all(fdt).expect("Unable to write data"); -+} -diff --git a/util/src/lib.rs b/util/src/lib.rs -index a5feaef..d135c74 100644 ---- a/util/src/lib.rs -+++ b/util/src/lib.rs -@@ -28,6 +28,8 @@ pub mod checksum; - pub mod daemonize; - #[cfg(target_arch = "aarch64")] - pub mod device_tree; -+#[cfg(target_arch = "aarch64")] -+pub mod fdt; - pub mod leak_bucket; - mod link_list; - pub mod loop_context; -@@ -131,6 +133,30 @@ pub mod errors { - description("Index out of bound of array") - display("Index :{} out of bound :{}", index, bound) - } -+ NodeDepthMismatch(target_dep: u32, real_dep: u32) { -+ description("Fdt structure nested node depth mismatch") -+ display("Desired node depth :{}, current node depth :{}", target_dep, real_dep) -+ } -+ NodeUnclosed(unclose: u32) { -+ description("Fdt structure block node unclose") -+ display("Still have {} node open when terminating the fdt", unclose) -+ } -+ IllegelPropertyPos { -+ description("Cann't add property outside the node") -+ display("Failed to add property because there is no open node") -+ } -+ IllegalString(s: String) { -+ description("The string for fdt should not contain null") -+ display("Failed to add string to fdt because of null character inside \"{}\"", s) -+ } -+ MemReserveOverlap { -+ description("The mem reserve entry should not overlap") -+ display("Failed to add overlapped mem reserve entries to fdt") -+ } -+ SetPropertyErr(s: String) { -+ description("Cann't set property for fdt node") -+ display("Failed to set {} property", s) -+ } - } - } - } --- -2.31.1 - diff --git a/0012-devices-gicv3-use-mod-fdt-instead-of-device_tree.patch b/0012-devices-gicv3-use-mod-fdt-instead-of-device_tree.patch deleted file mode 100644 index dd1ae4ddb071028b9f11b4b63fb3223ddf60d419..0000000000000000000000000000000000000000 --- a/0012-devices-gicv3-use-mod-fdt-instead-of-device_tree.patch +++ /dev/null @@ -1,132 +0,0 @@ -From bc7aa4bcc37cfd5244697e81af7555fa781249bb Mon Sep 17 00:00:00 2001 -From: Jiajie Li -Date: Wed, 23 Jun 2021 15:06:21 +0800 -Subject: [PATCH 2/5] devices/gicv3: use mod fdt instead of device_tree - -Use fdt API provided by mod fdt, instead of mod device_tree -which is a wrapper around libfdt. - -Signed-off-by: Jiajie Li ---- - .../src/interrupt_controller/aarch64/gicv3.rs | 50 +++++++++---------- - .../src/interrupt_controller/aarch64/mod.rs | 11 ++-- - 2 files changed, 31 insertions(+), 30 deletions(-) - -diff --git a/devices/src/interrupt_controller/aarch64/gicv3.rs b/devices/src/interrupt_controller/aarch64/gicv3.rs -index 235bf37..a39a3d5 100644 ---- a/devices/src/interrupt_controller/aarch64/gicv3.rs -+++ b/devices/src/interrupt_controller/aarch64/gicv3.rs -@@ -14,7 +14,7 @@ use std::sync::{Arc, Mutex}; - - use kvm_ioctls::{DeviceFd, VmFd}; - use machine_manager::machine::{KvmVmState, MachineLifecycle}; --use util::device_tree; -+use util::fdt::{self, FdtBuilder}; - - use super::{GICConfig, GICDevice, UtilResult}; - use crate::errors::{ErrorKind, Result, ResultExt}; -@@ -379,7 +379,7 @@ impl GICDevice for GICv3 { - Ok(()) - } - -- fn generate_fdt(&self, fdt: &mut Vec) -> UtilResult<()> { -+ fn generate_fdt(&self, fdt: &mut FdtBuilder) -> UtilResult<()> { - let redist_count = self.redist_regions.len() as u32; - let mut gic_reg = vec![self.dist_base, self.dist_size]; - -@@ -388,34 +388,32 @@ impl GICDevice for GICv3 { - gic_reg.push(redist.size); - } - -- let node = "/intc"; -- device_tree::add_sub_node(fdt, node)?; -- device_tree::set_property_string(fdt, node, "compatible", "arm,gic-v3")?; -- device_tree::set_property(fdt, node, "interrupt-controller", None)?; -- device_tree::set_property_u32(fdt, node, "#interrupt-cells", 0x3)?; -- device_tree::set_property_u32(fdt, node, "phandle", device_tree::GIC_PHANDLE)?; -- device_tree::set_property_u32(fdt, node, "#address-cells", 0x2)?; -- device_tree::set_property_u32(fdt, node, "#size-cells", 0x2)?; -- device_tree::set_property_u32(fdt, node, "#redistributor-regions", redist_count)?; -- device_tree::set_property_array_u64(fdt, node, "reg", &gic_reg)?; -- -- let gic_intr = [ -- device_tree::GIC_FDT_IRQ_TYPE_PPI, -- 0x9, -- device_tree::IRQ_TYPE_LEVEL_HIGH, -- ]; -- device_tree::set_property_array_u32(fdt, node, "interrupts", &gic_intr)?; -+ let node = "intc"; -+ let intc_node_dep = fdt.begin_node(node)?; -+ fdt.set_property_string("compatible", "arm,gic-v3")?; -+ fdt.set_property("interrupt-controller", &Vec::new())?; -+ fdt.set_property_u32("#interrupt-cells", 0x3)?; -+ fdt.set_property_u32("phandle", fdt::GIC_PHANDLE)?; -+ fdt.set_property_u32("#address-cells", 0x2)?; -+ fdt.set_property_u32("#size-cells", 0x2)?; -+ fdt.set_property_u32("#redistributor-regions", redist_count)?; -+ fdt.set_property_array_u64("reg", &gic_reg)?; -+ -+ let gic_intr = [fdt::GIC_FDT_IRQ_TYPE_PPI, 0x9, fdt::IRQ_TYPE_LEVEL_HIGH]; -+ fdt.set_property_array_u32("interrupts", &gic_intr)?; - - if let Some(its) = &self.its_dev { -- device_tree::set_property(fdt, node, "ranges", None)?; -+ fdt.set_property("ranges", &Vec::new())?; - let its_reg = [its.msi_base, its.msi_size]; -- let node = "/intc/its"; -- device_tree::add_sub_node(fdt, node)?; -- device_tree::set_property_string(fdt, node, "compatible", "arm,gic-v3-its")?; -- device_tree::set_property(fdt, node, "msi-controller", None)?; -- device_tree::set_property_u32(fdt, node, "phandle", device_tree::GIC_ITS_PHANDLE)?; -- device_tree::set_property_array_u64(fdt, node, "reg", &its_reg)?; -+ let node = "its"; -+ let its_node_dep = fdt.begin_node(node)?; -+ fdt.set_property_string("compatible", "arm,gic-v3-its")?; -+ fdt.set_property("msi-controller", &Vec::new())?; -+ fdt.set_property_u32("phandle", fdt::GIC_ITS_PHANDLE)?; -+ fdt.set_property_array_u64("reg", &its_reg)?; -+ fdt.end_node(its_node_dep)?; - } -+ fdt.end_node(intc_node_dep)?; - - Ok(()) - } -diff --git a/devices/src/interrupt_controller/aarch64/mod.rs b/devices/src/interrupt_controller/aarch64/mod.rs -index d2a1b50..f1b40cf 100644 ---- a/devices/src/interrupt_controller/aarch64/mod.rs -+++ b/devices/src/interrupt_controller/aarch64/mod.rs -@@ -18,7 +18,10 @@ use std::sync::Arc; - - use kvm_ioctls::VmFd; - use machine_manager::machine::{KvmVmState, MachineLifecycle}; --use util::{device_tree, errors::Result as UtilResult}; -+use util::{ -+ errors::Result as UtilResult, -+ fdt::{self, FdtBuilder}, -+}; - - use crate::errors::{ErrorKind, Result, ResultExt}; - -@@ -88,7 +91,7 @@ pub trait GICDevice: MachineLifecycle { - /// # Arguments - /// - /// * `fdt` - Device tree presented by bytes. -- fn generate_fdt(&self, fdt: &mut Vec) -> UtilResult<()>; -+ fn generate_fdt(&self, fdt: &mut FdtBuilder) -> UtilResult<()>; - } - - /// A wrapper around creating and using a kvm-based interrupt controller. -@@ -121,8 +124,8 @@ impl InterruptController { - } - } - --impl device_tree::CompileFDT for InterruptController { -- fn generate_fdt_node(&self, fdt: &mut Vec) -> UtilResult<()> { -+impl fdt::CompileFDT for InterruptController { -+ fn generate_fdt_node(&self, fdt: &mut FdtBuilder) -> UtilResult<()> { - self.gic.generate_fdt(fdt)?; - Ok(()) - } --- -2.31.1 - diff --git a/0013-machine-micro_vm-use-fdt-API-of-mod-fdt-instead-of-d.patch b/0013-machine-micro_vm-use-fdt-API-of-mod-fdt-instead-of-d.patch deleted file mode 100644 index f482e6034a5d52b20ae8d34f3e41262f6406e412..0000000000000000000000000000000000000000 --- a/0013-machine-micro_vm-use-fdt-API-of-mod-fdt-instead-of-d.patch +++ /dev/null @@ -1,453 +0,0 @@ -From 999b6194eff54881f3ce4181f2355113fc72435b Mon Sep 17 00:00:00 2001 -From: Jiajie Li -Date: Wed, 23 Jun 2021 15:20:54 +0800 -Subject: [PATCH 3/5] machine/micro_vm: use fdt API of mod fdt instead of - device_tree - -Use fdt API provided by mod fdt, instead of mod device_tree -which is a wrapper around libfdt. - -Signed-off-by: Jiajie Li ---- - micro_vm/src/lib.rs | 291 ++++++++++++++++++++++---------------------- - 1 file changed, 143 insertions(+), 148 deletions(-) - -diff --git a/micro_vm/src/lib.rs b/micro_vm/src/lib.rs -index 7188f21..dd6cf97 100644 ---- a/micro_vm/src/lib.rs -+++ b/micro_vm/src/lib.rs -@@ -111,7 +111,7 @@ use sysbus::{SysBusDevType, SysRes}; - #[cfg(target_arch = "aarch64")] - use util::device_tree; - #[cfg(target_arch = "aarch64")] --use util::device_tree::CompileFDT; -+use util::fdt::{self, CompileFDT, FdtBuilder}; - use util::loop_context::{ - EventLoopManager, EventNotifier, EventNotifierHelper, NotifierCallback, NotifierOperation, - }; -@@ -628,12 +628,13 @@ impl LightMachine { - drop(boot_source); - #[cfg(target_arch = "aarch64")] - { -- let mut fdt = vec![0; device_tree::FDT_MAX_SIZE as usize]; -- vm.generate_fdt_node(&mut fdt)?; -+ let mut fdt_helper = FdtBuilder::new(); -+ vm.generate_fdt_node(&mut fdt_helper)?; -+ let fdt_vec = fdt_helper.finish()?; - vm.sys_mem.write( -- &mut fdt.as_slice(), -+ &mut fdt_vec.as_slice(), - GuestAddress(boot_config.fdt_addr as u64), -- fdt.len() as u64, -+ fdt_vec.len() as u64, - )?; - } - vm.register_power_event()?; -@@ -1477,23 +1478,23 @@ impl EventLoopManager for LightMachine { - // * `dev_info` - Device resource info of serial device. - // * `fdt` - Flatted device-tree blob where serial node will be filled into. - #[cfg(target_arch = "aarch64")] --fn generate_serial_device_node(fdt: &mut Vec, res: &SysRes) -> util::errors::Result<()> { -- let node = format!("/uart@{:x}", res.region_base); -- device_tree::add_sub_node(fdt, &node)?; -- device_tree::set_property_string(fdt, &node, "compatible", "ns16550a")?; -- device_tree::set_property_string(fdt, &node, "clock-names", "apb_pclk")?; -- device_tree::set_property_u32(fdt, &node, "clocks", device_tree::CLK_PHANDLE)?; -- device_tree::set_property_array_u64(fdt, &node, "reg", &[res.region_base, res.region_size])?; -- device_tree::set_property_array_u32( -- fdt, -- &node, -+fn generate_serial_device_node(fdt: &mut FdtBuilder, res: &SysRes) -> util::errors::Result<()> { -+ let node = format!("uart@{:x}", res.region_base); -+ let serial_node_dep = fdt.begin_node(&node)?; -+ fdt.set_property_string("compatible", "ns16550a")?; -+ fdt.set_property_string("clock-names", "apb_pclk")?; -+ fdt.set_property_u32("clocks", fdt::CLK_PHANDLE)?; -+ fdt.set_property_array_u64("reg", &[res.region_base, res.region_size])?; -+ fdt.set_property_array_u32( - "interrupts", - &[ -- device_tree::GIC_FDT_IRQ_TYPE_SPI, -+ fdt::GIC_FDT_IRQ_TYPE_SPI, - res.irq as u32, -- device_tree::IRQ_TYPE_EDGE_RISING, -+ fdt::IRQ_TYPE_EDGE_RISING, - ], - )?; -+ fdt.end_node(serial_node_dep)?; -+ - Ok(()) - } - -@@ -1504,23 +1505,23 @@ fn generate_serial_device_node(fdt: &mut Vec, res: &SysRes) -> util::errors: - // * `dev_info` - Device resource info of RTC device. - // * `fdt` - Flatted device-tree blob where RTC node will be filled into. - #[cfg(target_arch = "aarch64")] --fn generate_rtc_device_node(fdt: &mut Vec, res: &SysRes) -> util::errors::Result<()> { -- let node = format!("/pl031@{:x}", res.region_base); -- device_tree::add_sub_node(fdt, &node)?; -- device_tree::set_property_string(fdt, &node, "compatible", "arm,pl031\0arm,primecell\0")?; -- device_tree::set_property_string(fdt, &node, "clock-names", "apb_pclk")?; -- device_tree::set_property_u32(fdt, &node, "clocks", device_tree::CLK_PHANDLE)?; -- device_tree::set_property_array_u64(fdt, &node, "reg", &[res.region_base, res.region_size])?; -- device_tree::set_property_array_u32( -- fdt, -- &node, -+fn generate_rtc_device_node(fdt: &mut FdtBuilder, res: &SysRes) -> util::errors::Result<()> { -+ let node = format!("pl031@{:x}", res.region_base); -+ let rtc_node_dep = fdt.begin_node(&node)?; -+ fdt.set_property_string("compatible", "arm,pl031\0arm,primecell\0")?; -+ fdt.set_property_string("clock-names", "apb_pclk")?; -+ fdt.set_property_u32("clocks", fdt::CLK_PHANDLE)?; -+ fdt.set_property_array_u64("reg", &[res.region_base, res.region_size])?; -+ fdt.set_property_array_u32( - "interrupts", - &[ -- device_tree::GIC_FDT_IRQ_TYPE_SPI, -+ fdt::GIC_FDT_IRQ_TYPE_SPI, - res.irq as u32, -- device_tree::IRQ_TYPE_LEVEL_HIGH, -+ fdt::IRQ_TYPE_LEVEL_HIGH, - ], - )?; -+ fdt.end_node(rtc_node_dep)?; -+ - Ok(()) - } - -@@ -1531,22 +1532,21 @@ fn generate_rtc_device_node(fdt: &mut Vec, res: &SysRes) -> util::errors::Re - // * `dev_info` - Device resource info of Virtio-Mmio device. - // * `fdt` - Flatted device-tree blob where node will be filled into. - #[cfg(target_arch = "aarch64")] --fn generate_virtio_devices_node(fdt: &mut Vec, res: &SysRes) -> util::errors::Result<()> { -- let node = format!("/virtio_mmio@{:x}", res.region_base); -- device_tree::add_sub_node(fdt, &node)?; -- device_tree::set_property_string(fdt, &node, "compatible", "virtio,mmio")?; -- device_tree::set_property_u32(fdt, &node, "interrupt-parent", device_tree::GIC_PHANDLE)?; -- device_tree::set_property_array_u64(fdt, &node, "reg", &[res.region_base, res.region_size])?; -- device_tree::set_property_array_u32( -- fdt, -- &node, -+fn generate_virtio_devices_node(fdt: &mut FdtBuilder, res: &SysRes) -> util::errors::Result<()> { -+ let node = format!("virtio_mmio@{:x}", res.region_base); -+ let virtio_node_dep = fdt.begin_node(&node)?; -+ fdt.set_property_string("compatible", "virtio,mmio")?; -+ fdt.set_property_u32("interrupt-parent", fdt::GIC_PHANDLE)?; -+ fdt.set_property_array_u64("reg", &[res.region_base, res.region_size])?; -+ fdt.set_property_array_u32( - "interrupts", - &[ -- device_tree::GIC_FDT_IRQ_TYPE_SPI, -+ fdt::GIC_FDT_IRQ_TYPE_SPI, - res.irq as u32, -- device_tree::IRQ_TYPE_EDGE_RISING, -+ fdt::IRQ_TYPE_EDGE_RISING, - ], - )?; -+ fdt.end_node(virtio_node_dep)?; - Ok(()) - } - -@@ -1555,73 +1555,72 @@ fn generate_virtio_devices_node(fdt: &mut Vec, res: &SysRes) -> util::errors - #[cfg(target_arch = "aarch64")] - trait CompileFDTHelper { - /// Function that helps to generate cpu nodes. -- fn generate_cpu_nodes(&self, fdt: &mut Vec) -> util::errors::Result<()>; -+ fn generate_cpu_nodes(&self, fdt: &mut FdtBuilder) -> util::errors::Result<()>; - /// Function that helps to generate memory nodes. -- fn generate_memory_node(&self, fdt: &mut Vec) -> util::errors::Result<()>; -+ fn generate_memory_node(&self, fdt: &mut FdtBuilder) -> util::errors::Result<()>; - /// Function that helps to generate Virtio-mmio devices' nodes. -- fn generate_devices_node(&self, fdt: &mut Vec) -> util::errors::Result<()>; -+ fn generate_devices_node(&self, fdt: &mut FdtBuilder) -> util::errors::Result<()>; - /// Function that helps to generate the chosen node. -- fn generate_chosen_node(&self, fdt: &mut Vec) -> util::errors::Result<()>; -+ fn generate_chosen_node(&self, fdt: &mut FdtBuilder) -> util::errors::Result<()>; - } - - #[cfg(target_arch = "aarch64")] - impl CompileFDTHelper for LightMachine { -- fn generate_cpu_nodes(&self, fdt: &mut Vec) -> util::errors::Result<()> { -- let node = "/cpus"; -+ fn generate_cpu_nodes(&self, fdt: &mut FdtBuilder) -> util::errors::Result<()> { -+ let node = "cpus"; - -- device_tree::add_sub_node(fdt, node)?; -- device_tree::set_property_u32(fdt, node, "#address-cells", 0x02)?; -- device_tree::set_property_u32(fdt, node, "#size-cells", 0x0)?; -+ let cpus_node_dep = fdt.begin_node(node)?; -+ fdt.set_property_u32("#address-cells", 0x02)?; -+ fdt.set_property_u32("#size-cells", 0x0)?; - - // Generate CPU topology - if self.cpu_topo.max_cpus > 0 && self.cpu_topo.max_cpus % 8 == 0 { -- device_tree::add_sub_node(fdt, "/cpus/cpu-map")?; -+ let cpu_map_node_dep = fdt.begin_node("cpu-map")?; - - let sockets = self.cpu_topo.max_cpus / 8; - for cluster in 0..u32::from(sockets) { -- let clster = format!("/cpus/cpu-map/cluster{}", cluster); -- device_tree::add_sub_node(fdt, &clster)?; -+ let clster = format!("cluster{}", cluster); -+ let cluster_node_dep = fdt.begin_node(&clster)?; - - for i in 0..2_u32 { -- let sub_cluster = format!("{}/cluster{}", clster, i); -- device_tree::add_sub_node(fdt, &sub_cluster)?; -- -- let core0 = format!("{}/core0", sub_cluster); -- device_tree::add_sub_node(fdt, &core0)?; -- let thread0 = format!("{}/thread0", core0); -- device_tree::add_sub_node(fdt, &thread0)?; -- device_tree::set_property_u32(fdt, &thread0, "cpu", cluster * 8 + i * 4 + 10)?; -- -- let thread1 = format!("{}/thread1", core0); -- device_tree::add_sub_node(fdt, &thread1)?; -- device_tree::set_property_u32( -- fdt, -- &thread1, -- "cpu", -- cluster * 8 + i * 4 + 10 + 1, -- )?; -- -- let core1 = format!("{}/core1", sub_cluster); -- device_tree::add_sub_node(fdt, &core1)?; -- let thread0 = format!("{}/thread0", core1); -- device_tree::add_sub_node(fdt, &thread0)?; -- device_tree::set_property_u32( -- fdt, -- &thread0, -- "cpu", -- cluster * 8 + i * 4 + 10 + 2, -- )?; -- -- let thread1 = format!("{}/thread1", core1); -- device_tree::add_sub_node(fdt, &thread1)?; -- device_tree::set_property_u32( -- fdt, -- &thread1, -- "cpu", -- cluster * 8 + i * 4 + 10 + 3, -- )?; -+ let sub_cluster = format!("cluster{}", i); -+ let sub_cluster_node_dep = fdt.begin_node(&sub_cluster)?; -+ -+ let core0 = "core0".to_string(); -+ let core0_node_dep = fdt.begin_node(&core0)?; -+ -+ let thread0 = "thread0".to_string(); -+ let thread0_node_dep = fdt.begin_node(&thread0)?; -+ fdt.set_property_u32("cpu", cluster * 8 + i * 4 + 10)?; -+ fdt.end_node(thread0_node_dep)?; -+ -+ let thread1 = "thread1".to_string(); -+ let thread1_node_dep = fdt.begin_node(&thread1)?; -+ fdt.set_property_u32("cpu", cluster * 8 + i * 4 + 10 + 1)?; -+ fdt.end_node(thread1_node_dep)?; -+ -+ fdt.end_node(core0_node_dep)?; -+ -+ let core1 = "core1".to_string(); -+ let core1_node_dep = fdt.begin_node(&core1)?; -+ -+ let thread0 = "thread0".to_string(); -+ let thread0_node_dep = fdt.begin_node(&thread0)?; -+ fdt.set_property_u32("cpu", cluster * 8 + i * 4 + 10 + 2)?; -+ fdt.end_node(thread0_node_dep)?; -+ -+ let thread1 = "thread1".to_string(); -+ let thread1_node_dep = fdt.begin_node(&thread1)?; -+ fdt.set_property_u32("cpu", cluster * 8 + i * 4 + 10 + 3)?; -+ fdt.end_node(thread1_node_dep)?; -+ -+ fdt.end_node(core1_node_dep)?; -+ -+ fdt.end_node(sub_cluster_node_dep)?; - } -+ fdt.end_node(cluster_node_dep)?; - } -+ fdt.end_node(cpu_map_node_dep)?; - } - - let cpu_list = self.cpus.lock().unwrap(); -@@ -1632,68 +1631,69 @@ impl CompileFDTHelper for LightMachine { - .unwrap() - .get_mpidr(cpu_list[cpu_index as usize].fd()); - -- let node = format!("/cpus/cpu@{:x}", mpidr); -- device_tree::add_sub_node(fdt, &node)?; -- device_tree::set_property_u32( -- fdt, -- &node, -- "phandle", -- u32::from(cpu_index) + device_tree::CPU_PHANDLE_START, -- )?; -- device_tree::set_property_string(fdt, &node, "device_type", "cpu")?; -- device_tree::set_property_string(fdt, &node, "compatible", "arm,arm-v8")?; -+ let node = format!("cpu@{:x}", mpidr); -+ let mpidr_node_dep = fdt.begin_node(&node)?; -+ fdt.set_property_u32("phandle", u32::from(cpu_index) + fdt::CPU_PHANDLE_START)?; -+ fdt.set_property_string("device_type", "cpu")?; -+ fdt.set_property_string("compatible", "arm,arm-v8")?; - if self.cpu_topo.max_cpus > 1 { -- device_tree::set_property_string(fdt, &node, "enable-method", "psci")?; -+ fdt.set_property_string("enable-method", "psci")?; - } -- device_tree::set_property_u64(fdt, &node, "reg", mpidr & 0x007F_FFFF)?; -+ fdt.set_property_u64("reg", mpidr & 0x007F_FFFF)?; -+ fdt.end_node(mpidr_node_dep)?; - } - -+ fdt.end_node(cpus_node_dep)?; -+ - Ok(()) - } - -- fn generate_memory_node(&self, fdt: &mut Vec) -> util::errors::Result<()> { -+ fn generate_memory_node(&self, fdt: &mut FdtBuilder) -> util::errors::Result<()> { - let mem_base = MEM_LAYOUT[LayoutEntryType::Mem as usize].0; - let mem_size = self.sys_mem.memory_end_address().raw_value() - - MEM_LAYOUT[LayoutEntryType::Mem as usize].0; -- let node = "/memory"; -- device_tree::add_sub_node(fdt, node)?; -- device_tree::set_property_string(fdt, node, "device_type", "memory")?; -- device_tree::set_property_array_u64(fdt, node, "reg", &[mem_base, mem_size as u64])?; -+ let node = "memory"; -+ let memory_node_dep = fdt.begin_node(node)?; -+ fdt.set_property_string("device_type", "memory")?; -+ fdt.set_property_array_u64("reg", &[mem_base, mem_size as u64])?; -+ fdt.end_node(memory_node_dep)?; - - Ok(()) - } - -- fn generate_devices_node(&self, fdt: &mut Vec) -> util::errors::Result<()> { -+ fn generate_devices_node(&self, fdt: &mut FdtBuilder) -> util::errors::Result<()> { - // timer - let mut cells: Vec = Vec::new(); - for &irq in [13, 14, 11, 10].iter() { -- cells.push(device_tree::GIC_FDT_IRQ_TYPE_PPI); -+ cells.push(fdt::GIC_FDT_IRQ_TYPE_PPI); - cells.push(irq); -- cells.push(device_tree::IRQ_TYPE_LEVEL_HIGH); -+ cells.push(fdt::IRQ_TYPE_LEVEL_HIGH); - } -- let node = "/timer"; -- device_tree::add_sub_node(fdt, node)?; -- device_tree::set_property_string(fdt, node, "compatible", "arm,armv8-timer")?; -- device_tree::set_property(fdt, node, "always-on", None)?; -- device_tree::set_property_array_u32(fdt, node, "interrupts", &cells)?; -+ let node = "timer"; -+ let timer_node_dep = fdt.begin_node(node)?; -+ fdt.set_property_string("compatible", "arm,armv8-timer")?; -+ fdt.set_property("always-on", &Vec::new())?; -+ fdt.set_property_array_u32("interrupts", &cells)?; -+ fdt.end_node(timer_node_dep)?; - - // clock -- let node = "/apb-pclk"; -- device_tree::add_sub_node(fdt, node)?; -- device_tree::set_property_string(fdt, node, "compatible", "fixed-clock")?; -- device_tree::set_property_string(fdt, node, "clock-output-names", "clk24mhz")?; -- device_tree::set_property_u32(fdt, node, "#clock-cells", 0x0)?; -- device_tree::set_property_u32(fdt, node, "clock-frequency", 24_000_000)?; -- device_tree::set_property_u32(fdt, node, "phandle", device_tree::CLK_PHANDLE)?; -+ let node = "apb-pclk"; -+ let clock_node_dep = fdt.begin_node(node)?; -+ fdt.set_property_string("compatible", "fixed-clock")?; -+ fdt.set_property_string("clock-output-names", "clk24mhz")?; -+ fdt.set_property_u32("#clock-cells", 0x0)?; -+ fdt.set_property_u32("clock-frequency", 24_000_000)?; -+ fdt.set_property_u32("phandle", fdt::CLK_PHANDLE)?; -+ fdt.end_node(clock_node_dep)?; - - // psci -- let node = "/psci"; -- device_tree::add_sub_node(fdt, node)?; -- device_tree::set_property_string(fdt, node, "compatible", "arm,psci-0.2")?; -- device_tree::set_property_string(fdt, node, "method", "hvc")?; -+ let node = "psci"; -+ let psci_node_dep = fdt.begin_node(node)?; -+ fdt.set_property_string("compatible", "arm,psci-0.2")?; -+ fdt.set_property_string("method", "hvc")?; -+ fdt.end_node(psci_node_dep)?; - -- // Reversing vector is needed because FDT node is added in reverse. -- for dev in self.sysbus.devices.iter().rev() { -+ for dev in self.sysbus.devices.iter() { - let mut locked_dev = dev.lock().unwrap(); - let dev_type = locked_dev.get_type(); - let sys_res = locked_dev.get_sys_resource(); -@@ -1707,46 +1707,39 @@ impl CompileFDTHelper for LightMachine { - Ok(()) - } - -- fn generate_chosen_node(&self, fdt: &mut Vec) -> util::errors::Result<()> { -- let node = "/chosen"; -- -+ fn generate_chosen_node(&self, fdt: &mut FdtBuilder) -> util::errors::Result<()> { -+ let node = "chosen"; - let boot_source = self.boot_source.lock().unwrap(); - -- device_tree::add_sub_node(fdt, node)?; -+ let chosen_node_dep = fdt.begin_node(node)?; - let cmdline = &boot_source.kernel_cmdline.to_string(); -- device_tree::set_property_string(fdt, node, "bootargs", cmdline.as_str())?; -+ fdt.set_property_string("bootargs", cmdline.as_str())?; - - match &boot_source.initrd { - Some(initrd) => { -- device_tree::set_property_u64( -- fdt, -- node, -- "linux,initrd-start", -- *initrd.initrd_addr.lock().unwrap(), -- )?; -- device_tree::set_property_u64( -- fdt, -- node, -+ fdt.set_property_u64("linux,initrd-start", *initrd.initrd_addr.lock().unwrap())?; -+ fdt.set_property_u64( - "linux,initrd-end", - *initrd.initrd_addr.lock().unwrap() + initrd.initrd_size, - )?; - } - None => {} - } -+ fdt.end_node(chosen_node_dep)?; - - Ok(()) - } - } - - #[cfg(target_arch = "aarch64")] --impl device_tree::CompileFDT for LightMachine { -- fn generate_fdt_node(&self, fdt: &mut Vec) -> util::errors::Result<()> { -- device_tree::create_device_tree(fdt)?; -+impl fdt::CompileFDT for LightMachine { -+ fn generate_fdt_node(&self, fdt: &mut FdtBuilder) -> util::errors::Result<()> { -+ let node_dep = fdt.begin_node("")?; - -- device_tree::set_property_string(fdt, "/", "compatible", "linux,dummy-virt")?; -- device_tree::set_property_u32(fdt, "/", "#address-cells", 0x2)?; -- device_tree::set_property_u32(fdt, "/", "#size-cells", 0x2)?; -- device_tree::set_property_u32(fdt, "/", "interrupt-parent", device_tree::GIC_PHANDLE)?; -+ fdt.set_property_string("compatible", "linux,dummy-virt")?; -+ fdt.set_property_u32("#address-cells", 0x2)?; -+ fdt.set_property_u32("#size-cells", 0x2)?; -+ fdt.set_property_u32("interrupt-parent", fdt::GIC_PHANDLE)?; - - self.generate_cpu_nodes(fdt)?; - self.generate_memory_node(fdt)?; -@@ -1754,6 +1747,8 @@ impl device_tree::CompileFDT for LightMachine { - self.generate_chosen_node(fdt)?; - self.irq_chip.as_ref().unwrap().generate_fdt_node(fdt)?; - -+ fdt.end_node(node_dep)?; -+ - Ok(()) - } - } --- -2.31.1 - diff --git a/0014-Replace-mod-device_tree-with-mod-fdt.patch b/0014-Replace-mod-device_tree-with-mod-fdt.patch deleted file mode 100644 index 8e54f4dc06c96274dc67356728273e08d1ce7de1..0000000000000000000000000000000000000000 --- a/0014-Replace-mod-device_tree-with-mod-fdt.patch +++ /dev/null @@ -1,1001 +0,0 @@ -From e1d0d0ef1d7de4454653a907e7f27e0c7f0185db Mon Sep 17 00:00:00 2001 -From: Jiajie Li -Date: Wed, 23 Jun 2021 15:24:37 +0800 -Subject: [PATCH 4/5] Replace mod device_tree with mod fdt - -Delete mod device_tree and replace the dependency -on the mod device_tree with mod fdt. What's more, -remove the compile parameter "link-arg=-lfdt" in -config to get rid of libfdt. - -Signed-off-by: Jiajie Li ---- - .cargo/config | 1 - - .../src/interrupt_controller/aarch64/gicv3.rs | 12 +- - .../src/interrupt_controller/aarch64/mod.rs | 4 +- - machine_manager/src/config/mod.rs | 4 +- - micro_vm/src/lib.rs | 37 +- - util/src/device_tree.rs | 386 +++++++++++------- - util/src/fdt.rs | 300 -------------- - util/src/lib.rs | 2 - - 8 files changed, 264 insertions(+), 482 deletions(-) - delete mode 100644 util/src/fdt.rs - -diff --git a/.cargo/config b/.cargo/config -index 0b1372f..2105adb 100644 ---- a/.cargo/config -+++ b/.cargo/config -@@ -15,5 +15,4 @@ - [target.'cfg(any(target_arch="aarch64"))'] - rustflags = [ - "-C", "link-arg=-lgcc", -- "-C", "link-arg=-lfdt", - ] -diff --git a/devices/src/interrupt_controller/aarch64/gicv3.rs b/devices/src/interrupt_controller/aarch64/gicv3.rs -index a39a3d5..08f2fd5 100644 ---- a/devices/src/interrupt_controller/aarch64/gicv3.rs -+++ b/devices/src/interrupt_controller/aarch64/gicv3.rs -@@ -14,7 +14,7 @@ use std::sync::{Arc, Mutex}; - - use kvm_ioctls::{DeviceFd, VmFd}; - use machine_manager::machine::{KvmVmState, MachineLifecycle}; --use util::fdt::{self, FdtBuilder}; -+use util::device_tree::{self, FdtBuilder}; - - use super::{GICConfig, GICDevice, UtilResult}; - use crate::errors::{ErrorKind, Result, ResultExt}; -@@ -393,13 +393,17 @@ impl GICDevice for GICv3 { - fdt.set_property_string("compatible", "arm,gic-v3")?; - fdt.set_property("interrupt-controller", &Vec::new())?; - fdt.set_property_u32("#interrupt-cells", 0x3)?; -- fdt.set_property_u32("phandle", fdt::GIC_PHANDLE)?; -+ fdt.set_property_u32("phandle", device_tree::GIC_PHANDLE)?; - fdt.set_property_u32("#address-cells", 0x2)?; - fdt.set_property_u32("#size-cells", 0x2)?; - fdt.set_property_u32("#redistributor-regions", redist_count)?; - fdt.set_property_array_u64("reg", &gic_reg)?; - -- let gic_intr = [fdt::GIC_FDT_IRQ_TYPE_PPI, 0x9, fdt::IRQ_TYPE_LEVEL_HIGH]; -+ let gic_intr = [ -+ device_tree::GIC_FDT_IRQ_TYPE_PPI, -+ 0x9, -+ device_tree::IRQ_TYPE_LEVEL_HIGH, -+ ]; - fdt.set_property_array_u32("interrupts", &gic_intr)?; - - if let Some(its) = &self.its_dev { -@@ -409,7 +413,7 @@ impl GICDevice for GICv3 { - let its_node_dep = fdt.begin_node(node)?; - fdt.set_property_string("compatible", "arm,gic-v3-its")?; - fdt.set_property("msi-controller", &Vec::new())?; -- fdt.set_property_u32("phandle", fdt::GIC_ITS_PHANDLE)?; -+ fdt.set_property_u32("phandle", device_tree::GIC_ITS_PHANDLE)?; - fdt.set_property_array_u64("reg", &its_reg)?; - fdt.end_node(its_node_dep)?; - } -diff --git a/devices/src/interrupt_controller/aarch64/mod.rs b/devices/src/interrupt_controller/aarch64/mod.rs -index f1b40cf..ba44eb5 100644 ---- a/devices/src/interrupt_controller/aarch64/mod.rs -+++ b/devices/src/interrupt_controller/aarch64/mod.rs -@@ -19,8 +19,8 @@ use std::sync::Arc; - use kvm_ioctls::VmFd; - use machine_manager::machine::{KvmVmState, MachineLifecycle}; - use util::{ -+ device_tree::{self, FdtBuilder}, - errors::Result as UtilResult, -- fdt::{self, FdtBuilder}, - }; - - use crate::errors::{ErrorKind, Result, ResultExt}; -@@ -124,7 +124,7 @@ impl InterruptController { - } - } - --impl fdt::CompileFDT for InterruptController { -+impl device_tree::CompileFDT for InterruptController { - fn generate_fdt_node(&self, fdt: &mut FdtBuilder) -> UtilResult<()> { - self.gic.generate_fdt(fdt)?; - Ok(()) -diff --git a/machine_manager/src/config/mod.rs b/machine_manager/src/config/mod.rs -index 0922943..b83b9b4 100644 ---- a/machine_manager/src/config/mod.rs -+++ b/machine_manager/src/config/mod.rs -@@ -29,7 +29,7 @@ use std::str::FromStr; - use serde::{Deserialize, Serialize}; - - #[cfg(target_arch = "aarch64")] --use util::device_tree; -+use util::device_tree::{self, FdtBuilder}; - - pub use self::errors::{ErrorKind, Result}; - pub use balloon::*; -@@ -238,7 +238,7 @@ impl VmConfig { - - #[cfg(target_arch = "aarch64")] - impl device_tree::CompileFDT for VmConfig { -- fn generate_fdt_node(&self, _fdt: &mut Vec) -> util::errors::Result<()> { -+ fn generate_fdt_node(&self, _fdt: &mut FdtBuilder) -> util::errors::Result<()> { - Ok(()) - } - } -diff --git a/micro_vm/src/lib.rs b/micro_vm/src/lib.rs -index dd6cf97..5cf7226 100644 ---- a/micro_vm/src/lib.rs -+++ b/micro_vm/src/lib.rs -@@ -109,9 +109,7 @@ use sysbus::SysBus; - #[cfg(target_arch = "aarch64")] - use sysbus::{SysBusDevType, SysRes}; - #[cfg(target_arch = "aarch64")] --use util::device_tree; --#[cfg(target_arch = "aarch64")] --use util::fdt::{self, CompileFDT, FdtBuilder}; -+use util::device_tree::{self, CompileFDT, FdtBuilder}; - use util::loop_context::{ - EventLoopManager, EventNotifier, EventNotifierHelper, NotifierCallback, NotifierOperation, - }; -@@ -1483,14 +1481,14 @@ fn generate_serial_device_node(fdt: &mut FdtBuilder, res: &SysRes) -> util::erro - let serial_node_dep = fdt.begin_node(&node)?; - fdt.set_property_string("compatible", "ns16550a")?; - fdt.set_property_string("clock-names", "apb_pclk")?; -- fdt.set_property_u32("clocks", fdt::CLK_PHANDLE)?; -+ fdt.set_property_u32("clocks", device_tree::CLK_PHANDLE)?; - fdt.set_property_array_u64("reg", &[res.region_base, res.region_size])?; - fdt.set_property_array_u32( - "interrupts", - &[ -- fdt::GIC_FDT_IRQ_TYPE_SPI, -+ device_tree::GIC_FDT_IRQ_TYPE_SPI, - res.irq as u32, -- fdt::IRQ_TYPE_EDGE_RISING, -+ device_tree::IRQ_TYPE_EDGE_RISING, - ], - )?; - fdt.end_node(serial_node_dep)?; -@@ -1510,14 +1508,14 @@ fn generate_rtc_device_node(fdt: &mut FdtBuilder, res: &SysRes) -> util::errors: - let rtc_node_dep = fdt.begin_node(&node)?; - fdt.set_property_string("compatible", "arm,pl031\0arm,primecell\0")?; - fdt.set_property_string("clock-names", "apb_pclk")?; -- fdt.set_property_u32("clocks", fdt::CLK_PHANDLE)?; -+ fdt.set_property_u32("clocks", device_tree::CLK_PHANDLE)?; - fdt.set_property_array_u64("reg", &[res.region_base, res.region_size])?; - fdt.set_property_array_u32( - "interrupts", - &[ -- fdt::GIC_FDT_IRQ_TYPE_SPI, -+ device_tree::GIC_FDT_IRQ_TYPE_SPI, - res.irq as u32, -- fdt::IRQ_TYPE_LEVEL_HIGH, -+ device_tree::IRQ_TYPE_LEVEL_HIGH, - ], - )?; - fdt.end_node(rtc_node_dep)?; -@@ -1536,14 +1534,14 @@ fn generate_virtio_devices_node(fdt: &mut FdtBuilder, res: &SysRes) -> util::err - let node = format!("virtio_mmio@{:x}", res.region_base); - let virtio_node_dep = fdt.begin_node(&node)?; - fdt.set_property_string("compatible", "virtio,mmio")?; -- fdt.set_property_u32("interrupt-parent", fdt::GIC_PHANDLE)?; -+ fdt.set_property_u32("interrupt-parent", device_tree::GIC_PHANDLE)?; - fdt.set_property_array_u64("reg", &[res.region_base, res.region_size])?; - fdt.set_property_array_u32( - "interrupts", - &[ -- fdt::GIC_FDT_IRQ_TYPE_SPI, -+ device_tree::GIC_FDT_IRQ_TYPE_SPI, - res.irq as u32, -- fdt::IRQ_TYPE_EDGE_RISING, -+ device_tree::IRQ_TYPE_EDGE_RISING, - ], - )?; - fdt.end_node(virtio_node_dep)?; -@@ -1633,7 +1631,10 @@ impl CompileFDTHelper for LightMachine { - - let node = format!("cpu@{:x}", mpidr); - let mpidr_node_dep = fdt.begin_node(&node)?; -- fdt.set_property_u32("phandle", u32::from(cpu_index) + fdt::CPU_PHANDLE_START)?; -+ fdt.set_property_u32( -+ "phandle", -+ u32::from(cpu_index) + device_tree::CPU_PHANDLE_START, -+ )?; - fdt.set_property_string("device_type", "cpu")?; - fdt.set_property_string("compatible", "arm,arm-v8")?; - if self.cpu_topo.max_cpus > 1 { -@@ -1665,9 +1666,9 @@ impl CompileFDTHelper for LightMachine { - // timer - let mut cells: Vec = Vec::new(); - for &irq in [13, 14, 11, 10].iter() { -- cells.push(fdt::GIC_FDT_IRQ_TYPE_PPI); -+ cells.push(device_tree::GIC_FDT_IRQ_TYPE_PPI); - cells.push(irq); -- cells.push(fdt::IRQ_TYPE_LEVEL_HIGH); -+ cells.push(device_tree::IRQ_TYPE_LEVEL_HIGH); - } - let node = "timer"; - let timer_node_dep = fdt.begin_node(node)?; -@@ -1683,7 +1684,7 @@ impl CompileFDTHelper for LightMachine { - fdt.set_property_string("clock-output-names", "clk24mhz")?; - fdt.set_property_u32("#clock-cells", 0x0)?; - fdt.set_property_u32("clock-frequency", 24_000_000)?; -- fdt.set_property_u32("phandle", fdt::CLK_PHANDLE)?; -+ fdt.set_property_u32("phandle", device_tree::CLK_PHANDLE)?; - fdt.end_node(clock_node_dep)?; - - // psci -@@ -1732,14 +1733,14 @@ impl CompileFDTHelper for LightMachine { - } - - #[cfg(target_arch = "aarch64")] --impl fdt::CompileFDT for LightMachine { -+impl device_tree::CompileFDT for LightMachine { - fn generate_fdt_node(&self, fdt: &mut FdtBuilder) -> util::errors::Result<()> { - let node_dep = fdt.begin_node("")?; - - fdt.set_property_string("compatible", "linux,dummy-virt")?; - fdt.set_property_u32("#address-cells", 0x2)?; - fdt.set_property_u32("#size-cells", 0x2)?; -- fdt.set_property_u32("interrupt-parent", fdt::GIC_PHANDLE)?; -+ fdt.set_property_u32("interrupt-parent", device_tree::GIC_PHANDLE)?; - - self.generate_cpu_nodes(fdt)?; - self.generate_memory_node(fdt)?; -diff --git a/util/src/device_tree.rs b/util/src/device_tree.rs -index 120fd7c..2fdab44 100644 ---- a/util/src/device_tree.rs -+++ b/util/src/device_tree.rs -@@ -10,9 +10,10 @@ - // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - // See the Mulan PSL v2 for more details. - --use super::errors::Result; --use libc::{c_char, c_int, c_void}; --use std::ffi::CString; -+use std::mem::size_of; -+ -+use crate::errors::{ErrorKind, Result, ResultExt}; -+use byteorder::{BigEndian, ByteOrder}; - - pub const CLK_PHANDLE: u32 = 1; - pub const GIC_PHANDLE: u32 = 2; -@@ -26,185 +27,257 @@ pub const IRQ_TYPE_LEVEL_HIGH: u32 = 4; - - pub const FDT_MAX_SIZE: u32 = 0x1_0000; - --extern "C" { -- fn fdt_create(buf: *mut c_void, bufsize: c_int) -> c_int; -- fn fdt_finish_reservemap(fdt: *mut c_void) -> c_int; -- fn fdt_begin_node(fdt: *mut c_void, name: *const c_char) -> c_int; -- fn fdt_end_node(fdt: *mut c_void) -> c_int; -- fn fdt_finish(fdt: *const c_void) -> c_int; -- fn fdt_open_into(fdt: *const c_void, buf: *mut c_void, size: c_int) -> c_int; -- -- fn fdt_path_offset(fdt: *const c_void, path: *const c_char) -> c_int; -- fn fdt_add_subnode(fdt: *mut c_void, offset: c_int, name: *const c_char) -> c_int; -- fn fdt_setprop( -- fdt: *mut c_void, -- offset: c_int, -- name: *const c_char, -- val: *const c_void, -- len: c_int, -- ) -> c_int; -+// Magic number in fdt header(big-endian). -+const FDT_MAGIC: u32 = 0xd00dfeed; -+// Fdt Header default information. -+const FDT_HEADER_SIZE: usize = 40; -+const FDT_VERSION: u32 = 17; -+const FDT_LAST_COMP_VERSION: u32 = 16; -+// Beginning token type of structure block. -+const FDT_BEGIN_NODE: u32 = 0x00000001; -+const FDT_END_NODE: u32 = 0x00000002; -+const FDT_PROP: u32 = 0x00000003; -+const FDT_END: u32 = 0x00000009; -+// Memory reservation block alignment. -+const MEM_RESERVE_ALIGNMENT: usize = 8; -+// Structure block alignment. -+const STRUCTURE_BLOCK_ALIGNMENT: usize = 4; -+ -+/// FdtBuilder structure. -+pub struct FdtBuilder { -+ /// The header of flattened device tree. -+ fdt_header: Vec, -+ /// The memory reservation block of flattened device tree. -+ /// It provides the client program with a list of areas -+ /// in physical memory which are reserved. -+ mem_reserve: Vec, -+ /// The structure block of flattened device tree. -+ /// It describes the structure and contents of the tree. -+ structure_blk: Vec, -+ /// The strings block of flattened device tree. -+ /// It contains strings representing all the property names used in the tree. -+ strings_blk: Vec, -+ /// The physical ID of the system’s boot CPU. -+ boot_cpuid_phys: u32, -+ /// The depth of nested node. -+ subnode_depth: u32, -+ /// Is there a open node or not. -+ begin_node: bool, - } - --pub fn create_device_tree(fdt: &mut Vec) -> Result<()> { -- let mut ret = unsafe { fdt_create(fdt.as_mut_ptr() as *mut c_void, FDT_MAX_SIZE as c_int) }; -- if ret < 0 { -- bail!("Failed to fdt_create, return {}.", ret); -+/// FdtReserveEntry structure. -+#[derive(Clone, Debug)] -+pub struct FdtReserveEntry { -+ /// The address of reserved memory. -+ /// On 32-bit CPUs the upper 32-bits of the value are ignored. -+ address: u64, -+ /// The size of reserved memory. -+ size: u64, -+} -+ -+fn check_mem_reserve_overlap(mem_reservations: &[FdtReserveEntry]) -> bool { -+ if mem_reservations.len() <= 1 { -+ return true; - } - -- ret = unsafe { fdt_finish_reservemap(fdt.as_mut_ptr() as *mut c_void) }; -- if ret < 0 { -- bail!("Failed to fdt_finish_reservemap, return {}.", ret); -+ let mut mem_reser = mem_reservations.to_vec(); -+ mem_reser.sort_by_key(|m| m.address); -+ -+ for i in 0..(mem_reser.len() - 1) { -+ if mem_reser[i].address + mem_reser[i].size > mem_reser[i + 1].address { -+ return false; -+ } - } -+ true -+} -+ -+// If there is null character in string, return false. -+fn check_string_legality(s: &str) -> bool { -+ !s.contains('\0') -+} - -- let c_str = CString::new("").unwrap(); -- ret = unsafe { fdt_begin_node(fdt.as_mut_ptr() as *mut c_void, c_str.as_ptr()) }; -- if ret < 0 { -- bail!("Failed to fdt_begin_node, return {}.", ret); -+impl Default for FdtBuilder { -+ fn default() -> Self { -+ Self { -+ fdt_header: vec![0_u8; FDT_HEADER_SIZE], -+ mem_reserve: Vec::new(), -+ structure_blk: Vec::new(), -+ strings_blk: Vec::new(), -+ boot_cpuid_phys: 0, -+ subnode_depth: 0, -+ begin_node: false, -+ } - } -+} - -- ret = unsafe { fdt_end_node(fdt.as_mut_ptr() as *mut c_void) }; -- if ret < 0 { -- bail!("Failed to fdt_end_node, return {}.", ret); -+impl FdtBuilder { -+ pub fn new() -> Self { -+ FdtBuilder::default() - } - -- ret = unsafe { fdt_finish(fdt.as_mut_ptr() as *mut c_void) }; -- if ret < 0 { -- bail!("Failed to fdt_finish, return {}.", ret); -+ pub fn finish(mut self) -> Result> { -+ if self.subnode_depth > 0 { -+ return Err(ErrorKind::NodeUnclosed(self.subnode_depth).into()); -+ } -+ self.structure_blk -+ .extend_from_slice(&FDT_END.to_be_bytes()[..]); -+ -+ // According to the spec, mem_reserve blocks shall be ended -+ // with an entry where both address and size are equal to 0. -+ self.mem_reserve.extend_from_slice(&0_u64.to_be_bytes()); -+ self.mem_reserve.extend_from_slice(&0_u64.to_be_bytes()); -+ -+ // Fill fdt header. -+ let total_size = FDT_HEADER_SIZE -+ + self.mem_reserve.len() -+ + self.structure_blk.len() -+ + self.strings_blk.len(); -+ let off_dt_struct = FDT_HEADER_SIZE + self.mem_reserve.len(); -+ let off_dt_strings = FDT_HEADER_SIZE + self.mem_reserve.len() + self.structure_blk.len(); -+ let off_mem_rsvmap = FDT_HEADER_SIZE; -+ -+ BigEndian::write_u32(&mut self.fdt_header[0..4], FDT_MAGIC); -+ BigEndian::write_u32(&mut self.fdt_header[4..8], total_size as u32); -+ BigEndian::write_u32(&mut self.fdt_header[8..12], off_dt_struct as u32); -+ BigEndian::write_u32(&mut self.fdt_header[12..16], off_dt_strings as u32); -+ BigEndian::write_u32(&mut self.fdt_header[16..20], off_mem_rsvmap as u32); -+ BigEndian::write_u32(&mut self.fdt_header[20..24], FDT_VERSION); -+ BigEndian::write_u32(&mut self.fdt_header[24..28], FDT_LAST_COMP_VERSION); -+ BigEndian::write_u32(&mut self.fdt_header[28..32], self.boot_cpuid_phys); -+ BigEndian::write_u32(&mut self.fdt_header[32..36], self.strings_blk.len() as u32); -+ BigEndian::write_u32( -+ &mut self.fdt_header[36..40], -+ self.structure_blk.len() as u32, -+ ); -+ -+ self.fdt_header.extend_from_slice(&self.mem_reserve); -+ self.fdt_header.extend_from_slice(&self.structure_blk); -+ self.fdt_header.extend_from_slice(&self.strings_blk); -+ Ok(self.fdt_header) - } - -- ret = unsafe { -- fdt_open_into( -- fdt.as_ptr() as *mut c_void, -- fdt.as_mut_ptr() as *mut c_void, -- FDT_MAX_SIZE as c_int, -- ) -- }; -- if ret < 0 { -- bail!("Failed to fdt_open_into, return {}.", ret); -+ pub fn add_mem_reserve(&mut self, mem_reservations: &[FdtReserveEntry]) -> Result<()> { -+ if !check_mem_reserve_overlap(mem_reservations) { -+ return Err(ErrorKind::MemReserveOverlap.into()); -+ } -+ -+ for mem_reser in mem_reservations { -+ self.mem_reserve -+ .extend_from_slice(&mem_reser.address.to_be_bytes()); -+ self.mem_reserve -+ .extend_from_slice(&mem_reser.size.to_be_bytes()); -+ } -+ self.align_structure_blk(MEM_RESERVE_ALIGNMENT); -+ -+ Ok(()) - } - -- Ok(()) --} -+ pub fn begin_node(&mut self, node_name: &str) -> Result { -+ if !check_string_legality(node_name) { -+ return Err(ErrorKind::IllegalString(node_name.to_string()).into()); -+ } - --pub fn add_sub_node(fdt: &mut Vec, node_path: &str) -> Result<()> { -- let names: Vec<&str> = node_path.split('/').collect(); -- if names.len() < 2 { -- bail!("Failed to add sub node, node_path: {} invalid.", node_path); -+ self.structure_blk -+ .extend_from_slice(&FDT_BEGIN_NODE.to_be_bytes()[..]); -+ if node_name.is_empty() { -+ self.structure_blk -+ .extend_from_slice(&0_u32.to_be_bytes()[..]); -+ } else { -+ let mut val_array = node_name.as_bytes().to_vec(); -+ // The node’s name string should end with null('\0'). -+ val_array.push(0x0_u8); -+ self.structure_blk.extend_from_slice(&val_array); -+ } -+ self.align_structure_blk(STRUCTURE_BLOCK_ALIGNMENT); -+ self.subnode_depth += 1; -+ self.begin_node = true; -+ Ok(self.subnode_depth) - } - -- let node_name = names[names.len() - 1]; -- let pare_name = names[0..names.len() - 1].join("/"); -+ pub fn end_node(&mut self, begin_node_depth: u32) -> Result<()> { -+ if begin_node_depth != self.subnode_depth { -+ return Err(ErrorKind::NodeDepthMismatch(begin_node_depth, self.subnode_depth).into()); -+ } - -- let c_str = if pare_name.is_empty() { -- CString::new("/").unwrap() -- } else { -- CString::new(pare_name).unwrap() -- }; -+ self.structure_blk -+ .extend_from_slice(&FDT_END_NODE.to_be_bytes()[..]); -+ self.subnode_depth -= 1; -+ self.begin_node = false; -+ Ok(()) -+ } - -- let offset = unsafe { fdt_path_offset(fdt.as_ptr() as *const c_void, c_str.as_ptr()) }; -- if offset < 0 { -- bail!("Failed to fdt_path_offset, return {}.", offset); -+ pub fn set_boot_cpuid_phys(&mut self, boot_cpuid: u32) { -+ self.boot_cpuid_phys = boot_cpuid; - } - -- let c_str = CString::new(node_name).unwrap(); -- let ret = unsafe { fdt_add_subnode(fdt.as_mut_ptr() as *mut c_void, offset, c_str.as_ptr()) }; -- if ret < 0 { -- bail!("Failed to fdt_add_subnode, return {}.", ret); -+ pub fn set_property_string(&mut self, prop: &str, val: &str) -> Result<()> { -+ let mut val_array = val.as_bytes().to_vec(); -+ // The string property should end with null('\0'). -+ val_array.push(0x0_u8); -+ self.set_property(prop, &val_array) -+ .chain_err(|| ErrorKind::SetPropertyErr("string".to_string())) - } - -- Ok(()) --} -+ pub fn set_property_u32(&mut self, prop: &str, val: u32) -> Result<()> { -+ self.set_property(prop, &val.to_be_bytes()[..]) -+ .chain_err(|| ErrorKind::SetPropertyErr("u32".to_string())) -+ } - --pub fn set_property( -- fdt: &mut Vec, -- node_path: &str, -- prop: &str, -- val: Option<&[u8]>, --) -> Result<()> { -- let c_str = CString::new(node_path).unwrap(); -- let offset = unsafe { fdt_path_offset(fdt.as_ptr() as *const c_void, c_str.as_ptr()) }; -- if offset < 0 { -- bail!("Failed to fdt_path_offset, return {}.", offset); -- } -- -- let (ptr, len) = if let Some(val) = val { -- (val.as_ptr() as *const c_void, val.len() as i32) -- } else { -- (std::ptr::null::(), 0) -- }; -- -- let c_str = CString::new(prop).unwrap(); -- let ret = unsafe { -- fdt_setprop( -- fdt.as_mut_ptr() as *mut c_void, -- offset, -- c_str.as_ptr(), -- ptr, -- len, -- ) -- }; -- if ret < 0 { -- bail!("Failed to fdt_setprop, return {}.", ret); -- } -- -- Ok(()) --} -+ pub fn set_property_u64(&mut self, prop: &str, val: u64) -> Result<()> { -+ self.set_property(prop, &val.to_be_bytes()[..]) -+ .chain_err(|| ErrorKind::SetPropertyErr("u64".to_string())) -+ } - --pub fn set_property_string( -- fdt: &mut Vec, -- node_path: &str, -- prop: &str, -- val: &str, --) -> Result<()> { -- set_property( -- fdt, -- node_path, -- prop, -- Some(&([val.as_bytes(), &[0_u8]].concat())), -- ) --} -+ pub fn set_property_array_u32(&mut self, prop: &str, array: &[u32]) -> Result<()> { -+ let mut prop_array = Vec::with_capacity(array.len() * size_of::()); -+ for element in array { -+ prop_array.extend_from_slice(&element.to_be_bytes()[..]); -+ } -+ self.set_property(prop, &prop_array) -+ .chain_err(|| ErrorKind::SetPropertyErr("u32 array".to_string())) -+ } - --pub fn set_property_u32(fdt: &mut Vec, node_path: &str, prop: &str, val: u32) -> Result<()> { -- set_property(fdt, node_path, prop, Some(&val.to_be_bytes())) --} -+ pub fn set_property_array_u64(&mut self, prop: &str, array: &[u64]) -> Result<()> { -+ let mut prop_array = Vec::with_capacity(array.len() * size_of::()); -+ for element in array { -+ prop_array.extend_from_slice(&element.to_be_bytes()[..]); -+ } -+ self.set_property(prop, &prop_array) -+ .chain_err(|| ErrorKind::SetPropertyErr("u64 array".to_string())) -+ } - --pub fn set_property_u64(fdt: &mut Vec, node_path: &str, prop: &str, val: u64) -> Result<()> { -- set_property(fdt, node_path, prop, Some(&val.to_be_bytes())) --} -+ pub fn set_property(&mut self, property_name: &str, property_val: &[u8]) -> Result<()> { -+ if !check_string_legality(property_name) { -+ return Err(ErrorKind::IllegalString(property_name.to_string()).into()); -+ } - --pub fn set_property_array_u32( -- fdt: &mut Vec, -- node_path: &str, -- prop: &str, -- array: &[u32], --) -> Result<()> { -- let mut bytes: Vec = Vec::new(); -- for &val in array { -- bytes.append(&mut val.to_be_bytes().to_vec()); -- } -- set_property(fdt, node_path, prop, Some(&bytes)) --} -+ if !self.begin_node { -+ return Err(ErrorKind::IllegelPropertyPos.into()); -+ } - --pub fn set_property_array_u64( -- fdt: &mut Vec, -- node_path: &str, -- prop: &str, -- array: &[u64], --) -> Result<()> { -- let mut bytes: Vec = Vec::new(); -- for &val in array { -- bytes.append(&mut val.to_be_bytes().to_vec()); -- } -- set_property(fdt, node_path, prop, Some(&bytes)) --} -+ let len = property_val.len() as u32; -+ let nameoff = self.strings_blk.len() as u32; -+ self.structure_blk -+ .extend_from_slice(&FDT_PROP.to_be_bytes()[..]); -+ self.structure_blk.extend_from_slice(&len.to_be_bytes()[..]); -+ self.structure_blk -+ .extend_from_slice(&nameoff.to_be_bytes()[..]); -+ self.structure_blk.extend_from_slice(property_val); -+ self.align_structure_blk(STRUCTURE_BLOCK_ALIGNMENT); - --pub fn dump_dtb(fdt: &[u8], file_path: &str) { -- use std::fs::File; -- use std::io::Write; -+ self.strings_blk.extend_from_slice(property_name.as_bytes()); -+ // These strings in strings block should end with null('\0'). -+ self.strings_blk.extend_from_slice("\0".as_bytes()); - -- let mut f = File::create(file_path).unwrap(); -- for i in fdt.iter() { -- f.write_all(&[*i]).expect("Unable to write data"); -+ Ok(()) -+ } -+ -+ fn align_structure_blk(&mut self, alignment: usize) { -+ let remainder = self.structure_blk.len() % alignment; -+ if remainder != 0 { -+ self.structure_blk -+ .extend(vec![0_u8; (alignment - remainder) as usize]); -+ } - } - } - -@@ -215,6 +288,13 @@ pub trait CompileFDT { - /// - /// # Arguments - /// -- /// * `fdt` - the fdt slice to be expended. -- fn generate_fdt_node(&self, fdt: &mut Vec) -> Result<()>; -+ /// * `fdt` - the FdtBuilder to be filled. -+ fn generate_fdt_node(&self, fdt: &mut FdtBuilder) -> Result<()>; -+} -+ -+pub fn dump_dtb(fdt: &[u8], file_path: &str) { -+ use std::fs::File; -+ use std::io::Write; -+ let mut f = File::create(file_path).unwrap(); -+ f.write_all(fdt).expect("Unable to write data"); - } -diff --git a/util/src/fdt.rs b/util/src/fdt.rs -deleted file mode 100644 -index 2fdab44..0000000 ---- a/util/src/fdt.rs -+++ /dev/null -@@ -1,300 +0,0 @@ --// Copyright (c) 2020 Huawei Technologies Co.,Ltd. All rights reserved. --// --// StratoVirt is licensed under Mulan PSL v2. --// You can use this software according to the terms and conditions of the Mulan --// PSL v2. --// You may obtain a copy of Mulan PSL v2 at: --// http://license.coscl.org.cn/MulanPSL2 --// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY --// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO --// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. --// See the Mulan PSL v2 for more details. -- --use std::mem::size_of; -- --use crate::errors::{ErrorKind, Result, ResultExt}; --use byteorder::{BigEndian, ByteOrder}; -- --pub const CLK_PHANDLE: u32 = 1; --pub const GIC_PHANDLE: u32 = 2; --pub const GIC_ITS_PHANDLE: u32 = 3; --pub const CPU_PHANDLE_START: u32 = 10; -- --pub const GIC_FDT_IRQ_TYPE_SPI: u32 = 0; --pub const GIC_FDT_IRQ_TYPE_PPI: u32 = 1; --pub const IRQ_TYPE_EDGE_RISING: u32 = 1; --pub const IRQ_TYPE_LEVEL_HIGH: u32 = 4; -- --pub const FDT_MAX_SIZE: u32 = 0x1_0000; -- --// Magic number in fdt header(big-endian). --const FDT_MAGIC: u32 = 0xd00dfeed; --// Fdt Header default information. --const FDT_HEADER_SIZE: usize = 40; --const FDT_VERSION: u32 = 17; --const FDT_LAST_COMP_VERSION: u32 = 16; --// Beginning token type of structure block. --const FDT_BEGIN_NODE: u32 = 0x00000001; --const FDT_END_NODE: u32 = 0x00000002; --const FDT_PROP: u32 = 0x00000003; --const FDT_END: u32 = 0x00000009; --// Memory reservation block alignment. --const MEM_RESERVE_ALIGNMENT: usize = 8; --// Structure block alignment. --const STRUCTURE_BLOCK_ALIGNMENT: usize = 4; -- --/// FdtBuilder structure. --pub struct FdtBuilder { -- /// The header of flattened device tree. -- fdt_header: Vec, -- /// The memory reservation block of flattened device tree. -- /// It provides the client program with a list of areas -- /// in physical memory which are reserved. -- mem_reserve: Vec, -- /// The structure block of flattened device tree. -- /// It describes the structure and contents of the tree. -- structure_blk: Vec, -- /// The strings block of flattened device tree. -- /// It contains strings representing all the property names used in the tree. -- strings_blk: Vec, -- /// The physical ID of the system’s boot CPU. -- boot_cpuid_phys: u32, -- /// The depth of nested node. -- subnode_depth: u32, -- /// Is there a open node or not. -- begin_node: bool, --} -- --/// FdtReserveEntry structure. --#[derive(Clone, Debug)] --pub struct FdtReserveEntry { -- /// The address of reserved memory. -- /// On 32-bit CPUs the upper 32-bits of the value are ignored. -- address: u64, -- /// The size of reserved memory. -- size: u64, --} -- --fn check_mem_reserve_overlap(mem_reservations: &[FdtReserveEntry]) -> bool { -- if mem_reservations.len() <= 1 { -- return true; -- } -- -- let mut mem_reser = mem_reservations.to_vec(); -- mem_reser.sort_by_key(|m| m.address); -- -- for i in 0..(mem_reser.len() - 1) { -- if mem_reser[i].address + mem_reser[i].size > mem_reser[i + 1].address { -- return false; -- } -- } -- true --} -- --// If there is null character in string, return false. --fn check_string_legality(s: &str) -> bool { -- !s.contains('\0') --} -- --impl Default for FdtBuilder { -- fn default() -> Self { -- Self { -- fdt_header: vec![0_u8; FDT_HEADER_SIZE], -- mem_reserve: Vec::new(), -- structure_blk: Vec::new(), -- strings_blk: Vec::new(), -- boot_cpuid_phys: 0, -- subnode_depth: 0, -- begin_node: false, -- } -- } --} -- --impl FdtBuilder { -- pub fn new() -> Self { -- FdtBuilder::default() -- } -- -- pub fn finish(mut self) -> Result> { -- if self.subnode_depth > 0 { -- return Err(ErrorKind::NodeUnclosed(self.subnode_depth).into()); -- } -- self.structure_blk -- .extend_from_slice(&FDT_END.to_be_bytes()[..]); -- -- // According to the spec, mem_reserve blocks shall be ended -- // with an entry where both address and size are equal to 0. -- self.mem_reserve.extend_from_slice(&0_u64.to_be_bytes()); -- self.mem_reserve.extend_from_slice(&0_u64.to_be_bytes()); -- -- // Fill fdt header. -- let total_size = FDT_HEADER_SIZE -- + self.mem_reserve.len() -- + self.structure_blk.len() -- + self.strings_blk.len(); -- let off_dt_struct = FDT_HEADER_SIZE + self.mem_reserve.len(); -- let off_dt_strings = FDT_HEADER_SIZE + self.mem_reserve.len() + self.structure_blk.len(); -- let off_mem_rsvmap = FDT_HEADER_SIZE; -- -- BigEndian::write_u32(&mut self.fdt_header[0..4], FDT_MAGIC); -- BigEndian::write_u32(&mut self.fdt_header[4..8], total_size as u32); -- BigEndian::write_u32(&mut self.fdt_header[8..12], off_dt_struct as u32); -- BigEndian::write_u32(&mut self.fdt_header[12..16], off_dt_strings as u32); -- BigEndian::write_u32(&mut self.fdt_header[16..20], off_mem_rsvmap as u32); -- BigEndian::write_u32(&mut self.fdt_header[20..24], FDT_VERSION); -- BigEndian::write_u32(&mut self.fdt_header[24..28], FDT_LAST_COMP_VERSION); -- BigEndian::write_u32(&mut self.fdt_header[28..32], self.boot_cpuid_phys); -- BigEndian::write_u32(&mut self.fdt_header[32..36], self.strings_blk.len() as u32); -- BigEndian::write_u32( -- &mut self.fdt_header[36..40], -- self.structure_blk.len() as u32, -- ); -- -- self.fdt_header.extend_from_slice(&self.mem_reserve); -- self.fdt_header.extend_from_slice(&self.structure_blk); -- self.fdt_header.extend_from_slice(&self.strings_blk); -- Ok(self.fdt_header) -- } -- -- pub fn add_mem_reserve(&mut self, mem_reservations: &[FdtReserveEntry]) -> Result<()> { -- if !check_mem_reserve_overlap(mem_reservations) { -- return Err(ErrorKind::MemReserveOverlap.into()); -- } -- -- for mem_reser in mem_reservations { -- self.mem_reserve -- .extend_from_slice(&mem_reser.address.to_be_bytes()); -- self.mem_reserve -- .extend_from_slice(&mem_reser.size.to_be_bytes()); -- } -- self.align_structure_blk(MEM_RESERVE_ALIGNMENT); -- -- Ok(()) -- } -- -- pub fn begin_node(&mut self, node_name: &str) -> Result { -- if !check_string_legality(node_name) { -- return Err(ErrorKind::IllegalString(node_name.to_string()).into()); -- } -- -- self.structure_blk -- .extend_from_slice(&FDT_BEGIN_NODE.to_be_bytes()[..]); -- if node_name.is_empty() { -- self.structure_blk -- .extend_from_slice(&0_u32.to_be_bytes()[..]); -- } else { -- let mut val_array = node_name.as_bytes().to_vec(); -- // The node’s name string should end with null('\0'). -- val_array.push(0x0_u8); -- self.structure_blk.extend_from_slice(&val_array); -- } -- self.align_structure_blk(STRUCTURE_BLOCK_ALIGNMENT); -- self.subnode_depth += 1; -- self.begin_node = true; -- Ok(self.subnode_depth) -- } -- -- pub fn end_node(&mut self, begin_node_depth: u32) -> Result<()> { -- if begin_node_depth != self.subnode_depth { -- return Err(ErrorKind::NodeDepthMismatch(begin_node_depth, self.subnode_depth).into()); -- } -- -- self.structure_blk -- .extend_from_slice(&FDT_END_NODE.to_be_bytes()[..]); -- self.subnode_depth -= 1; -- self.begin_node = false; -- Ok(()) -- } -- -- pub fn set_boot_cpuid_phys(&mut self, boot_cpuid: u32) { -- self.boot_cpuid_phys = boot_cpuid; -- } -- -- pub fn set_property_string(&mut self, prop: &str, val: &str) -> Result<()> { -- let mut val_array = val.as_bytes().to_vec(); -- // The string property should end with null('\0'). -- val_array.push(0x0_u8); -- self.set_property(prop, &val_array) -- .chain_err(|| ErrorKind::SetPropertyErr("string".to_string())) -- } -- -- pub fn set_property_u32(&mut self, prop: &str, val: u32) -> Result<()> { -- self.set_property(prop, &val.to_be_bytes()[..]) -- .chain_err(|| ErrorKind::SetPropertyErr("u32".to_string())) -- } -- -- pub fn set_property_u64(&mut self, prop: &str, val: u64) -> Result<()> { -- self.set_property(prop, &val.to_be_bytes()[..]) -- .chain_err(|| ErrorKind::SetPropertyErr("u64".to_string())) -- } -- -- pub fn set_property_array_u32(&mut self, prop: &str, array: &[u32]) -> Result<()> { -- let mut prop_array = Vec::with_capacity(array.len() * size_of::()); -- for element in array { -- prop_array.extend_from_slice(&element.to_be_bytes()[..]); -- } -- self.set_property(prop, &prop_array) -- .chain_err(|| ErrorKind::SetPropertyErr("u32 array".to_string())) -- } -- -- pub fn set_property_array_u64(&mut self, prop: &str, array: &[u64]) -> Result<()> { -- let mut prop_array = Vec::with_capacity(array.len() * size_of::()); -- for element in array { -- prop_array.extend_from_slice(&element.to_be_bytes()[..]); -- } -- self.set_property(prop, &prop_array) -- .chain_err(|| ErrorKind::SetPropertyErr("u64 array".to_string())) -- } -- -- pub fn set_property(&mut self, property_name: &str, property_val: &[u8]) -> Result<()> { -- if !check_string_legality(property_name) { -- return Err(ErrorKind::IllegalString(property_name.to_string()).into()); -- } -- -- if !self.begin_node { -- return Err(ErrorKind::IllegelPropertyPos.into()); -- } -- -- let len = property_val.len() as u32; -- let nameoff = self.strings_blk.len() as u32; -- self.structure_blk -- .extend_from_slice(&FDT_PROP.to_be_bytes()[..]); -- self.structure_blk.extend_from_slice(&len.to_be_bytes()[..]); -- self.structure_blk -- .extend_from_slice(&nameoff.to_be_bytes()[..]); -- self.structure_blk.extend_from_slice(property_val); -- self.align_structure_blk(STRUCTURE_BLOCK_ALIGNMENT); -- -- self.strings_blk.extend_from_slice(property_name.as_bytes()); -- // These strings in strings block should end with null('\0'). -- self.strings_blk.extend_from_slice("\0".as_bytes()); -- -- Ok(()) -- } -- -- fn align_structure_blk(&mut self, alignment: usize) { -- let remainder = self.structure_blk.len() % alignment; -- if remainder != 0 { -- self.structure_blk -- .extend(vec![0_u8; (alignment - remainder) as usize]); -- } -- } --} -- --/// Trait for devices to be added to the Flattened Device Tree. --#[allow(clippy::upper_case_acronyms)] --pub trait CompileFDT { -- /// function to generate fdt node -- /// -- /// # Arguments -- /// -- /// * `fdt` - the FdtBuilder to be filled. -- fn generate_fdt_node(&self, fdt: &mut FdtBuilder) -> Result<()>; --} -- --pub fn dump_dtb(fdt: &[u8], file_path: &str) { -- use std::fs::File; -- use std::io::Write; -- let mut f = File::create(file_path).unwrap(); -- f.write_all(fdt).expect("Unable to write data"); --} -diff --git a/util/src/lib.rs b/util/src/lib.rs -index d135c74..2c59065 100644 ---- a/util/src/lib.rs -+++ b/util/src/lib.rs -@@ -28,8 +28,6 @@ pub mod checksum; - pub mod daemonize; - #[cfg(target_arch = "aarch64")] - pub mod device_tree; --#[cfg(target_arch = "aarch64")] --pub mod fdt; - pub mod leak_bucket; - mod link_list; - pub mod loop_context; --- -2.31.1 - diff --git a/0015-util-fdt-add-some-UT-test-cases.patch b/0015-util-fdt-add-some-UT-test-cases.patch deleted file mode 100644 index ad9b44d8ebb5ab43ac01842408beb585759c40de..0000000000000000000000000000000000000000 --- a/0015-util-fdt-add-some-UT-test-cases.patch +++ /dev/null @@ -1,220 +0,0 @@ -From 1081b4f57b1bc959fa5e26a1e6520f1cfbf999b0 Mon Sep 17 00:00:00 2001 -From: Jiajie Li -Date: Thu, 24 Jun 2021 16:15:48 +0800 -Subject: [PATCH 5/5] util/fdt: add some UT test cases - -Test the basic function of mod fdt, like adding all kinds -of properties for fdt node, adding nested node, getting the -final result. What's more, add some boundary test cases. - -Signed-off-by: Jiajie Li ---- - util/src/device_tree.rs | 195 ++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 195 insertions(+) - -diff --git a/util/src/device_tree.rs b/util/src/device_tree.rs -index 2fdab44..d47b7f5 100644 ---- a/util/src/device_tree.rs -+++ b/util/src/device_tree.rs -@@ -298,3 +298,198 @@ pub fn dump_dtb(fdt: &[u8], file_path: &str) { - let mut f = File::create(file_path).unwrap(); - f.write_all(fdt).expect("Unable to write data"); - } -+ -+#[cfg(test)] -+mod tests { -+ use super::*; -+ -+ #[test] -+ fn test_add_all_properties() { -+ let mut fdt_builder = FdtBuilder::new(); -+ let root_node = fdt_builder.begin_node("").unwrap(); -+ fdt_builder.set_property("null", &[]).unwrap(); -+ fdt_builder.set_property_u32("u32", 0x01234567).unwrap(); -+ fdt_builder -+ .set_property_u64("u64", 0x0123456789abcdef) -+ .unwrap(); -+ fdt_builder -+ .set_property_array_u32( -+ "u32_array", -+ &vec![0x11223344, 0x55667788, 0x99aabbcc, 0xddeeff00], -+ ) -+ .unwrap(); -+ fdt_builder -+ .set_property_array_u64("u64_array", &vec![0x0011223344556677, 0x8899aabbccddeeff]) -+ .unwrap(); -+ fdt_builder -+ .set_property_string("string", "hello fdt") -+ .unwrap(); -+ fdt_builder.end_node(root_node).unwrap(); -+ let right_fdt: Vec = vec![ -+ 0xd0, 0x0d, 0xfe, 0xed, // 00: magic (0xd00dfeed) -+ 0x00, 0x00, 0x00, 0xf0, // 04: totalsize (0xf0) -+ 0x00, 0x00, 0x00, 0x38, // 08: off_dt_struct (0x38) -+ 0x00, 0x00, 0x00, 0xc8, // 0c: off_dt_strings (0xc8) -+ 0x00, 0x00, 0x00, 0x28, // 10: off_mem_rsvmap (0x28) -+ 0x00, 0x00, 0x00, 0x11, // 14: version (17) -+ 0x00, 0x00, 0x00, 0x10, // 18: last_comp_version (16) -+ 0x00, 0x00, 0x00, 0x00, // 1c: boot_cpuid_phys (0) -+ 0x00, 0x00, 0x00, 0x28, // 20: size_dt_strings (0x28) -+ 0x00, 0x00, 0x00, 0x90, // 24: size_dt_struct (0x90) -+ 0x00, 0x00, 0x00, 0x00, // 28: high address of memory reservation block terminator -+ 0x00, 0x00, 0x00, 0x00, // 2c: low address of memory reservation block terminator -+ 0x00, 0x00, 0x00, 0x00, // 30: high size of memory reservation block terminator -+ 0x00, 0x00, 0x00, 0x00, // 34: low size of memory reservation block terminator -+ 0x00, 0x00, 0x00, 0x01, // 38: FDT_BEGIN_NODE -+ 0x00, 0x00, 0x00, 0x00, // 3c: node name ("") with 4-byte alignment -+ 0x00, 0x00, 0x00, 0x03, // 40: FDT_PROP ("null") -+ 0x00, 0x00, 0x00, 0x00, // 44: property len (0) -+ 0x00, 0x00, 0x00, 0x00, // 48: property nameoff (0x00) -+ 0x00, 0x00, 0x00, 0x03, // 4c: FDT_PROP ("u32") -+ 0x00, 0x00, 0x00, 0x04, // 50: property len (4) -+ 0x00, 0x00, 0x00, 0x05, // 54: property nameoff (0x05) -+ 0x01, 0x23, 0x45, 0x67, // 58: property’s value (0x01234567) -+ 0x00, 0x00, 0x00, 0x03, // 5c: FDT_PROP ("u64") -+ 0x00, 0x00, 0x00, 0x08, // 60: property len (8) -+ 0x00, 0x00, 0x00, 0x09, // 64: property nameoff (0x09) -+ 0x01, 0x23, 0x45, 0x67, // 68: property’s value (0x01234567) -+ 0x89, 0xab, 0xcd, 0xef, // 6c: property’s value (0x89abcdef) -+ 0x00, 0x00, 0x00, 0x03, // 70: FDT_PROP ("u32_array") -+ 0x00, 0x00, 0x00, 0x10, // 74: property len (16) -+ 0x00, 0x00, 0x00, 0x0d, // 78: property nameoff (0x0d) -+ 0x11, 0x22, 0x33, 0x44, // 7c: property’s value (0x11223344) -+ 0x55, 0x66, 0x77, 0x88, // 80: property’s value (0x55667788) -+ 0x99, 0xaa, 0xbb, 0xcc, // 84: property’s value (0x99aabbcc) -+ 0xdd, 0xee, 0xff, 0x00, // 88: property’s value (0xddeeff00) -+ 0x00, 0x00, 0x00, 0x03, // 8c: FDT_PROP ("u64_array") -+ 0x00, 0x00, 0x00, 0x10, // 90: property len (16) -+ 0x00, 0x00, 0x00, 0x17, // 94: property nameoff (0x17) -+ 0x00, 0x11, 0x22, 0x33, // 98: property’s value (0x00112233) -+ 0x44, 0x55, 0x66, 0x77, // 9c: property’s value (0x44556677) -+ 0x88, 0x99, 0xaa, 0xbb, // a0: property’s value (0x8899aabb) -+ 0xcc, 0xdd, 0xee, 0xff, // a4: property’s value (0xccddeeff) -+ 0x00, 0x00, 0x00, 0x03, // a8: FDT_PROP ("string") -+ 0x00, 0x00, 0x00, 0x0a, // ac: property len (10) -+ 0x00, 0x00, 0x00, 0x21, // b0: property nameoff (0x21) -+ b'h', b'e', b'l', b'l', // b4: property’s value ("hell") -+ b'o', b' ', b'f', b'd', // b8: property’s value ("o fd") -+ b't', b'\0', 0x00, 0x00, // bc: property’s value ("t\0" with padding) -+ 0x00, 0x00, 0x00, 0x02, // c0: FDT_END_NODE -+ 0x00, 0x00, 0x00, 0x09, // c4: FDT_END -+ b'n', b'u', b'l', b'l', b'\0', // c8: "null" with offset 0x00 -+ b'u', b'3', b'2', b'\0', // cd: "u32" with offset 0x05 -+ b'u', b'6', b'4', b'\0', // d1: "u64" with offset 0x09 -+ b'u', b'3', b'2', b'_', b'a', b'r', b'r', b'a', b'y', -+ b'\0', // d5: "u32_array" with offset 0x0d -+ b'u', b'6', b'4', b'_', b'a', b'r', b'r', b'a', b'y', -+ b'\0', // df: "u64_array" with offset 0x17 -+ b's', b't', b'r', b'i', b'n', b'g', b'\0', // e9: "string" with offset 0x21 -+ ]; -+ let sample_fdt = fdt_builder.finish().unwrap(); -+ assert_eq!(right_fdt, sample_fdt); -+ } -+ -+ #[test] -+ fn test_nested_node() { -+ let mut fdt_builder = FdtBuilder::new(); -+ let root_node = fdt_builder.begin_node("").unwrap(); -+ -+ let cpus_node = fdt_builder.begin_node("cpus").unwrap(); -+ fdt_builder.set_property_u32("addrcells", 0x02).unwrap(); -+ fdt_builder.set_property_u32("sizecells", 0x0).unwrap(); -+ -+ let cpu_map_node = fdt_builder.begin_node("cpu-map").unwrap(); -+ fdt_builder.set_property_u32("cpu", 10).unwrap(); -+ -+ fdt_builder.end_node(cpu_map_node).unwrap(); -+ fdt_builder.end_node(cpus_node).unwrap(); -+ fdt_builder.end_node(root_node).unwrap(); -+ -+ fdt_builder.set_boot_cpuid_phys(1); -+ -+ let right_fdt: Vec = vec![ -+ 0xd0, 0x0d, 0xfe, 0xed, // 00: magic (0xd00dfeed) -+ 0x00, 0x00, 0x00, 0xb0, // 04: totalsize (0xb0) -+ 0x00, 0x00, 0x00, 0x38, // 08: off_dt_struct (0x38) -+ 0x00, 0x00, 0x00, 0x98, // 0c: off_dt_strings (0x98) -+ 0x00, 0x00, 0x00, 0x28, // 10: off_mem_rsvmap (0x28) -+ 0x00, 0x00, 0x00, 0x11, // 14: version (17) -+ 0x00, 0x00, 0x00, 0x10, // 18: last_comp_version (16) -+ 0x00, 0x00, 0x00, 0x01, // 1c: boot_cpuid_phys (1) -+ 0x00, 0x00, 0x00, 0x18, // 20: size_dt_strings (0x18) -+ 0x00, 0x00, 0x00, 0x60, // 24: size_dt_struct (0x60) -+ 0x00, 0x00, 0x00, 0x00, // 28: high address of memory reservation block terminator -+ 0x00, 0x00, 0x00, 0x00, // 2c: low address of memory reservation block terminator -+ 0x00, 0x00, 0x00, 0x00, // 30: high size of memory reservation block terminator -+ 0x00, 0x00, 0x00, 0x00, // 34: low size of memory reservation block terminator -+ 0x00, 0x00, 0x00, 0x01, // 38: FDT_BEGIN_NODE -+ 0x00, 0x00, 0x00, 0x00, // 3c: node name ("") -+ 0x00, 0x00, 0x00, 0x01, // 40: FDT_BEGIN_NODE -+ b'c', b'p', b'u', b's', // 44: node name ("cpus") with 4-byte alignment -+ b'\0', 0x00, 0x00, 0x00, // 48: padding -+ 0x00, 0x00, 0x00, 0x03, // 4c: FDT_PROP ("addrcells") -+ 0x00, 0x00, 0x00, 0x04, // 50: property len (4) -+ 0x00, 0x00, 0x00, 0x00, // 54: property nameoff (0x00) -+ 0x00, 0x00, 0x00, 0x02, // 58: property’s value (0x02) -+ 0x00, 0x00, 0x00, 0x03, // 5c: FDT_PROP ("sizecells") -+ 0x00, 0x00, 0x00, 0x04, // 60: property len (4) -+ 0x00, 0x00, 0x00, 0x0a, // 64: property nameoff (0xa) -+ 0x00, 0x00, 0x00, 0x00, // 68: property’s value (0x0) -+ 0x00, 0x00, 0x00, 0x01, // 6c: FDT_BEGIN_NODE -+ b'c', b'p', b'u', b'-', // 70: node name ("cpu-map") -+ b'm', b'a', b'p', b'\0', // 74: node name ("cpu-map") -+ 0x00, 0x00, 0x00, 0x03, // 78: FDT_PROP ("cpu") -+ 0x00, 0x00, 0x00, 0x04, // 7c: property len (4) -+ 0x00, 0x00, 0x00, 0x14, // 80: property nameoff (0x14) -+ 0x00, 0x00, 0x00, 0x0a, // 84: property’s value (10) -+ 0x00, 0x00, 0x00, 0x02, // 88: FDT_END_NODE -+ 0x00, 0x00, 0x00, 0x02, // 8c: FDT_END_NODE -+ 0x00, 0x00, 0x00, 0x02, // 90: FDT_END_NODE -+ 0x00, 0x00, 0x00, 0x09, // 94: FDT_END -+ b'a', b'd', b'd', b'r', b'c', b'e', b'l', b'l', b's', -+ b'\0', // 98: "addrcells" with offset 0x00 -+ b's', b'i', b'z', b'e', b'c', b'e', b'l', b'l', b's', -+ b'\0', // a2: "sizecells" with offset 0x0a -+ b'c', b'p', b'u', b'\0', // ac: "cpu" with offset 0x14 -+ ]; -+ let sample_fdt = fdt_builder.finish().unwrap(); -+ assert_eq!(right_fdt, sample_fdt); -+ } -+ -+ #[test] -+ fn test_illegeal_string() { -+ let mut fdt_builder = FdtBuilder::new(); -+ assert!(fdt_builder.begin_node("bad\0string").is_err()); -+ -+ fdt_builder.begin_node("good string").unwrap(); -+ assert!(fdt_builder.set_property("bad property\0name", &[]).is_err()); -+ assert!(fdt_builder -+ .set_property_string("good property name", "test\0val") -+ .is_ok()); -+ } -+ -+ #[test] -+ fn test_unclose_nested_node() { -+ let mut fdt_builder = FdtBuilder::new(); -+ let root_node = fdt_builder.begin_node("").unwrap(); -+ fdt_builder.begin_node("nested node").unwrap(); -+ assert!(fdt_builder.end_node(root_node).is_err()); -+ assert!(fdt_builder.finish().is_err()); -+ } -+ -+ #[test] -+ fn test_mem_reserve_overlap() { -+ let mut fdt_builder = FdtBuilder::new(); -+ let mem_reservations = [ -+ FdtReserveEntry { -+ address: 0x100, -+ size: 0x100, -+ }, -+ FdtReserveEntry { -+ address: 0x150, -+ size: 0x100, -+ }, -+ ]; -+ assert!(fdt_builder.add_mem_reserve(&mem_reservations).is_err()); -+ } -+} --- -2.31.1 - diff --git a/stratovirt-0.3.0.tar.gz b/stratovirt-0.3.0.tar.gz deleted file mode 100644 index 6a2cb1645fb580fc4fca8c91e22e9397292b500f..0000000000000000000000000000000000000000 Binary files a/stratovirt-0.3.0.tar.gz and /dev/null differ diff --git a/stratovirt-2.0.0.tar.gz b/stratovirt-2.0.0.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..8003621c55d8f04db0a2a4e0e3a4dad9d53e8403 Binary files /dev/null and b/stratovirt-2.0.0.tar.gz differ diff --git a/stratovirt.spec b/stratovirt.spec index dc957c3f22b68e248aa712d25119cba993a304d8..79cac585602a85add9f2bb9d910e02b3c03aed8c 100644 --- a/stratovirt.spec +++ b/stratovirt.spec @@ -5,34 +5,16 @@ %define _unpackaged_files_terminate_build 0 Name: stratovirt -Version: 0.3.0 -Release: 5 +Version: 2.0.0 +Release: 3 Summary: StratoVirt is an opensource VMM(Virtual Machine Manager) which aims to perform next generation virtualization. License: Mulan PSL v2 URL: https://gitee.com/openeuler/StratoVirt Source0: %{name}-%{version}.tar.gz -Patch0001: 0001-docs-update-readme.md-for-building-via-musl-toolchai.patch -Patch0002: 0002-docs-turn-on-the-option-switch-of-virtio-rng-for-x86.patch -Patch0003: 0003-doc-fix-an-uncorrect-link-for-build_guide-in-quickst.patch -Patch0004: 0004-update-rootfs-disk-image-description-in-README.ch.md.patch -Patch0005: 0005-update-rootfs-disk-image-description-in-README.md.patch -Patch0006: 0006-StratoVirt-clear-clippy-warnings-for-updating-rust-1.patch -Patch0007: 0007-testcases-virtio_blk-decrease-hot-plugged-blk-number.patch -Patch0008: 0008-testscases-vmlife-decrease-test-blk-number.patch -Patch0009: 0009-README-update-readme.patch -Patch0010: 0010-docs-add-IMAGE_BUILD.md.patch -Patch0011: 0011-util-fdt-implement-basic-fdt-API.patch -Patch0012: 0012-devices-gicv3-use-mod-fdt-instead-of-device_tree.patch -Patch0013: 0013-machine-micro_vm-use-fdt-API-of-mod-fdt-instead-of-d.patch -Patch0014: 0014-Replace-mod-device_tree-with-mod-fdt.patch -Patch0015: 0015-util-fdt-add-some-UT-test-cases.patch - - ExclusiveArch: x86_64 aarch64 - %ifarch aarch64 Requires: dtc BuildRequires: dtc-devel @@ -46,9 +28,17 @@ BuildRequires: gcc %description Based on Rust programming language, StratoVirt is lightweight, efficient and safe. StratoVirt reduces memory resource consumption and improves VM startup speed while retains isolation capability and security capability of traditional virtualization. StratoVirt works with iSulad and Kata container, and can be integrated in Kubernetes ecosystem perfectly. The current version can be applied to microservices or serverless scenarios. StratoVirt reserves interface and design for importing more features, even standard virtualization. - Summary: %{summary} +Patch001: 0001-fix-spelling-errors-in-project.patch +Patch002: 0002-migration-fix-an-error-during-migration-interface-on.patch +Patch003: 0003-migration-fix-an-errors-during-the-PL011-device-stat.patch +Patch004: 0004-machine-standard_vm-fix-inappropriate-file-open-perm.patch +Patch005: 0005-kernel_config-update-kernel-config-5.10-on-aarch64-p.patch +Patch006: 0006-syscall-add-syscall-newfstatat-in-x86_64-unknown-lin.patch +Patch007: 0007-vfio-fix-the-problem-of-dma-mapping-failed.patch +Patch008: 0008-virtio-fix-dev_id-initialization-for-virtio-pci-and-.patch + %files -n stratovirt %{_bindir}/stratovirt @@ -80,50 +70,54 @@ sed -i 's/rustflags = \[/rustflags = \["-Clink-arg=-lgcc", /g' ./.cargo/config %install %cargo_install -a -chmod 550 ${RPM_BUILD_ROOT}/usr/bin/stratovirt +chmod 555 ${RPM_BUILD_ROOT}/usr/bin/stratovirt %changelog +* Fri Aug 20 2021 Jie Yang - 2.0.0-3 +- virtio: fix dev_id initialization for virtio-pci and vfio device on aarch64 platform +- vfio: fix the problem of dma mapping failed +- syscall: add syscall "newfstatat" in x86_64-unknown-linux-gnu target +- kernel_config: update kernel config 5.10 on aarch64 platform +- machine/standard_vm: fix inappropriate file open permissions +- migration: fix an errors during the PL011 device state restore +- migration: fix an error during migration interface on aarch64 +- fix spelling errors in project + +* Wed Aug 18 2021 Xinle.Guo - 2.0.0-2 +- switch stratovirt permission from 550 to 555 + +* Fri Aug 13 2021 Jie Yang - 2.0.0-1 +- add ACPI support +- add PCIe/PCI support +- add support for UEFI boot +- add virtio pci support +- provide standard type machine on x86_64 and aarch64 +- add hot boot feature +- add VFIO support +- add initial support for being managed by libvirt + * Tue Jul 27 2021 XuFei - 0.3.0-5 -- Type:NA -- ID:NA -- SUG:NA -- DESC:add fdt patches for musl compilation +- add fdt patches for musl compilation * Wed Jun 16 2021 XuFei - 0.3.0-4 -- Type:NA -- ID:NA -- SUG:NA -- DESC:add gcc dependency package +- add gcc dependency package * Sun May 28 2021 XuFei - 0.3.0-3 -- Type:NA -- ID:NA -- SUG:NA -- DESC:modify docs,modify testcases and clear clippy warnings for updating rust 1.51.0 +- modify docs +- modify testcases +- clear clippy warnings for updating rust 1.51.0 * Sun Apr 25 2021 LiangZhang - 0.3.0-2 -- Type:NA -- ID:NA -- SUG:NA -- DESC:Add hydropper to package +- add hydropper to package * Sun Apr 25 2021 LiangZhang - 0.3.0-1 -- Type:NA -- ID:NA -- SUG:NA -- DESC:Update package to 0.3.0 +- update package to 0.3.0 * Wed Jan 13 2021 LiangZhang - 0.1.0-3 -- Type:NA -- ID:NA -- SUG:NA -- DESC:Update package to latest source +- update package to latest source * Wed Jan 13 2021 XuFei - 0.1.0-2 -- Type:NA -- ID:NA -- SUG:NA -- DESC:Modify summary and description for spec +- modify summary and description for spec * Thu Jul 16 2020 Xu Yandong - 0.1.0-1 -- Initial package +- initial package