Quoting Michael Roth (2024-04-21 13:01:00) > This patchset is also available at: > > https://github.com/amdese/linux/commits/snp-host-v14 > > and is based on commit 20cc50a0410f (just before the v13 SNP patches) from: > > https://git.kernel.org/pub/scm/virt/kvm/kvm.git/log/?h=kvm-coco-queue > > > Patch Layout > ------------ > > 01-04: These patches add some basic infrastructure and introduces a new > KVM_X86_SNP_VM vm_type to handle differences verses the existing > KVM_X86_SEV_VM and KVM_X86_SEV_ES_VM types. > > 05-07: These implement the KVM API to handle the creation of a > cryptographic launch context, encrypt/measure the initial image > into guest memory, and finalize it before launching it. > > 08-13: These implement handling for various guest-generated events such > as page state changes, onlining of additional vCPUs, etc. > > 14-17: These implement the gmem hooks needed to prepare gmem-allocated > pages before mapping them into guest private memory ranges as > well as cleaning them up prior to returning them to the host for > use as normal memory. Because this supplants certain activities > like issued WBINVDs during KVM MMU invalidations, there's also > a patch to avoid duplicating that work to avoid unecessary > overhead. > > 18: With all the core support in place, the patch adds a kvm_amd module > parameter to enable SNP support. > > 19-22: These patches all deal with the servicing of guest requests to handle > things like attestation, as well as some related host-management > interfaces. I just sent an additional set of fixups, patches 23-29. These add some additional input validation on GHCB requests, mainly ensuring that SNP-specific requests from non-SNP guests result in an error as soon as they are received rather than reaching an error state indirectly further into the call stack. It's a small diff (included below), but a bit of a pain to squash in patch by patch due to close proximity with each other, so I've pushed an updated branch here that already has them squashed in: https://github.com/amdese/linux/commits/snp-host-v14b If preferred I can also resubmit as v15, just let me know. Full diff is below. Thanks! -Mike diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 1cec466e593b..1137a7f4136b 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -3280,6 +3280,8 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm) goto vmgexit_err; break; case SVM_VMGEXIT_AP_CREATION: + if (!sev_snp_guest(vcpu->kvm)) + goto vmgexit_err; if (lower_32_bits(control->exit_info_1) != SVM_VMGEXIT_AP_DESTROY) if (!kvm_ghcb_rax_is_valid(svm)) goto vmgexit_err; @@ -3289,10 +3291,19 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm) case SVM_VMGEXIT_AP_JUMP_TABLE: case SVM_VMGEXIT_UNSUPPORTED_EVENT: case SVM_VMGEXIT_HV_FEATURES: - case SVM_VMGEXIT_PSC: case SVM_VMGEXIT_TERM_REQUEST: + break; + case SVM_VMGEXIT_PSC: case SVM_VMGEXIT_GUEST_REQUEST: + if (!sev_snp_guest(vcpu->kvm)) + goto vmgexit_err; + break; case SVM_VMGEXIT_EXT_GUEST_REQUEST: + if (!sev_snp_guest(vcpu->kvm)) + goto vmgexit_err; + if (!kvm_ghcb_rax_is_valid(svm) || + !kvm_ghcb_rbx_is_valid(svm)) + goto vmgexit_err; break; default: reason = GHCB_ERR_INVALID_EVENT; @@ -3970,6 +3981,9 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm) GHCB_MSR_INFO_MASK, GHCB_MSR_INFO_POS); break; case GHCB_MSR_PREF_GPA_REQ: + if (!sev_snp_guest(vcpu->kvm)) + goto out_terminate; + set_ghcb_msr_bits(svm, GHCB_MSR_PREF_GPA_NONE, GHCB_MSR_GPA_VALUE_MASK, GHCB_MSR_GPA_VALUE_POS); set_ghcb_msr_bits(svm, GHCB_MSR_PREF_GPA_RESP, GHCB_MSR_INFO_MASK, @@ -3978,6 +3992,9 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm) case GHCB_MSR_REG_GPA_REQ: { u64 gfn; + if (!sev_snp_guest(vcpu->kvm)) + goto out_terminate; + gfn = get_ghcb_msr_bits(svm, GHCB_MSR_GPA_VALUE_MASK, GHCB_MSR_GPA_VALUE_POS); @@ -3990,6 +4007,9 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm) break; } case GHCB_MSR_PSC_REQ: + if (!sev_snp_guest(vcpu->kvm)) + goto out_terminate; + ret = snp_begin_psc_msr(vcpu, control->ghcb_gpa); break; case GHCB_MSR_TERM_REQ: { @@ -4004,12 +4024,7 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm) pr_info("SEV-ES guest requested termination: %#llx:%#llx\n", reason_set, reason_code); - vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT; - vcpu->run->system_event.type = KVM_SYSTEM_EVENT_SEV_TERM; - vcpu->run->system_event.ndata = 1; - vcpu->run->system_event.data[0] = control->ghcb_gpa; - - return 0; + goto out_terminate; } default: /* Error, keep GHCB MSR value as-is */ @@ -4020,6 +4035,14 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm) control->ghcb_gpa, ret); return ret; + +out_terminate: + vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT; + vcpu->run->system_event.type = KVM_SYSTEM_EVENT_SEV_TERM; + vcpu->run->system_event.ndata = 1; + vcpu->run->system_event.data[0] = control->ghcb_gpa; + + return 0; } int sev_handle_vmgexit(struct kvm_vcpu *vcpu)