i386/sev: Add sev_kvm_init() override for SEV class
Some aspects of the init routine SEV are specific to SEV and not applicable for SNP guests, so move the SEV-specific bits into separate class method and retain only the common functionality. Co-developed-by: Michael Roth <michael.roth@amd.com> Signed-off-by: Michael Roth <michael.roth@amd.com> Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com> Message-ID: <20240530111643.1091816-10-pankaj.gupta@amd.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
99190f805d
commit
990da8d243
@ -73,6 +73,7 @@ struct SevCommonStateClass {
|
|||||||
/* public */
|
/* public */
|
||||||
int (*launch_start)(SevCommonState *sev_common);
|
int (*launch_start)(SevCommonState *sev_common);
|
||||||
void (*launch_finish)(SevCommonState *sev_common);
|
void (*launch_finish)(SevCommonState *sev_common);
|
||||||
|
int (*kvm_init)(ConfidentialGuestSupport *cgs, Error **errp);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -882,7 +883,7 @@ out:
|
|||||||
return sev_common->kvm_type;
|
return sev_common->kvm_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
|
static int sev_common_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
|
||||||
{
|
{
|
||||||
SevCommonState *sev_common = SEV_COMMON(cgs);
|
SevCommonState *sev_common = SEV_COMMON(cgs);
|
||||||
char *devname;
|
char *devname;
|
||||||
@ -892,12 +893,6 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
|
|||||||
struct sev_user_data_status status = {};
|
struct sev_user_data_status status = {};
|
||||||
SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(cgs);
|
SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(cgs);
|
||||||
|
|
||||||
ret = ram_block_discard_disable(true);
|
|
||||||
if (ret) {
|
|
||||||
error_report("%s: cannot disable RAM discard", __func__);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sev_common->state = SEV_STATE_UNINIT;
|
sev_common->state = SEV_STATE_UNINIT;
|
||||||
|
|
||||||
host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL);
|
host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL);
|
||||||
@ -911,7 +906,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
|
|||||||
if (host_cbitpos != sev_common->cbitpos) {
|
if (host_cbitpos != sev_common->cbitpos) {
|
||||||
error_setg(errp, "%s: cbitpos check failed, host '%d' requested '%d'",
|
error_setg(errp, "%s: cbitpos check failed, host '%d' requested '%d'",
|
||||||
__func__, host_cbitpos, sev_common->cbitpos);
|
__func__, host_cbitpos, sev_common->cbitpos);
|
||||||
goto err;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -924,7 +919,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
|
|||||||
error_setg(errp, "%s: reduced_phys_bits check failed,"
|
error_setg(errp, "%s: reduced_phys_bits check failed,"
|
||||||
" it should be in the range of 1 to 63, requested '%d'",
|
" it should be in the range of 1 to 63, requested '%d'",
|
||||||
__func__, sev_common->reduced_phys_bits);
|
__func__, sev_common->reduced_phys_bits);
|
||||||
goto err;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
devname = object_property_get_str(OBJECT(sev_common), "sev-device", NULL);
|
devname = object_property_get_str(OBJECT(sev_common), "sev-device", NULL);
|
||||||
@ -933,7 +928,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
|
|||||||
error_setg(errp, "%s: Failed to open %s '%s'", __func__,
|
error_setg(errp, "%s: Failed to open %s '%s'", __func__,
|
||||||
devname, strerror(errno));
|
devname, strerror(errno));
|
||||||
g_free(devname);
|
g_free(devname);
|
||||||
goto err;
|
return -1;
|
||||||
}
|
}
|
||||||
g_free(devname);
|
g_free(devname);
|
||||||
|
|
||||||
@ -943,7 +938,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
|
|||||||
error_setg(errp, "%s: failed to get platform status ret=%d "
|
error_setg(errp, "%s: failed to get platform status ret=%d "
|
||||||
"fw_error='%d: %s'", __func__, ret, fw_error,
|
"fw_error='%d: %s'", __func__, ret, fw_error,
|
||||||
fw_error_to_str(fw_error));
|
fw_error_to_str(fw_error));
|
||||||
goto err;
|
return -1;
|
||||||
}
|
}
|
||||||
sev_common->build_id = status.build;
|
sev_common->build_id = status.build;
|
||||||
sev_common->api_major = status.api_major;
|
sev_common->api_major = status.api_major;
|
||||||
@ -953,7 +948,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
|
|||||||
if (!kvm_kernel_irqchip_allowed()) {
|
if (!kvm_kernel_irqchip_allowed()) {
|
||||||
error_setg(errp, "%s: SEV-ES guests require in-kernel irqchip"
|
error_setg(errp, "%s: SEV-ES guests require in-kernel irqchip"
|
||||||
"support", __func__);
|
"support", __func__);
|
||||||
goto err;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -962,7 +957,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
|
|||||||
error_setg(errp, "%s: guest policy requires SEV-ES, but "
|
error_setg(errp, "%s: guest policy requires SEV-ES, but "
|
||||||
"host SEV-ES support unavailable",
|
"host SEV-ES support unavailable",
|
||||||
__func__);
|
__func__);
|
||||||
goto err;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -980,27 +975,61 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
error_setg(errp, "%s: failed to initialize ret=%d fw_error=%d '%s'",
|
error_setg(errp, "%s: failed to initialize ret=%d fw_error=%d '%s'",
|
||||||
__func__, ret, fw_error, fw_error_to_str(fw_error));
|
__func__, ret, fw_error, fw_error_to_str(fw_error));
|
||||||
goto err;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = klass->launch_start(sev_common);
|
ret = klass->launch_start(sev_common);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
error_setg(errp, "%s: failed to create encryption context", __func__);
|
error_setg(errp, "%s: failed to create encryption context", __func__);
|
||||||
goto err;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (klass->kvm_init && klass->kvm_init(cgs, errp)) {
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ram_block_notifier_add(&sev_ram_notifier);
|
|
||||||
qemu_add_machine_init_done_notifier(&sev_machine_done_notify);
|
|
||||||
qemu_add_vm_change_state_handler(sev_vm_state_change, sev_common);
|
qemu_add_vm_change_state_handler(sev_vm_state_change, sev_common);
|
||||||
|
|
||||||
cgs->ready = true;
|
cgs->ready = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
err:
|
}
|
||||||
ram_block_discard_disable(false);
|
|
||||||
|
static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SEV/SEV-ES rely on pinned memory to back guest RAM so discarding
|
||||||
|
* isn't actually possible. With SNP, only guest_memfd pages are used
|
||||||
|
* for private guest memory, so discarding of shared memory is still
|
||||||
|
* possible..
|
||||||
|
*/
|
||||||
|
ret = ram_block_discard_disable(true);
|
||||||
|
if (ret) {
|
||||||
|
error_setg(errp, "%s: cannot disable RAM discard", __func__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SEV uses these notifiers to register/pin pages prior to guest use,
|
||||||
|
* but SNP relies on guest_memfd for private pages, which has its
|
||||||
|
* own internal mechanisms for registering/pinning private memory.
|
||||||
|
*/
|
||||||
|
ram_block_notifier_add(&sev_ram_notifier);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The machine done notify event is used for SEV guests to get the
|
||||||
|
* measurement of the encrypted images. When SEV-SNP is enabled, the
|
||||||
|
* measurement is part of the guest attestation process where it can
|
||||||
|
* be collected without any reliance on the VMM. So skip registering
|
||||||
|
* the notifier for SNP in favor of using guest attestation instead.
|
||||||
|
*/
|
||||||
|
qemu_add_machine_init_done_notifier(&sev_machine_done_notify);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp)
|
sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp)
|
||||||
{
|
{
|
||||||
@ -1397,7 +1426,7 @@ sev_common_class_init(ObjectClass *oc, void *data)
|
|||||||
ConfidentialGuestSupportClass *klass = CONFIDENTIAL_GUEST_SUPPORT_CLASS(oc);
|
ConfidentialGuestSupportClass *klass = CONFIDENTIAL_GUEST_SUPPORT_CLASS(oc);
|
||||||
X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc);
|
X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc);
|
||||||
|
|
||||||
klass->kvm_init = sev_kvm_init;
|
klass->kvm_init = sev_common_kvm_init;
|
||||||
x86_klass->kvm_type = sev_kvm_type;
|
x86_klass->kvm_type = sev_kvm_type;
|
||||||
|
|
||||||
object_class_property_add_str(oc, "sev-device",
|
object_class_property_add_str(oc, "sev-device",
|
||||||
@ -1486,6 +1515,7 @@ sev_guest_class_init(ObjectClass *oc, void *data)
|
|||||||
|
|
||||||
klass->launch_start = sev_launch_start;
|
klass->launch_start = sev_launch_start;
|
||||||
klass->launch_finish = sev_launch_finish;
|
klass->launch_finish = sev_launch_finish;
|
||||||
|
klass->kvm_init = sev_kvm_init;
|
||||||
|
|
||||||
object_class_property_add_str(oc, "dh-cert-file",
|
object_class_property_add_str(oc, "dh-cert-file",
|
||||||
sev_guest_get_dh_cert_file,
|
sev_guest_get_dh_cert_file,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user