From 66b713010388d3141ae5dba270a08d5e868425d2 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 27 Feb 2025 09:42:39 -0500 Subject: [PATCH 01/40] Add TDX Makefile target Signed-off-by: Jake Correnti --- Makefile | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Makefile b/Makefile index abe3a9dcc..0beb081a9 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,8 @@ SNP_INIT_SRC = init/tee/snp_attest.c \ init/tee/snp_attest.h \ $(KBS_INIT_SRC) \ +TDX_INIT_SRC = $(KBS_INIT_SRC) + KBS_LD_FLAGS = -lcurl -lidn2 -lssl -lcrypto -lzstd -lz -lbrotlidec-static \ -lbrotlicommon-static @@ -27,6 +29,14 @@ ifeq ($(SEV),1) INIT_SRC += $(SNP_INIT_SRC) BUILD_INIT = 0 endif +ifeq ($(TDX),1) + VARIANT = -tdx + FEATURE_FLAGS := --features intel-tdx,tee,blk,kbs-types,serde,serde_json,curl + INIT_DEFS += -DTDX=1 + INIT_DEFS += $(KBS_LD_FLAGS) + INIT_SRC += $(KBS_INIT_SRC) + BUILD_INIT = 0 +endif ifeq ($(GPU),1) FEATURE_FLAGS += --features gpu endif @@ -91,6 +101,9 @@ $(LIBRARY_RELEASE_$(OS)): $(INIT_BINARY) ifeq ($(SEV),1) mv target/release/libkrun.so target/release/$(KRUN_BASE_$(OS)) endif +ifeq ($(TDX),1) + mv target/release/libkrun.so target/release/$(KRUN_BASE_$(OS)) +endif ifeq ($(OS),Linux) patchelf --set-soname $(KRUN_SONAME_$(OS)) --output $(LIBRARY_RELEASE_$(OS)) target/release/$(KRUN_BASE_$(OS)) else @@ -108,6 +121,9 @@ $(LIBRARY_DEBUG_$(OS)): $(INIT_BINARY) ifeq ($(SEV),1) mv target/debug/libkrun.so target/debug/$(KRUN_BASE_$(OS)) endif +ifeq ($(TDX),1) + mv target/debug/libkrun.so target/debug/$(KRUN_BASE_$(OS)) +endif ifeq ($(OS),Linux) patchelf --set-soname $(KRUN_SONAME_$(OS)) --output $(LIBRARY_DEBUG_$(OS)) target/debug/$(KRUN_BASE_$(OS)) else From 3e50bea520a9048690eb3d980656a585c0d97b0d Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 27 Feb 2025 09:45:00 -0500 Subject: [PATCH 02/40] Add TDX Makefile target for examples Signed-off-by: Jake Correnti --- examples/Makefile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/Makefile b/examples/Makefile index 8c163059e..529b85547 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -4,6 +4,7 @@ LDFLAGS_x86_64_Linux = -lkrun LDFLAGS_aarch64_Linux = -lkrun LDFLAGS_arm64_Darwin = -L/opt/homebrew/lib -lkrun LDFLAGS_sev = -lkrun-sev +LDFLAGS_tdx = -L../target/debug -lkrun-tdx LDFLAGS_efi = -L/opt/homebrew/lib -lkrun-efi CFLAGS = -O2 -g -I../include ROOTFS_DISTRO := fedora @@ -15,6 +16,9 @@ EXAMPLES := chroot_vm ifeq ($(SEV),1) EXAMPLES := launch-tee endif +ifeq ($(TDX),1) + EXAMPLES := launch-tee +endif ifeq ($(EFI),1) EXAMPLES := boot_efi endif @@ -28,7 +32,12 @@ ifeq ($(OS),Darwin) endif launch-tee: launch-tee.c +ifeq ($(SEV),1) gcc -o $@ $< $(CFLAGS) $(LDFLAGS_sev) +endif +ifeq ($(TDX),1) + gcc -o $@ $< $(CFLAGS) $(LDFLAGS_tdx) +endif boot_efi: boot_efi.c gcc -o $@ $< $(CFLAGS) $(LDFLAGS_efi) From 4af1d461115b9857780356803db2b993f4eced8e Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 27 Feb 2025 09:46:25 -0500 Subject: [PATCH 03/40] add tdx-config-noattest.json Signed-off-by: Jake Correnti --- examples/tdx-config-noattest.json | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 examples/tdx-config-noattest.json diff --git a/examples/tdx-config-noattest.json b/examples/tdx-config-noattest.json new file mode 100644 index 000000000..5a80f15bd --- /dev/null +++ b/examples/tdx-config-noattest.json @@ -0,0 +1,8 @@ +{ + "workload_id": "tdxtest", + "cpus": 1, + "ram_mib": 2048, + "tee": "tdx", + "tee_data": "{\"vendor_chain\": \"\", \"attestation_server_pubkey\": \"\"}", + "attestation_url": "" +} From 3f20d2bcdf3a354065781d86ce0be9c70b32ee1d Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 27 Feb 2025 10:04:58 -0500 Subject: [PATCH 04/40] update dependencies Signed-off-by: Jake Correnti --- Cargo.lock | 24 +++++++++++++++++++----- src/arch/Cargo.toml | 6 ++++-- src/cpuid/Cargo.toml | 4 ++-- src/libkrun/Cargo.toml | 4 ++++ src/vmm/Cargo.toml | 7 +++++-- 5 files changed, 34 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 42e60ad7c..4cad4ef4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,6 +72,7 @@ dependencies = [ "kvm-ioctls", "libc", "smbios", + "tdx", "utils", "vm-fdt", "vm-memory", @@ -716,17 +717,13 @@ dependencies = [ [[package]] name = "kvm-bindings" version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4933174d0cc4b77b958578cd45784071cc5ae212c2d78fbd755aaaa6dfa71a" dependencies = [ "vmm-sys-util", ] [[package]] name = "kvm-ioctls" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "337d1afa126368bbd6a5c328048f71a69a737e9afe7e436b392a8f8d770c9171" +version = "0.19.1" dependencies = [ "bitflags 2.6.0", "kvm-bindings", @@ -760,11 +757,14 @@ dependencies = [ "devices", "env_logger", "hvf", + "kvm-bindings", + "kvm-ioctls", "libc", "log", "once_cell", "polly", "utils", + "vm-memory", "vmm", ] @@ -1405,6 +1405,18 @@ version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" +[[package]] +name = "tdx" +version = "0.1.0" +dependencies = [ + "bitflags 2.6.0", + "kvm-bindings", + "kvm-ioctls", + "libc", + "uuid", + "vmm-sys-util", +] + [[package]] name = "termcolor" version = "1.4.1" @@ -1587,6 +1599,7 @@ name = "vmm" version = "0.1.0" dependencies = [ "arch", + "arch_gen", "codicon", "cpuid", "crossbeam-channel", @@ -1607,6 +1620,7 @@ dependencies = [ "serde", "serde_json", "sev", + "tdx", "utils", "vm-memory", "vmm-sys-util", diff --git a/src/arch/Cargo.toml b/src/arch/Cargo.toml index baaedda55..0cd19bf73 100644 --- a/src/arch/Cargo.toml +++ b/src/arch/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [features] tee = [] amd-sev = [ "tee" ] +intel-tdx = [ "tee", "tdx" ] efi = [] [dependencies] @@ -18,8 +19,9 @@ smbios = { path = "../smbios" } utils = { path = "../utils" } [target.'cfg(target_os = "linux")'.dependencies] -kvm-bindings = { version = ">=0.8", features = ["fam-wrappers"] } -kvm-ioctls = ">=0.17" +kvm-bindings = { path = "../../../kvm-ioctls/kvm-bindings", features = ["fam-wrappers"]} +kvm-ioctls = { path = "../../../kvm-ioctls/kvm-ioctls"} +tdx = { path = "../../../tdx", optional = true } [target.'cfg(target_arch = "aarch64")'.dependencies] vm-fdt = ">= 0.2.0" diff --git a/src/cpuid/Cargo.toml b/src/cpuid/Cargo.toml index 41c53aee0..2a87bfaeb 100644 --- a/src/cpuid/Cargo.toml +++ b/src/cpuid/Cargo.toml @@ -8,5 +8,5 @@ edition = "2021" vmm-sys-util = ">=0.11" [target.'cfg(target_os = "linux")'.dependencies] -kvm-bindings = { version = ">=0.8", features = ["fam-wrappers"] } -kvm-ioctls = ">=0.17" +kvm-bindings = { path = "../../../kvm-ioctls/kvm-bindings", features = ["fam-wrappers"]} +kvm-ioctls = { path = "../../../kvm-ioctls/kvm-ioctls"} diff --git a/src/libkrun/Cargo.toml b/src/libkrun/Cargo.toml index e12347513..815a9c1b0 100644 --- a/src/libkrun/Cargo.toml +++ b/src/libkrun/Cargo.toml @@ -8,6 +8,7 @@ build = "build.rs" [features] tee = [] amd-sev = [ "blk", "tee" ] +intel-tdx = [ "blk", "tee" ] net = [] blk = [] efi = [ "blk", "net" ] @@ -21,6 +22,9 @@ env_logger = "0.9.0" libc = ">=0.2.39" log = "0.4.0" once_cell = "1.4.1" +kvm-bindings = { path = "../../../kvm-ioctls/kvm-bindings", features = ["fam-wrappers"]} +kvm-ioctls = { path = "../../../kvm-ioctls/kvm-ioctls"} +vm-memory = { version = ">=0.13", features = ["backend-mmap"] } devices = { path = "../devices" } polly = { path = "../polly" } diff --git a/src/vmm/Cargo.toml b/src/vmm/Cargo.toml index 25ed38d72..c66dbb75a 100644 --- a/src/vmm/Cargo.toml +++ b/src/vmm/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [features] tee = [] amd-sev = [ "blk", "tee", "codicon", "kbs-types", "procfs", "rdrand", "serde", "serde_json", "sev", "curl" ] +intel-tdx = [ "blk", "tee", "kbs-types", "serde", "serde_json", "curl", "tdx" ] net = [] blk = [] efi = [ "blk", "net" ] @@ -21,6 +22,7 @@ log = "0.4.0" vm-memory = { version = ">=0.13", features = ["backend-mmap"] } arch = { path = "../arch" } +arch_gen = { path = "../arch_gen" } devices = { path = "../devices" } kernel = { path = "../kernel" } utils = { path = "../utils"} @@ -41,8 +43,9 @@ nix = "0.24.1" cpuid = { path = "../cpuid" } [target.'cfg(target_os = "linux")'.dependencies] -kvm-bindings = { version = ">=0.10", features = ["fam-wrappers"] } -kvm-ioctls = ">=0.17" +tdx = { path = "../../../tdx", optional = true } +kvm-bindings = { path = "../../../kvm-ioctls/kvm-bindings", features = ["fam-wrappers"]} +kvm-ioctls = { path = "../../../kvm-ioctls/kvm-ioctls"} [target.'cfg(target_os = "macos")'.dependencies] hvf = { path = "../hvf" } From 48198ae0e34afe0a113721b07032caa0a88024ac Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 27 Feb 2025 10:18:21 -0500 Subject: [PATCH 05/40] update pre-existing CC feature checks Signed-off-by: Jake Correnti --- src/vmm/src/builder.rs | 3 ++- src/vmm/src/linux/vstate.rs | 8 ++++---- src/vmm/src/vmm_config/boot_source.rs | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index 21397de6d..1d1300b9e 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -429,7 +429,7 @@ pub fn build_microvm( #[cfg(feature = "tee")] let tee = vm_resources.tee_config().tee; - #[cfg(feature = "tee")] + #[cfg(feature = "amd-sev")] let snp_launcher = match tee { Tee::Snp => Some( vm.snp_secure_virt_prepare(&guest_memory) @@ -712,6 +712,7 @@ pub fn build_microvm( #[cfg(feature = "tee")] { match tee { + #[cfg(feature = "amd-sev")] Tee::Snp => { let cpuid = kvm .fd() diff --git a/src/vmm/src/linux/vstate.rs b/src/vmm/src/linux/vstate.rs index 63d74cad8..75efcaf6b 100644 --- a/src/vmm/src/linux/vstate.rs +++ b/src/vmm/src/linux/vstate.rs @@ -257,19 +257,19 @@ impl Display for Error { ), SetUserMemoryRegion(e) => write!(f, "Cannot set the memory regions: {e}"), ShmMmap(e) => write!(f, "Error creating memory map for SHM region: {e}"), - #[cfg(feature = "tee")] + #[cfg(feature = "amd-sev")] SnpSecVirtInit(e) => write!( f, "Error initializing the Secure Virtualization Backend (SEV): {e:?}" ), - #[cfg(feature = "tee")] + #[cfg(feature = "amd-sev")] SnpSecVirtPrepare(e) => write!( f, "Error preparing the VM for Secure Virtualization (SNP): {e:?}" ), - #[cfg(feature = "tee")] + #[cfg(feature = "amd-sev")] SnpSecVirtAttest(e) => write!(f, "Error attesting the Secure VM (SNP): {e:?}"), SignalVcpu(e) => write!(f, "Failed to signal Vcpu: {e}"), @@ -441,7 +441,7 @@ pub struct Vm { #[cfg(feature = "amd-sev")] tee: Option, - #[cfg(feature = "amd-sev")] + #[cfg(feature = "tee")] pub tee_config: Tee, } diff --git a/src/vmm/src/vmm_config/boot_source.rs b/src/vmm/src/vmm_config/boot_source.rs index bb6d2cb24..483336ee6 100644 --- a/src/vmm/src/vmm_config/boot_source.rs +++ b/src/vmm/src/vmm_config/boot_source.rs @@ -6,7 +6,7 @@ use std::fmt::{Display, Formatter, Result}; #[cfg(all(target_os = "linux", not(feature = "tee")))] pub const DEFAULT_KERNEL_CMDLINE: &str = "reboot=k panic=-1 panic_print=0 nomodule console=hvc0 \ rootfstype=virtiofs rw quiet no-kvmapf"; -#[cfg(feature = "amd-sev")] +#[cfg(feature = "tee")] pub const DEFAULT_KERNEL_CMDLINE: &str = "reboot=k panic=-1 panic_print=0 nomodule console=hvc0 \ root=/dev/vda rw quiet no-kvmapf"; #[cfg(target_os = "macos")] From 02c018995d5c43af574f3502001689274d382d43 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 27 Feb 2025 10:26:40 -0500 Subject: [PATCH 06/40] temporarily link libkrun-tdx with libkrunfw-sev Signed-off-by: Jake Correnti --- src/libkrun/build.rs | 4 +++- src/libkrun/src/lib.rs | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/libkrun/build.rs b/src/libkrun/build.rs index a3ccc2288..00506e9b6 100644 --- a/src/libkrun/build.rs +++ b/src/libkrun/build.rs @@ -5,6 +5,8 @@ fn main() { println!("cargo:rustc-link-search=/opt/homebrew/lib"); #[cfg(all(not(feature = "tee"), not(feature = "efi")))] println!("cargo:rustc-link-lib=krunfw"); - #[cfg(feature = "tee")] + #[cfg(feature = "amd-sev")] + println!("cargo:rustc-link-lib=krunfw-sev"); + #[cfg(feature = "intel-tdx")] println!("cargo:rustc-link-lib=krunfw-sev"); } diff --git a/src/libkrun/src/lib.rs b/src/libkrun/src/lib.rs index 9af22c511..766ebed84 100644 --- a/src/libkrun/src/lib.rs +++ b/src/libkrun/src/lib.rs @@ -253,7 +253,20 @@ extern "C" { fn krunfw_get_version() -> u32; } -#[cfg(feature = "tee")] +#[cfg(feature = "amd-sev")] +#[link(name = "krunfw-sev")] +extern "C" { + fn krunfw_get_qboot(size: *mut size_t) -> *mut c_char; + fn krunfw_get_initrd(size: *mut size_t) -> *mut c_char; + fn krunfw_get_kernel( + load_addr: *mut u64, + entry_addr: *mut u64, + size: *mut size_t, + ) -> *mut c_char; + fn krunfw_get_version() -> u32; +} + +#[cfg(feature = "intel-tdx")] #[link(name = "krunfw-sev")] extern "C" { fn krunfw_get_qboot(size: *mut size_t) -> *mut c_char; From 4e7d38c2a60d027adc7329b53ff672fd406d132a Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Tue, 17 Sep 2024 11:56:57 -0400 Subject: [PATCH 07/40] Use `kvm_userspace_memory_region2` and friends In `memory_init` we need to use `kvm_userspace_memory_region2`, `kvm_create_guest_memfd`, and `kvm_memory_attributes` for the TDX architecture, otherwise it will fail. Signed-off-by: Jake Correnti --- src/vmm/src/linux/vstate.rs | 96 +++++++++++++++++++++++++++++++------ 1 file changed, 82 insertions(+), 14 deletions(-) diff --git a/src/vmm/src/linux/vstate.rs b/src/vmm/src/linux/vstate.rs index 75efcaf6b..0d5bfbfa7 100644 --- a/src/vmm/src/linux/vstate.rs +++ b/src/vmm/src/linux/vstate.rs @@ -42,7 +42,10 @@ use kvm_bindings::{ Msrs, KVM_CLOCK_TSC_STABLE, KVM_IRQCHIP_IOAPIC, KVM_IRQCHIP_PIC_MASTER, KVM_IRQCHIP_PIC_SLAVE, KVM_MAX_CPUID_ENTRIES, KVM_PIT_SPEAKER_DUMMY, }; -use kvm_bindings::{kvm_userspace_memory_region, KVM_API_VERSION}; +use kvm_bindings::{ + kvm_create_guest_memfd, kvm_memory_attributes, kvm_userspace_memory_region, + kvm_userspace_memory_region2, KVM_API_VERSION, +}; use kvm_ioctls::*; use utils::eventfd::EventFd; use utils::signal::{register_signal_handler, sigrtmin, Killable}; @@ -63,6 +66,9 @@ pub enum Error { #[cfg(target_arch = "x86_64")] /// A call to cpuid instruction failed. CpuId(cpuid::Error), + #[cfg(feature = "intel-tdx")] + /// Cannot create guest memfd + CreateGuestMemfd(kvm_ioctls::Error), #[cfg(target_arch = "x86_64")] /// Error configuring the floating point related registers FPUConfiguration(arch::x86_64::regs::Error), @@ -104,6 +110,12 @@ pub enum Error { SetupGIC(arch::aarch64::gic::Error), /// Cannot set the memory regions. SetUserMemoryRegion(kvm_ioctls::Error), + #[cfg(feature = "intel-tdx")] + /// Cannot set the memory regions. + SetUserMemoryRegion2(kvm_ioctls::Error), + #[cfg(feature = "intel-tdx")] + /// Cannot set the memory attributes + SetMemoryAttributes(kvm_ioctls::Error), /// Error creating memory map for SHM region. ShmMmap(io::Error), #[cfg(feature = "amd-sev")] @@ -231,6 +243,8 @@ impl Display for Error { match self { #[cfg(target_arch = "x86_64")] CpuId(e) => write!(f, "Cpuid error: {e:?}"), + #[cfg(feature = "intel-tdx")] + CreateGuestMemfd(e) => write!(f, "Failed to create guest memfd: {e:?}",), GuestMemoryMmap(e) => write!(f, "Guest memory error: {e:?}"), #[cfg(target_arch = "x86_64")] GuestMSRs(e) => write!(f, "Retrieving supported guest MSRs fails: {e:?}"), @@ -257,6 +271,10 @@ impl Display for Error { ), SetUserMemoryRegion(e) => write!(f, "Cannot set the memory regions: {e}"), ShmMmap(e) => write!(f, "Error creating memory map for SHM region: {e}"), + #[cfg(feature = "intel-tdx")] + SetUserMemoryRegion2(e) => write!(f, "Cannot set the memory regions: {e:?}",), + #[cfg(feature = "intel-tdx")] + SetMemoryAttributes(e) => write!(f, "Cannot set the memory attributes: {e:?}",), #[cfg(feature = "amd-sev")] SnpSecVirtInit(e) => write!( f, @@ -524,20 +542,70 @@ impl Vm { // It's safe to unwrap because the guest address is valid. let host_addr = guest_mem.get_host_address(region.start_addr()).unwrap(); debug!("Guest memory starts at {:x?}", host_addr); - let memory_region = kvm_userspace_memory_region { - slot: self.next_mem_slot, - guest_phys_addr: region.start_addr().raw_value(), - memory_size: region.len(), - userspace_addr: host_addr as u64, - flags: 0, - }; - // Safe because we mapped the memory region, we made sure that the regions - // are not overlapping. - unsafe { + + #[cfg(feature = "intel-tdx")] + { + let gmem = kvm_create_guest_memfd { + size: region.len(), + flags: 0, + reserved: [0; 6], + }; + let gmem = self + .fd + .create_guest_memfd(gmem) + .map_err(Error::CreateGuestMemfd)?; + + let memory_region = kvm_userspace_memory_region2 { + slot: self.next_mem_slot, + // KVM_MEM_GUEST_MEMFD + flags: 1 << 2, + guest_phys_addr: region.start_addr().raw_value(), + memory_size: region.len(), + userspace_addr: host_addr as u64, + guest_memfd_offset: 0, + guest_memfd: gmem as u32, + pad1: 0, + pad2: [0; 14], + }; + + // Safe because we mapped the memory region, we made sure that the regions + // are not overlapping. + unsafe { + self.fd + .set_user_memory_region2(memory_region) + .map_err(Error::SetUserMemoryRegion2)?; + } + + let attr = kvm_memory_attributes { + address: region.start_addr().raw_value(), + size: region.len() as u64, + // KVM_MEMORY_ATTRIBUTE_PRIVATE, + attributes: 1 << 3, + flags: 0, + }; + self.fd - .set_user_memory_region(memory_region) - .map_err(Error::SetUserMemoryRegion)?; - }; + .set_memory_attributes(attr) + .map_err(Error::SetMemoryAttributes)?; + } + + #[cfg(not(feature = "intel-tdx"))] + { + let memory_region = kvm_userspace_memory_region { + slot: self.next_mem_slot, + guest_phys_addr: region.start_addr().raw_value(), + memory_size: region.len(), + userspace_addr: host_addr as u64, + flags: 0, + }; + // Safe because we mapped the memory region, we made sure that the regions + // are not overlapping. + unsafe { + self.fd + .set_user_memory_region(memory_region) + .map_err(Error::SetUserMemoryRegion)?; + }; + } self.next_mem_slot += 1; } From 5eed8f1f539e0424cab0eb1225789e49f0bea734 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 27 Feb 2025 10:35:52 -0500 Subject: [PATCH 08/40] Disable `KVM_CREATE_IRQCHIP` for TDX TDX does not use the `KVM_CREATE_IRQCHIP` ioctl, rather it enables the `KVM_SPLIT_IRQCHIP` capability, which is handled by virtee/tdx. Signed-off-by: Jake Correnti --- src/vmm/src/builder.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index 1d1300b9e..4db183c31 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -537,6 +537,7 @@ pub fn build_microvm( // while on aarch64 we need to do it the other way around. #[cfg(target_arch = "x86_64")] { + #[cfg(not(feature = "intel-tdx"))] setup_interrupt_controller(&vm)?; attach_legacy_devices(&vm, &mut pio_device_manager)?; @@ -1570,6 +1571,7 @@ pub mod tests { let (guest_memory, _arch_memory_info, _shm_manager) = default_guest_memory(128).unwrap(); let mut vm = setup_vm(&guest_memory).unwrap(); + #[cfg(not(feature = "intel-tdx"))] setup_interrupt_controller(&mut vm).unwrap(); let vcpu_config = VcpuConfig { vcpu_count, From 68d1e25a293b89176abe6cf335b3bd997a900875 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 27 Feb 2025 10:38:28 -0500 Subject: [PATCH 09/40] Disable register setup for TDX Registers are confidential for TDX, so configuring them through the KVM API is not allowed. Signed-off-by: Jake Correnti --- src/vmm/src/linux/vstate.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/vmm/src/linux/vstate.rs b/src/vmm/src/linux/vstate.rs index 0d5bfbfa7..d620bb7fe 100644 --- a/src/vmm/src/linux/vstate.rs +++ b/src/vmm/src/linux/vstate.rs @@ -1001,12 +1001,15 @@ impl Vcpu { .set_cpuid2(&self.cpuid) .map_err(Error::VcpuSetCpuid)?; - arch::x86_64::msr::setup_msrs(&self.fd).map_err(Error::MSRSConfiguration)?; - arch::x86_64::regs::setup_regs(&self.fd, kernel_start_addr.raw_value(), self.id) - .map_err(Error::REGSConfiguration)?; - arch::x86_64::regs::setup_fpu(&self.fd).map_err(Error::FPUConfiguration)?; - arch::x86_64::regs::setup_sregs(guest_mem, &self.fd, self.id) - .map_err(Error::SREGSConfiguration)?; + #[cfg(not(feature = "intel-tdx"))] + { + arch::x86_64::msr::setup_msrs(&self.fd).map_err(Error::MSRSConfiguration)?; + arch::x86_64::regs::setup_regs(&self.fd, kernel_start_addr.raw_value(), self.id) + .map_err(Error::REGSConfiguration)?; + arch::x86_64::regs::setup_fpu(&self.fd).map_err(Error::FPUConfiguration)?; + arch::x86_64::regs::setup_sregs(guest_mem, &self.fd, self.id) + .map_err(Error::SREGSConfiguration)?; + } arch::x86_64::interrupts::set_lint(&self.fd).map_err(Error::LocalIntConfiguration)?; Ok(()) } From 25b3a62ef8e224a64fd7a4bcdeaeeac93d4f936d Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Tue, 17 Sep 2024 09:44:28 -0400 Subject: [PATCH 10/40] Implement `Vm::new()` for TDX Adds a new `inteltdx` module and implements a feature-flagged `new` method for `VM to create a VM with the TDX architecure. Signed-off-by: Jake Correnti --- src/vmm/src/linux/tee/inteltdx.rs | 44 +++++++++++++++++++++++++++++++ src/vmm/src/linux/tee/mod.rs | 3 +++ src/vmm/src/linux/vstate.rs | 39 +++++++++++++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 src/vmm/src/linux/tee/inteltdx.rs diff --git a/src/vmm/src/linux/tee/inteltdx.rs b/src/vmm/src/linux/tee/inteltdx.rs new file mode 100644 index 000000000..56d56b523 --- /dev/null +++ b/src/vmm/src/linux/tee/inteltdx.rs @@ -0,0 +1,44 @@ +use tdx::launch::{TdxCapabilities, TdxVm}; +use tdx::tdvf::{self, TdvfSection}; + +use kvm_ioctls::VmFd; + +use std::fs::File; +use std::io; + +#[derive(Debug)] +pub enum Error { + CreateTdxVmStruct, + GetCapabilities, + OpenTdvfFirmwareFile(io::Error), + ParseTdvfSections(tdvf::Error), +} + +pub struct IntelTdx { + caps: TdxCapabilities, + vm: TdxVm, + tdvf_sections: Vec, + tdvf_file: File, +} + +impl IntelTdx { + pub fn new(vm_fd: &VmFd) -> Result { + // FIXME(jakecorrenti): need to specify the max number of VCPUs here and not just assume 100 + let vm = TdxVm::new(vm_fd, 100).or_else(|_| return Err(Error::CreateTdxVmStruct))?; + let caps = vm + .get_capabilities(vm_fd) + .or_else(|_| return Err(Error::GetCapabilities))?; + + let mut firmware = std::fs::File::open("/usr/share/edk2/ovmf/OVMF.inteltdx.fd") + .map_err(Error::OpenTdvfFirmwareFile)?; + let tdvf_sections = + tdx::tdvf::parse_sections(&mut firmware).map_err(Error::ParseTdvfSections)?; + + Ok(IntelTdx { + caps, + vm, + tdvf_sections, + tdvf_file: firmware, + }) + } +} diff --git a/src/vmm/src/linux/tee/mod.rs b/src/vmm/src/linux/tee/mod.rs index cd9d2ad6d..b4274b649 100644 --- a/src/vmm/src/linux/tee/mod.rs +++ b/src/vmm/src/linux/tee/mod.rs @@ -1,2 +1,5 @@ #[cfg(feature = "amd-sev")] pub mod amdsnp; + +#[cfg(feature = "intel-tdx")] +pub mod inteltdx; diff --git a/src/vmm/src/linux/vstate.rs b/src/vmm/src/linux/vstate.rs index d620bb7fe..2790e295c 100644 --- a/src/vmm/src/linux/vstate.rs +++ b/src/vmm/src/linux/vstate.rs @@ -25,6 +25,9 @@ use super::super::{FC_EXIT_CODE_GENERIC_ERROR, FC_EXIT_CODE_OK}; #[cfg(feature = "amd-sev")] use super::tee::amdsnp::{AmdSnp, Error as SnpError}; +#[cfg(feature = "intel-tdx")] +use super::tee::inteltdx::{Error as TdxError, IntelTdx}; + #[cfg(feature = "tee")] use kbs_types::Tee; @@ -127,6 +130,9 @@ pub enum Error { #[cfg(feature = "amd-sev")] /// Error attesting the Secure VM (SNP). SnpSecVirtAttest(SnpError), + #[cfg(feature = "intel-tdx")] + /// Error initializing the Trust Domain Extensions Backend (TDX) + TdxSecVirtInit(TdxError), #[cfg(feature = "tee")] /// The TEE specified is not supported. InvalidTee, @@ -291,6 +297,11 @@ impl Display for Error { SnpSecVirtAttest(e) => write!(f, "Error attesting the Secure VM (SNP): {e:?}"), SignalVcpu(e) => write!(f, "Failed to signal Vcpu: {e}"), + #[cfg(feature = "intel-tdx")] + TdxSecVirtInit(e) => write!( + f, + "Error initializing the Trust Domain Extensions Backend (TDX): {e:?}" + ), #[cfg(feature = "tee")] MissingTeeConfig => write!(f, "Missing TEE configuration"), #[cfg(target_arch = "x86_64")] @@ -459,6 +470,9 @@ pub struct Vm { #[cfg(feature = "amd-sev")] tee: Option, + #[cfg(feature = "intel-tdx")] + tdx: Option, + #[cfg(feature = "tee")] pub tee_config: Tee, } @@ -517,6 +531,31 @@ impl Vm { }) } + #[cfg(feature = "intel-tdx")] + pub fn new(kvm: &Kvm, tee_config: &TeeConfig) -> Result { + // create fd for interacting with kvm-vm specific functions + let vm_fd = kvm + .create_vm_with_type(tdx::launch::KVM_X86_TDX_VM) + .map_err(Error::VmFd)?; + + let supported_cpuid = kvm + .get_supported_cpuid(KVM_MAX_CPUID_ENTRIES) + .map_err(Error::VmFd)?; + + let supported_msrs = + arch::x86_64::msr::supported_guest_msrs(kvm).map_err(Error::GuestMSRs)?; + + let tdx = IntelTdx::new(&vm_fd).map_err(Error::TdxSecVirtInit)?; + Ok(Vm { + fd: vm_fd, + next_mem_slot: 0, + supported_cpuid, + supported_msrs, + tdx: Some(tdx), + tee_config: tee_config.tee, + }) + } + /// Returns a ref to the supported `CpuId` for this Vm. #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub fn supported_cpuid(&self) -> &CpuId { From 4adca376734eb8c8f8d65b56082bc01fecec8ec4 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 27 Feb 2025 13:38:41 -0500 Subject: [PATCH 11/40] adjust params header Signed-off-by: Jake Correnti --- examples/launch-tee | Bin 0 -> 23736 bytes src/arch/src/x86_64/mod.rs | 12 ++++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100755 examples/launch-tee diff --git a/examples/launch-tee b/examples/launch-tee new file mode 100755 index 0000000000000000000000000000000000000000..597bc7b0bef94b6f253a542eb69d3cd4198784cd GIT binary patch literal 23736 zcmeHP4Rlo1oxktBnaL!9WI})hP9VOigC8GZPwE zt60PmDM#8`wY62Wb?fn?YSmix97zjG(RNF#w%XP%cF`tlt*8`P?UMcd@5h@rFEiNP zvwQZOp4>C@{`dd;|Ni&u-S=_dz3*MuyljcCX-oy3UCc=HjSp~0Y#ICEDy~Xw9vjO7 z>|AyZ^8j(-AK(^}BBtc4x-cl|l{^EI{3kDlsqCELP^!0)F$+wC(AR>5PnLUuu(AimNBQ_dg-@b`YE|s@|C1K zD6D=n9r>T+w^I5on=aB>Ha);2N}exZrliX6a`^Ffk@im#YB#Tv`Q_UWKH2_C%I0O& zU9r~sxz$~fs;*ePx38*iUVT;lTz@Lzuj5%$xhN0nE=w<4%k*t*fH2vNd|!;0I@xc0 z=z&XLeSOO-Q-3<++dck*CFkBd`DT>{10!X(*M>_0H<*|$aC`Gl!uvv z|3hH8(wUSeopj<^SkR&&>C8Oaq@N{2>*pomW z-Qk`L(v|24bwxKvyE0HRkw}LkvDDQWXmhtrUqZaB(KxD-;Y7meu){6c73+?rQ>;7O z)s<*NO>z9T$(nYDV{z8g3u`K!?25)&M>O5`xd`itCX9UqZO`$q}o&N$WK4&iNQ(c|`=r}fbT$~YvPK@lJ!DA!( zmO5YcPLAOUX0UdNJ^tleaoW>a5;}z=3juvZL8@|bgkG0{QHoU}!_t@}K8{TKb)jlKhHXB}Ma8yun@WH>z>D-7%2XhYtt0AMozyISpU%2f)KK zk78RoHGmlDon#w2GK?_uH>A_8$k1V~|B`f_^Z~BFKsw!$3_Zg2ACpeE5JP*p{xs=y z>oBy3>)$7xZW)HQas7VM=~iK=hwJx{PPYg{o4EcB(&^SPpRT^;QI zAb9D-e^eGvHtcc*9g0AHAa-v#{aO{fguqZ#-Fv3I42 zd~F6jCD2NsJAwA^r()Bn6u=iVv?|K~`UBK>i~Em!=E}y6`}duLEE>1}ba?RL|3n3L z&DnP!05r{EsBiyra0|qTukV{LS^eh@Rv^8%pBmf*L*s|P+vl4WKw>6O;;-a$=U}rm zt+bimAk+52^Q37l(oVF$-ZYmd!(A6b`@_0NA5IsU|!>`i2yP1eKGdeUa? zB5N^OzYpt&zujj}7nSX=99&7ZcTtzYTgmqNzQIft=aTIuvTc>Ae#us%iDZ3(tQ%q7 z*M|(L_6M;K(8o>!8@i3G7nAjNSf%CnWcg1xx0g=6fs^TcQ2S0x|1Yiz_WvQc{phik zYnp2ZY7Yeu9t@P>@SpI&KQMN@-EZgb&!~HXyBA!JF>Y|T`w|lKPo^i})N(DH=+sg; ze57>hHp*zfl;BU}{0kJZRt+;GS%hJ%2mSxT6;>I^S6lNHyo7ZC%B*KA$#a zOo4X~o(0f@6ynZI(^#Mtm6(f5DjQ3Di%PtW z#h{Ib(H0nOfzcKiZGq7i7;S;k78q@T(H8i7Xn|vLUH5>Lbn8svQW;S?tx2OWMhI)2 zv|2lLQu+`aF>Rz4Cts({Inkj>)icLVIr$)QCOMf*EDUiGhDSckSSNJ0ZLRaP9BzbC0n#v!u zY`i|(Bp;JeT$kCgV^Y6N+GR5Te?qMA|ETg^5zmlCoY(vMp_DYB0~m3hCKqZLR+Te~npJQ#ZHfQ?>KWb5}(p zW-y$VhN`;R4)$DsEwSg+*456-V#821XEtkG*D$xIwyypHwrX7iR(r;2tlZJo=FEvL zTGtSc#}lowcuw=uD;jG0=0xghE~pQiet&gpODYoWNmXOrcy+inRuxaAqy9FwdS$~L zwz{dImNhMDn0FfDl4T85wWqN!ZA2O?TPU^Wh8h-IjZIb=V)0lS8S-poT%;+LEHYLE zr(0`1;|y(1xYl}iq+XsQ=$LVGnx#$2TpT9*$V4e~ zanyN;O$bma_ufFcf{lpizo@8(aC-}$CgCdB2Qkj;*1SI@T`w3U zp?UrVqF@y^#;l4Z+~U3!d$r(3f@Y833Q_KIV`(%ipmiL^c@q~9%j^C$H1C~=7t)g+ zr1T2K34n1eC9xB6*W~gzhYFs6C?@mE_?J-G3Yhm^h(ZDi)?nkVEdLC}3*qgaJpOvb zJ$q<#Oe=g8ax8G;-w|O&*B}}qY?i_dN``sbpnJY2_=_C2ULss4Y*#sKza_tRVcTli zD8{_6@q}qJOAzkJCV2h?y;{&jIrtn7c!(PfJya8j;S;p8# zqVs$wz5r73%(2UXcxk^DeE^`G(rj00GSAJximuYe5aC+oTgocN0oTU633m2W?VHDN z!S<~LqlE0^@uxoN`z{cZY@<3?JQ4pp`^>Ap+-LOt8D&p27 zp~{b;YSW7jK#ct!HfI-8Lwz0puMzYhoM#kLhE#=z3Hl8-GdV=vdI0}P(PWZovpAN5 z19h#*F{Yiv5&Z^v(5*sEuf|=2rmfX#nd@s3rnc4}kqYgRZwijS8O$|Wt)^XW6yfZn zKQB47J0G_=Og|!V+WRjH-1zd55S-!XWBLcuPMzkRjGehYmImr+ddau|s>0ZHP$s!} zDMbmW5t%+ynyE|A%Qhc|`66kiqv1-sxzM0xT|DTkB#92EUW>%^PKnc@x7&tqk@yL? z-)qC~miQFx!~+5^G-zp;$mS7grVjUS%1jHrcyK)_&D3f2LsH=#+RbZSXwdpE!98r} z9<^~VR9spSCb)0gxx+SYhvL!_F~Rkeix@A%WT{XYzN)yiW=wEr*tzp;+z}AY4I4 z2ojvZiikrAc9cv*des=ul+swj=ax>> z#&a*hDJ#=vmXsG8Q>RQ_TT!O@;5H5gf>XJy2yP0-TNU9MifT--KwdimPV_TbWiUm_ z8LP0E5-iik6$C1`^46&2B`+3L!6^u;7cC}gCdxS3j^U&(8Xvoe*AG4XOv?45N%0cV zuBhyO>~l9xp8trrrfDCSj3t4+NOzTpOobO?Rrqhf|7!d<VvKLLBcgo? z8=Wo=`aQIH6dU6iY+MIu^E2A~iZ*n`biIWQ?pIi$t}bN8c+KrD$1O~myW-bwx5r!I zuJ8czcxRRKFy8Iu`fcuFkG6h2EY%X}cb9lHKY(5fDD`OGac=KL0Q=og9u)DN?n0#D zJqq|%_c)&1UE~aXyY#)4=x*;%l;_j7RAhW-R*E8Z%Kj$8)5O5(u*IVYb53tI#(jeS zm8bXr1oOtzdrNb!dM#QnTyxoe%%m}2rH#whQv+;pmr`SOsJ6HYU@5gyhhBt!iV>>W zRQo9!I)1{i)2!-F_r{|OI->DtGS&t)oNVh{AYL-A+FWN=b(mEv>hNk}FYdSJh0-h) z+Zu(i-oqUEdZl_*GZcc$oH~nadx26;GlzP@=}snQks00&rKx*tdgG~BM;zm6y2ZDY zw$5;p;myua%z9xm)k(AY7K7*_u~0f3>ym}$CE#yf%9k#!qGw+E424>IV_lem4)M1$ zo$r!ju|b=ye3XxsNY3|A>5bLQyP@(mPElHNmalyx+0ClJ^fsuKX6Dt?5wC<=9JN|O zzGrITnU`CuI}_c}>d&?%_>?}qM^2>bXkWOyrz@IbUE$t%TW1w2fRT1}Zz@TYYCLkF zX9c19xfq2Tx4-g$LxZFMZ(*3}z{3a(VDTj^z2JZH#d#A~jRNVMJG$Yxn91*5i0undTagrDDJ%XDu_NJ4m3LbSr zb+LuoTGzstbl11FwRgE*(qGk~zp5W}b3pMeX>)AS*0`GP*R|EI`*rTWhWwv$0eH&w ziVOY#UU9ugzro;7T`fIxD z8fuo;^w)Jy54**M_!0dmagOSP#2M6&OU`lqq{aDIA12PQzTE(4yK%E2(z)6As-e>P zy74XSMAx^ByNPqR@sQ*^WISqdo;02z&NIe7;_NeCl$;lhpIe+)jMs?sn(;buUN?p$ zXUKTR;(TCyNSqIij|?=zN5;)ASBmQOfa_uE1`oR)bHVp9*FKjh=RVhdmn!EW*RRR= zN7wakZ6hBC(+v)V0(EE{zT0~4 zp3V2Lft>sTrk=}Z^SvzB^K63^vTX$cJC(-`R>aivbi2`D#Y{bS&&F{#FQ2Dn<71hb z6ECrzOl0#*nf1KTW-#dKq#D6w;bm;u^neW!Q3GFU=*x+hGc^xlcQUa5)%-^`J|Xjc z7n{Lg6Rr3BZ7{wHfcyPGzz*@a!7AC_ocJX6ot*gO5or)$Fg1IVZ8oqX>%L8aY>@NM z9DxyFu(R^uQ}f_v9(-CJe0m=I>^%645x54##oils8ZHK)*^U=e5`vJq_-pgvn}F-A zgsErGPwj>Wu4|&ZT z{8F9pk;er+ILnp(SMuQB2JS;T&g1C*Jp5+}*GHabew2s*avuDTdGL?&;A2r=DyQ>2 zFqyZ*$Of7XyiE5ouNlZP))Q_!AL7Xz56!@Hwc8bW@XrGGq2JyY2*?zKNaW$~BwWXN zTOJqc+E~u{CDxqMEScI~;FP{|zdR`U)gY+ zc}o+#FzOC92cjKsh1 zggRw^>?ssUB|@E8xlSK~YFPmm#)P5XR5X$)n)Osc3~#d&kH&3G=lDAm=?d}bWBL%3 zm?aMN#ORY#t*MkOk@yZ1Mv#eQR?1f8GGliE*&bblLim!E+WGW}tJ8nCD)WrNO5A!r zLS0K#+4kKk=1*X8gkVEUhRH$3db-lg&x`Hn?J?armq8-8HyQP%!y6vvK-g0n-VrMN;+OYXmrX zuk=^-$0Q36&hm$WV%ou~|A6!#kpAj>id07pf90>%NyUH>Rpqb7m51epU#;%~g$GK* z9%!n7)>bKhHU7MeGDJ9E2=OgV#1&7;Yk|>PEv2h*>Ne?LBmJG_moVFn2(_v5SL4}7 zr2i&Kbhe+WKi$8R|02m#<6fU^sM}?Q$-e@BXZzg^j3_F7<_kbWz)+Tgb0p{7|K9}1 z?r%zeQ~H}Sf1VgN61L=b9scTmD^MmpejxjS(_iTiIsDbQ{3ITLbV6pqNKtOP7gxD*DwN-vf>TtIEt8vd>>F?ZM z#I*-607^@hUyUQa^Edj_DhNtb(ygSG|3(WD5tYA^6A_`jo&Ky=@Gn+GnT}GGr0<}r zeM1!Wd?rvQ9O%2M_TX#}nkRQqIQ@n>!pm7MC-;&({*O!lbL@pfl1~41dHjFdAo8d2 zwLLgg7Rlqk<09eZTs!CV?~(q_dM;Zi{5_8Ihw@kQpYr&xY83wO*$a=j@>6n`^mou$ z(;|VKtvaS8C_lx&BaeT3vtX#}jN&`}Nq1C{Q@2U~fIQG<0i}Btb=;|R3xPR`$o&VF bbHRcRqceZHOgJdq(R;b@f5743P}zS0tuRa4 literal 0 HcmV?d00001 diff --git a/src/arch/src/x86_64/mod.rs b/src/arch/src/x86_64/mod.rs index e31046e81..388da8e61 100644 --- a/src/arch/src/x86_64/mod.rs +++ b/src/arch/src/x86_64/mod.rs @@ -242,12 +242,20 @@ pub fn configure_system( params.0.hdr.ramdisk_size = initrd_config.size as u32; } - #[cfg(feature = "tee")] + #[cfg(all(feature = "tee", not(feature = "intel-tdx")))] { params.0.hdr.syssize = num_cpus as u32; } - add_e820_entry(&mut params.0, 0, EBDA_START, E820_RAM)?; + #[cfg(feature = "intel-tdx")] + { + // number of 4k pages + params.0.hdr.syssize = (arch_memory_info.ram_last_addr / 4096) as u32; + // nuymber of vCPUs + params.0.hdr.root_flags = num_cpus as u16; + } + + add_e820_entry(&mut params.0, 0, EBDA_START - 0x10000 , E820_RAM)?; let last_addr = GuestAddress(arch_memory_info.ram_last_addr); if last_addr < end_32bit_gap_start { From 3044cf54168e0858a29c68770d19d42ead27a010 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 27 Feb 2025 13:40:49 -0500 Subject: [PATCH 12/40] change reset vector for TDX Signed-off-by: Jake Correnti --- src/arch/src/x86_64/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/arch/src/x86_64/mod.rs b/src/arch/src/x86_64/mod.rs index 388da8e61..c8352d8c9 100644 --- a/src/arch/src/x86_64/mod.rs +++ b/src/arch/src/x86_64/mod.rs @@ -51,7 +51,10 @@ pub enum Error { // Where BIOS/VGA magic would live on a real PC. const EBDA_START: u64 = 0x9fc00; +#[cfg(not(feature = "intel-tdx"))] pub const RESET_VECTOR: u64 = 0xfff0; +#[cfg(feature = "intel-tdx")] +pub const RESET_VECTOR: u64 = 0xffff_fff0; pub const RESET_VECTOR_SEV_AP: u64 = 0xfff3; pub const BIOS_START: u64 = 0xffff_0000; pub const BIOS_SIZE: usize = 65536; From 8c65fbd0527479df1b5e2b3b52316f58105a6ac5 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Tue, 17 Sep 2024 10:32:37 -0400 Subject: [PATCH 13/40] Implement `tdx_secure_virt_prepare` Implements the `tdx_secure_virt_prepare` method which in turn calls the `KVM_TDX_INIT_VM` TDX ioctl which does VM specific initialization. Signed-off-by: Jake Correnti --- src/vmm/src/builder.rs | 9 +++++++++ src/vmm/src/linux/tee/inteltdx.rs | 13 +++++++++++++ src/vmm/src/linux/vstate.rs | 19 +++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index 4db183c31..f050cee33 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -438,6 +438,15 @@ pub fn build_microvm( _ => None, }; + #[cfg(feature = "intel-tdx")] + let _ = match tee { + Tee::Tdx => Some( + vm.tdx_secure_virt_prepare() + .map_err(StartMicrovmError::SecureVirtPrepare)?, + ), + _ => None, + }; + #[cfg(feature = "tee")] let measured_regions = { println!("Injecting and measuring memory regions. This may take a while."); diff --git a/src/vmm/src/linux/tee/inteltdx.rs b/src/vmm/src/linux/tee/inteltdx.rs index 56d56b523..4d3d2a7f4 100644 --- a/src/vmm/src/linux/tee/inteltdx.rs +++ b/src/vmm/src/linux/tee/inteltdx.rs @@ -10,6 +10,7 @@ use std::io; pub enum Error { CreateTdxVmStruct, GetCapabilities, + InitVm, OpenTdvfFirmwareFile(io::Error), ParseTdvfSections(tdvf::Error), } @@ -41,4 +42,16 @@ impl IntelTdx { tdvf_file: firmware, }) } + + pub fn vm_prepare( + &self, + fd: &kvm_ioctls::VmFd, + cpuid: kvm_bindings::CpuId, + ) -> Result<(), Error> { + self.vm + .init_vm(fd, cpuid) + .or_else(|_| return Err(Error::InitVm))?; + + Ok(()) + } } diff --git a/src/vmm/src/linux/vstate.rs b/src/vmm/src/linux/vstate.rs index 2790e295c..cc7241f2a 100644 --- a/src/vmm/src/linux/vstate.rs +++ b/src/vmm/src/linux/vstate.rs @@ -133,6 +133,9 @@ pub enum Error { #[cfg(feature = "intel-tdx")] /// Error initializing the Trust Domain Extensions Backend (TDX) TdxSecVirtInit(TdxError), + #[cfg(feature = "intel-tdx")] + /// Error preparing the VM for Trust Domain Extensions (TDX) + TdxSecVirtPrepare(TdxError), #[cfg(feature = "tee")] /// The TEE specified is not supported. InvalidTee, @@ -302,6 +305,11 @@ impl Display for Error { f, "Error initializing the Trust Domain Extensions Backend (TDX): {e:?}" ), + #[cfg(feature = "intel-tdx")] + TdxSecVirtPrepare(e) => write!( + f, + "Error preparing the VM for Trust Domain Extensions (TDX): {e:?}" + ), #[cfg(feature = "tee")] MissingTeeConfig => write!(f, "Missing TEE configuration"), #[cfg(target_arch = "x86_64")] @@ -656,6 +664,17 @@ impl Vm { Ok(()) } + #[cfg(feature = "intel-tdx")] + pub fn tdx_secure_virt_prepare(&self) -> Result<()> { + match &self.tdx { + // FIXME(jakecorrenti): before we call KVM_TDX_INIT_VM, we should be modifying the CPUId based on TDX restrictions + Some(t) => t + .vm_prepare(&self.fd, self.supported_cpuid.clone()) + .map_err(Error::TdxSecVirtPrepare), + None => Err(Error::InvalidTee), + } + } + #[cfg(feature = "amd-sev")] pub fn snp_secure_virt_prepare( &self, From fd8d51eeb54f3aa47c4691b7c1f45b31f2788c15 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 27 Feb 2025 13:58:38 -0500 Subject: [PATCH 14/40] Change measured regions for TDX Signed-off-by: Jake Correnti --- src/vmm/src/builder.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index f050cee33..067fa122b 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -447,7 +447,11 @@ pub fn build_microvm( _ => None, }; - #[cfg(feature = "tee")] + // TODO(jakecorrenti): this shouldn't be pointing to something in Sergio's user + let qboot_file = std::fs::File::open("/home/slp/src/qboot-krunfw/build/bios.bin").unwrap(); + let qboot_size = qboot_file.metadata().unwrap().len(); + + #[cfg(all(feature = "tee", not(feature = "intel-tdx")))] let measured_regions = { println!("Injecting and measuring memory regions. This may take a while."); @@ -485,6 +489,25 @@ pub fn build_microvm( m }; + #[cfg(feature = "intel-tdx")] + let measured_regions = { + println!("Injecting and measuring memory regions. This may take a while."); + let m = vec![ + MeasuredRegion { + guest_addr: 0, + host_addr: guest_memory.get_host_address(GuestAddress(0)).unwrap() as u64, + size: 0x8000_0000, + }, + MeasuredRegion { + guest_addr: arch::BIOS_START, + host_addr: guest_memory.get_host_address(GuestAddress(arch::BIOS_START)).unwrap() as u64, + size: qboot_size as usize, + }, + ]; + + m + }; + // On x86_64 always create a serial device, // while on aarch64 only create it if 'console=' is specified in the boot args. let serial_device = if cfg!(feature = "efi") { From 3a3ac1c05883c1648859916f75e4573f4da7500c Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 27 Feb 2025 14:04:59 -0500 Subject: [PATCH 15/40] update how qboot is written to memory Signed-off-by: Jake Correnti --- src/vmm/src/builder.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index 067fa122b..8d70c6f90 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -809,8 +809,8 @@ fn load_payload( kernel_region, kernel_load_addr, kernel_size, - qboot_host_addr, - qboot_size, + _qboot_host_addr, + _qboot_size, initrd_host_addr, initrd_size, ) => { @@ -820,11 +820,13 @@ fn load_payload( .write(kernel_data, GuestAddress(kernel_load_addr)) .unwrap(); - let qboot_data = - unsafe { std::slice::from_raw_parts(qboot_host_addr as *mut u8, qboot_size) }; - guest_mem - .write(qboot_data, GuestAddress(arch::BIOS_START)) - .unwrap(); + let mut qboot_file = std::fs::File::open("/home/slp/src/qboot-krunfw/build/bios.bin").unwrap(); + let qboot_size = qboot_file.metadata().unwrap().len(); + guest_mem.read_exact_volatile_from( + GuestAddress(arch::BIOS_START), + &mut qboot_file, + qboot_size as usize, + ).unwrap(); let initrd_data = unsafe { std::slice::from_raw_parts(initrd_host_addr as *mut u8, initrd_size) }; From 6f28cfcb83050cd19334779eecfea25331ee69d4 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 27 Feb 2025 14:33:11 -0500 Subject: [PATCH 16/40] update CPUID for vcpu on TDX Signed-off-by: Jake Correnti --- src/cpuid/src/transformer/intel.rs | 47 ++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/cpuid/src/transformer/intel.rs b/src/cpuid/src/transformer/intel.rs index bd0de741a..b727055dc 100644 --- a/src/cpuid/src/transformer/intel.rs +++ b/src/cpuid/src/transformer/intel.rs @@ -17,11 +17,56 @@ pub fn update_feature_info_entry( common::update_feature_info_entry(entry, vm_spec)?; + if entry.index == 0x1 { + println!("adjusting 0x1 index feature"); + entry.ecx &= (1 << 21); + } + entry.ecx.write_bit(ecx::TSC_DEADLINE_TIMER_BITINDEX, true); Ok(()) } +pub fn update_kvm_features( + entry: &mut kvm_cpuid_entry2, + vm_spec: &VmSpec, +) -> Result<(), Error> { + // KVM feature bits + const NOP_IO_RELAY: u32 = 1; + const PV_UNHALT: u32 = 1; + const PV_TLB_FLUSH: u32 = 9; + const PV_SEND_IPI: u32 = 11; + const POLL_CONTROL: u32 = 12; + const PV_SCHED_YIELD: u32 = 13; + const MSI_EXT_DEST_ID: u32 = 15; + + // These features are not supported by TDX + entry.eax &= (1 << NOP_IO_RELAY) | (1 << PV_UNHALT) | (1 << PV_TLB_FLUSH) | (1 << PV_SEND_IPI) | (1 << POLL_CONTROL) | (1 << PV_SCHED_YIELD) | (1 << MSI_EXT_DEST_ID); + Ok(()) +} + +pub fn update_0xd_for_tdx( + entry: &mut kvm_cpuid_entry2, + vm_spec: &VmSpec, +) -> Result<(), Error> { + if entry.function == 0xD && entry.index == 0 { + const XFEATURE_MASK_XTILE: u32 = (1 << 17) | (1 << 18); + if (entry.eax & XFEATURE_MASK_XTILE) != XFEATURE_MASK_XTILE { + entry.eax &= !XFEATURE_MASK_XTILE; + } + } + + if entry.function == 0xD && entry.index == 1 { + entry.ecx &= !(1 << 15); + const XFEATURE_MASK_CET: u32 = (1 << 11) | (1 << 12); + if entry.ecx & XFEATURE_MASK_CET > 0 { + entry.ecx |= XFEATURE_MASK_CET; + } + } + + Ok(()) +} + fn update_deterministic_cache_entry( entry: &mut kvm_cpuid_entry2, vm_spec: &VmSpec, @@ -146,6 +191,8 @@ impl CpuidTransformer for IntelCpuidTransformer { leaf_0x6::LEAF_NUM => Some(intel::update_power_management_entry), leaf_0xa::LEAF_NUM => Some(intel::update_perf_mon_entry), leaf_0xb::LEAF_NUM => Some(intel::update_extended_cache_topology_entry), + leaf_0xd::LEAF_NUM => Some(intel::update_0xd_for_tdx), + 0x4000_0001 => Some(intel::update_kvm_features), 0x8000_0002..=0x8000_0004 => Some(common::update_brand_string_entry), _ => None, } From 0b0a24cab8187c1b30a04514a733ad8f25db1c45 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 27 Feb 2025 14:45:03 -0500 Subject: [PATCH 17/40] init tdx vcpu Signed-off-by: Jake Correnti --- src/vmm/src/builder.rs | 3 +++ src/vmm/src/linux/vstate.rs | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index 8d70c6f90..e04942cb3 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -1113,6 +1113,9 @@ fn create_vcpus_x86_64( vcpu.configure_x86_64(guest_mem, entry_addr, vcpu_config) .map_err(Error::Vcpu)?; + #[cfg(feature = "intel-tdx")] + vcpu.tdx_secure_virt_init().map_err(Error::Vcpu)?; + vcpus.push(vcpu); } Ok(vcpus) diff --git a/src/vmm/src/linux/vstate.rs b/src/vmm/src/linux/vstate.rs index cc7241f2a..8459ed091 100644 --- a/src/vmm/src/linux/vstate.rs +++ b/src/vmm/src/linux/vstate.rs @@ -136,6 +136,9 @@ pub enum Error { #[cfg(feature = "intel-tdx")] /// Error preparing the VM for Trust Domain Extensions (TDX) TdxSecVirtPrepare(TdxError), + #[cfg(feature = "intel-tdx")] + /// Error initializing vCPU for Trust Domain Extensions (TDX) + TdxSecVirtInitVcpu, #[cfg(feature = "tee")] /// The TEE specified is not supported. InvalidTee, @@ -310,6 +313,11 @@ impl Display for Error { f, "Error preparing the VM for Trust Domain Extensions (TDX): {e:?}" ), + #[cfg(feature = "intel-tdx")] + TdxSecVirtInitVcpu => write!( + f, + "Error initializing vCPU for Trust Domain Extensions (TDX)" + ), #[cfg(feature = "tee")] MissingTeeConfig => write!(f, "Missing TEE configuration"), #[cfg(target_arch = "x86_64")] @@ -1443,6 +1451,11 @@ impl Vcpu { StateMachine::finish() } + #[cfg(feature = "intel-tdx")] + pub fn tdx_secure_virt_init(&self) -> Result<()> { + tdx::launch::TdxVcpu::init_raw(&self.fd, 0).or_else(|_| return Err(Error::TdxSecVirtInitVcpu)) + } + #[cfg(test)] // In tests the main/vmm thread exits without 'exit()'ing the whole process. // All channels get closed on the other side while this Vcpu thread is still running. From 9acdc260fc3feed1f05fea57c19f1140b947dd42 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 27 Feb 2025 16:17:51 -0500 Subject: [PATCH 18/40] init memory regions for tdx Signed-off-by: Jake Correnti --- src/vmm/src/builder.rs | 6 ++++++ src/vmm/src/linux/tee/inteltdx.rs | 21 +++++++++++++++++++++ src/vmm/src/linux/vstate.rs | 8 ++++++++ 3 files changed, 35 insertions(+) diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index e04942cb3..ab82341b2 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -761,6 +761,12 @@ pub fn build_microvm( ) .map_err(StartMicrovmError::SecureVirtAttest)?; } + #[cfg(feature = "intel-tdx")] + Tee::Tdx => { + vmm.kvm_vm() + .tdx_secure_virt_prepare_memory(&measured_regions) + .map_err(StartMicrovmError::SecureVirtPrepare)?; + } _ => return Err(StartMicrovmError::InvalidTee), } diff --git a/src/vmm/src/linux/tee/inteltdx.rs b/src/vmm/src/linux/tee/inteltdx.rs index 4d3d2a7f4..e4e4bc55c 100644 --- a/src/vmm/src/linux/tee/inteltdx.rs +++ b/src/vmm/src/linux/tee/inteltdx.rs @@ -54,4 +54,25 @@ impl IntelTdx { Ok(()) } + + pub fn configure_td_memory(&self, fd: &kvm_ioctls::VmFd, regions: &Vec) -> Result<(), Error> { + for region in regions { + let ext = if arch::BIOS_START == region.guest_addr { + 1 + } else { + 0 + }; + + match self.vm.init_mem_region(fd, region.guest_addr, (region.size / 4096) as u64, ext, region.host_addr) { + Err(e) => if e.code == 11 { + // continue + } else { + panic!("error: {:#?}", e) + }, + _ => (), + } + } + + Ok(()) + } } diff --git a/src/vmm/src/linux/vstate.rs b/src/vmm/src/linux/vstate.rs index 8459ed091..04080f001 100644 --- a/src/vmm/src/linux/vstate.rs +++ b/src/vmm/src/linux/vstate.rs @@ -683,6 +683,14 @@ impl Vm { } } + #[cfg(feature = "intel-tdx")] + pub fn tdx_secure_virt_prepare_memory(&self, regions: &Vec) -> Result<()> { + match &self.tdx { + Some(t) => t.configure_td_memory(&self.fd, ®ions).map_err(Error::TdxSecVirtPrepare), + None => Err(Error::InvalidTee), + } + } + #[cfg(feature = "amd-sev")] pub fn snp_secure_virt_prepare( &self, From 657a0a34cba6459c66db39654f2851a329c83db1 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 27 Feb 2025 17:03:47 -0500 Subject: [PATCH 19/40] finalize vm for tdx Signed-off-by: Jake Correnti --- src/vmm/src/builder.rs | 3 +++ src/vmm/src/linux/tee/inteltdx.rs | 5 +++++ src/vmm/src/linux/vstate.rs | 8 ++++++++ 3 files changed, 16 insertions(+) diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index ab82341b2..5856d07db 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -766,6 +766,9 @@ pub fn build_microvm( vmm.kvm_vm() .tdx_secure_virt_prepare_memory(&measured_regions) .map_err(StartMicrovmError::SecureVirtPrepare)?; + vmm.kvm_vm() + .tdx_secure_virt_finalize_vm() + .map_err(StartMicrovmError::SecureVirtPrepare)?; } _ => return Err(StartMicrovmError::InvalidTee), } diff --git a/src/vmm/src/linux/tee/inteltdx.rs b/src/vmm/src/linux/tee/inteltdx.rs index e4e4bc55c..feeda9711 100644 --- a/src/vmm/src/linux/tee/inteltdx.rs +++ b/src/vmm/src/linux/tee/inteltdx.rs @@ -13,6 +13,7 @@ pub enum Error { InitVm, OpenTdvfFirmwareFile(io::Error), ParseTdvfSections(tdvf::Error), + FinalizeVm, } pub struct IntelTdx { @@ -75,4 +76,8 @@ impl IntelTdx { Ok(()) } + + pub fn finalize_vm(&self, fd: &kvm_ioctls::VmFd) -> Result<(), Error> { + self.vm.finalize(fd).or_else(|_| return Err(Error::FinalizeVm)) + } } diff --git a/src/vmm/src/linux/vstate.rs b/src/vmm/src/linux/vstate.rs index 04080f001..b7a880736 100644 --- a/src/vmm/src/linux/vstate.rs +++ b/src/vmm/src/linux/vstate.rs @@ -691,6 +691,14 @@ impl Vm { } } + #[cfg(feature = "intel-tdx")] + pub fn tdx_secure_virt_finalize_vm(&self) -> Result<()> { + match &self.tdx { + Some(t) => t.finalize_vm(&self.fd).map_err(Error::TdxSecVirtPrepare), + None => Err(Error::InvalidTee), + } + } + #[cfg(feature = "amd-sev")] pub fn snp_secure_virt_prepare( &self, From fe1dadfc721dc87dd51a092eecbf681b344b963e Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 27 Feb 2025 17:06:04 -0500 Subject: [PATCH 20/40] add serial device to TDX or else it hangs Signed-off-by: Jake Correnti --- src/vmm/src/builder.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index 5856d07db..5db082d8e 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -510,13 +510,13 @@ pub fn build_microvm( // On x86_64 always create a serial device, // while on aarch64 only create it if 'console=' is specified in the boot args. - let serial_device = if cfg!(feature = "efi") { + let serial_device = if cfg!(any(feature = "efi", feature = "intel-tdx")) { Some(setup_serial_device( event_manager, None, - None, + // None, // Uncomment this to get EFI output when debugging EDK2. - // Some(Box::new(io::stdout())), + Some(Box::new(io::stdout())), )?) } else { None From 636812347996f0f94f72648879a3589117f8988c Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 27 Feb 2025 17:15:50 -0500 Subject: [PATCH 21/40] introduce support for TDX vCPU exit reason Signed-off-by: Jake Correnti --- src/vmm/src/linux/vstate.rs | 52 +++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/vmm/src/linux/vstate.rs b/src/vmm/src/linux/vstate.rs index b7a880736..30d8a49f7 100644 --- a/src/vmm/src/linux/vstate.rs +++ b/src/vmm/src/linux/vstate.rs @@ -63,6 +63,16 @@ use sev::launch::snp; /// Signal number (SIGRTMIN) used to kick Vcpus. pub(crate) const VCPU_RTSIG_OFFSET: i32 = 0; +const TDG_VP_VMCALL_MAP_GPA: u64 = 0x10001; +const TDG_VP_VMCALL_GET_QUOTE: u64 = 0x10002; +const TDG_VP_VMCALL_REPORT_FATAL_ERROR: u64 = 0x10003; +const TDG_VP_VMCALL_SETUP_EVENT_NOTIFY_INTERRUPT: u64 = 0x10004; +const TDG_VP_VMCALL_SUCCESS: u64 = 0x0000000000000000; +const TDG_VP_VMCALL_RETRY: u64 = 0x0000000000000001; +const TDG_VP_VMCALL_INVALID_OPERAND: u64 = 0x8000000000000000; +const TDG_VP_VMCALL_GPA_INUSE: u64 = 0x8000000000000001; +const TDG_VP_VMCALL_ALIGN_ERROR: u64 = 0x8000000000000002; + /// Errors associated with the wrappers over KVM ioctls. #[derive(Debug)] pub enum Error { @@ -1325,6 +1335,48 @@ impl Vcpu { error!("Received KVM_EXIT_INTERNAL_ERROR signal"); Err(Error::VcpuUnhandledKvmExit) } + VcpuExit::Tdx => { + let kvm_run = self.fd.get_kvm_run(); + let tdx = unsafe { &mut kvm_run.__bindgen_anon_1.tdx }; + + const KVM_EXIT_TDX_VMCALL: u32 = 1; + + // check if the exit type is KVM_EXIT_TDX_VMCALL + if tdx.type_ != KVM_EXIT_TDX_VMCALL { + println!("unknown tdx exit type 0x{:x}", tdx.type_); + return Err(Error::VcpuUnhandledKvmExit); + } + + // handle the vmcall + let mut vmcall = unsafe { tdx.u.vmcall }; + unsafe { + vmcall.__bindgen_anon_4.status_code = TDG_VP_VMCALL_INVALID_OPERAND; + + if vmcall.__bindgen_anon_2.type_ != 0 { + println!("unknown TDG.VP.VMCALL type 0x{:x} subfunction 0x{:x}", vmcall.__bindgen_anon_2.type_, vmcall.__bindgen_anon_3.subfunction); + return Err(Error::VcpuUnhandledKvmExit); + } + + match vmcall.__bindgen_anon_3.subfunction { + TDG_VP_VMCALL_MAP_GPA => { + return Ok(VcpuEmulation::Handled); + } + TDG_VP_VMCALL_GET_QUOTE => { + return Ok(VcpuEmulation::Handled); + }, + TDG_VP_VMCALL_REPORT_FATAL_ERROR => { + return Err(Error::VcpuUnhandledKvmExit); + }, + TDG_VP_VMCALL_SETUP_EVENT_NOTIFY_INTERRUPT => { + return Ok(VcpuEmulation::Handled); + }, + _ => { + println!("unknown TDG.VP.VMCALL type 0x{:x} subfunction 0x{:x}", vmcall.__bindgen_anon_2.type_, vmcall.__bindgen_anon_3.subfunction); + return Err(Error::VcpuUnhandledKvmExit); + } + } + } + } r => { // TODO: Are we sure we want to finish running a vcpu upon // receiving a vm exit that is not necessarily an error? From 7e7acfa1576fa74ed53e1f77ea249599c2b08174 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 27 Feb 2025 17:20:23 -0500 Subject: [PATCH 22/40] implement TDG_VP_VMCALL_REPORT_FATAL_ERROR handler Signed-off-by: Jake Correnti --- src/vmm/src/linux/vstate.rs | 43 +++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/vmm/src/linux/vstate.rs b/src/vmm/src/linux/vstate.rs index 30d8a49f7..0f5861e94 100644 --- a/src/vmm/src/linux/vstate.rs +++ b/src/vmm/src/linux/vstate.rs @@ -1365,6 +1365,7 @@ impl Vcpu { return Ok(VcpuEmulation::Handled); }, TDG_VP_VMCALL_REPORT_FATAL_ERROR => { + let _ = Self::tdx_handle_report_fatal_error(&mut vmcall); return Err(Error::VcpuUnhandledKvmExit); }, TDG_VP_VMCALL_SETUP_EVENT_NOTIFY_INTERRUPT => { @@ -1403,6 +1404,48 @@ impl Vcpu { } } + unsafe fn tdx_handle_report_fatal_error(vmcall: &mut kvm_bindings::kvm_tdx_exit__bindgen_ty_1_kvm_tdx_vmcall) -> i32 { + const GUEST_PANIC_INFO_TDX_MESSAGE_MAX: usize = 64; + let error_code = vmcall.in_r12; + // This is supposed to be initialized to -1... is 0 going to be ok here? + let mut gpa: u64 = 0; + + if (error_code & 0xffff) > 0 { + println!("TDX: REPORT_FATAL_ERROR: invalid error code: 0x{:x}", error_code); + return -1; + } + + let mut message = [char::default(); GUEST_PANIC_INFO_TDX_MESSAGE_MAX + 1]; + + // it has optional message + if vmcall.in_r14 > 0 { + message[1] = char::from_u32(u64::to_le(vmcall.in_r14) as u32).unwrap(); + message[2] = char::from_u32(u64::to_le(vmcall.in_r15) as u32).unwrap(); + message[3] = char::from_u32(u64::to_le(vmcall.in_rbx) as u32).unwrap(); + message[4] = char::from_u32(u64::to_le(vmcall.in_rdi) as u32).unwrap(); + message[5] = char::from_u32(u64::to_le(vmcall.in_rsi) as u32).unwrap(); + message[6] = char::from_u32(u64::to_le(vmcall.in_r8) as u32).unwrap(); + message[7] = char::from_u32(u64::to_le(vmcall.in_r9) as u32).unwrap(); + message[8] = char::from_u32(u64::to_le(vmcall.in_rdx) as u32).unwrap(); + message[GUEST_PANIC_INFO_TDX_MESSAGE_MAX] = '\0'; + } + + const TDX_REPORT_FATAL_ERROR_GPA_VALID: u64 = 1 << 63; + if (error_code & TDX_REPORT_FATAL_ERROR_GPA_VALID) > 0 { + gpa = vmcall.in_r13; + } + + let message = { + let mut s = String::new(); + message.iter_mut().for_each(|c| s.push(*c)); + s + }; + + println!("TDX: REPORT_FATAL_ERROR: message: {} error_code: {} gpa: 0x{:x}", message, error_code, gpa); + + -1 + } + /// Main loop of the vCPU thread. /// /// Runs the vCPU in KVM context in a loop. Handles KVM_EXITs then goes back in. From 77caaf53ddfafc121778024f97b22e17e0d2c06e Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 27 Feb 2025 17:24:31 -0500 Subject: [PATCH 23/40] add TDG_VP_VMCALL_SETUP_EVENT_NOTIFY_INTERRUPT handler Signed-off-by: Jake Correnti --- src/vmm/src/linux/vstate.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/vmm/src/linux/vstate.rs b/src/vmm/src/linux/vstate.rs index 0f5861e94..774c9f5c1 100644 --- a/src/vmm/src/linux/vstate.rs +++ b/src/vmm/src/linux/vstate.rs @@ -1369,6 +1369,7 @@ impl Vcpu { return Err(Error::VcpuUnhandledKvmExit); }, TDG_VP_VMCALL_SETUP_EVENT_NOTIFY_INTERRUPT => { + let _ = Self::tdx_handle_setup_event_notify_interrupt(&mut vmcall); return Ok(VcpuEmulation::Handled); }, _ => { @@ -1404,6 +1405,20 @@ impl Vcpu { } } + unsafe fn tdx_handle_setup_event_notify_interrupt(vmcall: &mut kvm_bindings::kvm_tdx_exit__bindgen_ty_1_kvm_tdx_vmcall) -> i32 { + let vector = vmcall.in_r12; + + if 32 <= vector && vector >= 255 { + // normally this is where we would update the runtime state + // with the vector and the apic_id of the cpu + vmcall.__bindgen_anon_4.status_code = TDG_VP_VMCALL_SUCCESS; + } else { + vmcall.__bindgen_anon_4.status_code = TDG_VP_VMCALL_INVALID_OPERAND; + } + + 0 + } + unsafe fn tdx_handle_report_fatal_error(vmcall: &mut kvm_bindings::kvm_tdx_exit__bindgen_ty_1_kvm_tdx_vmcall) -> i32 { const GUEST_PANIC_INFO_TDX_MESSAGE_MAX: usize = 64; let error_code = vmcall.in_r12; From 5418aec2e880baea46fe24289c2e87e2b097fb00 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Fri, 28 Feb 2025 11:47:41 -0500 Subject: [PATCH 24/40] keep track of guest memfd regions in vmm Signed-off-by: Jake Correnti --- src/vmm/src/builder.rs | 8 ++++++-- src/vmm/src/lib.rs | 5 +++++ src/vmm/src/linux/vstate.rs | 3 +++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index 5db082d8e..00f3a1142 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -355,6 +355,8 @@ pub fn build_microvm( _shutdown_efd: Option, #[cfg(target_os = "macos")] _map_sender: Sender, ) -> std::result::Result>, StartMicrovmError> { + let mut guest_memfd_regions: Vec<(vm_memory::GuestAddress, u64, u64)> = vec![]; + #[cfg(not(feature = "efi"))] let kernel_bundle = vm_resources .kernel_bundle() @@ -422,7 +424,7 @@ pub fn build_microvm( let kvm = KvmContext::new() .map_err(Error::KvmContext) .map_err(StartMicrovmError::Internal)?; - let vm = setup_vm(&kvm, &guest_memory, vm_resources.tee_config())?; + let vm = setup_vm(&kvm, &guest_memory, vm_resources.tee_config(), &mut guest_memfd_regions)?; (kvm, vm) }; @@ -639,6 +641,7 @@ pub fn build_microvm( let mut vmm = Vmm { guest_memory, + guest_memfd_regions, arch_memory_info, kernel_cmdline, vcpus_handles: Vec::new(), @@ -945,11 +948,12 @@ pub(crate) fn setup_vm( kvm: &KvmContext, guest_memory: &GuestMemoryMmap, tee_config: &TeeConfig, + guest_memfd_regions: &mut Vec<(vm_memory::GuestAddress, u64, u64)>, ) -> std::result::Result { let mut vm = Vm::new(kvm.fd(), tee_config) .map_err(Error::Vm) .map_err(StartMicrovmError::Internal)?; - vm.memory_init(guest_memory, kvm.max_memslots()) + vm.memory_init(guest_memory, kvm.max_memslots(), guest_memfd_regions) .map_err(Error::Vm) .map_err(StartMicrovmError::Internal)?; Ok(vm) diff --git a/src/vmm/src/lib.rs b/src/vmm/src/lib.rs index 0e680a846..011ab7d2c 100644 --- a/src/vmm/src/lib.rs +++ b/src/vmm/src/lib.rs @@ -186,6 +186,7 @@ pub type Result = std::result::Result; pub struct Vmm { // Guest VM core resources. guest_memory: GuestMemoryMmap, + guest_memfd_regions: Vec<(vm_memory::GuestAddress, u64, u64)>, arch_memory_info: ArchMemoryInfo, kernel_cmdline: KernelCmdline, @@ -322,6 +323,10 @@ impl Vmm { &self.guest_memory } + pub fn guest_memfd_regions(&self) -> &Vec<(vm_memory::GuestAddress, u64, u64)> { + &self.guest_memfd_regions + } + /// Injects CTRL+ALT+DEL keystroke combo in the i8042 device. #[cfg(target_arch = "x86_64")] pub fn send_ctrl_alt_del(&mut self) -> Result<()> { diff --git a/src/vmm/src/linux/vstate.rs b/src/vmm/src/linux/vstate.rs index 774c9f5c1..af5f53dcc 100644 --- a/src/vmm/src/linux/vstate.rs +++ b/src/vmm/src/linux/vstate.rs @@ -599,6 +599,7 @@ impl Vm { &mut self, guest_mem: &GuestMemoryMmap, kvm_max_memslots: usize, + guest_memfd_regions: &mut Vec<(vm_memory::GuestAddress, u64, u64)>, ) -> Result<()> { if guest_mem.num_regions() > kvm_max_memslots { return Err(Error::NotEnoughMemorySlots); @@ -652,6 +653,8 @@ impl Vm { self.fd .set_memory_attributes(attr) .map_err(Error::SetMemoryAttributes)?; + + guest_memfd_regions.push((region.start_addr(), region.len(), gmem as u64)); } #[cfg(not(feature = "intel-tdx"))] From 2b05f41fd068a4638e3efc25b41809107e2a653e Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Fri, 28 Feb 2025 11:55:40 -0500 Subject: [PATCH 25/40] add Vmm::vm_fd() Signed-off-by: Jake Correnti --- src/vmm/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vmm/src/lib.rs b/src/vmm/src/lib.rs index 011ab7d2c..6deab7003 100644 --- a/src/vmm/src/lib.rs +++ b/src/vmm/src/lib.rs @@ -327,6 +327,10 @@ impl Vmm { &self.guest_memfd_regions } + pub fn vm_fd(&self) -> &kvm_ioctls::VmFd { + &self.vm.fd() + } + /// Injects CTRL+ALT+DEL keystroke combo in the i8042 device. #[cfg(target_arch = "x86_64")] pub fn send_ctrl_alt_del(&mut self) -> Result<()> { From 6686e411c9c15c0400575816f0d31ca5f4f76ab5 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Fri, 28 Feb 2025 12:03:45 -0500 Subject: [PATCH 26/40] add convert_memory() Signed-off-by: Jake Correnti --- src/libkrun/src/lib.rs | 119 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 1 deletion(-) diff --git a/src/libkrun/src/lib.rs b/src/libkrun/src/lib.rs index 766ebed84..ae25988e7 100644 --- a/src/libkrun/src/lib.rs +++ b/src/libkrun/src/lib.rs @@ -14,7 +14,18 @@ use std::os::fd::RawFd; use std::path::PathBuf; use std::slice; use std::sync::atomic::{AtomicI32, Ordering}; -use std::sync::Mutex; +use std::sync::{Arc, Mutex}; + +use vm_memory::{Address, GuestAddress, GuestMemory}; + +use libc::{ + fallocate, + madvise, + FALLOC_FL_KEEP_SIZE, + FALLOC_FL_PUNCH_HOLE, + MADV_DONTNEED, + MADV_REMOVE, +}; #[cfg(target_os = "macos")] use crossbeam_channel::unbounded; @@ -1283,3 +1294,109 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 { } } } + +// FIXME(jakecorrenti): this should return an option for the guestmemfd id +fn has_guest_memory(gpa: u64, size: u64, memfd_regions: &Vec<(vm_memory::GuestAddress, u64, u64)>) -> (bool, i64) { + for (a, s, i) in memfd_regions.iter() { + if gpa >= a.0 && gpa + size <= a.0 + *s { + return (true, *i as i64); + } + } + (false, -1) +} + +fn convert_memory(vmm: &Arc>, gpa: u64, size: u64, to_private: bool) -> i32 { + let mut ret = -1; + let vmm = vmm.as_ref().lock().unwrap(); + let guest_memfd_regions = vmm.guest_memfd_regions(); + + let page_size = 4096; + + // check to make sure the starting address is aligned with the page size + // check to make sure the size of the memory block is also aligned with the page size + if (gpa % page_size) != 0 || (size % page_size) != 0 { + return -1; + } + + // if size is non-positive then return -1 + if size < 1 { + return -1; + } + + let region = vmm.guest_memory().find_region(GuestAddress(gpa)); + if let None = region { + // ignore converting non-assigned region to shared + // + // TDX requires vMMIO region to be shared to inject #VE to guest. OVMF issues + // conservatively MapGPA(shared) on 32bit PCI MMIO region, and vIO-APIC 0xFEC 4k page. OVMF + // assignes 32bit PCI MMIO region to [top of low memory: typically 2GB=0xC0000000, + // 0xFC000000) + if !to_private { + return 0; + } + + return -1; + } + let region = region.unwrap(); + + // retrive the memory region associated with the starting address and the size + let (region_has_guest_memfd, memfd_id) = has_guest_memory(gpa, size, guest_memfd_regions); + + // check to make sure there is a guest memfd backing + if !region_has_guest_memfd { + println!("cannot convert non guest_memfd backed memory region"); + return -1; + } + + // set the memory attributes to the desired value + let attr = kvm_bindings::kvm_memory_attributes { + address: gpa, + size, + attributes: if to_private { + // KVM_MEMORY_ATTRIBUTE_PRIVATE, + 1 << 3 } else { 0 }, + flags: 0, + }; + + vmm.vm_fd().set_memory_attributes(attr).unwrap(); + + use vm_memory::GuestMemoryRegion; + + let offset = gpa - region.start_addr().raw_value(); + if to_private { + // ram_block_discard_range + let host_addr = region.get_host_address(vm_memory::MemoryRegionAddress(gpa)).unwrap(); + + // let host_addr = gpa + offset; + unsafe { + let _ret = madvise( + host_addr as *mut libc::c_void, + size.try_into().unwrap(), + // madv_remove, + MADV_DONTNEED, + ); + + if _ret < 0 { + println!("error discarding memory range: gpa: 0x{:x} size: 0x{:x} res: {}", gpa, size, std::io::Error::last_os_error()); + return _ret; + } + } + } else { + // ram_block_discard_guest_memfd_range + unsafe { + let _ret = fallocate( + memfd_id as i32, + FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, + offset as i64, + size as i64, + ); + + if _ret < 0 { + println!("error discarding guest memfd memory range: {}", std::io::Error::last_os_error()); + return _ret; + } + } + } + + 0 +} From 311e0fd88ab447ee4e715293f65f01cb359d0990 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Fri, 28 Feb 2025 13:37:20 -0500 Subject: [PATCH 27/40] setup thread that when sent a GPA, length, and to_private, will convert the memory page accordingly Signed-off-by: Jake Correnti --- src/libkrun/src/lib.rs | 22 +++++++++++++++++++--- src/vmm/src/builder.rs | 5 +++++ src/vmm/src/linux/vstate.rs | 4 ++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/libkrun/src/lib.rs b/src/libkrun/src/lib.rs index ae25988e7..3032152ec 100644 --- a/src/libkrun/src/lib.rs +++ b/src/libkrun/src/lib.rs @@ -1246,14 +1246,17 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 { ctx_cfg.vmr.set_console_output(console_output); } - #[cfg(target_os = "macos")] - let (sender, receiver) = unbounded(); + // #[cfg(target_os = "macos")] + // let (sender, receiver) = unbounded(); + + let (sender, receiver) = crossbeam_channel::unbounded(); let _vmm = match vmm::builder::build_microvm( &ctx_cfg.vmr, &mut event_manager, ctx_cfg.shutdown_efd, - #[cfg(target_os = "macos")] + // #[cfg(target_os = "macos")] + // sender, sender, ) { Ok(vmm) => vmm, @@ -1266,6 +1269,8 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 { #[cfg(target_os = "macos")] let mapper_vmm = _vmm.clone(); + let vmm = _vmm.clone(); + #[cfg(target_os = "macos")] std::thread::Builder::new() .name("mapping worker".into()) @@ -1284,6 +1289,17 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 { }) .unwrap(); + std::thread::Builder::new() + .name("vmcall worker".into()) + .spawn(move || loop { + match receiver.recv() { + Err(e) => error!("Error in receiver: {:?}", e), + Ok((gpa, size, private)) => { + let _ = convert_memory(&vmm, gpa, size, private); + }, + } + }).unwrap(); + loop { match event_manager.run() { Ok(_) => {} diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index 00f3a1142..0f53c057f 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -5,6 +5,7 @@ #[cfg(target_os = "macos")] use crossbeam_channel::{unbounded, Sender}; +use crossbeam_channel::Sender; use std::fmt::{Display, Formatter}; use std::fs::File; use std::io; @@ -354,6 +355,7 @@ pub fn build_microvm( event_manager: &mut EventManager, _shutdown_efd: Option, #[cfg(target_os = "macos")] _map_sender: Sender, + vmcall_sender: Sender<(u64, u64, bool)>, ) -> std::result::Result>, StartMicrovmError> { let mut guest_memfd_regions: Vec<(vm_memory::GuestAddress, u64, u64)> = vec![]; @@ -582,6 +584,7 @@ pub fn build_microvm( boot_ip, &pio_device_manager.io_bus, &exit_evt, + vmcall_sender, ) .map_err(StartMicrovmError::Internal)?; } @@ -1110,6 +1113,7 @@ fn create_vcpus_x86_64( entry_addr: GuestAddress, io_bus: &devices::Bus, exit_evt: &EventFd, + vmcall_sender: Sender<(u64, u64, bool)>, ) -> super::Result> { let mut vcpus = Vec::with_capacity(vcpu_config.vcpu_count as usize); for cpu_index in 0..vcpu_config.vcpu_count { @@ -1120,6 +1124,7 @@ fn create_vcpus_x86_64( vm.supported_msrs().clone(), io_bus.clone(), exit_evt.try_clone().map_err(Error::EventFd)?, + vmcall_sender.clone(), ) .map_err(Error::Vcpu)?; diff --git a/src/vmm/src/linux/vstate.rs b/src/vmm/src/linux/vstate.rs index af5f53dcc..73cfeaab2 100644 --- a/src/vmm/src/linux/vstate.rs +++ b/src/vmm/src/linux/vstate.rs @@ -891,6 +891,8 @@ pub struct Vcpu { response_receiver: Option>, // The transmitting end of the responses channel owned by the vcpu side. response_sender: Sender, + + vmcall_sender: Sender<(u64, u64, bool)>, } impl Vcpu { @@ -994,6 +996,7 @@ impl Vcpu { msr_list: MsrList, io_bus: devices::Bus, exit_evt: EventFd, + vmcall_sender: Sender<(u64, u64, bool)>, ) -> Result { let kvm_vcpu = vm_fd.create_vcpu(id as u64).map_err(Error::VcpuFd)?; let (event_sender, event_receiver) = unbounded(); @@ -1012,6 +1015,7 @@ impl Vcpu { event_sender: Some(event_sender), response_receiver: Some(response_receiver), response_sender, + vmcall_sender, }) } From 8d02d59326611f0b01203c15cce0ae254391dcc0 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Fri, 28 Feb 2025 13:45:35 -0500 Subject: [PATCH 28/40] add TDG_VP_VMCALL_MAP_GPA handler Signed-off-by: Jake Correnti --- src/vmm/src/linux/vstate.rs | 69 +++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/src/vmm/src/linux/vstate.rs b/src/vmm/src/linux/vstate.rs index 73cfeaab2..7582f03cd 100644 --- a/src/vmm/src/linux/vstate.rs +++ b/src/vmm/src/linux/vstate.rs @@ -1366,6 +1366,10 @@ impl Vcpu { match vmcall.__bindgen_anon_3.subfunction { TDG_VP_VMCALL_MAP_GPA => { + let ret = self.tdx_handle_map_gpa(&mut vmcall); + if ret < 0 { + return Err(Error::VcpuUnhandledKvmExit); + } return Ok(VcpuEmulation::Handled); } TDG_VP_VMCALL_GET_QUOTE => { @@ -1412,6 +1416,71 @@ impl Vcpu { } } + unsafe fn tdx_handle_map_gpa(&self, vmcall: &mut kvm_bindings::kvm_tdx_exit__bindgen_ty_1_kvm_tdx_vmcall) -> i32 { + const TDX_MAP_GPA_MAX_LEN: u64 = (64 * 1024 * 1024); + let phys_bits = unsafe { std::arch::x86_64::__cpuid(0x8000_0008).eax } & 0xff; + let mut retry = false; + let mut size = vmcall.in_r13; + let mut ret = 0; + + let shared_bit = if phys_bits > 48 { + 1 << 51 + } else { + 1 << 47 + }; + let gpa = vmcall.in_r12 & !shared_bit; + + let private: bool = if vmcall.in_r12 & shared_bit > 0 { + false + } else { + true + }; + + vmcall.__bindgen_anon_4.status_code = TDG_VP_VMCALL_INVALID_OPERAND; + + if (gpa % 4096) != 0 || (size % 4096) != 0 { + vmcall.__bindgen_anon_4.status_code = TDG_VP_VMCALL_ALIGN_ERROR; + return 0; + } + + // overflow case + if (gpa + size < gpa) { + return 0; + } + + if gpa >= (1 << phys_bits) || gpa + size >= (1 << phys_bits) { + return 0; + } + + if size > TDX_MAP_GPA_MAX_LEN { + retry = true; + size = TDX_MAP_GPA_MAX_LEN; + } + + if (size > 0) { + // convert memory + if let Err(e) = self.vmcall_sender.send((gpa, size, private)) { + ret = -1; + } + // FIXME(jakecorrenti): this is not practical. Find a way to solve the race condition + std::thread::sleep(std::time::Duration::from_millis(1000)); + } + + if ret == 0 { + if retry { + vmcall.__bindgen_anon_4.status_code = TDG_VP_VMCALL_RETRY; + vmcall.out_r11 = gpa + size; + if !private { + vmcall.out_r11 |= shared_bit; + } + } else { + vmcall.__bindgen_anon_4.status_code = TDG_VP_VMCALL_SUCCESS; + } + } + + 0 + } + unsafe fn tdx_handle_setup_event_notify_interrupt(vmcall: &mut kvm_bindings::kvm_tdx_exit__bindgen_ty_1_kvm_tdx_vmcall) -> i32 { let vector = vmcall.in_r12; From f8b3c5dd2be28a035899273b9a114073fd28bfd9 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Fri, 28 Feb 2025 14:11:10 -0500 Subject: [PATCH 29/40] implement VcpuExit::MemoryFault Signed-off-by: Jake Correnti --- src/vmm/src/linux/vstate.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/vmm/src/linux/vstate.rs b/src/vmm/src/linux/vstate.rs index 7582f03cd..0b94cc2db 100644 --- a/src/vmm/src/linux/vstate.rs +++ b/src/vmm/src/linux/vstate.rs @@ -1342,6 +1342,21 @@ impl Vcpu { error!("Received KVM_EXIT_INTERNAL_ERROR signal"); Err(Error::VcpuUnhandledKvmExit) } + VcpuExit::MemoryFault { flags, gpa, size } => { + if flags & !kvm_bindings::KVM_MEMORY_EXIT_FLAG_PRIVATE as u64 != 0 { + println!("KVM_EXIT_MEMORY_FAULT: Unknown flag {}", flags); + Err(Error::VcpuUnhandledKvmExit) + } else { + let attr = (flags & kvm_bindings::KVM_MEMORY_EXIT_FLAG_PRIVATE as u64); + + let res = self.vmcall_sender.try_send((gpa, size, attr > 0)); + if res.is_err() { + println!("KVM_EXIT_MEMORY_FAULT: unable to convert memory: Exit {:#?}", res); + return Err(Error::VcpuUnhandledKvmExit); + } + Ok(VcpuEmulation::Handled) + } + } VcpuExit::Tdx => { let kvm_run = self.fd.get_kvm_run(); let tdx = unsafe { &mut kvm_run.__bindgen_anon_1.tdx }; From 8e8c20e41215bfa24ccde444c5cff1529b12df0e Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Thu, 6 Mar 2025 09:00:01 -0500 Subject: [PATCH 30/40] misc intermediate commit before adding IOAPIC Signed-off-by: Jake Correnti --- examples/Makefile | 3 ++- examples/chroot_vm.c | 8 +++++++- examples/launch-tee | Bin 23736 -> 23736 bytes examples/launch-tee.c | 2 +- init/init.c | 12 ++++++++---- src/devices/src/virtio/mmio.rs | 1 + src/libkrun/src/lib.rs | 11 ++++++----- src/vmm/src/builder.rs | 12 ++++++++++-- src/vmm/src/lib.rs | 2 +- src/vmm/src/linux/vstate.rs | 8 +++++++- src/vmm/src/resources.rs | 8 ++++---- src/vmm/src/vmm_config/boot_source.rs | 4 ++-- src/vmm/src/vmm_config/mod.rs | 2 +- 13 files changed, 50 insertions(+), 23 deletions(-) diff --git a/examples/Makefile b/examples/Makefile index 529b85547..34aa56445 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -26,7 +26,8 @@ endif all: $(EXAMPLES) chroot_vm: chroot_vm.c - gcc -o $@ $< $(CFLAGS) $(LDFLAGS_$(ARCH)_$(OS)) + # gcc -o $@ $< $(CFLAGS) $(LDFLAGS_$(ARCH)_$(OS)) + gcc -o $@ $< $(CFLAGS) $(LDFLAGS_tdx) ifeq ($(OS),Darwin) codesign --entitlements chroot_vm.entitlements --force -s - $@ endif diff --git a/examples/chroot_vm.c b/examples/chroot_vm.c index 86321aeff..954c06a86 100644 --- a/examples/chroot_vm.c +++ b/examples/chroot_vm.c @@ -218,7 +218,7 @@ int main(int argc, char *const argv[]) } // Set the log level to "off". - err = krun_set_log_level(0); + err = krun_set_log_level(4); if (err) { errno = -err; perror("Error configuring log level"); @@ -280,6 +280,12 @@ int main(int argc, char *const argv[]) } } + if (err = krun_set_tee_config_file(ctx_id, "/home/jcorrent/libkrun/examples/tdx-config-noattest.json")) { + errno = -err; + perror("Error setting the TEE config file"); + return -1; + } + // Configure the rlimits that will be set in the guest if (err = krun_set_rlimits(ctx_id, &rlimits[0])) { errno = -err; diff --git a/examples/launch-tee b/examples/launch-tee index 597bc7b0bef94b6f253a542eb69d3cd4198784cd..9b17ca98e2ea01a285ea174eae1debd80a547ae8 100755 GIT binary patch delta 1799 zcmZuyeQZ-z6u-CK+E>`5AFHq325e>tV6=67I4}aQu#F+z%HlvaO)jN4-MnoN}=iaug8qczG&;6a> z{oRju@9D`=dUBK=yl5G*5Md+7zdK;4d3CZi_4RL-{uAq8d+(6KcAvQR^eNb7d)03n>F&JY>RcAZmiT<#bfWxLb z_;#%WPAX1lGu2qaK|RRATCyL$H1#bb5p7e*lZ<;FC9C|aSFB|7Jqs4z3+HWg)k#Pi- zHk6^$;0h{DFAczUD_laJ%Tnd8E<;mgV`gNRTF#na%piSa-ASM4%g8;H&*#(U_l(Wh z(}X*19?SKYfW5a7_=HG=oaSec9?vP5@}OGuJnTIuSk1kF;ZGS5rgo z;AB4Ef$ZHsakhY>2o0sox$~2G_{(N(Phh_&nZrpshV&*YYEGZhyovDXR~i(8@HbQJ z+nl{G$;p#c{Wq^FNQ~ zHe%!Zdkavc2>)SGX&~1 zT1X1BGR>fO8mAK}JKX-MaTXyq;(tKlO80CU9vUT1LYBd^PprrH-MB_>jv5GQATBae zyhSDUMkL$#hsHzYR=Uw~_|+)Wz1+LsLXMr>M-*FuGmcu^MnpEt6%1A)6%`6OLdJx` zSJ1sirk4ftcdlbVof<`uDvQ)=@cCuhApACX$1l4V;0$&{6+Y?$vq&UMpt)0qxqcVj zz}fD8@VW){s%uSR`3B_#TAc>_n@xEk?GedT2*jDb+<@3>gb2<7{g%7LKS> zrFI~m&{;G%K-gw2ra`W2_Wj`qOQ>Q#74>n}5F5}`7+5>U#*m|jw<>+HStK8>}-^m@zGk@sSwe6}E0b*L65FBug%(D^Td#+P)!1 zkQqf8WPx!K(D;WaAz4s#WB##;!U*6z0Br!P2wtDVsH;VE8adOV@ z_dDmFd*3^EaEJ~L(Gz3lUNg~FZ~ynlb;WO9_;B;>A71{pe6;dx(rxrDJ?A_Q2ZUDG zt+&H%!46`9oesi;-b3#~vt9xh;(rQudQywlU?iiW6Z%o{f`)bK?R1=b^eZh+B7aWv zmZFzLr5$b+1YkU9fkC+hE*gqqaGe#Z4K_Gxu$lL@vv4B5Gr9{BhEjc7ND0Bcpaf%v zZME*@Bo^HfcBd2WRixg(as38X?XGsOoby-I@U!WNpdFE0LG$xs=-1g!y7W)9QbI&c zMo5PK;1CI#;sZ4LzImby;Xe58p0UmGPlAAUA^;AvAKbwRU9f;FbX z1qE|@LYBd6i0(EOI*fU!EX!KNF%xv7;&aRk=ArZ83zM{uO;plj*u~c(~|rCC1B#)puusBli*bjFWP_5 z#@ltBi$#PQj-^dqchyapkV8ulz05DJq5D9kOC3gi1FGNng{w8_AVS^yjp~h=3_P%i zz7HOjRB@ArZlzMhn$J9h?;?Eps7odY|MU>P&(+7$T>R<`1g*u^BS>~#>A(3@%vhWfE$CA5ym?=ly&9idZ3&+Af#(_0fzv1rt^$oq#E{ zUxH*?^lUGx?$qNc)jy`P`kQ(Bqnxec>{yPS%wuElqOFt$q1#rftC@!Lwldvg({R&P zRyv95JEyS^buD^V-o~U6JQIGB9|tlvhm*E~!~GsT2t#gW5lynj&Hg2QQ04L9U~Ti1 z(*T5gHs~{V4A5m|M!I}p@#?3FG_*u8lTKtM+K0A8m`}uk9^WNlF(oC0tj(6x>T-jZ zMu>&@ABR1go-YVv=;GtxDAJ)v?Bq=DU*a;p4#7P^!cph;EL`0r(evDQT*6GNu82$) z%bIT1T-B7{X!cjlKG5_Fu)g>|^_@T)rK&1qEjp2yT#r^;#c}?t<#0VT`^)i>nb<5j z_8=z`2kDg`%}HqN5oE2pg+$KvH#?6uu=pi<25$K!$46X4P-Dqf7{QpYeqMoI*X(zi zRl$o{fAL=FLg+zT!L6fO;Je_2in5kDYu0cUh8riB)ou%T8#itsjMWFWvbqN5+v07k zV-2-i2&?xut@rv_lh5~DT?=dRuJ_k5INekZzXi%*Z_rbd>`>Bj{v*dC{4peZQyp=Z zjwmb@i?&CVG+{fV@hC|vsaOOi0~OXeK`gP0#UlG6FomWm)9QX;&R5)HFtG=kN3 zq|@2jm>-S9XwwpBwi#`|NL-1eP}S17fz<_S;h%yh`Gddcr9^6PTND{QhLSyAI2GZ= y!^-{vV{?yyBl1p*#~d(bFFF9XT2`Aob5SQ)wyrk!<)S`l#%Ok!a2U2OG5!l6I~pYb diff --git a/examples/launch-tee.c b/examples/launch-tee.c index d7867e84d..da6157404 100644 --- a/examples/launch-tee.c +++ b/examples/launch-tee.c @@ -45,7 +45,7 @@ int main(int argc, char *const argv[]) } // Set the log level to "error". - err = krun_set_log_level(1); + err = krun_set_log_level(4); if (err) { errno = -err; perror("Error configuring log level"); diff --git a/init/init.c b/init/init.c index 93553b736..29e147727 100644 --- a/init/init.c +++ b/init/init.c @@ -808,6 +808,8 @@ int setup_redirects() return 0; } +#include + int main(int argc, char **argv) { struct ifreq ifr; @@ -822,10 +824,12 @@ int main(int argc, char **argv) char **config_argv, **exec_argv; #ifdef SEV - if (chroot_luks() < 0) { - printf("Couldn't switch to LUKS volume, bailing out\n"); - exit(-1); - } + if (chroot_luks() < 0) { + const char msg[] = "Couldn't switch to LUKS volume, bailing out\n"; + write(STDOUT_FILENO, msg, sizeof(msg)-1); + printf("Couldn't switch to LUKS volume, bailing out\n"); + exit(-1); + } #endif if (mount_filesystems() < 0) { printf("Couldn't mount filesystems, bailing out\n"); diff --git a/src/devices/src/virtio/mmio.rs b/src/devices/src/virtio/mmio.rs index a6492cf00..3970c1326 100644 --- a/src/devices/src/virtio/mmio.rs +++ b/src/devices/src/virtio/mmio.rs @@ -207,6 +207,7 @@ impl MmioTransport { impl BusDevice for MmioTransport { fn read(&mut self, _vcpuid: u64, offset: u64, data: &mut [u8]) { + println!("MMIO read: offset={offset:x}"); match offset { 0x00..=0xff if data.len() == 4 => { let v = match offset { diff --git a/src/libkrun/src/lib.rs b/src/libkrun/src/lib.rs index 3032152ec..d4bf34b84 100644 --- a/src/libkrun/src/lib.rs +++ b/src/libkrun/src/lib.rs @@ -420,7 +420,7 @@ pub extern "C" fn krun_set_vm_config(ctx_id: u32, num_vcpus: u8, ram_mib: u32) - #[allow(clippy::missing_safety_doc)] #[no_mangle] -#[cfg(not(feature = "tee"))] +// #[cfg(not(feature = "tee"))] pub unsafe extern "C" fn krun_set_root(ctx_id: u32, c_root_path: *const c_char) -> i32 { let root_path = match CStr::from_ptr(c_root_path).to_str() { Ok(root) => root, @@ -433,7 +433,7 @@ pub unsafe extern "C" fn krun_set_root(ctx_id: u32, c_root_path: *const c_char) match CTX_MAP.lock().unwrap().entry(ctx_id) { Entry::Occupied(mut ctx_cfg) => { let cfg = ctx_cfg.get_mut(); - cfg.vmr.add_fs_device(FsDeviceConfig { + cfg.vmr.add_fs_device(vmm::vmm_config::fs::FsDeviceConfig { fs_id, shared_dir, // Default to a conservative 512 MB window. @@ -1322,6 +1322,7 @@ fn has_guest_memory(gpa: u64, size: u64, memfd_regions: &Vec<(vm_memory::GuestAd } fn convert_memory(vmm: &Arc>, gpa: u64, size: u64, to_private: bool) -> i32 { + println!("GPA: 0x{:x} SIZE: 0x{:x}, to_private: {}", gpa, size, to_private); let mut ret = -1; let vmm = vmm.as_ref().lock().unwrap(); let guest_memfd_regions = vmm.guest_memfd_regions(); @@ -1379,9 +1380,9 @@ fn convert_memory(vmm: &Arc>, gpa: u64, size: u64, to_private: b use vm_memory::GuestMemoryRegion; let offset = gpa - region.start_addr().raw_value(); + // ram_block_discard_range + let host_addr = region.get_host_address(vm_memory::MemoryRegionAddress(gpa)).unwrap(); if to_private { - // ram_block_discard_range - let host_addr = region.get_host_address(vm_memory::MemoryRegionAddress(gpa)).unwrap(); // let host_addr = gpa + offset; unsafe { @@ -1403,7 +1404,7 @@ fn convert_memory(vmm: &Arc>, gpa: u64, size: u64, to_private: b let _ret = fallocate( memfd_id as i32, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, - offset as i64, + host_addr as i64, size as i64, ); diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index 0f53c057f..384fe1dcf 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -452,7 +452,7 @@ pub fn build_microvm( }; // TODO(jakecorrenti): this shouldn't be pointing to something in Sergio's user - let qboot_file = std::fs::File::open("/home/slp/src/qboot-krunfw/build/bios.bin").unwrap(); + let qboot_file = std::fs::File::open("/home/jcorrent/qboot-krunfw/build/bios.bin").unwrap(); let qboot_size = qboot_file.metadata().unwrap().len(); #[cfg(all(feature = "tee", not(feature = "intel-tdx")))] @@ -835,7 +835,7 @@ fn load_payload( .write(kernel_data, GuestAddress(kernel_load_addr)) .unwrap(); - let mut qboot_file = std::fs::File::open("/home/slp/src/qboot-krunfw/build/bios.bin").unwrap(); + let mut qboot_file = std::fs::File::open("/home/jcorrent/qboot-krunfw/build/bios.bin").unwrap(); let qboot_size = qboot_file.metadata().unwrap().len(); guest_mem.read_exact_volatile_from( GuestAddress(arch::BIOS_START), @@ -843,6 +843,7 @@ fn load_payload( qboot_size as usize, ).unwrap(); + println!("initrd is present"); let initrd_data = unsafe { std::slice::from_raw_parts(initrd_host_addr as *mut u8, initrd_size) }; guest_mem @@ -1217,6 +1218,7 @@ fn attach_mmio_device( .device_type(); let _cmdline = &mut vmm.kernel_cmdline; + debug!("cmdline before: {:?}", _cmdline); #[cfg(target_os = "linux")] let (_mmio_base, _irq) = vmm.mmio_device_manager @@ -1229,6 +1231,7 @@ fn attach_mmio_device( #[cfg(target_arch = "x86_64")] vmm.mmio_device_manager .add_device_to_cmdline(_cmdline, _mmio_base, _irq)?; + debug!("cmdline after: {:?}", _cmdline); Ok(()) } @@ -1295,12 +1298,14 @@ fn attach_console_devices( use self::StartMicrovmError::*; let ports = if let Some(console_output) = console_output { + debug!("console output is present"); let file = File::create(console_output.as_path()).map_err(OpenConsoleFile)?; vec![PortDescription::Console { input: Some(port_io::input_empty().unwrap()), output: Some(port_io::output_file(file).unwrap()), }] } else { + debug!("defaulting to using std in, out, err for console"); let stdin_is_terminal = isatty(STDIN_FILENO).unwrap_or(false); let stdout_is_terminal = isatty(STDOUT_FILENO).unwrap_or(false); let stderr_is_terminal = isatty(STDERR_FILENO).unwrap_or(false); @@ -1324,6 +1329,7 @@ fn attach_console_devices( }; let console_output = if stdout_is_terminal { + debug!("stdout is a terminal"); Some(port_io::stdout().unwrap()) } else { Some(port_io::output_to_log_as_err()) @@ -1363,6 +1369,7 @@ fn attach_console_devices( vmm.exit_observers.push(console.clone()); if let Some(intc) = intc { + debug!("setting interrupt controller for console"); console.lock().unwrap().set_intc(intc); } @@ -1374,6 +1381,7 @@ fn attach_console_devices( register_sigwinch_handler(console.lock().unwrap().get_sigwinch_fd()) .map_err(RegisterFsSigwinch)?; + debug!("attaching hvc0 device"); // The device mutex mustn't be locked here otherwise it will deadlock. attach_mmio_device( vmm, diff --git a/src/vmm/src/lib.rs b/src/vmm/src/lib.rs index 6deab7003..0d1923f91 100644 --- a/src/vmm/src/lib.rs +++ b/src/vmm/src/lib.rs @@ -344,7 +344,7 @@ impl Vmm { /// Waits for all vCPUs to exit and terminates the Firecracker process. pub fn stop(&mut self, exit_code: i32) { - info!("Vmm is stopping."); + info!("Vmm is stopping. {}", exit_code); if let Err(e) = term_set_canonical_mode() { log::error!("Failed to restore terminal to canonical mode: {e}") diff --git a/src/vmm/src/linux/vstate.rs b/src/vmm/src/linux/vstate.rs index 0b94cc2db..047fbd2d8 100644 --- a/src/vmm/src/linux/vstate.rs +++ b/src/vmm/src/linux/vstate.rs @@ -1313,6 +1313,7 @@ impl Vcpu { Ok(VcpuEmulation::Handled) } VcpuExit::MmioRead(addr, data) => { + println!("vcpu_exit::mmio_read"); if let Some(ref mmio_bus) = self.mmio_bus { mmio_bus.read(0, addr, data); } @@ -1343,6 +1344,7 @@ impl Vcpu { Err(Error::VcpuUnhandledKvmExit) } VcpuExit::MemoryFault { flags, gpa, size } => { + println!("vcpu_exit::memory_fault"); if flags & !kvm_bindings::KVM_MEMORY_EXIT_FLAG_PRIVATE as u64 != 0 { println!("KVM_EXIT_MEMORY_FAULT: Unknown flag {}", flags); Err(Error::VcpuUnhandledKvmExit) @@ -1416,8 +1418,12 @@ impl Vcpu { // error in our code in which case it is better to panic. Err(ref e) => { match e.errno() { - libc::EAGAIN => Ok(VcpuEmulation::Handled), + libc::EAGAIN => { + println!("Error: EAGAIN"); + Ok(VcpuEmulation::Handled) + }, libc::EINTR => { + println!("Error: EINTR"); self.fd.set_kvm_immediate_exit(0); // Notify that this KVM_RUN was interrupted. Ok(VcpuEmulation::Interrupted) diff --git a/src/vmm/src/resources.rs b/src/vmm/src/resources.rs index 35be64613..3ffa1a0f3 100644 --- a/src/vmm/src/resources.rs +++ b/src/vmm/src/resources.rs @@ -18,7 +18,7 @@ use kbs_types::Tee; #[cfg(feature = "blk")] use crate::vmm_config::block::{BlockBuilder, BlockConfigError, BlockDeviceConfig}; use crate::vmm_config::boot_source::{BootSourceConfig, BootSourceConfigError}; -#[cfg(not(feature = "tee"))] +// #[cfg(not(feature = "tee"))] use crate::vmm_config::fs::*; #[cfg(feature = "tee")] use crate::vmm_config::kernel_bundle::{InitrdBundle, QbootBundle, QbootBundleError}; @@ -92,8 +92,8 @@ pub struct VmResources { #[cfg(feature = "tee")] pub initrd_bundle: Option, /// The fs device. - #[cfg(not(feature = "tee"))] - pub fs: Vec, + // #[cfg(not(feature = "tee"))] + pub fs: Vec, /// The vsock device. pub vsock: VsockBuilder, /// The virtio-blk device. @@ -233,7 +233,7 @@ impl VmResources { Ok(()) } - #[cfg(not(feature = "tee"))] + // #[cfg(not(feature = "tee"))] pub fn add_fs_device(&mut self, config: FsDeviceConfig) { self.fs.push(config) } diff --git a/src/vmm/src/vmm_config/boot_source.rs b/src/vmm/src/vmm_config/boot_source.rs index 483336ee6..ddf8789d6 100644 --- a/src/vmm/src/vmm_config/boot_source.rs +++ b/src/vmm/src/vmm_config/boot_source.rs @@ -7,8 +7,8 @@ use std::fmt::{Display, Formatter, Result}; pub const DEFAULT_KERNEL_CMDLINE: &str = "reboot=k panic=-1 panic_print=0 nomodule console=hvc0 \ rootfstype=virtiofs rw quiet no-kvmapf"; #[cfg(feature = "tee")] -pub const DEFAULT_KERNEL_CMDLINE: &str = "reboot=k panic=-1 panic_print=0 nomodule console=hvc0 \ - root=/dev/vda rw quiet no-kvmapf"; +pub const DEFAULT_KERNEL_CMDLINE: &str = "reboot=k panic=-1 panic_print=0 rw nomodule initcall_debug=0 console=hvc0 \ + root=/dev/vda rw earlyprintk=hvc0 no-kvmapf"; #[cfg(target_os = "macos")] pub const DEFAULT_KERNEL_CMDLINE: &str = "reboot=k panic=-1 panic_print=0 nomodule console=hvc0 \ rootfstype=virtiofs rw quiet no-kvmapf"; diff --git a/src/vmm/src/vmm_config/mod.rs b/src/vmm/src/vmm_config/mod.rs index 8f772b174..c9f9d84d9 100644 --- a/src/vmm/src/vmm_config/mod.rs +++ b/src/vmm/src/vmm_config/mod.rs @@ -9,7 +9,7 @@ pub mod block; pub mod boot_source; /// Wrapper for configuring the Fs devices attached to the microVM. -#[cfg(not(feature = "tee"))] +// #[cfg(not(feature = "tee"))] pub mod fs; /// Wrapper over the microVM general information attached to the microVM. From c1f34bc27c801d1f32bd93449e7a577fd743326c Mon Sep 17 00:00:00 2001 From: Sergio Lopez Date: Tue, 21 Jan 2025 14:17:33 +0100 Subject: [PATCH 31/40] libkrun: load libkrunfw as a dynamic library Instead of linking statically against libkrunfw, load it as a dynamic library. This will enable us to make its presence optional, which will come handy when we support loading external payloads. Signed-off-by: Sergio Lopez --- Cargo.lock | 1 + src/libkrun/Cargo.toml | 1 + src/libkrun/build.rs | 8 -- src/libkrun/src/lib.rs | 176 ++++++++++++++++++----------------------- 4 files changed, 80 insertions(+), 106 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4cad4ef4f..a39dae2ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -760,6 +760,7 @@ dependencies = [ "kvm-bindings", "kvm-ioctls", "libc", + "libloading", "log", "once_cell", "polly", diff --git a/src/libkrun/Cargo.toml b/src/libkrun/Cargo.toml index 815a9c1b0..513631dac 100644 --- a/src/libkrun/Cargo.toml +++ b/src/libkrun/Cargo.toml @@ -20,6 +20,7 @@ virgl_resource_map2 = [] crossbeam-channel = "0.5" env_logger = "0.9.0" libc = ">=0.2.39" +libloading = "0.8" log = "0.4.0" once_cell = "1.4.1" kvm-bindings = { path = "../../../kvm-ioctls/kvm-bindings", features = ["fam-wrappers"]} diff --git a/src/libkrun/build.rs b/src/libkrun/build.rs index 00506e9b6..9ccb2c75e 100644 --- a/src/libkrun/build.rs +++ b/src/libkrun/build.rs @@ -1,12 +1,4 @@ fn main() { #[cfg(target_os = "macos")] println!("cargo:rustc-link-lib=framework=Hypervisor"); - #[cfg(target_os = "macos")] - println!("cargo:rustc-link-search=/opt/homebrew/lib"); - #[cfg(all(not(feature = "tee"), not(feature = "efi")))] - println!("cargo:rustc-link-lib=krunfw"); - #[cfg(feature = "amd-sev")] - println!("cargo:rustc-link-lib=krunfw-sev"); - #[cfg(feature = "intel-tdx")] - println!("cargo:rustc-link-lib=krunfw-sev"); } diff --git a/src/libkrun/src/lib.rs b/src/libkrun/src/lib.rs index d4bf34b84..9e47ade41 100644 --- a/src/libkrun/src/lib.rs +++ b/src/libkrun/src/lib.rs @@ -59,14 +59,19 @@ use vmm::vmm_config::machine_config::VmConfig; use vmm::vmm_config::net::NetworkInterfaceConfig; use vmm::vmm_config::vsock::VsockDeviceConfig; -// Minimum krunfw version we require. -#[cfg(not(feature = "efi"))] -const KRUNFW_MIN_VERSION: u32 = 4; // Value returned on success. We use libc's errors otherwise. const KRUN_SUCCESS: i32 = 0; // Maximum number of arguments/environment variables we allow const MAX_ARGS: usize = 4096; +// krunfw library name for each context +#[cfg(all(target_os = "linux", not(feature = "amd-sev")))] +const KRUNFW_NAME: &str = "libkrunfw.so.4"; +#[cfg(all(target_os = "linux", feature = "amd-sev"))] +const KRUNFW_NAME: &str = "libkrunfw-sev.so.4"; +#[cfg(target_os = "macos")] +const KRUNFW_NAME: &str = "libkrunfw.4.dylib"; + // Path to the init binary to be executed inside the VM. const INIT_PATH: &str = "/init.krun"; @@ -253,43 +258,6 @@ impl ContextConfig { static CTX_MAP: Lazy>> = Lazy::new(|| Mutex::new(HashMap::new())); static CTX_IDS: AtomicI32 = AtomicI32::new(0); -#[cfg(all(not(feature = "tee"), not(feature = "efi")))] -#[link(name = "krunfw")] -extern "C" { - fn krunfw_get_kernel( - load_addr: *mut u64, - entry_addr: *mut u64, - size: *mut size_t, - ) -> *mut c_char; - fn krunfw_get_version() -> u32; -} - -#[cfg(feature = "amd-sev")] -#[link(name = "krunfw-sev")] -extern "C" { - fn krunfw_get_qboot(size: *mut size_t) -> *mut c_char; - fn krunfw_get_initrd(size: *mut size_t) -> *mut c_char; - fn krunfw_get_kernel( - load_addr: *mut u64, - entry_addr: *mut u64, - size: *mut size_t, - ) -> *mut c_char; - fn krunfw_get_version() -> u32; -} - -#[cfg(feature = "intel-tdx")] -#[link(name = "krunfw-sev")] -extern "C" { - fn krunfw_get_qboot(size: *mut size_t) -> *mut c_char; - fn krunfw_get_initrd(size: *mut size_t) -> *mut c_char; - fn krunfw_get_kernel( - load_addr: *mut u64, - entry_addr: *mut u64, - size: *mut size_t, - ) -> *mut c_char; - fn krunfw_get_version() -> u32; -} - #[no_mangle] pub extern "C" fn krun_set_log_level(level: u32) -> i32 { let log_level = match level { @@ -305,67 +273,11 @@ pub extern "C" fn krun_set_log_level(level: u32) -> i32 { } #[no_mangle] -#[cfg(not(feature = "efi"))] pub extern "C" fn krun_create_ctx() -> i32 { - let krunfw_version = unsafe { krunfw_get_version() }; - if krunfw_version < KRUNFW_MIN_VERSION { - eprintln!("Unsupported libkrunfw version: {krunfw_version}"); - return -libc::EINVAL; - } - - let mut kernel_guest_addr: u64 = 0; - let mut kernel_entry_addr: u64 = 0; - let mut kernel_size: usize = 0; - let kernel_host_addr = unsafe { - krunfw_get_kernel( - &mut kernel_guest_addr as *mut u64, - &mut kernel_entry_addr as *mut u64, - &mut kernel_size as *mut usize, - ) - }; - - let mut ctx_cfg = ContextConfig::default(); - - let kernel_bundle = KernelBundle { - host_addr: kernel_host_addr as u64, - guest_addr: kernel_guest_addr, - entry_addr: kernel_entry_addr, - size: kernel_size, - }; - ctx_cfg.vmr.set_kernel_bundle(kernel_bundle).unwrap(); + #[cfg(not(feature = "tee"))] + let ctx_cfg = ContextConfig::default(); #[cfg(feature = "tee")] - { - let mut qboot_size: usize = 0; - let qboot_host_addr = unsafe { krunfw_get_qboot(&mut qboot_size as *mut usize) }; - let qboot_bundle = QbootBundle { - host_addr: qboot_host_addr as u64, - size: qboot_size, - }; - ctx_cfg.vmr.set_qboot_bundle(qboot_bundle).unwrap(); - - let mut initrd_size: usize = 0; - let initrd_host_addr = unsafe { krunfw_get_initrd(&mut initrd_size as *mut usize) }; - let initrd_bundle = InitrdBundle { - host_addr: initrd_host_addr as u64, - size: initrd_size, - }; - ctx_cfg.vmr.set_initrd_bundle(initrd_bundle).unwrap(); - } - - let ctx_id = CTX_IDS.fetch_add(1, Ordering::SeqCst); - if ctx_id == i32::MAX || CTX_MAP.lock().unwrap().contains_key(&(ctx_id as u32)) { - // libkrun is not intended to be used as a daemon for managing VMs. - panic!("Context ID namespace exhausted"); - } - CTX_MAP.lock().unwrap().insert(ctx_id as u32, ctx_cfg); - - ctx_id -} - -#[no_mangle] -#[cfg(feature = "efi")] -pub extern "C" fn krun_create_ctx() -> i32 { let ctx_cfg = ContextConfig { shutdown_efd: Some(EventFd::new(utils::eventfd::EFD_NONBLOCK).unwrap()), ..Default::default() @@ -1128,6 +1040,61 @@ fn create_virtio_net(ctx_cfg: &mut ContextConfig, backend: VirtioNetBackend) { .expect("Failed to create network interface"); } +unsafe fn load_krunfw_payload( + krunfw: &libloading::Library, + vmr: &mut VmResources, +) -> Result<(), libloading::Error> { + let krunfw_get_kernel: libloading::Symbol< + unsafe extern "C" fn(*mut u64, *mut u64, *mut size_t) -> *mut c_char, + > = krunfw.get(b"krunfw_get_kernel")?; + + let mut kernel_guest_addr: u64 = 0; + let mut kernel_entry_addr: u64 = 0; + let mut kernel_size: usize = 0; + let kernel_host_addr = unsafe { + krunfw_get_kernel( + &mut kernel_guest_addr as *mut u64, + &mut kernel_entry_addr as *mut u64, + &mut kernel_size as *mut usize, + ) + }; + let kernel_bundle = KernelBundle { + host_addr: kernel_host_addr as u64, + guest_addr: kernel_guest_addr, + entry_addr: kernel_entry_addr, + size: kernel_size, + }; + vmr.set_kernel_bundle(kernel_bundle).unwrap(); + + #[cfg(feature = "tee")] + { + let krunfw_get_initrd: libloading::Symbol< + unsafe extern "C" fn(*mut size_t) -> *mut c_char, + > = krunfw.get(b"krunfw_get_initrd")?; + + let krunfw_get_qboot: libloading::Symbol *mut c_char> = + krunfw.get(b"krunfw_get_qboot")?; + + let mut qboot_size: usize = 0; + let qboot_host_addr = unsafe { krunfw_get_qboot(&mut qboot_size as *mut usize) }; + let qboot_bundle = QbootBundle { + host_addr: qboot_host_addr as u64, + size: qboot_size, + }; + ctx_cfg.vmr.set_qboot_bundle(qboot_bundle).unwrap(); + + let mut initrd_size: usize = 0; + let initrd_host_addr = unsafe { krunfw_get_initrd(&mut initrd_size as *mut usize) }; + let initrd_bundle = InitrdBundle { + host_addr: initrd_host_addr as u64, + size: initrd_size, + }; + ctx_cfg.vmr.set_initrd_bundle(initrd_bundle).unwrap(); + } + + Ok(()) +} + #[no_mangle] pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 { #[cfg(target_os = "linux")] @@ -1152,6 +1119,19 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 { None => return -libc::ENOENT, }; + // The reference to the dynamically loaded library must be kept alive. + let krunfw = match unsafe { libloading::Library::new(KRUNFW_NAME) } { + Ok(lib) => lib, + Err(err) => { + eprintln!("Can't load libkrunfw: {err}"); + return -libc::ENOENT; + } + }; + if let Err(err) = unsafe { load_krunfw_payload(&krunfw, &mut ctx_cfg.vmr) } { + eprintln!("Can't load libkrunfw symbols: {err}"); + return -libc::ENOENT; + } + #[cfg(feature = "blk")] for block_cfg in ctx_cfg.get_block_cfg() { if ctx_cfg.vmr.add_block_device(block_cfg).is_err() { From 3448d3055992280f1e3a489d12d9219efb45b78d Mon Sep 17 00:00:00 2001 From: Sergio Lopez Date: Tue, 21 Jan 2025 14:50:09 +0100 Subject: [PATCH 32/40] libkrun: support external kernels on aarch64 Introduce initial support for external kernels by dealing with the easier case: raw images on aarch64. This commit adds a new function, "krun_set_kernel", which receives a path to the external kernel. Future commits will add support for more image formats and x86_64. Signed-off-by: Sergio Lopez --- include/libkrun.h | 13 +++++ src/libkrun/src/lib.rs | 107 ++++++++++++++++++++++++++++++++++----- src/vmm/src/resources.rs | 4 -- 3 files changed, 107 insertions(+), 17 deletions(-) diff --git a/include/libkrun.h b/include/libkrun.h index efd3127a6..5afeb2545 100644 --- a/include/libkrun.h +++ b/include/libkrun.h @@ -403,6 +403,19 @@ int32_t krun_set_exec(uint32_t ctx_id, const char *const argv[], const char *const envp[]); +/** + * Sets the path to the kernel to be loaded in the microVM. + * + * Arguments: + * "ctx_id" - the configuration context ID. + * "kernel_path" - the path to the kernel, relative to the host's filesystem. + * + * Returns: + * Zero on success or a negative error number on failure. + */ +int32_t krun_set_kernel(uint32_t ctx_id, + const char *kernel_path); + /** * Sets environment variables to be configured in the context of the executable. * diff --git a/src/libkrun/src/lib.rs b/src/libkrun/src/lib.rs index 9e47ade41..c0a9a4a63 100644 --- a/src/libkrun/src/lib.rs +++ b/src/libkrun/src/lib.rs @@ -8,7 +8,9 @@ use std::env; use std::ffi::CStr; #[cfg(target_os = "linux")] use std::ffi::CString; -#[cfg(target_os = "linux")] +#[cfg(all(target_arch = "aarch64", not(feature = "efi")))] +use std::fs::File; +#[cfg(not(feature = "efi"))] use std::os::fd::AsRawFd; use std::os::fd::RawFd; use std::path::PathBuf; @@ -69,7 +71,7 @@ const MAX_ARGS: usize = 4096; const KRUNFW_NAME: &str = "libkrunfw.so.4"; #[cfg(all(target_os = "linux", feature = "amd-sev"))] const KRUNFW_NAME: &str = "libkrunfw-sev.so.4"; -#[cfg(target_os = "macos")] +#[cfg(all(target_os = "macos", not(feature = "efi")))] const KRUNFW_NAME: &str = "libkrunfw.4.dylib"; // Path to the init binary to be executed inside the VM. @@ -117,6 +119,8 @@ struct ContextConfig { gpu_shm_size: Option, enable_snd: bool, console_output: Option, + #[cfg(not(feature = "efi"))] + external_kernel: bool, } impl ContextConfig { @@ -1040,6 +1044,77 @@ fn create_virtio_net(ctx_cfg: &mut ContextConfig, backend: VirtioNetBackend) { .expect("Failed to create network interface"); } +#[cfg(any(target_arch = "x86_64", feature = "tee", feature = "efi"))] +#[allow(clippy::format_collect)] +#[allow(clippy::missing_safety_doc)] +#[no_mangle] +pub unsafe extern "C" fn krun_set_kernel(_ctx_id: u32, _c_kernel_path: *const c_char) -> i32 { + -libc::EOPNOTSUPP +} + +#[cfg(all(target_arch = "aarch64", not(feature = "efi")))] +#[allow(clippy::format_collect)] +#[allow(clippy::missing_safety_doc)] +#[no_mangle] +pub unsafe extern "C" fn krun_set_kernel(ctx_id: u32, c_kernel_path: *const c_char) -> i32 { + let kernel_path = match CStr::from_ptr(c_kernel_path).to_str() { + Ok(path) => path, + Err(e) => { + error!("Error parsing kernel_path: {:?}", e); + return -libc::EINVAL; + } + }; + + let file = match File::options().read(true).write(false).open(kernel_path) { + Ok(file) => file, + Err(err) => { + error!("Error opening external kernel: {err}"); + return -libc::EINVAL; + } + }; + + let kernel_size = file.metadata().unwrap().len(); + + let kernel_host_addr = unsafe { + libc::mmap( + std::ptr::null_mut(), + kernel_size as usize, + libc::PROT_READ, + libc::MAP_SHARED, + file.as_raw_fd(), + 0_i64, + ) + }; + if kernel_host_addr == libc::MAP_FAILED { + error!("Can't load kernel into process map"); + return -libc::EINVAL; + } + + let kernel_bundle = KernelBundle { + host_addr: kernel_host_addr as u64, + guest_addr: 0x8000_0000, + entry_addr: 0x8000_0000, + size: kernel_size as usize, + }; + + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let ctx_cfg = ctx_cfg.get_mut(); + if ctx_cfg.external_kernel { + error!("An extenal kernel was already configured"); + return -libc::EINVAL; + } else { + ctx_cfg.external_kernel = true; + } + ctx_cfg.vmr.set_kernel_bundle(kernel_bundle).unwrap() + } + Entry::Vacant(_) => return -libc::ENOENT, + } + + KRUN_SUCCESS +} + +#[cfg(not(feature = "efi"))] unsafe fn load_krunfw_payload( krunfw: &libloading::Library, vmr: &mut VmResources, @@ -1081,7 +1156,7 @@ unsafe fn load_krunfw_payload( host_addr: qboot_host_addr as u64, size: qboot_size, }; - ctx_cfg.vmr.set_qboot_bundle(qboot_bundle).unwrap(); + vmr.set_qboot_bundle(qboot_bundle).unwrap(); let mut initrd_size: usize = 0; let initrd_host_addr = unsafe { krunfw_get_initrd(&mut initrd_size as *mut usize) }; @@ -1089,7 +1164,7 @@ unsafe fn load_krunfw_payload( host_addr: initrd_host_addr as u64, size: initrd_size, }; - ctx_cfg.vmr.set_initrd_bundle(initrd_bundle).unwrap(); + vmr.set_initrd_bundle(initrd_bundle).unwrap(); } Ok(()) @@ -1119,18 +1194,24 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 { None => return -libc::ENOENT, }; - // The reference to the dynamically loaded library must be kept alive. - let krunfw = match unsafe { libloading::Library::new(KRUNFW_NAME) } { - Ok(lib) => lib, - Err(err) => { - eprintln!("Can't load libkrunfw: {err}"); + #[cfg(not(feature = "efi"))] + let _krunfw = if !ctx_cfg.external_kernel { + // The reference to the dynamically loaded library must be kept alive. + let krunfw = match unsafe { libloading::Library::new(KRUNFW_NAME) } { + Ok(lib) => lib, + Err(err) => { + eprintln!("Can't load libkrunfw: {err}"); + return -libc::ENOENT; + } + }; + if let Err(err) = unsafe { load_krunfw_payload(&krunfw, &mut ctx_cfg.vmr) } { + eprintln!("Can't load libkrunfw symbols: {err}"); return -libc::ENOENT; } + Some(krunfw) + } else { + None }; - if let Err(err) = unsafe { load_krunfw_payload(&krunfw, &mut ctx_cfg.vmr) } { - eprintln!("Can't load libkrunfw symbols: {err}"); - return -libc::ENOENT; - } #[cfg(feature = "blk")] for block_cfg in ctx_cfg.get_block_cfg() { diff --git a/src/vmm/src/resources.rs b/src/vmm/src/resources.rs index 3ffa1a0f3..29a5f9fa9 100644 --- a/src/vmm/src/resources.rs +++ b/src/vmm/src/resources.rs @@ -199,10 +199,6 @@ impl VmResources { return Err(KernelBundleError::InvalidGuestAddress); } - if kernel_bundle.size & (page_size - 1) != 0 { - return Err(KernelBundleError::InvalidSize); - } - self.kernel_bundle = Some(kernel_bundle); Ok(()) } From 4db1e645301d085128de8ff6913094b5535ecc7e Mon Sep 17 00:00:00 2001 From: Sergio Lopez Date: Thu, 23 Jan 2025 16:44:32 +0100 Subject: [PATCH 33/40] Support multiple kernel formats In the previous commit we added support for the simplest type of external kernel, a raw image that can be directly copied into the VM's memory. This commit builds on that to add support for multiple kernel formats. The ones currently implemented are: - ELF: A kernel binary in ELF format (vmlinux). - PeGz: A PE binary embedding a kernel image compressed with GZIP. - ImageBz2: An Image file embedding a kernel compressed with BZIP2. - ImageGz: An Image file embedding a kernel compressed with GZIP. - ImageZstd: An Image file embedding a kernel compressed with ZSTD. Adding new kernel formats should be quite straightforward. Please note this change doesn't implement support for loading an external initramfs. The main reason is that we can't guarantee to maintain the control of the VM boot when using an arbitrary initramfs. This means that the external kernel must be built with, at least, the following driver built-in: - virtio-mmio - virtio-console - virtio-fs Depending on the use case, more drivers might be required. Signed-off-by: Sergio Lopez --- Cargo.lock | 73 +++ include/libkrun.h | 14 +- src/arch/src/x86_64/mod.rs | 78 ++- src/libkrun/src/lib.rs | 101 ++-- src/vmm/Cargo.toml | 4 + src/vmm/src/builder.rs | 606 ++++++++++++++++------ src/vmm/src/resources.rs | 11 + src/vmm/src/vmm_config/external_kernel.rs | 33 ++ src/vmm/src/vmm_config/mod.rs | 3 + 9 files changed, 704 insertions(+), 219 deletions(-) create mode 100644 src/vmm/src/vmm_config/external_kernel.rs diff --git a/Cargo.lock b/Cargo.lock index a39dae2ab..83b2fe1ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -191,6 +191,27 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "bzip2" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bafdbf26611df8c14810e268ddceda071c297570a5fb360ceddf617fe417ef58" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + [[package]] name = "caps" version = "0.5.5" @@ -207,6 +228,8 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" dependencies = [ + "jobserver", + "libc", "shlex", ] @@ -686,6 +709,15 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" version = "0.3.72" @@ -829,6 +861,15 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linux-loader" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "870c3814345f050991f99869417779f6062542bcf4ed81db7a1b926ad1306638" +dependencies = [ + "vm-memory", +] + [[package]] name = "log" version = "0.4.22" @@ -1601,18 +1642,21 @@ version = "0.1.0" dependencies = [ "arch", "arch_gen", + "bzip2", "codicon", "cpuid", "crossbeam-channel", "curl", "devices", "env_logger", + "flate2", "hvf", "kbs-types", "kernel", "kvm-bindings", "kvm-ioctls", "libc", + "linux-loader", "log", "nix 0.24.3", "polly", @@ -1625,6 +1669,7 @@ dependencies = [ "utils", "vm-memory", "vmm-sys-util", + "zstd", ] [[package]] @@ -1945,3 +1990,31 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zstd" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.13+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/include/libkrun.h b/include/libkrun.h index 5afeb2545..66a96cd5c 100644 --- a/include/libkrun.h +++ b/include/libkrun.h @@ -403,18 +403,26 @@ int32_t krun_set_exec(uint32_t ctx_id, const char *const argv[], const char *const envp[]); +#define KRUN_KERNEL_FORMAT_RAW 0 +#define KRUN_KERNEL_FORMAT_ELF 1 +#define KRUN_KERNEL_FORMAT_PE_GZ 2 +#define KRUN_KERNEL_FORMAT_IMAGE_BZ2 3 +#define KRUN_KERNEL_FORMAT_IMAGE_GZ 4 +#define KRUN_KERNEL_FORMAT_IMAGE_ZSTD 5 /** * Sets the path to the kernel to be loaded in the microVM. * * Arguments: - * "ctx_id" - the configuration context ID. - * "kernel_path" - the path to the kernel, relative to the host's filesystem. + * "ctx_id" - the configuration context ID. + * "kernel_path" - the path to the kernel, relative to the host's filesystem. + * "kernel_format" - the kernel format. * * Returns: * Zero on success or a negative error number on failure. */ int32_t krun_set_kernel(uint32_t ctx_id, - const char *kernel_path); + const char *kernel_path, + uint32_t kernel_format); /** * Sets environment variables to be configured in the context of the executable. diff --git a/src/arch/src/x86_64/mod.rs b/src/arch/src/x86_64/mod.rs index c8352d8c9..d1f535445 100644 --- a/src/arch/src/x86_64/mod.rs +++ b/src/arch/src/x86_64/mod.rs @@ -70,48 +70,68 @@ pub const MMIO_MEM_START: u64 = FIRST_ADDR_PAST_32BITS - MEM_32BIT_GAP_SIZE; #[cfg(not(feature = "tee"))] pub fn arch_memory_regions( size: usize, - kernel_load_addr: u64, + kernel_load_addr: Option, kernel_size: usize, ) -> (ArchMemoryInfo, Vec<(GuestAddress, usize)>) { let page_size: usize = unsafe { libc::sysconf(libc::_SC_PAGESIZE).try_into().unwrap() }; let size = round_up(size, page_size); - if size < (kernel_load_addr + kernel_size as u64) as usize { - panic!("Kernel doesn't fit in RAM"); - } // It's safe to cast MMIO_MEM_START to usize because it fits in a u32 variable // (It points to an address in the 32 bit space). let (ram_last_addr, shm_start_addr, regions) = match size.checked_sub(MMIO_MEM_START as usize) { // case1: guest memory fits before the gap None | Some(0) => { - let ram_last_addr = kernel_load_addr + kernel_size as u64 + size as u64; let shm_start_addr = FIRST_ADDR_PAST_32BITS; - ( - ram_last_addr, - shm_start_addr, - vec![ - (GuestAddress(0), kernel_load_addr as usize), - (GuestAddress(kernel_load_addr + kernel_size as u64), size), - ], - ) + + if let Some(kernel_load_addr) = kernel_load_addr { + if size < (kernel_load_addr + kernel_size as u64) as usize { + panic!("Kernel doesn't fit in RAM"); + } + + let ram_last_addr = kernel_load_addr + kernel_size as u64 + size as u64; + ( + ram_last_addr, + shm_start_addr, + vec![ + (GuestAddress(0), kernel_load_addr as usize), + (GuestAddress(kernel_load_addr + kernel_size as u64), size), + ], + ) + } else { + let ram_last_addr = size as u64; + (ram_last_addr, shm_start_addr, vec![(GuestAddress(0), size)]) + } } + // case2: guest memory extends beyond the gap Some(remaining) => { let ram_last_addr = FIRST_ADDR_PAST_32BITS + remaining as u64; let shm_start_addr = ((ram_last_addr / 0x4000_0000) + 1) * 0x4000_0000; - ( - ram_last_addr, - shm_start_addr, - vec![ - (GuestAddress(0), kernel_load_addr as usize), - ( - GuestAddress(kernel_load_addr + kernel_size as u64), - (MMIO_MEM_START - (kernel_load_addr + kernel_size as u64)) as usize, - ), - (GuestAddress(FIRST_ADDR_PAST_32BITS), remaining), - ], - ) + + if let Some(kernel_load_addr) = kernel_load_addr { + ( + ram_last_addr, + shm_start_addr, + vec![ + (GuestAddress(0), kernel_load_addr as usize), + ( + GuestAddress(kernel_load_addr + kernel_size as u64), + (MMIO_MEM_START - (kernel_load_addr + kernel_size as u64)) as usize, + ), + (GuestAddress(FIRST_ADDR_PAST_32BITS), remaining), + ], + ) + } else { + ( + ram_last_addr, + shm_start_addr, + vec![ + (GuestAddress(0), MMIO_MEM_START as usize), + (GuestAddress(FIRST_ADDR_PAST_32BITS), remaining), + ], + ) + } } }; let info = ArchMemoryInfo { @@ -130,14 +150,16 @@ pub fn arch_memory_regions( #[cfg(feature = "tee")] pub fn arch_memory_regions( size: usize, - kernel_load_addr: u64, + kernel_load_addr: Option, kernel_size: usize, ) -> (ArchMemoryInfo, Vec<(GuestAddress, usize)>) { let page_size: usize = unsafe { libc::sysconf(libc::_SC_PAGESIZE).try_into().unwrap() }; let size = round_up(size, page_size); - if size < (kernel_load_addr + kernel_size as u64) as usize { - panic!("Kernel doesn't fit in RAM"); + if let Some(kernel_load_addr) = kernel_load_addr { + if size < (kernel_load_addr + kernel_size as u64) as usize { + panic!("Kernel doesn't fit in RAM"); + } } // It's safe to cast MMIO_MEM_START to usize because it fits in a u32 variable diff --git a/src/libkrun/src/lib.rs b/src/libkrun/src/lib.rs index c0a9a4a63..3c60f93a9 100644 --- a/src/libkrun/src/lib.rs +++ b/src/libkrun/src/lib.rs @@ -8,9 +8,9 @@ use std::env; use std::ffi::CStr; #[cfg(target_os = "linux")] use std::ffi::CString; -#[cfg(all(target_arch = "aarch64", not(feature = "efi")))] +#[cfg(all(target_arch = "x86_64", not(feature = "tee")))] use std::fs::File; -#[cfg(not(feature = "efi"))] +#[cfg(target_os = "linux")] use std::os::fd::AsRawFd; use std::os::fd::RawFd; use std::path::PathBuf; @@ -51,6 +51,8 @@ use vmm::resources::VmResources; use vmm::vmm_config::block::BlockDeviceConfig; use vmm::vmm_config::boot_source::{BootSourceConfig, DEFAULT_KERNEL_CMDLINE}; #[cfg(not(feature = "tee"))] +use vmm::vmm_config::external_kernel::{ExternalKernel, KernelFormat}; +#[cfg(not(feature = "tee"))] use vmm::vmm_config::fs::FsDeviceConfig; #[cfg(not(feature = "efi"))] use vmm::vmm_config::kernel_bundle::KernelBundle; @@ -119,8 +121,6 @@ struct ContextConfig { gpu_shm_size: Option, enable_snd: bool, console_output: Option, - #[cfg(not(feature = "efi"))] - external_kernel: bool, } impl ContextConfig { @@ -1044,27 +1044,8 @@ fn create_virtio_net(ctx_cfg: &mut ContextConfig, backend: VirtioNetBackend) { .expect("Failed to create network interface"); } -#[cfg(any(target_arch = "x86_64", feature = "tee", feature = "efi"))] -#[allow(clippy::format_collect)] -#[allow(clippy::missing_safety_doc)] -#[no_mangle] -pub unsafe extern "C" fn krun_set_kernel(_ctx_id: u32, _c_kernel_path: *const c_char) -> i32 { - -libc::EOPNOTSUPP -} - -#[cfg(all(target_arch = "aarch64", not(feature = "efi")))] -#[allow(clippy::format_collect)] -#[allow(clippy::missing_safety_doc)] -#[no_mangle] -pub unsafe extern "C" fn krun_set_kernel(ctx_id: u32, c_kernel_path: *const c_char) -> i32 { - let kernel_path = match CStr::from_ptr(c_kernel_path).to_str() { - Ok(path) => path, - Err(e) => { - error!("Error parsing kernel_path: {:?}", e); - return -libc::EINVAL; - } - }; - +#[cfg(all(target_arch = "x86_64", not(feature = "tee")))] +fn map_kernel(ctx_id: u32, kernel_path: &str) -> i32 { let file = match File::options().read(true).write(false).open(kernel_path) { Ok(file) => file, Err(err) => { @@ -1098,16 +1079,66 @@ pub unsafe extern "C" fn krun_set_kernel(ctx_id: u32, c_kernel_path: *const c_ch }; match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let ctx_cfg = ctx_cfg.get_mut(); - if ctx_cfg.external_kernel { - error!("An extenal kernel was already configured"); - return -libc::EINVAL; - } else { - ctx_cfg.external_kernel = true; - } - ctx_cfg.vmr.set_kernel_bundle(kernel_bundle).unwrap() + Entry::Occupied(mut ctx_cfg) => ctx_cfg + .get_mut() + .vmr + .set_kernel_bundle(kernel_bundle) + .unwrap(), + Entry::Vacant(_) => return -libc::ENOENT, + } + + KRUN_SUCCESS +} + +#[cfg(feature = "tee")] +#[allow(clippy::format_collect)] +#[allow(clippy::missing_safety_doc)] +#[no_mangle] +pub unsafe extern "C" fn krun_set_kernel(_ctx_id: u32, _c_kernel_path: *const c_char) -> i32 { + -libc::EOPNOTSUPP +} + +#[cfg(not(feature = "tee"))] +#[allow(clippy::format_collect)] +#[allow(clippy::missing_safety_doc)] +#[no_mangle] +pub unsafe extern "C" fn krun_set_kernel( + ctx_id: u32, + c_kernel_path: *const c_char, + kernel_format: u32, +) -> i32 { + let kernel_path = match CStr::from_ptr(c_kernel_path).to_str() { + Ok(path) => path, + Err(e) => { + error!("Error parsing kernel_path: {:?}", e); + return -libc::EINVAL; } + }; + + let format = match kernel_format { + // For raw kernels in x86_64, we map the kernel into the + // process and treat it as a bundled kernel. + #[cfg(all(target_arch = "x86_64", not(feature = "tee")))] + 0 => return map_kernel(ctx_id, kernel_path), + #[cfg(target_arch = "aarch64")] + 0 => KernelFormat::Raw, + 1 => KernelFormat::Elf, + 2 => KernelFormat::PeGz, + 3 => KernelFormat::ImageBz2, + 4 => KernelFormat::ImageGz, + 5 => KernelFormat::ImageZstd, + _ => { + return -libc::EINVAL; + } + }; + + let external_kernel = ExternalKernel { + path: PathBuf::from(kernel_path), + format, + }; + + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => ctx_cfg.get_mut().vmr.set_external_kernel(external_kernel), Entry::Vacant(_) => return -libc::ENOENT, } @@ -1195,7 +1226,7 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 { }; #[cfg(not(feature = "efi"))] - let _krunfw = if !ctx_cfg.external_kernel { + let _krunfw = if ctx_cfg.vmr.external_kernel.is_none() && ctx_cfg.vmr.kernel_bundle.is_none() { // The reference to the dynamically loaded library must be kept alive. let krunfw = match unsafe { libloading::Library::new(KRUNFW_NAME) } { Ok(lib) => lib, diff --git a/src/vmm/Cargo.toml b/src/vmm/Cargo.toml index c66dbb75a..58a4977df 100644 --- a/src/vmm/Cargo.toml +++ b/src/vmm/Cargo.toml @@ -17,7 +17,9 @@ snd = [] [dependencies] crossbeam-channel = "0.5" env_logger = "0.9.0" +flate2 = "1.0.35" libc = ">=0.2.39" +linux-loader = { version = "0.13.0", features = ["bzimage", "elf", "pe"] } log = "0.4.0" vm-memory = { version = ">=0.13", features = ["backend-mmap"] } @@ -40,7 +42,9 @@ curl = { version = "0.4", optional = true } nix = "0.24.1" [target.'cfg(target_arch = "x86_64")'.dependencies] +bzip2 = "0.5" cpuid = { path = "../cpuid" } +zstd = "0.13" [target.'cfg(target_os = "linux")'.dependencies] tdx = { path = "../../../tdx", optional = true } diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index 384fe1dcf..23530e183 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -8,7 +8,7 @@ use crossbeam_channel::{unbounded, Sender}; use crossbeam_channel::Sender; use std::fmt::{Display, Formatter}; use std::fs::File; -use std::io; +use std::io::{self, Read}; #[cfg(target_os = "linux")] use std::os::fd::AsRawFd; use std::path::PathBuf; @@ -20,6 +20,7 @@ use super::{Error, Vmm}; use crate::device_manager::legacy::PortIODeviceManager; use crate::device_manager::mmio::MMIODeviceManager; use crate::resources::VmResources; +use crate::vmm_config::external_kernel::{ExternalKernel, KernelFormat}; use devices::legacy::GicV3; use devices::legacy::Serial; #[cfg(target_os = "macos")] @@ -57,13 +58,16 @@ use arch::InitrdConfig; use device_manager::shm::ShmManager; #[cfg(not(feature = "tee"))] use devices::virtio::{fs::ExportTable, VirtioShmRegion}; +use flate2::read::GzDecoder; #[cfg(feature = "tee")] use kvm_bindings::KVM_MAX_CPUID_ENTRIES; use libc::{STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO}; +#[cfg(target_arch = "x86_64")] +use linux_loader::loader::{self, KernelLoader}; use nix::unistd::isatty; use polly::event_manager::{Error as EventManagerError, EventManager}; use utils::eventfd::EventFd; -#[cfg(not(feature = "efi"))] +#[cfg(all(target_arch = "x86_64", not(feature = "efi"), not(feature = "tee")))] use vm_memory::mmap::MmapRegion; #[cfg(not(feature = "tee"))] use vm_memory::Address; @@ -83,18 +87,48 @@ pub enum StartMicrovmError { AttachBlockDevice(io::Error), /// Failed to create a `RateLimiter` object. CreateRateLimiter(io::Error), + /// Cannot open the file containing the kernel code. + ElfOpenKernel(io::Error), + /// Cannot load the kernel into the VM. + ElfLoadKernel(linux_loader::loader::Error), /// Memory regions are overlapping or mmap fails. GuestMemoryMmap(vm_memory::Error), + /// The BZIP2 decoder couldn't decompress the kernel. + ImageBz2Decoder(io::Error), + /// Cannot find compressed kernel in file. + ImageBz2Invalid, + /// Cannot load the kernel from the uncompressed ELF data. + ImageBz2LoadKernel(linux_loader::loader::Error), + /// Cannot open the file containing the kernel code. + ImageBz2OpenKernel(io::Error), + /// The GZIP decoder couldn't decompress the kernel. + ImageGzDecoder(io::Error), + /// Cannot find compressed kernel in file. + ImageGzInvalid, + /// Cannot load the kernel from the uncompressed ELF data. + ImageGzLoadKernel(linux_loader::loader::Error), + /// Cannot open the file containing the kernel code. + ImageGzOpenKernel(io::Error), + /// The ZSTD decoder couldn't decompress the kernel. + ImageZstdDecoder(io::Error), + /// Cannot find compressed kernel in file. + ImageZstdInvalid, + /// Cannot load the kernel from the uncompressed ELF data. + ImageZstdLoadKernel(linux_loader::loader::Error), + /// Cannot open the file containing the kernel code. + ImageZstdOpenKernel(io::Error), /// Cannot load initrd due to an invalid memory configuration. InitrdLoad, /// Cannot load initrd due to an invalid image. InitrdRead(io::Error), /// Internal error encountered while starting a microVM. Internal(Error), + /// Cannot inject the kernel into the guest memory due to a problem with the bundle. + InvalidKernelBundle(vm_memory::mmap::MmapRegionError), /// The kernel command line is invalid. KernelCmdline(String), - /// Cannot inject the kernel into the guest memory due to a problem with the bundle. - KernelBundle(vm_memory::mmap::MmapRegionError), + /// The supplied kernel format is not supported. + KernelFormatUnsupported, /// Cannot load command line string. LoadCommandline(kernel::cmdline::Error), /// The start command was issued more than once. @@ -109,6 +143,14 @@ pub enum StartMicrovmError { OpenBlockDevice(io::Error), /// Cannot open console output file. OpenConsoleFile(io::Error), + /// The GZIP decoder couldn't decompress the kernel. + PeGzDecoder(io::Error), + /// Cannot open the file containing the kernel code. + PeGzOpenKernel(io::Error), + /// Cannot find compressed kernel in file. + PeGzInvalid, + /// Cannot open the file containing the kernel code. + RawOpenKernel(io::Error), /// Cannot initialize a MMIO Balloon device or add a device to the MMIO Bus. RegisterBalloonDevice(device_manager::mmio::Error), /// Cannot initialize a MMIO Block Device or add a device to the MMIO Bus. @@ -160,20 +202,70 @@ impl Display for StartMicrovmError { write!(f, "Unable to attach block device to Vmm. Error: {err}") } CreateRateLimiter(ref err) => write!(f, "Cannot create RateLimiter: {err}"), + ElfOpenKernel(ref err) => { + write!(f, "Cannot open the file containing the kernel code: {err}") + } + ElfLoadKernel(ref err) => { + write!(f, "Cannot load the kernel into the VM: {err}") + } GuestMemoryMmap(ref err) => { // Remove imbricated quotes from error message. let mut err_msg = format!("{err:?}"); err_msg = err_msg.replace('\"', ""); write!(f, "Invalid Memory Configuration: {err_msg}") } + ImageBz2Decoder(ref err) => { + write!(f, "The BZIP2 decoder couldn't decompress the kernel. {err}") + } + ImageBz2Invalid => { + write!(f, "Cannot find compressed kernel in file.") + } + ImageBz2LoadKernel(ref err) => { + write!( + f, + "Cannot load the kernel from the uncompressed ELF data. {err}" + ) + } + ImageBz2OpenKernel(ref err) => { + write!(f, "Cannot open the file containing the kernel code. {err}") + } + ImageGzDecoder(ref err) => { + write!(f, "The GZIP decoder couldn't decompress the kernel. {err}") + } + ImageGzInvalid => { + write!(f, "Cannot find compressed kernel in file.") + } + ImageGzLoadKernel(ref err) => { + write!( + f, + "Cannot load the kernel from the uncompressed ELF data. {err}" + ) + } + ImageGzOpenKernel(ref err) => { + write!(f, "Cannot open the file containing the kernel code. {err}") + } + ImageZstdDecoder(ref err) => { + write!(f, "The ZSTD decoder couldn't decompress the kernel. {err}") + } + ImageZstdInvalid => { + write!(f, "Cannot find compressed kernel in file.") + } + ImageZstdLoadKernel(ref err) => { + write!( + f, + "Cannot load the kernel from the uncompressed ELF data. {err}" + ) + } + ImageZstdOpenKernel(ref err) => { + write!(f, "Cannot open the file containing the kernel code. {err}") + } InitrdLoad => write!( f, "Cannot load initrd due to an invalid memory configuration." ), InitrdRead(ref err) => write!(f, "Cannot load initrd due to an invalid image: {err}"), Internal(ref err) => write!(f, "Internal error while starting microVM: {err:?}"), - KernelCmdline(ref err) => write!(f, "Invalid kernel command line: {err}"), - KernelBundle(ref err) => { + InvalidKernelBundle(ref err) => { let mut err_msg = format!("{err}"); err_msg = err_msg.replace('\"', ""); write!( @@ -182,6 +274,10 @@ impl Display for StartMicrovmError { bundle. {err_msg}" ) } + KernelCmdline(ref err) => write!(f, "Invalid kernel command line: {err}"), + KernelFormatUnsupported => { + write!(f, "The supplied kernel format is not supported.") + } LoadCommandline(ref err) => { let mut err_msg = format!("{err}"); err_msg = err_msg.replace('\"', ""); @@ -207,6 +303,18 @@ impl Display for StartMicrovmError { write!(f, "Cannot open the console output file. {err_msg}") } + PeGzDecoder(ref err) => { + write!(f, "The GZIP decoder couldn't decompress the kernel. {err}") + } + PeGzOpenKernel(ref err) => { + write!(f, "Cannot open the file containing the kernel code. {err}") + } + PeGzInvalid => { + write!(f, "Cannot find compressed kernel in file.") + } + RawOpenKernel(ref err) => { + write!(f, "Cannot open the file containing the kernel code: {err}") + } RegisterBalloonDevice(ref err) => { let mut err_msg = format!("{err}"); err_msg = err_msg.replace('\"', ""); @@ -330,17 +438,42 @@ impl Display for StartMicrovmError { } } } + enum Payload { #[cfg(all(target_arch = "x86_64", not(feature = "tee")))] - KernelMmap(MmapRegion, u64, usize), - #[cfg(all(target_arch = "aarch64", not(feature = "efi")))] - KernelCopy(MmapRegion, u64, usize), + KernelMmap, + #[cfg(target_arch = "aarch64")] + KernelCopy, + ExternalKernel(ExternalKernel), #[cfg(test)] Empty, - #[cfg(feature = "efi")] Efi, #[cfg(feature = "tee")] - Tee(MmapRegion, u64, usize, u64, usize, u64, usize), + Tee, +} + +fn choose_payload(vm_resources: &VmResources) -> Result { + if let Some(_kernel_bundle) = &vm_resources.kernel_bundle { + #[cfg(feature = "tee")] + if vm_resources.qboot_bundle.is_none() || vm_resources.initrd_bundle.is_none() { + return Err(StartMicrovmError::MissingKernelConfig); + } + + #[cfg(feature = "tee")] + return Ok(Payload::Tee); + + #[cfg(all(target_os = "linux", target_arch = "x86_64", not(feature = "tee")))] + return Ok(Payload::KernelMmap); + + #[cfg(target_arch = "aarch64")] + return Ok(Payload::KernelCopy); + } else if let Some(external_kernel) = vm_resources.external_kernel() { + Ok(Payload::ExternalKernel(external_kernel.clone())) + } else if cfg!(feature = "efi") { + Ok(Payload::Efi) + } else { + Err(StartMicrovmError::MissingKernelConfig) + } } /// Builds and starts a microVM based on the current Firecracker VmResources configuration. @@ -358,54 +491,15 @@ pub fn build_microvm( vmcall_sender: Sender<(u64, u64, bool)>, ) -> std::result::Result>, StartMicrovmError> { let mut guest_memfd_regions: Vec<(vm_memory::GuestAddress, u64, u64)> = vec![]; - - #[cfg(not(feature = "efi"))] - let kernel_bundle = vm_resources - .kernel_bundle() - .ok_or(StartMicrovmError::MissingKernelConfig)?; - #[cfg(not(feature = "efi"))] - let kernel_region = unsafe { - MmapRegion::build_raw(kernel_bundle.host_addr as *mut u8, kernel_bundle.size, 0, 0) - .map_err(StartMicrovmError::KernelBundle)? - }; - - #[cfg(feature = "tee")] - let qboot_bundle = vm_resources - .qboot_bundle() - .ok_or(StartMicrovmError::MissingKernelConfig)?; - - #[cfg(feature = "tee")] - let initrd_bundle = vm_resources - .initrd_bundle() - .ok_or(StartMicrovmError::MissingKernelConfig)?; + let payload = choose_payload(vm_resources)?; - #[cfg(feature = "tee")] - let payload = Payload::Tee( - kernel_region, - kernel_bundle.guest_addr, - kernel_bundle.size, - qboot_bundle.host_addr, - qboot_bundle.size, - initrd_bundle.host_addr, - initrd_bundle.size, - ); - #[cfg(all(target_os = "linux", target_arch = "x86_64", not(feature = "tee")))] - let payload = Payload::KernelMmap(kernel_region, kernel_bundle.guest_addr, kernel_bundle.size); - #[cfg(all(target_arch = "aarch64", not(feature = "efi")))] - let payload = Payload::KernelCopy(kernel_region, kernel_bundle.guest_addr, kernel_bundle.size); - #[cfg(all(target_arch = "aarch64", feature = "efi"))] - let payload = Payload::Efi; - - let (guest_memory, arch_memory_info, mut _shm_manager) = create_guest_memory( + let (guest_memory, entry_addr, arch_memory_info, mut _shm_manager) = create_guest_memory( vm_resources .vm_config() .mem_size_mib .ok_or(StartMicrovmError::MissingMemSizeConfig)?, - #[cfg(feature = "tee")] - None, - #[cfg(not(feature = "tee"))] - Some(vm_resources), - payload, + vm_resources, + &payload, )?; let vcpu_config = vm_resources.vcpu_config(); @@ -459,27 +553,44 @@ pub fn build_microvm( let measured_regions = { println!("Injecting and measuring memory regions. This may take a while."); - let m = vec![ + let qboot_size = if let Some(qboot_bundle) = &vm_resources.qboot_bundle { + qboot_bundle.size + } else { + return Err(StartMicrovmError::MissingKernelConfig); + }; + let (kernel_guest_addr, kernel_size) = + if let Some(kernel_bundle) = &vm_resources.kernel_bundle { + (kernel_bundle.guest_addr, kernel_bundle.size) + } else { + return Err(StartMicrovmError::MissingKernelConfig); + }; + let initrd_size = if let Some(initrd_bundle) = &vm_resources.initrd_bundle { + initrd_bundle.size + } else { + return Err(StartMicrovmError::MissingKernelConfig); + }; + + vec![ MeasuredRegion { guest_addr: arch::BIOS_START, host_addr: guest_memory .get_host_address(GuestAddress(arch::BIOS_START)) .unwrap() as u64, - size: qboot_bundle.size, + size: qboot_size, }, MeasuredRegion { - guest_addr: kernel_bundle.guest_addr, + guest_addr: kernel_guest_addr, host_addr: guest_memory - .get_host_address(GuestAddress(kernel_bundle.guest_addr)) + .get_host_address(GuestAddress(kernel_guest_addr)) .unwrap() as u64, - size: kernel_bundle.size, + size: kernel_size, }, MeasuredRegion { guest_addr: arch::x86_64::layout::INITRD_SEV_START, host_addr: guest_memory .get_host_address(GuestAddress(arch::x86_64::layout::INITRD_SEV_START)) .unwrap() as u64, - size: initrd_bundle.size, + size: initrd_size, }, MeasuredRegion { guest_addr: arch::x86_64::layout::ZERO_PAGE_START, @@ -488,9 +599,7 @@ pub fn build_microvm( .unwrap() as u64, size: 4096, }, - ]; - - m + ] }; #[cfg(feature = "intel-tdx")] @@ -563,11 +672,6 @@ pub fn build_microvm( #[cfg(target_os = "macos")] let intc = Some(GicV3::new(vcpu_list.clone())); - #[cfg(all(target_os = "linux", target_arch = "x86_64", not(feature = "tee")))] - let boot_ip: GuestAddress = GuestAddress(kernel_bundle.entry_addr); - #[cfg(feature = "tee")] - let boot_ip: GuestAddress = GuestAddress(arch::RESET_VECTOR); - let vcpus; // For x86_64 we need to create the interrupt controller before calling `KVM_CREATE_VCPUS` // while on aarch64 we need to do it the other way around. @@ -581,7 +685,7 @@ pub fn build_microvm( &vm, &vcpu_config, &guest_memory, - boot_ip, + entry_addr, &pio_device_manager.io_bus, &exit_evt, vmcall_sender, @@ -595,14 +699,8 @@ pub fn build_microvm( // Search for `kvm_arch_vcpu_create` in arch/arm/kvm/arm.c. #[cfg(all(target_arch = "aarch64", target_os = "linux"))] { - vcpus = create_vcpus_aarch64( - &vm, - &vcpu_config, - &guest_memory, - GuestAddress(kernel_bundle.guest_addr), - &exit_evt, - ) - .map_err(StartMicrovmError::Internal)?; + vcpus = create_vcpus_aarch64(&vm, &vcpu_config, &guest_memory, entry_addr, &exit_evt) + .map_err(StartMicrovmError::Internal)?; setup_interrupt_controller(&mut vm, vcpu_config.vcpu_count)?; attach_legacy_devices( @@ -615,16 +713,11 @@ pub fn build_microvm( #[cfg(all(target_arch = "aarch64", target_os = "macos"))] { - #[cfg(not(feature = "efi"))] - let start_addr = GuestAddress(kernel_bundle.guest_addr); - #[cfg(feature = "efi")] - let start_addr = GuestAddress(0u64); - vcpus = create_vcpus_aarch64( &vm, &vcpu_config, &guest_memory, - start_addr, + entry_addr, &exit_evt, vcpu_list.clone(), ) @@ -733,10 +826,22 @@ pub fn build_microvm( load_cmdline(&vmm)?; #[cfg(feature = "tee")] - let initrd_config = Some(InitrdConfig { - address: GuestAddress(arch::x86_64::layout::INITRD_SEV_START), - size: initrd_bundle.size, - }); + let initrd_config = { + match payload { + Payload::Tee => { + let initrd_size = if let Some(initrd_bundle) = &vm_resources.initrd_bundle { + initrd_bundle.size + } else { + return Err(StartMicrovmError::MissingKernelConfig); + }; + Some(InitrdConfig { + address: GuestAddress(arch::x86_64::layout::INITRD_SEV_START), + size: initrd_size, + }) + } + _ => return Err(StartMicrovmError::MissingKernelConfig), + } + }; #[cfg(not(feature = "tee"))] let initrd_config = None; @@ -796,54 +901,236 @@ pub fn build_microvm( Ok(vmm) } +fn load_external_kernel( + guest_mem: &GuestMemoryMmap, + external_kernel: &ExternalKernel, +) -> std::result::Result { + let entry_addr = match external_kernel.format { + // Raw images are treated as bundled kernels on x86_64 + #[cfg(target_arch = "x86_64")] + KernelFormat::Raw => unreachable!(), + #[cfg(target_arch = "aarch64")] + KernelFormat::Raw => { + let data: Vec = std::fs::read(external_kernel.path.clone()) + .map_err(StartMicrovmError::RawOpenKernel)?; + guest_mem.write(&data, GuestAddress(0x8000_0000)).unwrap(); + GuestAddress(0x8000_0000) + } + #[cfg(target_arch = "x86_64")] + KernelFormat::Elf => { + let mut file = File::options() + .read(true) + .write(false) + .open(external_kernel.path.clone()) + .map_err(StartMicrovmError::ElfOpenKernel)?; + let load_result = loader::Elf::load(guest_mem, None, &mut file, None) + .map_err(StartMicrovmError::ElfLoadKernel)?; + load_result.kernel_load + } + #[cfg(target_arch = "aarch64")] + KernelFormat::PeGz => { + let data: Vec = std::fs::read(external_kernel.path.clone()) + .map_err(StartMicrovmError::PeGzOpenKernel)?; + if let Some(magic) = data + .windows(3) + .position(|window| window == [0x1f, 0x8b, 0x8]) + { + debug!("Found GZIP header on PE file at: 0x{:x}", magic); + let (_, compressed) = data.split_at(magic); + let mut gz = GzDecoder::new(compressed); + let mut kernel_data: Vec = Vec::new(); + gz.read_to_end(&mut kernel_data) + .map_err(StartMicrovmError::PeGzDecoder)?; + guest_mem + .write(&kernel_data, GuestAddress(0x8000_0000)) + .unwrap(); + GuestAddress(0x8000_0000) + } else { + return Err(StartMicrovmError::PeGzInvalid); + } + } + #[cfg(target_arch = "x86_64")] + KernelFormat::ImageBz2 => { + let data: Vec = std::fs::read(external_kernel.path.clone()) + .map_err(StartMicrovmError::ImageBz2OpenKernel)?; + if let Some(magic) = data + .windows(4) + .position(|window| window == [b'B', b'Z', b'h']) + { + debug!("Found BZIP2 header on Image file at: 0x{:x}", magic); + let (_, compressed) = data.split_at(magic); + let mut kernel_data: Vec = Vec::new(); + let mut bz2 = bzip2::read::BzDecoder::new(compressed); + bz2.read_to_end(&mut kernel_data) + .map_err(StartMicrovmError::ImageBz2Decoder)?; + let load_result = loader::Elf::load( + guest_mem, + None, + &mut std::io::Cursor::new(kernel_data), + None, + ) + .map_err(StartMicrovmError::ImageBz2LoadKernel)?; + load_result.kernel_load + } else { + return Err(StartMicrovmError::ImageBz2Invalid); + } + } + #[cfg(target_arch = "x86_64")] + KernelFormat::ImageGz => { + let data: Vec = std::fs::read(external_kernel.path.clone()) + .map_err(StartMicrovmError::ImageGzOpenKernel)?; + if let Some(magic) = data + .windows(3) + .position(|window| window == [0x1f, 0x8b, 0x8]) + { + debug!("Found GZIP header on Image file at: 0x{:x}", magic); + let (_, compressed) = data.split_at(magic); + let mut gz = GzDecoder::new(compressed); + let mut kernel_data: Vec = Vec::new(); + gz.read_to_end(&mut kernel_data) + .map_err(StartMicrovmError::ImageGzDecoder)?; + let load_result = loader::Elf::load( + guest_mem, + None, + &mut std::io::Cursor::new(kernel_data), + None, + ) + .map_err(StartMicrovmError::ImageGzLoadKernel)?; + load_result.kernel_load + } else { + return Err(StartMicrovmError::ImageGzInvalid); + } + } + #[cfg(target_arch = "x86_64")] + KernelFormat::ImageZstd => { + let data: Vec = std::fs::read(external_kernel.path.clone()) + .map_err(StartMicrovmError::ImageZstdOpenKernel)?; + if let Some(magic) = data + .windows(4) + .position(|window| window == [0x28, 0xb5, 0x2f, 0xfd]) + { + debug!("Found ZSTD header on Image file at: 0x{:x}", magic); + let (_, zstd_data) = data.split_at(magic); + let mut kernel_data: Vec = Vec::new(); + let _ = zstd::stream::copy_decode(zstd_data, &mut kernel_data); + let load_result = loader::Elf::load( + guest_mem, + None, + &mut std::io::Cursor::new(kernel_data), + None, + ) + .map_err(StartMicrovmError::ImageZstdLoadKernel)?; + load_result.kernel_load + } else { + return Err(StartMicrovmError::ImageZstdInvalid); + } + } + _ => return Err(StartMicrovmError::KernelFormatUnsupported), + }; + + debug!("load_external_kernel: 0x{:x}", entry_addr.0); + + Ok(entry_addr) +} + fn load_payload( + _vm_resources: &VmResources, guest_mem: GuestMemoryMmap, - payload: Payload, -) -> std::result::Result { + payload: &Payload, +) -> std::result::Result<(GuestMemoryMmap, GuestAddress), StartMicrovmError> { match payload { - #[cfg(all(target_arch = "aarch64", not(feature = "efi")))] - Payload::KernelCopy(kernel_region, kernel_load_addr, kernel_size) => { + #[cfg(target_arch = "aarch64")] + Payload::KernelCopy => { + let (kernel_entry_addr, kernel_host_addr, kernel_guest_addr, kernel_size) = + if let Some(kernel_bundle) = &_vm_resources.kernel_bundle { + ( + kernel_bundle.entry_addr, + kernel_bundle.host_addr, + kernel_bundle.guest_addr, + kernel_bundle.size, + ) + } else { + return Err(StartMicrovmError::MissingKernelConfig); + }; + let kernel_data = - unsafe { std::slice::from_raw_parts(kernel_region.as_ptr(), kernel_size) }; + unsafe { std::slice::from_raw_parts(kernel_host_addr as *mut u8, kernel_size) }; guest_mem - .write(kernel_data, GuestAddress(kernel_load_addr)) + .write(kernel_data, GuestAddress(kernel_guest_addr)) .unwrap(); - Ok(guest_mem) + Ok((guest_mem, GuestAddress(kernel_entry_addr))) } #[cfg(all(target_arch = "x86_64", not(feature = "tee")))] - Payload::KernelMmap(kernel_region, kernel_load_addr, _kernel_size) => guest_mem - .insert_region(Arc::new( - GuestRegionMmap::new(kernel_region, GuestAddress(kernel_load_addr)) + Payload::KernelMmap => { + let (kernel_entry_addr, kernel_host_addr, kernel_guest_addr, kernel_size) = + if let Some(kernel_bundle) = &_vm_resources.kernel_bundle { + ( + kernel_bundle.entry_addr, + kernel_bundle.host_addr, + kernel_bundle.guest_addr, + kernel_bundle.size, + ) + } else { + return Err(StartMicrovmError::MissingKernelConfig); + }; + + let kernel_region = unsafe { + MmapRegion::build_raw(kernel_host_addr as *mut u8, kernel_size, 0, 0) + .map_err(StartMicrovmError::InvalidKernelBundle)? + }; + + Ok(( + guest_mem + .insert_region(Arc::new( + GuestRegionMmap::new(kernel_region, GuestAddress(kernel_guest_addr)) + .map_err(StartMicrovmError::GuestMemoryMmap)?, + )) .map_err(StartMicrovmError::GuestMemoryMmap)?, + GuestAddress(kernel_entry_addr), )) - .map_err(StartMicrovmError::GuestMemoryMmap), + } + Payload::ExternalKernel(external_kernel) => { + let entry_addr = load_external_kernel(&guest_mem, external_kernel)?; + Ok((guest_mem, entry_addr)) + } #[cfg(test)] - Payload::Empty => Ok(guest_mem), + Payload::Empty => Ok((guest_mem, GuestAddress(0))), #[cfg(feature = "tee")] - Payload::Tee( - kernel_region, - kernel_load_addr, - kernel_size, - _qboot_host_addr, - _qboot_size, - initrd_host_addr, - initrd_size, - ) => { + Payload::Tee => { + let (kernel_host_addr, kernel_guest_addr, kernel_size) = + if let Some(kernel_bundle) = &_vm_resources.kernel_bundle { + ( + kernel_bundle.host_addr, + kernel_bundle.guest_addr, + kernel_bundle.size, + ) + } else { + return Err(StartMicrovmError::MissingKernelConfig); + }; let kernel_data = - unsafe { std::slice::from_raw_parts(kernel_region.as_ptr(), kernel_size) }; + unsafe { std::slice::from_raw_parts(kernel_host_addr as *mut u8, kernel_size) }; guest_mem - .write(kernel_data, GuestAddress(kernel_load_addr)) + .write(kernel_data, GuestAddress(kernel_guest_addr)) .unwrap(); - let mut qboot_file = std::fs::File::open("/home/jcorrent/qboot-krunfw/build/bios.bin").unwrap(); - let qboot_size = qboot_file.metadata().unwrap().len(); - guest_mem.read_exact_volatile_from( - GuestAddress(arch::BIOS_START), - &mut qboot_file, - qboot_size as usize, - ).unwrap(); + let (qboot_host_addr, qboot_size) = + if let Some(qboot_bundle) = &_vm_resources.qboot_bundle { + (qboot_bundle.host_addr, qboot_bundle.size) + } else { + return Err(StartMicrovmError::MissingKernelConfig); + }; + let qboot_data = + unsafe { std::slice::from_raw_parts(qboot_host_addr as *mut u8, qboot_size) }; + guest_mem + .write(qboot_data, GuestAddress(arch::BIOS_START)) + .unwrap(); - println!("initrd is present"); + let (initrd_host_addr, initrd_size) = + if let Some(initrd_bundle) = &_vm_resources.initrd_bundle { + (initrd_bundle.host_addr, initrd_bundle.size) + } else { + return Err(StartMicrovmError::MissingKernelConfig); + }; let initrd_data = unsafe { std::slice::from_raw_parts(initrd_host_addr as *mut u8, initrd_size) }; guest_mem @@ -852,72 +1139,85 @@ fn load_payload( GuestAddress(arch::x86_64::layout::INITRD_SEV_START), ) .unwrap(); - Ok(guest_mem) + Ok((guest_mem, GuestAddress(arch::RESET_VECTOR))) } #[cfg(feature = "efi")] Payload::Efi => { guest_mem.write(EDK2_BINARY, GuestAddress(0u64)).unwrap(); - Ok(guest_mem) + Ok((guest_mem, GuestAddress(0))) + } + #[cfg(not(feature = "efi"))] + Payload::Efi => { + unreachable!("EFI support was not built in") } } } fn create_guest_memory( mem_size: usize, - vm_resources: Option<&VmResources>, - payload: Payload, -) -> std::result::Result<(GuestMemoryMmap, ArchMemoryInfo, ShmManager), StartMicrovmError> { + vm_resources: &VmResources, + payload: &Payload, +) -> std::result::Result< + (GuestMemoryMmap, GuestAddress, ArchMemoryInfo, ShmManager), + StartMicrovmError, +> { let mem_size = mem_size << 20; #[cfg(target_arch = "x86_64")] let (arch_mem_info, mut arch_mem_regions) = match payload { #[cfg(not(feature = "tee"))] - Payload::KernelMmap(ref _kernel_region, kernel_load_addr, kernel_size) => { - arch::arch_memory_regions(mem_size, kernel_load_addr, kernel_size) + Payload::KernelMmap => { + let (kernel_guest_addr, kernel_size) = + if let Some(kernel_bundle) = &vm_resources.kernel_bundle { + (kernel_bundle.guest_addr, kernel_bundle.size) + } else { + return Err(StartMicrovmError::MissingKernelConfig); + }; + arch::arch_memory_regions(mem_size, Some(kernel_guest_addr), kernel_size) } + #[cfg(not(feature = "efi"))] + Payload::ExternalKernel(_kernel_path) => arch::arch_memory_regions(mem_size, None, 0), #[cfg(feature = "tee")] - Payload::Tee( - ref _kernel_region, - kernel_load_addr, - kernel_size, - _qboot_host_addr, - _qboot_size, - _initrd_host_addr, - _initrd_size, - ) => arch::arch_memory_regions(mem_size, kernel_load_addr, kernel_size), + Payload::Tee => { + let (kernel_guest_addr, kernel_size) = + if let Some(kernel_bundle) = &vm_resources.kernel_bundle { + (kernel_bundle.guest_addr, kernel_bundle.size) + } else { + return Err(StartMicrovmError::MissingKernelConfig); + }; + arch::arch_memory_regions(mem_size, Some(kernel_guest_addr), kernel_size) + } #[cfg(test)] - Payload::Empty => arch::arch_memory_regions(mem_size, 0, 0), + Payload::Empty => arch::arch_memory_regions(mem_size, None, 0), }; #[cfg(target_arch = "aarch64")] let (arch_mem_info, mut arch_mem_regions) = arch::arch_memory_regions(mem_size); let mut shm_manager = ShmManager::new(&arch_mem_info); - if let Some(vm_resources) = vm_resources { - #[cfg(not(feature = "tee"))] - for (index, fs) in vm_resources.fs.iter().enumerate() { - if let Some(shm_size) = fs.shm_size { - shm_manager - .create_fs_region(index, shm_size) - .map_err(StartMicrovmError::ShmCreate)?; - } - } - if vm_resources.gpu_virgl_flags.is_some() { - let size = vm_resources.gpu_shm_size.unwrap_or(1 << 33); + #[cfg(not(feature = "tee"))] + for (index, fs) in vm_resources.fs.iter().enumerate() { + if let Some(shm_size) = fs.shm_size { shm_manager - .create_gpu_region(size) + .create_fs_region(index, shm_size) .map_err(StartMicrovmError::ShmCreate)?; } - - arch_mem_regions.extend(shm_manager.regions()); } + if vm_resources.gpu_virgl_flags.is_some() { + let size = vm_resources.gpu_shm_size.unwrap_or(1 << 33); + shm_manager + .create_gpu_region(size) + .map_err(StartMicrovmError::ShmCreate)?; + } + + arch_mem_regions.extend(shm_manager.regions()); let guest_mem = GuestMemoryMmap::from_ranges(&arch_mem_regions) .map_err(StartMicrovmError::GuestMemoryMmap)?; - let guest_mem = load_payload(guest_mem, payload)?; + let (guest_mem, entry_addr) = load_payload(vm_resources, guest_mem, payload)?; - Ok((guest_mem, arch_mem_info, shm_manager)) + Ok((guest_mem, entry_addr, arch_mem_info, shm_manager)) } #[cfg(all(target_arch = "x86_64", not(feature = "tee")))] @@ -1696,10 +1996,10 @@ pub mod tests { let err = Internal(Error::Serial(io::Error::from_raw_os_error(0))); let _ = format!("{}{:?}", err, err); - let err = KernelCmdline(String::from("dummy --cmdline")); + let err = InvalidKernelBundle(vm_memory::mmap::MmapRegionError::InvalidPointer); let _ = format!("{}{:?}", err, err); - let err = KernelBundle(vm_memory::mmap::MmapRegionError::InvalidPointer); + let err = KernelCmdline(String::from("dummy --cmdline")); let _ = format!("{}{:?}", err, err); let err = LoadCommandline(kernel::cmdline::Error::TooLarge); diff --git a/src/vmm/src/resources.rs b/src/vmm/src/resources.rs index 29a5f9fa9..34084bd0f 100644 --- a/src/vmm/src/resources.rs +++ b/src/vmm/src/resources.rs @@ -18,6 +18,7 @@ use kbs_types::Tee; #[cfg(feature = "blk")] use crate::vmm_config::block::{BlockBuilder, BlockConfigError, BlockDeviceConfig}; use crate::vmm_config::boot_source::{BootSourceConfig, BootSourceConfigError}; +use crate::vmm_config::external_kernel::ExternalKernel; // #[cfg(not(feature = "tee"))] use crate::vmm_config::fs::*; #[cfg(feature = "tee")] @@ -85,6 +86,8 @@ pub struct VmResources { pub boot_config: BootSourceConfig, /// The parameters for the kernel bundle to be loaded in this microVM. pub kernel_bundle: Option, + /// The path to an external kernel, as an alternative to KernelBundle. + pub external_kernel: Option, /// The parameters for the qboot bundle to be loaded in this microVM. #[cfg(feature = "tee")] pub qboot_bundle: Option, @@ -203,6 +206,14 @@ impl VmResources { Ok(()) } + pub fn external_kernel(&self) -> Option<&ExternalKernel> { + self.external_kernel.as_ref() + } + + pub fn set_external_kernel(&mut self, external_kernel: ExternalKernel) { + self.external_kernel = Some(external_kernel); + } + #[cfg(feature = "tee")] pub fn qboot_bundle(&self) -> Option<&QbootBundle> { self.qboot_bundle.as_ref() diff --git a/src/vmm/src/vmm_config/external_kernel.rs b/src/vmm/src/vmm_config/external_kernel.rs new file mode 100644 index 000000000..4b21d12e6 --- /dev/null +++ b/src/vmm/src/vmm_config/external_kernel.rs @@ -0,0 +1,33 @@ +// Copyright 2024, Red Hat Inc. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +use std::path::PathBuf; + +#[derive(Clone, Debug)] +pub enum KernelFormat { + // Raw image, ready to be loaded into the VM. + Raw, + // ELF image, need to locale sections be loaded. + Elf, + // Raw image compressed with GZIP, embedded into a PE file. + PeGz, + // ELF image compressed with BZIP2, embedded into an Image file. + ImageBz2, + // ELF image compressed with GZIP, embedded into an Image file. + ImageGz, + // ELF image compressed with ZSTD, embedded into an Image file. + ImageZstd, +} + +impl Default for KernelFormat { + fn default() -> Self { + Self::Raw + } +} + +/// Data structure holding the attributes read from the `libkrunfw` kernel config. +#[derive(Clone, Debug, Default)] +pub struct ExternalKernel { + pub path: PathBuf, + pub format: KernelFormat, +} diff --git a/src/vmm/src/vmm_config/mod.rs b/src/vmm/src/vmm_config/mod.rs index c9f9d84d9..1a1c2e57e 100644 --- a/src/vmm/src/vmm_config/mod.rs +++ b/src/vmm/src/vmm_config/mod.rs @@ -8,6 +8,9 @@ pub mod block; /// Wrapper for configuring the microVM boot source. pub mod boot_source; +/// Wrapper for configuring an external kernel to be loaded in the microVM. +pub mod external_kernel; + /// Wrapper for configuring the Fs devices attached to the microVM. // #[cfg(not(feature = "tee"))] pub mod fs; From 4c71406c621f56bf551c7a738a01e9b248d64994 Mon Sep 17 00:00:00 2001 From: Sergio Lopez Date: Mon, 17 Feb 2025 17:05:28 +0100 Subject: [PATCH 34/40] Support external initramfs and custom cmdline Complement the external kernel support added in the previous commits with support for external initramfs and a custom kernel command line. We don't have an immediate use case for this, as loading an external initramfs may imply losing control of what's happening in the guest, but it's a low-hanging fruit and may be useful for debugging or a future use case. Signed-off-by: Sergio Lopez --- include/libkrun.h | 6 +- src/arch/src/aarch64/mod.rs | 6 +- src/arch/src/lib.rs | 1 + src/arch/src/x86_64/mod.rs | 21 ++- src/libkrun/src/lib.rs | 49 +++++- src/vmm/src/builder.rs | 196 +++++++++++++--------- src/vmm/src/resources.rs | 1 + src/vmm/src/vmm_config/external_kernel.rs | 3 + 8 files changed, 192 insertions(+), 91 deletions(-) diff --git a/include/libkrun.h b/include/libkrun.h index 66a96cd5c..d10f91785 100644 --- a/include/libkrun.h +++ b/include/libkrun.h @@ -416,13 +416,17 @@ int32_t krun_set_exec(uint32_t ctx_id, * "ctx_id" - the configuration context ID. * "kernel_path" - the path to the kernel, relative to the host's filesystem. * "kernel_format" - the kernel format. + * "initramfs" - the path to the initramfs, relative to the host's filesystem. + * "cmdline" - the kernel command line. * * Returns: * Zero on success or a negative error number on failure. */ int32_t krun_set_kernel(uint32_t ctx_id, const char *kernel_path, - uint32_t kernel_format); + uint32_t kernel_format, + const char *initramfs, + const char *cmdline); /** * Sets environment variables to be configured in the context of the executable. diff --git a/src/arch/src/aarch64/mod.rs b/src/arch/src/aarch64/mod.rs index c76d99a90..c42cb5491 100644 --- a/src/arch/src/aarch64/mod.rs +++ b/src/arch/src/aarch64/mod.rs @@ -47,7 +47,10 @@ use crate::DeviceType; /// Returns a Vec of the valid memory addresses for aarch64. /// See [`layout`](layout) module for a drawing of the specific memory model for this platform. -pub fn arch_memory_regions(size: usize) -> (ArchMemoryInfo, Vec<(GuestAddress, usize)>) { +pub fn arch_memory_regions( + size: usize, + initrd_size: u64, +) -> (ArchMemoryInfo, Vec<(GuestAddress, usize)>) { let page_size: usize = unsafe { libc::sysconf(libc::_SC_PAGESIZE).try_into().unwrap() }; let dram_size = round_up(size, page_size); let ram_last_addr = layout::DRAM_MEM_START + (dram_size as u64); @@ -57,6 +60,7 @@ pub fn arch_memory_regions(size: usize) -> (ArchMemoryInfo, Vec<(GuestAddress, u ram_last_addr, shm_start_addr, page_size, + initrd_addr: ram_last_addr - layout::FDT_MAX_SIZE as u64 - initrd_size, }; let regions = if cfg!(feature = "efi") { vec![ diff --git a/src/arch/src/lib.rs b/src/arch/src/lib.rs index 87046e80d..c97674b16 100644 --- a/src/arch/src/lib.rs +++ b/src/arch/src/lib.rs @@ -12,6 +12,7 @@ pub struct ArchMemoryInfo { pub ram_last_addr: u64, pub shm_start_addr: u64, pub page_size: usize, + pub initrd_addr: u64, } /// Module for aarch64 related functionality. diff --git a/src/arch/src/x86_64/mod.rs b/src/arch/src/x86_64/mod.rs index d1f535445..97e36da24 100644 --- a/src/arch/src/x86_64/mod.rs +++ b/src/arch/src/x86_64/mod.rs @@ -72,6 +72,7 @@ pub fn arch_memory_regions( size: usize, kernel_load_addr: Option, kernel_size: usize, + initrd_size: u64, ) -> (ArchMemoryInfo, Vec<(GuestAddress, usize)>) { let page_size: usize = unsafe { libc::sysconf(libc::_SC_PAGESIZE).try_into().unwrap() }; @@ -138,6 +139,7 @@ pub fn arch_memory_regions( ram_last_addr, shm_start_addr, page_size, + initrd_addr: ram_last_addr - initrd_size, }; (info, regions) } @@ -152,6 +154,7 @@ pub fn arch_memory_regions( size: usize, kernel_load_addr: Option, kernel_size: usize, + _initrd_size: u64, ) -> (ArchMemoryInfo, Vec<(GuestAddress, usize)>) { let page_size: usize = unsafe { libc::sysconf(libc::_SC_PAGESIZE).try_into().unwrap() }; @@ -197,6 +200,7 @@ pub fn arch_memory_regions( ram_last_addr, shm_start_addr, page_size, + initrd_addr: layout::INITRD_SEV_START, }; (info, regions) } @@ -352,7 +356,8 @@ mod tests { #[test] fn regions_lt_4gb() { - let (_info, regions) = arch_memory_regions(1usize << 29, KERNEL_LOAD_ADDR, KERNEL_SIZE); + let (_info, regions) = + arch_memory_regions(1usize << 29, Some(KERNEL_LOAD_ADDR), KERNEL_SIZE, 0); assert_eq!(2, regions.len()); assert_eq!(GuestAddress(0), regions[0].0); assert_eq!(KERNEL_LOAD_ADDR as usize, regions[0].1); @@ -365,8 +370,12 @@ mod tests { #[test] fn regions_gt_4gb() { - let (_info, regions) = - arch_memory_regions((1usize << 32) + 0x8000, KERNEL_LOAD_ADDR, KERNEL_SIZE); + let (_info, regions) = arch_memory_regions( + (1usize << 32) + 0x8000, + Some(KERNEL_LOAD_ADDR), + KERNEL_SIZE, + 0, + ); assert_eq!(3, regions.len()); assert_eq!(GuestAddress(0), regions[0].0); assert_eq!(KERNEL_LOAD_ADDR as usize, regions[0].1); @@ -393,21 +402,21 @@ mod tests { // Now assigning some memory that falls before the 32bit memory hole. let mem_size = 128 << 20; let (arch_mem_info, arch_mem_regions) = - arch_memory_regions(mem_size, KERNEL_LOAD_ADDR, KERNEL_SIZE); + arch_memory_regions(mem_size, Some(KERNEL_LOAD_ADDR), KERNEL_SIZE, 0); let gm = GuestMemoryMmap::from_ranges(&arch_mem_regions).unwrap(); configure_system(&gm, &arch_mem_info, GuestAddress(0), 0, &None, no_vcpus).unwrap(); // Now assigning some memory that is equal to the start of the 32bit memory hole. let mem_size = 3328 << 20; let (arch_mem_info, arch_mem_regions) = - arch_memory_regions(mem_size, KERNEL_LOAD_ADDR, KERNEL_SIZE); + arch_memory_regions(mem_size, Some(KERNEL_LOAD_ADDR), KERNEL_SIZE, 0); let gm = GuestMemoryMmap::from_ranges(&arch_mem_regions).unwrap(); configure_system(&gm, &arch_mem_info, GuestAddress(0), 0, &None, no_vcpus).unwrap(); // Now assigning some memory that falls after the 32bit memory hole. let mem_size = 3330 << 20; let (arch_mem_info, arch_mem_regions) = - arch_memory_regions(mem_size, KERNEL_LOAD_ADDR, KERNEL_SIZE); + arch_memory_regions(mem_size, Some(KERNEL_LOAD_ADDR), KERNEL_SIZE, 0); let gm = GuestMemoryMmap::from_ranges(&arch_mem_regions).unwrap(); configure_system(&gm, &arch_mem_info, GuestAddress(0), 0, &None, no_vcpus).unwrap(); } diff --git a/src/libkrun/src/lib.rs b/src/libkrun/src/lib.rs index 3c60f93a9..78a3eeefb 100644 --- a/src/libkrun/src/lib.rs +++ b/src/libkrun/src/lib.rs @@ -1045,7 +1045,7 @@ fn create_virtio_net(ctx_cfg: &mut ContextConfig, backend: VirtioNetBackend) { } #[cfg(all(target_arch = "x86_64", not(feature = "tee")))] -fn map_kernel(ctx_id: u32, kernel_path: &str) -> i32 { +fn map_kernel(ctx_id: u32, kernel_path: &PathBuf) -> i32 { let file = match File::options().read(true).write(false).open(kernel_path) { Ok(file) => file, Err(err) => { @@ -1106,9 +1106,11 @@ pub unsafe extern "C" fn krun_set_kernel( ctx_id: u32, c_kernel_path: *const c_char, kernel_format: u32, + c_initramfs_path: *const c_char, + c_cmdline: *const c_char, ) -> i32 { - let kernel_path = match CStr::from_ptr(c_kernel_path).to_str() { - Ok(path) => path, + let path = match CStr::from_ptr(c_kernel_path).to_str() { + Ok(path) => PathBuf::from(path), Err(e) => { error!("Error parsing kernel_path: {:?}", e); return -libc::EINVAL; @@ -1119,7 +1121,7 @@ pub unsafe extern "C" fn krun_set_kernel( // For raw kernels in x86_64, we map the kernel into the // process and treat it as a bundled kernel. #[cfg(all(target_arch = "x86_64", not(feature = "tee")))] - 0 => return map_kernel(ctx_id, kernel_path), + 0 => return map_kernel(ctx_id, &path), #[cfg(target_arch = "aarch64")] 0 => KernelFormat::Raw, 1 => KernelFormat::Elf, @@ -1132,9 +1134,46 @@ pub unsafe extern "C" fn krun_set_kernel( } }; + let (initramfs_path, initramfs_size) = if !c_initramfs_path.is_null() { + match CStr::from_ptr(c_initramfs_path).to_str() { + Ok(path) => { + let path = PathBuf::from(path); + let size = match std::fs::metadata(&path) { + Ok(metadata) => metadata.len(), + Err(e) => { + error!("Can't read initramfs metadata: {:?}", e); + return -libc::EINVAL; + } + }; + (Some(path), size) + } + Err(e) => { + error!("Error parsing initramfs path: {:?}", e); + return -libc::EINVAL; + } + } + } else { + (None, 0) + }; + + let cmdline = if !c_cmdline.is_null() { + match CStr::from_ptr(c_cmdline).to_str() { + Ok(cmdline) => Some(cmdline.to_string()), + Err(e) => { + error!("Error parsing kernel cmdline: {:?}", e); + return -libc::EINVAL; + } + } + } else { + None + }; + let external_kernel = ExternalKernel { - path: PathBuf::from(kernel_path), + path, format, + initramfs_path, + initramfs_size, + cmdline, }; match CTX_MAP.lock().unwrap().entry(ctx_id) { diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index 23530e183..cd150df8e 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -6,6 +6,7 @@ #[cfg(target_os = "macos")] use crossbeam_channel::{unbounded, Sender}; use crossbeam_channel::Sender; +use kernel::cmdline::Cmdline; use std::fmt::{Display, Formatter}; use std::fs::File; use std::io::{self, Read}; @@ -52,9 +53,7 @@ use crate::vstate::KvmContext; #[cfg(all(target_os = "linux", feature = "tee"))] use crate::vstate::MeasuredRegion; use crate::vstate::{Error as VstateError, Vcpu, VcpuConfig, Vm}; -use arch::ArchMemoryInfo; -#[cfg(feature = "tee")] -use arch::InitrdConfig; +use arch::{ArchMemoryInfo, InitrdConfig}; use device_manager::shm::ShmManager; #[cfg(not(feature = "tee"))] use devices::virtio::{fs::ExportTable, VirtioShmRegion}; @@ -71,7 +70,6 @@ use utils::eventfd::EventFd; use vm_memory::mmap::MmapRegion; #[cfg(not(feature = "tee"))] use vm_memory::Address; -#[cfg(any(target_arch = "aarch64", feature = "tee"))] use vm_memory::Bytes; #[cfg(all(target_arch = "x86_64", not(feature = "tee")))] use vm_memory::GuestRegionMmap; @@ -493,7 +491,7 @@ pub fn build_microvm( let mut guest_memfd_regions: Vec<(vm_memory::GuestAddress, u64, u64)> = vec![]; let payload = choose_payload(vm_resources)?; - let (guest_memory, entry_addr, arch_memory_info, mut _shm_manager) = create_guest_memory( + let (guest_memory, arch_memory_info, mut _shm_manager, payload_config) = create_guest_memory( vm_resources .vm_config() .mem_size_mib @@ -505,11 +503,14 @@ pub fn build_microvm( // Clone the command-line so that a failed boot doesn't pollute the original. #[allow(unused_mut)] - let mut kernel_cmdline = kernel::cmdline::Cmdline::new(arch::CMDLINE_MAX_SIZE); - match &vm_resources.boot_config.kernel_cmdline_prolog { - None => kernel_cmdline.insert_str(DEFAULT_KERNEL_CMDLINE).unwrap(), - Some(s) => kernel_cmdline.insert_str(s).unwrap(), - }; + let mut kernel_cmdline = Cmdline::new(arch::CMDLINE_MAX_SIZE); + if let Some(cmdline) = payload_config.kernel_cmdline { + kernel_cmdline.insert_str(cmdline.as_str()).unwrap(); + } else if let Some(cmdline) = &vm_resources.boot_config.kernel_cmdline_prolog { + kernel_cmdline.insert_str(cmdline).unwrap(); + } else { + kernel_cmdline.insert_str(DEFAULT_KERNEL_CMDLINE).unwrap(); + } #[cfg(not(feature = "tee"))] #[allow(unused_mut)] @@ -564,8 +565,9 @@ pub fn build_microvm( } else { return Err(StartMicrovmError::MissingKernelConfig); }; - let initrd_size = if let Some(initrd_bundle) = &vm_resources.initrd_bundle { - initrd_bundle.size + let (initrd_addr, initrd_size) = if let Some(initrd_config) = &payload_config.initrd_config + { + (initrd_config.address, initrd_config.size) } else { return Err(StartMicrovmError::MissingKernelConfig); }; @@ -586,10 +588,8 @@ pub fn build_microvm( size: kernel_size, }, MeasuredRegion { - guest_addr: arch::x86_64::layout::INITRD_SEV_START, - host_addr: guest_memory - .get_host_address(GuestAddress(arch::x86_64::layout::INITRD_SEV_START)) - .unwrap() as u64, + guest_addr: initrd_addr.0, + host_addr: guest_memory.get_host_address(initrd_addr).unwrap() as u64, size: initrd_size, }, MeasuredRegion { @@ -685,7 +685,7 @@ pub fn build_microvm( &vm, &vcpu_config, &guest_memory, - entry_addr, + payload_config.entry_addr, &pio_device_manager.io_bus, &exit_evt, vmcall_sender, @@ -699,8 +699,14 @@ pub fn build_microvm( // Search for `kvm_arch_vcpu_create` in arch/arm/kvm/arm.c. #[cfg(all(target_arch = "aarch64", target_os = "linux"))] { - vcpus = create_vcpus_aarch64(&vm, &vcpu_config, &guest_memory, entry_addr, &exit_evt) - .map_err(StartMicrovmError::Internal)?; + vcpus = create_vcpus_aarch64( + &vm, + &vcpu_config, + &guest_memory, + payload_config.entry_addr, + &exit_evt, + ) + .map_err(StartMicrovmError::Internal)?; setup_interrupt_controller(&mut vm, vcpu_config.vcpu_count)?; attach_legacy_devices( @@ -717,7 +723,7 @@ pub fn build_microvm( &vm, &vcpu_config, &guest_memory, - entry_addr, + payload_config.entry_addr, &exit_evt, vcpu_list.clone(), ) @@ -825,30 +831,9 @@ pub fn build_microvm( #[cfg(all(target_arch = "x86_64", not(feature = "tee")))] load_cmdline(&vmm)?; - #[cfg(feature = "tee")] - let initrd_config = { - match payload { - Payload::Tee => { - let initrd_size = if let Some(initrd_bundle) = &vm_resources.initrd_bundle { - initrd_bundle.size - } else { - return Err(StartMicrovmError::MissingKernelConfig); - }; - Some(InitrdConfig { - address: GuestAddress(arch::x86_64::layout::INITRD_SEV_START), - size: initrd_size, - }) - } - _ => return Err(StartMicrovmError::MissingKernelConfig), - } - }; - - #[cfg(not(feature = "tee"))] - let initrd_config = None; - vmm.configure_system( vcpus.as_slice(), - &initrd_config, + &payload_config.initrd_config, &vm_resources.smbios_oem_strings, ) .map_err(StartMicrovmError::Internal)?; @@ -903,8 +888,9 @@ pub fn build_microvm( fn load_external_kernel( guest_mem: &GuestMemoryMmap, + arch_mem_info: &ArchMemoryInfo, external_kernel: &ExternalKernel, -) -> std::result::Result { +) -> std::result::Result<(GuestAddress, Option, Option), StartMicrovmError> { let entry_addr = match external_kernel.format { // Raw images are treated as bundled kernels on x86_64 #[cfg(target_arch = "x86_64")] @@ -1030,14 +1016,36 @@ fn load_external_kernel( debug!("load_external_kernel: 0x{:x}", entry_addr.0); - Ok(entry_addr) + let initrd_config = if let Some(initramfs_path) = &external_kernel.initramfs_path { + let data = std::fs::read(initramfs_path).map_err(StartMicrovmError::InitrdRead)?; + guest_mem + .write(&data, GuestAddress(arch_mem_info.initrd_addr)) + .unwrap(); + Some(InitrdConfig { + address: GuestAddress(arch_mem_info.initrd_addr), + size: data.len(), + }) + } else { + None + }; + + Ok((entry_addr, initrd_config, external_kernel.cmdline.clone())) } fn load_payload( _vm_resources: &VmResources, guest_mem: GuestMemoryMmap, + _arch_mem_info: &ArchMemoryInfo, payload: &Payload, -) -> std::result::Result<(GuestMemoryMmap, GuestAddress), StartMicrovmError> { +) -> std::result::Result< + ( + GuestMemoryMmap, + GuestAddress, + Option, + Option, + ), + StartMicrovmError, +> { match payload { #[cfg(target_arch = "aarch64")] Payload::KernelCopy => { @@ -1058,7 +1066,7 @@ fn load_payload( guest_mem .write(kernel_data, GuestAddress(kernel_guest_addr)) .unwrap(); - Ok((guest_mem, GuestAddress(kernel_entry_addr))) + Ok((guest_mem, GuestAddress(kernel_entry_addr), None, None)) } #[cfg(all(target_arch = "x86_64", not(feature = "tee")))] Payload::KernelMmap => { @@ -1087,14 +1095,17 @@ fn load_payload( )) .map_err(StartMicrovmError::GuestMemoryMmap)?, GuestAddress(kernel_entry_addr), + None, + None, )) } Payload::ExternalKernel(external_kernel) => { - let entry_addr = load_external_kernel(&guest_mem, external_kernel)?; - Ok((guest_mem, entry_addr)) + let (entry_addr, initrd_config, cmdline) = + load_external_kernel(&guest_mem, _arch_mem_info, external_kernel)?; + Ok((guest_mem, entry_addr, initrd_config, cmdline)) } #[cfg(test)] - Payload::Empty => Ok((guest_mem, GuestAddress(0))), + Payload::Empty => Ok((guest_mem, GuestAddress(0), None, None)), #[cfg(feature = "tee")] Payload::Tee => { let (kernel_host_addr, kernel_guest_addr, kernel_size) = @@ -1134,17 +1145,25 @@ fn load_payload( let initrd_data = unsafe { std::slice::from_raw_parts(initrd_host_addr as *mut u8, initrd_size) }; guest_mem - .write( - initrd_data, - GuestAddress(arch::x86_64::layout::INITRD_SEV_START), - ) + .write(initrd_data, GuestAddress(_arch_mem_info.initrd_addr)) .unwrap(); - Ok((guest_mem, GuestAddress(arch::RESET_VECTOR))) + + let initrd_config = InitrdConfig { + address: GuestAddress(_arch_mem_info.initrd_addr), + size: initrd_data.len(), + }; + + Ok(( + guest_mem, + GuestAddress(arch::RESET_VECTOR), + Some(initrd_config), + None, + )) } #[cfg(feature = "efi")] Payload::Efi => { guest_mem.write(EDK2_BINARY, GuestAddress(0u64)).unwrap(); - Ok((guest_mem, GuestAddress(0))) + Ok((guest_mem, GuestAddress(0), None, None)) } #[cfg(not(feature = "efi"))] Payload::Efi => { @@ -1153,12 +1172,18 @@ fn load_payload( } } +struct PayloadConfig { + entry_addr: GuestAddress, + initrd_config: Option, + kernel_cmdline: Option, +} + fn create_guest_memory( mem_size: usize, vm_resources: &VmResources, payload: &Payload, ) -> std::result::Result< - (GuestMemoryMmap, GuestAddress, ArchMemoryInfo, ShmManager), + (GuestMemoryMmap, ArchMemoryInfo, ShmManager, PayloadConfig), StartMicrovmError, > { let mem_size = mem_size << 20; @@ -1173,10 +1198,11 @@ fn create_guest_memory( } else { return Err(StartMicrovmError::MissingKernelConfig); }; - arch::arch_memory_regions(mem_size, Some(kernel_guest_addr), kernel_size) + arch::arch_memory_regions(mem_size, Some(kernel_guest_addr), kernel_size, 0) + } + Payload::ExternalKernel(external_kernel) => { + arch::arch_memory_regions(mem_size, None, 0, external_kernel.initramfs_size) } - #[cfg(not(feature = "efi"))] - Payload::ExternalKernel(_kernel_path) => arch::arch_memory_regions(mem_size, None, 0), #[cfg(feature = "tee")] Payload::Tee => { let (kernel_guest_addr, kernel_size) = @@ -1185,13 +1211,19 @@ fn create_guest_memory( } else { return Err(StartMicrovmError::MissingKernelConfig); }; - arch::arch_memory_regions(mem_size, Some(kernel_guest_addr), kernel_size) + arch::arch_memory_regions(mem_size, Some(kernel_guest_addr), kernel_size, 0) } #[cfg(test)] - Payload::Empty => arch::arch_memory_regions(mem_size, None, 0), + Payload::Empty => arch::arch_memory_regions(mem_size, None, 0, 0), + Payload::Efi => unreachable!(), }; #[cfg(target_arch = "aarch64")] - let (arch_mem_info, mut arch_mem_regions) = arch::arch_memory_regions(mem_size); + let (arch_mem_info, mut arch_mem_regions) = match payload { + Payload::ExternalKernel(external_kernel) => { + arch::arch_memory_regions(mem_size, external_kernel.initramfs_size) + } + _ => arch::arch_memory_regions(mem_size, 0), + }; let mut shm_manager = ShmManager::new(&arch_mem_info); @@ -1215,9 +1247,16 @@ fn create_guest_memory( let guest_mem = GuestMemoryMmap::from_ranges(&arch_mem_regions) .map_err(StartMicrovmError::GuestMemoryMmap)?; - let (guest_mem, entry_addr) = load_payload(vm_resources, guest_mem, payload)?; + let (guest_mem, entry_addr, initrd_config, cmdline) = + load_payload(vm_resources, guest_mem, &arch_mem_info, payload)?; - Ok((guest_mem, entry_addr, arch_mem_info, shm_manager)) + let payload_config = PayloadConfig { + entry_addr, + initrd_config, + kernel_cmdline: cmdline.clone(), + }; + + Ok((guest_mem, arch_mem_info, shm_manager, payload_config)) } #[cfg(all(target_arch = "x86_64", not(feature = "tee")))] @@ -1908,23 +1947,23 @@ fn attach_snd_device( #[cfg(test)] pub mod tests { use super::*; + use crate::vmm_config::kernel_bundle::KernelBundle; fn default_guest_memory( mem_size_mib: usize, - ) -> std::result::Result<(GuestMemoryMmap, ArchMemoryInfo, ShmManager), StartMicrovmError> { - let kernel_guest_addr: u64 = 0x1000; - let kernel_size: usize = 0x1000; - let kernel_host_addr: u64 = 0x1000; - - let kernel_region = unsafe { - MmapRegion::build_raw(kernel_host_addr as *mut _, kernel_size, 0, 0).unwrap() - }; + ) -> std::result::Result< + (GuestMemoryMmap, ArchMemoryInfo, ShmManager, PayloadConfig), + StartMicrovmError, + > { + let mut vm_resources = VmResources::default(); + vm_resources.kernel_bundle = Some(KernelBundle { + host_addr: 0x1000, + guest_addr: 0x1000, + entry_addr: 0x1000, + size: 0x1000, + }); - create_guest_memory( - mem_size_mib, - None, - Payload::KernelMmap(kernel_region, kernel_guest_addr, kernel_size), - ) + create_guest_memory(mem_size_mib, &vm_resources, &Payload::KernelMmap) } #[test] @@ -1932,7 +1971,8 @@ pub mod tests { fn test_create_vcpus_x86_64() { let vcpu_count = 2; - let (guest_memory, _arch_memory_info, _shm_manager) = default_guest_memory(128).unwrap(); + let (guest_memory, _arch_memory_info, _shm_manager, _payload_config) = + default_guest_memory(128).unwrap(); let mut vm = setup_vm(&guest_memory).unwrap(); #[cfg(not(feature = "intel-tdx"))] setup_interrupt_controller(&mut vm).unwrap(); diff --git a/src/vmm/src/resources.rs b/src/vmm/src/resources.rs index 34084bd0f..8d7390b22 100644 --- a/src/vmm/src/resources.rs +++ b/src/vmm/src/resources.rs @@ -330,6 +330,7 @@ mod tests { vm_config: VmConfig::default(), boot_config: default_boot_cfg(), kernel_bundle: Default::default(), + external_kernel: None, fs: Default::default(), vsock: Default::default(), #[cfg(feature = "net")] diff --git a/src/vmm/src/vmm_config/external_kernel.rs b/src/vmm/src/vmm_config/external_kernel.rs index 4b21d12e6..c6a26400c 100644 --- a/src/vmm/src/vmm_config/external_kernel.rs +++ b/src/vmm/src/vmm_config/external_kernel.rs @@ -30,4 +30,7 @@ impl Default for KernelFormat { pub struct ExternalKernel { pub path: PathBuf, pub format: KernelFormat, + pub initramfs_path: Option, + pub initramfs_size: u64, + pub cmdline: Option, } From fb4aa04b627c0822d1aae45be7796216b1cfe0aa Mon Sep 17 00:00:00 2001 From: Sergio Lopez Date: Wed, 19 Feb 2025 18:18:05 +0100 Subject: [PATCH 35/40] examples: add an example for external kernels Add an example for loading an external kernel, initramfs and custom kernel command line. Signed-off-by: Sergio Lopez --- examples/Makefile | 10 +- examples/external_kernel.c | 321 +++++++++++++++++++++++++++++++++++++ 2 files changed, 329 insertions(+), 2 deletions(-) create mode 100644 examples/external_kernel.c diff --git a/examples/Makefile b/examples/Makefile index 34aa56445..d0acd46d3 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -12,7 +12,7 @@ ROOTFS_DIR = rootfs_$(ROOTFS_DISTRO) .PHONY: clean rootfs -EXAMPLES := chroot_vm +EXAMPLES := chroot_vm external_kernel ifeq ($(SEV),1) EXAMPLES := launch-tee endif @@ -46,6 +46,12 @@ ifeq ($(OS),Darwin) codesign --entitlements chroot_vm.entitlements --force -s - $@ endif +external_kernel: external_kernel.c + gcc -o $@ $< $(CFLAGS) $(LDFLAGS_$(ARCH)_$(OS)) +ifeq ($(OS),Darwin) + codesign --entitlements chroot_vm.entitlements --force -s - $@ +endif + # Build the rootfs to be used with chroot_vm. rootfs: mkdir -p $(ROOTFS_DIR) @@ -54,4 +60,4 @@ rootfs: podman rm libkrun_chroot_vm clean: - rm -rf chroot_vm $(ROOTFS_DIR) launch-tee boot_efi + rm -rf chroot_vm $(ROOTFS_DIR) launch-tee boot_efi external_kernel diff --git a/examples/external_kernel.c b/examples/external_kernel.c new file mode 100644 index 000000000..c1b4dc1b5 --- /dev/null +++ b/examples/external_kernel.c @@ -0,0 +1,321 @@ +/* + * This is an example implementing chroot-like functionality with libkrun. + * + * It executes the requested command (relative to NEWROOT) inside a fresh + * Virtual Machine created and managed by libkrun. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_ARGS_LEN 4096 +#ifndef MAX_PATH +#define MAX_PATH 4096 +#endif + +enum net_mode +{ + NET_MODE_PASST = 0, + NET_MODE_TSI, +}; + +#if defined(__x86_64__) +#define KERNEL_FORMAT KRUN_KERNEL_FORMAT_ELF +#else +#define KERNEL_FORMAT KRUN_KERNEL_FORMAT_RAW +#endif + +static void print_help(char *const name) +{ + fprintf(stderr, + "Usage: %s [OPTIONS] KERNEL\n" + "OPTIONS: \n" + " -b --boot-disk Path to a boot disk in raw format\n" + " -c --kernel-cmdline Kernel command line\n" + " -d --data-disk Path to a data disk in raw format\n" + " -h --help Show help\n" + " -i --initrd Path to initramfs\n" + " --net=NET_MODE Set network mode\n" + " --passt-socket=PATH Connect to passt socket at PATH" + "\n" + "NET_MODE can be either TSI (default) or PASST\n" + "\n" +#if defined(__x86_64__) + "KERNEL: path to the kernel image in ELF format\n", +#else + "KERNEL: path to the kernel image in RAW format\n", +#endif + name); +} + +static const struct option long_options[] = { + {"boot-disk", required_argument, NULL, 'b'}, + {"kernel-cmdline", required_argument, NULL, 'c'}, + {"data-disk", required_argument, NULL, 'd'}, + {"initrd-path", required_argument, NULL, 'i'}, + {"help", no_argument, NULL, 'h'}, + {"passt-socket", required_argument, NULL, 'P'}, + {NULL, 0, NULL, 0}}; + +struct cmdline +{ + bool show_help; + enum net_mode net_mode; + char const *boot_disk; + char const *data_disk; + char const *passt_socket_path; + char const *kernel_path; + char const *kernel_cmdline; + char const *initrd_path; +}; + +bool parse_cmdline(int argc, char *const argv[], struct cmdline *cmdline) +{ + assert(cmdline != NULL); + + // set the defaults + *cmdline = (struct cmdline){ + .show_help = false, + .net_mode = NET_MODE_TSI, + .passt_socket_path = "/tmp/network.sock", + .boot_disk = NULL, + .data_disk = NULL, + .kernel_path = NULL, + .kernel_cmdline = NULL, + .initrd_path = NULL, + }; + + int option_index = 0; + int c; + // the '+' in optstring is a GNU extension that disables permutating argv + while ((c = getopt_long(argc, argv, "+hb:c:d:i:", long_options, &option_index)) != -1) + { + switch (c) + { + case 'b': + cmdline->boot_disk = optarg; + break; + case 'c': + cmdline->kernel_cmdline = optarg; + break; + case 'd': + cmdline->data_disk = optarg; + break; + case 'h': + cmdline->show_help = true; + return true; + case 'i': + cmdline->initrd_path = optarg; + break; + case 'P': + cmdline->passt_socket_path = optarg; + break; + case '?': + return false; + default: + fprintf(stderr, "internal argument parsing error (returned character code 0x%x)\n", c); + return false; + } + } + + if (optind <= argc - 1) + { + cmdline->kernel_path = argv[optind]; + return true; + } + + if (optind == argc) + { + fprintf(stderr, "Missing KERNEL argument\n"); + } + + return false; +} + +int connect_to_passt(char *socket_path) +{ + struct sockaddr_un addr; + int socket_fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (socket_fd < 0) + { + perror("Failed to create passt socket fd"); + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1); + + if (connect(socket_fd, (const struct sockaddr *)&addr, sizeof(addr)) < 0) + { + perror("Failed to bind passt socket"); + return -1; + } + + return socket_fd; +} + +int start_passt() +{ + int socket_fds[2]; + const int PARENT = 0; + const int CHILD = 1; + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_fds) < 0) + { + perror("Failed to create passt socket fd"); + return -1; + } + + int pid = fork(); + if (pid < 0) + { + perror("fork"); + return -1; + } + + if (pid == 0) + { // child + if (close(socket_fds[PARENT]) < 0) + { + perror("close PARENT"); + } + + char fd_as_str[16]; + snprintf(fd_as_str, sizeof(fd_as_str), "%d", socket_fds[CHILD]); + + printf("passing fd %s to passt", fd_as_str); + + if (execlp("passt", "passt", "-f", "--fd", fd_as_str, NULL) < 0) + { + perror("execlp"); + return -1; + } + } + else + { // parent + if (close(socket_fds[CHILD]) < 0) + { + perror("close CHILD"); + } + + return socket_fds[PARENT]; + } +} + +int main(int argc, char *const argv[]) +{ + int ctx_id; + int err; + pthread_t thread; + struct cmdline cmdline; + + if (!parse_cmdline(argc, argv, &cmdline)) + { + putchar('\n'); + print_help(argv[0]); + return -1; + } + + if (cmdline.show_help) + { + print_help(argv[0]); + return 0; + } + + // Set the log level to "off". + err = krun_set_log_level(0); + if (err) + { + errno = -err; + perror("Error configuring log level"); + return -1; + } + + // Create the configuration context. + ctx_id = krun_create_ctx(); + if (ctx_id < 0) + { + errno = -ctx_id; + perror("Error creating configuration context"); + return -1; + } + + // Configure the number of vCPUs (2) and the amount of RAM (1024 MiB). + if (err = krun_set_vm_config(ctx_id, 2, 2048)) + { + errno = -err; + perror("Error configuring the number of vCPUs and/or the amount of RAM"); + return -1; + } + + if (cmdline.boot_disk) + { + if (err = krun_add_disk(ctx_id, "boot", cmdline.boot_disk, 0)) + { + errno = -err, + perror("Error configuring boot disk"); + return -1; + } + } + if (cmdline.data_disk) + { + if (err = krun_add_disk(ctx_id, "data", cmdline.data_disk, 0)) + { + errno = -err, + perror("Error configuring data disk"); + return -1; + } + } + + if (cmdline.net_mode == NET_MODE_PASST) + { + int passt_fd = cmdline.passt_socket_path ? connect_to_passt(cmdline.passt_socket_path) : start_passt(); + + if (passt_fd < 0) + { + return -1; + } + + if (err = krun_set_passt_fd(ctx_id, passt_fd)) + { + errno = -err; + perror("Error configuring net mode"); + return -1; + } + } + + fprintf(stderr, "kernel_path: %s\n", cmdline.kernel_path); + fprintf(stderr, "kernel_cmdline: %s\n", cmdline.kernel_cmdline); + fflush(stderr); + + if (err = krun_set_kernel(ctx_id, cmdline.kernel_path, KERNEL_FORMAT, + cmdline.initrd_path, cmdline.kernel_cmdline)) + { + errno = -err; + perror("Error configuring kernel"); + return -1; + } + + // Start and enter the microVM. Unless there is some error while creating the microVM + // this function never returns. + if (err = krun_start_enter(ctx_id)) + { + errno = -err; + perror("Error creating the microVM"); + return -1; + } + + // Not reached. + return 0; +} From 0aaea80a57ddf89eb5336a8644d1144428602c63 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Tue, 18 Mar 2025 09:44:27 -0400 Subject: [PATCH 36/40] misc commit for changing cfg feat. should be added as its own name Signed-off-by: Jake Correnti --- examples/launch-tee | Bin 23736 -> 23736 bytes src/libkrun/src/lib.rs | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/launch-tee b/examples/launch-tee index 9b17ca98e2ea01a285ea174eae1debd80a547ae8..4c3371b9f2de60da6f6d01076c3ffa2bb913fd5e 100755 GIT binary patch delta 195 zcmdn7lX1sR#tj+F!ikB$>I8283sT)Fy8O-M^`SKihbC7u_fFPem6)u+VlX)ZNN2DZ zFg8sNWD#e~pS+PppYi?Vhb-=lQ$Zq=9atq8m)d@)N4^6JC0{|R&Mmzuj delta 167 zcmdn7lX1sR#tj+F!jt~FR9ybdnY}G+>dF}o@h#h)L{F|}?qxhOIgmwsvI2_%V-Aqz z&iEF@XN;V@kwu?z!Q_W5?vpuKBqlqsN=yy_(gmy%jQwC08^L59P@Tl&i>!W=Cj@X! zwr7)>yu)5-@)S0Cu9C!}lK9lTlGLKfhH`2yPmU8WC=lQ)^@ MF|OPE(B!&0083ju9smFU diff --git a/src/libkrun/src/lib.rs b/src/libkrun/src/lib.rs index 78a3eeefb..4e1d95d4e 100644 --- a/src/libkrun/src/lib.rs +++ b/src/libkrun/src/lib.rs @@ -69,9 +69,9 @@ const KRUN_SUCCESS: i32 = 0; const MAX_ARGS: usize = 4096; // krunfw library name for each context -#[cfg(all(target_os = "linux", not(feature = "amd-sev")))] +#[cfg(all(target_os = "linux", not(feature = "intel-tdx")))] const KRUNFW_NAME: &str = "libkrunfw.so.4"; -#[cfg(all(target_os = "linux", feature = "amd-sev"))] +#[cfg(all(target_os = "linux", feature = "intel-tdx"))] const KRUNFW_NAME: &str = "libkrunfw-sev.so.4"; #[cfg(all(target_os = "macos", not(feature = "efi")))] const KRUNFW_NAME: &str = "libkrunfw.4.dylib"; From 123a09ba9678dc9dccd8e9c7dc5a9c1ba22b155d Mon Sep 17 00:00:00 2001 From: Sergio Lopez Date: Thu, 6 Mar 2025 16:48:24 +0100 Subject: [PATCH 37/40] devices: generalize interrupt controllers So far we didn't have a general way for creating an managing IRQ chips. On KVM systems, the in-kernel chip was implicitly created by vstate, while on HVF the userspace gicv3 was created explicitly. In this change we generalize IRQ management behind IrqChip, and we make the creation of the IRQ chip explicit for every platform. This is a pretty large commit, but all these changes must be done in an atomic way. Signed-off-by: Sergio Lopez --- Cargo.lock | 4 +- src/arch/Cargo.toml | 3 - src/arch/src/aarch64/linux/gic.rs | 160 ---------------- src/arch/src/aarch64/linux/gicv2.rs | 114 ------------ src/arch/src/aarch64/linux/gicv3.rs | 117 ------------ src/arch/src/aarch64/linux/mod.rs | 3 - src/arch/src/aarch64/macos/gic.rs | 76 -------- src/arch/src/aarch64/macos/gicv2.rs | 88 --------- src/arch/src/aarch64/macos/gicv3.rs | 94 ---------- src/arch/src/aarch64/macos/mod.rs | 3 - src/arch/src/aarch64/mod.rs | 31 +--- src/arch/src/lib.rs | 23 --- src/devices/Cargo.toml | 5 + src/{arch/src/aarch64 => devices/src}/fdt.rs | 96 ++-------- src/devices/src/legacy/aarch64/gpio.rs | 16 +- src/devices/src/legacy/aarch64/serial.rs | 25 +-- src/devices/src/legacy/gic.rs | 16 ++ src/devices/src/legacy/gicv3.rs | 174 ++++++++++++------ src/devices/src/legacy/irqchip.rs | 96 ++++++++++ src/devices/src/legacy/kvmgicv3.rs | 146 +++++++++++++++ src/devices/src/legacy/kvmioapic.rs | 69 +++++++ src/devices/src/legacy/mod.rs | 11 ++ src/devices/src/lib.rs | 25 +++ src/devices/src/virtio/balloon/device.rs | 17 +- .../src/virtio/balloon/event_handler.rs | 4 +- src/devices/src/virtio/block/device.rs | 6 +- src/devices/src/virtio/block/worker.rs | 15 +- src/devices/src/virtio/console/device.rs | 4 +- .../src/virtio/console/irq_signaler.rs | 16 +- src/devices/src/virtio/fs/device.rs | 6 +- src/devices/src/virtio/fs/worker.rs | 16 +- src/devices/src/virtio/gpu/device.rs | 17 +- src/devices/src/virtio/gpu/virtio_gpu.rs | 13 +- src/devices/src/virtio/gpu/worker.rs | 17 +- src/devices/src/virtio/net/device.rs | 6 +- src/devices/src/virtio/net/worker.rs | 17 +- src/devices/src/virtio/rng/device.rs | 17 +- src/devices/src/virtio/rng/event_handler.rs | 4 +- src/devices/src/virtio/snd/device.rs | 6 +- src/devices/src/virtio/snd/mod.rs | 14 +- src/devices/src/virtio/snd/worker.rs | 16 +- src/devices/src/virtio/vsock/device.rs | 17 +- src/devices/src/virtio/vsock/muxer.rs | 16 +- src/devices/src/virtio/vsock/muxer_thread.rs | 16 +- src/devices/src/virtio/vsock/timesync.rs | 16 +- src/vmm/src/builder.rs | 127 ++++++------- src/vmm/src/device_manager/hvf/mmio.rs | 37 ++-- src/vmm/src/device_manager/kvm/mmio.rs | 31 ++-- src/vmm/src/lib.rs | 44 +++-- src/vmm/src/linux/vstate.rs | 99 +--------- src/vmm/src/macos/vstate.rs | 26 +-- 51 files changed, 782 insertions(+), 1253 deletions(-) delete mode 100644 src/arch/src/aarch64/linux/gic.rs delete mode 100644 src/arch/src/aarch64/linux/gicv2.rs delete mode 100644 src/arch/src/aarch64/linux/gicv3.rs delete mode 100644 src/arch/src/aarch64/macos/gic.rs delete mode 100644 src/arch/src/aarch64/macos/gicv2.rs delete mode 100644 src/arch/src/aarch64/macos/gicv3.rs rename src/{arch/src/aarch64 => devices/src}/fdt.rs (85%) create mode 100644 src/devices/src/legacy/gic.rs create mode 100644 src/devices/src/legacy/irqchip.rs create mode 100644 src/devices/src/legacy/kvmgicv3.rs create mode 100644 src/devices/src/legacy/kvmioapic.rs diff --git a/Cargo.lock b/Cargo.lock index 83b2fe1ce..ea7f0ef81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,7 +74,6 @@ dependencies = [ "smbios", "tdx", "utils", - "vm-fdt", "vm-memory", ] @@ -387,6 +386,8 @@ dependencies = [ "env_logger", "hvf", "imago", + "kvm-bindings", + "kvm-ioctls", "libc", "log", "lru", @@ -398,6 +399,7 @@ dependencies = [ "thiserror", "utils", "virtio-bindings", + "vm-fdt", "vm-memory", "zerocopy 0.6.6", "zerocopy-derive 0.6.6", diff --git a/src/arch/Cargo.toml b/src/arch/Cargo.toml index 0cd19bf73..5292015e8 100644 --- a/src/arch/Cargo.toml +++ b/src/arch/Cargo.toml @@ -23,8 +23,5 @@ kvm-bindings = { path = "../../../kvm-ioctls/kvm-bindings", features = ["fam-wra kvm-ioctls = { path = "../../../kvm-ioctls/kvm-ioctls"} tdx = { path = "../../../tdx", optional = true } -[target.'cfg(target_arch = "aarch64")'.dependencies] -vm-fdt = ">= 0.2.0" - [dev-dependencies] utils = { path = "../utils" } diff --git a/src/arch/src/aarch64/linux/gic.rs b/src/arch/src/aarch64/linux/gic.rs deleted file mode 100644 index 1f09c2c88..000000000 --- a/src/arch/src/aarch64/linux/gic.rs +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -use std::{boxed::Box, result}; - -use kvm_ioctls::{DeviceFd, VmFd}; - -use super::gicv2::GICv2; -use super::gicv3::GICv3; - -/// Errors thrown while setting up the GIC. -#[derive(Debug)] -pub enum Error { - /// Error while calling KVM ioctl for setting up the global interrupt controller. - CreateGIC(kvm_ioctls::Error), - /// Error while setting device attributes for the GIC. - SetDeviceAttribute(kvm_ioctls::Error), -} -type Result = result::Result; - -/// Trait for GIC devices. -pub trait GICDevice { - /// Returns the file descriptor of the GIC device - fn device_fd(&self) -> &DeviceFd; - - /// Returns an array with GIC device properties - fn device_properties(&self) -> &[u64]; - - /// Returns the number of vCPUs this GIC handles - fn vcpu_count(&self) -> u64; - - /// Returns the fdt compatibility property of the device - fn fdt_compatibility(&self) -> &str; - - /// Returns the maint_irq fdt property of the device - fn fdt_maint_irq(&self) -> u32; - - /// Returns the GIC version of the device - fn version() -> u32 - where - Self: Sized; - - /// Create the GIC device object - fn create_device(fd: DeviceFd, vcpu_count: u64) -> Box - where - Self: Sized; - - /// Setup the device-specific attributes - fn init_device_attributes(gic_device: &Box) -> Result<()> - where - Self: Sized; - - /// Initialize a GIC device - fn init_device(vm: &VmFd) -> Result - where - Self: Sized, - { - let mut gic_device = kvm_bindings::kvm_create_device { - type_: Self::version(), - fd: 0, - flags: 0, - }; - - vm.create_device(&mut gic_device).map_err(Error::CreateGIC) - } - - /// Set a GIC device attribute - fn set_device_attribute( - fd: &DeviceFd, - group: u32, - attr: u64, - addr: u64, - flags: u32, - ) -> Result<()> - where - Self: Sized, - { - let attr = kvm_bindings::kvm_device_attr { - group, - attr, - addr, - flags, - }; - fd.set_device_attr(&attr) - .map_err(Error::SetDeviceAttribute)?; - - Ok(()) - } - - /// Finalize the setup of a GIC device - fn finalize_device(gic_device: &Box) -> Result<()> - where - Self: Sized, - { - /* We need to tell the kernel how many irqs to support with this vgic. - * See the `layout` module for details. - */ - let nr_irqs: u32 = super::super::layout::IRQ_MAX - super::super::layout::IRQ_BASE + 1; - let nr_irqs_ptr = &nr_irqs as *const u32; - Self::set_device_attribute( - gic_device.device_fd(), - kvm_bindings::KVM_DEV_ARM_VGIC_GRP_NR_IRQS, - 0, - nr_irqs_ptr as u64, - 0, - )?; - - /* Finalize the GIC. - * See https://code.woboq.org/linux/linux/virt/kvm/arm/vgic/vgic-kvm-device.c.html#211. - */ - Self::set_device_attribute( - gic_device.device_fd(), - kvm_bindings::KVM_DEV_ARM_VGIC_GRP_CTRL, - u64::from(kvm_bindings::KVM_DEV_ARM_VGIC_CTRL_INIT), - 0, - 0, - )?; - - Ok(()) - } - - /// Method to initialize the GIC device - #[allow(clippy::new_ret_no_self)] - fn new(vm: &VmFd, vcpu_count: u64) -> Result> - where - Self: Sized, - { - let vgic_fd = Self::init_device(vm)?; - - let device = Self::create_device(vgic_fd, vcpu_count); - - Self::init_device_attributes(&device)?; - - Self::finalize_device(&device)?; - - Ok(device) - } -} - -/// Create a GIC device. -/// -/// It will try to create by default a GICv3 device. If that fails it will try -/// to fall-back to a GICv2 device. -pub fn create_gic(vm: &VmFd, vcpu_count: u64) -> Result> { - GICv3::new(vm, vcpu_count).or_else(|_| GICv2::new(vm, vcpu_count)) -} - -#[cfg(test)] -mod tests { - - use super::*; - use kvm_ioctls::Kvm; - - #[test] - fn test_create_gic() { - let kvm = Kvm::new().unwrap(); - let vm = kvm.create_vm().unwrap(); - assert!(create_gic(&vm, 1).is_ok()); - } -} diff --git a/src/arch/src/aarch64/linux/gicv2.rs b/src/arch/src/aarch64/linux/gicv2.rs deleted file mode 100644 index be66c8e0a..000000000 --- a/src/arch/src/aarch64/linux/gicv2.rs +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -use std::{boxed::Box, result}; - -use kvm_ioctls::DeviceFd; - -use super::gic::{Error, GICDevice}; - -type Result = result::Result; - -/// Represent a GIC v2 device -pub struct GICv2 { - /// The file descriptor for the KVM device - fd: DeviceFd, - - /// GIC device properties, to be used for setting up the fdt entry - properties: [u64; 4], - - /// Number of CPUs handled by the device - vcpu_count: u64, -} - -impl GICv2 { - // Unfortunately bindgen omits defines that are based on other defines. - // See arch/arm64/include/uapi/asm/kvm.h file from the linux kernel. - const KVM_VGIC_V2_DIST_SIZE: u64 = 0x1000; - const KVM_VGIC_V2_CPU_SIZE: u64 = 0x2000; - - // Device trees specific constants - const ARCH_GIC_V2_MAINT_IRQ: u32 = 8; - - /// Get the address of the GICv2 distributor. - const fn get_dist_addr() -> u64 { - super::super::layout::MAPPED_IO_START - GICv2::KVM_VGIC_V2_DIST_SIZE - } - - /// Get the size of the GIC_v2 distributor. - const fn get_dist_size() -> u64 { - GICv2::KVM_VGIC_V2_DIST_SIZE - } - - /// Get the address of the GIC_v2 CPU. - const fn get_cpu_addr() -> u64 { - GICv2::get_dist_addr() - GICv2::KVM_VGIC_V2_CPU_SIZE - } - - /// Get the size of the GIC_v2 CPU. - const fn get_cpu_size() -> u64 { - GICv2::KVM_VGIC_V2_CPU_SIZE - } -} - -impl GICDevice for GICv2 { - fn version() -> u32 { - kvm_bindings::kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V2 - } - - fn device_fd(&self) -> &DeviceFd { - &self.fd - } - - fn device_properties(&self) -> &[u64] { - &self.properties - } - - fn vcpu_count(&self) -> u64 { - self.vcpu_count - } - - fn fdt_compatibility(&self) -> &str { - "arm,gic-400" - } - - fn fdt_maint_irq(&self) -> u32 { - GICv2::ARCH_GIC_V2_MAINT_IRQ - } - - fn create_device(fd: DeviceFd, vcpu_count: u64) -> Box { - Box::new(GICv2 { - fd, - properties: [ - GICv2::get_dist_addr(), - GICv2::get_dist_size(), - GICv2::get_cpu_addr(), - GICv2::get_cpu_size(), - ], - vcpu_count, - }) - } - - fn init_device_attributes(gic_device: &Box) -> Result<()> { - /* Setting up the distributor attribute. - We are placing the GIC below 1GB so we need to substract the size of the distributor. */ - Self::set_device_attribute( - gic_device.device_fd(), - kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR, - u64::from(kvm_bindings::KVM_VGIC_V2_ADDR_TYPE_DIST), - &GICv2::get_dist_addr() as *const u64 as u64, - 0, - )?; - - /* Setting up the CPU attribute. */ - Self::set_device_attribute( - gic_device.device_fd(), - kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR, - u64::from(kvm_bindings::KVM_VGIC_V2_ADDR_TYPE_CPU), - &GICv2::get_cpu_addr() as *const u64 as u64, - 0, - )?; - - Ok(()) - } -} diff --git a/src/arch/src/aarch64/linux/gicv3.rs b/src/arch/src/aarch64/linux/gicv3.rs deleted file mode 100644 index a9b1b2054..000000000 --- a/src/arch/src/aarch64/linux/gicv3.rs +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -use std::{boxed::Box, result}; - -use kvm_ioctls::DeviceFd; - -use super::gic::{Error, GICDevice}; - -type Result = result::Result; - -pub struct GICv3 { - /// The file descriptor for the KVM device - fd: DeviceFd, - - /// GIC device properties, to be used for setting up the fdt entry - properties: [u64; 4], - - /// Number of CPUs handled by the device - vcpu_count: u64, -} - -impl GICv3 { - // Unfortunately bindgen omits defines that are based on other defines. - // See arch/arm64/include/uapi/asm/kvm.h file from the linux kernel. - const SZ_64K: u64 = 0x0001_0000; - const KVM_VGIC_V3_DIST_SIZE: u64 = GICv3::SZ_64K; - const KVM_VGIC_V3_REDIST_SIZE: u64 = (2 * GICv3::SZ_64K); - - // Device trees specific constants - const ARCH_GIC_V3_MAINT_IRQ: u32 = 9; - - /// Get the address of the GIC distributor. - fn get_dist_addr() -> u64 { - super::super::layout::MAPPED_IO_START - GICv3::KVM_VGIC_V3_DIST_SIZE - } - - /// Get the size of the GIC distributor. - fn get_dist_size() -> u64 { - GICv3::KVM_VGIC_V3_DIST_SIZE - } - - /// Get the address of the GIC redistributors. - fn get_redists_addr(vcpu_count: u64) -> u64 { - GICv3::get_dist_addr() - GICv3::get_redists_size(vcpu_count) - } - - /// Get the size of the GIC redistributors. - fn get_redists_size(vcpu_count: u64) -> u64 { - vcpu_count * GICv3::KVM_VGIC_V3_REDIST_SIZE - } -} - -impl GICDevice for GICv3 { - fn version() -> u32 { - kvm_bindings::kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V3 - } - - fn device_fd(&self) -> &DeviceFd { - &self.fd - } - - fn device_properties(&self) -> &[u64] { - &self.properties - } - - fn vcpu_count(&self) -> u64 { - self.vcpu_count - } - - fn fdt_compatibility(&self) -> &str { - "arm,gic-v3" - } - - fn fdt_maint_irq(&self) -> u32 { - GICv3::ARCH_GIC_V3_MAINT_IRQ - } - - fn create_device(fd: DeviceFd, vcpu_count: u64) -> Box { - Box::new(GICv3 { - fd, - properties: [ - GICv3::get_dist_addr(), - GICv3::get_dist_size(), - GICv3::get_redists_addr(vcpu_count), - GICv3::get_redists_size(vcpu_count), - ], - vcpu_count, - }) - } - - fn init_device_attributes(gic_device: &Box) -> Result<()> { - /* Setting up the distributor attribute. - We are placing the GIC below 1GB so we need to substract the size of the distributor. - */ - Self::set_device_attribute( - gic_device.device_fd(), - kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR, - u64::from(kvm_bindings::KVM_VGIC_V3_ADDR_TYPE_DIST), - &GICv3::get_dist_addr() as *const u64 as u64, - 0, - )?; - - /* Setting up the redistributors' attribute. - We are calculating here the start of the redistributors address. We have one per CPU. - */ - Self::set_device_attribute( - gic_device.device_fd(), - kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR, - u64::from(kvm_bindings::KVM_VGIC_V3_ADDR_TYPE_REDIST), - &GICv3::get_redists_addr(gic_device.vcpu_count()) as *const u64 as u64, - 0, - )?; - - Ok(()) - } -} diff --git a/src/arch/src/aarch64/linux/mod.rs b/src/arch/src/aarch64/linux/mod.rs index e81d7a168..0a86d1c06 100644 --- a/src/arch/src/aarch64/linux/mod.rs +++ b/src/arch/src/aarch64/linux/mod.rs @@ -1,4 +1 @@ -pub mod gic; -mod gicv2; -mod gicv3; pub mod regs; diff --git a/src/arch/src/aarch64/macos/gic.rs b/src/arch/src/aarch64/macos/gic.rs deleted file mode 100644 index 5566d2dbf..000000000 --- a/src/arch/src/aarch64/macos/gic.rs +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -use std::{boxed::Box, result}; - -use super::gicv3::GICv3; - -/// Errors thrown while setting up the GIC. -#[derive(Debug)] -pub enum Error {} -type Result = result::Result; - -/// Trait for GIC devices. -pub trait GICDevice: Send { - /// Returns an array with GIC device properties - fn device_properties(&self) -> &[u64]; - - /// Returns the number of vCPUs this GIC handles - fn vcpu_count(&self) -> u64; - - /// Returns the fdt compatibility property of the device - fn fdt_compatibility(&self) -> &str; - - /// Returns the maint_irq fdt property of the device - fn fdt_maint_irq(&self) -> u32; - - /// Returns the GIC version of the device - fn version() -> u32 - where - Self: Sized; - - /// Create the GIC device object - fn create_device(vcpu_count: u64) -> Box - where - Self: Sized; - - /// Setup the device-specific attributes - fn init_device_attributes(gic_device: &Box) -> Result<()> - where - Self: Sized; - - /// Set a GIC device attribute - fn set_device_attribute(_group: u32, _attr: u64, _addr: u64, _flags: u32) -> Result<()> - where - Self: Sized, - { - Ok(()) - } - - /// Finalize the setup of a GIC device - fn finalize_device(_gic_device: &Box) -> Result<()> - where - Self: Sized, - { - Ok(()) - } - - /// Method to initialize the GIC device - fn new(vcpu_count: u64) -> Result> - where - Self: Sized, - { - let device = Self::create_device(vcpu_count); - - Self::init_device_attributes(&device)?; - - Self::finalize_device(&device)?; - - Ok(device) - } -} - -/// Create a GICv3 device. -pub fn create_gic(vcpu_count: u64) -> Result> { - GICv3::new(vcpu_count) -} diff --git a/src/arch/src/aarch64/macos/gicv2.rs b/src/arch/src/aarch64/macos/gicv2.rs deleted file mode 100644 index 21dd161a2..000000000 --- a/src/arch/src/aarch64/macos/gicv2.rs +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -use std::{boxed::Box, result}; - -use super::gic::{Error, GICDevice}; - -type Result = result::Result; - -/// This is just a placeholder for building the FDT entry. -/// The actual emulated GICv2 is in devices/legacy. -pub struct GICv2 { - /// GIC device properties, to be used for setting up the fdt entry - properties: [u64; 4], - - /// Number of CPUs handled by the device - vcpu_count: u64, -} - -impl GICv2 { - // Unfortunately bindgen omits defines that are based on other defines. - // See arch/arm64/include/uapi/asm/kvm.h file from the linux kernel. - const GIC_V2_DIST_SIZE: u64 = 0x1000; - const GIC_V2_CPU_SIZE: u64 = 0x2000; - - // Device trees specific constants - const GIC_V2_MAINT_IRQ: u32 = 8; - - /// Get the address of the GICv2 distributor. - pub const fn get_dist_addr() -> u64 { - super::super::layout::MAPPED_IO_START - GICv2::GIC_V2_DIST_SIZE - } - - /// Get the size of the GIC_v2 distributor. - pub const fn get_dist_size() -> u64 { - GICv2::GIC_V2_DIST_SIZE - } - - /// Get the address of the GIC_v2 CPU. - pub const fn get_cpu_addr() -> u64 { - GICv2::get_dist_addr() - GICv2::GIC_V2_CPU_SIZE - } - - /// Get the size of the GIC_v2 CPU. - pub const fn get_cpu_size() -> u64 { - GICv2::GIC_V2_CPU_SIZE - } -} - -impl GICDevice for GICv2 { - fn version() -> u32 { - 0 - } - - fn device_properties(&self) -> &[u64] { - &self.properties - } - - fn vcpu_count(&self) -> u64 { - self.vcpu_count - } - - fn fdt_compatibility(&self) -> &str { - "arm,cortex-a15-gic" - } - - fn fdt_maint_irq(&self) -> u32 { - GICv2::GIC_V2_MAINT_IRQ - } - - fn create_device(vcpu_count: u64) -> Box { - Box::new(GICv2 { - properties: [ - GICv2::get_dist_addr(), - GICv2::get_dist_size(), - GICv2::get_cpu_addr(), - GICv2::get_cpu_size(), - ], - vcpu_count, - }) - } - - fn init_device_attributes(_gic_device: &Box) -> Result<()> { - /* Setting up the distributor attribute. - We are placing the GIC below 1GB so we need to substract the size of the distributor. */ - Ok(()) - } -} diff --git a/src/arch/src/aarch64/macos/gicv3.rs b/src/arch/src/aarch64/macos/gicv3.rs deleted file mode 100644 index a717e1bbf..000000000 --- a/src/arch/src/aarch64/macos/gicv3.rs +++ /dev/null @@ -1,94 +0,0 @@ -use std::{boxed::Box, result}; - -use super::gic::{Error, GICDevice}; - -type Result = result::Result; - -/// This is just a placeholder for building the FDT entry. -/// The actual emulated GICv3 is in devices/legacy. -pub struct GICv3 { - /// GIC device properties, to be used for setting up the fdt entry - properties: [u64; 4], - - /// Number of CPUs handled by the device - vcpu_count: u64, -} - -impl GICv3 { - const SZ_64K: u64 = 0x0001_0000; - - // Device trees specific constants - const GIC_V3_MAINT_IRQ: u32 = 8; - - /// Get the address of the GICv3 distributor. - pub fn get_dist_addr() -> u64 { - super::super::layout::MAPPED_IO_START - 3 * GICv3::SZ_64K - } - - /// Get the size of the GIC_v3 distributor. - pub const fn get_dist_size() -> u64 { - GICv3::SZ_64K - } - - /// Get the address of the GIC redistributors. - pub const fn compute_redists_addr(vcpu_count: u64) -> u64 { - super::super::layout::MAPPED_IO_START - - 3 * GICv3::SZ_64K - - GICv3::compute_redists_size(vcpu_count) - } - - pub fn get_redists_addr(&self) -> u64 { - Self::compute_redists_addr(self.vcpu_count) - } - - /// Get the size of the GIC redistributors. - pub const fn compute_redists_size(vcpu_count: u64) -> u64 { - vcpu_count * GICv3::get_redist_size() - } - - pub fn get_redists_size(&self) -> u64 { - GICv3::compute_redists_size(self.vcpu_count) - } - - pub const fn get_redist_size() -> u64 { - 2 * GICv3::SZ_64K - } -} - -impl GICDevice for GICv3 { - fn device_properties(&self) -> &[u64] { - &self.properties - } - - fn vcpu_count(&self) -> u64 { - self.vcpu_count - } - - fn fdt_compatibility(&self) -> &str { - "arm,gic-v3" - } - - fn fdt_maint_irq(&self) -> u32 { - GICv3::GIC_V3_MAINT_IRQ - } - - fn version() -> u32 { - 0 - } - - fn create_device(vcpu_count: u64) -> Box { - Box::new(GICv3 { - properties: [ - GICv3::get_dist_addr(), - GICv3::get_dist_size(), - GICv3::compute_redists_addr(vcpu_count), - GICv3::compute_redists_size(vcpu_count), - ], - vcpu_count, - }) - } - - fn init_device_attributes(_gic_device: &Box) -> Result<()> { - Ok(()) - } -} diff --git a/src/arch/src/aarch64/macos/mod.rs b/src/arch/src/aarch64/macos/mod.rs index 90ce234ea..66d1eb54e 100644 --- a/src/arch/src/aarch64/macos/mod.rs +++ b/src/arch/src/aarch64/macos/mod.rs @@ -1,6 +1,3 @@ #[allow(clippy::new_ret_no_self)] -pub mod gic; -pub mod gicv2; -pub mod gicv3; pub mod regs; pub mod sysreg; diff --git a/src/arch/src/aarch64/mod.rs b/src/arch/src/aarch64/mod.rs index c42cb5491..ed11c75ab 100644 --- a/src/arch/src/aarch64/mod.rs +++ b/src/arch/src/aarch64/mod.rs @@ -3,7 +3,6 @@ #![allow(clippy::borrowed_box)] -mod fdt; /// Layout for this aarch64 system. pub mod layout; @@ -16,10 +15,8 @@ pub mod macos; #[cfg(target_os = "macos")] pub use self::macos::*; -use std::collections::HashMap; use std::fmt::Debug; -use self::gic::GICDevice; use crate::{round_up, ArchMemoryInfo}; use vm_memory::{Address, GuestAddress, GuestMemory, GuestMemoryMmap}; @@ -29,8 +26,6 @@ use smbios; /// Errors thrown while configuring aarch64 system. #[derive(Debug)] pub enum Error { - /// Failed to create a Flattened Device Tree for this aarch64 microVM. - SetupFDT(fdt::Error), /// Failed to compute the initrd address. InitrdAddress, @@ -42,9 +37,6 @@ pub enum Error { /// The start of the memory area reserved for MMIO devices. pub const MMIO_MEM_START: u64 = layout::MAPPED_IO_START; -pub use self::fdt::DeviceInfoForFDT; -use crate::DeviceType; - /// Returns a Vec of the valid memory addresses for aarch64. /// See [`layout`](layout) module for a drawing of the specific memory model for this platform. pub fn arch_memory_regions( @@ -87,29 +79,12 @@ pub fn arch_memory_regions( /// * `gic_device` - The GIC device. /// * `initrd` - Information about an optional initrd. #[allow(clippy::too_many_arguments)] -pub fn configure_system( - guest_mem: &GuestMemoryMmap, - arch_memory_info: &ArchMemoryInfo, - cmdline_cstring: &str, - vcpu_mpidr: Vec, - device_info: &HashMap<(DeviceType, String), T>, - gic_device: &Box, - initrd: &Option, +pub fn configure_system( + _guest_mem: &GuestMemoryMmap, _smbios_oem_strings: &Option>, ) -> super::Result<()> { - fdt::create_fdt( - guest_mem, - arch_memory_info, - vcpu_mpidr, - cmdline_cstring, - device_info, - gic_device, - initrd, - ) - .map_err(Error::SetupFDT)?; - #[cfg(feature = "efi")] - smbios::setup_smbios(guest_mem, layout::SMBIOS_START, _smbios_oem_strings) + smbios::setup_smbios(_guest_mem, layout::SMBIOS_START, _smbios_oem_strings) .map_err(Error::Smbios)?; Ok(()) diff --git a/src/arch/src/lib.rs b/src/arch/src/lib.rs index c97674b16..453385ea5 100644 --- a/src/arch/src/lib.rs +++ b/src/arch/src/lib.rs @@ -4,7 +4,6 @@ //! Implements platform specific functionality. //! Supported platforms: x86_64 and aarch64. -use std::fmt; use std::result; #[derive(Default)] @@ -39,22 +38,6 @@ pub use crate::x86_64::{ /// Type for returning public functions outcome. pub type Result = result::Result; -/// Types of devices that can get attached to this platform. -#[derive(Clone, Debug, PartialEq, Eq, Hash, Copy)] -pub enum DeviceType { - /// Device Type: Virtio. - Virtio(u32), - /// Device Type: GPIO (PL061). - #[cfg(target_arch = "aarch64")] - Gpio, - /// Device Type: Serial. - #[cfg(target_arch = "aarch64")] - Serial, - /// Device Type: RTC. - #[cfg(target_arch = "aarch64")] - RTC, -} - /// Type for passing information about the initrd in the guest memory. pub struct InitrdConfig { /// Load address of initrd in guest memory @@ -74,9 +57,3 @@ pub fn round_down(size: usize, align: usize) -> usize { let page_mask = !(align - 1); size & page_mask } - -impl fmt::Display for DeviceType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{self:?}") - } -} diff --git a/src/devices/Cargo.toml b/src/devices/Cargo.toml index 7e5163467..8b2157166 100644 --- a/src/devices/Cargo.toml +++ b/src/devices/Cargo.toml @@ -43,3 +43,8 @@ lru = ">=0.9" [target.'cfg(target_os = "linux")'.dependencies] rutabaga_gfx = { path = "../rutabaga_gfx", features = ["x"], optional = true } caps = "0.5.5" +kvm-bindings = { path = "../../../kvm-ioctls/kvm-bindings", features = ["fam-wrappers"]} +kvm-ioctls = { path = "../../../kvm-ioctls/kvm-ioctls"} + +[target.'cfg(target_arch = "aarch64")'.dependencies] +vm-fdt = ">= 0.2.0" diff --git a/src/arch/src/aarch64/fdt.rs b/src/devices/src/fdt.rs similarity index 85% rename from src/arch/src/aarch64/fdt.rs rename to src/devices/src/fdt.rs index 02b451123..d374f2fac 100644 --- a/src/arch/src/aarch64/fdt.rs +++ b/src/devices/src/fdt.rs @@ -9,12 +9,12 @@ use std::collections::HashMap; use std::fmt::Debug; use std::{io, result}; -use super::super::DeviceType; -use super::super::InitrdConfig; -use super::get_fdt_addr; -use super::gic::GICDevice; -use super::layout::{GTIMER_HYP, GTIMER_PHYS, GTIMER_SEC, GTIMER_VIRT}; -use crate::ArchMemoryInfo; +use crate::legacy::gic::GICDevice; +use crate::legacy::IrqChip; +use crate::DeviceType; +use arch::aarch64::get_fdt_addr; +use arch::aarch64::layout::{GTIMER_HYP, GTIMER_PHYS, GTIMER_SEC, GTIMER_VIRT}; +use arch::{ArchMemoryInfo, InitrdConfig}; use vm_fdt::{Error as FdtError, FdtWriter}; use vm_memory::{Address, Bytes, GuestAddress, GuestMemoryError, GuestMemoryMmap}; @@ -76,7 +76,7 @@ pub fn create_fdt( vcpu_mpidr: Vec, cmdline: &str, device_info: &HashMap<(DeviceType, String), T>, - gic_device: &Box, + gic_device: &IrqChip, initrd: &Option, ) -> Result> { // Alocate stuff necessary for the holding the blob. @@ -177,10 +177,10 @@ fn create_memory_node( _guest_mem: &GuestMemoryMmap, arch_memory_info: &ArchMemoryInfo, ) -> Result<()> { - let mem_size = arch_memory_info.ram_last_addr - super::layout::DRAM_MEM_START; + let mem_size = arch_memory_info.ram_last_addr - arch::aarch64::layout::DRAM_MEM_START; // See https://github.com/torvalds/linux/blob/master/Documentation/devicetree/booting-without-of.txt#L960 // for an explanation of this. - let mem_reg_prop = generate_prop64(&[super::layout::DRAM_MEM_START, mem_size]); + let mem_reg_prop = generate_prop64(&[arch::aarch64::layout::DRAM_MEM_START, mem_size]); let mem_node = fdt.begin_node("memory")?; fdt.property_string("device_type", "memory")?; @@ -210,11 +210,12 @@ fn create_chosen_node( Ok(()) } -fn create_gic_node(fdt: &mut FdtWriter, gic_device: &Box) -> Result<()> { - let gic_reg_prop = generate_prop64(gic_device.device_properties()); +fn create_gic_node(fdt: &mut FdtWriter, gic_device: &IrqChip) -> Result<()> { + let gic_device = gic_device.lock().unwrap(); + let gic_reg_prop = generate_prop64(&gic_device.device_properties()); let intc_node = fdt.begin_node("intc")?; - fdt.property_string("compatible", gic_device.fdt_compatibility())?; + fdt.property_string("compatible", &gic_device.fdt_compatibility())?; fdt.property_null("interrupt-controller")?; // "interrupt-cells" field specifies the number of cells needed to encode an // interrupt source. The type shall be a and the value shall be 3 if no PPI affinity description @@ -422,74 +423,3 @@ fn create_devices_node( Ok(()) } - -#[cfg(test)] -mod tests { - use super::*; - use crate::aarch64::gic::create_gic; - use crate::aarch64::{arch_memory_regions, layout}; - use kvm_ioctls::Kvm; - - const LEN: u64 = 4096; - - #[derive(Clone, Debug)] - pub struct MMIODeviceInfo { - addr: u64, - irq: u32, - } - - impl DeviceInfoForFDT for MMIODeviceInfo { - fn addr(&self) -> u64 { - self.addr - } - fn irq(&self) -> u32 { - self.irq - } - fn length(&self) -> u64 { - LEN - } - } - - #[test] - fn test_create_fdt_with_devices() { - let (mem_info, regions) = arch_memory_regions(layout::FDT_MAX_SIZE + 0x1000); - let mem = GuestMemoryMmap::from_ranges(®ions).expect("Cannot initialize memory"); - - let dev_info: HashMap<(DeviceType, std::string::String), MMIODeviceInfo> = [ - ( - (DeviceType::Serial, DeviceType::Serial.to_string()), - MMIODeviceInfo { addr: 0x00, irq: 1 }, - ), - ( - (DeviceType::Virtio(1), "virtio".to_string()), - MMIODeviceInfo { - addr: 0x00 + LEN, - irq: 2, - }, - ), - ( - (DeviceType::RTC, "rtc".to_string()), - MMIODeviceInfo { - addr: 0x00 + 2 * LEN, - irq: 3, - }, - ), - ] - .iter() - .cloned() - .collect(); - let kvm = Kvm::new().unwrap(); - let vm = kvm.create_vm().unwrap(); - let gic = create_gic(&vm, 1).unwrap(); - assert!(create_fdt( - &mem, - &mem_info, - vec![0], - "console=tty0", - &dev_info, - &gic, - &None, - ) - .is_ok()) - } -} diff --git a/src/devices/src/legacy/aarch64/gpio.rs b/src/devices/src/legacy/aarch64/gpio.rs index a732c78f5..223157246 100644 --- a/src/devices/src/legacy/aarch64/gpio.rs +++ b/src/devices/src/legacy/aarch64/gpio.rs @@ -17,7 +17,7 @@ use utils::epoll::{EpollEvent, EventSet}; use utils::eventfd::EventFd; use crate::bus::BusDevice; -use crate::legacy::GicV3; +use crate::legacy::IrqChip; const OFS_DATA: u64 = 0x400; // Data Register const GPIODIR: u64 = 0x400; // Direction Register @@ -73,7 +73,7 @@ pub struct Gpio { afsel: u32, // GPIO irq_field interrupt_evt: EventFd, - intc: Option, + intc: Option, irq_line: Option, shutdown_efd: EventFd, } @@ -97,7 +97,7 @@ impl Gpio { } } - pub fn set_intc(&mut self, intc: GicV3) { + pub fn set_intc(&mut self, intc: IrqChip) { self.intc = Some(intc); } @@ -166,9 +166,13 @@ impl Gpio { fn trigger_gpio_interrupt(&self) { if let Some(intc) = &self.intc { - intc.set_irq(self.irq_line.unwrap()); - } else if let Err(e) = self.interrupt_evt.write(1) { - error!("Failed to signal used queue: {:?}", e); + if let Err(e) = intc + .lock() + .unwrap() + .set_irq(self.irq_line, Some(&self.interrupt_evt)) + { + warn!("Error signalling irq: {e:?}"); + } } } } diff --git a/src/devices/src/legacy/aarch64/serial.rs b/src/devices/src/legacy/aarch64/serial.rs index b0532e3da..2cf605c42 100644 --- a/src/devices/src/legacy/aarch64/serial.rs +++ b/src/devices/src/legacy/aarch64/serial.rs @@ -16,7 +16,8 @@ use utils::epoll::{EpollEvent, EventSet}; use utils::eventfd::EventFd; use crate::bus::BusDevice; -use crate::legacy::{GicV3, ReadableFd}; +use crate::legacy::{IrqChip, ReadableFd}; +use crate::Error as DeviceError; /* Registers */ const UARTDR: u64 = 0; @@ -50,7 +51,7 @@ const AMBA_ID_HIGH: u64 = 0x401; pub enum Error { BadWriteOffset(u64), DmaNotImplemented, - InterruptFailure(io::Error), + InterruptFailure(DeviceError), WriteAllFailure(io::Error), FlushFailure(io::Error), } @@ -60,7 +61,7 @@ impl fmt::Display for Error { match self { Error::BadWriteOffset(offset) => write!(f, "pl011_write: Bad Write Offset: {offset}"), Error::DmaNotImplemented => write!(f, "pl011: DMA not implemented."), - Error::InterruptFailure(e) => write!(f, "Failed to trigger interrupt: {e}"), + Error::InterruptFailure(e) => write!(f, "Failed to trigger interrupt: {e:?}"), Error::WriteAllFailure(e) => write!(f, "Failed to write: {e}"), Error::FlushFailure(e) => write!(f, "Failed to flush: {e}"), } @@ -89,7 +90,7 @@ pub struct Serial { read_trigger: u32, out: Option>, input: Option>, - intc: Option, + intc: Option, irq_line: Option, } @@ -177,7 +178,7 @@ impl Serial { Self::new(interrupt_evt, None, None) } - pub fn set_intc(&mut self, intc: GicV3) { + pub fn set_intc(&mut self, intc: IrqChip) { self.intc = Some(intc); } @@ -192,7 +193,7 @@ impl Serial { } /// Queues raw bytes for the guest to read and signals the interrupt - pub fn queue_input_bytes(&mut self, c: &[u8]) -> io::Result<()> { + pub fn queue_input_bytes(&mut self, c: &[u8]) -> result::Result<(), DeviceError> { self.read_fifo.extend(c); self.read_count += c.len() as u32; self.flags &= !PL011_FLAG_RXFE; @@ -305,13 +306,13 @@ impl Serial { Ok(()) } - fn trigger_interrupt(&mut self) -> result::Result<(), io::Error> { + fn trigger_interrupt(&mut self) -> result::Result<(), DeviceError> { if let Some(intc) = &self.intc { - intc.set_irq(self.irq_line.unwrap()); - Ok(()) - } else { - self.interrupt_evt.write(1) + intc.lock() + .unwrap() + .set_irq(self.irq_line, Some(&self.interrupt_evt))?; } + Ok(()) } } @@ -410,7 +411,7 @@ impl Subscriber for Serial { match input.read(&mut out[..]) { Ok(count) => { self.queue_input_bytes(&out[..count]) - .unwrap_or_else(|e| warn!("Serial error on input: {}", e)); + .unwrap_or_else(|e| warn!("Serial error on input: {:?}", e)); } Err(e) => { warn!("error while reading stdin: {:?}", e); diff --git a/src/devices/src/legacy/gic.rs b/src/devices/src/legacy/gic.rs new file mode 100644 index 000000000..28235dd21 --- /dev/null +++ b/src/devices/src/legacy/gic.rs @@ -0,0 +1,16 @@ +pub trait GICDevice { + /// Returns an array with GIC device properties + fn device_properties(&self) -> Vec; + + /// Returns the number of vCPUs this GIC handles + fn vcpu_count(&self) -> u64; + + /// Returns the fdt compatibility property of the device + fn fdt_compatibility(&self) -> String; + + /// Returns the maint_irq fdt property of the device + fn fdt_maint_irq(&self) -> u32; + + /// Returns the GIC version of the device + fn version(&self) -> u32; +} diff --git a/src/devices/src/legacy/gicv3.rs b/src/devices/src/legacy/gicv3.rs index 2d033f69f..f72cc95bc 100644 --- a/src/devices/src/legacy/gicv3.rs +++ b/src/devices/src/legacy/gicv3.rs @@ -1,10 +1,14 @@ use std::convert::TryInto; -use std::sync::{Arc, Mutex}; - -use arch::aarch64::gicv3::GICv3; +use std::io; +use std::sync::Arc; use crate::bus::BusDevice; +use crate::legacy::gic::GICDevice; +use crate::legacy::irqchip::IrqChipT; use crate::legacy::VcpuList; +use crate::Error as DeviceError; + +use utils::eventfd::EventFd; const IRQ_NUM: u32 = 288; const MAXIRQ: u32 = 1020; @@ -81,79 +85,76 @@ const GICR_TYPER_LAST_SHIFT: u64 = 4; const GICV3_PIDR0_DIST: u8 = 0x92; const GICV3_PIDR0_REDIST: u8 = 0x93; +// Device tree specific constants +const GICV3_BASE_SIZE: u64 = 0x0001_0000; +const GICV3_MAINT_IRQ: u32 = 8; + #[derive(Clone)] pub struct GicV3 { - gic: Arc>, -} + dist_addr: u64, + dist_size: u64, + redist_size: u64, + redists_addr: u64, + redists_size: u64, -impl GicV3 { - pub fn new(vcpu_list: Arc) -> Self { - Self { - gic: Arc::new(Mutex::new(GicV3Internal::new(vcpu_list))), - } - } + gicd_ctlr: u32, + vcpu_list: Arc, + revision: u8, + edge_trigger: [u32; BITMAP_SZ], + gicr_waker: u32, + gicd_irouter: [u64; MAXIRQ as usize], - pub fn get_mmio_addr(&self) -> u64 { - self.gic.lock().unwrap().get_mmio_addr() - } + /// GIC device properties, to be used for setting up the fdt entry + properties: [u64; 4], +} - pub fn get_mmio_size(&self) -> u64 { - self.gic.lock().unwrap().get_mmio_size() +impl GicV3 { + /// Get the address of the GICv3 distributor. + pub fn get_dist_addr(&self) -> u64 { + self.dist_addr } - pub fn set_irq(&self, irq_line: u32) { - self.gic.lock().unwrap().set_irq(irq_line) + /// Get the size of the GIC_v3 distributor. + pub const fn get_dist_size(&self) -> u64 { + self.dist_size } - pub fn as_device(&self) -> Arc> { - self.gic.clone() + pub fn get_redists_addr(&self) -> u64 { + self.redists_addr } -} -impl BusDevice for GicV3 { - fn read(&mut self, vcpuid: u64, offset: u64, data: &mut [u8]) { - self.gic.lock().unwrap().read(vcpuid, offset, data) + pub fn get_redists_size(&self) -> u64 { + self.redists_size } - fn write(&mut self, vcpuid: u64, offset: u64, data: &[u8]) { - self.gic.lock().unwrap().write(vcpuid, offset, data) + pub const fn get_redist_size(&self) -> u64 { + self.redist_size } -} - -struct GicV3Internal { - gicd_ctlr: u32, - vcpu_list: Arc, - revision: u8, - edge_trigger: [u32; BITMAP_SZ], - gicr_waker: u32, - gicd_irouter: [u64; MAXIRQ as usize], -} -impl GicV3Internal { pub fn new(vcpu_list: Arc) -> Self { + let vcpu_count = vcpu_list.get_cpu_count(); + let dist_size = GICV3_BASE_SIZE; + let dist_addr = arch::MMIO_MEM_START - 3 * dist_size; + let redist_size = 2 * dist_size; + let redists_size = redist_size * vcpu_count; + let redists_addr = dist_addr - redists_size; + Self { + dist_addr, + dist_size, + redist_size, + redists_addr, + redists_size, + gicd_ctlr: GICD_CTLR_DS | GICD_CTLR_ARE, vcpu_list, revision: 3, edge_trigger: [0; BITMAP_SZ], gicr_waker: GICR_WAKER_PROCESSOR_SLEEP | GICR_WAKER_CHILDREN_ASLEEP, gicd_irouter: [0; MAXIRQ as usize], - } - } - - pub fn get_mmio_addr(&self) -> u64 { - GICv3::compute_redists_addr(self.vcpu_list.get_cpu_count()) - } - - pub fn get_mmio_size(&self) -> u64 { - GICv3::get_dist_size() + GICv3::compute_redists_size(self.vcpu_list.get_cpu_count()) - } - pub fn set_irq(&self, irq_line: u32) { - assert!(irq_line < MAXIRQ, "[GICv3] intid out of range"); - // TODO(p1-0tr): extract full MPID, but for now Aff0 will do - let mpid = self.gicd_irouter[irq_line as usize] & 0xff; - self.vcpu_list.set_irq_common(mpid, irq_line); + properties: [dist_addr, dist_size, redists_addr, redists_size], + } } fn handle_dist_read32(&self, _vcpuid: u64, offset: u64, data: &mut [u8]) { @@ -390,10 +391,39 @@ impl GicV3Internal { } } -impl BusDevice for GicV3Internal { +impl IrqChipT for GicV3 { + fn get_mmio_addr(&self) -> u64 { + self.redists_addr + } + + fn get_mmio_size(&self) -> u64 { + self.dist_size + self.redists_size + } + + fn set_irq( + &self, + irq_line: Option, + _interrupt_evt: Option<&EventFd>, + ) -> Result<(), DeviceError> { + if let Some(irq_line) = irq_line { + assert!(irq_line < MAXIRQ, "[GICv3] intid out of range"); + // TODO(p1-0tr): extract full MPID, but for now Aff0 will do + let mpid = self.gicd_irouter[irq_line as usize] & 0xff; + self.vcpu_list.set_irq_common(mpid, irq_line); + Ok(()) + } else { + Err(DeviceError::FailedSignalingUsedQueue(io::Error::new( + io::ErrorKind::InvalidData, + "IRQ not line configured", + ))) + } + } +} + +impl BusDevice for GicV3 { fn read(&mut self, vcpuid: u64, offset: u64, data: &mut [u8]) { - if offset >= GICv3::compute_redists_size(self.vcpu_list.get_cpu_count()) { - let offset = offset - GICv3::compute_redists_size(self.vcpu_list.get_cpu_count()); + if offset >= self.redists_size { + let offset = offset - self.redists_size; match data.len() { 1 => panic!("GIC DIST read8 vcpuid={} offset=0x{:x}", vcpuid, offset), 2 => panic!("GIC DIST read16 vcpuid={} offset=0x{:x}", vcpuid, offset), @@ -402,8 +432,8 @@ impl BusDevice for GicV3Internal { _ => panic!("GIC DIST unsupported read size"), } } else { - let vcpuid = offset / GICv3::get_redist_size(); - let offset = offset % GICv3::get_redist_size(); + let vcpuid = offset / self.redist_size; + let offset = offset % self.redist_size; match data.len() { 1 => panic!("GIC REDIST read8 vcpuid={} offset=0x{:x}", vcpuid, offset), @@ -416,8 +446,8 @@ impl BusDevice for GicV3Internal { } fn write(&mut self, vcpuid: u64, offset: u64, data: &[u8]) { - if offset >= GICv3::compute_redists_size(self.vcpu_list.get_cpu_count()) { - let offset = offset - GICv3::compute_redists_size(self.vcpu_list.get_cpu_count()); + if offset >= self.redists_size { + let offset = offset - self.redists_size; match data.len() { 1 => panic!( "GIC DIST write8 vcpuid={} offset=0x{:x}, data={:?}", @@ -432,8 +462,8 @@ impl BusDevice for GicV3Internal { _ => panic!("GIC DIST unsupported read size"), } } else { - let vcpuid = offset / GICv3::get_redist_size(); - let offset = offset % GICv3::get_redist_size(); + let vcpuid = offset / self.redist_size; + let offset = offset % self.redist_size; match data.len() { 1 => panic!( @@ -455,6 +485,28 @@ impl BusDevice for GicV3Internal { } } +impl GICDevice for GicV3 { + fn device_properties(&self) -> Vec { + self.properties.to_vec() + } + + fn vcpu_count(&self) -> u64 { + self.vcpu_list.get_cpu_count() + } + + fn fdt_compatibility(&self) -> String { + "arm,gic-v3".to_string() + } + + fn fdt_maint_irq(&self) -> u32 { + GICV3_MAINT_IRQ + } + + fn version(&self) -> u32 { + 0 + } +} + fn half_shuffle32(val: u32) -> u32 { /* This algorithm is from _Hacker's Delight_ section 7-2 "Shuffling Bits". * It ignores any bits set in the top half of the input. diff --git a/src/devices/src/legacy/irqchip.rs b/src/devices/src/legacy/irqchip.rs new file mode 100644 index 000000000..b7c5679bc --- /dev/null +++ b/src/devices/src/legacy/irqchip.rs @@ -0,0 +1,96 @@ +use std::sync::{Arc, Mutex}; + +use crate::bus::BusDevice; +#[cfg(target_arch = "aarch64")] +use crate::legacy::gic::GICDevice; +use crate::Error as DeviceError; + +use utils::eventfd::EventFd; + +pub type IrqChip = Arc>; + +pub struct IrqChipDevice { + inner: Box, +} + +impl IrqChipDevice { + pub fn new(irqchip: Box) -> Self { + Self { inner: irqchip } + } + + pub fn get_mmio_addr(&self) -> u64 { + self.inner.get_mmio_addr() + } + + pub fn get_mmio_size(&self) -> u64 { + self.inner.get_mmio_size() + } + + pub fn set_irq( + &self, + irq_line: Option, + interrupt_evt: Option<&EventFd>, + ) -> Result<(), DeviceError> { + self.inner.set_irq(irq_line, interrupt_evt) + } +} + +impl BusDevice for IrqChipDevice { + fn read(&mut self, vcpuid: u64, offset: u64, data: &mut [u8]) { + self.inner.read(vcpuid, offset, data) + } + + fn write(&mut self, vcpuid: u64, offset: u64, data: &[u8]) { + self.inner.write(vcpuid, offset, data) + } +} + +#[cfg(target_arch = "aarch64")] +impl GICDevice for IrqChipDevice { + /// Returns an array with GIC device properties + fn device_properties(&self) -> Vec { + self.inner.device_properties().clone() + } + + /// Returns the number of vCPUs this GIC handles + fn vcpu_count(&self) -> u64 { + self.inner.vcpu_count() + } + + /// Returns the fdt compatibility property of the device + fn fdt_compatibility(&self) -> String { + self.inner.fdt_compatibility().clone() + } + + /// Returns the maint_irq fdt property of the device + fn fdt_maint_irq(&self) -> u32 { + self.inner.fdt_maint_irq() + } + + /// Returns the GIC version of the device + fn version(&self) -> u32 { + self.inner.version() + } +} + +#[cfg(target_arch = "x86_64")] +pub trait IrqChipT: BusDevice { + fn get_mmio_addr(&self) -> u64; + fn get_mmio_size(&self) -> u64; + fn set_irq( + &self, + irq_line: Option, + interrupt_evt: Option<&EventFd>, + ) -> Result<(), DeviceError>; +} + +#[cfg(target_arch = "aarch64")] +pub trait IrqChipT: BusDevice + GICDevice { + fn get_mmio_addr(&self) -> u64; + fn get_mmio_size(&self) -> u64; + fn set_irq( + &self, + irq_line: Option, + interrupt_evt: Option<&EventFd>, + ) -> Result<(), DeviceError>; +} diff --git a/src/devices/src/legacy/kvmgicv3.rs b/src/devices/src/legacy/kvmgicv3.rs new file mode 100644 index 000000000..72f12354d --- /dev/null +++ b/src/devices/src/legacy/kvmgicv3.rs @@ -0,0 +1,146 @@ +// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +use std::io; + +use crate::bus::BusDevice; +use crate::legacy::gic::GICDevice; +use crate::legacy::irqchip::IrqChipT; +use crate::Error as DeviceError; + +use kvm_ioctls::{DeviceFd, VmFd}; +use utils::eventfd::EventFd; + +const KVM_VGIC_V3_BASE_SIZE: u64 = 0x0001_0000; + +// Device trees specific constants +const ARCH_GIC_V3_MAINT_IRQ: u32 = 9; + +pub struct KvmGicV3 { + _device_fd: DeviceFd, + + /// GIC device properties, to be used for setting up the fdt entry + properties: [u64; 4], + + /// Number of CPUs handled by the device + vcpu_count: u64, +} + +impl KvmGicV3 { + pub fn new(vm: &VmFd, vcpu_count: u64) -> Self { + let dist_size = KVM_VGIC_V3_BASE_SIZE; + let dist_addr = arch::MMIO_MEM_START - dist_size; + let redist_size = 2 * dist_size; + let redists_size = redist_size * vcpu_count; + let redists_addr = dist_addr - redists_size; + + let mut gic_device = kvm_bindings::kvm_create_device { + type_: kvm_bindings::kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V3, + fd: 0, + flags: 0, + }; + let device_fd = vm.create_device(&mut gic_device).unwrap(); + + let attr = kvm_bindings::kvm_device_attr { + group: kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR, + attr: u64::from(kvm_bindings::KVM_VGIC_V3_ADDR_TYPE_DIST), + addr: &dist_addr as *const u64 as u64, + flags: 0, + }; + device_fd.set_device_attr(&attr).unwrap(); + + let attr = kvm_bindings::kvm_device_attr { + group: kvm_bindings::KVM_DEV_ARM_VGIC_GRP_ADDR, + attr: u64::from(kvm_bindings::KVM_VGIC_V3_ADDR_TYPE_REDIST), + addr: &redists_addr as *const u64 as u64, + flags: 0, + }; + device_fd.set_device_attr(&attr).unwrap(); + + let nr_irqs: u32 = arch::aarch64::layout::IRQ_MAX - arch::aarch64::layout::IRQ_BASE + 1; + let nr_irqs_ptr = &nr_irqs as *const u32; + let attr = kvm_bindings::kvm_device_attr { + group: kvm_bindings::KVM_DEV_ARM_VGIC_GRP_NR_IRQS, + attr: 0, + addr: nr_irqs_ptr as u64, + flags: 0, + }; + device_fd.set_device_attr(&attr).unwrap(); + + let attr = kvm_bindings::kvm_device_attr { + group: kvm_bindings::KVM_DEV_ARM_VGIC_GRP_CTRL, + attr: u64::from(kvm_bindings::KVM_DEV_ARM_VGIC_CTRL_INIT), + addr: 0, + flags: 0, + }; + device_fd.set_device_attr(&attr).unwrap(); + + Self { + _device_fd: device_fd, + properties: [dist_addr, dist_size, redists_addr, redists_size], + vcpu_count, + } + } +} + +impl IrqChipT for KvmGicV3 { + fn get_mmio_addr(&self) -> u64 { + 0 + } + + fn get_mmio_size(&self) -> u64 { + 0 + } + + fn set_irq( + &self, + _irq_line: Option, + interrupt_evt: Option<&EventFd>, + ) -> Result<(), DeviceError> { + if let Some(interrupt_evt) = interrupt_evt { + if let Err(e) = interrupt_evt.write(1) { + error!("Failed to signal used queue: {:?}", e); + return Err(DeviceError::FailedSignalingUsedQueue(e)); + } + } else { + error!("EventFd not set up for irq line"); + return Err(DeviceError::FailedSignalingUsedQueue(io::Error::new( + io::ErrorKind::NotFound, + format!("EventFd not set up for irq line"), + ))); + } + Ok(()) + } +} + +impl BusDevice for KvmGicV3 { + fn read(&mut self, _vcpuid: u64, _offset: u64, _data: &mut [u8]) { + unreachable!("MMIO operations are managed in-kernel"); + } + + fn write(&mut self, _vcpuid: u64, _offset: u64, _data: &[u8]) { + unreachable!("MMIO operations are managed in-kernel"); + } +} + +impl GICDevice for KvmGicV3 { + fn device_properties(&self) -> Vec { + self.properties.to_vec() + } + + fn vcpu_count(&self) -> u64 { + self.vcpu_count + } + + fn fdt_compatibility(&self) -> String { + "arm,gic-v3".to_string() + } + + fn fdt_maint_irq(&self) -> u32 { + ARCH_GIC_V3_MAINT_IRQ + } + + fn version(&self) -> u32 { + kvm_bindings::kvm_device_type_KVM_DEV_TYPE_ARM_VGIC_V3 + } +} diff --git a/src/devices/src/legacy/kvmioapic.rs b/src/devices/src/legacy/kvmioapic.rs new file mode 100644 index 000000000..8eff7dc89 --- /dev/null +++ b/src/devices/src/legacy/kvmioapic.rs @@ -0,0 +1,69 @@ +// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +use std::io; + +use crate::bus::BusDevice; +use crate::legacy::irqchip::IrqChipT; +use crate::Error as DeviceError; + +use kvm_bindings::{kvm_pit_config, KVM_PIT_SPEAKER_DUMMY}; +use kvm_ioctls::{Error, VmFd}; +use utils::eventfd::EventFd; + +pub struct KvmIoapic {} + +impl KvmIoapic { + pub fn new(vm: &VmFd) -> Result { + vm.create_irq_chip()?; + let pit_config = kvm_pit_config { + // We need to enable the emulation of a dummy speaker port stub so that writing to port + // 0x61 (i.e. KVM_SPEAKER_BASE_ADDRESS) does not trigger an exit to user space. + flags: KVM_PIT_SPEAKER_DUMMY, + ..Default::default() + }; + vm.create_pit2(pit_config)?; + + Ok(Self {}) + } +} + +impl IrqChipT for KvmIoapic { + fn get_mmio_addr(&self) -> u64 { + 0 + } + + fn get_mmio_size(&self) -> u64 { + 0 + } + + fn set_irq( + &self, + _irq_line: Option, + interrupt_evt: Option<&EventFd>, + ) -> Result<(), DeviceError> { + if let Some(interrupt_evt) = interrupt_evt { + if let Err(e) = interrupt_evt.write(1) { + error!("Failed to signal used queue: {:?}", e); + return Err(DeviceError::FailedSignalingUsedQueue(e)); + } + } else { + error!("EventFd not set up for irq line"); + return Err(DeviceError::FailedSignalingUsedQueue(io::Error::new( + io::ErrorKind::NotFound, + "EventFd not set up for irq line", + ))); + } + Ok(()) + } +} + +impl BusDevice for KvmIoapic { + fn read(&mut self, _vcpuid: u64, _offset: u64, _data: &mut [u8]) { + unreachable!("MMIO operations are managed in-kernel"); + } + + fn write(&mut self, _vcpuid: u64, _offset: u64, _data: &[u8]) { + unreachable!("MMIO operations are managed in-kernel"); + } +} diff --git a/src/devices/src/legacy/mod.rs b/src/devices/src/legacy/mod.rs index ee04fb253..f90fb7f8a 100644 --- a/src/devices/src/legacy/mod.rs +++ b/src/devices/src/legacy/mod.rs @@ -5,9 +5,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the THIRD-PARTY file. +pub mod gic; #[cfg(target_os = "macos")] mod gicv3; mod i8042; +mod irqchip; +#[cfg(all(target_os = "linux", target_arch = "aarch64"))] +mod kvmgicv3; +#[cfg(all(target_os = "linux", target_arch = "x86_64"))] +mod kvmioapic; #[cfg(target_arch = "aarch64")] mod rtc_pl031; #[cfg(target_os = "macos")] @@ -29,6 +35,11 @@ pub use self::gicv3::GicV3; pub use self::gpio::Gpio; pub use self::i8042::Error as I8042DeviceError; pub use self::i8042::I8042Device; +pub use self::irqchip::{IrqChip, IrqChipDevice, IrqChipT}; +#[cfg(all(target_os = "linux", target_arch = "aarch64"))] +pub use self::kvmgicv3::KvmGicV3; +#[cfg(all(target_os = "linux", target_arch = "x86_64"))] +pub use self::kvmioapic::KvmIoapic; #[cfg(target_arch = "aarch64")] pub use self::rtc_pl031::RTC; pub use self::serial::Serial; diff --git a/src/devices/src/lib.rs b/src/devices/src/lib.rs index 4c232f71c..789459fd8 100644 --- a/src/devices/src/lib.rs +++ b/src/devices/src/lib.rs @@ -10,9 +10,12 @@ #[macro_use] extern crate log; +use std::fmt; use std::io; mod bus; +#[cfg(target_arch = "aarch64")] +pub mod fdt; pub mod legacy; pub mod virtio; @@ -31,3 +34,25 @@ pub enum Error { NoAvailBuffers, SpuriousEvent, } + +/// Types of devices that can get attached to this platform. +#[derive(Clone, Debug, PartialEq, Eq, Hash, Copy)] +pub enum DeviceType { + /// Device Type: Virtio. + Virtio(u32), + /// Device Type: GPIO (PL061). + #[cfg(target_arch = "aarch64")] + Gpio, + /// Device Type: Serial. + #[cfg(target_arch = "aarch64")] + Serial, + /// Device Type: RTC. + #[cfg(target_arch = "aarch64")] + RTC, +} + +impl fmt::Display for DeviceType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{self:?}") + } +} diff --git a/src/devices/src/virtio/balloon/device.rs b/src/devices/src/virtio/balloon/device.rs index 98ea14efe..194e7ca6d 100644 --- a/src/devices/src/virtio/balloon/device.rs +++ b/src/devices/src/virtio/balloon/device.rs @@ -13,7 +13,7 @@ use super::super::{ VIRTIO_MMIO_INT_VRING, }; use super::{defs, defs::uapi}; -use crate::legacy::GicV3; +use crate::legacy::IrqChip; use crate::Error as DeviceError; // Inflate queue. @@ -59,7 +59,7 @@ pub struct Balloon { pub(crate) activate_evt: EventFd, pub(crate) device_state: DeviceState, config: VirtioBalloonConfig, - intc: Option, + intc: Option, irq_line: Option, } @@ -102,7 +102,7 @@ impl Balloon { defs::BALLOON_DEV_ID } - pub fn set_intc(&mut self, intc: GicV3) { + pub fn set_intc(&mut self, intc: IrqChip) { self.intc = Some(intc); } @@ -111,14 +111,11 @@ impl Balloon { self.interrupt_status .fetch_or(VIRTIO_MMIO_INT_VRING as usize, Ordering::SeqCst); if let Some(intc) = &self.intc { - intc.set_irq(self.irq_line.unwrap()); - Ok(()) - } else { - self.interrupt_evt.write(1).map_err(|e| { - error!("Failed to signal used queue: {:?}", e); - DeviceError::FailedSignalingUsedQueue(e) - }) + intc.lock() + .unwrap() + .set_irq(self.irq_line, Some(&self.interrupt_evt))?; } + Ok(()) } pub fn process_frq(&mut self) -> bool { diff --git a/src/devices/src/virtio/balloon/event_handler.rs b/src/devices/src/virtio/balloon/event_handler.rs index ef4ff2e03..035e5dae2 100644 --- a/src/devices/src/virtio/balloon/event_handler.rs +++ b/src/devices/src/virtio/balloon/event_handler.rs @@ -81,7 +81,9 @@ impl Balloon { e ); } else if self.process_frq() { - self.signal_used_queue().unwrap(); + if let Err(e) = self.signal_used_queue() { + warn!("Failed to signal queue: {e:?}"); + } } } diff --git a/src/devices/src/virtio/block/device.rs b/src/devices/src/virtio/block/device.rs index de8dafe2c..26f694238 100644 --- a/src/devices/src/virtio/block/device.rs +++ b/src/devices/src/virtio/block/device.rs @@ -35,7 +35,7 @@ use super::{ Error, QUEUE_SIZES, SECTOR_SHIFT, SECTOR_SIZE, }; -use crate::legacy::GicV3; +use crate::legacy::IrqChip; use crate::virtio::{block::ImageType, ActivateError}; /// Configuration options for disk caching. @@ -189,7 +189,7 @@ pub struct Block { pub(crate) partuuid: Option, // Interrupt specific fields. - intc: Option, + intc: Option, irq_line: Option, } @@ -271,7 +271,7 @@ impl Block { }) } - pub fn set_intc(&mut self, intc: GicV3) { + pub fn set_intc(&mut self, intc: IrqChip) { self.intc = Some(intc); } diff --git a/src/devices/src/virtio/block/worker.rs b/src/devices/src/virtio/block/worker.rs index 19d7d2133..88f13e8ac 100644 --- a/src/devices/src/virtio/block/worker.rs +++ b/src/devices/src/virtio/block/worker.rs @@ -1,4 +1,4 @@ -use crate::legacy::GicV3; +use crate::legacy::IrqChip; use crate::virtio::descriptor_utils::{Reader, Writer}; use crate::Error as DeviceError; @@ -51,7 +51,7 @@ pub struct BlockWorker { queue_evt: EventFd, interrupt_status: Arc, interrupt_evt: EventFd, - intc: Option, + intc: Option, irq_line: Option, mem: GuestMemoryMmap, @@ -66,7 +66,7 @@ impl BlockWorker { queue_evt: EventFd, interrupt_status: Arc, interrupt_evt: EventFd, - intc: Option, + intc: Option, irq_line: Option, mem: GuestMemoryMmap, disk: DiskProperties, @@ -271,12 +271,9 @@ impl BlockWorker { self.interrupt_status .fetch_or(VIRTIO_MMIO_INT_VRING as usize, Ordering::SeqCst); if let Some(intc) = &self.intc { - intc.set_irq(self.irq_line.unwrap()); - } else { - self.interrupt_evt.write(1).map_err(|e| { - error!("Failed to signal used queue: {:?}", e); - DeviceError::FailedSignalingUsedQueue(e) - })?; + intc.lock() + .unwrap() + .set_irq(self.irq_line, Some(&self.interrupt_evt))?; } Ok(()) } diff --git a/src/devices/src/virtio/console/device.rs b/src/devices/src/virtio/console/device.rs index 6b746f6c1..dadcf4dbe 100644 --- a/src/devices/src/virtio/console/device.rs +++ b/src/devices/src/virtio/console/device.rs @@ -15,7 +15,7 @@ use super::super::{ ActivateError, ActivateResult, ConsoleError, DeviceState, Queue as VirtQueue, VirtioDevice, }; use super::{defs, defs::control_event, defs::uapi}; -use crate::legacy::GicV3; +use crate::legacy::IrqChip; use crate::virtio::console::console_control::{ ConsoleControl, VirtioConsoleControl, VirtioConsoleResize, }; @@ -142,7 +142,7 @@ impl Console { defs::CONSOLE_DEV_ID } - pub fn set_intc(&mut self, intc: GicV3) { + pub fn set_intc(&mut self, intc: IrqChip) { self.irq.set_intc(intc) } diff --git a/src/devices/src/virtio/console/irq_signaler.rs b/src/devices/src/virtio/console/irq_signaler.rs index e84aa3762..c482cddc5 100644 --- a/src/devices/src/virtio/console/irq_signaler.rs +++ b/src/devices/src/virtio/console/irq_signaler.rs @@ -3,14 +3,14 @@ use std::sync::Arc; use utils::eventfd::EventFd; -use crate::legacy::GicV3; +use crate::legacy::IrqChip; use crate::virtio::{VIRTIO_MMIO_INT_CONFIG, VIRTIO_MMIO_INT_VRING}; #[derive(Clone)] pub struct IRQSignaler { interrupt_status: Arc, interrupt_evt: Arc, - intc: Option, + intc: Option, irq_line: Option, } @@ -32,9 +32,13 @@ impl IRQSignaler { self.interrupt_status .fetch_or(VIRTIO_MMIO_INT_VRING as usize, Ordering::SeqCst); if let Some(intc) = &self.intc { - intc.set_irq(self.irq_line.unwrap()); - } else if let Err(e) = self.interrupt_evt.write(1) { - error!("Failed to signal used queue: {e:?}"); + if let Err(e) = intc + .lock() + .unwrap() + .set_irq(self.irq_line, Some(&self.interrupt_evt)) + { + error!("Failed to signal used queue: {e:?}"); + } } } @@ -55,7 +59,7 @@ impl IRQSignaler { self.interrupt_status.clone() } - pub fn set_intc(&mut self, intc: GicV3) { + pub fn set_intc(&mut self, intc: IrqChip) { self.intc = Some(intc); } diff --git a/src/devices/src/virtio/fs/device.rs b/src/devices/src/virtio/fs/device.rs index 9d7a21e04..af4617a65 100644 --- a/src/devices/src/virtio/fs/device.rs +++ b/src/devices/src/virtio/fs/device.rs @@ -19,7 +19,7 @@ use super::passthrough; use super::worker::FsWorker; use super::ExportTable; use super::{defs, defs::uapi}; -use crate::legacy::GicV3; +use crate::legacy::IrqChip; #[derive(Copy, Clone)] #[repr(C, packed)] @@ -46,7 +46,7 @@ pub struct Fs { acked_features: u64, interrupt_status: Arc, interrupt_evt: EventFd, - intc: Option, + intc: Option, irq_line: Option, device_state: DeviceState, config: VirtioFsConfig, @@ -114,7 +114,7 @@ impl Fs { defs::FS_DEV_ID } - pub fn set_intc(&mut self, intc: GicV3) { + pub fn set_intc(&mut self, intc: IrqChip) { self.intc = Some(intc); } diff --git a/src/devices/src/virtio/fs/worker.rs b/src/devices/src/virtio/fs/worker.rs index a0b93e08d..703e8859a 100644 --- a/src/devices/src/virtio/fs/worker.rs +++ b/src/devices/src/virtio/fs/worker.rs @@ -17,7 +17,7 @@ use super::defs::{HPQ_INDEX, REQ_INDEX}; use super::descriptor_utils::{Reader, Writer}; use super::passthrough::{self, PassthroughFs}; use super::server::Server; -use crate::legacy::GicV3; +use crate::legacy::IrqChip; use crate::virtio::VirtioShmRegion; pub struct FsWorker { @@ -25,7 +25,7 @@ pub struct FsWorker { queue_evts: Vec, interrupt_status: Arc, interrupt_evt: EventFd, - intc: Option, + intc: Option, irq_line: Option, mem: GuestMemoryMmap, @@ -43,7 +43,7 @@ impl FsWorker { queue_evts: Vec, interrupt_status: Arc, interrupt_evt: EventFd, - intc: Option, + intc: Option, irq_line: Option, mem: GuestMemoryMmap, shm_region: Option, @@ -184,9 +184,13 @@ impl FsWorker { self.interrupt_status .fetch_or(VIRTIO_MMIO_INT_VRING as usize, Ordering::SeqCst); if let Some(intc) = &self.intc { - intc.set_irq(self.irq_line.unwrap()); - } else if let Err(e) = self.interrupt_evt.write(1) { - error!("Failed to signal used queue: {:?}", e); + if let Err(e) = intc + .lock() + .unwrap() + .set_irq(self.irq_line, Some(&self.interrupt_evt)) + { + error!("Failed to signal used queue: {:?}", e); + } } } } diff --git a/src/devices/src/virtio/gpu/device.rs b/src/devices/src/virtio/gpu/device.rs index fc72f80f9..061892881 100644 --- a/src/devices/src/virtio/gpu/device.rs +++ b/src/devices/src/virtio/gpu/device.rs @@ -15,7 +15,7 @@ use super::defs; use super::defs::uapi; use super::defs::uapi::virtio_gpu_config; use super::worker::Worker; -use crate::legacy::GicV3; +use crate::legacy::IrqChip; use crate::Error as DeviceError; #[cfg(target_os = "macos")] use hvf::MemoryMapping; @@ -44,7 +44,7 @@ pub struct Gpu { pub(crate) activate_evt: EventFd, pub(crate) device_state: DeviceState, shm_region: Option, - intc: Option, + intc: Option, irq_line: Option, pub(crate) sender: Option>, virgl_flags: u32, @@ -110,7 +110,7 @@ impl Gpu { defs::GPU_DEV_ID } - pub fn set_intc(&mut self, intc: GicV3) { + pub fn set_intc(&mut self, intc: IrqChip) { self.intc = Some(intc); } @@ -128,14 +128,11 @@ impl Gpu { self.interrupt_status .fetch_or(VIRTIO_MMIO_INT_VRING as usize, Ordering::SeqCst); if let Some(intc) = &self.intc { - intc.set_irq(self.irq_line.unwrap()); - Ok(()) - } else { - self.interrupt_evt.write(1).map_err(|e| { - error!("Failed to signal used queue: {:?}", e); - DeviceError::FailedSignalingUsedQueue(e) - }) + intc.lock() + .unwrap() + .set_irq(self.irq_line, Some(&self.interrupt_evt))?; } + Ok(()) } /* diff --git a/src/devices/src/virtio/gpu/virtio_gpu.rs b/src/devices/src/virtio/gpu/virtio_gpu.rs index d457e17f8..ad0e1e4d2 100644 --- a/src/devices/src/virtio/gpu/virtio_gpu.rs +++ b/src/devices/src/virtio/gpu/virtio_gpu.rs @@ -38,7 +38,7 @@ use super::protocol::{ }; use super::{GpuError, Result}; -use crate::legacy::GicV3; +use crate::legacy::IrqChip; use crate::virtio::fs::ExportTable; use crate::virtio::gpu::protocol::VIRTIO_GPU_FLAG_INFO_RING_IDX; use crate::virtio::{VirtioShmRegion, VIRTIO_MMIO_INT_VRING}; @@ -117,7 +117,7 @@ impl VirtioGpu { fence_state: Arc>, interrupt_status: Arc, interrupt_evt: EventFd, - intc: Option, + intc: Option, irq_line: Option, ) -> RutabagaFenceHandler { RutabagaFenceHandler::new(move |completed_fence: RutabagaFence| { @@ -157,9 +157,10 @@ impl VirtioGpu { interrupt_status.fetch_or(VIRTIO_MMIO_INT_VRING as usize, Ordering::SeqCst); if let Some(intc) = &intc { - intc.set_irq(irq_line.unwrap()); - } else if let Err(e) = interrupt_evt.write(1) { - error!("Failed to signal used queue: {:?}", e); + if let Err(e) = intc.lock().unwrap().set_irq(irq_line, Some(&interrupt_evt)) + { + error!("Failed to signal used queue: {:?}", e); + } } } else { i += 1; @@ -178,7 +179,7 @@ impl VirtioGpu { queue_ctl: Arc>, interrupt_status: Arc, interrupt_evt: EventFd, - intc: Option, + intc: Option, irq_line: Option, virgl_flags: u32, #[cfg(target_os = "macos")] map_sender: Sender, diff --git a/src/devices/src/virtio/gpu/worker.rs b/src/devices/src/virtio/gpu/worker.rs index a8c6f0ce4..d84b792e5 100644 --- a/src/devices/src/virtio/gpu/worker.rs +++ b/src/devices/src/virtio/gpu/worker.rs @@ -21,7 +21,7 @@ use super::protocol::{ virtio_gpu_ctrl_hdr, virtio_gpu_mem_entry, GpuCommand, GpuResponse, VirtioGpuResult, }; use super::virtio_gpu::VirtioGpu; -use crate::legacy::GicV3; +use crate::legacy::IrqChip; use crate::virtio::fs::ExportTable; use crate::virtio::gpu::protocol::{VIRTIO_GPU_FLAG_FENCE, VIRTIO_GPU_FLAG_INFO_RING_IDX}; use crate::virtio::gpu::virtio_gpu::VirtioGpuRing; @@ -34,7 +34,7 @@ pub struct Worker { queue_ctl: Arc>, interrupt_status: Arc, interrupt_evt: EventFd, - intc: Option, + intc: Option, irq_line: Option, shm_region: VirtioShmRegion, virgl_flags: u32, @@ -51,7 +51,7 @@ impl Worker { queue_ctl: Arc>, interrupt_status: Arc, interrupt_evt: EventFd, - intc: Option, + intc: Option, irq_line: Option, shm_region: VirtioShmRegion, virgl_flags: u32, @@ -110,14 +110,11 @@ impl Worker { self.interrupt_status .fetch_or(VIRTIO_MMIO_INT_VRING as usize, Ordering::SeqCst); if let Some(intc) = &self.intc { - intc.set_irq(self.irq_line.unwrap()); - Ok(()) - } else { - self.interrupt_evt.write(1).map_err(|e| { - error!("Failed to signal used queue: {:?}", e); - DeviceError::FailedSignalingUsedQueue(e) - }) + intc.lock() + .unwrap() + .set_irq(self.irq_line, Some(&self.interrupt_evt))?; } + Ok(()) } fn process_gpu_command( diff --git a/src/devices/src/virtio/net/device.rs b/src/devices/src/virtio/net/device.rs index 65b8fb2b9..e7a363a75 100644 --- a/src/devices/src/virtio/net/device.rs +++ b/src/devices/src/virtio/net/device.rs @@ -4,7 +4,7 @@ // Portions Copyright 2017 The Chromium OS Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the THIRD-PARTY file. -use crate::legacy::GicV3; +use crate::legacy::IrqChip; use crate::virtio::net::{Error, Result}; use crate::virtio::net::{QUEUE_SIZES, RX_INDEX, TX_INDEX}; use crate::virtio::queue::Error as QueueError; @@ -84,7 +84,7 @@ pub struct Net { pub(crate) device_state: DeviceState, - intc: Option, + intc: Option, irq_line: Option, config: VirtioNetConfig, @@ -143,7 +143,7 @@ impl Net { &self.id } - pub fn set_intc(&mut self, intc: GicV3) { + pub fn set_intc(&mut self, intc: IrqChip) { self.intc = Some(intc); } } diff --git a/src/devices/src/virtio/net/worker.rs b/src/devices/src/virtio/net/worker.rs index 599154f43..015463dbc 100644 --- a/src/devices/src/virtio/net/worker.rs +++ b/src/devices/src/virtio/net/worker.rs @@ -1,4 +1,4 @@ -use crate::legacy::GicV3; +use crate::legacy::IrqChip; use crate::virtio::net::gvproxy::Gvproxy; use crate::virtio::net::passt::Passt; use crate::virtio::net::{MAX_BUFFER_SIZE, QUEUE_SIZE, RX_INDEX, TX_INDEX}; @@ -36,7 +36,7 @@ pub struct NetWorker { queue_evts: Vec, interrupt_status: Arc, interrupt_evt: EventFd, - intc: Option, + intc: Option, irq_line: Option, mem: GuestMemoryMmap, @@ -58,7 +58,7 @@ impl NetWorker { queue_evts: Vec, interrupt_status: Arc, interrupt_evt: EventFd, - intc: Option, + intc: Option, irq_line: Option, mem: GuestMemoryMmap, cfg_backend: VirtioNetBackend, @@ -383,14 +383,11 @@ impl NetWorker { self.interrupt_status .fetch_or(VIRTIO_MMIO_INT_VRING as usize, Ordering::SeqCst); if let Some(intc) = &self.intc { - intc.set_irq(self.irq_line.unwrap()); - Ok(()) - } else { - self.interrupt_evt.write(1).map_err(|e| { - error!("Failed to signal used queue: {:?}", e); - DeviceError::FailedSignalingUsedQueue(e) - }) + intc.lock() + .unwrap() + .set_irq(self.irq_line, Some(&self.interrupt_evt))?; } + Ok(()) } // Copies a single frame from `self.rx_frame_buf` into the guest. diff --git a/src/devices/src/virtio/rng/device.rs b/src/devices/src/virtio/rng/device.rs index eafcb06be..7bf7b4acb 100644 --- a/src/devices/src/virtio/rng/device.rs +++ b/src/devices/src/virtio/rng/device.rs @@ -11,7 +11,7 @@ use super::super::{ VIRTIO_MMIO_INT_VRING, }; use super::{defs, defs::uapi}; -use crate::legacy::GicV3; +use crate::legacy::IrqChip; use crate::Error as DeviceError; // Request queue. @@ -33,7 +33,7 @@ pub struct Rng { pub(crate) interrupt_evt: EventFd, pub(crate) activate_evt: EventFd, pub(crate) device_state: DeviceState, - intc: Option, + intc: Option, irq_line: Option, } @@ -71,7 +71,7 @@ impl Rng { defs::RNG_DEV_ID } - pub fn set_intc(&mut self, intc: GicV3) { + pub fn set_intc(&mut self, intc: IrqChip) { self.intc = Some(intc); } @@ -80,14 +80,11 @@ impl Rng { self.interrupt_status .fetch_or(VIRTIO_MMIO_INT_VRING as usize, Ordering::SeqCst); if let Some(intc) = &self.intc { - intc.set_irq(self.irq_line.unwrap()); - Ok(()) - } else { - self.interrupt_evt.write(1).map_err(|e| { - error!("Failed to signal used queue: {:?}", e); - DeviceError::FailedSignalingUsedQueue(e) - }) + intc.lock() + .unwrap() + .set_irq(self.irq_line, Some(&self.interrupt_evt))?; } + Ok(()) } pub fn process_req(&mut self) -> bool { diff --git a/src/devices/src/virtio/rng/event_handler.rs b/src/devices/src/virtio/rng/event_handler.rs index e46d0d215..c48daf49d 100644 --- a/src/devices/src/virtio/rng/event_handler.rs +++ b/src/devices/src/virtio/rng/event_handler.rs @@ -19,7 +19,9 @@ impl Rng { if let Err(e) = self.queue_events[REQ_INDEX].read() { error!("Failed to read request queue event: {:?}", e); } else if self.process_req() { - self.signal_used_queue().unwrap(); + if let Err(e) = self.signal_used_queue() { + warn!("Failed to signal queue: {e:?}"); + } } } diff --git a/src/devices/src/virtio/snd/device.rs b/src/devices/src/virtio/snd/device.rs index 082f967f4..1efd96491 100644 --- a/src/devices/src/virtio/snd/device.rs +++ b/src/devices/src/virtio/snd/device.rs @@ -12,7 +12,7 @@ use super::virtio_sound::VirtioSoundConfig; use super::worker::SndWorker; use super::{defs, defs::uapi, defs::QUEUE_INDEXES, Error}; -use crate::legacy::GicV3; +use crate::legacy::IrqChip; use crate::virtio::DeviceState; // Supported features. @@ -31,7 +31,7 @@ pub struct Snd { pub(crate) interrupt_evt: EventFd, pub(crate) activate_evt: EventFd, pub(crate) device_state: DeviceState, - intc: Option, + intc: Option, irq_line: Option, worker_thread: Option>, worker_stopfd: EventFd, @@ -76,7 +76,7 @@ impl Snd { defs::SND_DEV_ID } - pub fn set_intc(&mut self, intc: GicV3) { + pub fn set_intc(&mut self, intc: IrqChip) { self.intc = Some(intc); } } diff --git a/src/devices/src/virtio/snd/mod.rs b/src/devices/src/virtio/snd/mod.rs index 87e12077c..9d30fb009 100644 --- a/src/devices/src/virtio/snd/mod.rs +++ b/src/devices/src/virtio/snd/mod.rs @@ -22,7 +22,7 @@ use virtio_sound::*; use super::{Descriptor, Queue}; use crate::{ - legacy::GicV3, + legacy::IrqChip, virtio::{ snd::virtio_sound::{VirtioSoundHeader, VirtioSoundPcmStatus}, VIRTIO_MMIO_INT_VRING, @@ -182,7 +182,7 @@ pub struct Vring { queue: Queue, interrupt_evt: EventFd, interrupt_status: Arc, - intc: Option, + intc: Option, irq_line: Option, } @@ -194,9 +194,13 @@ impl Vring { std::sync::atomic::Ordering::SeqCst, ); if let Some(intc) = &self.intc { - intc.set_irq(self.irq_line.unwrap()); - } else if let Err(e) = self.interrupt_evt.write(1) { - error!("Failed to signal used queue: {:?}", e); + if let Err(e) = intc + .lock() + .unwrap() + .set_irq(self.irq_line, Some(&self.interrupt_evt)) + { + warn!("Failed to signal queue: {e:?}"); + } } } } diff --git a/src/devices/src/virtio/snd/worker.rs b/src/devices/src/virtio/snd/worker.rs index dd937569b..52adf8b8f 100644 --- a/src/devices/src/virtio/snd/worker.rs +++ b/src/devices/src/virtio/snd/worker.rs @@ -23,7 +23,7 @@ use super::{ BackendType, Direction, Error, VirtioSoundChmapInfo, VirtioSoundJackInfo, Vring, VIRTIO_SND_CHMAP_FL, VIRTIO_SND_CHMAP_FR, VIRTIO_SND_CHMAP_MAX_SIZE, VIRTIO_SND_CHMAP_NONE, }; -use crate::legacy::GicV3; +use crate::legacy::IrqChip; use crate::virtio::snd::stream::Buffer; use crate::virtio::snd::{ControlMessageKind, IOMessage}; use crate::virtio::DescriptorChain; @@ -33,7 +33,7 @@ pub struct SndWorker { queue_evts: Vec, interrupt_status: Arc, interrupt_evt: EventFd, - intc: Option, + intc: Option, irq_line: Option, mem: GuestMemoryMmap, @@ -52,7 +52,7 @@ impl SndWorker { queue_evts: Vec, interrupt_status: Arc, interrupt_evt: EventFd, - intc: Option, + intc: Option, irq_line: Option, mem: GuestMemoryMmap, stop_fd: EventFd, @@ -249,9 +249,13 @@ impl SndWorker { self.interrupt_status .fetch_or(VIRTIO_MMIO_INT_VRING as usize, Ordering::SeqCst); if let Some(intc) = &self.intc { - intc.set_irq(self.irq_line.unwrap()); - } else if let Err(e) = self.interrupt_evt.write(1) { - error!("Failed to signal used queue: {:?}", e); + if let Err(e) = intc + .lock() + .unwrap() + .set_irq(self.irq_line, Some(&self.interrupt_evt)) + { + error!("Failed to signal used queue: {:?}", e); + } } } } else { diff --git a/src/devices/src/virtio/vsock/device.rs b/src/devices/src/virtio/vsock/device.rs index de0ee3bac..49c1aa5dc 100644 --- a/src/devices/src/virtio/vsock/device.rs +++ b/src/devices/src/virtio/vsock/device.rs @@ -23,7 +23,7 @@ use super::super::{ use super::muxer::VsockMuxer; use super::packet::VsockPacket; use super::{defs, defs::uapi}; -use crate::legacy::GicV3; +use crate::legacy::IrqChip; pub(crate) const RXQ_INDEX: usize = 0; pub(crate) const TXQ_INDEX: usize = 1; @@ -50,7 +50,7 @@ pub struct Vsock { pub(crate) interrupt_evt: EventFd, pub(crate) activate_evt: EventFd, pub(crate) device_state: DeviceState, - intc: Option, + intc: Option, irq_line: Option, } @@ -116,7 +116,7 @@ impl Vsock { defs::VSOCK_DEV_ID } - pub fn set_intc(&mut self, intc: GicV3) { + pub fn set_intc(&mut self, intc: IrqChip) { self.intc = Some(intc); } @@ -131,14 +131,11 @@ impl Vsock { self.interrupt_status .fetch_or(VIRTIO_MMIO_INT_VRING as usize, Ordering::SeqCst); if let Some(intc) = &self.intc { - intc.set_irq(self.irq_line.unwrap()); - Ok(()) - } else { - self.interrupt_evt.write(1).map_err(|e| { - error!("Failed to signal used queue: {:?}", e); - DeviceError::FailedSignalingUsedQueue(e) - }) + intc.lock() + .unwrap() + .set_irq(self.irq_line, Some(&self.interrupt_evt))?; } + Ok(()) } /// Walk the driver-provided RX queue buffers and attempt to fill them up with any data that we diff --git a/src/devices/src/virtio/vsock/muxer.rs b/src/devices/src/virtio/vsock/muxer.rs index fdecb1d84..f2171ebaf 100644 --- a/src/devices/src/virtio/vsock/muxer.rs +++ b/src/devices/src/virtio/vsock/muxer.rs @@ -4,7 +4,7 @@ use std::path::PathBuf; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::{Arc, Mutex, RwLock}; -use super::super::super::legacy::GicV3; +use super::super::super::legacy::IrqChip; use super::super::Queue as VirtQueue; use super::super::VIRTIO_MMIO_INT_VRING; use super::defs; @@ -107,7 +107,7 @@ pub struct VsockMuxer { epoll: Epoll, interrupt_evt: EventFd, interrupt_status: Arc, - intc: Option, + intc: Option, irq_line: Option, proxy_map: ProxyMap, reaper_sender: Option>, @@ -143,7 +143,7 @@ impl VsockMuxer { &mut self, mem: GuestMemoryMmap, queue: Arc>, - intc: Option, + intc: Option, irq_line: Option, ) { self.queue = Some(queue.clone()); @@ -242,9 +242,13 @@ impl VsockMuxer { self.interrupt_status .fetch_or(VIRTIO_MMIO_INT_VRING as usize, Ordering::SeqCst); if let Some(intc) = &self.intc { - intc.set_irq(self.irq_line.unwrap()); - } else if let Err(e) = self.interrupt_evt.write(1) { - warn!("failed to signal used queue: {:?}", e); + if let Err(e) = intc + .lock() + .unwrap() + .set_irq(self.irq_line, Some(&self.interrupt_evt)) + { + warn!("failed to signal used queue: {:?}", e); + } } } } diff --git a/src/devices/src/virtio/vsock/muxer_thread.rs b/src/devices/src/virtio/vsock/muxer_thread.rs index f98f2d9a2..2428723d6 100644 --- a/src/devices/src/virtio/vsock/muxer_thread.rs +++ b/src/devices/src/virtio/vsock/muxer_thread.rs @@ -5,7 +5,7 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::{Arc, Mutex}; use std::thread; -use super::super::super::legacy::GicV3; +use super::super::super::legacy::IrqChip; use super::super::Queue as VirtQueue; use super::super::VIRTIO_MMIO_INT_VRING; use super::muxer::{push_packet, MuxerRx, ProxyMap}; @@ -30,7 +30,7 @@ pub struct MuxerThread { queue: Arc>, interrupt_evt: EventFd, interrupt_status: Arc, - intc: Option, + intc: Option, irq_line: Option, reaper_sender: Sender, unix_ipc_port_map: HashMap, @@ -47,7 +47,7 @@ impl MuxerThread { queue: Arc>, interrupt_evt: EventFd, interrupt_status: Arc, - intc: Option, + intc: Option, irq_line: Option, reaper_sender: Sender, unix_ipc_port_map: HashMap, @@ -159,9 +159,13 @@ impl MuxerThread { self.interrupt_status .fetch_or(VIRTIO_MMIO_INT_VRING as usize, Ordering::SeqCst); if let Some(intc) = &self.intc { - intc.set_irq(self.irq_line.unwrap()); - } else if let Err(e) = self.interrupt_evt.write(1) { - warn!("failed to signal used queue: {:?}", e); + if let Err(e) = intc + .lock() + .unwrap() + .set_irq(self.irq_line, Some(&self.interrupt_evt)) + { + warn!("failed to signal used queue: {:?}", e); + } } } } diff --git a/src/devices/src/virtio/vsock/timesync.rs b/src/devices/src/virtio/vsock/timesync.rs index 8df47a8b9..8ab3a9008 100644 --- a/src/devices/src/virtio/vsock/timesync.rs +++ b/src/devices/src/virtio/vsock/timesync.rs @@ -3,7 +3,7 @@ use std::sync::{Arc, Mutex}; use std::thread; use std::time; -use super::super::super::legacy::GicV3; +use super::super::super::legacy::IrqChip; use super::super::Queue as VirtQueue; use super::super::VIRTIO_MMIO_INT_VRING; use super::defs::uapi; @@ -22,7 +22,7 @@ pub struct TimesyncThread { queue_mutex: Arc>, interrupt_evt: EventFd, interrupt_status: Arc, - intc: Option, + intc: Option, irq_line: Option, } @@ -33,7 +33,7 @@ impl TimesyncThread { queue_mutex: Arc>, interrupt_evt: EventFd, interrupt_status: Arc, - intc: Option, + intc: Option, irq_line: Option, ) -> Self { Self { @@ -68,9 +68,13 @@ impl TimesyncThread { self.interrupt_status .fetch_or(VIRTIO_MMIO_INT_VRING as usize, Ordering::SeqCst); if let Some(intc) = &self.intc { - intc.set_irq(self.irq_line.unwrap()); - } else if let Err(e) = self.interrupt_evt.write(1) { - warn!("failed to signal used queue: {:?}", e); + if let Err(e) = intc + .lock() + .unwrap() + .set_irq(self.irq_line, Some(&self.interrupt_evt)) + { + warn!("failed to signal used queue: {:?}", e); + } } } } diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index cd150df8e..b222f9a96 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -22,10 +22,16 @@ use crate::device_manager::legacy::PortIODeviceManager; use crate::device_manager::mmio::MMIODeviceManager; use crate::resources::VmResources; use crate::vmm_config::external_kernel::{ExternalKernel, KernelFormat}; +#[cfg(target_os = "macos")] use devices::legacy::GicV3; +#[cfg(target_arch = "x86_64")] +use devices::legacy::KvmIoapic; use devices::legacy::Serial; #[cfg(target_os = "macos")] use devices::legacy::VcpuList; +use devices::legacy::{IrqChip, IrqChipDevice}; +#[cfg(all(target_os = "linux", target_arch = "aarch64"))] +use devices::legacy::{IrqChipDevice, KvmGicV3}; #[cfg(feature = "net")] use devices::virtio::Net; use devices::virtio::{port_io, MmioTransport, PortDescription, Vsock}; @@ -83,6 +89,9 @@ static EDK2_BINARY: &[u8] = include_bytes!("../../../edk2/KRUN_EFI.silent.fd"); pub enum StartMicrovmError { /// Unable to attach block device to Vmm. AttachBlockDevice(io::Error), + #[cfg(target_os = "linux")] + /// Failed to create KVM in-kernel IrqChip. + CreateKvmIrqChip(kvm_ioctls::Error), /// Failed to create a `RateLimiter` object. CreateRateLimiter(io::Error), /// Cannot open the file containing the kernel code. @@ -199,6 +208,10 @@ impl Display for StartMicrovmError { AttachBlockDevice(ref err) => { write!(f, "Unable to attach block device to Vmm. Error: {err}") } + #[cfg(target_os = "linux")] + CreateKvmIrqChip(ref err) => { + write!(f, "Cannot create KVM in-kernel IrqChip: {err}") + } CreateRateLimiter(ref err) => write!(f, "Cannot create RateLimiter: {err}"), ElfOpenKernel(ref err) => { write!(f, "Cannot open the file containing the kernel code: {err}") @@ -667,18 +680,16 @@ pub fn build_microvm( Arc::new(VcpuList::new(cpu_count as u64)) }; - #[cfg(target_os = "linux")] - let intc = None; - #[cfg(target_os = "macos")] - let intc = Some(GicV3::new(vcpu_list.clone())); - let vcpus; + let intc: IrqChip; // For x86_64 we need to create the interrupt controller before calling `KVM_CREATE_VCPUS` // while on aarch64 we need to do it the other way around. #[cfg(target_arch = "x86_64")] { - #[cfg(not(feature = "intel-tdx"))] - setup_interrupt_controller(&vm)?; + // TODO(jakecorrenti): this shouldn't be used with TDX. TDX needs to use a split irq + let kvmioapic = KvmIoapic::new(vm.fd()).map_err(StartMicrovmError::CreateKvmIrqChip)?; + intc = Arc::new(Mutex::new(IrqChipDevice::new(Box::new(kvmioapic)))); + attach_legacy_devices(&vm, &mut pio_device_manager)?; vcpus = create_vcpus_x86_64( @@ -699,6 +710,11 @@ pub fn build_microvm( // Search for `kvm_arch_vcpu_create` in arch/arm/kvm/arm.c. #[cfg(all(target_arch = "aarch64", target_os = "linux"))] { + intc = Arc::new(Mutex::new(IrqChipDevice::new(Box::new(KvmGicV3::new( + vm.fd(), + vm_resources.vm_config().vcpu_count.unwrap() as u64, + ))))); + vcpus = create_vcpus_aarch64( &vm, &vcpu_config, @@ -708,7 +724,6 @@ pub fn build_microvm( ) .map_err(StartMicrovmError::Internal)?; - setup_interrupt_controller(&mut vm, vcpu_config.vcpu_count)?; attach_legacy_devices( &vm, &mut mmio_device_manager, @@ -719,6 +734,10 @@ pub fn build_microvm( #[cfg(all(target_arch = "aarch64", target_os = "macos"))] { + intc = Arc::new(Mutex::new(IrqChipDevice::new(Box::new(GicV3::new( + vcpu_list.clone(), + ))))); + vcpus = create_vcpus_aarch64( &vm, &vcpu_config, @@ -729,7 +748,6 @@ pub fn build_microvm( ) .map_err(StartMicrovmError::Internal)?; - setup_interrupt_controller(&mut vm, vcpu_config.vcpu_count)?; attach_legacy_devices( &vm, &mut mmio_device_manager, @@ -833,6 +851,7 @@ pub fn build_microvm( vmm.configure_system( vcpus.as_slice(), + &intc, &payload_config.initrd_config, &vm_resources.smbios_oem_strings, ) @@ -1274,6 +1293,7 @@ fn load_cmdline(vmm: &Vmm) -> std::result::Result<(), StartMicrovmError> { #[cfg(all(target_os = "linux", not(feature = "tee")))] pub(crate) fn setup_vm( guest_memory: &GuestMemoryMmap, + _vcpu_count: u8, ) -> std::result::Result { let kvm = KvmContext::new() .map_err(Error::KvmContext) @@ -1314,25 +1334,6 @@ pub(crate) fn setup_vm( Ok(vm) } -/// Sets up the irqchip for a x86_64 microVM. -#[cfg(target_arch = "x86_64")] -pub fn setup_interrupt_controller(vm: &Vm) -> std::result::Result<(), StartMicrovmError> { - vm.setup_irqchip() - .map_err(Error::Vm) - .map_err(StartMicrovmError::Internal) -} - -/// Sets up the irqchip for a aarch64 microVM. -#[cfg(target_arch = "aarch64")] -pub fn setup_interrupt_controller( - vm: &mut Vm, - vcpu_count: u8, -) -> std::result::Result<(), StartMicrovmError> { - vm.setup_irqchip(vcpu_count) - .map_err(Error::Vm) - .map_err(StartMicrovmError::Internal) -} - /// Sets up the serial device. pub fn setup_serial_device( event_manager: &mut EventManager, @@ -1413,7 +1414,7 @@ fn attach_legacy_devices( vm: &Vm, mmio_device_manager: &mut MMIODeviceManager, kernel_cmdline: &mut kernel::cmdline::Cmdline, - intc: Option, + intc: IrqChip, serial: Option>>, event_manager: &mut EventManager, shutdown_efd: Option, @@ -1581,7 +1582,7 @@ fn attach_fs_devices( fs_devs: &[FsDeviceConfig], shm_manager: &mut ShmManager, #[cfg(not(feature = "tee"))] export_table: Option, - intc: Option, + intc: IrqChip, #[cfg(target_os = "macos")] map_sender: Sender, ) -> std::result::Result<(), StartMicrovmError> { use self::StartMicrovmError::*; @@ -1593,9 +1594,7 @@ fn attach_fs_devices( let id = format!("{}{}", String::from(fs.lock().unwrap().id()), i); - if let Some(ref intc) = intc { - fs.lock().unwrap().set_intc(intc.clone()); - } + fs.lock().unwrap().set_intc(intc.clone()); if let Some(shm_region) = shm_manager.fs_region(i) { fs.lock().unwrap().set_shm_region(VirtioShmRegion { @@ -1631,7 +1630,7 @@ fn attach_fs_devices( fn attach_console_devices( vmm: &mut Vmm, event_manager: &mut EventManager, - intc: Option, + intc: IrqChip, console_output: Option, ) -> std::result::Result<(), StartMicrovmError> { use self::StartMicrovmError::*; @@ -1707,10 +1706,7 @@ fn attach_console_devices( vmm.exit_observers.push(console.clone()); - if let Some(intc) = intc { - debug!("setting interrupt controller for console"); - console.lock().unwrap().set_intc(intc); - } + console.lock().unwrap().set_intc(intc); event_manager .add_subscriber(console.clone()) @@ -1736,14 +1732,12 @@ fn attach_console_devices( fn attach_net_devices<'a>( vmm: &mut Vmm, net_devices: impl Iterator>>, - intc: Option, + intc: IrqChip, ) -> Result<(), StartMicrovmError> { for net_device in net_devices { let id = net_device.lock().unwrap().id().to_string(); - if let Some(ref intc) = intc { - net_device.lock().unwrap().set_intc(intc.clone()); - } + net_device.lock().unwrap().set_intc(intc.clone()); attach_mmio_device( vmm, @@ -1759,7 +1753,7 @@ fn attach_unixsock_vsock_device( vmm: &mut Vmm, unix_vsock: &Arc>, event_manager: &mut EventManager, - intc: Option, + intc: IrqChip, ) -> std::result::Result<(), StartMicrovmError> { use self::StartMicrovmError::*; @@ -1769,9 +1763,7 @@ fn attach_unixsock_vsock_device( let id = String::from(unix_vsock.lock().unwrap().id()); - if let Some(intc) = intc { - unix_vsock.lock().unwrap().set_intc(intc); - } + unix_vsock.lock().unwrap().set_intc(intc); // The device mutex mustn't be locked here otherwise it will deadlock. attach_mmio_device( @@ -1788,7 +1780,7 @@ fn attach_unixsock_vsock_device( fn attach_balloon_device( vmm: &mut Vmm, event_manager: &mut EventManager, - intc: Option, + intc: IrqChip, ) -> std::result::Result<(), StartMicrovmError> { use self::StartMicrovmError::*; @@ -1800,9 +1792,7 @@ fn attach_balloon_device( let id = String::from(balloon.lock().unwrap().id()); - if let Some(intc) = intc { - balloon.lock().unwrap().set_intc(intc); - } + balloon.lock().unwrap().set_intc(intc); // The device mutex mustn't be locked here otherwise it will deadlock. attach_mmio_device( @@ -1819,16 +1809,14 @@ fn attach_balloon_device( fn attach_block_devices( vmm: &mut Vmm, block_devs: &BlockBuilder, - intc: Option, + intc: IrqChip, ) -> std::result::Result<(), StartMicrovmError> { use self::StartMicrovmError::*; for block in block_devs.list.iter() { let id = String::from(block.lock().unwrap().id()); - if let Some(ref intc) = intc { - block.lock().unwrap().set_intc(intc.clone()); - } + block.lock().unwrap().set_intc(intc.clone()); // The device mutex mustn't be locked here otherwise it will deadlock. attach_mmio_device( @@ -1846,7 +1834,7 @@ fn attach_block_devices( fn attach_rng_device( vmm: &mut Vmm, event_manager: &mut EventManager, - intc: Option, + intc: IrqChip, ) -> std::result::Result<(), StartMicrovmError> { use self::StartMicrovmError::*; @@ -1858,9 +1846,7 @@ fn attach_rng_device( let id = String::from(rng.lock().unwrap().id()); - if let Some(intc) = intc { - rng.lock().unwrap().set_intc(intc); - } + rng.lock().unwrap().set_intc(intc); // The device mutex mustn't be locked here otherwise it will deadlock. attach_mmio_device(vmm, id, MmioTransport::new(vmm.guest_memory().clone(), rng)) @@ -1875,7 +1861,7 @@ fn attach_gpu_device( event_manager: &mut EventManager, shm_manager: &mut ShmManager, #[cfg(not(feature = "tee"))] mut export_table: Option, - intc: Option, + intc: IrqChip, virgl_flags: u32, #[cfg(target_os = "macos")] map_sender: Sender, ) -> std::result::Result<(), StartMicrovmError> { @@ -1896,9 +1882,7 @@ fn attach_gpu_device( let id = String::from(gpu.lock().unwrap().id()); - if let Some(intc) = intc { - gpu.lock().unwrap().set_intc(intc); - } + gpu.lock().unwrap().set_intc(intc); if let Some(shm_region) = shm_manager.gpu_region() { gpu.lock().unwrap().set_shm_region(VirtioShmRegion { @@ -1924,18 +1908,13 @@ fn attach_gpu_device( } #[cfg(feature = "snd")] -fn attach_snd_device( - vmm: &mut Vmm, - intc: Option, -) -> std::result::Result<(), StartMicrovmError> { +fn attach_snd_device(vmm: &mut Vmm, intc: IrqChip) -> std::result::Result<(), StartMicrovmError> { use self::StartMicrovmError::*; let snd = Arc::new(Mutex::new(devices::virtio::Snd::new().unwrap())); let id = String::from(snd.lock().unwrap().id()); - if let Some(intc) = intc { - snd.lock().unwrap().set_intc(intc); - } + snd.lock().unwrap().set_intc(intc); // The device mutex mustn't be locked here otherwise it will deadlock. attach_mmio_device(vmm, id, MmioTransport::new(vmm.guest_memory().clone(), snd)) @@ -1971,17 +1950,17 @@ pub mod tests { fn test_create_vcpus_x86_64() { let vcpu_count = 2; - let (guest_memory, _arch_memory_info, _shm_manager, _payload_config) = - default_guest_memory(128).unwrap(); - let mut vm = setup_vm(&guest_memory).unwrap(); - #[cfg(not(feature = "intel-tdx"))] - setup_interrupt_controller(&mut vm).unwrap(); let vcpu_config = VcpuConfig { vcpu_count, ht_enabled: false, cpu_template: None, }; + let (guest_memory, _arch_memory_info, _shm_manager, _payload_config) = + default_guest_memory(128).unwrap(); + let vm = setup_vm(&guest_memory, vcpu_count).unwrap(); + let _kvmioapic = KvmIoapic::new(&vm.fd()).unwrap(); + // Dummy entry_addr, vcpus will not boot. let entry_addr = GuestAddress(0); let bus = devices::Bus::new(); diff --git a/src/vmm/src/device_manager/hvf/mmio.rs b/src/vmm/src/device_manager/hvf/mmio.rs index f506324be..f6f356242 100644 --- a/src/vmm/src/device_manager/hvf/mmio.rs +++ b/src/vmm/src/device_manager/hvf/mmio.rs @@ -9,13 +9,9 @@ use std::collections::HashMap; use std::sync::{Arc, Mutex}; use std::{fmt, io}; -#[cfg(target_arch = "aarch64")] -use arch::aarch64::DeviceInfoForFDT; -use arch::DeviceType; -use devices; - -use devices::legacy::GicV3; -use devices::BusDevice; +use devices::fdt::DeviceInfoForFDT; +use devices::legacy::IrqChip; +use devices::{BusDevice, DeviceType}; use kernel::cmdline as kernel_cmdline; use polly::event_manager::EventManager; #[cfg(target_arch = "aarch64")] @@ -142,14 +138,14 @@ impl MMIODeviceManager { &mut self, _vm: &Vm, cmdline: &mut kernel_cmdline::Cmdline, - intc: Option, + intc: IrqChip, serial: Arc>, ) -> Result<()> { if self.irq > self.last_irq { return Err(Error::IrqsExhausted); } - if let Some(intc) = intc { + { let mut serial = serial.lock().unwrap(); serial.set_intc(intc); serial.set_irq_line(self.irq); @@ -184,7 +180,7 @@ impl MMIODeviceManager { #[cfg(target_arch = "aarch64")] /// Register a MMIO RTC device. - pub fn register_mmio_rtc(&mut self, _vm: &Vm, _intc: Option) -> Result<()> { + pub fn register_mmio_rtc(&mut self, _vm: &Vm, _intc: IrqChip) -> Result<()> { if self.irq > self.last_irq { return Err(Error::IrqsExhausted); } @@ -218,7 +214,7 @@ impl MMIODeviceManager { pub fn register_mmio_gpio( &mut self, _vm: &Vm, - intc: Option, + intc: IrqChip, event_manager: &mut EventManager, shutdown_efd: EventFd, ) -> Result<()> { @@ -235,7 +231,7 @@ impl MMIODeviceManager { return Err(Error::IrqsExhausted); } - if let Some(intc) = intc { + { let mut gpio = gpio.lock().unwrap(); gpio.set_intc(intc); gpio.set_irq_line(self.irq); @@ -263,14 +259,15 @@ impl MMIODeviceManager { #[cfg(target_arch = "aarch64")] /// Register a MMIO GIC device. - pub fn register_mmio_gic(&mut self, _vm: &Vm, intc: Option) -> Result<()> { - if let Some(intc) = intc { - let mmio_addr = intc.get_mmio_addr(); - let mmio_size = intc.get_mmio_size(); - self.bus - .insert(intc.as_device(), mmio_addr, mmio_size) - .map_err(Error::BusError)?; - } + pub fn register_mmio_gic(&mut self, _vm: &Vm, intc: IrqChip) -> Result<()> { + let (mmio_addr, mmio_size) = { + let intc = intc.lock().unwrap(); + (intc.get_mmio_addr(), intc.get_mmio_size()) + }; + + self.bus + .insert(intc, mmio_addr, mmio_size) + .map_err(Error::BusError)?; Ok(()) } diff --git a/src/vmm/src/device_manager/kvm/mmio.rs b/src/vmm/src/device_manager/kvm/mmio.rs index c3aec6e48..e8b22f971 100644 --- a/src/vmm/src/device_manager/kvm/mmio.rs +++ b/src/vmm/src/device_manager/kvm/mmio.rs @@ -10,11 +10,8 @@ use std::sync::{Arc, Mutex}; use std::{fmt, io}; #[cfg(target_arch = "aarch64")] -use arch::aarch64::DeviceInfoForFDT; -use arch::DeviceType; -use devices; - -use devices::BusDevice; +use devices::fdt::DeviceInfoForFDT; +use devices::{BusDevice, DeviceType}; use kernel::cmdline as kernel_cmdline; use kvm_ioctls::{IoEventAddress, VmFd}; #[cfg(target_arch = "aarch64")] @@ -284,7 +281,10 @@ mod tests { use super::super::super::super::builder; use super::*; use arch; - use devices::virtio::{ActivateResult, Queue, VirtioDevice}; + use devices::{ + legacy::KvmIoapic, + virtio::{ActivateResult, Queue, VirtioDevice}, + }; use std::sync::atomic::AtomicUsize; use std::sync::Arc; use utils::errno; @@ -401,16 +401,14 @@ mod tests { let start_addr2 = GuestAddress(0x1000); let guest_mem = GuestMemoryMmap::from_ranges(&[(start_addr1, 0x1000), (start_addr2, 0x1000)]).unwrap(); - let mut vm = builder::setup_vm(&guest_mem).unwrap(); + let vcpu_count: u8 = 1; + let vm = builder::setup_vm(&guest_mem, vcpu_count).unwrap(); let mut device_manager = MMIODeviceManager::new(&mut 0xd000_0000, (arch::IRQ_BASE, arch::IRQ_MAX)); + let _kvmioapic = KvmIoapic::new(vm.fd()).unwrap(); let mut cmdline = kernel_cmdline::Cmdline::new(4096); let dummy = Arc::new(Mutex::new(DummyDevice::new())); - #[cfg(target_arch = "x86_64")] - assert!(builder::setup_interrupt_controller(&mut vm).is_ok()); - #[cfg(target_arch = "aarch64")] - assert!(builder::setup_interrupt_controller(&mut vm, 1).is_ok()); assert!(device_manager .register_virtio_device(vm.fd(), guest_mem, dummy, &mut cmdline, 0, "dummy") @@ -423,15 +421,13 @@ mod tests { let start_addr2 = GuestAddress(0x1000); let guest_mem = GuestMemoryMmap::from_ranges(&[(start_addr1, 0x1000), (start_addr2, 0x1000)]).unwrap(); - let mut vm = builder::setup_vm(&guest_mem).unwrap(); + let vcpu_count: u8 = 1; + let vm = builder::setup_vm(&guest_mem, vcpu_count).unwrap(); let mut device_manager = MMIODeviceManager::new(&mut 0xd000_0000, (arch::IRQ_BASE, arch::IRQ_MAX)); + let _kvmioapic = KvmIoapic::new(vm.fd()).unwrap(); let mut cmdline = kernel_cmdline::Cmdline::new(4096); - #[cfg(target_arch = "x86_64")] - assert!(builder::setup_interrupt_controller(&mut vm).is_ok()); - #[cfg(target_arch = "aarch64")] - assert!(builder::setup_interrupt_controller(&mut vm, 1).is_ok()); for _i in arch::IRQ_BASE..=arch::IRQ_MAX { device_manager @@ -526,7 +522,8 @@ mod tests { let start_addr2 = GuestAddress(0x1000); let guest_mem = GuestMemoryMmap::from_ranges(&[(start_addr1, 0x1000), (start_addr2, 0x1000)]).unwrap(); - let vm = builder::setup_vm(&guest_mem).unwrap(); + let vcpu_count = 1; + let vm = builder::setup_vm(&guest_mem, vcpu_count).unwrap(); let mut device_manager = MMIODeviceManager::new(&mut 0xd000_0000, (arch::IRQ_BASE, arch::IRQ_MAX)); let mut cmdline = kernel_cmdline::Cmdline::new(4096); diff --git a/src/vmm/src/lib.rs b/src/vmm/src/lib.rs index 0d1923f91..412d05884 100644 --- a/src/vmm/src/lib.rs +++ b/src/vmm/src/lib.rs @@ -52,11 +52,14 @@ use crate::terminal::term_set_canonical_mode; use crate::vstate::VcpuEvent; use crate::vstate::{Vcpu, VcpuHandle, VcpuResponse, Vm}; -use arch::{ArchMemoryInfo, DeviceType, InitrdConfig}; +use arch::{ArchMemoryInfo, InitrdConfig}; #[cfg(target_os = "macos")] use crossbeam_channel::Sender; +#[cfg(target_arch = "aarch64")] +use devices::fdt; +use devices::legacy::IrqChip; use devices::virtio::VmmExitObserver; -use devices::BusDevice; +use devices::{BusDevice, DeviceType}; use kernel::cmdline::Cmdline as KernelCmdline; use polly::event_manager::{self, EventManager, Subscriber}; use utils::epoll::{EpollEvent, EventSet}; @@ -111,6 +114,9 @@ pub enum Error { RegisterMMIODevice(device_manager::mmio::Error), /// Write to the serial console failed. Serial(io::Error), + #[cfg(target_arch = "aarch64")] + /// Cannot generate or write FDT + SetupFDT(devices::fdt::Error), /// Cannot create Timer file descriptor. TimerFd(io::Error), /// Vcpu error. @@ -149,6 +155,8 @@ impl Display for Error { LoadCommandline(e) => write!(f, "Cannot load command line: {e}"), RegisterMMIODevice(e) => write!(f, "Cannot add a device to the MMIO Bus. {e}"), Serial(e) => write!(f, "Error writing to the serial console: {e:?}"), + #[cfg(target_arch = "aarch64")] + SetupFDT(e) => write!(f, "Error generating or writting FDT: {e:?}"), TimerFd(e) => write!(f, "Error creating timer fd: {e}"), Vcpu(e) => write!(f, "Vcpu error: {e}"), VcpuEvent(e) => write!(f, "Cannot send event to vCPU. {e:?}"), @@ -262,6 +270,7 @@ impl Vmm { pub fn configure_system( &self, vcpus: &[Vcpu], + _intc: &IrqChip, initrd: &Option, _smbios_oem_strings: &Option>, ) -> Result<()> { @@ -284,36 +293,31 @@ impl Vmm { .map_err(Error::ConfigureSystem)?; } - #[cfg(all(target_arch = "aarch64", target_os = "linux"))] + #[cfg(target_arch = "aarch64")] { let vcpu_mpidr = vcpus.iter().map(|cpu| cpu.get_mpidr()).collect(); - arch::aarch64::configure_system( + fdt::create_fdt( &self.guest_memory, &self.arch_memory_info, - self.kernel_cmdline.as_str(), vcpu_mpidr, + self.kernel_cmdline.as_str(), self.mmio_device_manager.get_device_info(), - self.vm.get_irqchip(), + _intc, initrd, - _smbios_oem_strings, ) - .map_err(Error::ConfigureSystem)?; + .map_err(Error::SetupFDT)?; + } + + #[cfg(all(target_arch = "aarch64", target_os = "linux"))] + { + arch::aarch64::configure_system(&self.guest_memory, _smbios_oem_strings) + .map_err(Error::ConfigureSystem)?; } #[cfg(all(target_arch = "aarch64", target_os = "macos"))] { - let vcpu_mpidr = vcpus.iter().map(|cpu| cpu.get_mpidr()).collect(); - arch::aarch64::configure_system( - &self.guest_memory, - &self.arch_memory_info, - self.kernel_cmdline.as_str(), - vcpu_mpidr, - self.mmio_device_manager.get_device_info(), - self.vm.get_irqchip(), - initrd, - _smbios_oem_strings, - ) - .map_err(Error::ConfigureSystem)?; + arch::aarch64::configure_system(&self.guest_memory, _smbios_oem_strings) + .map_err(Error::ConfigureSystem)?; } Ok(()) } diff --git a/src/vmm/src/linux/vstate.rs b/src/vmm/src/linux/vstate.rs index 047fbd2d8..d20fdedef 100644 --- a/src/vmm/src/linux/vstate.rs +++ b/src/vmm/src/linux/vstate.rs @@ -34,16 +34,14 @@ use kbs_types::Tee; #[cfg(feature = "tee")] use crate::resources::TeeConfig; use crate::vmm_config::machine_config::CpuFeaturesTemplate; -#[cfg(target_arch = "aarch64")] -use arch::aarch64::gic::GICDevice; #[cfg(target_arch = "x86_64")] use cpuid::{c3, filter_cpuid, t2, VmSpec}; #[cfg(target_arch = "x86_64")] use kvm_bindings::{ - kvm_clock_data, kvm_debugregs, kvm_irqchip, kvm_lapic_state, kvm_mp_state, kvm_pit_config, - kvm_pit_state2, kvm_regs, kvm_sregs, kvm_vcpu_events, kvm_xcrs, kvm_xsave, CpuId, MsrList, - Msrs, KVM_CLOCK_TSC_STABLE, KVM_IRQCHIP_IOAPIC, KVM_IRQCHIP_PIC_MASTER, KVM_IRQCHIP_PIC_SLAVE, - KVM_MAX_CPUID_ENTRIES, KVM_PIT_SPEAKER_DUMMY, + kvm_clock_data, kvm_debugregs, kvm_irqchip, kvm_lapic_state, kvm_mp_state, kvm_pit_state2, + kvm_regs, kvm_sregs, kvm_vcpu_events, kvm_xcrs, kvm_xsave, CpuId, MsrList, Msrs, + KVM_CLOCK_TSC_STABLE, KVM_IRQCHIP_IOAPIC, KVM_IRQCHIP_PIC_MASTER, KVM_IRQCHIP_PIC_SLAVE, + KVM_MAX_CPUID_ENTRIES, }; use kvm_bindings::{ kvm_create_guest_memfd, kvm_memory_attributes, kvm_userspace_memory_region, @@ -118,9 +116,6 @@ pub enum Error { #[cfg(target_arch = "x86_64")] /// Error configuring the general purpose registers REGSConfiguration(arch::x86_64::regs::Error), - #[cfg(target_arch = "aarch64")] - /// Error setting up the global interrupt controller. - SetupGIC(arch::aarch64::gic::Error), /// Cannot set the memory regions. SetUserMemoryRegion(kvm_ioctls::Error), #[cfg(feature = "intel-tdx")] @@ -404,8 +399,6 @@ impl Display for Error { #[cfg(target_arch = "x86_64")] VmSetIrqChip(e) => write!(f, "Failed to set KVM vm irqchip: {e}"), #[cfg(target_arch = "aarch64")] - SetupGIC(e) => write!(f, "Error setting up the global interrupt controller: {e:?}"), - #[cfg(target_arch = "aarch64")] VcpuArmPreferredTarget(e) => { write!(f, "Error getting the Vcpu preferred target on Arm: {e}") } @@ -488,11 +481,6 @@ pub struct Vm { #[cfg(target_arch = "x86_64")] supported_msrs: MsrList, - // Arm specific fields. - // On aarch64 we need to keep around the fd obtained by creating the VGIC device. - #[cfg(target_arch = "aarch64")] - irqchip_handle: Option>, - #[cfg(feature = "amd-sev")] tee: Option, @@ -525,8 +513,6 @@ impl Vm { supported_cpuid, #[cfg(target_arch = "x86_64")] supported_msrs, - #[cfg(target_arch = "aarch64")] - irqchip_handle: None, }) } @@ -741,35 +727,6 @@ impl Vm { } } - /// Creates the irq chip and an in-kernel device model for the PIT. - #[cfg(target_arch = "x86_64")] - pub fn setup_irqchip(&self) -> Result<()> { - self.fd.create_irq_chip().map_err(Error::VmSetup)?; - let pit_config = kvm_pit_config { - // We need to enable the emulation of a dummy speaker port stub so that writing to port - // 0x61 (i.e. KVM_SPEAKER_BASE_ADDRESS) does not trigger an exit to user space. - flags: KVM_PIT_SPEAKER_DUMMY, - ..Default::default() - }; - self.fd.create_pit2(pit_config).map_err(Error::VmSetup) - } - - /// Creates the GIC (Global Interrupt Controller). - #[cfg(target_arch = "aarch64")] - pub fn setup_irqchip(&mut self, vcpu_count: u8) -> Result<()> { - self.irqchip_handle = Some( - arch::aarch64::gic::create_gic(&self.fd, vcpu_count.into()).map_err(Error::SetupGIC)?, - ); - Ok(()) - } - - /// Gets a reference to the irqchip of the VM - #[allow(clippy::borrowed_box)] - #[cfg(target_arch = "aarch64")] - pub fn get_irqchip(&self) -> &Box { - self.irqchip_handle.as_ref().unwrap() - } - /// Gets a reference to the kvm file descriptor owned by this VM. pub fn fd(&self) -> &VmFd { &self.fd @@ -1788,6 +1745,7 @@ mod tests { use super::*; use devices; + use devices::legacy::KvmIoapic; use utils::signal::validate_signal_num; @@ -1809,6 +1767,7 @@ mod tests { let kvm = KvmContext::new().unwrap(); let gm = GuestMemoryMmap::from_ranges(&[(GuestAddress(0), mem_size)]).unwrap(); let mut vm = Vm::new(kvm.fd()).expect("Cannot create new vm"); + let _kvmioapic = KvmIoapic::new(&vm.fd()).unwrap(); assert!(vm.memory_init(&gm, kvm.max_memslots()).is_ok()); let exit_evt = EventFd::new(utils::eventfd::EFD_NONBLOCK).unwrap(); @@ -1816,7 +1775,6 @@ mod tests { let vcpu; #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { - vm.setup_irqchip().unwrap(); vcpu = Vcpu::new_x86_64( 1, vm.fd(), @@ -1830,7 +1788,6 @@ mod tests { #[cfg(target_arch = "aarch64")] { vcpu = Vcpu::new_aarch64(1, vm.fd(), exit_evt).unwrap(); - vm.setup_irqchip(1).expect("Cannot setup irqchip"); } (vm, vcpu, gm) @@ -1877,50 +1834,6 @@ mod tests { assert!(vm.memory_init(&gm, kvm_context.max_memslots()).is_err()); } - #[cfg(target_arch = "x86_64")] - #[test] - fn test_setup_irqchip() { - let kvm_context = KvmContext::new().unwrap(); - let vm = Vm::new(kvm_context.fd()).expect("Cannot create new vm"); - - vm.setup_irqchip().expect("Cannot setup irqchip"); - // Trying to setup two irqchips will result in EEXIST error. At the moment - // there is no good way of testing the actual error because io::Error does not implement - // PartialEq. - assert!(vm.setup_irqchip().is_err()); - - let _vcpu = Vcpu::new_x86_64( - 1, - vm.fd(), - vm.supported_cpuid().clone(), - vm.supported_msrs().clone(), - devices::Bus::new(), - EventFd::new(utils::eventfd::EFD_NONBLOCK).unwrap(), - ) - .unwrap(); - // Trying to setup irqchip after KVM_VCPU_CREATE was called will result in error. - assert!(vm.setup_irqchip().is_err()); - } - - #[cfg(target_arch = "aarch64")] - #[test] - fn test_setup_irqchip() { - let kvm = KvmContext::new().unwrap(); - - let mut vm = Vm::new(kvm.fd()).expect("Cannot create new vm"); - let vcpu_count = 1; - let _vcpu = Vcpu::new_aarch64( - 1, - vm.fd(), - EventFd::new(utils::eventfd::EFD_NONBLOCK).unwrap(), - ) - .unwrap(); - - vm.setup_irqchip(vcpu_count).expect("Cannot setup irqchip"); - // Trying to setup two irqchips will result in EEXIST error. - assert!(vm.setup_irqchip(vcpu_count).is_err()); - } - #[cfg(target_arch = "x86_64")] #[test] fn test_configure_vcpu() { diff --git a/src/vmm/src/macos/vstate.rs b/src/vmm/src/macos/vstate.rs index 66de5a130..d8977a1fc 100644 --- a/src/vmm/src/macos/vstate.rs +++ b/src/vmm/src/macos/vstate.rs @@ -17,7 +17,6 @@ use std::time::Duration; use super::super::{FC_EXIT_CODE_GENERIC_ERROR, FC_EXIT_CODE_OK}; use crate::vmm_config::machine_config::CpuFeaturesTemplate; -use arch::aarch64::gic::GICDevice; use crossbeam_channel::{unbounded, Receiver, RecvTimeoutError, Sender}; use devices::legacy::VcpuList; use hvf::{HvfVcpu, HvfVm, VcpuExit, Vcpus}; @@ -35,8 +34,6 @@ pub enum Error { NotEnoughMemorySlots, /// Error configuring the general purpose aarch64 registers. REGSConfiguration(arch::aarch64::regs::Error), - /// Error setting up the global interrupt controller. - SetupGIC(arch::aarch64::gic::Error), /// Cannot set the memory regions. SetUserMemoryRegion(hvf::Error), /// Failed to signal Vcpu. @@ -85,11 +82,6 @@ impl Display for Error { VcpuTlsInit => write!(f, "Cannot clean init vcpu TLS"), VcpuTlsNotPresent => write!(f, "Vcpu not present in TLS"), VcpuUnhandledKvmExit => write!(f, "Unexpected KVM_RUN exit reason"), - SetupGIC(e) => write!( - f, - "Error setting up the global interrupt controller: {:?}", - e - ), VcpuArmPreferredTarget => write!(f, "Error getting the Vcpu preferred target on Arm"), VcpuArmInit => write!(f, "Error doing Vcpu Init on Arm"), } @@ -101,7 +93,6 @@ pub type Result = result::Result; /// A wrapper around creating and using a VM. pub struct Vm { hvf_vm: HvfVm, - irqchip_handle: Option>, } impl Vm { @@ -109,10 +100,7 @@ impl Vm { pub fn new() -> Result { let hvf_vm = HvfVm::new().map_err(Error::VmSetup)?; - Ok(Vm { - hvf_vm, - irqchip_handle: None, - }) + Ok(Vm { hvf_vm }) } /// Initializes the guest memory. @@ -138,18 +126,6 @@ impl Vm { Ok(()) } - pub fn setup_irqchip(&mut self, vcpu_count: u8) -> Result<()> { - self.irqchip_handle = - Some(arch::aarch64::gic::create_gic(vcpu_count.into()).map_err(Error::SetupGIC)?); - Ok(()) - } - - /// Gets a reference to the irqchip of the VM - #[allow(clippy::borrowed_box)] - pub fn get_irqchip(&self) -> &Box { - self.irqchip_handle.as_ref().unwrap() - } - pub fn add_mapping( &self, reply_sender: Sender, From 045a0fdd44a7cbb6b1199121d968cbedd6212401 Mon Sep 17 00:00:00 2001 From: Sergio Lopez Date: Fri, 14 Mar 2025 15:47:11 +0100 Subject: [PATCH 38/40] macos/vstate: unify MPIDR generation With HVF, we generate MPIDR by taking Vcpu.id and setting Aff1 to that value by doing a left-shift, as this is what the GIC expects to be found in the distributor. But, in vstate::Vcpu::configure_aarch64, we were using the Vcpu.id without left-shifting it. For consistency, let's generate MPIDR for the Vcpu once and use it everywhere. Signed-off-by: Sergio Lopez --- src/hvf/src/lib.rs | 5 ++--- src/vmm/src/builder.rs | 14 +++++++++----- src/vmm/src/macos/vstate.rs | 19 ++++++++----------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/hvf/src/lib.rs b/src/hvf/src/lib.rs index 79ba02d45..c0c1e93d9 100644 --- a/src/hvf/src/lib.rs +++ b/src/hvf/src/lib.rs @@ -231,7 +231,7 @@ pub struct HvfVcpu<'a> { } impl HvfVcpu<'_> { - pub fn new() -> Result { + pub fn new(mpidr: u64) -> Result { let mut vcpuid: hv_vcpu_t = 0; let vcpu_exit_ptr: *mut hv_vcpu_exit_t = std::ptr::null_mut(); @@ -257,8 +257,7 @@ impl HvfVcpu<'_> { // We write vcpuid to Aff1 as otherwise it won't match the redistributor ID // when using HVF in-kernel GICv3. - let ret = - unsafe { hv_vcpu_set_sys_reg(vcpuid, hv_sys_reg_t_HV_SYS_REG_MPIDR_EL1, vcpuid << 8) }; + let ret = unsafe { hv_vcpu_set_sys_reg(vcpuid, hv_sys_reg_t_HV_SYS_REG_MPIDR_EL1, mpidr) }; if ret != HV_SUCCESS { return Err(Error::VcpuCreate); } diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index b222f9a96..c7517da5a 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -7,6 +7,7 @@ use crossbeam_channel::{unbounded, Sender}; use crossbeam_channel::Sender; use kernel::cmdline::Cmdline; +use std::collections::HashMap; use std::fmt::{Display, Formatter}; use std::fs::File; use std::io::{self, Read}; @@ -1515,15 +1516,14 @@ fn create_vcpus_aarch64( vcpu_list: Arc, ) -> super::Result> { let mut vcpus = Vec::with_capacity(vcpu_config.vcpu_count as usize); - let mut boot_senders = Vec::with_capacity(vcpu_config.vcpu_count as usize - 1); + let mut boot_senders: HashMap> = HashMap::new(); for cpu_index in 0..vcpu_config.vcpu_count { - let boot_receiver = if cpu_index != 0 { + let (boot_sender, boot_receiver) = if cpu_index != 0 { let (boot_sender, boot_receiver) = unbounded(); - boot_senders.push(boot_sender); - Some(boot_receiver) + (Some(boot_sender), Some(boot_receiver)) } else { - None + (None, None) }; let mut vcpu = Vcpu::new_aarch64( @@ -1537,6 +1537,10 @@ fn create_vcpus_aarch64( vcpu.configure_aarch64(guest_mem).map_err(Error::Vcpu)?; + if let Some(boot_sender) = boot_sender { + boot_senders.insert(vcpu.get_mpidr(), boot_sender); + } + vcpus.push(vcpu); } diff --git a/src/vmm/src/macos/vstate.rs b/src/vmm/src/macos/vstate.rs index d8977a1fc..38a8bb6ed 100644 --- a/src/vmm/src/macos/vstate.rs +++ b/src/vmm/src/macos/vstate.rs @@ -6,6 +6,7 @@ // found in the THIRD-PARTY file. use std::cell::Cell; +use std::collections::HashMap; use std::fmt::{Display, Formatter}; use std::io; use std::result; @@ -176,7 +177,7 @@ pub struct Vcpu { id: u8, boot_entry_addr: u64, boot_receiver: Option>, - boot_senders: Option>>, + boot_senders: Option>>, fdt_addr: u64, mmio_bus: Option, #[cfg_attr(all(test, target_arch = "aarch64"), allow(unused))] @@ -280,7 +281,7 @@ impl Vcpu { fdt_addr: 0, mmio_bus: None, exit_evt, - mpidr: 0, + mpidr: id as u64, event_receiver, event_sender: Some(event_sender), response_receiver: Some(response_receiver), @@ -304,7 +305,7 @@ impl Vcpu { self.mmio_bus = Some(mmio_bus); } - pub fn set_boot_senders(&mut self, boot_senders: Vec>) { + pub fn set_boot_senders(&mut self, boot_senders: HashMap>) { self.boot_senders = Some(boot_senders); } @@ -312,11 +313,8 @@ impl Vcpu { /// /// # Arguments /// - /// * `vm_fd` - The kvm `VmFd` for this microvm. /// * `guest_mem` - The guest memory used by this microvm. - /// * `kernel_load_addr` - Offset from `guest_mem` at which the kernel is loaded. pub fn configure_aarch64(&mut self, guest_mem: &GuestMemoryMmap) -> Result<()> { - self.mpidr = self.id as u64; self.fdt_addr = arch::aarch64::get_fdt_addr(guest_mem); Ok(()) @@ -369,13 +367,12 @@ impl Vcpu { "CpuOn: mpidr=0x{:x} entry=0x{:x} context_id={}", mpidr, entry, context_id ); - // assuming a flat CPU hierarchy, only the bottom bits of mpidr should be used, - // and cpuid == mpidr - let cpuid: usize = mpidr as usize; if let Some(boot_senders) = &self.boot_senders { - if let Some(sender) = boot_senders.get(cpuid - 1) { + if let Some(sender) = boot_senders.get(&mpidr) { sender.send(entry).unwrap() } + } else { + error!("CpuOn request coming from an unexpected vCPU={}", self.id); } Ok(VcpuEmulation::Handled) } @@ -432,7 +429,7 @@ impl Vcpu { /// Main loop of the vCPU thread. pub fn run(&mut self, init_tls_sender: Sender) { - let mut hvf_vcpu = HvfVcpu::new().expect("Can't create HVF vCPU"); + let mut hvf_vcpu = HvfVcpu::new(self.mpidr).expect("Can't create HVF vCPU"); let hvf_vcpuid = hvf_vcpu.id(); init_tls_sender From 0049b2b6c44558ee82d18df5bfb041fafbcce064 Mon Sep 17 00:00:00 2001 From: Sergio Lopez Date: Thu, 27 Feb 2025 15:10:06 +0100 Subject: [PATCH 39/40] hvf: update Hypervisor.framework bindings Re-generate them from SDK 15.0. Signed-off-by: Sergio Lopez --- src/hvf/src/bindings.rs | 4782 ++++++++++++++++++++++++++++++++------- src/hvf/src/lib.rs | 5 +- 2 files changed, 3906 insertions(+), 881 deletions(-) diff --git a/src/hvf/src/bindings.rs b/src/hvf/src/bindings.rs index fb76312de..f2cd1ed40 100644 --- a/src/hvf/src/bindings.rs +++ b/src/hvf/src/bindings.rs @@ -1,94 +1,13 @@ -/* automatically generated by rust-bindgen 0.56.0 */ +/* automatically generated by rust-bindgen 0.70.1 */ -pub const true_: u32 = 1; -pub const false_: u32 = 0; -pub const __bool_true_false_are_defined: u32 = 1; -pub const __WORDSIZE: u32 = 64; -pub const __DARWIN_ONLY_64_BIT_INO_T: u32 = 1; -pub const __DARWIN_ONLY_UNIX_CONFORMANCE: u32 = 1; -pub const __DARWIN_ONLY_VERS_1050: u32 = 1; -pub const __DARWIN_UNIX03: u32 = 1; -pub const __DARWIN_64_BIT_INO_T: u32 = 1; -pub const __DARWIN_VERS_1050: u32 = 1; -pub const __DARWIN_NON_CANCELABLE: u32 = 0; -pub const __DARWIN_SUF_EXTSN: &[u8; 14usize] = b"$DARWIN_EXTSN\0"; -pub const __DARWIN_C_ANSI: u32 = 4096; -pub const __DARWIN_C_FULL: u32 = 900000; -pub const __DARWIN_C_LEVEL: u32 = 900000; -pub const __STDC_WANT_LIB_EXT1__: u32 = 1; -pub const __DARWIN_NO_LONG_LONG: u32 = 0; -pub const _DARWIN_FEATURE_64_BIT_INODE: u32 = 1; -pub const _DARWIN_FEATURE_ONLY_64_BIT_INODE: u32 = 1; -pub const _DARWIN_FEATURE_ONLY_VERS_1050: u32 = 1; -pub const _DARWIN_FEATURE_ONLY_UNIX_CONFORMANCE: u32 = 1; -pub const _DARWIN_FEATURE_UNIX_CONFORMANCE: u32 = 3; -pub const __PTHREAD_SIZE__: u32 = 8176; -pub const __PTHREAD_ATTR_SIZE__: u32 = 56; -pub const __PTHREAD_MUTEXATTR_SIZE__: u32 = 8; -pub const __PTHREAD_MUTEX_SIZE__: u32 = 56; -pub const __PTHREAD_CONDATTR_SIZE__: u32 = 8; -pub const __PTHREAD_COND_SIZE__: u32 = 40; -pub const __PTHREAD_ONCE_SIZE__: u32 = 8; -pub const __PTHREAD_RWLOCK_SIZE__: u32 = 192; -pub const __PTHREAD_RWLOCKATTR_SIZE__: u32 = 16; -pub const INT8_MAX: u32 = 127; -pub const INT16_MAX: u32 = 32767; -pub const INT32_MAX: u32 = 2147483647; -pub const INT64_MAX: u64 = 9223372036854775807; -pub const INT8_MIN: i32 = -128; -pub const INT16_MIN: i32 = -32768; -pub const INT32_MIN: i32 = -2147483648; -pub const INT64_MIN: i64 = -9223372036854775808; -pub const UINT8_MAX: u32 = 255; -pub const UINT16_MAX: u32 = 65535; -pub const UINT32_MAX: u32 = 4294967295; -pub const UINT64_MAX: i32 = -1; -pub const INT_LEAST8_MIN: i32 = -128; -pub const INT_LEAST16_MIN: i32 = -32768; -pub const INT_LEAST32_MIN: i32 = -2147483648; -pub const INT_LEAST64_MIN: i64 = -9223372036854775808; -pub const INT_LEAST8_MAX: u32 = 127; -pub const INT_LEAST16_MAX: u32 = 32767; -pub const INT_LEAST32_MAX: u32 = 2147483647; -pub const INT_LEAST64_MAX: u64 = 9223372036854775807; -pub const UINT_LEAST8_MAX: u32 = 255; -pub const UINT_LEAST16_MAX: u32 = 65535; -pub const UINT_LEAST32_MAX: u32 = 4294967295; -pub const UINT_LEAST64_MAX: i32 = -1; -pub const INT_FAST8_MIN: i32 = -128; -pub const INT_FAST16_MIN: i32 = -32768; -pub const INT_FAST32_MIN: i32 = -2147483648; -pub const INT_FAST64_MIN: i64 = -9223372036854775808; -pub const INT_FAST8_MAX: u32 = 127; -pub const INT_FAST16_MAX: u32 = 32767; -pub const INT_FAST32_MAX: u32 = 2147483647; -pub const INT_FAST64_MAX: u64 = 9223372036854775807; -pub const UINT_FAST8_MAX: u32 = 255; -pub const UINT_FAST16_MAX: u32 = 65535; -pub const UINT_FAST32_MAX: u32 = 4294967295; -pub const UINT_FAST64_MAX: i32 = -1; -pub const INTPTR_MAX: u64 = 9223372036854775807; -pub const INTPTR_MIN: i64 = -9223372036854775808; -pub const UINTPTR_MAX: i32 = -1; -pub const SIZE_MAX: i32 = -1; -pub const RSIZE_MAX: i32 = -1; -pub const WINT_MIN: i32 = -2147483648; -pub const WINT_MAX: u32 = 2147483647; -pub const SIG_ATOMIC_MIN: i32 = -2147483648; -pub const SIG_ATOMIC_MAX: u32 = 2147483647; pub const API_TO_BE_DEPRECATED: u32 = 100000; -pub const __ENABLE_LEGACY_MAC_AVAILABILITY: u32 = 1; -pub const _QUAD_HIGHWORD: u32 = 1; -pub const _QUAD_LOWWORD: u32 = 0; -pub const __DARWIN_LITTLE_ENDIAN: u32 = 1234; -pub const __DARWIN_BIG_ENDIAN: u32 = 4321; -pub const __DARWIN_PDP_ENDIAN: u32 = 3412; -pub const __DARWIN_BYTE_ORDER: u32 = 1234; -pub const LITTLE_ENDIAN: u32 = 1234; -pub const BIG_ENDIAN: u32 = 4321; -pub const PDP_ENDIAN: u32 = 3412; -pub const BYTE_ORDER: u32 = 1234; -pub const __API_TO_BE_DEPRECATED: u32 = 100000; +pub const API_TO_BE_DEPRECATED_MACOS: u32 = 100000; +pub const API_TO_BE_DEPRECATED_IOS: u32 = 100000; +pub const API_TO_BE_DEPRECATED_TVOS: u32 = 100000; +pub const API_TO_BE_DEPRECATED_WATCHOS: u32 = 100000; +pub const __API_TO_BE_DEPRECATED_MACCATALYST: u32 = 100000; +pub const API_TO_BE_DEPRECATED_DRIVERKIT: u32 = 100000; +pub const API_TO_BE_DEPRECATED_VISIONOS: u32 = 100000; pub const __MAC_10_0: u32 = 1000; pub const __MAC_10_1: u32 = 1010; pub const __MAC_10_2: u32 = 1020; @@ -117,6 +36,7 @@ pub const __MAC_10_13_4: u32 = 101304; pub const __MAC_10_14: u32 = 101400; pub const __MAC_10_14_1: u32 = 101401; pub const __MAC_10_14_4: u32 = 101404; +pub const __MAC_10_14_5: u32 = 101405; pub const __MAC_10_14_6: u32 = 101406; pub const __MAC_10_15: u32 = 101500; pub const __MAC_10_15_1: u32 = 101501; @@ -124,6 +44,32 @@ pub const __MAC_10_15_4: u32 = 101504; pub const __MAC_10_16: u32 = 101600; pub const __MAC_11_0: u32 = 110000; pub const __MAC_11_1: u32 = 110100; +pub const __MAC_11_3: u32 = 110300; +pub const __MAC_11_4: u32 = 110400; +pub const __MAC_11_5: u32 = 110500; +pub const __MAC_11_6: u32 = 110600; +pub const __MAC_12_0: u32 = 120000; +pub const __MAC_12_1: u32 = 120100; +pub const __MAC_12_2: u32 = 120200; +pub const __MAC_12_3: u32 = 120300; +pub const __MAC_12_4: u32 = 120400; +pub const __MAC_12_5: u32 = 120500; +pub const __MAC_12_6: u32 = 120600; +pub const __MAC_12_7: u32 = 120700; +pub const __MAC_13_0: u32 = 130000; +pub const __MAC_13_1: u32 = 130100; +pub const __MAC_13_2: u32 = 130200; +pub const __MAC_13_3: u32 = 130300; +pub const __MAC_13_4: u32 = 130400; +pub const __MAC_13_5: u32 = 130500; +pub const __MAC_13_6: u32 = 130600; +pub const __MAC_14_0: u32 = 140000; +pub const __MAC_14_1: u32 = 140100; +pub const __MAC_14_2: u32 = 140200; +pub const __MAC_14_3: u32 = 140300; +pub const __MAC_14_4: u32 = 140400; +pub const __MAC_14_5: u32 = 140500; +pub const __MAC_15_0: u32 = 150000; pub const __IPHONE_2_0: u32 = 20000; pub const __IPHONE_2_1: u32 = 20100; pub const __IPHONE_2_2: u32 = 20200; @@ -175,6 +121,83 @@ pub const __IPHONE_14_0: u32 = 140000; pub const __IPHONE_14_1: u32 = 140100; pub const __IPHONE_14_2: u32 = 140200; pub const __IPHONE_14_3: u32 = 140300; +pub const __IPHONE_14_5: u32 = 140500; +pub const __IPHONE_14_4: u32 = 140400; +pub const __IPHONE_14_6: u32 = 140600; +pub const __IPHONE_14_7: u32 = 140700; +pub const __IPHONE_14_8: u32 = 140800; +pub const __IPHONE_15_0: u32 = 150000; +pub const __IPHONE_15_1: u32 = 150100; +pub const __IPHONE_15_2: u32 = 150200; +pub const __IPHONE_15_3: u32 = 150300; +pub const __IPHONE_15_4: u32 = 150400; +pub const __IPHONE_15_5: u32 = 150500; +pub const __IPHONE_15_6: u32 = 150600; +pub const __IPHONE_15_7: u32 = 150700; +pub const __IPHONE_15_8: u32 = 150800; +pub const __IPHONE_16_0: u32 = 160000; +pub const __IPHONE_16_1: u32 = 160100; +pub const __IPHONE_16_2: u32 = 160200; +pub const __IPHONE_16_3: u32 = 160300; +pub const __IPHONE_16_4: u32 = 160400; +pub const __IPHONE_16_5: u32 = 160500; +pub const __IPHONE_16_6: u32 = 160600; +pub const __IPHONE_16_7: u32 = 160700; +pub const __IPHONE_17_0: u32 = 170000; +pub const __IPHONE_17_1: u32 = 170100; +pub const __IPHONE_17_2: u32 = 170200; +pub const __IPHONE_17_3: u32 = 170300; +pub const __IPHONE_17_4: u32 = 170400; +pub const __IPHONE_17_5: u32 = 170500; +pub const __IPHONE_18_0: u32 = 180000; +pub const __WATCHOS_1_0: u32 = 10000; +pub const __WATCHOS_2_0: u32 = 20000; +pub const __WATCHOS_2_1: u32 = 20100; +pub const __WATCHOS_2_2: u32 = 20200; +pub const __WATCHOS_3_0: u32 = 30000; +pub const __WATCHOS_3_1: u32 = 30100; +pub const __WATCHOS_3_1_1: u32 = 30101; +pub const __WATCHOS_3_2: u32 = 30200; +pub const __WATCHOS_4_0: u32 = 40000; +pub const __WATCHOS_4_1: u32 = 40100; +pub const __WATCHOS_4_2: u32 = 40200; +pub const __WATCHOS_4_3: u32 = 40300; +pub const __WATCHOS_5_0: u32 = 50000; +pub const __WATCHOS_5_1: u32 = 50100; +pub const __WATCHOS_5_2: u32 = 50200; +pub const __WATCHOS_5_3: u32 = 50300; +pub const __WATCHOS_6_0: u32 = 60000; +pub const __WATCHOS_6_1: u32 = 60100; +pub const __WATCHOS_6_2: u32 = 60200; +pub const __WATCHOS_7_0: u32 = 70000; +pub const __WATCHOS_7_1: u32 = 70100; +pub const __WATCHOS_7_2: u32 = 70200; +pub const __WATCHOS_7_3: u32 = 70300; +pub const __WATCHOS_7_4: u32 = 70400; +pub const __WATCHOS_7_5: u32 = 70500; +pub const __WATCHOS_7_6: u32 = 70600; +pub const __WATCHOS_8_0: u32 = 80000; +pub const __WATCHOS_8_1: u32 = 80100; +pub const __WATCHOS_8_3: u32 = 80300; +pub const __WATCHOS_8_4: u32 = 80400; +pub const __WATCHOS_8_5: u32 = 80500; +pub const __WATCHOS_8_6: u32 = 80600; +pub const __WATCHOS_8_7: u32 = 80700; +pub const __WATCHOS_8_8: u32 = 80800; +pub const __WATCHOS_9_0: u32 = 90000; +pub const __WATCHOS_9_1: u32 = 90100; +pub const __WATCHOS_9_2: u32 = 90200; +pub const __WATCHOS_9_3: u32 = 90300; +pub const __WATCHOS_9_4: u32 = 90400; +pub const __WATCHOS_9_5: u32 = 90500; +pub const __WATCHOS_9_6: u32 = 90600; +pub const __WATCHOS_10_0: u32 = 100000; +pub const __WATCHOS_10_1: u32 = 100100; +pub const __WATCHOS_10_2: u32 = 100200; +pub const __WATCHOS_10_3: u32 = 100300; +pub const __WATCHOS_10_4: u32 = 100400; +pub const __WATCHOS_10_5: u32 = 100500; +pub const __WATCHOS_11_0: u32 = 110000; pub const __TVOS_9_0: u32 = 90000; pub const __TVOS_9_1: u32 = 90100; pub const __TVOS_9_2: u32 = 90200; @@ -200,28 +223,75 @@ pub const __TVOS_14_0: u32 = 140000; pub const __TVOS_14_1: u32 = 140100; pub const __TVOS_14_2: u32 = 140200; pub const __TVOS_14_3: u32 = 140300; -pub const __WATCHOS_1_0: u32 = 10000; -pub const __WATCHOS_2_0: u32 = 20000; -pub const __WATCHOS_2_1: u32 = 20100; -pub const __WATCHOS_2_2: u32 = 20200; -pub const __WATCHOS_3_0: u32 = 30000; -pub const __WATCHOS_3_1: u32 = 30100; -pub const __WATCHOS_3_1_1: u32 = 30101; -pub const __WATCHOS_3_2: u32 = 30200; -pub const __WATCHOS_4_0: u32 = 40000; -pub const __WATCHOS_4_1: u32 = 40100; -pub const __WATCHOS_4_2: u32 = 40200; -pub const __WATCHOS_4_3: u32 = 40300; -pub const __WATCHOS_5_0: u32 = 50000; -pub const __WATCHOS_5_1: u32 = 50100; -pub const __WATCHOS_5_2: u32 = 50200; -pub const __WATCHOS_5_3: u32 = 50300; -pub const __WATCHOS_6_0: u32 = 60000; -pub const __WATCHOS_6_1: u32 = 60100; -pub const __WATCHOS_6_2: u32 = 60200; -pub const __WATCHOS_7_0: u32 = 70000; -pub const __WATCHOS_7_1: u32 = 70100; -pub const __WATCHOS_7_2: u32 = 70200; +pub const __TVOS_14_5: u32 = 140500; +pub const __TVOS_14_6: u32 = 140600; +pub const __TVOS_14_7: u32 = 140700; +pub const __TVOS_15_0: u32 = 150000; +pub const __TVOS_15_1: u32 = 150100; +pub const __TVOS_15_2: u32 = 150200; +pub const __TVOS_15_3: u32 = 150300; +pub const __TVOS_15_4: u32 = 150400; +pub const __TVOS_15_5: u32 = 150500; +pub const __TVOS_15_6: u32 = 150600; +pub const __TVOS_16_0: u32 = 160000; +pub const __TVOS_16_1: u32 = 160100; +pub const __TVOS_16_2: u32 = 160200; +pub const __TVOS_16_3: u32 = 160300; +pub const __TVOS_16_4: u32 = 160400; +pub const __TVOS_16_5: u32 = 160500; +pub const __TVOS_16_6: u32 = 160600; +pub const __TVOS_17_0: u32 = 170000; +pub const __TVOS_17_1: u32 = 170100; +pub const __TVOS_17_2: u32 = 170200; +pub const __TVOS_17_3: u32 = 170300; +pub const __TVOS_17_4: u32 = 170400; +pub const __TVOS_17_5: u32 = 170500; +pub const __TVOS_18_0: u32 = 180000; +pub const __BRIDGEOS_2_0: u32 = 20000; +pub const __BRIDGEOS_3_0: u32 = 30000; +pub const __BRIDGEOS_3_1: u32 = 30100; +pub const __BRIDGEOS_3_4: u32 = 30400; +pub const __BRIDGEOS_4_0: u32 = 40000; +pub const __BRIDGEOS_4_1: u32 = 40100; +pub const __BRIDGEOS_5_0: u32 = 50000; +pub const __BRIDGEOS_5_1: u32 = 50100; +pub const __BRIDGEOS_5_3: u32 = 50300; +pub const __BRIDGEOS_6_0: u32 = 60000; +pub const __BRIDGEOS_6_2: u32 = 60200; +pub const __BRIDGEOS_6_4: u32 = 60400; +pub const __BRIDGEOS_6_5: u32 = 60500; +pub const __BRIDGEOS_6_6: u32 = 60600; +pub const __BRIDGEOS_7_0: u32 = 70000; +pub const __BRIDGEOS_7_1: u32 = 70100; +pub const __BRIDGEOS_7_2: u32 = 70200; +pub const __BRIDGEOS_7_3: u32 = 70300; +pub const __BRIDGEOS_7_4: u32 = 70400; +pub const __BRIDGEOS_7_6: u32 = 70600; +pub const __BRIDGEOS_8_0: u32 = 80000; +pub const __BRIDGEOS_8_1: u32 = 80100; +pub const __BRIDGEOS_8_2: u32 = 80200; +pub const __BRIDGEOS_8_3: u32 = 80300; +pub const __BRIDGEOS_8_4: u32 = 80400; +pub const __BRIDGEOS_8_5: u32 = 80500; +pub const __BRIDGEOS_9_0: u32 = 90000; +pub const __DRIVERKIT_19_0: u32 = 190000; +pub const __DRIVERKIT_20_0: u32 = 200000; +pub const __DRIVERKIT_21_0: u32 = 210000; +pub const __DRIVERKIT_22_0: u32 = 220000; +pub const __DRIVERKIT_22_4: u32 = 220400; +pub const __DRIVERKIT_22_5: u32 = 220500; +pub const __DRIVERKIT_22_6: u32 = 220600; +pub const __DRIVERKIT_23_0: u32 = 230000; +pub const __DRIVERKIT_23_1: u32 = 230100; +pub const __DRIVERKIT_23_2: u32 = 230200; +pub const __DRIVERKIT_23_3: u32 = 230300; +pub const __DRIVERKIT_23_4: u32 = 230400; +pub const __DRIVERKIT_23_5: u32 = 230500; +pub const __DRIVERKIT_24_0: u32 = 240000; +pub const __VISIONOS_1_0: u32 = 10000; +pub const __VISIONOS_1_1: u32 = 10100; +pub const __VISIONOS_1_2: u32 = 10200; +pub const __VISIONOS_2_0: u32 = 20000; pub const MAC_OS_X_VERSION_10_0: u32 = 1000; pub const MAC_OS_X_VERSION_10_1: u32 = 1010; pub const MAC_OS_X_VERSION_10_2: u32 = 1020; @@ -250,13 +320,139 @@ pub const MAC_OS_X_VERSION_10_13_4: u32 = 101304; pub const MAC_OS_X_VERSION_10_14: u32 = 101400; pub const MAC_OS_X_VERSION_10_14_1: u32 = 101401; pub const MAC_OS_X_VERSION_10_14_4: u32 = 101404; +pub const MAC_OS_X_VERSION_10_14_5: u32 = 101405; pub const MAC_OS_X_VERSION_10_14_6: u32 = 101406; pub const MAC_OS_X_VERSION_10_15: u32 = 101500; pub const MAC_OS_X_VERSION_10_15_1: u32 = 101501; +pub const MAC_OS_X_VERSION_10_15_4: u32 = 101504; pub const MAC_OS_X_VERSION_10_16: u32 = 101600; pub const MAC_OS_VERSION_11_0: u32 = 110000; -pub const __DRIVERKIT_19_0: u32 = 190000; -pub const __DRIVERKIT_20_0: u32 = 200000; +pub const MAC_OS_VERSION_11_1: u32 = 110100; +pub const MAC_OS_VERSION_11_3: u32 = 110300; +pub const MAC_OS_VERSION_11_4: u32 = 110400; +pub const MAC_OS_VERSION_11_5: u32 = 110500; +pub const MAC_OS_VERSION_11_6: u32 = 110600; +pub const MAC_OS_VERSION_12_0: u32 = 120000; +pub const MAC_OS_VERSION_12_1: u32 = 120100; +pub const MAC_OS_VERSION_12_2: u32 = 120200; +pub const MAC_OS_VERSION_12_3: u32 = 120300; +pub const MAC_OS_VERSION_12_4: u32 = 120400; +pub const MAC_OS_VERSION_12_5: u32 = 120500; +pub const MAC_OS_VERSION_12_6: u32 = 120600; +pub const MAC_OS_VERSION_12_7: u32 = 120700; +pub const MAC_OS_VERSION_13_0: u32 = 130000; +pub const MAC_OS_VERSION_13_1: u32 = 130100; +pub const MAC_OS_VERSION_13_2: u32 = 130200; +pub const MAC_OS_VERSION_13_3: u32 = 130300; +pub const MAC_OS_VERSION_13_4: u32 = 130400; +pub const MAC_OS_VERSION_13_5: u32 = 130500; +pub const MAC_OS_VERSION_13_6: u32 = 130600; +pub const MAC_OS_VERSION_14_0: u32 = 140000; +pub const MAC_OS_VERSION_14_1: u32 = 140100; +pub const MAC_OS_VERSION_14_2: u32 = 140200; +pub const MAC_OS_VERSION_14_3: u32 = 140300; +pub const MAC_OS_VERSION_14_4: u32 = 140400; +pub const MAC_OS_VERSION_14_5: u32 = 140500; +pub const MAC_OS_VERSION_15_0: u32 = 150000; +pub const __MAC_OS_X_VERSION_MAX_ALLOWED: u32 = 150000; +pub const __ENABLE_LEGACY_MAC_AVAILABILITY: u32 = 1; +pub const __has_safe_buffers: u32 = 1; +pub const __DARWIN_ONLY_64_BIT_INO_T: u32 = 1; +pub const __DARWIN_ONLY_UNIX_CONFORMANCE: u32 = 1; +pub const __DARWIN_ONLY_VERS_1050: u32 = 1; +pub const __DARWIN_UNIX03: u32 = 1; +pub const __DARWIN_64_BIT_INO_T: u32 = 1; +pub const __DARWIN_VERS_1050: u32 = 1; +pub const __DARWIN_NON_CANCELABLE: u32 = 0; +pub const __DARWIN_SUF_EXTSN: &[u8; 14] = b"$DARWIN_EXTSN\0"; +pub const __DARWIN_C_ANSI: u32 = 4096; +pub const __DARWIN_C_FULL: u32 = 900000; +pub const __DARWIN_C_LEVEL: u32 = 900000; +pub const __STDC_WANT_LIB_EXT1__: u32 = 1; +pub const __DARWIN_NO_LONG_LONG: u32 = 0; +pub const _DARWIN_FEATURE_64_BIT_INODE: u32 = 1; +pub const _DARWIN_FEATURE_ONLY_64_BIT_INODE: u32 = 1; +pub const _DARWIN_FEATURE_ONLY_VERS_1050: u32 = 1; +pub const _DARWIN_FEATURE_ONLY_UNIX_CONFORMANCE: u32 = 1; +pub const _DARWIN_FEATURE_UNIX_CONFORMANCE: u32 = 3; +pub const __has_ptrcheck: u32 = 0; +pub const __bool_true_false_are_defined: u32 = 1; +pub const true_: u32 = 1; +pub const false_: u32 = 0; +pub const __WORDSIZE: u32 = 64; +pub const USE_CLANG_TYPES: u32 = 0; +pub const __PTHREAD_SIZE__: u32 = 8176; +pub const __PTHREAD_ATTR_SIZE__: u32 = 56; +pub const __PTHREAD_MUTEXATTR_SIZE__: u32 = 8; +pub const __PTHREAD_MUTEX_SIZE__: u32 = 56; +pub const __PTHREAD_CONDATTR_SIZE__: u32 = 8; +pub const __PTHREAD_COND_SIZE__: u32 = 40; +pub const __PTHREAD_ONCE_SIZE__: u32 = 8; +pub const __PTHREAD_RWLOCK_SIZE__: u32 = 192; +pub const __PTHREAD_RWLOCKATTR_SIZE__: u32 = 16; +pub const INT8_MAX: u32 = 127; +pub const INT16_MAX: u32 = 32767; +pub const INT32_MAX: u32 = 2147483647; +pub const INT64_MAX: u64 = 9223372036854775807; +pub const INT8_MIN: i32 = -128; +pub const INT16_MIN: i32 = -32768; +pub const INT32_MIN: i32 = -2147483648; +pub const INT64_MIN: i64 = -9223372036854775808; +pub const UINT8_MAX: u32 = 255; +pub const UINT16_MAX: u32 = 65535; +pub const UINT32_MAX: u32 = 4294967295; +pub const UINT64_MAX: i32 = -1; +pub const INT_LEAST8_MIN: i32 = -128; +pub const INT_LEAST16_MIN: i32 = -32768; +pub const INT_LEAST32_MIN: i32 = -2147483648; +pub const INT_LEAST64_MIN: i64 = -9223372036854775808; +pub const INT_LEAST8_MAX: u32 = 127; +pub const INT_LEAST16_MAX: u32 = 32767; +pub const INT_LEAST32_MAX: u32 = 2147483647; +pub const INT_LEAST64_MAX: u64 = 9223372036854775807; +pub const UINT_LEAST8_MAX: u32 = 255; +pub const UINT_LEAST16_MAX: u32 = 65535; +pub const UINT_LEAST32_MAX: u32 = 4294967295; +pub const UINT_LEAST64_MAX: i32 = -1; +pub const INT_FAST8_MIN: i32 = -128; +pub const INT_FAST16_MIN: i32 = -32768; +pub const INT_FAST32_MIN: i32 = -2147483648; +pub const INT_FAST64_MIN: i64 = -9223372036854775808; +pub const INT_FAST8_MAX: u32 = 127; +pub const INT_FAST16_MAX: u32 = 32767; +pub const INT_FAST32_MAX: u32 = 2147483647; +pub const INT_FAST64_MAX: u64 = 9223372036854775807; +pub const UINT_FAST8_MAX: u32 = 255; +pub const UINT_FAST16_MAX: u32 = 65535; +pub const UINT_FAST32_MAX: u32 = 4294967295; +pub const UINT_FAST64_MAX: i32 = -1; +pub const INTPTR_MAX: u64 = 9223372036854775807; +pub const INTPTR_MIN: i64 = -9223372036854775808; +pub const UINTPTR_MAX: i32 = -1; +pub const SIZE_MAX: i32 = -1; +pub const RSIZE_MAX: i32 = -1; +pub const WINT_MIN: i32 = -2147483648; +pub const WINT_MAX: u32 = 2147483647; +pub const SIG_ATOMIC_MIN: i32 = -2147483648; +pub const SIG_ATOMIC_MAX: u32 = 2147483647; +pub const _QUAD_HIGHWORD: u32 = 1; +pub const _QUAD_LOWWORD: u32 = 0; +pub const __DARWIN_LITTLE_ENDIAN: u32 = 1234; +pub const __DARWIN_BIG_ENDIAN: u32 = 4321; +pub const __DARWIN_PDP_ENDIAN: u32 = 3412; +pub const LITTLE_ENDIAN: u32 = 1234; +pub const BIG_ENDIAN: u32 = 4321; +pub const PDP_ENDIAN: u32 = 3412; +pub const __DARWIN_BYTE_ORDER: u32 = 1234; +pub const BYTE_ORDER: u32 = 1234; +pub const USE_CLANG_STDDEF: u32 = 0; +pub const __API_TO_BE_DEPRECATED: u32 = 100000; +pub const __API_TO_BE_DEPRECATED_MACOS: u32 = 100000; +pub const __API_TO_BE_DEPRECATED_IOS: u32 = 100000; +pub const __API_TO_BE_DEPRECATED_WATCHOS: u32 = 100000; +pub const __API_TO_BE_DEPRECATED_TVOS: u32 = 100000; +pub const __API_TO_BE_DEPRECATED_DRIVERKIT: u32 = 100000; +pub const __API_TO_BE_DEPRECATED_VISIONOS: u32 = 100000; pub const __DARWIN_FD_SETSIZE: u32 = 1024; pub const __DARWIN_NBBY: u32 = 8; pub const NBBY: u32 = 8; @@ -315,13 +511,14 @@ pub const KERN_CODESIGN_ERROR: u32 = 50; pub const KERN_POLICY_STATIC: u32 = 51; pub const KERN_INSUFFICIENT_BUFFER_SIZE: u32 = 52; pub const KERN_DENIED: u32 = 53; +pub const KERN_MISSING_KC: u32 = 54; +pub const KERN_INVALID_KC: u32 = 55; +pub const KERN_NOT_FOUND: u32 = 56; pub const KERN_RETURN_MAX: u32 = 256; pub const code_emask: u32 = 16383; pub const err_max_system: u32 = 63; pub const DYNAMIC_TARGETS_ENABLED: u32 = 0; pub const TARGET_OS_MAC: u32 = 1; -pub const TARGET_OS_WIN32: u32 = 0; -pub const TARGET_OS_UNIX: u32 = 0; pub const TARGET_OS_OSX: u32 = 1; pub const TARGET_OS_IPHONE: u32 = 0; pub const TARGET_OS_IOS: u32 = 0; @@ -331,29 +528,37 @@ pub const TARGET_OS_MACCATALYST: u32 = 0; pub const TARGET_OS_UIKITFORMAC: u32 = 0; pub const TARGET_OS_SIMULATOR: u32 = 0; pub const TARGET_OS_EMBEDDED: u32 = 0; +pub const TARGET_OS_UNIX: u32 = 0; pub const TARGET_OS_RTKIT: u32 = 0; +pub const TARGET_RT_LITTLE_ENDIAN: u32 = 1; +pub const TARGET_RT_BIG_ENDIAN: u32 = 0; +pub const TARGET_RT_64_BIT: u32 = 1; +pub const TARGET_RT_MAC_CFM: u32 = 0; +pub const TARGET_RT_MAC_MACHO: u32 = 1; +pub const TARGET_CPU_ARM64: u32 = 1; +pub const TARGET_OS_VISION: u32 = 0; pub const TARGET_OS_DRIVERKIT: u32 = 0; -pub const TARGET_IPHONE_SIMULATOR: u32 = 0; -pub const TARGET_OS_NANO: u32 = 0; +pub const TARGET_OS_WIN32: u32 = 0; +pub const TARGET_OS_WINDOWS: u32 = 0; +pub const TARGET_OS_LINUX: u32 = 0; pub const TARGET_CPU_PPC: u32 = 0; pub const TARGET_CPU_PPC64: u32 = 0; pub const TARGET_CPU_68K: u32 = 0; pub const TARGET_CPU_X86: u32 = 0; pub const TARGET_CPU_X86_64: u32 = 0; pub const TARGET_CPU_ARM: u32 = 0; -pub const TARGET_CPU_ARM64: u32 = 1; pub const TARGET_CPU_MIPS: u32 = 0; pub const TARGET_CPU_SPARC: u32 = 0; pub const TARGET_CPU_ALPHA: u32 = 0; -pub const TARGET_RT_MAC_CFM: u32 = 0; -pub const TARGET_RT_MAC_MACHO: u32 = 1; -pub const TARGET_RT_LITTLE_ENDIAN: u32 = 1; -pub const TARGET_RT_BIG_ENDIAN: u32 = 0; -pub const TARGET_RT_64_BIT: u32 = 1; +pub const TARGET_IPHONE_SIMULATOR: u32 = 0; +pub const TARGET_OS_NANO: u32 = 0; pub const OS_OBJECT_HAVE_OBJC_SUPPORT: u32 = 0; pub const OS_OBJECT_USE_OBJC: u32 = 0; pub const OS_OBJECT_SWIFT3: u32 = 0; pub const OS_OBJECT_USE_OBJC_RETAIN_RELEASE: u32 = 0; +pub type os_function_t = + ::std::option::Option; +pub type os_block_t = *mut ::std::os::raw::c_void; pub type int_least8_t = i8; pub type int_least16_t = i16; pub type int_least32_t = i32; @@ -386,41 +591,16 @@ pub type __darwin_ct_rune_t = ::std::os::raw::c_int; pub union __mbstate_t { pub __mbstate8: [::std::os::raw::c_char; 128usize], pub _mbstateL: ::std::os::raw::c_longlong, - _bindgen_union_align: [u64; 16usize], -} -#[test] -fn bindgen_test_layout___mbstate_t() { - assert_eq!( - ::std::mem::size_of::<__mbstate_t>(), - 128usize, - concat!("Size of: ", stringify!(__mbstate_t)) - ); - assert_eq!( - ::std::mem::align_of::<__mbstate_t>(), - 8usize, - concat!("Alignment of ", stringify!(__mbstate_t)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<__mbstate_t>())).__mbstate8 as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(__mbstate_t), - "::", - stringify!(__mbstate8) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<__mbstate_t>()))._mbstateL as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(__mbstate_t), - "::", - stringify!(_mbstateL) - ) - ); } +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of __mbstate_t"][::std::mem::size_of::<__mbstate_t>() - 128usize]; + ["Alignment of __mbstate_t"][::std::mem::align_of::<__mbstate_t>() - 8usize]; + ["Offset of field: __mbstate_t::__mbstate8"] + [::std::mem::offset_of!(__mbstate_t, __mbstate8) - 0usize]; + ["Offset of field: __mbstate_t::_mbstateL"] + [::std::mem::offset_of!(__mbstate_t, _mbstateL) - 0usize]; +}; pub type __darwin_mbstate_t = __mbstate_t; pub type __darwin_ptrdiff_t = ::std::os::raw::c_long; pub type __darwin_size_t = ::std::os::raw::c_ulong; @@ -459,435 +639,169 @@ pub struct __darwin_pthread_handler_rec { pub __arg: *mut ::std::os::raw::c_void, pub __next: *mut __darwin_pthread_handler_rec, } -#[test] -fn bindgen_test_layout___darwin_pthread_handler_rec() { - assert_eq!( - ::std::mem::size_of::<__darwin_pthread_handler_rec>(), - 24usize, - concat!("Size of: ", stringify!(__darwin_pthread_handler_rec)) - ); - assert_eq!( - ::std::mem::align_of::<__darwin_pthread_handler_rec>(), - 8usize, - concat!("Alignment of ", stringify!(__darwin_pthread_handler_rec)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<__darwin_pthread_handler_rec>())).__routine as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(__darwin_pthread_handler_rec), - "::", - stringify!(__routine) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<__darwin_pthread_handler_rec>())).__arg as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(__darwin_pthread_handler_rec), - "::", - stringify!(__arg) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<__darwin_pthread_handler_rec>())).__next as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(__darwin_pthread_handler_rec), - "::", - stringify!(__next) - ) - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of __darwin_pthread_handler_rec"] + [::std::mem::size_of::<__darwin_pthread_handler_rec>() - 24usize]; + ["Alignment of __darwin_pthread_handler_rec"] + [::std::mem::align_of::<__darwin_pthread_handler_rec>() - 8usize]; + ["Offset of field: __darwin_pthread_handler_rec::__routine"] + [::std::mem::offset_of!(__darwin_pthread_handler_rec, __routine) - 0usize]; + ["Offset of field: __darwin_pthread_handler_rec::__arg"] + [::std::mem::offset_of!(__darwin_pthread_handler_rec, __arg) - 8usize]; + ["Offset of field: __darwin_pthread_handler_rec::__next"] + [::std::mem::offset_of!(__darwin_pthread_handler_rec, __next) - 16usize]; +}; #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone)] pub struct _opaque_pthread_attr_t { pub __sig: ::std::os::raw::c_long, pub __opaque: [::std::os::raw::c_char; 56usize], } -#[test] -fn bindgen_test_layout__opaque_pthread_attr_t() { - assert_eq!( - ::std::mem::size_of::<_opaque_pthread_attr_t>(), - 64usize, - concat!("Size of: ", stringify!(_opaque_pthread_attr_t)) - ); - assert_eq!( - ::std::mem::align_of::<_opaque_pthread_attr_t>(), - 8usize, - concat!("Alignment of ", stringify!(_opaque_pthread_attr_t)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_opaque_pthread_attr_t>())).__sig as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_attr_t), - "::", - stringify!(__sig) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_opaque_pthread_attr_t>())).__opaque as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_attr_t), - "::", - stringify!(__opaque) - ) - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _opaque_pthread_attr_t"][::std::mem::size_of::<_opaque_pthread_attr_t>() - 64usize]; + ["Alignment of _opaque_pthread_attr_t"] + [::std::mem::align_of::<_opaque_pthread_attr_t>() - 8usize]; + ["Offset of field: _opaque_pthread_attr_t::__sig"] + [::std::mem::offset_of!(_opaque_pthread_attr_t, __sig) - 0usize]; + ["Offset of field: _opaque_pthread_attr_t::__opaque"] + [::std::mem::offset_of!(_opaque_pthread_attr_t, __opaque) - 8usize]; +}; #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone)] pub struct _opaque_pthread_cond_t { pub __sig: ::std::os::raw::c_long, pub __opaque: [::std::os::raw::c_char; 40usize], } -#[test] -fn bindgen_test_layout__opaque_pthread_cond_t() { - assert_eq!( - ::std::mem::size_of::<_opaque_pthread_cond_t>(), - 48usize, - concat!("Size of: ", stringify!(_opaque_pthread_cond_t)) - ); - assert_eq!( - ::std::mem::align_of::<_opaque_pthread_cond_t>(), - 8usize, - concat!("Alignment of ", stringify!(_opaque_pthread_cond_t)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_opaque_pthread_cond_t>())).__sig as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_cond_t), - "::", - stringify!(__sig) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_opaque_pthread_cond_t>())).__opaque as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_cond_t), - "::", - stringify!(__opaque) - ) - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _opaque_pthread_cond_t"][::std::mem::size_of::<_opaque_pthread_cond_t>() - 48usize]; + ["Alignment of _opaque_pthread_cond_t"] + [::std::mem::align_of::<_opaque_pthread_cond_t>() - 8usize]; + ["Offset of field: _opaque_pthread_cond_t::__sig"] + [::std::mem::offset_of!(_opaque_pthread_cond_t, __sig) - 0usize]; + ["Offset of field: _opaque_pthread_cond_t::__opaque"] + [::std::mem::offset_of!(_opaque_pthread_cond_t, __opaque) - 8usize]; +}; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct _opaque_pthread_condattr_t { pub __sig: ::std::os::raw::c_long, pub __opaque: [::std::os::raw::c_char; 8usize], } -#[test] -fn bindgen_test_layout__opaque_pthread_condattr_t() { - assert_eq!( - ::std::mem::size_of::<_opaque_pthread_condattr_t>(), - 16usize, - concat!("Size of: ", stringify!(_opaque_pthread_condattr_t)) - ); - assert_eq!( - ::std::mem::align_of::<_opaque_pthread_condattr_t>(), - 8usize, - concat!("Alignment of ", stringify!(_opaque_pthread_condattr_t)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<_opaque_pthread_condattr_t>())).__sig as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_condattr_t), - "::", - stringify!(__sig) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<_opaque_pthread_condattr_t>())).__opaque as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_condattr_t), - "::", - stringify!(__opaque) - ) - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _opaque_pthread_condattr_t"] + [::std::mem::size_of::<_opaque_pthread_condattr_t>() - 16usize]; + ["Alignment of _opaque_pthread_condattr_t"] + [::std::mem::align_of::<_opaque_pthread_condattr_t>() - 8usize]; + ["Offset of field: _opaque_pthread_condattr_t::__sig"] + [::std::mem::offset_of!(_opaque_pthread_condattr_t, __sig) - 0usize]; + ["Offset of field: _opaque_pthread_condattr_t::__opaque"] + [::std::mem::offset_of!(_opaque_pthread_condattr_t, __opaque) - 8usize]; +}; #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone)] pub struct _opaque_pthread_mutex_t { pub __sig: ::std::os::raw::c_long, pub __opaque: [::std::os::raw::c_char; 56usize], } -#[test] -fn bindgen_test_layout__opaque_pthread_mutex_t() { - assert_eq!( - ::std::mem::size_of::<_opaque_pthread_mutex_t>(), - 64usize, - concat!("Size of: ", stringify!(_opaque_pthread_mutex_t)) - ); - assert_eq!( - ::std::mem::align_of::<_opaque_pthread_mutex_t>(), - 8usize, - concat!("Alignment of ", stringify!(_opaque_pthread_mutex_t)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_opaque_pthread_mutex_t>())).__sig as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_mutex_t), - "::", - stringify!(__sig) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<_opaque_pthread_mutex_t>())).__opaque as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_mutex_t), - "::", - stringify!(__opaque) - ) - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _opaque_pthread_mutex_t"][::std::mem::size_of::<_opaque_pthread_mutex_t>() - 64usize]; + ["Alignment of _opaque_pthread_mutex_t"] + [::std::mem::align_of::<_opaque_pthread_mutex_t>() - 8usize]; + ["Offset of field: _opaque_pthread_mutex_t::__sig"] + [::std::mem::offset_of!(_opaque_pthread_mutex_t, __sig) - 0usize]; + ["Offset of field: _opaque_pthread_mutex_t::__opaque"] + [::std::mem::offset_of!(_opaque_pthread_mutex_t, __opaque) - 8usize]; +}; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct _opaque_pthread_mutexattr_t { pub __sig: ::std::os::raw::c_long, pub __opaque: [::std::os::raw::c_char; 8usize], } -#[test] -fn bindgen_test_layout__opaque_pthread_mutexattr_t() { - assert_eq!( - ::std::mem::size_of::<_opaque_pthread_mutexattr_t>(), - 16usize, - concat!("Size of: ", stringify!(_opaque_pthread_mutexattr_t)) - ); - assert_eq!( - ::std::mem::align_of::<_opaque_pthread_mutexattr_t>(), - 8usize, - concat!("Alignment of ", stringify!(_opaque_pthread_mutexattr_t)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<_opaque_pthread_mutexattr_t>())).__sig as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_mutexattr_t), - "::", - stringify!(__sig) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<_opaque_pthread_mutexattr_t>())).__opaque as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_mutexattr_t), - "::", - stringify!(__opaque) - ) - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _opaque_pthread_mutexattr_t"] + [::std::mem::size_of::<_opaque_pthread_mutexattr_t>() - 16usize]; + ["Alignment of _opaque_pthread_mutexattr_t"] + [::std::mem::align_of::<_opaque_pthread_mutexattr_t>() - 8usize]; + ["Offset of field: _opaque_pthread_mutexattr_t::__sig"] + [::std::mem::offset_of!(_opaque_pthread_mutexattr_t, __sig) - 0usize]; + ["Offset of field: _opaque_pthread_mutexattr_t::__opaque"] + [::std::mem::offset_of!(_opaque_pthread_mutexattr_t, __opaque) - 8usize]; +}; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct _opaque_pthread_once_t { pub __sig: ::std::os::raw::c_long, pub __opaque: [::std::os::raw::c_char; 8usize], } -#[test] -fn bindgen_test_layout__opaque_pthread_once_t() { - assert_eq!( - ::std::mem::size_of::<_opaque_pthread_once_t>(), - 16usize, - concat!("Size of: ", stringify!(_opaque_pthread_once_t)) - ); - assert_eq!( - ::std::mem::align_of::<_opaque_pthread_once_t>(), - 8usize, - concat!("Alignment of ", stringify!(_opaque_pthread_once_t)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_opaque_pthread_once_t>())).__sig as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_once_t), - "::", - stringify!(__sig) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_opaque_pthread_once_t>())).__opaque as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_once_t), - "::", - stringify!(__opaque) - ) - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _opaque_pthread_once_t"][::std::mem::size_of::<_opaque_pthread_once_t>() - 16usize]; + ["Alignment of _opaque_pthread_once_t"] + [::std::mem::align_of::<_opaque_pthread_once_t>() - 8usize]; + ["Offset of field: _opaque_pthread_once_t::__sig"] + [::std::mem::offset_of!(_opaque_pthread_once_t, __sig) - 0usize]; + ["Offset of field: _opaque_pthread_once_t::__opaque"] + [::std::mem::offset_of!(_opaque_pthread_once_t, __opaque) - 8usize]; +}; #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone)] pub struct _opaque_pthread_rwlock_t { pub __sig: ::std::os::raw::c_long, pub __opaque: [::std::os::raw::c_char; 192usize], } -#[test] -fn bindgen_test_layout__opaque_pthread_rwlock_t() { - assert_eq!( - ::std::mem::size_of::<_opaque_pthread_rwlock_t>(), - 200usize, - concat!("Size of: ", stringify!(_opaque_pthread_rwlock_t)) - ); - assert_eq!( - ::std::mem::align_of::<_opaque_pthread_rwlock_t>(), - 8usize, - concat!("Alignment of ", stringify!(_opaque_pthread_rwlock_t)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_opaque_pthread_rwlock_t>())).__sig as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_rwlock_t), - "::", - stringify!(__sig) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<_opaque_pthread_rwlock_t>())).__opaque as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_rwlock_t), - "::", - stringify!(__opaque) - ) - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _opaque_pthread_rwlock_t"] + [::std::mem::size_of::<_opaque_pthread_rwlock_t>() - 200usize]; + ["Alignment of _opaque_pthread_rwlock_t"] + [::std::mem::align_of::<_opaque_pthread_rwlock_t>() - 8usize]; + ["Offset of field: _opaque_pthread_rwlock_t::__sig"] + [::std::mem::offset_of!(_opaque_pthread_rwlock_t, __sig) - 0usize]; + ["Offset of field: _opaque_pthread_rwlock_t::__opaque"] + [::std::mem::offset_of!(_opaque_pthread_rwlock_t, __opaque) - 8usize]; +}; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct _opaque_pthread_rwlockattr_t { pub __sig: ::std::os::raw::c_long, pub __opaque: [::std::os::raw::c_char; 16usize], } -#[test] -fn bindgen_test_layout__opaque_pthread_rwlockattr_t() { - assert_eq!( - ::std::mem::size_of::<_opaque_pthread_rwlockattr_t>(), - 24usize, - concat!("Size of: ", stringify!(_opaque_pthread_rwlockattr_t)) - ); - assert_eq!( - ::std::mem::align_of::<_opaque_pthread_rwlockattr_t>(), - 8usize, - concat!("Alignment of ", stringify!(_opaque_pthread_rwlockattr_t)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<_opaque_pthread_rwlockattr_t>())).__sig as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_rwlockattr_t), - "::", - stringify!(__sig) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<_opaque_pthread_rwlockattr_t>())).__opaque as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_rwlockattr_t), - "::", - stringify!(__opaque) - ) - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _opaque_pthread_rwlockattr_t"] + [::std::mem::size_of::<_opaque_pthread_rwlockattr_t>() - 24usize]; + ["Alignment of _opaque_pthread_rwlockattr_t"] + [::std::mem::align_of::<_opaque_pthread_rwlockattr_t>() - 8usize]; + ["Offset of field: _opaque_pthread_rwlockattr_t::__sig"] + [::std::mem::offset_of!(_opaque_pthread_rwlockattr_t, __sig) - 0usize]; + ["Offset of field: _opaque_pthread_rwlockattr_t::__opaque"] + [::std::mem::offset_of!(_opaque_pthread_rwlockattr_t, __opaque) - 8usize]; +}; #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone)] pub struct _opaque_pthread_t { pub __sig: ::std::os::raw::c_long, pub __cleanup_stack: *mut __darwin_pthread_handler_rec, pub __opaque: [::std::os::raw::c_char; 8176usize], } -#[test] -fn bindgen_test_layout__opaque_pthread_t() { - assert_eq!( - ::std::mem::size_of::<_opaque_pthread_t>(), - 8192usize, - concat!("Size of: ", stringify!(_opaque_pthread_t)) - ); - assert_eq!( - ::std::mem::align_of::<_opaque_pthread_t>(), - 8usize, - concat!("Alignment of ", stringify!(_opaque_pthread_t)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_opaque_pthread_t>())).__sig as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_t), - "::", - stringify!(__sig) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<_opaque_pthread_t>())).__cleanup_stack as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_t), - "::", - stringify!(__cleanup_stack) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<_opaque_pthread_t>())).__opaque as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_t), - "::", - stringify!(__opaque) - ) - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _opaque_pthread_t"][::std::mem::size_of::<_opaque_pthread_t>() - 8192usize]; + ["Alignment of _opaque_pthread_t"][::std::mem::align_of::<_opaque_pthread_t>() - 8usize]; + ["Offset of field: _opaque_pthread_t::__sig"] + [::std::mem::offset_of!(_opaque_pthread_t, __sig) - 0usize]; + ["Offset of field: _opaque_pthread_t::__cleanup_stack"] + [::std::mem::offset_of!(_opaque_pthread_t, __cleanup_stack) - 8usize]; + ["Offset of field: _opaque_pthread_t::__opaque"] + [::std::mem::offset_of!(_opaque_pthread_t, __opaque) - 16usize]; +}; pub type __darwin_pthread_attr_t = _opaque_pthread_attr_t; pub type __darwin_pthread_cond_t = _opaque_pthread_cond_t; pub type __darwin_pthread_condattr_t = _opaque_pthread_condattr_t; @@ -898,6 +812,8 @@ pub type __darwin_pthread_once_t = _opaque_pthread_once_t; pub type __darwin_pthread_rwlock_t = _opaque_pthread_rwlock_t; pub type __darwin_pthread_rwlockattr_t = _opaque_pthread_rwlockattr_t; pub type __darwin_pthread_t = *mut _opaque_pthread_t; +pub type intmax_t = ::std::os::raw::c_long; +pub type uintmax_t = ::std::os::raw::c_ulong; pub type u_int8_t = ::std::os::raw::c_uchar; pub type u_int16_t = ::std::os::raw::c_ushort; pub type u_int32_t = ::std::os::raw::c_uint; @@ -911,11 +827,6 @@ pub type user_ulong_t = u_int64_t; pub type user_time_t = i64; pub type user_off_t = i64; pub type syscall_arg_t = u_int64_t; -pub type intmax_t = ::std::os::raw::c_long; -pub type uintmax_t = ::std::os::raw::c_ulong; -pub type os_function_t = - ::std::option::Option; -pub type os_block_t = *mut ::std::os::raw::c_void; pub type u_char = ::std::os::raw::c_uchar; pub type u_short = ::std::os::raw::c_ushort; pub type u_int = ::std::os::raw::c_uint; @@ -946,8 +857,6 @@ pub type segsz_t = i32; pub type swblk_t = i32; pub type uid_t = __darwin_uid_t; pub type clock_t = __darwin_clock_t; -pub type size_t = __darwin_size_t; -pub type ssize_t = __darwin_ssize_t; pub type time_t = __darwin_time_t; pub type useconds_t = __darwin_useconds_t; pub type suseconds_t = __darwin_suseconds_t; @@ -958,29 +867,12 @@ pub type errno_t = ::std::os::raw::c_int; pub struct fd_set { pub fds_bits: [__int32_t; 32usize], } -#[test] -fn bindgen_test_layout_fd_set() { - assert_eq!( - ::std::mem::size_of::(), - 128usize, - concat!("Size of: ", stringify!(fd_set)) - ); - assert_eq!( - ::std::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(fd_set)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).fds_bits as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(fd_set), - "::", - stringify!(fds_bits) - ) - ); -} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of fd_set"][::std::mem::size_of::() - 128usize]; + ["Alignment of fd_set"][::std::mem::align_of::() - 4usize]; + ["Offset of field: fd_set::fds_bits"][::std::mem::offset_of!(fd_set, fds_bits) - 0usize]; +}; extern "C" { pub fn __darwin_check_fd_set_overflow( arg1: ::std::os::raw::c_int, @@ -1004,24 +896,21 @@ pub type fsfilcnt_t = __darwin_fsfilcnt_t; pub type kern_return_t = ::std::os::raw::c_int; pub type mach_error_t = kern_return_t; pub type mach_error_fn_t = ::std::option::Option mach_error_t>; -pub const HV_SUCCESS: ::std::os::raw::c_int = 0; -pub const HV_ERROR: ::std::os::raw::c_int = -85377023; -pub const HV_BUSY: ::std::os::raw::c_int = -85377022; -pub const HV_BAD_ARGUMENT: ::std::os::raw::c_int = -85377021; -pub const HV_ILLEGAL_GUEST_STATE: ::std::os::raw::c_int = -85377020; -pub const HV_NO_RESOURCES: ::std::os::raw::c_int = -85377019; -pub const HV_NO_DEVICE: ::std::os::raw::c_int = -85377018; -pub const HV_DENIED: ::std::os::raw::c_int = -85377017; -pub const HV_UNSUPPORTED: ::std::os::raw::c_int = -85377009; +pub const HV_SUCCESS: _bindgen_ty_1 = 0; +pub const HV_ERROR: _bindgen_ty_1 = -85377023; +pub const HV_BUSY: _bindgen_ty_1 = -85377022; +pub const HV_BAD_ARGUMENT: _bindgen_ty_1 = -85377021; +pub const HV_ILLEGAL_GUEST_STATE: _bindgen_ty_1 = -85377020; +pub const HV_NO_RESOURCES: _bindgen_ty_1 = -85377019; +pub const HV_NO_DEVICE: _bindgen_ty_1 = -85377018; +pub const HV_DENIED: _bindgen_ty_1 = -85377017; +pub const HV_UNSUPPORTED: _bindgen_ty_1 = -85377009; pub type _bindgen_ty_1 = ::std::os::raw::c_int; pub type hv_return_t = mach_error_t; -pub const HV_MEMORY_READ: ::std::os::raw::c_uint = 1; -pub const HV_MEMORY_WRITE: ::std::os::raw::c_uint = 2; -pub const HV_MEMORY_EXEC: ::std::os::raw::c_uint = 4; +pub const HV_MEMORY_READ: _bindgen_ty_2 = 1; +pub const HV_MEMORY_WRITE: _bindgen_ty_2 = 2; +pub const HV_MEMORY_EXEC: _bindgen_ty_2 = 4; pub type _bindgen_ty_2 = ::std::os::raw::c_uint; -#[doc = " @enum hv_memory_flags_t"] -#[doc = " @abstract Guest physical memory region permissions for hv_vm_map()"] -#[doc = " and hv_vm_protect()"] pub type hv_memory_flags_t = u64; extern "C" { pub fn os_retain(object: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; @@ -1031,12 +920,3185 @@ extern "C" { } #[repr(C)] #[derive(Debug, Copy, Clone)] +pub struct hv_gic_config_s { + _unused: [u8; 0], +} +pub type hv_gic_config_t = *mut hv_gic_config_s; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct hv_gic_state_s { + _unused: [u8; 0], +} +pub type hv_gic_state_t = *mut hv_gic_state_s; +pub const hv_gic_intid_t_HV_GIC_INT_PERFORMANCE_MONITOR: hv_gic_intid_t = 23; +pub const hv_gic_intid_t_HV_GIC_INT_MAINTENANCE: hv_gic_intid_t = 25; +pub const hv_gic_intid_t_HV_GIC_INT_EL2_PHYSICAL_TIMER: hv_gic_intid_t = 26; +pub const hv_gic_intid_t_HV_GIC_INT_EL1_VIRTUAL_TIMER: hv_gic_intid_t = 27; +pub const hv_gic_intid_t_HV_GIC_INT_EL1_PHYSICAL_TIMER: hv_gic_intid_t = 30; +pub type hv_gic_intid_t = u16; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_CTLR: hv_gic_distributor_reg_t = 0; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_TYPER: hv_gic_distributor_reg_t = 4; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR0: hv_gic_distributor_reg_t = + 128; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR1: hv_gic_distributor_reg_t = + 132; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR2: hv_gic_distributor_reg_t = + 136; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR3: hv_gic_distributor_reg_t = + 140; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR4: hv_gic_distributor_reg_t = + 144; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR5: hv_gic_distributor_reg_t = + 148; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR6: hv_gic_distributor_reg_t = + 152; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR7: hv_gic_distributor_reg_t = + 156; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR8: hv_gic_distributor_reg_t = + 160; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR9: hv_gic_distributor_reg_t = + 164; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR10: hv_gic_distributor_reg_t = + 168; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR11: hv_gic_distributor_reg_t = + 172; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR12: hv_gic_distributor_reg_t = + 176; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR13: hv_gic_distributor_reg_t = + 180; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR14: hv_gic_distributor_reg_t = + 184; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR15: hv_gic_distributor_reg_t = + 188; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR16: hv_gic_distributor_reg_t = + 192; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR17: hv_gic_distributor_reg_t = + 196; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR18: hv_gic_distributor_reg_t = + 200; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR19: hv_gic_distributor_reg_t = + 204; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR20: hv_gic_distributor_reg_t = + 208; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR21: hv_gic_distributor_reg_t = + 212; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR22: hv_gic_distributor_reg_t = + 216; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR23: hv_gic_distributor_reg_t = + 220; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR24: hv_gic_distributor_reg_t = + 224; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR25: hv_gic_distributor_reg_t = + 228; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR26: hv_gic_distributor_reg_t = + 232; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR27: hv_gic_distributor_reg_t = + 236; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR28: hv_gic_distributor_reg_t = + 240; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR29: hv_gic_distributor_reg_t = + 244; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR30: hv_gic_distributor_reg_t = + 248; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IGROUPR31: hv_gic_distributor_reg_t = + 252; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER0: + hv_gic_distributor_reg_t = 256; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER1: + hv_gic_distributor_reg_t = 260; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER2: + hv_gic_distributor_reg_t = 264; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER3: + hv_gic_distributor_reg_t = 268; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER4: + hv_gic_distributor_reg_t = 272; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER5: + hv_gic_distributor_reg_t = 276; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER6: + hv_gic_distributor_reg_t = 280; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER7: + hv_gic_distributor_reg_t = 284; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER8: + hv_gic_distributor_reg_t = 288; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER9: + hv_gic_distributor_reg_t = 292; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER10: + hv_gic_distributor_reg_t = 296; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER11: + hv_gic_distributor_reg_t = 300; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER12: + hv_gic_distributor_reg_t = 304; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER13: + hv_gic_distributor_reg_t = 308; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER14: + hv_gic_distributor_reg_t = 312; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER15: + hv_gic_distributor_reg_t = 316; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER16: + hv_gic_distributor_reg_t = 320; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER17: + hv_gic_distributor_reg_t = 324; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER18: + hv_gic_distributor_reg_t = 328; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER19: + hv_gic_distributor_reg_t = 332; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER20: + hv_gic_distributor_reg_t = 336; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER21: + hv_gic_distributor_reg_t = 340; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER22: + hv_gic_distributor_reg_t = 344; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER23: + hv_gic_distributor_reg_t = 348; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER24: + hv_gic_distributor_reg_t = 352; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER25: + hv_gic_distributor_reg_t = 356; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER26: + hv_gic_distributor_reg_t = 360; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER27: + hv_gic_distributor_reg_t = 364; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER28: + hv_gic_distributor_reg_t = 368; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER29: + hv_gic_distributor_reg_t = 372; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER30: + hv_gic_distributor_reg_t = 376; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISENABLER31: + hv_gic_distributor_reg_t = 380; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER0: + hv_gic_distributor_reg_t = 384; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER1: + hv_gic_distributor_reg_t = 388; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER2: + hv_gic_distributor_reg_t = 392; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER3: + hv_gic_distributor_reg_t = 396; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER4: + hv_gic_distributor_reg_t = 400; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER5: + hv_gic_distributor_reg_t = 404; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER6: + hv_gic_distributor_reg_t = 408; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER7: + hv_gic_distributor_reg_t = 412; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER8: + hv_gic_distributor_reg_t = 416; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER9: + hv_gic_distributor_reg_t = 420; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER10: + hv_gic_distributor_reg_t = 424; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER11: + hv_gic_distributor_reg_t = 428; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER12: + hv_gic_distributor_reg_t = 432; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER13: + hv_gic_distributor_reg_t = 436; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER14: + hv_gic_distributor_reg_t = 440; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER15: + hv_gic_distributor_reg_t = 444; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER16: + hv_gic_distributor_reg_t = 448; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER17: + hv_gic_distributor_reg_t = 452; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER18: + hv_gic_distributor_reg_t = 456; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER19: + hv_gic_distributor_reg_t = 460; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER20: + hv_gic_distributor_reg_t = 464; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER21: + hv_gic_distributor_reg_t = 468; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER22: + hv_gic_distributor_reg_t = 472; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER23: + hv_gic_distributor_reg_t = 476; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER24: + hv_gic_distributor_reg_t = 480; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER25: + hv_gic_distributor_reg_t = 484; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER26: + hv_gic_distributor_reg_t = 488; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER27: + hv_gic_distributor_reg_t = 492; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER28: + hv_gic_distributor_reg_t = 496; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER29: + hv_gic_distributor_reg_t = 500; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER30: + hv_gic_distributor_reg_t = 504; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICENABLER31: + hv_gic_distributor_reg_t = 508; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR0: hv_gic_distributor_reg_t = + 512; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR1: hv_gic_distributor_reg_t = + 516; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR2: hv_gic_distributor_reg_t = + 520; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR3: hv_gic_distributor_reg_t = + 524; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR4: hv_gic_distributor_reg_t = + 528; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR5: hv_gic_distributor_reg_t = + 532; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR6: hv_gic_distributor_reg_t = + 536; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR7: hv_gic_distributor_reg_t = + 540; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR8: hv_gic_distributor_reg_t = + 544; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR9: hv_gic_distributor_reg_t = + 548; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR10: hv_gic_distributor_reg_t = + 552; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR11: hv_gic_distributor_reg_t = + 556; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR12: hv_gic_distributor_reg_t = + 560; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR13: hv_gic_distributor_reg_t = + 564; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR14: hv_gic_distributor_reg_t = + 568; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR15: hv_gic_distributor_reg_t = + 572; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR16: hv_gic_distributor_reg_t = + 576; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR17: hv_gic_distributor_reg_t = + 580; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR18: hv_gic_distributor_reg_t = + 584; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR19: hv_gic_distributor_reg_t = + 588; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR20: hv_gic_distributor_reg_t = + 592; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR21: hv_gic_distributor_reg_t = + 596; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR22: hv_gic_distributor_reg_t = + 600; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR23: hv_gic_distributor_reg_t = + 604; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR24: hv_gic_distributor_reg_t = + 608; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR25: hv_gic_distributor_reg_t = + 612; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR26: hv_gic_distributor_reg_t = + 616; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR27: hv_gic_distributor_reg_t = + 620; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR28: hv_gic_distributor_reg_t = + 624; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR29: hv_gic_distributor_reg_t = + 628; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR30: hv_gic_distributor_reg_t = + 632; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISPENDR31: hv_gic_distributor_reg_t = + 636; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR0: hv_gic_distributor_reg_t = + 640; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR1: hv_gic_distributor_reg_t = + 644; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR2: hv_gic_distributor_reg_t = + 648; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR3: hv_gic_distributor_reg_t = + 652; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR4: hv_gic_distributor_reg_t = + 656; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR5: hv_gic_distributor_reg_t = + 660; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR6: hv_gic_distributor_reg_t = + 664; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR7: hv_gic_distributor_reg_t = + 668; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR8: hv_gic_distributor_reg_t = + 672; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR9: hv_gic_distributor_reg_t = + 676; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR10: hv_gic_distributor_reg_t = + 680; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR11: hv_gic_distributor_reg_t = + 684; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR12: hv_gic_distributor_reg_t = + 688; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR13: hv_gic_distributor_reg_t = + 692; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR14: hv_gic_distributor_reg_t = + 696; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR15: hv_gic_distributor_reg_t = + 700; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR16: hv_gic_distributor_reg_t = + 704; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR17: hv_gic_distributor_reg_t = + 708; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR18: hv_gic_distributor_reg_t = + 712; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR19: hv_gic_distributor_reg_t = + 716; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR20: hv_gic_distributor_reg_t = + 720; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR21: hv_gic_distributor_reg_t = + 724; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR22: hv_gic_distributor_reg_t = + 728; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR23: hv_gic_distributor_reg_t = + 732; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR24: hv_gic_distributor_reg_t = + 736; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR25: hv_gic_distributor_reg_t = + 740; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR26: hv_gic_distributor_reg_t = + 744; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR27: hv_gic_distributor_reg_t = + 748; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR28: hv_gic_distributor_reg_t = + 752; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR29: hv_gic_distributor_reg_t = + 756; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR30: hv_gic_distributor_reg_t = + 760; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICPENDR31: hv_gic_distributor_reg_t = + 764; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER0: + hv_gic_distributor_reg_t = 768; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER1: + hv_gic_distributor_reg_t = 772; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER2: + hv_gic_distributor_reg_t = 776; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER3: + hv_gic_distributor_reg_t = 780; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER4: + hv_gic_distributor_reg_t = 784; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER5: + hv_gic_distributor_reg_t = 788; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER6: + hv_gic_distributor_reg_t = 792; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER7: + hv_gic_distributor_reg_t = 796; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER8: + hv_gic_distributor_reg_t = 800; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER9: + hv_gic_distributor_reg_t = 804; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER10: + hv_gic_distributor_reg_t = 808; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER11: + hv_gic_distributor_reg_t = 812; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER12: + hv_gic_distributor_reg_t = 816; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER13: + hv_gic_distributor_reg_t = 820; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER14: + hv_gic_distributor_reg_t = 824; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER15: + hv_gic_distributor_reg_t = 828; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER16: + hv_gic_distributor_reg_t = 832; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER17: + hv_gic_distributor_reg_t = 836; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER18: + hv_gic_distributor_reg_t = 840; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER19: + hv_gic_distributor_reg_t = 844; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER20: + hv_gic_distributor_reg_t = 848; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER21: + hv_gic_distributor_reg_t = 852; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER22: + hv_gic_distributor_reg_t = 856; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER23: + hv_gic_distributor_reg_t = 860; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER24: + hv_gic_distributor_reg_t = 864; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER25: + hv_gic_distributor_reg_t = 868; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER26: + hv_gic_distributor_reg_t = 872; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER27: + hv_gic_distributor_reg_t = 876; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER28: + hv_gic_distributor_reg_t = 880; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER29: + hv_gic_distributor_reg_t = 884; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER30: + hv_gic_distributor_reg_t = 888; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ISACTIVER31: + hv_gic_distributor_reg_t = 892; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER0: + hv_gic_distributor_reg_t = 896; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER1: + hv_gic_distributor_reg_t = 900; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER2: + hv_gic_distributor_reg_t = 904; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER3: + hv_gic_distributor_reg_t = 908; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER4: + hv_gic_distributor_reg_t = 912; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER5: + hv_gic_distributor_reg_t = 916; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER6: + hv_gic_distributor_reg_t = 920; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER7: + hv_gic_distributor_reg_t = 924; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER8: + hv_gic_distributor_reg_t = 928; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER9: + hv_gic_distributor_reg_t = 932; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER10: + hv_gic_distributor_reg_t = 936; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER11: + hv_gic_distributor_reg_t = 940; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER12: + hv_gic_distributor_reg_t = 944; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER13: + hv_gic_distributor_reg_t = 948; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER14: + hv_gic_distributor_reg_t = 952; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER15: + hv_gic_distributor_reg_t = 956; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER16: + hv_gic_distributor_reg_t = 960; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER17: + hv_gic_distributor_reg_t = 964; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER18: + hv_gic_distributor_reg_t = 968; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER19: + hv_gic_distributor_reg_t = 972; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER20: + hv_gic_distributor_reg_t = 976; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER21: + hv_gic_distributor_reg_t = 980; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER22: + hv_gic_distributor_reg_t = 984; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER23: + hv_gic_distributor_reg_t = 988; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER24: + hv_gic_distributor_reg_t = 992; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER25: + hv_gic_distributor_reg_t = 996; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER26: + hv_gic_distributor_reg_t = 1000; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER27: + hv_gic_distributor_reg_t = 1004; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER28: + hv_gic_distributor_reg_t = 1008; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER29: + hv_gic_distributor_reg_t = 1012; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER30: + hv_gic_distributor_reg_t = 1016; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER31: + hv_gic_distributor_reg_t = 1020; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR0: + hv_gic_distributor_reg_t = 1024; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR1: + hv_gic_distributor_reg_t = 1028; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR2: + hv_gic_distributor_reg_t = 1032; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR3: + hv_gic_distributor_reg_t = 1036; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR4: + hv_gic_distributor_reg_t = 1040; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR5: + hv_gic_distributor_reg_t = 1044; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR6: + hv_gic_distributor_reg_t = 1048; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR7: + hv_gic_distributor_reg_t = 1052; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR8: + hv_gic_distributor_reg_t = 1056; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR9: + hv_gic_distributor_reg_t = 1060; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR10: + hv_gic_distributor_reg_t = 1064; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR11: + hv_gic_distributor_reg_t = 1068; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR12: + hv_gic_distributor_reg_t = 1072; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR13: + hv_gic_distributor_reg_t = 1076; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR14: + hv_gic_distributor_reg_t = 1080; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR15: + hv_gic_distributor_reg_t = 1084; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR16: + hv_gic_distributor_reg_t = 1088; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR17: + hv_gic_distributor_reg_t = 1092; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR18: + hv_gic_distributor_reg_t = 1096; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR19: + hv_gic_distributor_reg_t = 1100; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR20: + hv_gic_distributor_reg_t = 1104; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR21: + hv_gic_distributor_reg_t = 1108; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR22: + hv_gic_distributor_reg_t = 1112; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR23: + hv_gic_distributor_reg_t = 1116; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR24: + hv_gic_distributor_reg_t = 1120; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR25: + hv_gic_distributor_reg_t = 1124; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR26: + hv_gic_distributor_reg_t = 1128; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR27: + hv_gic_distributor_reg_t = 1132; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR28: + hv_gic_distributor_reg_t = 1136; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR29: + hv_gic_distributor_reg_t = 1140; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR30: + hv_gic_distributor_reg_t = 1144; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR31: + hv_gic_distributor_reg_t = 1148; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR32: + hv_gic_distributor_reg_t = 1152; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR33: + hv_gic_distributor_reg_t = 1156; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR34: + hv_gic_distributor_reg_t = 1160; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR35: + hv_gic_distributor_reg_t = 1164; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR36: + hv_gic_distributor_reg_t = 1168; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR37: + hv_gic_distributor_reg_t = 1172; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR38: + hv_gic_distributor_reg_t = 1176; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR39: + hv_gic_distributor_reg_t = 1180; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR40: + hv_gic_distributor_reg_t = 1184; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR41: + hv_gic_distributor_reg_t = 1188; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR42: + hv_gic_distributor_reg_t = 1192; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR43: + hv_gic_distributor_reg_t = 1196; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR44: + hv_gic_distributor_reg_t = 1200; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR45: + hv_gic_distributor_reg_t = 1204; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR46: + hv_gic_distributor_reg_t = 1208; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR47: + hv_gic_distributor_reg_t = 1212; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR48: + hv_gic_distributor_reg_t = 1216; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR49: + hv_gic_distributor_reg_t = 1220; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR50: + hv_gic_distributor_reg_t = 1224; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR51: + hv_gic_distributor_reg_t = 1228; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR52: + hv_gic_distributor_reg_t = 1232; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR53: + hv_gic_distributor_reg_t = 1236; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR54: + hv_gic_distributor_reg_t = 1240; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR55: + hv_gic_distributor_reg_t = 1244; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR56: + hv_gic_distributor_reg_t = 1248; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR57: + hv_gic_distributor_reg_t = 1252; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR58: + hv_gic_distributor_reg_t = 1256; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR59: + hv_gic_distributor_reg_t = 1260; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR60: + hv_gic_distributor_reg_t = 1264; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR61: + hv_gic_distributor_reg_t = 1268; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR62: + hv_gic_distributor_reg_t = 1272; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR63: + hv_gic_distributor_reg_t = 1276; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR64: + hv_gic_distributor_reg_t = 1280; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR65: + hv_gic_distributor_reg_t = 1284; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR66: + hv_gic_distributor_reg_t = 1288; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR67: + hv_gic_distributor_reg_t = 1292; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR68: + hv_gic_distributor_reg_t = 1296; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR69: + hv_gic_distributor_reg_t = 1300; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR70: + hv_gic_distributor_reg_t = 1304; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR71: + hv_gic_distributor_reg_t = 1308; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR72: + hv_gic_distributor_reg_t = 1312; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR73: + hv_gic_distributor_reg_t = 1316; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR74: + hv_gic_distributor_reg_t = 1320; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR75: + hv_gic_distributor_reg_t = 1324; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR76: + hv_gic_distributor_reg_t = 1328; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR77: + hv_gic_distributor_reg_t = 1332; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR78: + hv_gic_distributor_reg_t = 1336; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR79: + hv_gic_distributor_reg_t = 1340; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR80: + hv_gic_distributor_reg_t = 1344; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR81: + hv_gic_distributor_reg_t = 1348; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR82: + hv_gic_distributor_reg_t = 1352; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR83: + hv_gic_distributor_reg_t = 1356; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR84: + hv_gic_distributor_reg_t = 1360; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR85: + hv_gic_distributor_reg_t = 1364; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR86: + hv_gic_distributor_reg_t = 1368; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR87: + hv_gic_distributor_reg_t = 1372; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR88: + hv_gic_distributor_reg_t = 1376; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR89: + hv_gic_distributor_reg_t = 1380; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR90: + hv_gic_distributor_reg_t = 1384; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR91: + hv_gic_distributor_reg_t = 1388; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR92: + hv_gic_distributor_reg_t = 1392; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR93: + hv_gic_distributor_reg_t = 1396; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR94: + hv_gic_distributor_reg_t = 1400; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR95: + hv_gic_distributor_reg_t = 1404; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR96: + hv_gic_distributor_reg_t = 1408; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR97: + hv_gic_distributor_reg_t = 1412; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR98: + hv_gic_distributor_reg_t = 1416; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR99: + hv_gic_distributor_reg_t = 1420; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR100: + hv_gic_distributor_reg_t = 1424; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR101: + hv_gic_distributor_reg_t = 1428; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR102: + hv_gic_distributor_reg_t = 1432; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR103: + hv_gic_distributor_reg_t = 1436; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR104: + hv_gic_distributor_reg_t = 1440; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR105: + hv_gic_distributor_reg_t = 1444; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR106: + hv_gic_distributor_reg_t = 1448; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR107: + hv_gic_distributor_reg_t = 1452; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR108: + hv_gic_distributor_reg_t = 1456; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR109: + hv_gic_distributor_reg_t = 1460; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR110: + hv_gic_distributor_reg_t = 1464; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR111: + hv_gic_distributor_reg_t = 1468; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR112: + hv_gic_distributor_reg_t = 1472; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR113: + hv_gic_distributor_reg_t = 1476; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR114: + hv_gic_distributor_reg_t = 1480; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR115: + hv_gic_distributor_reg_t = 1484; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR116: + hv_gic_distributor_reg_t = 1488; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR117: + hv_gic_distributor_reg_t = 1492; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR118: + hv_gic_distributor_reg_t = 1496; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR119: + hv_gic_distributor_reg_t = 1500; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR120: + hv_gic_distributor_reg_t = 1504; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR121: + hv_gic_distributor_reg_t = 1508; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR122: + hv_gic_distributor_reg_t = 1512; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR123: + hv_gic_distributor_reg_t = 1516; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR124: + hv_gic_distributor_reg_t = 1520; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR125: + hv_gic_distributor_reg_t = 1524; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR126: + hv_gic_distributor_reg_t = 1528; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR127: + hv_gic_distributor_reg_t = 1532; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR128: + hv_gic_distributor_reg_t = 1536; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR129: + hv_gic_distributor_reg_t = 1540; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR130: + hv_gic_distributor_reg_t = 1544; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR131: + hv_gic_distributor_reg_t = 1548; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR132: + hv_gic_distributor_reg_t = 1552; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR133: + hv_gic_distributor_reg_t = 1556; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR134: + hv_gic_distributor_reg_t = 1560; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR135: + hv_gic_distributor_reg_t = 1564; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR136: + hv_gic_distributor_reg_t = 1568; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR137: + hv_gic_distributor_reg_t = 1572; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR138: + hv_gic_distributor_reg_t = 1576; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR139: + hv_gic_distributor_reg_t = 1580; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR140: + hv_gic_distributor_reg_t = 1584; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR141: + hv_gic_distributor_reg_t = 1588; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR142: + hv_gic_distributor_reg_t = 1592; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR143: + hv_gic_distributor_reg_t = 1596; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR144: + hv_gic_distributor_reg_t = 1600; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR145: + hv_gic_distributor_reg_t = 1604; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR146: + hv_gic_distributor_reg_t = 1608; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR147: + hv_gic_distributor_reg_t = 1612; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR148: + hv_gic_distributor_reg_t = 1616; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR149: + hv_gic_distributor_reg_t = 1620; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR150: + hv_gic_distributor_reg_t = 1624; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR151: + hv_gic_distributor_reg_t = 1628; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR152: + hv_gic_distributor_reg_t = 1632; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR153: + hv_gic_distributor_reg_t = 1636; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR154: + hv_gic_distributor_reg_t = 1640; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR155: + hv_gic_distributor_reg_t = 1644; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR156: + hv_gic_distributor_reg_t = 1648; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR157: + hv_gic_distributor_reg_t = 1652; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR158: + hv_gic_distributor_reg_t = 1656; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR159: + hv_gic_distributor_reg_t = 1660; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR160: + hv_gic_distributor_reg_t = 1664; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR161: + hv_gic_distributor_reg_t = 1668; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR162: + hv_gic_distributor_reg_t = 1672; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR163: + hv_gic_distributor_reg_t = 1676; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR164: + hv_gic_distributor_reg_t = 1680; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR165: + hv_gic_distributor_reg_t = 1684; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR166: + hv_gic_distributor_reg_t = 1688; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR167: + hv_gic_distributor_reg_t = 1692; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR168: + hv_gic_distributor_reg_t = 1696; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR169: + hv_gic_distributor_reg_t = 1700; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR170: + hv_gic_distributor_reg_t = 1704; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR171: + hv_gic_distributor_reg_t = 1708; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR172: + hv_gic_distributor_reg_t = 1712; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR173: + hv_gic_distributor_reg_t = 1716; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR174: + hv_gic_distributor_reg_t = 1720; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR175: + hv_gic_distributor_reg_t = 1724; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR176: + hv_gic_distributor_reg_t = 1728; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR177: + hv_gic_distributor_reg_t = 1732; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR178: + hv_gic_distributor_reg_t = 1736; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR179: + hv_gic_distributor_reg_t = 1740; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR180: + hv_gic_distributor_reg_t = 1744; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR181: + hv_gic_distributor_reg_t = 1748; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR182: + hv_gic_distributor_reg_t = 1752; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR183: + hv_gic_distributor_reg_t = 1756; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR184: + hv_gic_distributor_reg_t = 1760; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR185: + hv_gic_distributor_reg_t = 1764; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR186: + hv_gic_distributor_reg_t = 1768; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR187: + hv_gic_distributor_reg_t = 1772; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR188: + hv_gic_distributor_reg_t = 1776; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR189: + hv_gic_distributor_reg_t = 1780; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR190: + hv_gic_distributor_reg_t = 1784; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR191: + hv_gic_distributor_reg_t = 1788; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR192: + hv_gic_distributor_reg_t = 1792; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR193: + hv_gic_distributor_reg_t = 1796; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR194: + hv_gic_distributor_reg_t = 1800; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR195: + hv_gic_distributor_reg_t = 1804; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR196: + hv_gic_distributor_reg_t = 1808; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR197: + hv_gic_distributor_reg_t = 1812; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR198: + hv_gic_distributor_reg_t = 1816; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR199: + hv_gic_distributor_reg_t = 1820; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR200: + hv_gic_distributor_reg_t = 1824; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR201: + hv_gic_distributor_reg_t = 1828; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR202: + hv_gic_distributor_reg_t = 1832; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR203: + hv_gic_distributor_reg_t = 1836; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR204: + hv_gic_distributor_reg_t = 1840; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR205: + hv_gic_distributor_reg_t = 1844; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR206: + hv_gic_distributor_reg_t = 1848; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR207: + hv_gic_distributor_reg_t = 1852; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR208: + hv_gic_distributor_reg_t = 1856; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR209: + hv_gic_distributor_reg_t = 1860; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR210: + hv_gic_distributor_reg_t = 1864; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR211: + hv_gic_distributor_reg_t = 1868; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR212: + hv_gic_distributor_reg_t = 1872; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR213: + hv_gic_distributor_reg_t = 1876; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR214: + hv_gic_distributor_reg_t = 1880; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR215: + hv_gic_distributor_reg_t = 1884; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR216: + hv_gic_distributor_reg_t = 1888; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR217: + hv_gic_distributor_reg_t = 1892; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR218: + hv_gic_distributor_reg_t = 1896; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR219: + hv_gic_distributor_reg_t = 1900; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR220: + hv_gic_distributor_reg_t = 1904; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR221: + hv_gic_distributor_reg_t = 1908; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR222: + hv_gic_distributor_reg_t = 1912; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR223: + hv_gic_distributor_reg_t = 1916; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR224: + hv_gic_distributor_reg_t = 1920; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR225: + hv_gic_distributor_reg_t = 1924; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR226: + hv_gic_distributor_reg_t = 1928; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR227: + hv_gic_distributor_reg_t = 1932; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR228: + hv_gic_distributor_reg_t = 1936; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR229: + hv_gic_distributor_reg_t = 1940; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR230: + hv_gic_distributor_reg_t = 1944; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR231: + hv_gic_distributor_reg_t = 1948; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR232: + hv_gic_distributor_reg_t = 1952; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR233: + hv_gic_distributor_reg_t = 1956; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR234: + hv_gic_distributor_reg_t = 1960; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR235: + hv_gic_distributor_reg_t = 1964; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR236: + hv_gic_distributor_reg_t = 1968; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR237: + hv_gic_distributor_reg_t = 1972; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR238: + hv_gic_distributor_reg_t = 1976; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR239: + hv_gic_distributor_reg_t = 1980; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR240: + hv_gic_distributor_reg_t = 1984; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR241: + hv_gic_distributor_reg_t = 1988; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR242: + hv_gic_distributor_reg_t = 1992; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR243: + hv_gic_distributor_reg_t = 1996; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR244: + hv_gic_distributor_reg_t = 2000; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR245: + hv_gic_distributor_reg_t = 2004; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR246: + hv_gic_distributor_reg_t = 2008; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR247: + hv_gic_distributor_reg_t = 2012; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR248: + hv_gic_distributor_reg_t = 2016; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR249: + hv_gic_distributor_reg_t = 2020; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR250: + hv_gic_distributor_reg_t = 2024; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR251: + hv_gic_distributor_reg_t = 2028; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR252: + hv_gic_distributor_reg_t = 2032; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR253: + hv_gic_distributor_reg_t = 2036; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IPRIORITYR254: + hv_gic_distributor_reg_t = 2040; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR0: hv_gic_distributor_reg_t = + 3072; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR1: hv_gic_distributor_reg_t = + 3076; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR2: hv_gic_distributor_reg_t = + 3080; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR3: hv_gic_distributor_reg_t = + 3084; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR4: hv_gic_distributor_reg_t = + 3088; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR5: hv_gic_distributor_reg_t = + 3092; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR6: hv_gic_distributor_reg_t = + 3096; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR7: hv_gic_distributor_reg_t = + 3100; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR8: hv_gic_distributor_reg_t = + 3104; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR9: hv_gic_distributor_reg_t = + 3108; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR10: hv_gic_distributor_reg_t = + 3112; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR11: hv_gic_distributor_reg_t = + 3116; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR12: hv_gic_distributor_reg_t = + 3120; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR13: hv_gic_distributor_reg_t = + 3124; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR14: hv_gic_distributor_reg_t = + 3128; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR15: hv_gic_distributor_reg_t = + 3132; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR16: hv_gic_distributor_reg_t = + 3136; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR17: hv_gic_distributor_reg_t = + 3140; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR18: hv_gic_distributor_reg_t = + 3144; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR19: hv_gic_distributor_reg_t = + 3148; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR20: hv_gic_distributor_reg_t = + 3152; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR21: hv_gic_distributor_reg_t = + 3156; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR22: hv_gic_distributor_reg_t = + 3160; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR23: hv_gic_distributor_reg_t = + 3164; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR24: hv_gic_distributor_reg_t = + 3168; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR25: hv_gic_distributor_reg_t = + 3172; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR26: hv_gic_distributor_reg_t = + 3176; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR27: hv_gic_distributor_reg_t = + 3180; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR28: hv_gic_distributor_reg_t = + 3184; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR29: hv_gic_distributor_reg_t = + 3188; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR30: hv_gic_distributor_reg_t = + 3192; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR31: hv_gic_distributor_reg_t = + 3196; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR32: hv_gic_distributor_reg_t = + 3200; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR33: hv_gic_distributor_reg_t = + 3204; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR34: hv_gic_distributor_reg_t = + 3208; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR35: hv_gic_distributor_reg_t = + 3212; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR36: hv_gic_distributor_reg_t = + 3216; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR37: hv_gic_distributor_reg_t = + 3220; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR38: hv_gic_distributor_reg_t = + 3224; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR39: hv_gic_distributor_reg_t = + 3228; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR40: hv_gic_distributor_reg_t = + 3232; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR41: hv_gic_distributor_reg_t = + 3236; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR42: hv_gic_distributor_reg_t = + 3240; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR43: hv_gic_distributor_reg_t = + 3244; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR44: hv_gic_distributor_reg_t = + 3248; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR45: hv_gic_distributor_reg_t = + 3252; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR46: hv_gic_distributor_reg_t = + 3256; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR47: hv_gic_distributor_reg_t = + 3260; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR48: hv_gic_distributor_reg_t = + 3264; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR49: hv_gic_distributor_reg_t = + 3268; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR50: hv_gic_distributor_reg_t = + 3272; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR51: hv_gic_distributor_reg_t = + 3276; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR52: hv_gic_distributor_reg_t = + 3280; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR53: hv_gic_distributor_reg_t = + 3284; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR54: hv_gic_distributor_reg_t = + 3288; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR55: hv_gic_distributor_reg_t = + 3292; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR56: hv_gic_distributor_reg_t = + 3296; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR57: hv_gic_distributor_reg_t = + 3300; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR58: hv_gic_distributor_reg_t = + 3304; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR59: hv_gic_distributor_reg_t = + 3308; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR60: hv_gic_distributor_reg_t = + 3312; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR61: hv_gic_distributor_reg_t = + 3316; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR62: hv_gic_distributor_reg_t = + 3320; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_ICFGR63: hv_gic_distributor_reg_t = + 3324; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER32: hv_gic_distributor_reg_t = + 24832; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER33: hv_gic_distributor_reg_t = + 24840; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER34: hv_gic_distributor_reg_t = + 24848; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER35: hv_gic_distributor_reg_t = + 24856; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER36: hv_gic_distributor_reg_t = + 24864; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER37: hv_gic_distributor_reg_t = + 24872; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER38: hv_gic_distributor_reg_t = + 24880; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER39: hv_gic_distributor_reg_t = + 24888; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER40: hv_gic_distributor_reg_t = + 24896; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER41: hv_gic_distributor_reg_t = + 24904; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER42: hv_gic_distributor_reg_t = + 24912; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER43: hv_gic_distributor_reg_t = + 24920; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER44: hv_gic_distributor_reg_t = + 24928; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER45: hv_gic_distributor_reg_t = + 24936; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER46: hv_gic_distributor_reg_t = + 24944; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER47: hv_gic_distributor_reg_t = + 24952; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER48: hv_gic_distributor_reg_t = + 24960; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER49: hv_gic_distributor_reg_t = + 24968; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER50: hv_gic_distributor_reg_t = + 24976; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER51: hv_gic_distributor_reg_t = + 24984; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER52: hv_gic_distributor_reg_t = + 24992; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER53: hv_gic_distributor_reg_t = + 25000; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER54: hv_gic_distributor_reg_t = + 25008; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER55: hv_gic_distributor_reg_t = + 25016; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER56: hv_gic_distributor_reg_t = + 25024; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER57: hv_gic_distributor_reg_t = + 25032; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER58: hv_gic_distributor_reg_t = + 25040; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER59: hv_gic_distributor_reg_t = + 25048; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER60: hv_gic_distributor_reg_t = + 25056; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER61: hv_gic_distributor_reg_t = + 25064; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER62: hv_gic_distributor_reg_t = + 25072; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER63: hv_gic_distributor_reg_t = + 25080; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER64: hv_gic_distributor_reg_t = + 25088; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER65: hv_gic_distributor_reg_t = + 25096; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER66: hv_gic_distributor_reg_t = + 25104; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER67: hv_gic_distributor_reg_t = + 25112; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER68: hv_gic_distributor_reg_t = + 25120; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER69: hv_gic_distributor_reg_t = + 25128; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER70: hv_gic_distributor_reg_t = + 25136; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER71: hv_gic_distributor_reg_t = + 25144; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER72: hv_gic_distributor_reg_t = + 25152; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER73: hv_gic_distributor_reg_t = + 25160; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER74: hv_gic_distributor_reg_t = + 25168; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER75: hv_gic_distributor_reg_t = + 25176; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER76: hv_gic_distributor_reg_t = + 25184; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER77: hv_gic_distributor_reg_t = + 25192; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER78: hv_gic_distributor_reg_t = + 25200; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER79: hv_gic_distributor_reg_t = + 25208; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER80: hv_gic_distributor_reg_t = + 25216; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER81: hv_gic_distributor_reg_t = + 25224; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER82: hv_gic_distributor_reg_t = + 25232; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER83: hv_gic_distributor_reg_t = + 25240; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER84: hv_gic_distributor_reg_t = + 25248; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER85: hv_gic_distributor_reg_t = + 25256; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER86: hv_gic_distributor_reg_t = + 25264; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER87: hv_gic_distributor_reg_t = + 25272; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER88: hv_gic_distributor_reg_t = + 25280; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER89: hv_gic_distributor_reg_t = + 25288; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER90: hv_gic_distributor_reg_t = + 25296; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER91: hv_gic_distributor_reg_t = + 25304; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER92: hv_gic_distributor_reg_t = + 25312; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER93: hv_gic_distributor_reg_t = + 25320; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER94: hv_gic_distributor_reg_t = + 25328; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER95: hv_gic_distributor_reg_t = + 25336; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER96: hv_gic_distributor_reg_t = + 25344; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER97: hv_gic_distributor_reg_t = + 25352; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER98: hv_gic_distributor_reg_t = + 25360; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER99: hv_gic_distributor_reg_t = + 25368; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER100: + hv_gic_distributor_reg_t = 25376; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER101: + hv_gic_distributor_reg_t = 25384; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER102: + hv_gic_distributor_reg_t = 25392; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER103: + hv_gic_distributor_reg_t = 25400; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER104: + hv_gic_distributor_reg_t = 25408; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER105: + hv_gic_distributor_reg_t = 25416; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER106: + hv_gic_distributor_reg_t = 25424; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER107: + hv_gic_distributor_reg_t = 25432; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER108: + hv_gic_distributor_reg_t = 25440; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER109: + hv_gic_distributor_reg_t = 25448; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER110: + hv_gic_distributor_reg_t = 25456; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER111: + hv_gic_distributor_reg_t = 25464; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER112: + hv_gic_distributor_reg_t = 25472; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER113: + hv_gic_distributor_reg_t = 25480; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER114: + hv_gic_distributor_reg_t = 25488; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER115: + hv_gic_distributor_reg_t = 25496; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER116: + hv_gic_distributor_reg_t = 25504; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER117: + hv_gic_distributor_reg_t = 25512; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER118: + hv_gic_distributor_reg_t = 25520; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER119: + hv_gic_distributor_reg_t = 25528; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER120: + hv_gic_distributor_reg_t = 25536; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER121: + hv_gic_distributor_reg_t = 25544; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER122: + hv_gic_distributor_reg_t = 25552; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER123: + hv_gic_distributor_reg_t = 25560; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER124: + hv_gic_distributor_reg_t = 25568; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER125: + hv_gic_distributor_reg_t = 25576; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER126: + hv_gic_distributor_reg_t = 25584; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER127: + hv_gic_distributor_reg_t = 25592; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER128: + hv_gic_distributor_reg_t = 25600; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER129: + hv_gic_distributor_reg_t = 25608; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER130: + hv_gic_distributor_reg_t = 25616; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER131: + hv_gic_distributor_reg_t = 25624; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER132: + hv_gic_distributor_reg_t = 25632; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER133: + hv_gic_distributor_reg_t = 25640; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER134: + hv_gic_distributor_reg_t = 25648; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER135: + hv_gic_distributor_reg_t = 25656; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER136: + hv_gic_distributor_reg_t = 25664; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER137: + hv_gic_distributor_reg_t = 25672; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER138: + hv_gic_distributor_reg_t = 25680; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER139: + hv_gic_distributor_reg_t = 25688; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER140: + hv_gic_distributor_reg_t = 25696; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER141: + hv_gic_distributor_reg_t = 25704; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER142: + hv_gic_distributor_reg_t = 25712; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER143: + hv_gic_distributor_reg_t = 25720; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER144: + hv_gic_distributor_reg_t = 25728; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER145: + hv_gic_distributor_reg_t = 25736; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER146: + hv_gic_distributor_reg_t = 25744; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER147: + hv_gic_distributor_reg_t = 25752; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER148: + hv_gic_distributor_reg_t = 25760; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER149: + hv_gic_distributor_reg_t = 25768; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER150: + hv_gic_distributor_reg_t = 25776; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER151: + hv_gic_distributor_reg_t = 25784; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER152: + hv_gic_distributor_reg_t = 25792; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER153: + hv_gic_distributor_reg_t = 25800; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER154: + hv_gic_distributor_reg_t = 25808; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER155: + hv_gic_distributor_reg_t = 25816; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER156: + hv_gic_distributor_reg_t = 25824; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER157: + hv_gic_distributor_reg_t = 25832; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER158: + hv_gic_distributor_reg_t = 25840; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER159: + hv_gic_distributor_reg_t = 25848; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER160: + hv_gic_distributor_reg_t = 25856; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER161: + hv_gic_distributor_reg_t = 25864; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER162: + hv_gic_distributor_reg_t = 25872; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER163: + hv_gic_distributor_reg_t = 25880; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER164: + hv_gic_distributor_reg_t = 25888; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER165: + hv_gic_distributor_reg_t = 25896; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER166: + hv_gic_distributor_reg_t = 25904; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER167: + hv_gic_distributor_reg_t = 25912; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER168: + hv_gic_distributor_reg_t = 25920; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER169: + hv_gic_distributor_reg_t = 25928; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER170: + hv_gic_distributor_reg_t = 25936; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER171: + hv_gic_distributor_reg_t = 25944; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER172: + hv_gic_distributor_reg_t = 25952; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER173: + hv_gic_distributor_reg_t = 25960; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER174: + hv_gic_distributor_reg_t = 25968; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER175: + hv_gic_distributor_reg_t = 25976; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER176: + hv_gic_distributor_reg_t = 25984; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER177: + hv_gic_distributor_reg_t = 25992; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER178: + hv_gic_distributor_reg_t = 26000; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER179: + hv_gic_distributor_reg_t = 26008; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER180: + hv_gic_distributor_reg_t = 26016; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER181: + hv_gic_distributor_reg_t = 26024; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER182: + hv_gic_distributor_reg_t = 26032; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER183: + hv_gic_distributor_reg_t = 26040; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER184: + hv_gic_distributor_reg_t = 26048; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER185: + hv_gic_distributor_reg_t = 26056; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER186: + hv_gic_distributor_reg_t = 26064; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER187: + hv_gic_distributor_reg_t = 26072; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER188: + hv_gic_distributor_reg_t = 26080; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER189: + hv_gic_distributor_reg_t = 26088; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER190: + hv_gic_distributor_reg_t = 26096; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER191: + hv_gic_distributor_reg_t = 26104; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER192: + hv_gic_distributor_reg_t = 26112; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER193: + hv_gic_distributor_reg_t = 26120; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER194: + hv_gic_distributor_reg_t = 26128; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER195: + hv_gic_distributor_reg_t = 26136; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER196: + hv_gic_distributor_reg_t = 26144; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER197: + hv_gic_distributor_reg_t = 26152; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER198: + hv_gic_distributor_reg_t = 26160; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER199: + hv_gic_distributor_reg_t = 26168; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER200: + hv_gic_distributor_reg_t = 26176; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER201: + hv_gic_distributor_reg_t = 26184; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER202: + hv_gic_distributor_reg_t = 26192; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER203: + hv_gic_distributor_reg_t = 26200; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER204: + hv_gic_distributor_reg_t = 26208; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER205: + hv_gic_distributor_reg_t = 26216; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER206: + hv_gic_distributor_reg_t = 26224; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER207: + hv_gic_distributor_reg_t = 26232; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER208: + hv_gic_distributor_reg_t = 26240; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER209: + hv_gic_distributor_reg_t = 26248; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER210: + hv_gic_distributor_reg_t = 26256; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER211: + hv_gic_distributor_reg_t = 26264; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER212: + hv_gic_distributor_reg_t = 26272; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER213: + hv_gic_distributor_reg_t = 26280; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER214: + hv_gic_distributor_reg_t = 26288; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER215: + hv_gic_distributor_reg_t = 26296; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER216: + hv_gic_distributor_reg_t = 26304; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER217: + hv_gic_distributor_reg_t = 26312; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER218: + hv_gic_distributor_reg_t = 26320; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER219: + hv_gic_distributor_reg_t = 26328; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER220: + hv_gic_distributor_reg_t = 26336; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER221: + hv_gic_distributor_reg_t = 26344; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER222: + hv_gic_distributor_reg_t = 26352; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER223: + hv_gic_distributor_reg_t = 26360; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER224: + hv_gic_distributor_reg_t = 26368; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER225: + hv_gic_distributor_reg_t = 26376; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER226: + hv_gic_distributor_reg_t = 26384; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER227: + hv_gic_distributor_reg_t = 26392; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER228: + hv_gic_distributor_reg_t = 26400; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER229: + hv_gic_distributor_reg_t = 26408; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER230: + hv_gic_distributor_reg_t = 26416; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER231: + hv_gic_distributor_reg_t = 26424; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER232: + hv_gic_distributor_reg_t = 26432; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER233: + hv_gic_distributor_reg_t = 26440; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER234: + hv_gic_distributor_reg_t = 26448; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER235: + hv_gic_distributor_reg_t = 26456; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER236: + hv_gic_distributor_reg_t = 26464; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER237: + hv_gic_distributor_reg_t = 26472; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER238: + hv_gic_distributor_reg_t = 26480; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER239: + hv_gic_distributor_reg_t = 26488; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER240: + hv_gic_distributor_reg_t = 26496; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER241: + hv_gic_distributor_reg_t = 26504; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER242: + hv_gic_distributor_reg_t = 26512; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER243: + hv_gic_distributor_reg_t = 26520; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER244: + hv_gic_distributor_reg_t = 26528; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER245: + hv_gic_distributor_reg_t = 26536; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER246: + hv_gic_distributor_reg_t = 26544; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER247: + hv_gic_distributor_reg_t = 26552; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER248: + hv_gic_distributor_reg_t = 26560; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER249: + hv_gic_distributor_reg_t = 26568; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER250: + hv_gic_distributor_reg_t = 26576; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER251: + hv_gic_distributor_reg_t = 26584; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER252: + hv_gic_distributor_reg_t = 26592; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER253: + hv_gic_distributor_reg_t = 26600; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER254: + hv_gic_distributor_reg_t = 26608; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER255: + hv_gic_distributor_reg_t = 26616; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER256: + hv_gic_distributor_reg_t = 26624; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER257: + hv_gic_distributor_reg_t = 26632; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER258: + hv_gic_distributor_reg_t = 26640; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER259: + hv_gic_distributor_reg_t = 26648; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER260: + hv_gic_distributor_reg_t = 26656; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER261: + hv_gic_distributor_reg_t = 26664; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER262: + hv_gic_distributor_reg_t = 26672; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER263: + hv_gic_distributor_reg_t = 26680; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER264: + hv_gic_distributor_reg_t = 26688; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER265: + hv_gic_distributor_reg_t = 26696; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER266: + hv_gic_distributor_reg_t = 26704; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER267: + hv_gic_distributor_reg_t = 26712; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER268: + hv_gic_distributor_reg_t = 26720; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER269: + hv_gic_distributor_reg_t = 26728; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER270: + hv_gic_distributor_reg_t = 26736; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER271: + hv_gic_distributor_reg_t = 26744; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER272: + hv_gic_distributor_reg_t = 26752; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER273: + hv_gic_distributor_reg_t = 26760; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER274: + hv_gic_distributor_reg_t = 26768; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER275: + hv_gic_distributor_reg_t = 26776; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER276: + hv_gic_distributor_reg_t = 26784; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER277: + hv_gic_distributor_reg_t = 26792; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER278: + hv_gic_distributor_reg_t = 26800; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER279: + hv_gic_distributor_reg_t = 26808; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER280: + hv_gic_distributor_reg_t = 26816; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER281: + hv_gic_distributor_reg_t = 26824; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER282: + hv_gic_distributor_reg_t = 26832; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER283: + hv_gic_distributor_reg_t = 26840; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER284: + hv_gic_distributor_reg_t = 26848; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER285: + hv_gic_distributor_reg_t = 26856; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER286: + hv_gic_distributor_reg_t = 26864; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER287: + hv_gic_distributor_reg_t = 26872; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER288: + hv_gic_distributor_reg_t = 26880; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER289: + hv_gic_distributor_reg_t = 26888; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER290: + hv_gic_distributor_reg_t = 26896; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER291: + hv_gic_distributor_reg_t = 26904; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER292: + hv_gic_distributor_reg_t = 26912; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER293: + hv_gic_distributor_reg_t = 26920; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER294: + hv_gic_distributor_reg_t = 26928; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER295: + hv_gic_distributor_reg_t = 26936; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER296: + hv_gic_distributor_reg_t = 26944; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER297: + hv_gic_distributor_reg_t = 26952; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER298: + hv_gic_distributor_reg_t = 26960; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER299: + hv_gic_distributor_reg_t = 26968; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER300: + hv_gic_distributor_reg_t = 26976; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER301: + hv_gic_distributor_reg_t = 26984; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER302: + hv_gic_distributor_reg_t = 26992; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER303: + hv_gic_distributor_reg_t = 27000; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER304: + hv_gic_distributor_reg_t = 27008; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER305: + hv_gic_distributor_reg_t = 27016; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER306: + hv_gic_distributor_reg_t = 27024; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER307: + hv_gic_distributor_reg_t = 27032; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER308: + hv_gic_distributor_reg_t = 27040; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER309: + hv_gic_distributor_reg_t = 27048; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER310: + hv_gic_distributor_reg_t = 27056; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER311: + hv_gic_distributor_reg_t = 27064; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER312: + hv_gic_distributor_reg_t = 27072; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER313: + hv_gic_distributor_reg_t = 27080; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER314: + hv_gic_distributor_reg_t = 27088; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER315: + hv_gic_distributor_reg_t = 27096; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER316: + hv_gic_distributor_reg_t = 27104; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER317: + hv_gic_distributor_reg_t = 27112; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER318: + hv_gic_distributor_reg_t = 27120; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER319: + hv_gic_distributor_reg_t = 27128; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER320: + hv_gic_distributor_reg_t = 27136; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER321: + hv_gic_distributor_reg_t = 27144; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER322: + hv_gic_distributor_reg_t = 27152; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER323: + hv_gic_distributor_reg_t = 27160; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER324: + hv_gic_distributor_reg_t = 27168; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER325: + hv_gic_distributor_reg_t = 27176; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER326: + hv_gic_distributor_reg_t = 27184; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER327: + hv_gic_distributor_reg_t = 27192; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER328: + hv_gic_distributor_reg_t = 27200; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER329: + hv_gic_distributor_reg_t = 27208; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER330: + hv_gic_distributor_reg_t = 27216; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER331: + hv_gic_distributor_reg_t = 27224; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER332: + hv_gic_distributor_reg_t = 27232; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER333: + hv_gic_distributor_reg_t = 27240; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER334: + hv_gic_distributor_reg_t = 27248; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER335: + hv_gic_distributor_reg_t = 27256; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER336: + hv_gic_distributor_reg_t = 27264; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER337: + hv_gic_distributor_reg_t = 27272; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER338: + hv_gic_distributor_reg_t = 27280; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER339: + hv_gic_distributor_reg_t = 27288; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER340: + hv_gic_distributor_reg_t = 27296; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER341: + hv_gic_distributor_reg_t = 27304; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER342: + hv_gic_distributor_reg_t = 27312; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER343: + hv_gic_distributor_reg_t = 27320; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER344: + hv_gic_distributor_reg_t = 27328; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER345: + hv_gic_distributor_reg_t = 27336; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER346: + hv_gic_distributor_reg_t = 27344; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER347: + hv_gic_distributor_reg_t = 27352; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER348: + hv_gic_distributor_reg_t = 27360; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER349: + hv_gic_distributor_reg_t = 27368; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER350: + hv_gic_distributor_reg_t = 27376; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER351: + hv_gic_distributor_reg_t = 27384; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER352: + hv_gic_distributor_reg_t = 27392; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER353: + hv_gic_distributor_reg_t = 27400; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER354: + hv_gic_distributor_reg_t = 27408; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER355: + hv_gic_distributor_reg_t = 27416; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER356: + hv_gic_distributor_reg_t = 27424; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER357: + hv_gic_distributor_reg_t = 27432; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER358: + hv_gic_distributor_reg_t = 27440; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER359: + hv_gic_distributor_reg_t = 27448; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER360: + hv_gic_distributor_reg_t = 27456; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER361: + hv_gic_distributor_reg_t = 27464; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER362: + hv_gic_distributor_reg_t = 27472; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER363: + hv_gic_distributor_reg_t = 27480; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER364: + hv_gic_distributor_reg_t = 27488; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER365: + hv_gic_distributor_reg_t = 27496; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER366: + hv_gic_distributor_reg_t = 27504; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER367: + hv_gic_distributor_reg_t = 27512; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER368: + hv_gic_distributor_reg_t = 27520; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER369: + hv_gic_distributor_reg_t = 27528; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER370: + hv_gic_distributor_reg_t = 27536; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER371: + hv_gic_distributor_reg_t = 27544; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER372: + hv_gic_distributor_reg_t = 27552; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER373: + hv_gic_distributor_reg_t = 27560; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER374: + hv_gic_distributor_reg_t = 27568; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER375: + hv_gic_distributor_reg_t = 27576; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER376: + hv_gic_distributor_reg_t = 27584; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER377: + hv_gic_distributor_reg_t = 27592; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER378: + hv_gic_distributor_reg_t = 27600; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER379: + hv_gic_distributor_reg_t = 27608; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER380: + hv_gic_distributor_reg_t = 27616; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER381: + hv_gic_distributor_reg_t = 27624; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER382: + hv_gic_distributor_reg_t = 27632; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER383: + hv_gic_distributor_reg_t = 27640; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER384: + hv_gic_distributor_reg_t = 27648; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER385: + hv_gic_distributor_reg_t = 27656; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER386: + hv_gic_distributor_reg_t = 27664; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER387: + hv_gic_distributor_reg_t = 27672; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER388: + hv_gic_distributor_reg_t = 27680; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER389: + hv_gic_distributor_reg_t = 27688; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER390: + hv_gic_distributor_reg_t = 27696; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER391: + hv_gic_distributor_reg_t = 27704; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER392: + hv_gic_distributor_reg_t = 27712; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER393: + hv_gic_distributor_reg_t = 27720; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER394: + hv_gic_distributor_reg_t = 27728; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER395: + hv_gic_distributor_reg_t = 27736; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER396: + hv_gic_distributor_reg_t = 27744; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER397: + hv_gic_distributor_reg_t = 27752; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER398: + hv_gic_distributor_reg_t = 27760; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER399: + hv_gic_distributor_reg_t = 27768; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER400: + hv_gic_distributor_reg_t = 27776; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER401: + hv_gic_distributor_reg_t = 27784; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER402: + hv_gic_distributor_reg_t = 27792; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER403: + hv_gic_distributor_reg_t = 27800; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER404: + hv_gic_distributor_reg_t = 27808; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER405: + hv_gic_distributor_reg_t = 27816; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER406: + hv_gic_distributor_reg_t = 27824; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER407: + hv_gic_distributor_reg_t = 27832; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER408: + hv_gic_distributor_reg_t = 27840; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER409: + hv_gic_distributor_reg_t = 27848; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER410: + hv_gic_distributor_reg_t = 27856; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER411: + hv_gic_distributor_reg_t = 27864; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER412: + hv_gic_distributor_reg_t = 27872; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER413: + hv_gic_distributor_reg_t = 27880; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER414: + hv_gic_distributor_reg_t = 27888; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER415: + hv_gic_distributor_reg_t = 27896; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER416: + hv_gic_distributor_reg_t = 27904; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER417: + hv_gic_distributor_reg_t = 27912; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER418: + hv_gic_distributor_reg_t = 27920; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER419: + hv_gic_distributor_reg_t = 27928; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER420: + hv_gic_distributor_reg_t = 27936; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER421: + hv_gic_distributor_reg_t = 27944; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER422: + hv_gic_distributor_reg_t = 27952; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER423: + hv_gic_distributor_reg_t = 27960; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER424: + hv_gic_distributor_reg_t = 27968; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER425: + hv_gic_distributor_reg_t = 27976; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER426: + hv_gic_distributor_reg_t = 27984; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER427: + hv_gic_distributor_reg_t = 27992; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER428: + hv_gic_distributor_reg_t = 28000; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER429: + hv_gic_distributor_reg_t = 28008; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER430: + hv_gic_distributor_reg_t = 28016; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER431: + hv_gic_distributor_reg_t = 28024; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER432: + hv_gic_distributor_reg_t = 28032; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER433: + hv_gic_distributor_reg_t = 28040; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER434: + hv_gic_distributor_reg_t = 28048; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER435: + hv_gic_distributor_reg_t = 28056; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER436: + hv_gic_distributor_reg_t = 28064; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER437: + hv_gic_distributor_reg_t = 28072; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER438: + hv_gic_distributor_reg_t = 28080; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER439: + hv_gic_distributor_reg_t = 28088; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER440: + hv_gic_distributor_reg_t = 28096; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER441: + hv_gic_distributor_reg_t = 28104; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER442: + hv_gic_distributor_reg_t = 28112; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER443: + hv_gic_distributor_reg_t = 28120; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER444: + hv_gic_distributor_reg_t = 28128; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER445: + hv_gic_distributor_reg_t = 28136; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER446: + hv_gic_distributor_reg_t = 28144; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER447: + hv_gic_distributor_reg_t = 28152; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER448: + hv_gic_distributor_reg_t = 28160; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER449: + hv_gic_distributor_reg_t = 28168; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER450: + hv_gic_distributor_reg_t = 28176; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER451: + hv_gic_distributor_reg_t = 28184; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER452: + hv_gic_distributor_reg_t = 28192; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER453: + hv_gic_distributor_reg_t = 28200; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER454: + hv_gic_distributor_reg_t = 28208; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER455: + hv_gic_distributor_reg_t = 28216; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER456: + hv_gic_distributor_reg_t = 28224; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER457: + hv_gic_distributor_reg_t = 28232; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER458: + hv_gic_distributor_reg_t = 28240; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER459: + hv_gic_distributor_reg_t = 28248; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER460: + hv_gic_distributor_reg_t = 28256; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER461: + hv_gic_distributor_reg_t = 28264; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER462: + hv_gic_distributor_reg_t = 28272; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER463: + hv_gic_distributor_reg_t = 28280; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER464: + hv_gic_distributor_reg_t = 28288; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER465: + hv_gic_distributor_reg_t = 28296; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER466: + hv_gic_distributor_reg_t = 28304; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER467: + hv_gic_distributor_reg_t = 28312; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER468: + hv_gic_distributor_reg_t = 28320; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER469: + hv_gic_distributor_reg_t = 28328; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER470: + hv_gic_distributor_reg_t = 28336; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER471: + hv_gic_distributor_reg_t = 28344; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER472: + hv_gic_distributor_reg_t = 28352; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER473: + hv_gic_distributor_reg_t = 28360; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER474: + hv_gic_distributor_reg_t = 28368; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER475: + hv_gic_distributor_reg_t = 28376; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER476: + hv_gic_distributor_reg_t = 28384; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER477: + hv_gic_distributor_reg_t = 28392; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER478: + hv_gic_distributor_reg_t = 28400; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER479: + hv_gic_distributor_reg_t = 28408; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER480: + hv_gic_distributor_reg_t = 28416; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER481: + hv_gic_distributor_reg_t = 28424; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER482: + hv_gic_distributor_reg_t = 28432; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER483: + hv_gic_distributor_reg_t = 28440; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER484: + hv_gic_distributor_reg_t = 28448; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER485: + hv_gic_distributor_reg_t = 28456; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER486: + hv_gic_distributor_reg_t = 28464; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER487: + hv_gic_distributor_reg_t = 28472; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER488: + hv_gic_distributor_reg_t = 28480; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER489: + hv_gic_distributor_reg_t = 28488; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER490: + hv_gic_distributor_reg_t = 28496; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER491: + hv_gic_distributor_reg_t = 28504; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER492: + hv_gic_distributor_reg_t = 28512; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER493: + hv_gic_distributor_reg_t = 28520; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER494: + hv_gic_distributor_reg_t = 28528; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER495: + hv_gic_distributor_reg_t = 28536; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER496: + hv_gic_distributor_reg_t = 28544; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER497: + hv_gic_distributor_reg_t = 28552; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER498: + hv_gic_distributor_reg_t = 28560; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER499: + hv_gic_distributor_reg_t = 28568; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER500: + hv_gic_distributor_reg_t = 28576; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER501: + hv_gic_distributor_reg_t = 28584; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER502: + hv_gic_distributor_reg_t = 28592; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER503: + hv_gic_distributor_reg_t = 28600; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER504: + hv_gic_distributor_reg_t = 28608; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER505: + hv_gic_distributor_reg_t = 28616; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER506: + hv_gic_distributor_reg_t = 28624; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER507: + hv_gic_distributor_reg_t = 28632; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER508: + hv_gic_distributor_reg_t = 28640; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER509: + hv_gic_distributor_reg_t = 28648; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER510: + hv_gic_distributor_reg_t = 28656; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER511: + hv_gic_distributor_reg_t = 28664; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER512: + hv_gic_distributor_reg_t = 28672; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER513: + hv_gic_distributor_reg_t = 28680; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER514: + hv_gic_distributor_reg_t = 28688; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER515: + hv_gic_distributor_reg_t = 28696; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER516: + hv_gic_distributor_reg_t = 28704; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER517: + hv_gic_distributor_reg_t = 28712; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER518: + hv_gic_distributor_reg_t = 28720; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER519: + hv_gic_distributor_reg_t = 28728; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER520: + hv_gic_distributor_reg_t = 28736; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER521: + hv_gic_distributor_reg_t = 28744; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER522: + hv_gic_distributor_reg_t = 28752; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER523: + hv_gic_distributor_reg_t = 28760; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER524: + hv_gic_distributor_reg_t = 28768; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER525: + hv_gic_distributor_reg_t = 28776; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER526: + hv_gic_distributor_reg_t = 28784; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER527: + hv_gic_distributor_reg_t = 28792; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER528: + hv_gic_distributor_reg_t = 28800; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER529: + hv_gic_distributor_reg_t = 28808; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER530: + hv_gic_distributor_reg_t = 28816; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER531: + hv_gic_distributor_reg_t = 28824; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER532: + hv_gic_distributor_reg_t = 28832; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER533: + hv_gic_distributor_reg_t = 28840; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER534: + hv_gic_distributor_reg_t = 28848; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER535: + hv_gic_distributor_reg_t = 28856; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER536: + hv_gic_distributor_reg_t = 28864; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER537: + hv_gic_distributor_reg_t = 28872; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER538: + hv_gic_distributor_reg_t = 28880; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER539: + hv_gic_distributor_reg_t = 28888; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER540: + hv_gic_distributor_reg_t = 28896; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER541: + hv_gic_distributor_reg_t = 28904; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER542: + hv_gic_distributor_reg_t = 28912; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER543: + hv_gic_distributor_reg_t = 28920; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER544: + hv_gic_distributor_reg_t = 28928; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER545: + hv_gic_distributor_reg_t = 28936; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER546: + hv_gic_distributor_reg_t = 28944; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER547: + hv_gic_distributor_reg_t = 28952; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER548: + hv_gic_distributor_reg_t = 28960; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER549: + hv_gic_distributor_reg_t = 28968; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER550: + hv_gic_distributor_reg_t = 28976; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER551: + hv_gic_distributor_reg_t = 28984; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER552: + hv_gic_distributor_reg_t = 28992; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER553: + hv_gic_distributor_reg_t = 29000; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER554: + hv_gic_distributor_reg_t = 29008; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER555: + hv_gic_distributor_reg_t = 29016; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER556: + hv_gic_distributor_reg_t = 29024; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER557: + hv_gic_distributor_reg_t = 29032; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER558: + hv_gic_distributor_reg_t = 29040; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER559: + hv_gic_distributor_reg_t = 29048; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER560: + hv_gic_distributor_reg_t = 29056; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER561: + hv_gic_distributor_reg_t = 29064; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER562: + hv_gic_distributor_reg_t = 29072; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER563: + hv_gic_distributor_reg_t = 29080; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER564: + hv_gic_distributor_reg_t = 29088; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER565: + hv_gic_distributor_reg_t = 29096; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER566: + hv_gic_distributor_reg_t = 29104; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER567: + hv_gic_distributor_reg_t = 29112; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER568: + hv_gic_distributor_reg_t = 29120; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER569: + hv_gic_distributor_reg_t = 29128; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER570: + hv_gic_distributor_reg_t = 29136; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER571: + hv_gic_distributor_reg_t = 29144; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER572: + hv_gic_distributor_reg_t = 29152; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER573: + hv_gic_distributor_reg_t = 29160; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER574: + hv_gic_distributor_reg_t = 29168; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER575: + hv_gic_distributor_reg_t = 29176; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER576: + hv_gic_distributor_reg_t = 29184; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER577: + hv_gic_distributor_reg_t = 29192; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER578: + hv_gic_distributor_reg_t = 29200; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER579: + hv_gic_distributor_reg_t = 29208; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER580: + hv_gic_distributor_reg_t = 29216; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER581: + hv_gic_distributor_reg_t = 29224; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER582: + hv_gic_distributor_reg_t = 29232; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER583: + hv_gic_distributor_reg_t = 29240; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER584: + hv_gic_distributor_reg_t = 29248; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER585: + hv_gic_distributor_reg_t = 29256; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER586: + hv_gic_distributor_reg_t = 29264; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER587: + hv_gic_distributor_reg_t = 29272; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER588: + hv_gic_distributor_reg_t = 29280; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER589: + hv_gic_distributor_reg_t = 29288; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER590: + hv_gic_distributor_reg_t = 29296; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER591: + hv_gic_distributor_reg_t = 29304; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER592: + hv_gic_distributor_reg_t = 29312; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER593: + hv_gic_distributor_reg_t = 29320; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER594: + hv_gic_distributor_reg_t = 29328; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER595: + hv_gic_distributor_reg_t = 29336; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER596: + hv_gic_distributor_reg_t = 29344; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER597: + hv_gic_distributor_reg_t = 29352; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER598: + hv_gic_distributor_reg_t = 29360; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER599: + hv_gic_distributor_reg_t = 29368; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER600: + hv_gic_distributor_reg_t = 29376; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER601: + hv_gic_distributor_reg_t = 29384; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER602: + hv_gic_distributor_reg_t = 29392; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER603: + hv_gic_distributor_reg_t = 29400; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER604: + hv_gic_distributor_reg_t = 29408; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER605: + hv_gic_distributor_reg_t = 29416; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER606: + hv_gic_distributor_reg_t = 29424; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER607: + hv_gic_distributor_reg_t = 29432; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER608: + hv_gic_distributor_reg_t = 29440; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER609: + hv_gic_distributor_reg_t = 29448; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER610: + hv_gic_distributor_reg_t = 29456; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER611: + hv_gic_distributor_reg_t = 29464; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER612: + hv_gic_distributor_reg_t = 29472; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER613: + hv_gic_distributor_reg_t = 29480; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER614: + hv_gic_distributor_reg_t = 29488; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER615: + hv_gic_distributor_reg_t = 29496; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER616: + hv_gic_distributor_reg_t = 29504; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER617: + hv_gic_distributor_reg_t = 29512; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER618: + hv_gic_distributor_reg_t = 29520; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER619: + hv_gic_distributor_reg_t = 29528; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER620: + hv_gic_distributor_reg_t = 29536; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER621: + hv_gic_distributor_reg_t = 29544; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER622: + hv_gic_distributor_reg_t = 29552; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER623: + hv_gic_distributor_reg_t = 29560; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER624: + hv_gic_distributor_reg_t = 29568; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER625: + hv_gic_distributor_reg_t = 29576; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER626: + hv_gic_distributor_reg_t = 29584; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER627: + hv_gic_distributor_reg_t = 29592; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER628: + hv_gic_distributor_reg_t = 29600; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER629: + hv_gic_distributor_reg_t = 29608; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER630: + hv_gic_distributor_reg_t = 29616; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER631: + hv_gic_distributor_reg_t = 29624; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER632: + hv_gic_distributor_reg_t = 29632; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER633: + hv_gic_distributor_reg_t = 29640; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER634: + hv_gic_distributor_reg_t = 29648; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER635: + hv_gic_distributor_reg_t = 29656; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER636: + hv_gic_distributor_reg_t = 29664; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER637: + hv_gic_distributor_reg_t = 29672; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER638: + hv_gic_distributor_reg_t = 29680; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER639: + hv_gic_distributor_reg_t = 29688; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER640: + hv_gic_distributor_reg_t = 29696; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER641: + hv_gic_distributor_reg_t = 29704; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER642: + hv_gic_distributor_reg_t = 29712; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER643: + hv_gic_distributor_reg_t = 29720; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER644: + hv_gic_distributor_reg_t = 29728; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER645: + hv_gic_distributor_reg_t = 29736; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER646: + hv_gic_distributor_reg_t = 29744; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER647: + hv_gic_distributor_reg_t = 29752; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER648: + hv_gic_distributor_reg_t = 29760; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER649: + hv_gic_distributor_reg_t = 29768; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER650: + hv_gic_distributor_reg_t = 29776; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER651: + hv_gic_distributor_reg_t = 29784; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER652: + hv_gic_distributor_reg_t = 29792; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER653: + hv_gic_distributor_reg_t = 29800; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER654: + hv_gic_distributor_reg_t = 29808; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER655: + hv_gic_distributor_reg_t = 29816; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER656: + hv_gic_distributor_reg_t = 29824; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER657: + hv_gic_distributor_reg_t = 29832; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER658: + hv_gic_distributor_reg_t = 29840; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER659: + hv_gic_distributor_reg_t = 29848; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER660: + hv_gic_distributor_reg_t = 29856; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER661: + hv_gic_distributor_reg_t = 29864; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER662: + hv_gic_distributor_reg_t = 29872; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER663: + hv_gic_distributor_reg_t = 29880; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER664: + hv_gic_distributor_reg_t = 29888; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER665: + hv_gic_distributor_reg_t = 29896; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER666: + hv_gic_distributor_reg_t = 29904; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER667: + hv_gic_distributor_reg_t = 29912; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER668: + hv_gic_distributor_reg_t = 29920; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER669: + hv_gic_distributor_reg_t = 29928; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER670: + hv_gic_distributor_reg_t = 29936; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER671: + hv_gic_distributor_reg_t = 29944; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER672: + hv_gic_distributor_reg_t = 29952; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER673: + hv_gic_distributor_reg_t = 29960; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER674: + hv_gic_distributor_reg_t = 29968; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER675: + hv_gic_distributor_reg_t = 29976; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER676: + hv_gic_distributor_reg_t = 29984; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER677: + hv_gic_distributor_reg_t = 29992; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER678: + hv_gic_distributor_reg_t = 30000; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER679: + hv_gic_distributor_reg_t = 30008; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER680: + hv_gic_distributor_reg_t = 30016; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER681: + hv_gic_distributor_reg_t = 30024; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER682: + hv_gic_distributor_reg_t = 30032; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER683: + hv_gic_distributor_reg_t = 30040; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER684: + hv_gic_distributor_reg_t = 30048; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER685: + hv_gic_distributor_reg_t = 30056; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER686: + hv_gic_distributor_reg_t = 30064; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER687: + hv_gic_distributor_reg_t = 30072; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER688: + hv_gic_distributor_reg_t = 30080; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER689: + hv_gic_distributor_reg_t = 30088; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER690: + hv_gic_distributor_reg_t = 30096; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER691: + hv_gic_distributor_reg_t = 30104; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER692: + hv_gic_distributor_reg_t = 30112; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER693: + hv_gic_distributor_reg_t = 30120; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER694: + hv_gic_distributor_reg_t = 30128; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER695: + hv_gic_distributor_reg_t = 30136; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER696: + hv_gic_distributor_reg_t = 30144; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER697: + hv_gic_distributor_reg_t = 30152; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER698: + hv_gic_distributor_reg_t = 30160; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER699: + hv_gic_distributor_reg_t = 30168; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER700: + hv_gic_distributor_reg_t = 30176; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER701: + hv_gic_distributor_reg_t = 30184; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER702: + hv_gic_distributor_reg_t = 30192; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER703: + hv_gic_distributor_reg_t = 30200; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER704: + hv_gic_distributor_reg_t = 30208; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER705: + hv_gic_distributor_reg_t = 30216; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER706: + hv_gic_distributor_reg_t = 30224; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER707: + hv_gic_distributor_reg_t = 30232; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER708: + hv_gic_distributor_reg_t = 30240; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER709: + hv_gic_distributor_reg_t = 30248; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER710: + hv_gic_distributor_reg_t = 30256; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER711: + hv_gic_distributor_reg_t = 30264; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER712: + hv_gic_distributor_reg_t = 30272; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER713: + hv_gic_distributor_reg_t = 30280; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER714: + hv_gic_distributor_reg_t = 30288; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER715: + hv_gic_distributor_reg_t = 30296; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER716: + hv_gic_distributor_reg_t = 30304; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER717: + hv_gic_distributor_reg_t = 30312; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER718: + hv_gic_distributor_reg_t = 30320; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER719: + hv_gic_distributor_reg_t = 30328; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER720: + hv_gic_distributor_reg_t = 30336; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER721: + hv_gic_distributor_reg_t = 30344; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER722: + hv_gic_distributor_reg_t = 30352; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER723: + hv_gic_distributor_reg_t = 30360; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER724: + hv_gic_distributor_reg_t = 30368; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER725: + hv_gic_distributor_reg_t = 30376; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER726: + hv_gic_distributor_reg_t = 30384; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER727: + hv_gic_distributor_reg_t = 30392; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER728: + hv_gic_distributor_reg_t = 30400; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER729: + hv_gic_distributor_reg_t = 30408; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER730: + hv_gic_distributor_reg_t = 30416; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER731: + hv_gic_distributor_reg_t = 30424; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER732: + hv_gic_distributor_reg_t = 30432; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER733: + hv_gic_distributor_reg_t = 30440; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER734: + hv_gic_distributor_reg_t = 30448; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER735: + hv_gic_distributor_reg_t = 30456; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER736: + hv_gic_distributor_reg_t = 30464; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER737: + hv_gic_distributor_reg_t = 30472; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER738: + hv_gic_distributor_reg_t = 30480; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER739: + hv_gic_distributor_reg_t = 30488; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER740: + hv_gic_distributor_reg_t = 30496; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER741: + hv_gic_distributor_reg_t = 30504; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER742: + hv_gic_distributor_reg_t = 30512; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER743: + hv_gic_distributor_reg_t = 30520; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER744: + hv_gic_distributor_reg_t = 30528; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER745: + hv_gic_distributor_reg_t = 30536; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER746: + hv_gic_distributor_reg_t = 30544; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER747: + hv_gic_distributor_reg_t = 30552; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER748: + hv_gic_distributor_reg_t = 30560; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER749: + hv_gic_distributor_reg_t = 30568; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER750: + hv_gic_distributor_reg_t = 30576; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER751: + hv_gic_distributor_reg_t = 30584; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER752: + hv_gic_distributor_reg_t = 30592; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER753: + hv_gic_distributor_reg_t = 30600; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER754: + hv_gic_distributor_reg_t = 30608; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER755: + hv_gic_distributor_reg_t = 30616; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER756: + hv_gic_distributor_reg_t = 30624; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER757: + hv_gic_distributor_reg_t = 30632; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER758: + hv_gic_distributor_reg_t = 30640; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER759: + hv_gic_distributor_reg_t = 30648; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER760: + hv_gic_distributor_reg_t = 30656; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER761: + hv_gic_distributor_reg_t = 30664; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER762: + hv_gic_distributor_reg_t = 30672; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER763: + hv_gic_distributor_reg_t = 30680; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER764: + hv_gic_distributor_reg_t = 30688; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER765: + hv_gic_distributor_reg_t = 30696; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER766: + hv_gic_distributor_reg_t = 30704; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER767: + hv_gic_distributor_reg_t = 30712; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER768: + hv_gic_distributor_reg_t = 30720; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER769: + hv_gic_distributor_reg_t = 30728; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER770: + hv_gic_distributor_reg_t = 30736; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER771: + hv_gic_distributor_reg_t = 30744; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER772: + hv_gic_distributor_reg_t = 30752; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER773: + hv_gic_distributor_reg_t = 30760; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER774: + hv_gic_distributor_reg_t = 30768; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER775: + hv_gic_distributor_reg_t = 30776; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER776: + hv_gic_distributor_reg_t = 30784; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER777: + hv_gic_distributor_reg_t = 30792; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER778: + hv_gic_distributor_reg_t = 30800; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER779: + hv_gic_distributor_reg_t = 30808; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER780: + hv_gic_distributor_reg_t = 30816; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER781: + hv_gic_distributor_reg_t = 30824; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER782: + hv_gic_distributor_reg_t = 30832; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER783: + hv_gic_distributor_reg_t = 30840; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER784: + hv_gic_distributor_reg_t = 30848; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER785: + hv_gic_distributor_reg_t = 30856; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER786: + hv_gic_distributor_reg_t = 30864; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER787: + hv_gic_distributor_reg_t = 30872; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER788: + hv_gic_distributor_reg_t = 30880; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER789: + hv_gic_distributor_reg_t = 30888; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER790: + hv_gic_distributor_reg_t = 30896; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER791: + hv_gic_distributor_reg_t = 30904; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER792: + hv_gic_distributor_reg_t = 30912; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER793: + hv_gic_distributor_reg_t = 30920; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER794: + hv_gic_distributor_reg_t = 30928; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER795: + hv_gic_distributor_reg_t = 30936; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER796: + hv_gic_distributor_reg_t = 30944; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER797: + hv_gic_distributor_reg_t = 30952; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER798: + hv_gic_distributor_reg_t = 30960; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER799: + hv_gic_distributor_reg_t = 30968; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER800: + hv_gic_distributor_reg_t = 30976; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER801: + hv_gic_distributor_reg_t = 30984; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER802: + hv_gic_distributor_reg_t = 30992; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER803: + hv_gic_distributor_reg_t = 31000; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER804: + hv_gic_distributor_reg_t = 31008; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER805: + hv_gic_distributor_reg_t = 31016; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER806: + hv_gic_distributor_reg_t = 31024; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER807: + hv_gic_distributor_reg_t = 31032; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER808: + hv_gic_distributor_reg_t = 31040; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER809: + hv_gic_distributor_reg_t = 31048; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER810: + hv_gic_distributor_reg_t = 31056; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER811: + hv_gic_distributor_reg_t = 31064; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER812: + hv_gic_distributor_reg_t = 31072; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER813: + hv_gic_distributor_reg_t = 31080; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER814: + hv_gic_distributor_reg_t = 31088; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER815: + hv_gic_distributor_reg_t = 31096; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER816: + hv_gic_distributor_reg_t = 31104; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER817: + hv_gic_distributor_reg_t = 31112; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER818: + hv_gic_distributor_reg_t = 31120; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER819: + hv_gic_distributor_reg_t = 31128; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER820: + hv_gic_distributor_reg_t = 31136; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER821: + hv_gic_distributor_reg_t = 31144; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER822: + hv_gic_distributor_reg_t = 31152; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER823: + hv_gic_distributor_reg_t = 31160; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER824: + hv_gic_distributor_reg_t = 31168; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER825: + hv_gic_distributor_reg_t = 31176; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER826: + hv_gic_distributor_reg_t = 31184; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER827: + hv_gic_distributor_reg_t = 31192; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER828: + hv_gic_distributor_reg_t = 31200; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER829: + hv_gic_distributor_reg_t = 31208; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER830: + hv_gic_distributor_reg_t = 31216; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER831: + hv_gic_distributor_reg_t = 31224; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER832: + hv_gic_distributor_reg_t = 31232; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER833: + hv_gic_distributor_reg_t = 31240; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER834: + hv_gic_distributor_reg_t = 31248; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER835: + hv_gic_distributor_reg_t = 31256; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER836: + hv_gic_distributor_reg_t = 31264; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER837: + hv_gic_distributor_reg_t = 31272; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER838: + hv_gic_distributor_reg_t = 31280; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER839: + hv_gic_distributor_reg_t = 31288; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER840: + hv_gic_distributor_reg_t = 31296; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER841: + hv_gic_distributor_reg_t = 31304; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER842: + hv_gic_distributor_reg_t = 31312; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER843: + hv_gic_distributor_reg_t = 31320; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER844: + hv_gic_distributor_reg_t = 31328; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER845: + hv_gic_distributor_reg_t = 31336; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER846: + hv_gic_distributor_reg_t = 31344; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER847: + hv_gic_distributor_reg_t = 31352; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER848: + hv_gic_distributor_reg_t = 31360; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER849: + hv_gic_distributor_reg_t = 31368; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER850: + hv_gic_distributor_reg_t = 31376; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER851: + hv_gic_distributor_reg_t = 31384; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER852: + hv_gic_distributor_reg_t = 31392; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER853: + hv_gic_distributor_reg_t = 31400; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER854: + hv_gic_distributor_reg_t = 31408; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER855: + hv_gic_distributor_reg_t = 31416; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER856: + hv_gic_distributor_reg_t = 31424; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER857: + hv_gic_distributor_reg_t = 31432; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER858: + hv_gic_distributor_reg_t = 31440; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER859: + hv_gic_distributor_reg_t = 31448; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER860: + hv_gic_distributor_reg_t = 31456; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER861: + hv_gic_distributor_reg_t = 31464; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER862: + hv_gic_distributor_reg_t = 31472; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER863: + hv_gic_distributor_reg_t = 31480; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER864: + hv_gic_distributor_reg_t = 31488; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER865: + hv_gic_distributor_reg_t = 31496; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER866: + hv_gic_distributor_reg_t = 31504; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER867: + hv_gic_distributor_reg_t = 31512; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER868: + hv_gic_distributor_reg_t = 31520; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER869: + hv_gic_distributor_reg_t = 31528; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER870: + hv_gic_distributor_reg_t = 31536; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER871: + hv_gic_distributor_reg_t = 31544; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER872: + hv_gic_distributor_reg_t = 31552; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER873: + hv_gic_distributor_reg_t = 31560; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER874: + hv_gic_distributor_reg_t = 31568; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER875: + hv_gic_distributor_reg_t = 31576; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER876: + hv_gic_distributor_reg_t = 31584; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER877: + hv_gic_distributor_reg_t = 31592; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER878: + hv_gic_distributor_reg_t = 31600; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER879: + hv_gic_distributor_reg_t = 31608; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER880: + hv_gic_distributor_reg_t = 31616; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER881: + hv_gic_distributor_reg_t = 31624; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER882: + hv_gic_distributor_reg_t = 31632; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER883: + hv_gic_distributor_reg_t = 31640; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER884: + hv_gic_distributor_reg_t = 31648; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER885: + hv_gic_distributor_reg_t = 31656; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER886: + hv_gic_distributor_reg_t = 31664; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER887: + hv_gic_distributor_reg_t = 31672; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER888: + hv_gic_distributor_reg_t = 31680; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER889: + hv_gic_distributor_reg_t = 31688; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER890: + hv_gic_distributor_reg_t = 31696; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER891: + hv_gic_distributor_reg_t = 31704; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER892: + hv_gic_distributor_reg_t = 31712; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER893: + hv_gic_distributor_reg_t = 31720; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER894: + hv_gic_distributor_reg_t = 31728; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER895: + hv_gic_distributor_reg_t = 31736; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER896: + hv_gic_distributor_reg_t = 31744; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER897: + hv_gic_distributor_reg_t = 31752; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER898: + hv_gic_distributor_reg_t = 31760; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER899: + hv_gic_distributor_reg_t = 31768; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER900: + hv_gic_distributor_reg_t = 31776; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER901: + hv_gic_distributor_reg_t = 31784; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER902: + hv_gic_distributor_reg_t = 31792; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER903: + hv_gic_distributor_reg_t = 31800; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER904: + hv_gic_distributor_reg_t = 31808; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER905: + hv_gic_distributor_reg_t = 31816; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER906: + hv_gic_distributor_reg_t = 31824; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER907: + hv_gic_distributor_reg_t = 31832; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER908: + hv_gic_distributor_reg_t = 31840; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER909: + hv_gic_distributor_reg_t = 31848; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER910: + hv_gic_distributor_reg_t = 31856; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER911: + hv_gic_distributor_reg_t = 31864; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER912: + hv_gic_distributor_reg_t = 31872; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER913: + hv_gic_distributor_reg_t = 31880; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER914: + hv_gic_distributor_reg_t = 31888; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER915: + hv_gic_distributor_reg_t = 31896; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER916: + hv_gic_distributor_reg_t = 31904; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER917: + hv_gic_distributor_reg_t = 31912; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER918: + hv_gic_distributor_reg_t = 31920; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER919: + hv_gic_distributor_reg_t = 31928; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER920: + hv_gic_distributor_reg_t = 31936; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER921: + hv_gic_distributor_reg_t = 31944; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER922: + hv_gic_distributor_reg_t = 31952; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER923: + hv_gic_distributor_reg_t = 31960; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER924: + hv_gic_distributor_reg_t = 31968; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER925: + hv_gic_distributor_reg_t = 31976; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER926: + hv_gic_distributor_reg_t = 31984; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER927: + hv_gic_distributor_reg_t = 31992; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER928: + hv_gic_distributor_reg_t = 32000; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER929: + hv_gic_distributor_reg_t = 32008; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER930: + hv_gic_distributor_reg_t = 32016; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER931: + hv_gic_distributor_reg_t = 32024; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER932: + hv_gic_distributor_reg_t = 32032; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER933: + hv_gic_distributor_reg_t = 32040; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER934: + hv_gic_distributor_reg_t = 32048; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER935: + hv_gic_distributor_reg_t = 32056; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER936: + hv_gic_distributor_reg_t = 32064; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER937: + hv_gic_distributor_reg_t = 32072; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER938: + hv_gic_distributor_reg_t = 32080; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER939: + hv_gic_distributor_reg_t = 32088; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER940: + hv_gic_distributor_reg_t = 32096; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER941: + hv_gic_distributor_reg_t = 32104; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER942: + hv_gic_distributor_reg_t = 32112; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER943: + hv_gic_distributor_reg_t = 32120; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER944: + hv_gic_distributor_reg_t = 32128; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER945: + hv_gic_distributor_reg_t = 32136; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER946: + hv_gic_distributor_reg_t = 32144; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER947: + hv_gic_distributor_reg_t = 32152; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER948: + hv_gic_distributor_reg_t = 32160; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER949: + hv_gic_distributor_reg_t = 32168; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER950: + hv_gic_distributor_reg_t = 32176; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER951: + hv_gic_distributor_reg_t = 32184; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER952: + hv_gic_distributor_reg_t = 32192; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER953: + hv_gic_distributor_reg_t = 32200; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER954: + hv_gic_distributor_reg_t = 32208; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER955: + hv_gic_distributor_reg_t = 32216; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER956: + hv_gic_distributor_reg_t = 32224; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER957: + hv_gic_distributor_reg_t = 32232; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER958: + hv_gic_distributor_reg_t = 32240; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER959: + hv_gic_distributor_reg_t = 32248; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER960: + hv_gic_distributor_reg_t = 32256; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER961: + hv_gic_distributor_reg_t = 32264; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER962: + hv_gic_distributor_reg_t = 32272; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER963: + hv_gic_distributor_reg_t = 32280; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER964: + hv_gic_distributor_reg_t = 32288; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER965: + hv_gic_distributor_reg_t = 32296; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER966: + hv_gic_distributor_reg_t = 32304; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER967: + hv_gic_distributor_reg_t = 32312; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER968: + hv_gic_distributor_reg_t = 32320; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER969: + hv_gic_distributor_reg_t = 32328; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER970: + hv_gic_distributor_reg_t = 32336; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER971: + hv_gic_distributor_reg_t = 32344; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER972: + hv_gic_distributor_reg_t = 32352; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER973: + hv_gic_distributor_reg_t = 32360; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER974: + hv_gic_distributor_reg_t = 32368; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER975: + hv_gic_distributor_reg_t = 32376; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER976: + hv_gic_distributor_reg_t = 32384; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER977: + hv_gic_distributor_reg_t = 32392; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER978: + hv_gic_distributor_reg_t = 32400; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER979: + hv_gic_distributor_reg_t = 32408; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER980: + hv_gic_distributor_reg_t = 32416; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER981: + hv_gic_distributor_reg_t = 32424; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER982: + hv_gic_distributor_reg_t = 32432; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER983: + hv_gic_distributor_reg_t = 32440; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER984: + hv_gic_distributor_reg_t = 32448; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER985: + hv_gic_distributor_reg_t = 32456; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER986: + hv_gic_distributor_reg_t = 32464; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER987: + hv_gic_distributor_reg_t = 32472; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER988: + hv_gic_distributor_reg_t = 32480; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER989: + hv_gic_distributor_reg_t = 32488; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER990: + hv_gic_distributor_reg_t = 32496; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER991: + hv_gic_distributor_reg_t = 32504; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER992: + hv_gic_distributor_reg_t = 32512; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER993: + hv_gic_distributor_reg_t = 32520; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER994: + hv_gic_distributor_reg_t = 32528; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER995: + hv_gic_distributor_reg_t = 32536; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER996: + hv_gic_distributor_reg_t = 32544; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER997: + hv_gic_distributor_reg_t = 32552; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER998: + hv_gic_distributor_reg_t = 32560; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER999: + hv_gic_distributor_reg_t = 32568; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER1000: + hv_gic_distributor_reg_t = 32576; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER1001: + hv_gic_distributor_reg_t = 32584; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER1002: + hv_gic_distributor_reg_t = 32592; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER1003: + hv_gic_distributor_reg_t = 32600; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER1004: + hv_gic_distributor_reg_t = 32608; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER1005: + hv_gic_distributor_reg_t = 32616; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER1006: + hv_gic_distributor_reg_t = 32624; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER1007: + hv_gic_distributor_reg_t = 32632; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER1008: + hv_gic_distributor_reg_t = 32640; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER1009: + hv_gic_distributor_reg_t = 32648; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER1010: + hv_gic_distributor_reg_t = 32656; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER1011: + hv_gic_distributor_reg_t = 32664; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER1012: + hv_gic_distributor_reg_t = 32672; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER1013: + hv_gic_distributor_reg_t = 32680; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER1014: + hv_gic_distributor_reg_t = 32688; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER1015: + hv_gic_distributor_reg_t = 32696; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER1016: + hv_gic_distributor_reg_t = 32704; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER1017: + hv_gic_distributor_reg_t = 32712; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER1018: + hv_gic_distributor_reg_t = 32720; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_IROUTER1019: + hv_gic_distributor_reg_t = 32728; +pub const hv_gic_distributor_reg_t_HV_GIC_DISTRIBUTOR_REG_GICD_PIDR2: hv_gic_distributor_reg_t = + 65512; +pub type hv_gic_distributor_reg_t = u16; +pub const hv_gic_redistributor_reg_t_HV_GIC_REDISTRIBUTOR_REG_GICR_TYPER: + hv_gic_redistributor_reg_t = 8; +pub const hv_gic_redistributor_reg_t_HV_GIC_REDISTRIBUTOR_REG_GICR_PIDR2: + hv_gic_redistributor_reg_t = 65512; +pub const hv_gic_redistributor_reg_t_HV_GIC_REDISTRIBUTOR_REG_GICR_IGROUPR0: + hv_gic_redistributor_reg_t = 65664; +pub const hv_gic_redistributor_reg_t_HV_GIC_REDISTRIBUTOR_REG_GICR_ISENABLER0: + hv_gic_redistributor_reg_t = 65792; +pub const hv_gic_redistributor_reg_t_HV_GIC_REDISTRIBUTOR_REG_GICR_ICENABLER0: + hv_gic_redistributor_reg_t = 65920; +pub const hv_gic_redistributor_reg_t_HV_GIC_REDISTRIBUTOR_REG_GICR_ISPENDR0: + hv_gic_redistributor_reg_t = 66048; +pub const hv_gic_redistributor_reg_t_HV_GIC_REDISTRIBUTOR_REG_GICR_ICPENDR0: + hv_gic_redistributor_reg_t = 66176; +pub const hv_gic_redistributor_reg_t_HV_GIC_REDISTRIBUTOR_REG_GICR_ISACTIVER0: + hv_gic_redistributor_reg_t = 66304; +pub const hv_gic_redistributor_reg_t_HV_GIC_REDISTRIBUTOR_REG_GICR_ICACTIVER0: + hv_gic_redistributor_reg_t = 66432; +pub const hv_gic_redistributor_reg_t_HV_GIC_REDISTRIBUTOR_REG_GICR_IPRIORITYR0: + hv_gic_redistributor_reg_t = 66560; +pub const hv_gic_redistributor_reg_t_HV_GIC_REDISTRIBUTOR_REG_GICR_IPRIORITYR1: + hv_gic_redistributor_reg_t = 66564; +pub const hv_gic_redistributor_reg_t_HV_GIC_REDISTRIBUTOR_REG_GICR_IPRIORITYR2: + hv_gic_redistributor_reg_t = 66568; +pub const hv_gic_redistributor_reg_t_HV_GIC_REDISTRIBUTOR_REG_GICR_IPRIORITYR3: + hv_gic_redistributor_reg_t = 66572; +pub const hv_gic_redistributor_reg_t_HV_GIC_REDISTRIBUTOR_REG_GICR_IPRIORITYR4: + hv_gic_redistributor_reg_t = 66576; +pub const hv_gic_redistributor_reg_t_HV_GIC_REDISTRIBUTOR_REG_GICR_IPRIORITYR5: + hv_gic_redistributor_reg_t = 66580; +pub const hv_gic_redistributor_reg_t_HV_GIC_REDISTRIBUTOR_REG_GICR_IPRIORITYR6: + hv_gic_redistributor_reg_t = 66584; +pub const hv_gic_redistributor_reg_t_HV_GIC_REDISTRIBUTOR_REG_GICR_IPRIORITYR7: + hv_gic_redistributor_reg_t = 66588; +pub const hv_gic_redistributor_reg_t_HV_GIC_REDISTRIBUTOR_REG_GICR_ICFGR0: + hv_gic_redistributor_reg_t = 68608; +pub const hv_gic_redistributor_reg_t_HV_GIC_REDISTRIBUTOR_REG_GICR_ICFGR1: + hv_gic_redistributor_reg_t = 68612; +pub type hv_gic_redistributor_reg_t = u32; +pub const hv_gic_icc_reg_t_HV_GIC_ICC_REG_PMR_EL1: hv_gic_icc_reg_t = 49712; +pub const hv_gic_icc_reg_t_HV_GIC_ICC_REG_BPR0_EL1: hv_gic_icc_reg_t = 50755; +pub const hv_gic_icc_reg_t_HV_GIC_ICC_REG_AP0R0_EL1: hv_gic_icc_reg_t = 50756; +pub const hv_gic_icc_reg_t_HV_GIC_ICC_REG_AP1R0_EL1: hv_gic_icc_reg_t = 50760; +pub const hv_gic_icc_reg_t_HV_GIC_ICC_REG_RPR_EL1: hv_gic_icc_reg_t = 50779; +pub const hv_gic_icc_reg_t_HV_GIC_ICC_REG_BPR1_EL1: hv_gic_icc_reg_t = 50787; +pub const hv_gic_icc_reg_t_HV_GIC_ICC_REG_CTLR_EL1: hv_gic_icc_reg_t = 50788; +pub const hv_gic_icc_reg_t_HV_GIC_ICC_REG_SRE_EL1: hv_gic_icc_reg_t = 50789; +pub const hv_gic_icc_reg_t_HV_GIC_ICC_REG_IGRPEN0_EL1: hv_gic_icc_reg_t = 50790; +pub const hv_gic_icc_reg_t_HV_GIC_ICC_REG_IGRPEN1_EL1: hv_gic_icc_reg_t = 50791; +pub const hv_gic_icc_reg_t_HV_GIC_ICC_REG_SRE_EL2: hv_gic_icc_reg_t = 58957; +pub type hv_gic_icc_reg_t = u16; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_AP0R0_EL2: hv_gic_ich_reg_t = 58944; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_AP1R0_EL2: hv_gic_ich_reg_t = 58952; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_HCR_EL2: hv_gic_ich_reg_t = 58968; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_VTR_EL2: hv_gic_ich_reg_t = 58969; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_MISR_EL2: hv_gic_ich_reg_t = 58970; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_EISR_EL2: hv_gic_ich_reg_t = 58971; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_ELRSR_EL2: hv_gic_ich_reg_t = 58973; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_VMCR_EL2: hv_gic_ich_reg_t = 58975; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_LR0_EL2: hv_gic_ich_reg_t = 58976; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_LR1_EL2: hv_gic_ich_reg_t = 58977; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_LR2_EL2: hv_gic_ich_reg_t = 58978; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_LR3_EL2: hv_gic_ich_reg_t = 58979; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_LR4_EL2: hv_gic_ich_reg_t = 58980; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_LR5_EL2: hv_gic_ich_reg_t = 58981; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_LR6_EL2: hv_gic_ich_reg_t = 58982; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_LR7_EL2: hv_gic_ich_reg_t = 58983; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_LR8_EL2: hv_gic_ich_reg_t = 58984; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_LR9_EL2: hv_gic_ich_reg_t = 58985; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_LR10_EL2: hv_gic_ich_reg_t = 58986; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_LR11_EL2: hv_gic_ich_reg_t = 58987; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_LR12_EL2: hv_gic_ich_reg_t = 58988; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_LR13_EL2: hv_gic_ich_reg_t = 58989; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_LR14_EL2: hv_gic_ich_reg_t = 58990; +pub const hv_gic_ich_reg_t_HV_GIC_ICH_REG_LR15_EL2: hv_gic_ich_reg_t = 58991; +pub type hv_gic_ich_reg_t = u16; +pub const hv_gic_icv_reg_t_HV_GIC_ICV_REG_PMR_EL1: hv_gic_icv_reg_t = 49712; +pub const hv_gic_icv_reg_t_HV_GIC_ICV_REG_BPR0_EL1: hv_gic_icv_reg_t = 50755; +pub const hv_gic_icv_reg_t_HV_GIC_ICV_REG_AP0R0_EL1: hv_gic_icv_reg_t = 50756; +pub const hv_gic_icv_reg_t_HV_GIC_ICV_REG_AP1R0_EL1: hv_gic_icv_reg_t = 50760; +pub const hv_gic_icv_reg_t_HV_GIC_ICV_REG_RPR_EL1: hv_gic_icv_reg_t = 50779; +pub const hv_gic_icv_reg_t_HV_GIC_ICV_REG_BPR1_EL1: hv_gic_icv_reg_t = 50787; +pub const hv_gic_icv_reg_t_HV_GIC_ICV_REG_CTLR_EL1: hv_gic_icv_reg_t = 50788; +pub const hv_gic_icv_reg_t_HV_GIC_ICV_REG_SRE_EL1: hv_gic_icv_reg_t = 50789; +pub const hv_gic_icv_reg_t_HV_GIC_ICV_REG_IGRPEN0_EL1: hv_gic_icv_reg_t = 50790; +pub const hv_gic_icv_reg_t_HV_GIC_ICV_REG_IGRPEN1_EL1: hv_gic_icv_reg_t = 50791; +pub type hv_gic_icv_reg_t = u16; +pub const hv_gic_msi_reg_t_HV_GIC_REG_GICM_TYPER: hv_gic_msi_reg_t = 8; +pub const hv_gic_msi_reg_t_HV_GIC_REG_GICM_SET_SPI_NSR: hv_gic_msi_reg_t = 64; +pub type hv_gic_msi_reg_t = u16; +#[repr(C)] +#[derive(Debug, Copy, Clone)] pub struct hv_vm_config_s { _unused: [u8; 0], } pub type hv_vm_config_t = *mut hv_vm_config_s; -#[doc = " @typedef hv_ipa_t"] -#[doc = " @abstract Type of an Intermediate Physical Address (a guest physical address)"] pub type hv_ipa_t = u64; #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -1044,22 +4106,14 @@ pub struct hv_vcpu_config_s { _unused: [u8; 0], } pub type hv_vcpu_config_t = *mut hv_vcpu_config_s; -#[doc = " @typedef hv_vcpu_t"] -#[doc = " @abstract Type of a vcpu instance ID"] pub type hv_vcpu_t = u64; pub const hv_exit_reason_t_HV_EXIT_REASON_CANCELED: hv_exit_reason_t = 0; pub const hv_exit_reason_t_HV_EXIT_REASON_EXCEPTION: hv_exit_reason_t = 1; pub const hv_exit_reason_t_HV_EXIT_REASON_VTIMER_ACTIVATED: hv_exit_reason_t = 2; pub const hv_exit_reason_t_HV_EXIT_REASON_UNKNOWN: hv_exit_reason_t = 3; pub type hv_exit_reason_t = u32; -#[doc = " @typedef hv_exception_syndrome_t"] -#[doc = " @abstract Type of a vcpu exception syndrome (Corresponds to ESR_EL2)."] pub type hv_exception_syndrome_t = u64; -#[doc = " @typedef hv_exception_address_t"] -#[doc = " @abstract Type of a vcpu exception virtual address. (Corresponds to FAR_EL2)."] pub type hv_exception_address_t = u64; -#[doc = " @typedef hv_vcpu_exit_exception_t"] -#[doc = " @abstract Contains details of a vcpu exception."] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct hv_vcpu_exit_exception_t { @@ -1067,100 +4121,34 @@ pub struct hv_vcpu_exit_exception_t { pub virtual_address: hv_exception_address_t, pub physical_address: hv_ipa_t, } -#[test] -fn bindgen_test_layout_hv_vcpu_exit_exception_t() { - assert_eq!( - ::std::mem::size_of::(), - 24usize, - concat!("Size of: ", stringify!(hv_vcpu_exit_exception_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(hv_vcpu_exit_exception_t)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).syndrome as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(hv_vcpu_exit_exception_t), - "::", - stringify!(syndrome) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).virtual_address as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(hv_vcpu_exit_exception_t), - "::", - stringify!(virtual_address) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::())).physical_address as *const _ - as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(hv_vcpu_exit_exception_t), - "::", - stringify!(physical_address) - ) - ); -} -#[doc = " @typedef hv_vcpu_exit_t"] -#[doc = " @abstract Contains information about an exit from the vcpu to the host."] +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of hv_vcpu_exit_exception_t"] + [::std::mem::size_of::() - 24usize]; + ["Alignment of hv_vcpu_exit_exception_t"] + [::std::mem::align_of::() - 8usize]; + ["Offset of field: hv_vcpu_exit_exception_t::syndrome"] + [::std::mem::offset_of!(hv_vcpu_exit_exception_t, syndrome) - 0usize]; + ["Offset of field: hv_vcpu_exit_exception_t::virtual_address"] + [::std::mem::offset_of!(hv_vcpu_exit_exception_t, virtual_address) - 8usize]; + ["Offset of field: hv_vcpu_exit_exception_t::physical_address"] + [::std::mem::offset_of!(hv_vcpu_exit_exception_t, physical_address) - 16usize]; +}; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct hv_vcpu_exit_t { pub reason: hv_exit_reason_t, pub exception: hv_vcpu_exit_exception_t, } -#[test] -fn bindgen_test_layout_hv_vcpu_exit_t() { - assert_eq!( - ::std::mem::size_of::(), - 32usize, - concat!("Size of: ", stringify!(hv_vcpu_exit_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(hv_vcpu_exit_t)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).reason as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(hv_vcpu_exit_t), - "::", - stringify!(reason) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).exception as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(hv_vcpu_exit_t), - "::", - stringify!(exception) - ) - ); -} -#[doc = " @typedef hv_simd_fp_uchar16_t"] -#[doc = " @abstract Value of an ARM SIMD&FP register."] +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of hv_vcpu_exit_t"][::std::mem::size_of::() - 32usize]; + ["Alignment of hv_vcpu_exit_t"][::std::mem::align_of::() - 8usize]; + ["Offset of field: hv_vcpu_exit_t::reason"] + [::std::mem::offset_of!(hv_vcpu_exit_t, reason) - 0usize]; + ["Offset of field: hv_vcpu_exit_t::exception"] + [::std::mem::offset_of!(hv_vcpu_exit_t, exception) - 8usize]; +}; pub type hv_simd_fp_uchar16_t = u128; pub const hv_reg_t_HV_REG_X0: hv_reg_t = 0; pub const hv_reg_t_HV_REG_X1: hv_reg_t = 1; @@ -1311,6 +4299,7 @@ pub const hv_sys_reg_t_HV_SYS_REG_ID_AA64MMFR0_EL1: hv_sys_reg_t = 49208; pub const hv_sys_reg_t_HV_SYS_REG_ID_AA64MMFR1_EL1: hv_sys_reg_t = 49209; pub const hv_sys_reg_t_HV_SYS_REG_ID_AA64MMFR2_EL1: hv_sys_reg_t = 49210; pub const hv_sys_reg_t_HV_SYS_REG_SCTLR_EL1: hv_sys_reg_t = 49280; +pub const hv_sys_reg_t_HV_SYS_REG_ACTLR_EL1: hv_sys_reg_t = 49281; pub const hv_sys_reg_t_HV_SYS_REG_CPACR_EL1: hv_sys_reg_t = 49282; pub const hv_sys_reg_t_HV_SYS_REG_TTBR0_EL1: hv_sys_reg_t = 49408; pub const hv_sys_reg_t_HV_SYS_REG_TTBR1_EL1: hv_sys_reg_t = 49409; @@ -1345,6 +4334,34 @@ pub const hv_sys_reg_t_HV_SYS_REG_TPIDRRO_EL0: hv_sys_reg_t = 56963; pub const hv_sys_reg_t_HV_SYS_REG_CNTV_CTL_EL0: hv_sys_reg_t = 57113; pub const hv_sys_reg_t_HV_SYS_REG_CNTV_CVAL_EL0: hv_sys_reg_t = 57114; pub const hv_sys_reg_t_HV_SYS_REG_SP_EL1: hv_sys_reg_t = 57864; +pub const hv_sys_reg_t_HV_SYS_REG_CNTP_CTL_EL0: hv_sys_reg_t = 57105; +pub const hv_sys_reg_t_HV_SYS_REG_CNTP_CVAL_EL0: hv_sys_reg_t = 57106; +pub const hv_sys_reg_t_HV_SYS_REG_CNTP_TVAL_EL0: hv_sys_reg_t = 57104; +pub const hv_sys_reg_t_HV_SYS_REG_CNTHCTL_EL2: hv_sys_reg_t = 59144; +pub const hv_sys_reg_t_HV_SYS_REG_CNTHP_CTL_EL2: hv_sys_reg_t = 59153; +pub const hv_sys_reg_t_HV_SYS_REG_CNTHP_CVAL_EL2: hv_sys_reg_t = 59154; +pub const hv_sys_reg_t_HV_SYS_REG_CNTHP_TVAL_EL2: hv_sys_reg_t = 59152; +pub const hv_sys_reg_t_HV_SYS_REG_CNTVOFF_EL2: hv_sys_reg_t = 59139; +pub const hv_sys_reg_t_HV_SYS_REG_CPTR_EL2: hv_sys_reg_t = 57482; +pub const hv_sys_reg_t_HV_SYS_REG_ELR_EL2: hv_sys_reg_t = 57857; +pub const hv_sys_reg_t_HV_SYS_REG_ESR_EL2: hv_sys_reg_t = 58000; +pub const hv_sys_reg_t_HV_SYS_REG_FAR_EL2: hv_sys_reg_t = 58112; +pub const hv_sys_reg_t_HV_SYS_REG_HCR_EL2: hv_sys_reg_t = 57480; +pub const hv_sys_reg_t_HV_SYS_REG_HPFAR_EL2: hv_sys_reg_t = 58116; +pub const hv_sys_reg_t_HV_SYS_REG_MAIR_EL2: hv_sys_reg_t = 58640; +pub const hv_sys_reg_t_HV_SYS_REG_MDCR_EL2: hv_sys_reg_t = 57369; +pub const hv_sys_reg_t_HV_SYS_REG_SCTLR_EL2: hv_sys_reg_t = 57472; +pub const hv_sys_reg_t_HV_SYS_REG_SPSR_EL2: hv_sys_reg_t = 57856; +pub const hv_sys_reg_t_HV_SYS_REG_SP_EL2: hv_sys_reg_t = 61960; +pub const hv_sys_reg_t_HV_SYS_REG_TCR_EL2: hv_sys_reg_t = 57602; +pub const hv_sys_reg_t_HV_SYS_REG_TPIDR_EL2: hv_sys_reg_t = 59010; +pub const hv_sys_reg_t_HV_SYS_REG_TTBR0_EL2: hv_sys_reg_t = 57600; +pub const hv_sys_reg_t_HV_SYS_REG_TTBR1_EL2: hv_sys_reg_t = 57601; +pub const hv_sys_reg_t_HV_SYS_REG_VBAR_EL2: hv_sys_reg_t = 58880; +pub const hv_sys_reg_t_HV_SYS_REG_VMPIDR_EL2: hv_sys_reg_t = 57349; +pub const hv_sys_reg_t_HV_SYS_REG_VPIDR_EL2: hv_sys_reg_t = 57344; +pub const hv_sys_reg_t_HV_SYS_REG_VTCR_EL2: hv_sys_reg_t = 57610; +pub const hv_sys_reg_t_HV_SYS_REG_VTTBR_EL2: hv_sys_reg_t = 57608; pub type hv_sys_reg_t = u16; pub const hv_interrupt_type_t_HV_INTERRUPT_TYPE_IRQ: hv_interrupt_type_t = 0; pub const hv_interrupt_type_t_HV_INTERRUPT_TYPE_FIQ: hv_interrupt_type_t = 1; @@ -1353,14 +4370,6 @@ pub const hv_cache_type_t_HV_CACHE_TYPE_DATA: hv_cache_type_t = 0; pub const hv_cache_type_t_HV_CACHE_TYPE_INSTRUCTION: hv_cache_type_t = 1; pub type hv_cache_type_t = u32; extern "C" { - #[doc = " @function hv_vcpu_create"] - #[doc = " @abstract Creates a vCPU instance for the current thread"] - #[doc = " @param vcpu Pointer to the ID of the vCPU instance (written on success)"] - #[doc = " @param exit Pointer to pointer to the vcpu exit information"] - #[doc = " (written on success)"] - #[doc = " @param config Configuration."] - #[doc = " @result 0 on success or error code"] - #[doc = " @discussion Each thread can only have one vCPU associated at a time."] pub fn hv_vcpu_create( vcpu: *mut hv_vcpu_t, exit: *mut *mut hv_vcpu_exit_t, @@ -1368,45 +4377,15 @@ extern "C" { ) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_destroy"] - #[doc = " @abstract Destroys the vCPU instance associated with the current thread"] - #[doc = " @param vcpu ID of the vCPU instance"] - #[doc = " @result 0 on success or error code"] - #[doc = " @discussion"] - #[doc = " Must be called by the owning thread"] pub fn hv_vcpu_destroy(vcpu: hv_vcpu_t) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_get_reg"] - #[doc = " @abstract Returns the current value of a vCPU register."] - #[doc = " @param vcpu ID of the vCPU instance"] - #[doc = " @param reg ID of the register."] - #[doc = " @param value Pointer to the register value."] - #[doc = " @result 0 on success or error code"] - #[doc = " @discussion"] - #[doc = " Must be called by the owning thread"] pub fn hv_vcpu_get_reg(vcpu: hv_vcpu_t, reg: hv_reg_t, value: *mut u64) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_set_reg"] - #[doc = " @abstract Sets the value of a vCPU register."] - #[doc = " @param vcpu ID of the vCPU instance"] - #[doc = " @param reg ID of the register."] - #[doc = " @param value The register value."] - #[doc = " @result 0 on success or error code"] - #[doc = " @discussion"] - #[doc = " Must be called by the owning thread"] pub fn hv_vcpu_set_reg(vcpu: hv_vcpu_t, reg: hv_reg_t, value: u64) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_get_simd_fp_reg"] - #[doc = " @abstract Returns the current value of a vCPU SIMD&FP register"] - #[doc = " @param vcpu ID of the vCPU instance"] - #[doc = " @param reg ID of the SIMD&FP register."] - #[doc = " @param value Pointer to the register value."] - #[doc = " @result 0 on success or error code"] - #[doc = " @discussion"] - #[doc = " Must be called by the owning thread"] pub fn hv_vcpu_get_simd_fp_reg( vcpu: hv_vcpu_t, reg: hv_simd_fp_reg_t, @@ -1414,14 +4393,6 @@ extern "C" { ) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_set_simd_fp_reg"] - #[doc = " @abstract Sets the value of a vCPU SIMD&FP register"] - #[doc = " @param vcpu ID of the vCPU instance"] - #[doc = " @param reg ID of the register."] - #[doc = " @param value The register value."] - #[doc = " @result 0 on success or error code"] - #[doc = " @discussion"] - #[doc = " Must be called by the owning thread"] pub fn hv_vcpu_set_simd_fp_reg( vcpu: hv_vcpu_t, reg: hv_simd_fp_reg_t, @@ -1429,35 +4400,12 @@ extern "C" { ) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_get_sys_reg"] - #[doc = " @abstract Returns the current value of a vCPU system register"] - #[doc = " @param vcpu ID of the vCPU instance"] - #[doc = " @param reg ID of the system register."] - #[doc = " @param value Pointer to the system register value."] - #[doc = " @result 0 on success or error code"] - #[doc = " @discussion"] - #[doc = " Must be called by the owning thread"] pub fn hv_vcpu_get_sys_reg(vcpu: hv_vcpu_t, reg: hv_sys_reg_t, value: *mut u64) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_set_sys_reg"] - #[doc = " @abstract Sets the value of a vCPU system register"] - #[doc = " @param vcpu ID of the vCPU instance"] - #[doc = " @param reg ID of the system register."] - #[doc = " @param value The system register value."] - #[doc = " @result 0 on success or error code"] - #[doc = " @discussion"] - #[doc = " Must be called by the owning thread"] pub fn hv_vcpu_set_sys_reg(vcpu: hv_vcpu_t, reg: hv_sys_reg_t, value: u64) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_get_pending_interrupt."] - #[doc = " @abstract Gets pending interrupts for a vcpu."] - #[doc = " @param vcpu ID of the vcpu instance."] - #[doc = " @param type Interrupt type."] - #[doc = " @param pending Returns whether the interrupt is pending or not."] - #[doc = " @discussion"] - #[doc = " Must be called by the owning thread."] pub fn hv_vcpu_get_pending_interrupt( vcpu: hv_vcpu_t, type_: hv_interrupt_type_t, @@ -1465,15 +4413,6 @@ extern "C" { ) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_set_pending_interrupt."] - #[doc = " @abstract Sets pending interrupts for a vcpu."] - #[doc = " @param vcpu ID of the vcpu instance."] - #[doc = " @param type Interrupt type."] - #[doc = " @param pending Whether the interrupt is pending or not."] - #[doc = " @discussion"] - #[doc = " Must be called by the owning thread."] - #[doc = " The pending interrupts automatically cleared after hv_vcpu_run returns. It is expected that"] - #[doc = " hv_vcpu_set_pending_interrupt be called before every hv_vcpu_run to set pending interrupts."] pub fn hv_vcpu_set_pending_interrupt( vcpu: hv_vcpu_t, type_: hv_interrupt_type_t, @@ -1481,115 +4420,200 @@ extern "C" { ) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_get_trap_debug_exceptions."] - #[doc = " @abstract Get whether debug exceptions in the guest are trapped to the host."] - #[doc = " @param vcpu ID of the vcpu instance."] - #[doc = " @param value Pointer to the result."] - #[doc = " @discussion"] - #[doc = " Must be called by the owning thread."] pub fn hv_vcpu_get_trap_debug_exceptions(vcpu: hv_vcpu_t, value: *mut bool) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_set_trap_debug_exceptions."] - #[doc = " @abstract Set whether debug exceptions in the guest are trapped to the host."] - #[doc = " @param vcpu ID of the vcpu instance."] - #[doc = " @param value If true, debug exceptions in the guest are trapped to the host"] - #[doc = " @discussion"] - #[doc = " Must be called by the owning thread."] pub fn hv_vcpu_set_trap_debug_exceptions(vcpu: hv_vcpu_t, value: bool) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_get_trap_debug_reg_accesses."] - #[doc = " @abstract Get whether debug register accesses in the guest are trapped to the host."] - #[doc = " @param vcpu ID of the vcpu instance."] - #[doc = " @param value Pointer to the result."] - #[doc = " @discussion"] - #[doc = " Must be called by the owning thread."] - #[doc = " This includes the DBGBCR_EL1, DBGBVR_EL1, DBGWCR_EL1,"] - #[doc = " DBGWVR_EL1 and MDSCR_EL1 registers."] pub fn hv_vcpu_get_trap_debug_reg_accesses(vcpu: hv_vcpu_t, value: *mut bool) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_set_trap_debug_reg_accesses."] - #[doc = " @abstract Set whether debug register accesses in the guest are trapped to the host."] - #[doc = " @param vcpu ID of the vcpu instance."] - #[doc = " @param value If true, debug register accesses in the guest are trapped to the host."] - #[doc = " @discussion"] - #[doc = " Must be called by the owning thread."] - #[doc = " This includes the DBGBCR_EL1, DBGBVR_EL1, DBGWCR_EL1,"] - #[doc = " DBGWVR_EL1 and MDSCR_EL1 registers."] pub fn hv_vcpu_set_trap_debug_reg_accesses(vcpu: hv_vcpu_t, value: bool) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_run"] - #[doc = " @abstract Executes a vCPU"] - #[doc = " @param vcpu ID of the vCPU instance"] - #[doc = " @result 0 on success or error code"] pub fn hv_vcpu_run(vcpu: hv_vcpu_t) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpus_exit"] - #[doc = " @abstract Forces an immediate exit of a set of vcpus of the VM."] - #[doc = " @param vcpus Pointer to a list of vcpu IDs"] - #[doc = " @param vcpu_count Number of vcpus in the list"] - #[doc = " @result 0 on success or error code"] - #[doc = " @discussion"] - #[doc = " If a vcpu is not running, the next time hv_vcpu_run is called for the corresponding"] - #[doc = " vcpu, it will return immediately without entering the guest."] pub fn hv_vcpus_exit(vcpus: *mut hv_vcpu_t, vcpu_count: u32) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_get_exec_time"] - #[doc = " @abstract Returns the cumulative execution time of a vCPU in units of"] - #[doc = " mach_absolute_time()"] - #[doc = " @param vcpu vCPU ID"] - #[doc = " @param time Pointer to execution time value (written on success)"] - #[doc = " @result 0 on success or error code"] - #[doc = " @discussion"] - #[doc = " Must be called by the owning thread"] pub fn hv_vcpu_get_exec_time(vcpu: hv_vcpu_t, time: *mut u64) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_get_vtimer_mask"] - #[doc = " @abstract Gets the VTimer mask."] - #[doc = " @param vcpu ID of the vcpu instance."] - #[doc = " @param vtimer_is_masked Value of the mask."] - #[doc = " @result 0 on success or error code."] pub fn hv_vcpu_get_vtimer_mask(vcpu: hv_vcpu_t, vtimer_is_masked: *mut bool) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_set_vtimer_mask"] - #[doc = " @abstract Sets the VTimer mask."] - #[doc = " @param vcpu ID of the vcpu instance."] - #[doc = " @param vtimer_is_masked New value of the mask."] - #[doc = " @result 0 on success or error code."] pub fn hv_vcpu_set_vtimer_mask(vcpu: hv_vcpu_t, vtimer_is_masked: bool) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_get_vtimer_offset"] - #[doc = " @abstract Gets the VTimer offset."] - #[doc = " @param vcpu ID of the vCPU instance."] - #[doc = " @param vtimer_offset Pointer to VTimer offset. (Written on success)."] - #[doc = " @result 0 on success or error code."] - #[doc = " @discussion"] - #[doc = " This corresponds to the CNTVOFF_EL2 register."] pub fn hv_vcpu_get_vtimer_offset(vcpu: hv_vcpu_t, vtimer_offset: *mut u64) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_set_vtimer_offset"] - #[doc = " @abstract Sets the VTimer offset."] - #[doc = " @param vcpu ID of the vCPU instance."] - #[doc = " @param vtimer_offset New VTimer offset."] - #[doc = " @result 0 on success or error code."] - #[doc = " @discussion"] - #[doc = " This corresponds to the CNTVOFF_EL2 register."] pub fn hv_vcpu_set_vtimer_offset(vcpu: hv_vcpu_t, vtimer_offset: u64) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_config_create"] - #[doc = " @abstract Creates a vcpu configuration object."] - #[doc = " @result A new vcpu configuration object. This should be released with os_release"] - #[doc = " when no longer used."] + pub fn hv_gic_create(gic_config: hv_gic_config_t) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_set_spi(intid: u32, level: bool) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_send_msi(address: hv_ipa_t, intid: u32) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_get_distributor_reg( + reg: hv_gic_distributor_reg_t, + value: *mut u64, + ) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_set_distributor_reg(reg: hv_gic_distributor_reg_t, value: u64) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_get_redistributor_base( + vcpu: hv_vcpu_t, + redistributor_base_address: *mut hv_ipa_t, + ) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_get_redistributor_reg( + vcpu: hv_vcpu_t, + reg: hv_gic_redistributor_reg_t, + value: *mut u64, + ) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_set_redistributor_reg( + vcpu: hv_vcpu_t, + reg: hv_gic_redistributor_reg_t, + value: u64, + ) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_get_icc_reg( + vcpu: hv_vcpu_t, + reg: hv_gic_icc_reg_t, + value: *mut u64, + ) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_set_icc_reg(vcpu: hv_vcpu_t, reg: hv_gic_icc_reg_t, value: u64) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_get_ich_reg( + vcpu: hv_vcpu_t, + reg: hv_gic_ich_reg_t, + value: *mut u64, + ) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_set_ich_reg(vcpu: hv_vcpu_t, reg: hv_gic_ich_reg_t, value: u64) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_get_icv_reg( + vcpu: hv_vcpu_t, + reg: hv_gic_icv_reg_t, + value: *mut u64, + ) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_set_icv_reg(vcpu: hv_vcpu_t, reg: hv_gic_icv_reg_t, value: u64) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_get_msi_reg(reg: hv_gic_msi_reg_t, value: *mut u64) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_set_msi_reg(reg: hv_gic_msi_reg_t, value: u64) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_set_state( + gic_state_data: *const ::std::os::raw::c_void, + gic_state_size: usize, + ) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_reset() -> hv_return_t; +} +extern "C" { + pub fn hv_gic_config_create() -> hv_gic_config_t; +} +extern "C" { + pub fn hv_gic_config_set_distributor_base( + config: hv_gic_config_t, + distributor_base_address: hv_ipa_t, + ) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_config_set_redistributor_base( + config: hv_gic_config_t, + redistributor_base_address: hv_ipa_t, + ) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_config_set_msi_region_base( + config: hv_gic_config_t, + msi_region_base_address: hv_ipa_t, + ) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_config_set_msi_interrupt_range( + config: hv_gic_config_t, + msi_intid_base: u32, + msi_intid_count: u32, + ) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_get_distributor_size(distributor_size: *mut usize) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_get_distributor_base_alignment( + distributor_base_alignment: *mut usize, + ) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_get_redistributor_region_size( + redistributor_region_size: *mut usize, + ) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_get_redistributor_size(redistributor_size: *mut usize) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_get_redistributor_base_alignment( + redistributor_base_alignment: *mut usize, + ) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_get_msi_region_size(msi_region_size: *mut usize) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_get_msi_region_base_alignment( + msi_region_base_alignment: *mut usize, + ) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_get_spi_interrupt_range( + spi_intid_base: *mut u32, + spi_intid_count: *mut u32, + ) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_get_intid(interrupt: hv_gic_intid_t, intid: *mut u32) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_state_create() -> hv_gic_state_t; +} +extern "C" { + pub fn hv_gic_state_get_size(state: hv_gic_state_t, gic_state_size: *mut usize) -> hv_return_t; +} +extern "C" { + pub fn hv_gic_state_get_data( + state: hv_gic_state_t, + gic_state_data: *mut ::std::os::raw::c_void, + ) -> hv_return_t; +} +extern "C" { pub fn hv_vcpu_config_create() -> hv_vcpu_config_t; } pub const hv_feature_reg_t_HV_FEATURE_REG_ID_AA64DFR0_EL1: hv_feature_reg_t = 0; @@ -1606,12 +4630,6 @@ pub const hv_feature_reg_t_HV_FEATURE_REG_CLIDR_EL1: hv_feature_reg_t = 10; pub const hv_feature_reg_t_HV_FEATURE_REG_DCZID_EL0: hv_feature_reg_t = 11; pub type hv_feature_reg_t = u32; extern "C" { - #[doc = " @function hv_vcpu_config_get_feature_reg"] - #[doc = " @abstract For a vcpu configuration, return the given feature register value."] - #[doc = " @param config Configuration."] - #[doc = " @param feature_reg The feature register."] - #[doc = " @param value Pointer to the feature register value."] - #[doc = " @result 0 on success or error code."] pub fn hv_vcpu_config_get_feature_reg( config: hv_vcpu_config_t, feature_reg: hv_feature_reg_t, @@ -1619,12 +4637,6 @@ extern "C" { ) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vcpu_config_get_ccs_idr_el1_sys_reg"] - #[doc = " @abstract For a vcpu configuration, return the given CCSIDR_EL1 values for a given cache type"] - #[doc = " @param config Configuration."] - #[doc = " @param cache_type The cache type."] - #[doc = " @param value Pointer to the CCSIDR_EL1 register values."] - #[doc = " @result 0 on success or error code."] pub fn hv_vcpu_config_get_ccsidr_el1_sys_reg_values( config: hv_vcpu_config_t, cache_type: hv_cache_type_t, @@ -1632,57 +4644,69 @@ extern "C" { ) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vm_get_max_vcpu_count"] - #[doc = " @abstract Return the max number of vcpus supported."] - #[doc = " @param max_vcpu_count pointer to the max vcpu count."] - #[doc = " @result 0 on success or error code"] pub fn hv_vm_get_max_vcpu_count(max_vcpu_count: *mut u32) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vm_create"] - #[doc = " @abstract Creates a VM instance for the current process."] - #[doc = " @param config Configuration. Pass NULL for the default configuration."] - #[doc = " @result 0 on success or error code"] pub fn hv_vm_create(config: hv_vm_config_t) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vm_destroy"] - #[doc = " @abstract Destroys the VM instance associated with the current process."] - #[doc = " @result 0 on success or error code"] pub fn hv_vm_destroy() -> hv_return_t; } extern "C" { - #[doc = " @function hv_vm_map"] - #[doc = " @abstract Maps a region in the virtual address space of the current process"] - #[doc = " into the guest physical address space of the VM."] - #[doc = " @param addr Page aligned virtual address in the current process"] - #[doc = " @param ipa Page aligned address in the guest physical address space"] - #[doc = " @param size Size in bytes of the region to be mapped (must be a multiple of the page size)"] - #[doc = " @param flags READ, WRITE and EXECUTE permissions of the region"] - #[doc = " @result 0 on success or error code"] pub fn hv_vm_map( addr: *mut ::std::os::raw::c_void, ipa: hv_ipa_t, - size: size_t, + size: usize, flags: hv_memory_flags_t, ) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vm_unmap"] - #[doc = " @abstract Unmaps a region in the guest physical address space of the VM."] - #[doc = " @param ipa Page aligned address in the guest physical address space"] - #[doc = " @param size Size in bytes of the region to be unmapped (must be a multiple of the page size)"] - #[doc = " @result 0 on success or error code"] - pub fn hv_vm_unmap(ipa: hv_ipa_t, size: size_t) -> hv_return_t; + pub fn hv_vm_unmap(ipa: hv_ipa_t, size: usize) -> hv_return_t; +} +extern "C" { + pub fn hv_vm_protect(ipa: hv_ipa_t, size: usize, flags: hv_memory_flags_t) -> hv_return_t; +} +extern "C" { + pub fn hv_vm_config_create() -> hv_vm_config_t; +} +extern "C" { + pub fn hv_vm_config_get_max_ipa_size(ipa_bit_length: *mut u32) -> hv_return_t; +} +extern "C" { + pub fn hv_vm_config_get_default_ipa_size(ipa_bit_length: *mut u32) -> hv_return_t; +} +extern "C" { + pub fn hv_vm_config_set_ipa_size(config: hv_vm_config_t, ipa_bit_length: u32) -> hv_return_t; +} +extern "C" { + pub fn hv_vm_config_get_ipa_size( + config: hv_vm_config_t, + ipa_bit_length: *mut u32, + ) -> hv_return_t; +} +extern "C" { + pub fn hv_vm_config_get_el2_supported(el2_supported: *mut bool) -> hv_return_t; +} +extern "C" { + pub fn hv_vm_config_get_el2_enabled( + config: hv_vm_config_t, + el2_enabled: *mut bool, + ) -> hv_return_t; +} +extern "C" { + pub fn hv_vm_config_set_el2_enabled(config: hv_vm_config_t, el2_enabled: bool) -> hv_return_t; +} +pub const HV_ALLOCATE_DEFAULT: _bindgen_ty_3 = 0; +pub type _bindgen_ty_3 = ::std::os::raw::c_uint; +pub type hv_allocate_flags_t = u64; +extern "C" { + pub fn hv_vm_allocate( + uvap: *mut *mut ::std::os::raw::c_void, + size: usize, + flags: hv_allocate_flags_t, + ) -> hv_return_t; } extern "C" { - #[doc = " @function hv_vm_protect"] - #[doc = " @abstract Modifies the permissions of a region in the guest physical"] - #[doc = " address space of the VM."] - #[doc = " @param ipa Page aligned address in the guest physical address space"] - #[doc = " @param size Size in bytes of the region to be modified (must be a multiple of the page size)"] - #[doc = " @param flags New READ, WRITE and EXECUTE permissions of the region"] - #[doc = " @result 0 on success or error code"] - pub fn hv_vm_protect(ipa: hv_ipa_t, size: size_t, flags: hv_memory_flags_t) -> hv_return_t; + pub fn hv_vm_deallocate(uva: *mut ::std::os::raw::c_void, size: usize) -> hv_return_t; } pub type __builtin_va_list = *mut ::std::os::raw::c_char; diff --git a/src/hvf/src/lib.rs b/src/hvf/src/lib.rs index c0c1e93d9..bf2ceb2b8 100644 --- a/src/hvf/src/lib.rs +++ b/src/hvf/src/lib.rs @@ -159,6 +159,7 @@ pub struct HvfVm {} impl HvfVm { pub fn new() -> Result { let ret = unsafe { hv_vm_create(std::ptr::null_mut()) }; + if ret != HV_SUCCESS { Err(Error::VmCreate) } else { @@ -176,7 +177,7 @@ impl HvfVm { hv_vm_map( host_start_addr as *mut core::ffi::c_void, guest_start_addr, - size, + size.try_into().unwrap(), (HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC).into(), ) }; @@ -188,7 +189,7 @@ impl HvfVm { } pub fn unmap_memory(&self, guest_start_addr: u64, size: u64) -> Result<(), Error> { - let ret = unsafe { hv_vm_unmap(guest_start_addr, size) }; + let ret = unsafe { hv_vm_unmap(guest_start_addr, size.try_into().unwrap()) }; if ret != HV_SUCCESS { Err(Error::MemoryUnmap) } else { From f796d4d8850f5b347eb62fe9c6b799d5fde5401d Mon Sep 17 00:00:00 2001 From: Sergio Lopez Date: Mon, 10 Mar 2025 18:35:07 +0100 Subject: [PATCH 40/40] devices: implement support for in-kernel HVF GICv3 macOS 15 extended Hypervisor.framework with an in-kernel HVF GICv3 device. Using it reduces the cost of GIC operations and enables us to use nested virt. Add support for it and enable it automatically when the functions are found in HVF. Signed-off-by: Sergio Lopez --- Cargo.lock | 2 + src/devices/Cargo.toml | 1 + src/devices/src/legacy/hvfgicv3.rs | 184 +++++++++++++++++++++++++ src/devices/src/legacy/mod.rs | 4 + src/hvf/Cargo.toml | 1 + src/hvf/src/lib.rs | 6 +- src/vmm/src/builder.rs | 24 +++- src/vmm/src/device_manager/hvf/mmio.rs | 10 +- src/vmm/src/macos/vstate.rs | 4 + 9 files changed, 225 insertions(+), 11 deletions(-) create mode 100644 src/devices/src/legacy/hvfgicv3.rs diff --git a/Cargo.lock b/Cargo.lock index ea7f0ef81..be3813cd5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -389,6 +389,7 @@ dependencies = [ "kvm-bindings", "kvm-ioctls", "libc", + "libloading", "log", "lru", "nix 0.24.3", @@ -639,6 +640,7 @@ dependencies = [ "arch", "crossbeam-channel", "env_logger", + "libloading", "log", ] diff --git a/src/devices/Cargo.toml b/src/devices/Cargo.toml index 8b2157166..f3a994e6f 100644 --- a/src/devices/Cargo.toml +++ b/src/devices/Cargo.toml @@ -19,6 +19,7 @@ bitflags = "1.2.0" crossbeam-channel = "0.5" env_logger = "0.9.0" libc = ">=0.2.39" +libloading = "0.8" log = "0.4.0" nix = { version = "0.24.1", features = ["poll"] } pw = { package = "pipewire", version = "0.8.0", optional = true } diff --git a/src/devices/src/legacy/hvfgicv3.rs b/src/devices/src/legacy/hvfgicv3.rs new file mode 100644 index 000000000..d401274ee --- /dev/null +++ b/src/devices/src/legacy/hvfgicv3.rs @@ -0,0 +1,184 @@ +// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +use std::io; +use std::sync::LazyLock; + +use crate::bus::BusDevice; +use crate::legacy::gic::GICDevice; +use crate::legacy::irqchip::IrqChipT; +use crate::Error as DeviceError; + +use hvf::bindings::{hv_gic_config_t, hv_ipa_t, hv_return_t, HV_SUCCESS}; +use hvf::Error; +use utils::eventfd::EventFd; + +// Device trees specific constants +const ARCH_GIC_V3_MAINT_IRQ: u32 = 9; + +pub struct HvfGicBindings { + hv_gic_create: + libloading::Symbol<'static, unsafe extern "C" fn(hv_gic_config_t) -> hv_return_t>, + hv_gic_config_create: libloading::Symbol<'static, unsafe extern "C" fn() -> hv_gic_config_t>, + hv_gic_config_set_distributor_base: + libloading::Symbol<'static, unsafe extern "C" fn(hv_gic_config_t, hv_ipa_t) -> hv_return_t>, + hv_gic_config_set_redistributor_base: + libloading::Symbol<'static, unsafe extern "C" fn(hv_gic_config_t, hv_ipa_t) -> hv_return_t>, + hv_gic_get_distributor_size: + libloading::Symbol<'static, unsafe extern "C" fn(*mut usize) -> hv_return_t>, + hv_gic_get_redistributor_size: + libloading::Symbol<'static, unsafe extern "C" fn(*mut usize) -> hv_return_t>, + hv_gic_set_spi: libloading::Symbol<'static, unsafe extern "C" fn(u32, bool) -> hv_return_t>, +} + +pub struct HvfGicV3 { + bindings: HvfGicBindings, + + /// GIC device properties, to be used for setting up the fdt entry + properties: [u64; 4], + + /// Number of CPUs handled by the device + vcpu_count: u64, +} + +static HVF: LazyLock = LazyLock::new(|| unsafe { + libloading::Library::new( + "/System/Library/Frameworks/Hypervisor.framework/Versions/A/Hypervisor", + ) + .unwrap() +}); + +impl HvfGicV3 { + pub fn new(vcpu_count: u64) -> Result { + let bindings = unsafe { + HvfGicBindings { + hv_gic_create: HVF.get(b"hv_gic_create").map_err(Error::FindSymbol)?, + hv_gic_config_create: HVF + .get(b"hv_gic_config_create") + .map_err(Error::FindSymbol)?, + hv_gic_config_set_distributor_base: HVF + .get(b"hv_gic_config_set_distributor_base") + .map_err(Error::FindSymbol)?, + hv_gic_config_set_redistributor_base: HVF + .get(b"hv_gic_config_set_redistributor_base") + .map_err(Error::FindSymbol)?, + hv_gic_get_distributor_size: HVF + .get(b"hv_gic_get_distributor_size") + .map_err(Error::FindSymbol)?, + hv_gic_get_redistributor_size: HVF + .get(b"hv_gic_get_redistributor_size") + .map_err(Error::FindSymbol)?, + hv_gic_set_spi: HVF.get(b"hv_gic_set_spi").map_err(Error::FindSymbol)?, + } + }; + + let mut dist_size: usize = 0; + let ret = unsafe { (bindings.hv_gic_get_distributor_size)(&mut dist_size) }; + if ret != HV_SUCCESS { + return Err(Error::VmCreate); + } + let dist_size = dist_size as u64; + + let mut redist_size: usize = 0; + let ret = unsafe { (bindings.hv_gic_get_redistributor_size)(&mut redist_size) }; + if ret != HV_SUCCESS { + return Err(Error::VmCreate); + } + + let redists_size = redist_size as u64 * vcpu_count; + let dist_addr = arch::MMIO_MEM_START - dist_size - redists_size; + let redists_addr = arch::MMIO_MEM_START - redists_size; + + let gic_config = unsafe { (bindings.hv_gic_config_create)() }; + let ret = unsafe { (bindings.hv_gic_config_set_distributor_base)(gic_config, dist_addr) }; + if ret != HV_SUCCESS { + return Err(Error::VmCreate); + } + + let ret = unsafe { + (bindings.hv_gic_config_set_redistributor_base)( + gic_config, + arch::MMIO_MEM_START - redists_size, + ) + }; + if ret != HV_SUCCESS { + return Err(Error::VmCreate); + } + + let ret = unsafe { (bindings.hv_gic_create)(gic_config) }; + if ret != HV_SUCCESS { + return Err(Error::VmCreate); + } + + Ok(Self { + bindings, + properties: [dist_addr, dist_size, redists_addr, redists_size], + vcpu_count, + }) + } +} + +impl IrqChipT for HvfGicV3 { + fn get_mmio_addr(&self) -> u64 { + 0 + } + + fn get_mmio_size(&self) -> u64 { + 0 + } + + fn set_irq( + &self, + irq_line: Option, + _interrupt_evt: Option<&EventFd>, + ) -> Result<(), DeviceError> { + if let Some(irq_line) = irq_line { + let ret = unsafe { (self.bindings.hv_gic_set_spi)(irq_line, true) }; + if ret != HV_SUCCESS { + Err(DeviceError::FailedSignalingUsedQueue(io::Error::new( + io::ErrorKind::Other, + "HVF returned error when setting SPI", + ))) + } else { + Ok(()) + } + } else { + Err(DeviceError::FailedSignalingUsedQueue(io::Error::new( + io::ErrorKind::InvalidData, + "IRQ not line configured", + ))) + } + } +} + +impl BusDevice for HvfGicV3 { + fn read(&mut self, _vcpuid: u64, _offset: u64, _data: &mut [u8]) { + unreachable!("MMIO operations are managed in-kernel"); + } + + fn write(&mut self, _vcpuid: u64, _offset: u64, _data: &[u8]) { + unreachable!("MMIO operations are managed in-kernel"); + } +} + +impl GICDevice for HvfGicV3 { + fn device_properties(&self) -> Vec { + self.properties.to_vec() + } + + fn vcpu_count(&self) -> u64 { + self.vcpu_count + } + + fn fdt_compatibility(&self) -> String { + "arm,gic-v3".to_string() + } + + fn fdt_maint_irq(&self) -> u32 { + ARCH_GIC_V3_MAINT_IRQ + } + + fn version(&self) -> u32 { + 7 + } +} diff --git a/src/devices/src/legacy/mod.rs b/src/devices/src/legacy/mod.rs index f90fb7f8a..65890cf96 100644 --- a/src/devices/src/legacy/mod.rs +++ b/src/devices/src/legacy/mod.rs @@ -8,6 +8,8 @@ pub mod gic; #[cfg(target_os = "macos")] mod gicv3; +#[cfg(all(target_os = "macos", target_arch = "aarch64"))] +mod hvfgicv3; mod i8042; mod irqchip; #[cfg(all(target_os = "linux", target_arch = "aarch64"))] @@ -33,6 +35,8 @@ use aarch64::serial; pub use self::gicv3::GicV3; #[cfg(target_arch = "aarch64")] pub use self::gpio::Gpio; +#[cfg(all(target_os = "macos", target_arch = "aarch64"))] +pub use self::hvfgicv3::HvfGicV3; pub use self::i8042::Error as I8042DeviceError; pub use self::i8042::I8042Device; pub use self::irqchip::{IrqChip, IrqChipDevice, IrqChipT}; diff --git a/src/hvf/Cargo.toml b/src/hvf/Cargo.toml index 31249d30d..bd3043177 100644 --- a/src/hvf/Cargo.toml +++ b/src/hvf/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [dependencies] crossbeam-channel = "0.5" +libloading = "0.8" log = "0.4.0" env_logger = "0.9.0" diff --git a/src/hvf/src/lib.rs b/src/hvf/src/lib.rs index bf2ceb2b8..cadd8a407 100644 --- a/src/hvf/src/lib.rs +++ b/src/hvf/src/lib.rs @@ -7,7 +7,7 @@ #[allow(non_snake_case)] #[allow(non_upper_case_globals)] #[allow(deref_nullptr)] -mod bindings; +pub mod bindings; use bindings::*; @@ -51,8 +51,9 @@ const EC_SYSTEMREGISTERTRAP: u64 = 0x18; const EC_DATAABORT: u64 = 0x24; const EC_AA64_BKPT: u64 = 0x3c; -#[derive(Clone, Debug)] +#[derive(Debug)] pub enum Error { + FindSymbol(libloading::Error), MemoryMap, MemoryUnmap, VcpuCreate, @@ -73,6 +74,7 @@ impl Display for Error { use self::Error::*; match self { + FindSymbol(ref err) => write!(f, "Couldn't find symbol in HVF library: {}", err), MemoryMap => write!(f, "Error registering memory region in HVF"), MemoryUnmap => write!(f, "Error unregistering memory region in HVF"), VcpuCreate => write!(f, "Error creating HVF vCPU instance"), diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index c7517da5a..0504f6f7d 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -23,13 +23,13 @@ use crate::device_manager::legacy::PortIODeviceManager; use crate::device_manager::mmio::MMIODeviceManager; use crate::resources::VmResources; use crate::vmm_config::external_kernel::{ExternalKernel, KernelFormat}; -#[cfg(target_os = "macos")] -use devices::legacy::GicV3; #[cfg(target_arch = "x86_64")] use devices::legacy::KvmIoapic; use devices::legacy::Serial; #[cfg(target_os = "macos")] use devices::legacy::VcpuList; +#[cfg(target_os = "macos")] +use devices::legacy::{GicV3, HvfGicV3}; use devices::legacy::{IrqChip, IrqChipDevice}; #[cfg(all(target_os = "linux", target_arch = "aarch64"))] use devices::legacy::{IrqChipDevice, KvmGicV3}; @@ -90,6 +90,9 @@ static EDK2_BINARY: &[u8] = include_bytes!("../../../edk2/KRUN_EFI.silent.fd"); pub enum StartMicrovmError { /// Unable to attach block device to Vmm. AttachBlockDevice(io::Error), + #[cfg(target_os = "macos")] + /// Failed to create HVF in-kernel IrqChip. + CreateHvfIrqChip(hvf::Error), #[cfg(target_os = "linux")] /// Failed to create KVM in-kernel IrqChip. CreateKvmIrqChip(kvm_ioctls::Error), @@ -209,6 +212,10 @@ impl Display for StartMicrovmError { AttachBlockDevice(ref err) => { write!(f, "Unable to attach block device to Vmm. Error: {err}") } + #[cfg(target_os = "macos")] + CreateHvfIrqChip(ref err) => { + write!(f, "Cannot create HVF in-kernel IrqChip: {err}") + } #[cfg(target_os = "linux")] CreateKvmIrqChip(ref err) => { write!(f, "Cannot create KVM in-kernel IrqChip: {err}") @@ -735,9 +742,15 @@ pub fn build_microvm( #[cfg(all(target_arch = "aarch64", target_os = "macos"))] { - intc = Arc::new(Mutex::new(IrqChipDevice::new(Box::new(GicV3::new( - vcpu_list.clone(), - ))))); + intc = { + // If the system supports the in-kernel GIC, use it. Otherwise, fall back to the + // userspace implementation. + let gic = match HvfGicV3::new(vm_resources.vm_config().vcpu_count.unwrap() as u64) { + Ok(hvfgic) => IrqChipDevice::new(Box::new(hvfgic)), + Err(_) => IrqChipDevice::new(Box::new(GicV3::new(vcpu_list.clone()))), + }; + Arc::new(Mutex::new(gic)) + }; vcpus = create_vcpus_aarch64( &vm, @@ -1294,7 +1307,6 @@ fn load_cmdline(vmm: &Vmm) -> std::result::Result<(), StartMicrovmError> { #[cfg(all(target_os = "linux", not(feature = "tee")))] pub(crate) fn setup_vm( guest_memory: &GuestMemoryMmap, - _vcpu_count: u8, ) -> std::result::Result { let kvm = KvmContext::new() .map_err(Error::KvmContext) diff --git a/src/vmm/src/device_manager/hvf/mmio.rs b/src/vmm/src/device_manager/hvf/mmio.rs index f6f356242..f526ddce3 100644 --- a/src/vmm/src/device_manager/hvf/mmio.rs +++ b/src/vmm/src/device_manager/hvf/mmio.rs @@ -265,9 +265,13 @@ impl MMIODeviceManager { (intc.get_mmio_addr(), intc.get_mmio_size()) }; - self.bus - .insert(intc, mmio_addr, mmio_size) - .map_err(Error::BusError)?; + // The in-kernel GIC reports a size of 0 to tell us we don't need to map + // anything in the guest. + if mmio_size != 0 { + self.bus + .insert(intc, mmio_addr, mmio_size) + .map_err(Error::BusError)?; + } Ok(()) } diff --git a/src/vmm/src/macos/vstate.rs b/src/vmm/src/macos/vstate.rs index 38a8bb6ed..2919894b2 100644 --- a/src/vmm/src/macos/vstate.rs +++ b/src/vmm/src/macos/vstate.rs @@ -104,6 +104,10 @@ impl Vm { Ok(Vm { hvf_vm }) } + pub fn hvf_vm(&self) -> &HvfVm { + &self.hvf_vm + } + /// Initializes the guest memory. pub fn memory_init(&mut self, guest_mem: &GuestMemoryMmap) -> Result<()> { for region in guest_mem.iter() {