On Tue, Apr 05, 2022, Peter Gonda wrote: > SEV-ES guests can request termination using the GHCB's MSR protocol. See > AMD's GHCB spec section '4.1.13 Termination Request'. Currently when a > guest does this the userspace VMM sees an KVM_EXIT_UNKNOWN (-EVINAL) s/EVINAL/EINVAL > return code from KVM_RUN. By adding a KVM_EXIT_SYSTEM_EVENT to kvm_run > struct the userspace VMM can clearly see the guest has requested a SEV-ES > termination including the termination reason code set and reason code. Nit, phrase that last part as a command, nowhere in the changelog is it actually stated that the patch converts to use KVM_EXIT_SYSTEM_EVENT. And my personal preference is to lead with the "what", especially when there's already a fair amount of assumed knowledge, e.g. someone that's familiar with SEV-ES probably already knows the guest can request termination, or at least won't be surprised by the news, whereas leading with the SEV-ES and GHCB info is just going to add to the confusion of someone who's clueless about SEV-ES. If an SEV-ES guest requests termination, exit to userspace with KVM_EXIT_SYSTEM_EVENT and a dedicated SEV_TERM type instead of -EINVAL so that userspace can take appropriate action. See AMD's GHCB spec section '4.1.13 Termination Request' for more details. > Signed-off-by: Peter Gonda <pgonda@xxxxxxxxxx> > Suggested-by: Sean Christopherson <seanjc@xxxxxxxxxx> > Cc: Vitaly Kuznetsov <vkuznets@xxxxxxxxxx> > Cc: Borislav Petkov <bp@xxxxxxxxx> > Cc: Tom Lendacky <thomas.lendacky@xxxxxxx> > Cc: Brijesh Singh <brijesh.singh@xxxxxxx> > Cc: Joerg Roedel <jroedel@xxxxxxx> > Cc: Marc Orr <marcorr@xxxxxxxxxx> > Cc: kvm@xxxxxxxxxxxxxxx > Cc: linux-kernel@xxxxxxxxxxxxxxx > > --- > > V4 > * Switch to using KVM_SYSTEM_EVENT exit reason. > > V3 > * Add Documentation/ update. > * Updated other KVM_EXIT_SHUTDOWN exits to clear ndata and set reason > to KVM_SHUTDOWN_REQ. > > V2 > * Add KVM_CAP_EXIT_SHUTDOWN_REASON check for KVM_CHECK_EXTENSION. > > Tested by making an SEV-ES guest call sev_es_terminate() with hardcoded > reason code set and reason code and then observing the codes from the > userspace VMM in the kvm_run.system_event fields. > > --- > arch/x86/kvm/svm/sev.c | 7 +++++-- > include/uapi/linux/kvm.h | 1 + > 2 files changed, 6 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c > index 75fa6dd268f0..039b241a9fb5 100644 > --- a/arch/x86/kvm/svm/sev.c > +++ b/arch/x86/kvm/svm/sev.c > @@ -2735,8 +2735,11 @@ 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); > > - ret = -EINVAL; > - break; > + vcpu->run->exit_reason = KVM_EXIT_SHUTDOWN; Wrong exit reason. > + vcpu->run->system_event.type = KVM_SYSTEM_EVENT_SEV_TERM; > + vcpu->run->system_event.flags = control->ghcb_gpa; > + > + return 0; > } > default: > /* Error, keep GHCB MSR value as-is */ > diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h > index 8616af85dc5d..d9d24db12930 100644 > --- a/include/uapi/linux/kvm.h > +++ b/include/uapi/linux/kvm.h > @@ -444,6 +444,7 @@ struct kvm_run { > #define KVM_SYSTEM_EVENT_SHUTDOWN 1 > #define KVM_SYSTEM_EVENT_RESET 2 > #define KVM_SYSTEM_EVENT_CRASH 3 > +#define KVM_SYSTEM_EVENT_SEV_TERM 4 > __u32 type; > __u64 flags; @type isn't properly padded, so this needs to be changed when using flags. And we definitely want to grab more room than just a single u64. Per Paolo and I's combined powers[*], use bit 31 of the type to enumerate that ndata is valid, and then change the sub-struct to: struct { #define KVM_SYSTEM_EVENT_SHUTDOWN 1 #define KVM_SYSTEM_EVENT_RESET 2 #define KVM_SYSTEM_EVENT_CRASH 3 #define KVM_SYSTEM_EVENT_SEV_TERM 4 #define KVM_SYSTEM_EVENT_NDATA_VALID (1u << 31) __u32 type; __u32 ndata; __u64 data[16]; } system_event; [*] https://lore.kernel.org/all/e0285020-49d9-8168-be4d-90940a30a048@xxxxxxxxxx > } system_event; > -- > 2.35.1.1094.g7c7d902a7c-goog >