On Mon, Jun 20, 2022 at 5:11 PM Ashish Kalra <Ashish.Kalra@xxxxxxx> wrote: > > From: Brijesh Singh <brijesh.singh@xxxxxxx> > > On VMGEXIT, sev_handle_vmgexit() creates a host mapping for the GHCB GPA, > and unmaps it just before VM-entry. This long-lived GHCB map is used by > the VMGEXIT handler through accessors such as ghcb_{set_get}_xxx(). > > A long-lived GHCB map can cause issue when SEV-SNP is enabled. When > SEV-SNP is enabled the mapped GPA needs to be protected against a page > state change. > > To eliminate the long-lived GHCB mapping, update the GHCB sync operations > to explicitly map the GHCB before access and unmap it after access is > complete. This requires that the setting of the GHCBs sw_exit_info_{1,2} > fields be done during sev_es_sync_to_ghcb(), so create two new fields in > the vcpu_svm struct to hold these values when required to be set outside > of the GHCB mapping. > > Signed-off-by: Brijesh Singh <brijesh.singh@xxxxxxx> > --- > arch/x86/kvm/svm/sev.c | 131 ++++++++++++++++++++++++++--------------- > arch/x86/kvm/svm/svm.c | 12 ++-- > arch/x86/kvm/svm/svm.h | 24 +++++++- > 3 files changed, 111 insertions(+), 56 deletions(-) > > diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c > index 01ea257e17d6..c70f3f7e06a8 100644 > --- a/arch/x86/kvm/svm/sev.c > +++ b/arch/x86/kvm/svm/sev.c > @@ -2823,15 +2823,40 @@ void sev_free_vcpu(struct kvm_vcpu *vcpu) > kvfree(svm->sev_es.ghcb_sa); > } > > +static inline int svm_map_ghcb(struct vcpu_svm *svm, struct kvm_host_map *map) > +{ > + struct vmcb_control_area *control = &svm->vmcb->control; > + u64 gfn = gpa_to_gfn(control->ghcb_gpa); > + > + if (kvm_vcpu_map(&svm->vcpu, gfn, map)) { > + /* Unable to map GHCB from guest */ > + pr_err("error mapping GHCB GFN [%#llx] from guest\n", gfn); > + return -EFAULT; > + } > + > + return 0; > +} There is a perf cost to this suggestion but it might make accessing the GHCB safer for KVM. Have you thought about just using kvm_read_guest() or copy_from_user() to fully copy out the GCHB into a KVM owned buffer, then copying it back before the VMRUN. That way the KVM doesn't need to guard against page_state_changes on the GHCBs, that could be a perf improvement in a follow up. Since we cannot unmap GHCBs I don't think UPM will help here so we probably want to make these patches safe against malicious guests making GHCBs private. But maybe UPM does help?