Skip to content

Commit bbc776a

Browse files
committed
fix bad MSR write and simplify KVM_MEMORY_FAULT impl
Signed-off-by: Jake Correnti <[email protected]>
1 parent 4dc66f9 commit bbc776a

File tree

3 files changed

+102
-54
lines changed

3 files changed

+102
-54
lines changed

src/cpuid/src/transformer/intel.rs

+49
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,56 @@ pub fn update_feature_info_entry(
1616
use crate::cpu_leaf::leaf_0x1::*;
1717

1818
common::update_feature_info_entry(entry, vm_spec)?;
19+
if entry.index == 0x1 {
20+
println!("adjusting 0x1 index feature");
21+
entry.ecx &= (1 << 21);
22+
}
1923

2024
entry.ecx.write_bit(ecx::TSC_DEADLINE_TIMER_BITINDEX, true);
2125

2226
Ok(())
2327
}
2428

29+
pub fn update_kvm_features(
30+
entry: &mut kvm_cpuid_entry2,
31+
vm_spec: &VmSpec,
32+
) -> Result<(), Error> {
33+
// KVM feature bits
34+
const NOP_IO_RELAY: u32 = 1;
35+
const PV_UNHALT: u32 = 1;
36+
const PV_TLB_FLUSH: u32 = 9;
37+
const PV_SEND_IPI: u32 = 11;
38+
const POLL_CONTROL: u32 = 12;
39+
const PV_SCHED_YIELD: u32 = 13;
40+
const MSI_EXT_DEST_ID: u32 = 15;
41+
42+
// These features are not supported by TDX
43+
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);
44+
Ok(())
45+
}
46+
47+
pub fn update_0xd_for_tdx(
48+
entry: &mut kvm_cpuid_entry2,
49+
vm_spec: &VmSpec,
50+
) -> Result<(), Error> {
51+
if entry.function == 0xD && entry.index == 0 {
52+
const XFEATURE_MASK_XTILE: u32 = (1 << 17) | (1 << 18);
53+
if (entry.eax & XFEATURE_MASK_XTILE) != XFEATURE_MASK_XTILE {
54+
entry.eax &= !XFEATURE_MASK_XTILE;
55+
}
56+
}
57+
58+
if entry.function == 0xD && entry.index == 1 {
59+
entry.ecx &= !(1 << 15);
60+
const XFEATURE_MASK_CET: u32 = (1 << 11) | (1 << 12);
61+
if entry.ecx & XFEATURE_MASK_CET > 0 {
62+
entry.ecx |= XFEATURE_MASK_CET;
63+
}
64+
}
65+
66+
Ok(())
67+
}
68+
2569
fn update_deterministic_cache_entry(
2670
entry: &mut kvm_cpuid_entry2,
2771
vm_spec: &VmSpec,
@@ -146,6 +190,11 @@ impl CpuidTransformer for IntelCpuidTransformer {
146190
leaf_0x6::LEAF_NUM => Some(intel::update_power_management_entry),
147191
leaf_0xa::LEAF_NUM => Some(intel::update_perf_mon_entry),
148192
leaf_0xb::LEAF_NUM => Some(intel::update_extended_cache_topology_entry),
193+
leaf_0xd::LEAF_NUM => Some(intel::update_0xd_for_tdx),
194+
0x4000_0001 => {
195+
196+
Some(intel::update_kvm_features)
197+
},
149198
0x8000_0002..=0x8000_0004 => Some(common::update_brand_string_entry),
150199
_ => None,
151200
}

src/vmm/src/builder.rs

+37-43
Original file line numberDiff line numberDiff line change
@@ -1175,55 +1175,49 @@ fn create_vcpus_x86_64(
11751175
.map_err(Error::Vcpu)?;
11761176

11771177
let mut cpuid = vm.supported_cpuid().clone();
1178-
for entry in cpuid.as_mut_slice().iter_mut() {
1179-
if entry.index == 0x1 {
1180-
entry.ecx &= 1 << 21;
1181-
}
1182-
1183-
if entry.function == 0xD && entry.index == 0 {
1184-
const XFEATURE_MASK_XTILE: u32 = (1 << 17) | (1 << 18);
1185-
if (entry.eax & XFEATURE_MASK_XTILE) != XFEATURE_MASK_XTILE {
1186-
entry.eax &= !XFEATURE_MASK_XTILE;
1187-
}
1188-
}
1189-
1190-
if entry.function == 0xD && entry.index == 1 {
1191-
entry.ecx &= !(1 << 15);
1192-
const XFEATURE_MASK_CET: u32 = (1 << 11) | (1 << 12);
1193-
if entry.ecx & XFEATURE_MASK_CET > 0 {
1194-
entry.ecx |= XFEATURE_MASK_CET;
1195-
}
1196-
}
1197-
1198-
if entry.function == 0x4000_0001 {
1199-
// KVM feature bits
1200-
const KVM_FEATURE_CLOCKSOURCE_BIT: u8 = 0;
1201-
const KVM_FEATURE_CLOCKSOURCE2_BIT: u8 = 3;
1202-
const KVM_FEATURE_CLOCKSOURCE_STABLE_BIT: u8 = 24;
1203-
const KVM_FEATURE_ASYNC_PF_BIT: u8 = 4;
1204-
const KVM_FEATURE_ASYNC_PF_VMEXIT_BIT: u8 = 10;
1205-
const KVM_FEATURE_STEAL_TIME_BIT: u8 = 5;
1206-
const KVM_FEATURE_PV_EOI: u8 = 6;
1178+
// for entry in cpuid.as_mut_slice().iter_mut() {
1179+
// if entry.index == 0x1 {
1180+
// entry.ecx &= 1 << 21;
1181+
// }
1182+
1183+
// if entry.function == 0xD && entry.index == 0 {
1184+
// const XFEATURE_MASK_XTILE: u32 = (1 << 17) | (1 << 18);
1185+
// if (entry.eax & XFEATURE_MASK_XTILE) != XFEATURE_MASK_XTILE {
1186+
// entry.eax &= !XFEATURE_MASK_XTILE;
1187+
// }
1188+
// }
1189+
1190+
// if entry.function == 0xD && entry.index == 1 {
1191+
// entry.ecx &= !(1 << 15);
1192+
// const XFEATURE_MASK_CET: u32 = (1 << 11) | (1 << 12);
1193+
// if entry.ecx & XFEATURE_MASK_CET > 0 {
1194+
// entry.ecx |= XFEATURE_MASK_CET;
1195+
// }
1196+
// }
1197+
1198+
// if entry.function == 0x4000_0001 {
1199+
// // KVM feature bits
1200+
// const NOP_IO_RELAY: u32 = 1;
1201+
// const PV_UNHALT: u32 = 1;
1202+
// const PV_TLB_FLUSH: u32 = 9;
1203+
// const PV_SEND_IPI: u32 = 11;
1204+
// const POLL_CONTROL: u32 = 12;
1205+
// const PV_SCHED_YIELD: u32 = 13;
1206+
// const MSI_EXT_DEST_ID: u32 = 15;
12071207

1208-
// These features are not supported by TDX
1209-
entry.eax &= !(1 << KVM_FEATURE_CLOCKSOURCE_BIT
1210-
| 1 << KVM_FEATURE_CLOCKSOURCE2_BIT
1211-
| 1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT
1212-
| 1 << KVM_FEATURE_ASYNC_PF_BIT
1213-
| 1 << KVM_FEATURE_ASYNC_PF_VMEXIT_BIT
1214-
| 1 << KVM_FEATURE_PV_EOI
1215-
| 1 << KVM_FEATURE_STEAL_TIME_BIT);
1216-
}
1217-
}
1218-
1219-
#[cfg(feature = "intel-tdx")]
1220-
vcpu.tdx_secure_virt_init(hob_section_addr, &cpuid)
1221-
.map_err(Error::Vcpu)?;
1208+
// // These features are not supported by TDX
1209+
// 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);
1210+
// }
1211+
// }
12221212

12231213
println!("entry addr: {:#?}", entry_addr);
12241214
vcpu.configure_x86_64(guest_mem, entry_addr, vcpu_config)
12251215
.map_err(Error::Vcpu)?;
12261216

1217+
#[cfg(feature = "intel-tdx")]
1218+
vcpu.tdx_secure_virt_init(0, &cpuid)
1219+
.map_err(Error::Vcpu)?;
1220+
12271221
vcpus.push(vcpu);
12281222
}
12291223
Ok(vcpus)

src/vmm/src/linux/vstate.rs

+16-11
Original file line numberDiff line numberDiff line change
@@ -1500,16 +1500,21 @@ impl Vcpu {
15001500
error!("KVM_EXIT_MEMORY_FAULT: Unknown flag {}", flags);
15011501
Err(Error::VcpuUnhandledKvmExit)
15021502
} else {
1503-
// from private to shared
1504-
let mut attr = 0;
1505-
// from shared to private
1506-
if flags & kvm_bindings::KVM_MEMORY_EXIT_FLAG_PRIVATE as u64
1507-
== kvm_bindings::KVM_MEMORY_EXIT_FLAG_PRIVATE as u64
1508-
{
1509-
attr = kvm_bindings::KVM_MEMORY_ATTRIBUTE_PRIVATE;
1510-
};
1511-
1512-
let _ = self.vmcall_sender.try_send((gpa, size, attr > 0));
1503+
// // from private to shared
1504+
// let mut attr = 0;
1505+
// // from shared to private
1506+
// if flags & kvm_bindings::KVM_MEMORY_EXIT_FLAG_PRIVATE as u64
1507+
// == kvm_bindings::KVM_MEMORY_EXIT_FLAG_PRIVATE as u64
1508+
// {
1509+
// attr = kvm_bindings::KVM_MEMORY_ATTRIBUTE_PRIVATE;
1510+
// };
1511+
let attr = (flags & kvm_bindings::KVM_MEMORY_EXIT_FLAG_PRIVATE as u64);
1512+
1513+
let res = self.vmcall_sender.try_send((gpa, size, attr > 0));
1514+
if res.is_err() {
1515+
error!("KVM_EXIT_MEMORY_FAULT: unable to convert memory: Exit {:#?}", res);
1516+
return Err(Error::VcpuUnhandledKvmExit);
1517+
}
15131518
Ok(VcpuEmulation::Handled)
15141519
}
15151520
}
@@ -1784,7 +1789,7 @@ impl Vcpu {
17841789

17851790
#[cfg(feature = "intel-tdx")]
17861791
pub fn tdx_secure_virt_init(&self, hob_addr: u64, cpuid: &CpuId) -> Result<()> {
1787-
self.fd.set_cpuid2(cpuid).unwrap();
1792+
// self.fd.set_cpuid2(cpuid).unwrap();
17881793
tdx::launch::TdxVcpu::init_raw(&self.fd, hob_addr)
17891794
.or_else(|_| return Err(Error::TdxSecVirtInitVcpu))
17901795
}

0 commit comments

Comments
 (0)