The next patch populates the SEV-SNP ID block's policy field. That value must be whatever policy is currently in effect on the platform but there is no way to read it back: the policy can come either from an IGVM GUEST_POLICY header or from the command line, and the command line sets it directly into the SEV/SNP guest struct without going through IGVM. Reading it back from the platform is the only source that always reflects the value in effect, regardless of where it came from.
Add a get_guest_policy callback to ConfidentialGuestSupportClass for this purpose. It is not yet used; the following patch wires it into the SNP ID block population. Signed-off-by: Luigi Leonardi <[email protected]> --- backends/confidential-guest-support.c | 9 +++++++++ include/system/confidential-guest-support.h | 8 ++++++++ target/i386/sev.c | 24 ++++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/backends/confidential-guest-support.c b/backends/confidential-guest-support.c index d60d1f6eaa..91701f1a5f 100644 --- a/backends/confidential-guest-support.c +++ b/backends/confidential-guest-support.c @@ -46,6 +46,14 @@ static int set_guest_policy(ConfidentialGuestPolicyType policy_type, return -1; } +static int get_guest_policy(ConfidentialGuestPolicyType policy_type, + uint64_t *policy, Error **errp) +{ + error_setg(errp, + "Getting guest policy is not supported for this platform"); + return -1; +} + static int set_id_block(void *id_block, uint32_t id_block_size, void *id_auth, uint32_t id_auth_size, Error **errp) @@ -71,6 +79,7 @@ static void confidential_guest_support_class_init(ObjectClass *oc, cgsc->check_support = check_support; cgsc->set_guest_state = set_guest_state; cgsc->set_guest_policy = set_guest_policy; + cgsc->get_guest_policy = get_guest_policy; cgsc->set_id_block = set_id_block; cgsc->get_mem_map_entry = get_mem_map_entry; } diff --git a/include/system/confidential-guest-support.h b/include/system/confidential-guest-support.h index 6d35ddb97a..27ae0a21b6 100644 --- a/include/system/confidential-guest-support.h +++ b/include/system/confidential-guest-support.h @@ -137,6 +137,14 @@ typedef struct ConfidentialGuestSupportClass { int (*set_guest_policy)(ConfidentialGuestPolicyType policy_type, uint64_t policy, Error **errp); + /* + * Get the guest policy currently configured for the confidential + * platform, be it from the command line or from a previous call to + * set_guest_policy. Its format is the same as for set_guest_policy. + */ + int (*get_guest_policy)(ConfidentialGuestPolicyType policy_type, + uint64_t *policy, Error **errp); + /* * Set the SEV-SNP ID block and ID authentication block. These are * passed to SNP_LAUNCH_FINISH to provide signed verification of the diff --git a/target/i386/sev.c b/target/i386/sev.c index 38f97fd9b2..f11fdb6590 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -2758,6 +2758,29 @@ static int cgs_set_guest_policy(ConfidentialGuestPolicyType policy_type, return 0; } +static int cgs_get_guest_policy(ConfidentialGuestPolicyType policy_type, + uint64_t *policy, Error **errp) +{ + SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); + + if (policy_type != GUEST_POLICY_SEV) { + error_setg(errp, "SEV: Invalid guest policy type provided for SEV: %d", + policy_type); + return -1; + } + + if (sev_snp_enabled()) { + SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(sev_common); + + *policy = sev_snp_guest->kvm_start_conf.policy; + } else { + SevGuestState *sev_guest = SEV_GUEST(sev_common); + + *policy = sev_guest->policy; + } + return 0; +} + static int cgs_set_id_block(void *id_block, uint32_t id_block_size, void *id_auth, uint32_t id_auth_size, Error **errp) @@ -2888,6 +2911,7 @@ sev_common_instance_init(Object *obj) cgs->set_guest_state = cgs_set_guest_state; cgs->get_mem_map_entry = cgs_get_mem_map_entry; cgs->set_guest_policy = cgs_set_guest_policy; + cgs->get_guest_policy = cgs_get_guest_policy; cgs->set_id_block = cgs_set_id_block; cgs->can_rebuild_guest_state = true; -- 2.55.0
