Re: [PATCH] KVM: SEV: Return INVALID_INPUT on SNP req/resp buffer access failure
From: Jacky Li
Date: Tue Sep 22 2026 - 16:29:24 EST
On Mon, Sep 21, 2026 at 11:53 AM Sean Christopherson <seanjc@xxxxxxxxxx> wrote:
>
> No, kvm_vcpu_map() actually has far worse semantics. GUP pins the *page*, it does
> not pin the userspace mapping. I.e. kvm_vcpu_map() guarantees that KVM won't write
> to a freed page, but that's literally it. E.g. if userspace mprotect()'s the page
> to make it read-only, KVM will write to what is supposed to be a RO page. Or if
> userspace completely unmaps the page, KVM will write to soon-to-be-freed memory.
Sorry for the confusion. I didn't mean writing to the response page through
map.hva; I only meant calling kvm_vcpu_map() to validate and pin the page,
while still using kvm_write_guest() to copy the response back:
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -4231,19 +4231,25 @@ static int snp_handle_guest_req(struct
vcpu_svm *svm, gpa_t req_gpa, gpa_t resp_
if (kvm_read_guest(kvm, req_gpa, sev->guest_req_buf, PAGE_SIZE))
return -EIO;
+ CLASS(kvm_vcpu_map_local, map)(&svm->vcpu, gpa_to_gfn(resp_gpa));
+ if (map.ret) {
+ svm_vmgexit_bad_input(svm, GHCB_ERR_INVALID_INPUT);
+ return 1;
+ }
+
data.gctx_paddr = __psp_pa(sev->snp_context);
data.req_paddr = __psp_pa(sev->guest_req_buf);
data.res_paddr = __psp_pa(sev->guest_resp_buf);
/*
* Firmware failures are propagated on to guest, but any other failure
* condition along the way should be reported to userspace. E.g. if
* the PSP is dead and commands are timing out.
*/
ret = sev_issue_cmd(kvm, SEV_CMD_SNP_GUEST_REQUEST, &data, &fw_err);
if (ret && !fw_err)
return ret;
if (kvm_write_guest(kvm, resp_gpa, sev->guest_resp_buf, PAGE_SIZE))
return -EIO;
Because the actual payload write still goes through kvm_write_guest()
(uaccess) rather than map.hva, a concurrent mprotect(PROT_READ) or
munmap() would still cause kvm_write_guest() to fail rather than
overwriting a read-only page or soon-to-be-freed memory.
> Who cares? The guest can only hurt itself by converting resp_gpa to private.
The only reason we care from the hypervisor's perspective is that
a post-command -EIO/-EFAULT exit causes the VMM to abort and looks like
a hypervisor infrastructure failure rather than a guest error.
That said, this only matters if a malicious guest deliberately races a
conversion against its own request. Given the complexity of a gpc and
that kvm_vcpu_map() is being phased out, the 1-byte tickle write is much
simpler and good enough to protect normal guests from burning their
VMPCK or killing the VM over a bad resp_gpa.
I'll send a v2 with the tickle approach. Thanks!