vmm_core/cpuid/
mod.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! VM CPUID support.
5
6pub mod topology;
7
8use hvdef::VIRTUALIZATION_STACK_CPUID_INTERFACE;
9use hvdef::VIRTUALIZATION_STACK_CPUID_PROPERTIES;
10use hvdef::VIRTUALIZATION_STACK_CPUID_VENDOR;
11use hvdef::VS1_PARTITION_PROPERTIES_EAX_EXTENDED_IOAPIC_RTE;
12use hvdef::VS1_PARTITION_PROPERTIES_EAX_IS_PORTABLE;
13use virt::CpuidLeaf;
14use x86defs::cpuid::CpuidFunction;
15
16/// A function used to query the cpuid result for a given input value (`eax`,
17/// `ecx`).
18pub type CpuidFn<'a> = &'a dyn Fn(u32, u32) -> [u32; 4];
19
20/// Returns CPUID leaves for Hyper-V-style VMs.
21///
22/// `extended_ioapic_rte` indicates that MSIs and the IOAPIC can reference a
23/// 15-bit APIC ID instead of the architectural 8-bit value. To match Hyper-V
24/// behavior, this should be enabled for non-PCAT VMs.
25pub fn hyperv_cpuid_leaves(extended_ioapic_rte: bool) -> impl Iterator<Item = CpuidLeaf> {
26    [
27        // Enable the virtualization bit.
28        //
29        // Not all hypervisors (e.g. KVM) enable this automatically.
30        CpuidLeaf::new(CpuidFunction::VersionAndFeatures.0, [0, 0, 1 << 31, 0]).masked([
31            0,
32            0,
33            1 << 31,
34            0,
35        ]),
36        CpuidLeaf::new(
37            VIRTUALIZATION_STACK_CPUID_VENDOR,
38            [
39                VIRTUALIZATION_STACK_CPUID_PROPERTIES,
40                u32::from_le_bytes(*b"Micr"),
41                u32::from_le_bytes(*b"osof"),
42                u32::from_le_bytes(*b"t VS"),
43            ],
44        ),
45        CpuidLeaf::new(
46            VIRTUALIZATION_STACK_CPUID_INTERFACE,
47            [u32::from_le_bytes(*b"VS#1"), 0, 0, 0],
48        ),
49        CpuidLeaf::new(
50            VIRTUALIZATION_STACK_CPUID_PROPERTIES,
51            [
52                VS1_PARTITION_PROPERTIES_EAX_IS_PORTABLE
53                    | if extended_ioapic_rte {
54                        VS1_PARTITION_PROPERTIES_EAX_EXTENDED_IOAPIC_RTE
55                    } else {
56                        0
57                    },
58                0,
59                0,
60                0,
61            ],
62        ),
63    ]
64    .into_iter()
65}