Skip to content

Commit 99b42b8

Browse files
committed
tdx: normalize TDX max_phys_bits handling
Normalize TDX max_phys_bits in VM config validation to supported GPA widths (48/52), make x86 CPUID phys-bits reporting follow the validated config value. Signed-off-by: Liang, Zhou <liang1.zhou@intel.com>
1 parent 5052f20 commit 99b42b8

3 files changed

Lines changed: 37 additions & 14 deletions

File tree

‎arch/src/x86_64/mod.rs‎

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -631,8 +631,6 @@ pub fn generate_common_cpuid(
631631

632632
CpuidPatch::patch_cpuid(&mut cpuid, &cpuid_patches);
633633

634-
let la57_enabled = CpuidPatch::is_feature_enabled(&cpuid, 7, 0, CpuidReg::ECX, 16);
635-
636634
#[cfg(feature = "tdx")]
637635
let tdx_capabilities = if config.tdx {
638636
let tdx_vm = vm.ok_or_else(|| {
@@ -715,14 +713,9 @@ pub fn generate_common_cpuid(
715713
}
716714
// Set CPU physical bits
717715
0x8000_0008 => {
718-
let virt_addr_width = if la57_enabled { 57 } else { 48 };
719-
let mut guest_phys_bits = (entry.eax >> 16) & 0xff;
720-
if guest_phys_bits > config.phys_bits as u32 {
721-
guest_phys_bits = config.phys_bits as u32;
722-
}
723-
entry.eax = (config.phys_bits as u32 & 0xff)
724-
| (virt_addr_width << 8)
725-
| (guest_phys_bits << 16);
716+
entry.eax = (entry.eax & 0xff00_ff00)
717+
| (config.phys_bits as u32 & 0xff)
718+
| ((config.phys_bits as u32 & 0xff) << 16);
726719
}
727720
0x4000_0001 => {
728721
// Enable KVM_FEATURE_MSI_EXT_DEST_ID. This allows the guest to target

‎docs/intel_tdx.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ guest image containing the TDX enlightened kernel.
7070
./cloud-hypervisor \
7171
--platform tdx=on \
7272
--firmware edk2/Build/IntelTdx/RELEASE_GCC5/FV/OVMF.fd \
73-
--cpus boot=1,max_phys_bits=52 \
73+
--cpus boot=1 \
7474
--memory size=1G \
7575
--serial tty \
7676
--console off \
@@ -84,7 +84,7 @@ firmware:
8484
./cloud-hypervisor \
8585
--platform tdx=on \
8686
--firmware edk2/Build/IntelTdx/DEBUG_GCC5/FV/OVMF.fd \
87-
--cpus boot=1,max_phys_bits=52 \
87+
--cpus boot=1 \
8888
--memory size=1G \
8989
--disk path=tdx_guest_img \
9090
--serial tty \
@@ -139,7 +139,7 @@ option as well.
139139
--firmware td-shim/target/release/final.bin \
140140
--kernel bzImage \
141141
--cmdline "root=/dev/vda1 rw console=ttyS0 ignore_loglevel earlyprintk=ttyS0" \
142-
--cpus boot=1,max_phys_bits=52 \
142+
--cpus boot=1 \
143143
--memory size=1G \
144144
--disk path=tdx_guest_img
145145
```
@@ -153,7 +153,7 @@ TDShim:
153153
--firmware td-shim/target/debug/final.bin \
154154
--kernel bzImage \
155155
--cmdline "root=/dev/vda1 rw console=ttyS0 ignore_loglevel earlyprintk=ttyS0" \
156-
--cpus boot=1,max_phys_bits=52 \
156+
--cpus boot=1 \
157157
--memory size=1G \
158158
--disk path=tdx_guest_img
159159
```

‎vmm/src/config.rs‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2873,6 +2873,16 @@ impl VmConfig {
28732873
if tdx_enabled && (self.cpus.max_vcpus != self.cpus.boot_vcpus) {
28742874
return Err(ValidationError::TdxNoCpuHotplug);
28752875
}
2876+
if tdx_enabled {
2877+
// For TDX the guest physical address width (GPAW) is fixed at:
2878+
// 48 - (GPAW-48, 4-level EPT)
2879+
// 52 - (GPAW-52, 5-level EPT)
2880+
if self.cpus.max_phys_bits < 52 {
2881+
self.cpus.max_phys_bits = 48;
2882+
} else {
2883+
self.cpus.max_phys_bits = 52;
2884+
}
2885+
}
28762886
}
28772887

28782888
#[cfg(feature = "sev_snp")]
@@ -4898,6 +4908,26 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}"
48984908

48994909
valid_config.validate().unwrap();
49004910

4911+
#[cfg(feature = "tdx")]
4912+
{
4913+
let mut tdx_config = valid_config.clone();
4914+
tdx_config.cpus.max_phys_bits = 51;
4915+
tdx_config.platform = Some(PlatformConfig {
4916+
tdx: true,
4917+
..platform_fixture()
4918+
});
4919+
if let Some(payload) = tdx_config.payload.as_mut() {
4920+
payload.firmware = Some(PathBuf::from("/path/to/firmware"));
4921+
}
4922+
4923+
tdx_config.validate().unwrap();
4924+
assert_eq!(tdx_config.cpus.max_phys_bits, 48);
4925+
4926+
tdx_config.cpus.max_phys_bits = 52;
4927+
tdx_config.validate().unwrap();
4928+
assert_eq!(tdx_config.cpus.max_phys_bits, 52);
4929+
}
4930+
49014931
let mut invalid_config = valid_config.clone();
49024932
invalid_config.serial.mode = ConsoleOutputMode::Tty;
49034933
invalid_config.console.mode = ConsoleOutputMode::Tty;

0 commit comments

Comments
 (0)