From mboxrd@z Thu Jan 1 00:00:00 1970 From: Joerg Roedel Subject: Re: [PATCH 2/9] Add helper functions for nested SVM v5 Date: Wed, 29 Oct 2008 14:48:49 +0100 Message-ID: <20081029134849.GD11682@8bytes.org> References: <1224522290-11740-1-git-send-email-agraf@suse.de> <1224522290-11740-2-git-send-email-agraf@suse.de> <1224522290-11740-3-git-send-email-agraf@suse.de> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: kvm@vger.kernel.org, anthony@codemonkey.ws, avi@redhat.com To: Alexander Graf Return-path: Received: from 8bytes.org ([88.198.83.132]:52549 "EHLO 8bytes.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753943AbYJ2Nsv (ORCPT ); Wed, 29 Oct 2008 09:48:51 -0400 Content-Disposition: inline In-Reply-To: <1224522290-11740-3-git-send-email-agraf@suse.de> Sender: kvm-owner@vger.kernel.org List-ID: On Mon, Oct 20, 2008 at 07:04:43PM +0200, Alexander Graf wrote: > These are helpers for the nested SVM implementation. > > - nsvm_printk implements a debug printk variant > - nested_svm_do calls a handler that can accesses gpa-based memory > > v3 makes use of the new permission checker > > Signed-off-by: Alexander Graf > --- > arch/x86/kvm/svm.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 88 insertions(+), 0 deletions(-) > > diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c > index 4ee5376..a00421b 100644 > --- a/arch/x86/kvm/svm.c > +++ b/arch/x86/kvm/svm.c > @@ -48,6 +48,16 @@ MODULE_LICENSE("GPL"); > > #define DEBUGCTL_RESERVED_BITS (~(0x3fULL)) > > +/* Turn on to get debugging output*/ > +/* #define NESTED_DEBUG */ > + > +#ifdef NESTED_DEBUG > +#define nsvm_printk(fmt, args...) printk(KERN_INFO fmt, ## args) > +#else > +static inline void nsvm_printk(char *fmt, ...) { > +} > +#endif > + > /* enable NPT for AMD64 and X86 with PAE */ > #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) > static bool npt_enabled = true; > @@ -1145,6 +1155,84 @@ static int vmmcall_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) > return 1; > } > > +static int nested_svm_check_permissions(struct vcpu_svm *svm) > +{ > + if (svm->vmcb->save.cpl) { > + printk(KERN_ERR "%s: invalid cpl 0x%x at ip 0x%lx\n", > + __func__, svm->vmcb->save.cpl, kvm_rip_read(&svm->vcpu)); This is not really a kernel error. Please remove this printk. It allows the guest to flood the logfiles of the host. > + kvm_queue_exception(&svm->vcpu, GP_VECTOR); > + return 1; > + } > + > + if (!(svm->vcpu.arch.shadow_efer & MSR_EFER_SVME_MASK) > + || !is_paging(&svm->vcpu)) { > + kvm_queue_exception(&svm->vcpu, UD_VECTOR); > + return 1; > + } > + > + return 0; > +} > + > +static struct page *nested_svm_get_page(struct vcpu_svm *svm, u64 gpa) > +{ > + struct page *page; > + > + down_read(¤t->mm->mmap_sem); > + page = gfn_to_page(svm->vcpu.kvm, gpa >> PAGE_SHIFT); > + up_read(¤t->mm->mmap_sem); > + > + if (is_error_page(page)) { > + printk(KERN_ERR "%s: could not find page at 0x%llx\n", > + __func__, gpa); > + kvm_release_page_clean(page); > + kvm_queue_exception(&svm->vcpu, GP_VECTOR); > + return NULL; > + } > + return page; > +} > + > +static int nested_svm_do(struct vcpu_svm *svm, > + u64 arg1_gpa, u64 arg2_gpa, void *opaque, > + int (*handler)(struct vcpu_svm *svm, > + void *arg1, > + void *arg2, > + void *opaque)) > +{ > + struct page *arg1_page; > + struct page *arg2_page = NULL; > + void *arg1; > + void *arg2 = NULL; > + int retval; > + > + arg1_page = nested_svm_get_page(svm, arg1_gpa); > + if(arg1_page == NULL) > + return 1; > + > + if (arg2_gpa) { > + arg2_page = nested_svm_get_page(svm, arg2_gpa); > + if(arg2_page == NULL) { > + kvm_release_page_clean(arg1_page); > + return 1; > + } > + } > + > + arg1 = kmap_atomic(arg1_page, KM_USER0); > + if (arg2_gpa) > + arg2 = kmap_atomic(arg2_page, KM_USER1); > + > + retval = handler(svm, arg1, arg2, opaque); > + > + kunmap_atomic(arg1, KM_USER0); > + if (arg2_gpa) > + kunmap_atomic(arg2, KM_USER1); > + > + kvm_release_page_dirty(arg1_page); > + if (arg2_gpa) > + kvm_release_page_dirty(arg2_page); > + > + return retval; > +} > + > static int invalid_op_interception(struct vcpu_svm *svm, > struct kvm_run *kvm_run) > { > -- > 1.5.6