On 5/10/21 1:57 PM, Peter Gonda wrote: >> +static void snp_handle_guest_request(struct vcpu_svm *svm, struct ghcb *ghcb, >> + gpa_t req_gpa, gpa_t resp_gpa) >> +{ >> + struct sev_data_snp_guest_request data = {}; >> + struct kvm_vcpu *vcpu = &svm->vcpu; >> + struct kvm *kvm = vcpu->kvm; >> + kvm_pfn_t req_pfn, resp_pfn; >> + struct kvm_sev_info *sev; >> + int rc, err = 0; >> + >> + if (!sev_snp_guest(vcpu->kvm)) { >> + rc = -ENODEV; >> + goto e_fail; >> + } >> + >> + sev = &to_kvm_svm(kvm)->sev_info; >> + >> + if (!__ratelimit(&sev->snp_guest_msg_rs)) { >> + pr_info_ratelimited("svm: too many guest message requests\n"); >> + rc = -EAGAIN; >> + goto e_fail; >> + } >> + >> + if (!IS_ALIGNED(req_gpa, PAGE_SIZE) || !IS_ALIGNED(resp_gpa, PAGE_SIZE)) { >> + pr_err("svm: guest request (%#llx) or response (%#llx) is not page aligned\n", >> + req_gpa, resp_gpa); >> + goto e_term; >> + } >> + >> + req_pfn = gfn_to_pfn(kvm, gpa_to_gfn(req_gpa)); >> + if (is_error_noslot_pfn(req_pfn)) { >> + pr_err("svm: guest request invalid gpa=%#llx\n", req_gpa); >> + goto e_term; >> + } >> + >> + resp_pfn = gfn_to_pfn(kvm, gpa_to_gfn(resp_gpa)); >> + if (is_error_noslot_pfn(resp_pfn)) { >> + pr_err("svm: guest response invalid gpa=%#llx\n", resp_gpa); >> + goto e_term; >> + } >> + >> + data.gctx_paddr = __psp_pa(sev->snp_context); >> + data.req_paddr = __sme_set(req_pfn << PAGE_SHIFT); >> + data.res_paddr = __psp_pa(sev->snp_resp_page); >> + >> + mutex_lock(&kvm->lock); >> + >> + rc = sev_issue_cmd(kvm, SEV_CMD_SNP_GUEST_REQUEST, &data, &err); >> + if (rc) { >> + mutex_unlock(&kvm->lock); >> + >> + /* If we have a firmware error code then use it. */ >> + if (err) >> + rc = err; >> + >> + goto e_fail; >> + } >> + >> + /* Copy the response after the firmware returns success. */ >> + rc = kvm_write_guest(kvm, resp_gpa, sev->snp_resp_page, PAGE_SIZE); >> + >> + mutex_unlock(&kvm->lock); >> + >> +e_fail: >> + ghcb_set_sw_exit_info_2(ghcb, rc); >> + return; >> + >> +e_term: >> + ghcb_set_sw_exit_info_1(ghcb, 1); >> + ghcb_set_sw_exit_info_2(ghcb, >> + X86_TRAP_GP | >> + SVM_EVTINJ_TYPE_EXEPT | >> + SVM_EVTINJ_VALID); >> +} > I am probably missing something in the spec but I don't see any > references to #GP in the '4.1.7 SNP Guest Request' section. Why is > this different from e_fail? The spec does not say to inject the #GP, I chose this because guest is not adhering to the spec and there was a not a good error code in the GHCB spec to communicate this condition. Per the spec, both the request and response page must be a valid GPA. If we detect that guest is not following the spec then its a guest BUG. IIRC, other places in the KVM does something similar when guest is trying invalid operation. -Brijesh