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