diff --git a/README.md b/README.md index b4b170bdb..6397fb369 100644 --- a/README.md +++ b/README.md @@ -180,7 +180,7 @@ To build the kernel: # Clone the Cloud Hypervisor Linux branch $ pushd $CLOUDH -$ git clone --depth 1 https://github.com/cloud-hypervisor/linux.git -b ch-5.12 linux-cloud-hypervisor +$ git clone --depth 1 https://github.com/cloud-hypervisor/linux.git -b ch-5.13-rc5 linux-cloud-hypervisor $ pushd linux-cloud-hypervisor # Use the cloud-hypervisor kernel config to build your kernel diff --git a/resources/linux-config-x86_64 b/resources/linux-config-x86_64 index cdd8709cc..6628b002e 100644 --- a/resources/linux-config-x86_64 +++ b/resources/linux-config-x86_64 @@ -1,11 +1,13 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86 5.12.0 Kernel Configuration +# Linux/x86 5.13.0-rc5 Kernel Configuration # -CONFIG_CC_VERSION_TEXT="gcc (GCC) 10.2.1 20201125 (Red Hat 10.2.1-9)" +CONFIG_CC_VERSION_TEXT="gcc (Ubuntu 10.2.0-13ubuntu1) 10.2.0" CONFIG_CC_IS_GCC=y -CONFIG_GCC_VERSION=100201 +CONFIG_GCC_VERSION=100200 CONFIG_CLANG_VERSION=0 +CONFIG_AS_IS_GNU=y +CONFIG_AS_VERSION=23500 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=23500 CONFIG_LLD_VERSION=0 @@ -97,6 +99,18 @@ CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y # end of Timers subsystem +CONFIG_BPF=y +CONFIG_HAVE_EBPF_JIT=y +CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y + +# +# BPF subsystem +# +CONFIG_BPF_SYSCALL=y +# CONFIG_BPF_UNPRIV_DEFAULT_OFF is not set +# CONFIG_BPF_PRELOAD is not set +# end of BPF subsystem + CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set @@ -173,6 +187,7 @@ CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_PERF=y CONFIG_CGROUP_BPF=y +# CONFIG_CGROUP_MISC is not set # CONFIG_CGROUP_DEBUG is not set CONFIG_SOCK_CGROUP_DATA=y CONFIG_NAMESPACES=y @@ -202,7 +217,6 @@ CONFIG_LD_ORPHAN_WARN=y CONFIG_SYSCTL=y CONFIG_SYSCTL_EXCEPTION_TRACE=y CONFIG_HAVE_PCSPKR_PLATFORM=y -CONFIG_BPF=y CONFIG_EXPERT=y CONFIG_MULTIUSER=y CONFIG_SGETMASK_SYSCALL=y @@ -226,14 +240,12 @@ CONFIG_AIO=y CONFIG_IO_URING=y CONFIG_ADVISE_SYSCALLS=y CONFIG_HAVE_ARCH_USERFAULTFD_WP=y +CONFIG_HAVE_ARCH_USERFAULTFD_MINOR=y CONFIG_MEMBARRIER=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set CONFIG_KALLSYMS_ABSOLUTE_PERCPU=y CONFIG_KALLSYMS_BASE_RELATIVE=y -CONFIG_BPF_SYSCALL=y -CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y -# CONFIG_BPF_PRELOAD is not set CONFIG_USERFAULTFD=y CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y # CONFIG_KCMP is not set @@ -280,7 +292,6 @@ CONFIG_GENERIC_BUG=y CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_ARCH_HAS_CPU_RELAX=y -CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y CONFIG_ARCH_HAS_FILTER_PGPROT=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y @@ -447,12 +458,8 @@ CONFIG_HAVE_LIVEPATCH=y # end of Processor type and features CONFIG_ARCH_HAS_ADD_PAGES=y -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y CONFIG_USE_PERCPU_NUMA_NODE_ID=y -CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y -CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y -CONFIG_ARCH_ENABLE_THP_MIGRATION=y # # Power management and ACPI options @@ -520,6 +527,7 @@ CONFIG_HAVE_ACPI_APEI_NMI=y # CONFIG_ACPI_DPTF is not set # CONFIG_ACPI_CONFIGFS is not set # CONFIG_PMIC_OPREGION is not set +CONFIG_ACPI_VIOT=y CONFIG_X86_PM_TIMER=y # @@ -734,6 +742,8 @@ CONFIG_HAVE_RELIABLE_STACKTRACE=y # CONFIG_COMPAT_32BIT_TIME is not set CONFIG_HAVE_ARCH_VMAP_STACK=y CONFIG_VMAP_STACK=y +CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET=y +# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y CONFIG_STRICT_KERNEL_RWX=y CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y @@ -857,19 +867,24 @@ CONFIG_HAVE_FAST_GUP=y CONFIG_NUMA_KEEP_MEMINFO=y CONFIG_MEMORY_ISOLATION=y CONFIG_HAVE_BOOTMEM_INFO_NODE=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTPLUG_SPARSE=y CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_MEMORY_HOTREMOVE=y +CONFIG_MHP_MEMMAP_ON_MEMORY=y CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y CONFIG_MEMORY_BALLOON=y CONFIG_BALLOON_COMPACTION=y CONFIG_COMPACTION=y CONFIG_PAGE_REPORTING=y CONFIG_MIGRATION=y +CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y +CONFIG_ARCH_ENABLE_THP_MIGRATION=y CONFIG_CONTIG_ALLOC=y CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y CONFIG_MMU_NOTIFIER=y CONFIG_KSM=y @@ -903,6 +918,7 @@ CONFIG_ZSMALLOC_STAT=y CONFIG_GENERIC_EARLY_IOREMAP=y # CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set # CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y CONFIG_ARCH_HAS_PTE_DEVMAP=y CONFIG_ZONE_DEVICE=y CONFIG_DEV_PAGEMAP_OPS=y @@ -974,7 +990,6 @@ CONFIG_NET_PTP_CLASSIFY=y # CONFIG_ATM is not set # CONFIG_L2TP is not set # CONFIG_BRIDGE is not set -CONFIG_HAVE_NET_DSA=y # CONFIG_NET_DSA is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set @@ -1002,6 +1017,7 @@ CONFIG_VIRTIO_VSOCKETS_COMMON=y # CONFIG_NET_L3_MASTER_DEV is not set # CONFIG_QRTR is not set # CONFIG_NET_NCSI is not set +CONFIG_PCPU_DEV_REFCNT=y CONFIG_RPS=y CONFIG_RFS_ACCEL=y CONFIG_SOCK_RX_QUEUE_MAPPING=y @@ -1039,7 +1055,6 @@ CONFIG_GRO_CELLS=y CONFIG_NET_SOCK_MSG=y CONFIG_FAILOVER=y # CONFIG_ETHTOOL_NETLINK is not set -CONFIG_HAVE_EBPF_JIT=y # # Device Drivers @@ -1182,7 +1197,6 @@ CONFIG_ZRAM_DEF_COMP_LZORLE=y CONFIG_ZRAM_DEF_COMP="lzo-rle" # CONFIG_ZRAM_WRITEBACK is not set # CONFIG_ZRAM_MEMORY_TRACKING is not set -# CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 CONFIG_BLK_DEV_CRYPTOLOOP=y @@ -1203,6 +1217,7 @@ CONFIG_VIRTIO_BLK=y # # CONFIG_BLK_DEV_NVME is not set # CONFIG_NVME_FC is not set +# CONFIG_NVME_TCP is not set # CONFIG_NVME_TARGET is not set # end of NVME Support @@ -1216,9 +1231,9 @@ CONFIG_VIRTIO_BLK=y # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_HP_ILO is not set # CONFIG_SRAM is not set +# CONFIG_DW_XDATA_PCIE is not set # CONFIG_PCI_ENDPOINT_TEST is not set # CONFIG_XILINX_SDFEC is not set -# CONFIG_PVPANIC is not set # CONFIG_C2PORT is not set # @@ -1248,6 +1263,7 @@ CONFIG_VIRTIO_BLK=y # CONFIG_MISC_RTSX_PCI is not set # CONFIG_HABANA_AI is not set # CONFIG_UACCE is not set +# CONFIG_PVPANIC is not set # end of Misc devices CONFIG_HAVE_IDE=y @@ -1295,13 +1311,6 @@ CONFIG_VETH=y CONFIG_VIRTIO_NET=y # CONFIG_NLMON is not set # CONFIG_ARCNET is not set - -# -# Distributed Switch Architecture drivers -# -# CONFIG_NET_DSA_MV88E6XXX_PTP is not set -# end of Distributed Switch Architecture drivers - # CONFIG_ETHERNET is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -1322,6 +1331,7 @@ CONFIG_VIRTIO_NET=y # # CONFIG_WLAN is not set # CONFIG_WAN is not set +# CONFIG_WWAN is not set # CONFIG_VMXNET3 is not set # CONFIG_FUJITSU_ES is not set # CONFIG_NETDEVSIM is not set @@ -1444,7 +1454,6 @@ CONFIG_SERIAL_ARC_NR_PORTS=1 # CONFIG_N_GSM is not set # CONFIG_NOZOMI is not set # CONFIG_NULL_TTY is not set -# CONFIG_TRACE_SINK is not set CONFIG_HVC_DRIVER=y CONFIG_SERIAL_DEV_BUS=y CONFIG_SERIAL_DEV_CTRL_TTYPORT=y @@ -1462,7 +1471,6 @@ CONFIG_HW_RANDOM_VIRTIO=y # CONFIG_APPLICOM is not set # CONFIG_MWAVE is not set CONFIG_DEVMEM=y -# CONFIG_DEVKMEM is not set CONFIG_NVRAM=y CONFIG_RAW_DRIVER=y CONFIG_MAX_RAW_DEVS=256 @@ -1549,6 +1557,7 @@ CONFIG_X86_THERMAL_VECTOR=y # end of ACPI INT340X thermal drivers # CONFIG_INTEL_PCH_THERMAL is not set +# CONFIG_INTEL_TCC_COOLING is not set # end of Intel thermal drivers CONFIG_WATCHDOG=y @@ -1634,7 +1643,6 @@ CONFIG_BCMA_POSSIBLE=y # CONFIG_MFD_MT6397 is not set # CONFIG_MFD_RDC321X is not set # CONFIG_MFD_SM501 is not set -# CONFIG_ABX500_CORE is not set # CONFIG_MFD_SYSCON is not set # CONFIG_MFD_TI_AM335X_TSCADC is not set # CONFIG_MFD_TQMX86 is not set @@ -1806,6 +1814,7 @@ CONFIG_HID_REDRAGON=y # CONFIG_HID_PRIMAX is not set # CONFIG_HID_SAITEK is not set # CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SEMITEK is not set # CONFIG_HID_SPEEDLINK is not set # CONFIG_HID_STEAM is not set # CONFIG_HID_STEELSERIES is not set @@ -1815,7 +1824,6 @@ CONFIG_HID_REDRAGON=y # CONFIG_HID_SMARTJOYPLUS is not set # CONFIG_HID_TIVO is not set # CONFIG_HID_TOPSEED is not set -# CONFIG_HID_THRUSTMASTER is not set # CONFIG_HID_UDRAW_PS3 is not set # CONFIG_HID_XINMO is not set # CONFIG_HID_ZEROPLUS is not set @@ -1915,6 +1923,7 @@ CONFIG_VFIO_PCI_INTX=y CONFIG_IRQ_BYPASS_MANAGER=y # CONFIG_VIRT_DRIVERS is not set CONFIG_VIRTIO=y +CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS=y CONFIG_VIRTIO_PCI_LIB=y CONFIG_VIRTIO_MENU=y CONFIG_VIRTIO_PCI=y @@ -1935,6 +1944,7 @@ CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y # end of Microsoft Hyper-V guest support # CONFIG_GREYBUS is not set +# CONFIG_COMEDI is not set # CONFIG_STAGING is not set # CONFIG_X86_PLATFORM_DEVICES is not set CONFIG_PMC_ATOM=y @@ -1975,9 +1985,6 @@ CONFIG_IOMMU_DMA=y # CONFIG_INTEL_IOMMU is not set # CONFIG_IRQ_REMAP is not set CONFIG_VIRTIO_IOMMU=y -CONFIG_VIRTIO_IOMMU_TOPOLOGY_HELPERS=y -CONFIG_VIRTIO_IOMMU_TOPOLOGY=y -CONFIG_ACPI_VIOT=y # # Remoteproc drivers @@ -2165,6 +2172,8 @@ CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y # # Caches # +CONFIG_NETFS_SUPPORT=y +# CONFIG_NETFS_STATS is not set CONFIG_FSCACHE=y # CONFIG_FSCACHE_STATS is not set # CONFIG_FSCACHE_HISTOGRAM is not set @@ -2350,6 +2359,7 @@ CONFIG_CRYPTO_SIMD=y # CONFIG_CRYPTO_RSA is not set # CONFIG_CRYPTO_DH is not set # CONFIG_CRYPTO_ECDH is not set +# CONFIG_CRYPTO_ECDSA is not set # CONFIG_CRYPTO_ECRDSA is not set # CONFIG_CRYPTO_SM2 is not set # CONFIG_CRYPTO_CURVE25519 is not set @@ -2507,6 +2517,8 @@ CONFIG_SYSTEM_BLACKLIST_KEYRING=y CONFIG_SYSTEM_BLACKLIST_HASH_LIST="" # end of Certificates for signature checking +CONFIG_BINARY_PRINTF=y + # # Library routines # @@ -2633,6 +2645,7 @@ CONFIG_SECTION_MISMATCH_WARN_ONLY=y # CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_32B is not set CONFIG_FRAME_POINTER=y CONFIG_STACK_VALIDATION=y +# CONFIG_VMLINUX_MAP is not set # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # end of Compile-time checks and compiler options @@ -2833,6 +2846,7 @@ CONFIG_RUNTIME_TESTING_MENU=y # CONFIG_TEST_LIST_SORT is not set # CONFIG_TEST_MIN_HEAP is not set # CONFIG_TEST_SORT is not set +# CONFIG_TEST_DIV64 is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_RBTREE_TEST is not set # CONFIG_REED_SOLOMON_TEST is not set @@ -2859,6 +2873,7 @@ CONFIG_RUNTIME_TESTING_MENU=y # CONFIG_TEST_MEMINIT is not set # CONFIG_TEST_FREE_PAGES is not set # CONFIG_TEST_FPU is not set +CONFIG_ARCH_USE_MEMTEST=y # CONFIG_MEMTEST is not set # end of Kernel Testing and Coverage # end of Kernel hacking diff --git a/scripts/run_integration_tests_x86_64.sh b/scripts/run_integration_tests_x86_64.sh index a202ed11b..28b0cb4b0 100755 --- a/scripts/run_integration_tests_x86_64.sh +++ b/scripts/run_integration_tests_x86_64.sh @@ -102,7 +102,7 @@ LINUX_CUSTOM_DIR="$WORKLOADS_DIR/linux-custom" if [ ! -f "$VMLINUX_IMAGE" ]; then SRCDIR=$PWD pushd $WORKLOADS_DIR - time git clone --depth 1 "https://github.com/cloud-hypervisor/linux.git" -b "ch-5.12" $LINUX_CUSTOM_DIR + time git clone --depth 1 "https://github.com/cloud-hypervisor/linux.git" -b "ch-5.13-rc5" $LINUX_CUSTOM_DIR cp $SRCDIR/resources/linux-config-x86_64 $LINUX_CUSTOM_DIR/.config popd fi diff --git a/virtio-devices/src/iommu.rs b/virtio-devices/src/iommu.rs index b6a363d2c..8d734f45d 100644 --- a/virtio-devices/src/iommu.rs +++ b/virtio-devices/src/iommu.rs @@ -62,7 +62,7 @@ const MSI_IOVA_END: u64 = 0xfeef_ffff; #[allow(unused)] const VIRTIO_IOMMU_F_INPUT_RANGE: u32 = 0; #[allow(unused)] -const VIRTIO_IOMMU_F_DOMAIN_BITS: u32 = 1; +const VIRTIO_IOMMU_F_DOMAIN_RANGE: u32 = 1; #[allow(unused)] const VIRTIO_IOMMU_F_MAP_UNMAP: u32 = 2; #[allow(unused)] @@ -71,7 +71,7 @@ const VIRTIO_IOMMU_F_PROBE: u32 = 4; #[allow(unused)] const VIRTIO_IOMMU_F_MMIO: u32 = 5; #[allow(unused)] -const VIRTIO_IOMMU_F_TOPOLOGY: u32 = 6; +const VIRTIO_IOMMU_F_BYPASS_CONFIG: u32 = 6; // Support 2MiB and 4KiB page sizes. const VIRTIO_IOMMU_PAGE_SIZE_MASK: u64 = (2 << 20) | (4 << 10); @@ -94,15 +94,6 @@ struct VirtioIommuRange64 { unsafe impl ByteValued for VirtioIommuRange64 {} -#[derive(Copy, Clone, Debug, Default)] -#[repr(packed)] -struct VirtioIommuTopoConfig { - num_items: u16, - offset: u16, -} - -unsafe impl ByteValued for VirtioIommuTopoConfig {} - #[derive(Copy, Clone, Debug, Default)] #[repr(packed)] struct VirtioIommuConfig { @@ -110,43 +101,12 @@ struct VirtioIommuConfig { input_range: VirtioIommuRange64, domain_range: VirtioIommuRange32, probe_size: u32, - topo_config: VirtioIommuTopoConfig, + bypass: u8, + reserved: [u8; 7], } unsafe impl ByteValued for VirtioIommuConfig {} -#[allow(unused)] -const VIRTIO_IOMMU_TOPO_PCI_RANGE: u8 = 1; -#[allow(unused)] -const VIRTIO_IOMMU_TOPO_MMIO: u8 = 2; - -#[derive(Copy, Clone, Debug, Default)] -#[repr(packed)] -struct VirtioIommuTopoPciRange { - type_: u8, - reserved: u8, - length: u16, - endpoint_start: u32, - segment_start: u16, - segment_end: u16, - bdf_start: u16, - bdf_end: u16, -} - -unsafe impl ByteValued for VirtioIommuTopoPciRange {} - -#[derive(Copy, Clone, Debug, Default)] -#[repr(packed)] -struct VirtioIommuTopoMmio { - type_: u8, - reserved: u8, - length: u16, - endpoint: u32, - address: u64, -} - -unsafe impl ByteValued for VirtioIommuTopoMmio {} - /// Virtio IOMMU request type const VIRTIO_IOMMU_T_ATTACH: u8 = 1; const VIRTIO_IOMMU_T_DETACH: u8 = 2; @@ -179,6 +139,8 @@ const VIRTIO_IOMMU_S_RANGE: u8 = 5; const VIRTIO_IOMMU_S_NOENT: u8 = 6; #[allow(unused)] const VIRTIO_IOMMU_S_FAULT: u8 = 7; +#[allow(unused)] +const VIRTIO_IOMMU_S_NOMEM: u8 = 8; #[derive(Copy, Clone, Debug, Default)] #[repr(packed)] @@ -217,9 +179,10 @@ const VIRTIO_IOMMU_MAP_F_READ: u32 = 1; #[allow(unused)] const VIRTIO_IOMMU_MAP_F_WRITE: u32 = 1 << 1; #[allow(unused)] -const VIRTIO_IOMMU_MAP_F_EXEC: u32 = 1 << 2; +const VIRTIO_IOMMU_MAP_F_MMIO: u32 = 1 << 2; #[allow(unused)] -const VIRTIO_IOMMU_MAP_F_MMIO: u32 = 1 << 3; +const VIRTIO_IOMMU_MAP_F_MASK: u32 = + VIRTIO_IOMMU_MAP_F_READ | VIRTIO_IOMMU_MAP_F_WRITE | VIRTIO_IOMMU_MAP_F_MMIO; /// MAP request #[derive(Copy, Clone, Debug, Default)] @@ -248,10 +211,10 @@ unsafe impl ByteValued for VirtioIommuReqUnmap {} /// Virtio IOMMU request PROBE types #[allow(unused)] -const VIRTIO_IOMMU_PROBE_T_MASK: u16 = 0xfff; -#[allow(unused)] const VIRTIO_IOMMU_PROBE_T_NONE: u16 = 0; const VIRTIO_IOMMU_PROBE_T_RESV_MEM: u16 = 1; +#[allow(unused)] +const VIRTIO_IOMMU_PROBE_T_MASK: u16 = 0xfff; /// PROBE request #[derive(Copy, Clone, Debug, Default)] @@ -315,7 +278,7 @@ struct VirtioIommuFault { reserved: [u8; 3], flags: u32, endpoint: u32, - reserved1: u32, + reserved2: [u8; 4], address: u64, } @@ -736,7 +699,6 @@ pub struct Iommu { common: VirtioCommon, id: String, config: VirtioIommuConfig, - config_topo_pci_ranges: Vec, mapping: Arc, ext_mapping: BTreeMap>, seccomp_action: SeccompAction, @@ -778,7 +740,6 @@ impl Iommu { ..Default::default() }, config, - config_topo_pci_ranges: Vec::new(), mapping: mapping.clone(), ext_mapping: BTreeMap::new(), seccomp_action, @@ -823,46 +784,6 @@ impl Iommu { .collect(); } - // This function lets the caller specify a list of devices attached to the - // virtual IOMMU. This list is translated into a virtio-iommu configuration - // topology, so that it can be understood by the guest driver. - // - // The topology is overridden everytime this function is being invoked. - // - // This function is dedicated to PCI, which means it will exclusively - // create VIRTIO_IOMMU_TOPO_PCI_RANGE entries. - pub fn attach_pci_devices(&mut self, segment: u16, device_ids: Vec) { - if device_ids.is_empty() { - warn!("No device to attach to virtual IOMMU"); - return; - } - - // If there is at least one device attached to the virtual IOMMU, we - // need the topology feature to be enabled. - self.common.avail_features |= 1u64 << VIRTIO_IOMMU_F_TOPOLOGY; - - // Update the topology. - let mut topo_pci_ranges = Vec::new(); - for device_id in device_ids.iter() { - let dev_id = *device_id; - topo_pci_ranges.push(VirtioIommuTopoPciRange { - type_: VIRTIO_IOMMU_TOPO_PCI_RANGE, - length: size_of::() as u16, - endpoint_start: dev_id, - segment_start: segment, - segment_end: segment, - bdf_start: dev_id as u16, - bdf_end: dev_id as u16, - ..Default::default() - }); - } - self.config_topo_pci_ranges = topo_pci_ranges; - - // Update the configuration to include the topology. - self.config.topo_config.num_items = self.config_topo_pci_ranges.len() as u16; - self.config.topo_config.offset = size_of::() as u16; - } - pub fn add_external_mapping(&mut self, device_id: u32, mapping: Arc) { self.ext_mapping.insert(device_id, mapping); } @@ -895,13 +816,7 @@ impl VirtioDevice for Iommu { } fn read_config(&self, offset: u64, data: &mut [u8]) { - let mut config: Vec = Vec::new(); - config.extend_from_slice(self.config.as_slice()); - for config_topo_pci_range in self.config_topo_pci_ranges.iter() { - config.extend_from_slice(config_topo_pci_range.as_slice()); - } - - self.read_config_from_slice(config.as_slice(), offset, data); + self.read_config_from_slice(self.config.as_slice(), offset, data); } fn activate( diff --git a/vmm/src/acpi.rs b/vmm/src/acpi.rs index 952fc1b7e..85dd9d7a0 100644 --- a/vmm/src/acpi.rs +++ b/vmm/src/acpi.rs @@ -109,6 +109,32 @@ impl MemoryAffinity { } } +#[repr(packed)] +#[derive(Default)] +struct ViotVirtioPciNode { + pub type_: u8, + _reserved: u8, + pub length: u16, + pub pci_segment: u16, + pub pci_bdf_number: u16, + _reserved2: [u8; 8], +} + +#[repr(packed)] +#[derive(Default)] +struct ViotPciRangeNode { + pub type_: u8, + _reserved: u8, + pub length: u16, + pub endpoint_start: u32, + pub pci_segment_start: u16, + pub pci_segment_end: u16, + pub pci_bdf_start: u16, + pub pci_bdf_end: u16, + pub output_node: u16, + _reserved2: [u8; 6], +} + pub fn create_dsdt_table( device_manager: &Arc>, cpu_manager: &Arc>, @@ -360,6 +386,42 @@ fn create_iort_table() -> Sdt { iort } +fn create_viot_table(iommu_bdf: u32, devices_bdf: &[u32]) -> Sdt { + // VIOT + let mut viot = Sdt::new(*b"VIOT", 36, 0, *b"CLOUDH", *b"CHVIOT ", 0); + // Node count + viot.append((devices_bdf.len() + 1) as u16); + // Node offset + viot.append(48u16); + // VIOT reserved 8 bytes + viot.append_slice(&[0u8; 8]); + + // Virtio-iommu based on virtio-pci node + viot.append(ViotVirtioPciNode { + type_: 3, + length: 16, + pci_segment: 0, + pci_bdf_number: iommu_bdf as u16, + ..Default::default() + }); + + for device_bdf in devices_bdf { + viot.append(ViotPciRangeNode { + type_: 1, + length: 24, + endpoint_start: *device_bdf, + pci_segment_start: 0, + pci_segment_end: 0, + pci_bdf_start: *device_bdf as u16, + pci_bdf_end: *device_bdf as u16, + output_node: 48, + ..Default::default() + }); + } + + viot +} + pub fn create_acpi_tables( guest_mem: &GuestMemoryMmap, device_manager: &Arc>, @@ -489,6 +551,20 @@ pub fn create_acpi_tables( prev_tbl_off = iort_offset; } + // VIOT + if let Some((iommu_bdf, devices_bdf)) = device_manager.lock().unwrap().iommu_attached_devices() + { + let viot = create_viot_table(*iommu_bdf, devices_bdf); + + let viot_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap(); + guest_mem + .write_slice(viot.as_slice(), viot_offset) + .expect("Error writing VIOT table"); + tables.push(viot_offset.0); + prev_tbl_len = viot.len() as u64; + prev_tbl_off = viot_offset; + } + // XSDT let mut xsdt = Sdt::new(*b"XSDT", 36, 1, *b"CLOUDH", *b"CHXSDT ", 1); for table in tables { diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 07cb8b156..a1196f986 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -869,6 +869,12 @@ pub struct DeviceManager { // Paravirtualized IOMMU iommu_device: Option>>, + // PCI information about devices attached to the paravirtualized IOMMU + // It contains the virtual IOMMU PCI BDF along with the list of PCI BDF + // representing the devices attached to the virtual IOMMU. This is useful + // information for filling the ACPI VIOT table. + iommu_attached_devices: Option<(u32, Vec)>, + // Bitmap of PCI devices to hotplug. pci_devices_up: u32, @@ -975,6 +981,7 @@ impl DeviceManager { legacy_interrupt_manager: None, passthrough_device: None, iommu_device: None, + iommu_attached_devices: None, pci_devices_up: 0, pci_devices_down: 0, pci_irq_slots: [0; 32], @@ -1196,15 +1203,8 @@ impl DeviceManager { iommu_attached_devices.append(&mut vfio_iommu_device_ids); if let Some(iommu_device) = iommu_device { - iommu_device - .lock() - .unwrap() - .attach_pci_devices(0, iommu_attached_devices); - - // Because we determined the virtio-iommu b/d/f, we have to - // add the device to the PCI topology now. Otherwise, the - // b/d/f won't match the virtio-iommu device as expected. - self.add_virtio_pci_device(iommu_device, &mut pci_bus, &None, iommu_id)?; + let dev_id = self.add_virtio_pci_device(iommu_device, &mut pci_bus, &None, iommu_id)?; + self.iommu_attached_devices = Some((dev_id, iommu_attached_devices)); } let pci_bus = Arc::new(Mutex::new(pci_bus)); @@ -3486,6 +3486,10 @@ impl DeviceManager { .trigger_key(3) .map_err(DeviceManagerError::AArch64PowerButtonNotification) } + + pub fn iommu_attached_devices(&self) -> &Option<(u32, Vec)> { + &self.iommu_attached_devices + } } #[cfg(feature = "acpi")]