Re: [PATCH v2 6/8] KVM: SEV: Add SNP vCPU state get and set commands
From: Tony Lindgren
Date: Tue Sep 15 2026 - 07:38:06 EST
On Tue, Sep 08, 2026 at 12:33:36PM +0200, Jörg Rödel wrote:
> From: Joerg Roedel <joerg.roedel@xxxxxxx>
> --- a/arch/x86/kvm/svm/sev.c
> +++ b/arch/x86/kvm/svm/sev.c
...
> +static int snp_get_vcpu_state(struct kvm_vcpu *vcpu,
> + struct kvm_sev_cmd *argp)
> +{
> + struct vcpu_svm *svm = to_svm(vcpu);
> + struct kvm *kvm = vcpu->kvm;
> + struct kvm_sev_snp_vcpu_state state = {};
> +
> + if (!is_sev_snp_guest(vcpu))
> + return -ENOTTY;
> + if (!to_kvm_sev_info(kvm)->snp_context)
> + return -EINVAL;
> +
> + guard(mutex)(&svm->sev_es.snp_vmsa_mutex);
> +
> + if (VALID_PAGE(svm->sev_es.snp_guest_vmsa_gpa) &&
> + VALID_PAGE(svm->vmcb->control.vmsa_pa)) {
> + state.vmsa_gpa = svm->sev_es.snp_guest_vmsa_gpa;
> + state.valid_fields |= KVM_SEV_SNP_VCPU_STATE_VMSA_VALID;
> + }
> +
> + if (VALID_PAGE(svm->vmcb->control.ghcb_gpa)) {
> + state.ghcb_gpa = svm->vmcb->control.ghcb_gpa;
> + state.valid_fields |= KVM_SEV_SNP_VCPU_STATE_GHCB_VALID;
> + }
> +
> + if (copy_to_user(u64_to_user_ptr(argp->data), &state, sizeof(state)))
> + return -EFAULT;
> +
> + return 0;
> +}
> +
> +static int snp_set_vcpu_state(struct kvm_vcpu *vcpu,
> + struct kvm_sev_cmd *argp)
> +{
> + struct vcpu_svm *svm = to_svm(vcpu);
> + struct kvm *kvm = vcpu->kvm;
> + struct kvm_sev_info *sev = to_kvm_sev_info(kvm);
> + struct kvm_sev_snp_vcpu_state state;
> + int ret;
> +
> + if (!is_sev_snp_guest(vcpu))
> + return -ENOTTY;
> + if (!sev->snp_direct_vmsa)
> + return -EINVAL;
> + if (!sev->snp_context || kvm->arch.pre_fault_allowed)
> + return -EINVAL;
> +
> + if (copy_from_user(&state, u64_to_user_ptr(argp->data), sizeof(state)))
> + return -EFAULT;
> +
> + if (memchr_inv(state.pad, 0, sizeof(state.pad)) ||
> + state.valid_fields & ~(KVM_SEV_SNP_VCPU_STATE_VMSA_VALID |
> + KVM_SEV_SNP_VCPU_STATE_GHCB_VALID))
> + return -EINVAL;
> +
> + if (state.valid_fields & KVM_SEV_SNP_VCPU_STATE_VMSA_VALID) {
> + if (!PAGE_ALIGNED(state.vmsa_gpa) ||
> + !page_address_valid(vcpu, state.vmsa_gpa) ||
> + IS_ALIGNED(state.vmsa_gpa, PMD_SIZE))
> + return -EINVAL;
> + }
> +
> + guard(mutex)(&svm->sev_es.snp_vmsa_mutex);
> +
> + if (state.valid_fields & KVM_SEV_SNP_VCPU_STATE_VMSA_VALID) {
> + ret = sev_snp_install_guest_vmsa(svm, state.vmsa_gpa);
> + if (ret)
> + return ret;
> + } else {
> + svm->sev_es.snp_has_guest_vmsa = true;
> + svm->sev_es.snp_guest_vmsa_gpa = INVALID_PAGE;
> + svm->vmcb->control.vmsa_pa = INVALID_PAGE;
> + }
> +
> + if (state.valid_fields & KVM_SEV_SNP_VCPU_STATE_GHCB_VALID)
> + svm->vmcb->control.ghcb_gpa = state.ghcb_gpa;
> + else
> + svm->vmcb->control.ghcb_gpa = INVALID_PAGE;
> +
> + vmcb_mark_all_dirty(svm->vmcb);
> + return 0;
> +}
> +
Nice, looks like snp_get/set_vcpu_state() could quite easily make use
of KVM_EXPORT/IMPORT_VCPU?