Message ID | 20190829170658.16739-1-rafaeldtinoco@ubuntu.com |
---|---|
State | New |
Headers | show |
Series | [1/2,Bionic] KVM: SVM: install RSM intercept | expand |
On Thu, Aug 29, 2019 at 02:06:57PM -0300, Rafael David Tinoco wrote: > From: Brijesh Singh <brijesh.singh@amd.com> > > BugLink: https://bugs.launchpad.net/bugs/1834522 > > RSM instruction is used by the SMM handler to return from SMM mode. > Currently, rsm causes a #UD - which results in instruction fetch, > decode, and emulate. By installing the RSM intercept we can avoid the > instruction fetch since we know that #VMEXIT was due to rsm. > > The patch is required for the SEV guest, because in case of SEV guest > memory is encrypted with guest-specific key and hypervisor will not able > to fetch the instruction bytes from the guest memory. > > Cc: Paolo Bonzini <pbonzini@redhat.com> > Cc: Radim Krčmář <rkrcmar@redhat.com> > Cc: Joerg Roedel <joro@8bytes.org> > Cc: Borislav Petkov <bp@suse.de> > Cc: Tom Lendacky <thomas.lendacky@amd.com> > Signed-off-by: Brijesh Singh <brijesh.singh@amd.com> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> > (cherry-picked from commit 7607b7174405aec7441ff6c970833c463114040a) > Signed-off-by: Rafael David Tinoco <rafaeldtinoco@ubuntu.com> Good cherry-picks from upstream, fixes make sense. A cover letter would have been nicer for a patchset. Acked-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com> > > --- > arch/x86/kvm/svm.c | 11 ++++++++++- > 1 file changed, 10 insertions(+), 1 deletion(-) > > diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c > index 72765bbac9f1..538ca5446cfd 100644 > --- a/arch/x86/kvm/svm.c > +++ b/arch/x86/kvm/svm.c > @@ -298,6 +298,8 @@ module_param(vls, int, 0444); > static int vgif = true; > module_param(vgif, int, 0444); > > +static u8 rsm_ins_bytes[] = "\x0f\xaa"; > + > static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); > static void svm_flush_tlb(struct kvm_vcpu *vcpu); > static void svm_complete_interrupts(struct vcpu_svm *svm); > @@ -1292,6 +1294,7 @@ static void init_vmcb(struct vcpu_svm *svm) > set_intercept(svm, INTERCEPT_SKINIT); > set_intercept(svm, INTERCEPT_WBINVD); > set_intercept(svm, INTERCEPT_XSETBV); > + set_intercept(svm, INTERCEPT_RSM); > > if (!kvm_mwait_in_guest()) { > set_intercept(svm, INTERCEPT_MONITOR); > @@ -3441,6 +3444,12 @@ static int emulate_on_interception(struct vcpu_svm *svm) > return emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE; > } > > +static int rsm_interception(struct vcpu_svm *svm) > +{ > + return x86_emulate_instruction(&svm->vcpu, 0, 0, > + rsm_ins_bytes, 2) == EMULATE_DONE; > +} > + > static int rdpmc_interception(struct vcpu_svm *svm) > { > int err; > @@ -4327,7 +4336,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = { > [SVM_EXIT_MWAIT] = mwait_interception, > [SVM_EXIT_XSETBV] = xsetbv_interception, > [SVM_EXIT_NPF] = npf_interception, > - [SVM_EXIT_RSM] = emulate_on_interception, > + [SVM_EXIT_RSM] = rsm_interception, > [SVM_EXIT_AVIC_INCOMPLETE_IPI] = avic_incomplete_ipi_interception, > [SVM_EXIT_AVIC_UNACCELERATED_ACCESS] = avic_unaccelerated_access_interception, > }; > -- > 2.17.1 > > > -- > kernel-team mailing list > kernel-team@lists.ubuntu.com > https://lists.ubuntu.com/mailman/listinfo/kernel-team
On 8/29/19 7:06 PM, Rafael David Tinoco wrote: > From: Brijesh Singh <brijesh.singh@amd.com> > > BugLink: https://bugs.launchpad.net/bugs/1834522 > > RSM instruction is used by the SMM handler to return from SMM mode. > Currently, rsm causes a #UD - which results in instruction fetch, > decode, and emulate. By installing the RSM intercept we can avoid the > instruction fetch since we know that #VMEXIT was due to rsm. > > The patch is required for the SEV guest, because in case of SEV guest > memory is encrypted with guest-specific key and hypervisor will not able > to fetch the instruction bytes from the guest memory. > > Cc: Paolo Bonzini <pbonzini@redhat.com> > Cc: Radim Krčmář <rkrcmar@redhat.com> > Cc: Joerg Roedel <joro@8bytes.org> > Cc: Borislav Petkov <bp@suse.de> > Cc: Tom Lendacky <thomas.lendacky@amd.com> > Signed-off-by: Brijesh Singh <brijesh.singh@amd.com> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> > (cherry-picked from commit 7607b7174405aec7441ff6c970833c463114040a) > Signed-off-by: Rafael David Tinoco <rafaeldtinoco@ubuntu.com> > > --- > arch/x86/kvm/svm.c | 11 ++++++++++- > 1 file changed, 10 insertions(+), 1 deletion(-) > > diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c > index 72765bbac9f1..538ca5446cfd 100644 > --- a/arch/x86/kvm/svm.c > +++ b/arch/x86/kvm/svm.c > @@ -298,6 +298,8 @@ module_param(vls, int, 0444); > static int vgif = true; > module_param(vgif, int, 0444); > > +static u8 rsm_ins_bytes[] = "\x0f\xaa"; > + > static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); > static void svm_flush_tlb(struct kvm_vcpu *vcpu); > static void svm_complete_interrupts(struct vcpu_svm *svm); > @@ -1292,6 +1294,7 @@ static void init_vmcb(struct vcpu_svm *svm) > set_intercept(svm, INTERCEPT_SKINIT); > set_intercept(svm, INTERCEPT_WBINVD); > set_intercept(svm, INTERCEPT_XSETBV); > + set_intercept(svm, INTERCEPT_RSM); > > if (!kvm_mwait_in_guest()) { > set_intercept(svm, INTERCEPT_MONITOR); > @@ -3441,6 +3444,12 @@ static int emulate_on_interception(struct vcpu_svm *svm) > return emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE; > } > > +static int rsm_interception(struct vcpu_svm *svm) > +{ > + return x86_emulate_instruction(&svm->vcpu, 0, 0, > + rsm_ins_bytes, 2) == EMULATE_DONE; > +} > + > static int rdpmc_interception(struct vcpu_svm *svm) > { > int err; > @@ -4327,7 +4336,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = { > [SVM_EXIT_MWAIT] = mwait_interception, > [SVM_EXIT_XSETBV] = xsetbv_interception, > [SVM_EXIT_NPF] = npf_interception, > - [SVM_EXIT_RSM] = emulate_on_interception, > + [SVM_EXIT_RSM] = rsm_interception, > [SVM_EXIT_AVIC_INCOMPLETE_IPI] = avic_incomplete_ipi_interception, > [SVM_EXIT_AVIC_UNACCELERATED_ACCESS] = avic_unaccelerated_access_interception, > }; > Clean cherry-picks, good test results. For both patches: Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
On 2019-08-29 14:06:57 , Rafael David Tinoco wrote: > From: Brijesh Singh <brijesh.singh@amd.com> > > BugLink: https://bugs.launchpad.net/bugs/1834522 > > RSM instruction is used by the SMM handler to return from SMM mode. > Currently, rsm causes a #UD - which results in instruction fetch, > decode, and emulate. By installing the RSM intercept we can avoid the > instruction fetch since we know that #VMEXIT was due to rsm. > > The patch is required for the SEV guest, because in case of SEV guest > memory is encrypted with guest-specific key and hypervisor will not able > to fetch the instruction bytes from the guest memory. > > Cc: Paolo Bonzini <pbonzini@redhat.com> > Cc: Radim Krčmář <rkrcmar@redhat.com> > Cc: Joerg Roedel <joro@8bytes.org> > Cc: Borislav Petkov <bp@suse.de> > Cc: Tom Lendacky <thomas.lendacky@amd.com> > Signed-off-by: Brijesh Singh <brijesh.singh@amd.com> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> > (cherry-picked from commit 7607b7174405aec7441ff6c970833c463114040a) > Signed-off-by: Rafael David Tinoco <rafaeldtinoco@ubuntu.com> > > --- > arch/x86/kvm/svm.c | 11 ++++++++++- > 1 file changed, 10 insertions(+), 1 deletion(-) > > diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c > index 72765bbac9f1..538ca5446cfd 100644 > --- a/arch/x86/kvm/svm.c > +++ b/arch/x86/kvm/svm.c > @@ -298,6 +298,8 @@ module_param(vls, int, 0444); > static int vgif = true; > module_param(vgif, int, 0444); > > +static u8 rsm_ins_bytes[] = "\x0f\xaa"; > + > static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); > static void svm_flush_tlb(struct kvm_vcpu *vcpu); > static void svm_complete_interrupts(struct vcpu_svm *svm); > @@ -1292,6 +1294,7 @@ static void init_vmcb(struct vcpu_svm *svm) > set_intercept(svm, INTERCEPT_SKINIT); > set_intercept(svm, INTERCEPT_WBINVD); > set_intercept(svm, INTERCEPT_XSETBV); > + set_intercept(svm, INTERCEPT_RSM); > > if (!kvm_mwait_in_guest()) { > set_intercept(svm, INTERCEPT_MONITOR); > @@ -3441,6 +3444,12 @@ static int emulate_on_interception(struct vcpu_svm *svm) > return emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE; > } > > +static int rsm_interception(struct vcpu_svm *svm) > +{ > + return x86_emulate_instruction(&svm->vcpu, 0, 0, > + rsm_ins_bytes, 2) == EMULATE_DONE; > +} > + > static int rdpmc_interception(struct vcpu_svm *svm) > { > int err; > @@ -4327,7 +4336,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = { > [SVM_EXIT_MWAIT] = mwait_interception, > [SVM_EXIT_XSETBV] = xsetbv_interception, > [SVM_EXIT_NPF] = npf_interception, > - [SVM_EXIT_RSM] = emulate_on_interception, > + [SVM_EXIT_RSM] = rsm_interception, > [SVM_EXIT_AVIC_INCOMPLETE_IPI] = avic_incomplete_ipi_interception, > [SVM_EXIT_AVIC_UNACCELERATED_ACCESS] = avic_unaccelerated_access_interception, > }; > -- > 2.17.1 > > > -- > kernel-team mailing list > kernel-team@lists.ubuntu.com > https://lists.ubuntu.com/mailman/listinfo/kernel-team
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 72765bbac9f1..538ca5446cfd 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -298,6 +298,8 @@ module_param(vls, int, 0444); static int vgif = true; module_param(vgif, int, 0444); +static u8 rsm_ins_bytes[] = "\x0f\xaa"; + static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); static void svm_flush_tlb(struct kvm_vcpu *vcpu); static void svm_complete_interrupts(struct vcpu_svm *svm); @@ -1292,6 +1294,7 @@ static void init_vmcb(struct vcpu_svm *svm) set_intercept(svm, INTERCEPT_SKINIT); set_intercept(svm, INTERCEPT_WBINVD); set_intercept(svm, INTERCEPT_XSETBV); + set_intercept(svm, INTERCEPT_RSM); if (!kvm_mwait_in_guest()) { set_intercept(svm, INTERCEPT_MONITOR); @@ -3441,6 +3444,12 @@ static int emulate_on_interception(struct vcpu_svm *svm) return emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE; } +static int rsm_interception(struct vcpu_svm *svm) +{ + return x86_emulate_instruction(&svm->vcpu, 0, 0, + rsm_ins_bytes, 2) == EMULATE_DONE; +} + static int rdpmc_interception(struct vcpu_svm *svm) { int err; @@ -4327,7 +4336,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = { [SVM_EXIT_MWAIT] = mwait_interception, [SVM_EXIT_XSETBV] = xsetbv_interception, [SVM_EXIT_NPF] = npf_interception, - [SVM_EXIT_RSM] = emulate_on_interception, + [SVM_EXIT_RSM] = rsm_interception, [SVM_EXIT_AVIC_INCOMPLETE_IPI] = avic_incomplete_ipi_interception, [SVM_EXIT_AVIC_UNACCELERATED_ACCESS] = avic_unaccelerated_access_interception, };