Skip to content

Commit 891434d

Browse files
authored
Merge pull request #401 from Dstack-TEE/disable-tee
vmm: Support for disabling TEE
2 parents 8ac5e70 + e3b6798 commit 891434d

File tree

8 files changed

+183
-48
lines changed

8 files changed

+183
-48
lines changed

vmm/rpc/proto/vmm_rpc.proto

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ message VmConfiguration {
9797
repeated string gateway_urls = 15;
9898
// The VM is stopped
9999
bool stopped = 16;
100+
// Disable confidential computing (fallback to non-TEE VM).
101+
bool no_tee = 17;
100102
}
101103

102104
// Requested GPU layout for a CVM.
@@ -151,6 +153,8 @@ message UpdateVmRequest {
151153
optional uint32 memory = 15;
152154
optional uint32 disk_size = 16;
153155
optional string image = 17;
156+
// Disable or re-enable TEE for an existing VM.
157+
optional bool no_tee = 18;
154158
}
155159

156160
// Parameters for listing CVMs with pagination and keyword filtering.

vmm/src/app.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ pub struct Manifest {
6363
pub kms_urls: Vec<String>,
6464
#[serde(default)]
6565
pub gateway_urls: Vec<String>,
66+
#[serde(default)]
67+
pub no_tee: bool,
6668
}
6769

6870
#[derive(Debug, Clone, Serialize, Deserialize, Default)]

vmm/src/app/qemu.rs

Lines changed: 62 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ impl VmInfo {
117117
.as_ref()
118118
.map(|c| c.gateway_urls.clone())
119119
.unwrap_or_default();
120+
let no_tee = vm_config
121+
.as_ref()
122+
.map(|c| c.no_tee)
123+
.unwrap_or(self.manifest.no_tee);
120124
let stopped = !workdir.started().unwrap_or(false);
121125

122126
Some(pb::VmConfiguration {
@@ -159,6 +163,7 @@ impl VmInfo {
159163
kms_urls,
160164
gateway_urls,
161165
stopped,
166+
no_tee,
162167
})
163168
},
164169
app_url: self
@@ -459,46 +464,7 @@ impl VmConfig {
459464
command.arg("-netdev").arg(netdev);
460465
command.arg("-device").arg("virtio-net-pci,netdev=net0");
461466

462-
command
463-
.arg("-machine")
464-
.arg("q35,kernel-irqchip=split,confidential-guest-support=tdx,hpet=off");
465-
466-
let img_ver = self.image.info.version_tuple().unwrap_or_default();
467-
let support_mr_config_id = img_ver >= (0, 5, 2);
468-
let tdx_object = if cfg.use_mrconfigid && support_mr_config_id {
469-
let app_compose = workdir.app_compose().context("Failed to get app compose")?;
470-
let compose_hash = workdir
471-
.app_compose_hash()
472-
.context("Failed to get compose hash")?;
473-
let mr_config = if app_compose.key_provider_id.is_empty() {
474-
MrConfig::V1 {
475-
compose_hash: &compose_hash,
476-
}
477-
} else {
478-
let instance_info = workdir
479-
.instance_info()
480-
.context("Failed to get instance info")?;
481-
let app_id = if instance_info.app_id.is_empty() {
482-
&compose_hash[..20]
483-
} else {
484-
&instance_info.app_id
485-
};
486-
487-
let key_provider = app_compose.key_provider();
488-
let key_provider_id = &app_compose.key_provider_id;
489-
MrConfig::V2 {
490-
compose_hash: &compose_hash,
491-
app_id: &app_id.try_into().context("Invalid app ID")?,
492-
key_provider,
493-
key_provider_id,
494-
}
495-
};
496-
let mrconfigid = BASE64_STANDARD.encode(mr_config.to_mr_config_id());
497-
format!("tdx-guest,id=tdx,mrconfigid={mrconfigid}")
498-
} else {
499-
"tdx-guest,id=tdx".to_string()
500-
};
501-
command.arg("-object").arg(tdx_object);
467+
self.configure_machine(&mut command, &workdir, cfg)?;
502468

503469
command
504470
.arg("-device")
@@ -686,6 +652,62 @@ impl VmConfig {
686652

687653
Ok(processes)
688654
}
655+
656+
fn configure_machine(
657+
&self,
658+
command: &mut Command,
659+
workdir: &VmWorkDir,
660+
cfg: &CvmConfig,
661+
) -> Result<()> {
662+
if self.manifest.no_tee {
663+
command
664+
.arg("-machine")
665+
.arg("q35,kernel-irqchip=split,hpet=off");
666+
return Ok(());
667+
}
668+
669+
command
670+
.arg("-machine")
671+
.arg("q35,kernel-irqchip=split,confidential-guest-support=tdx,hpet=off");
672+
673+
let img_ver = self.image.info.version_tuple().unwrap_or_default();
674+
let support_mr_config_id = img_ver >= (0, 5, 2);
675+
let tdx_object = if cfg.use_mrconfigid && support_mr_config_id {
676+
let app_compose = workdir.app_compose().context("Failed to get app compose")?;
677+
let compose_hash = workdir
678+
.app_compose_hash()
679+
.context("Failed to get compose hash")?;
680+
let mr_config = if app_compose.key_provider_id.is_empty() {
681+
MrConfig::V1 {
682+
compose_hash: &compose_hash,
683+
}
684+
} else {
685+
let instance_info = workdir
686+
.instance_info()
687+
.context("Failed to get instance info")?;
688+
let app_id = if instance_info.app_id.is_empty() {
689+
&compose_hash[..20]
690+
} else {
691+
&instance_info.app_id
692+
};
693+
694+
let key_provider = app_compose.key_provider();
695+
let key_provider_id = &app_compose.key_provider_id;
696+
MrConfig::V2 {
697+
compose_hash: &compose_hash,
698+
app_id: &app_id.try_into().context("Invalid app ID")?,
699+
key_provider,
700+
key_provider_id,
701+
}
702+
};
703+
let mrconfigid = BASE64_STANDARD.encode(mr_config.to_mr_config_id());
704+
format!("tdx-guest,id=tdx,mrconfigid={mrconfigid}")
705+
} else {
706+
"tdx-guest,id=tdx".to_string()
707+
};
708+
command.arg("-object").arg(tdx_object);
709+
Ok(())
710+
}
689711
}
690712

691713
/// Round up a value to the nearest multiple of another value.

vmm/src/console_beta.html

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1993,6 +1993,7 @@ <h2>Deploy a new instance</h2>
19931993
<label><input type="checkbox" v-model="form.public_logs"> Public logs</label>
19941994
<label><input type="checkbox" v-model="form.public_sysinfo"> Public sysinfo</label>
19951995
<label><input type="checkbox" v-model="form.public_tcbinfo"> Public TCB info</label>
1996+
<label><input type="checkbox" v-model="form.no_tee"> Disable TDX</label>
19961997
<label><input type="checkbox" v-model="form.pin_numa"> Pin NUMA</label>
19971998
<label><input type="checkbox" v-model="form.hugepages"> Huge pages</label>
19981999
</div>
@@ -2269,6 +2270,7 @@ <h3>Derive VM</h3>
22692270
public_logs: true,
22702271
public_sysinfo: true,
22712272
public_tcbinfo: true,
2273+
no_tee: false,
22722274
pin_numa: false,
22732275
hugepages: false,
22742276
user_config: '',
@@ -2318,6 +2320,7 @@ <h3>Derive VM</h3>
23182320
gateway_urls: undefined,
23192321
hugepages: false,
23202322
pin_numa: false,
2323+
no_tee: false,
23212324
encrypted_env: undefined,
23222325
app_id: undefined,
23232326
stopped: false,
@@ -2462,7 +2465,7 @@ <h3>Derive VM</h3>
24622465
return undefined;
24632466
}
24642467
function buildCreateVmPayload(source) {
2465-
var _a, _b, _c, _d;
2468+
var _a, _b, _c, _d, _e;
24662469
const normalizedPorts = normalizePorts(source.ports);
24672470
return {
24682471
name: source.name.trim(),
@@ -2477,9 +2480,10 @@ <h3>Derive VM</h3>
24772480
user_config: source.user_config || '',
24782481
hugepages: !!source.hugepages,
24792482
pin_numa: !!source.pin_numa,
2483+
no_tee: (_a = source.no_tee) !== null && _a !== void 0 ? _a : false,
24802484
gpus: source.gpus,
2481-
kms_urls: (_b = (_a = source.kms_urls) === null || _a === void 0 ? void 0 : _a.filter((url) => url && url.trim().length)) !== null && _b !== void 0 ? _b : [],
2482-
gateway_urls: (_d = (_c = source.gateway_urls) === null || _c === void 0 ? void 0 : _c.filter((url) => url && url.trim().length)) !== null && _d !== void 0 ? _d : [],
2485+
kms_urls: (_c = (_b = source.kms_urls) === null || _b === void 0 ? void 0 : _b.filter((url) => url && url.trim().length)) !== null && _c !== void 0 ? _c : [],
2486+
gateway_urls: (_e = (_d = source.gateway_urls) === null || _d === void 0 ? void 0 : _d.filter((url) => url && url.trim().length)) !== null && _e !== void 0 ? _e : [],
24832487
stopped: !!source.stopped,
24842488
};
24852489
}
@@ -2937,6 +2941,7 @@ <h3>Derive VM</h3>
29372941
user_config: vmForm.value.user_config,
29382942
hugepages: vmForm.value.hugepages,
29392943
pin_numa: vmForm.value.pin_numa,
2944+
no_tee: vmForm.value.no_tee,
29402945
gpus: configGpu(vmForm.value) || undefined,
29412946
kms_urls: vmForm.value.kms_urls,
29422947
gateway_urls: vmForm.value.gateway_urls,
@@ -3067,6 +3072,7 @@ <h3>Derive VM</h3>
30673072
public_tcbinfo: !!((_p = theVm.appCompose) === null || _p === void 0 ? void 0 : _p.public_tcbinfo),
30683073
pin_numa: !!config.pin_numa,
30693074
hugepages: !!config.hugepages,
3075+
no_tee: !!config.no_tee,
30703076
user_config: config.user_config || '',
30713077
stopped: !!config.stopped,
30723078
};
@@ -3093,6 +3099,7 @@ <h3>Derive VM</h3>
30933099
user_config: source.user_config,
30943100
hugepages: source.hugepages,
30953101
pin_numa: source.pin_numa,
3102+
no_tee: source.no_tee,
30963103
gpus: source.gpus,
30973104
kms_urls: source.kms_urls,
30983105
gateway_urls: source.gateway_urls,
@@ -6386,6 +6393,7 @@ <h3>Derive VM</h3>
63866393
* @property {Array.<string>|null} [kms_urls] VmConfiguration kms_urls
63876394
* @property {Array.<string>|null} [gateway_urls] VmConfiguration gateway_urls
63886395
* @property {boolean|null} [stopped] VmConfiguration stopped
6396+
* @property {boolean|null} [no_tee] VmConfiguration no_tee
63896397
*/
63906398
/**
63916399
* Constructs a new VmConfiguration.
@@ -6516,6 +6524,13 @@ <h3>Derive VM</h3>
65166524
* @instance
65176525
*/
65186526
VmConfiguration.prototype.stopped = false;
6527+
/**
6528+
* VmConfiguration no_tee.
6529+
* @member {boolean} no_tee
6530+
* @memberof vmm.VmConfiguration
6531+
* @instance
6532+
*/
6533+
VmConfiguration.prototype.no_tee = false;
65196534
// OneOf field names bound to virtual getters and setters
65206535
var $oneOfFields;
65216536
/**
@@ -6586,6 +6601,8 @@ <h3>Derive VM</h3>
65866601
writer.uint32(/* id 15, wireType 2 =*/ 122).string(message.gateway_urls[i]);
65876602
if (message.stopped != null && Object.hasOwnProperty.call(message, "stopped"))
65886603
writer.uint32(/* id 16, wireType 0 =*/ 128).bool(message.stopped);
6604+
if (message.no_tee != null && Object.hasOwnProperty.call(message, "no_tee"))
6605+
writer.uint32(/* id 17, wireType 0 =*/ 136).bool(message.no_tee);
65896606
return writer;
65906607
};
65916608
/**
@@ -6690,6 +6707,10 @@ <h3>Derive VM</h3>
66906707
message.stopped = reader.bool();
66916708
break;
66926709
}
6710+
case 17: {
6711+
message.no_tee = reader.bool();
6712+
break;
6713+
}
66936714
default:
66946715
reader.skipType(tag & 7);
66956716
break;
@@ -6790,6 +6811,9 @@ <h3>Derive VM</h3>
67906811
if (message.stopped != null && message.hasOwnProperty("stopped"))
67916812
if (typeof message.stopped !== "boolean")
67926813
return "stopped: boolean expected";
6814+
if (message.no_tee != null && message.hasOwnProperty("no_tee"))
6815+
if (typeof message.no_tee !== "boolean")
6816+
return "no_tee: boolean expected";
67936817
return null;
67946818
};
67956819
/**
@@ -6860,6 +6884,8 @@ <h3>Derive VM</h3>
68606884
}
68616885
if (object.stopped != null)
68626886
message.stopped = Boolean(object.stopped);
6887+
if (object.no_tee != null)
6888+
message.no_tee = Boolean(object.no_tee);
68636889
return message;
68646890
};
68656891
/**
@@ -6899,6 +6925,7 @@ <h3>Derive VM</h3>
68996925
object.pin_numa = false;
69006926
object.gpus = null;
69016927
object.stopped = false;
6928+
object.no_tee = false;
69026929
}
69036930
if (message.name != null && message.hasOwnProperty("name"))
69046931
object.name = message.name;
@@ -6944,6 +6971,8 @@ <h3>Derive VM</h3>
69446971
}
69456972
if (message.stopped != null && message.hasOwnProperty("stopped"))
69466973
object.stopped = message.stopped;
6974+
if (message.no_tee != null && message.hasOwnProperty("no_tee"))
6975+
object.no_tee = message.no_tee;
69476976
return object;
69486977
};
69496978
/**
@@ -7669,6 +7698,7 @@ <h3>Derive VM</h3>
76697698
* @property {number|null} [memory] UpdateVmRequest memory
76707699
* @property {number|null} [disk_size] UpdateVmRequest disk_size
76717700
* @property {string|null} [image] UpdateVmRequest image
7701+
* @property {boolean|null} [no_tee] UpdateVmRequest no_tee
76727702
*/
76737703
/**
76747704
* Constructs a new UpdateVmRequest.
@@ -7762,6 +7792,13 @@ <h3>Derive VM</h3>
77627792
* @instance
77637793
*/
77647794
UpdateVmRequest.prototype.image = null;
7795+
/**
7796+
* UpdateVmRequest no_tee.
7797+
* @member {boolean|null|undefined} no_tee
7798+
* @memberof vmm.UpdateVmRequest
7799+
* @instance
7800+
*/
7801+
UpdateVmRequest.prototype.no_tee = null;
77657802
// OneOf field names bound to virtual getters and setters
77667803
var $oneOfFields;
77677804
/**
@@ -7804,6 +7841,16 @@ <h3>Derive VM</h3>
78047841
get: $util.oneOfGetter($oneOfFields = ["image"]),
78057842
set: $util.oneOfSetter($oneOfFields)
78067843
});
7844+
/**
7845+
* UpdateVmRequest _no_tee.
7846+
* @member {"no_tee"|undefined} _no_tee
7847+
* @memberof vmm.UpdateVmRequest
7848+
* @instance
7849+
*/
7850+
Object.defineProperty(UpdateVmRequest.prototype, "_no_tee", {
7851+
get: $util.oneOfGetter($oneOfFields = ["no_tee"]),
7852+
set: $util.oneOfSetter($oneOfFields)
7853+
});
78077854
/**
78087855
* Creates a new UpdateVmRequest instance using the specified properties.
78097856
* @function create
@@ -7850,6 +7897,8 @@ <h3>Derive VM</h3>
78507897
writer.uint32(/* id 16, wireType 0 =*/ 128).uint32(message.disk_size);
78517898
if (message.image != null && Object.hasOwnProperty.call(message, "image"))
78527899
writer.uint32(/* id 17, wireType 2 =*/ 138).string(message.image);
7900+
if (message.no_tee != null && Object.hasOwnProperty.call(message, "no_tee"))
7901+
writer.uint32(/* id 18, wireType 0 =*/ 144).bool(message.no_tee);
78537902
return writer;
78547903
};
78557904
/**
@@ -7930,6 +7979,10 @@ <h3>Derive VM</h3>
79307979
message.image = reader.string();
79317980
break;
79327981
}
7982+
case 18: {
7983+
message.no_tee = reader.bool();
7984+
break;
7985+
}
79337986
default:
79347987
reader.skipType(tag & 7);
79357988
break;
@@ -8013,6 +8066,11 @@ <h3>Derive VM</h3>
80138066
if (!$util.isString(message.image))
80148067
return "image: string expected";
80158068
}
8069+
if (message.no_tee != null && message.hasOwnProperty("no_tee")) {
8070+
properties._no_tee = 1;
8071+
if (typeof message.no_tee !== "boolean")
8072+
return "no_tee: boolean expected";
8073+
}
80168074
return null;
80178075
};
80188076
/**
@@ -8063,6 +8121,8 @@ <h3>Derive VM</h3>
80638121
message.disk_size = object.disk_size >>> 0;
80648122
if (object.image != null)
80658123
message.image = String(object.image);
8124+
if (object.no_tee != null)
8125+
message.no_tee = Boolean(object.no_tee);
80668126
return message;
80678127
};
80688128
/**
@@ -8131,6 +8191,11 @@ <h3>Derive VM</h3>
81318191
if (options.oneofs)
81328192
object._image = "image";
81338193
}
8194+
if (message.no_tee != null && message.hasOwnProperty("no_tee")) {
8195+
object.no_tee = message.no_tee;
8196+
if (options.oneofs)
8197+
object._no_tee = "no_tee";
8198+
}
81348199
return object;
81358200
};
81368201
/**

0 commit comments

Comments
 (0)