From patchwork Mon Jan 11 16:51:19 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 8006931 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 4831A9F32E for ; Mon, 11 Jan 2016 16:54:16 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5B0662010B for ; Mon, 11 Jan 2016 16:54:15 +0000 (UTC) Received: from lists.xen.org (lists.xenproject.org [50.57.142.19]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7180F200F3 for ; Mon, 11 Jan 2016 16:54:14 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aIfgl-0005Yo-Fn; Mon, 11 Jan 2016 16:51:27 +0000 Received: from mail6.bemta4.messagelabs.com ([85.158.143.247]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aIfgk-0005YU-3F for xen-devel@lists.xen.org; Mon, 11 Jan 2016 16:51:26 +0000 Received: from [85.158.143.35] by server-1.bemta-4.messagelabs.com id 5A/28-09708-D8DD3965; Mon, 11 Jan 2016 16:51:25 +0000 X-Env-Sender: prvs=8114362ae=Andrew.Cooper3@citrix.com X-Msg-Ref: server-5.tower-21.messagelabs.com!1452531082!9508450!1 X-Originating-IP: [66.165.176.89] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni44OSA9PiAyMDMwMDc=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 7.35.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 21587 invoked from network); 11 Jan 2016 16:51:23 -0000 Received: from smtp.citrix.com (HELO SMTP.CITRIX.COM) (66.165.176.89) by server-5.tower-21.messagelabs.com with RC4-SHA encrypted SMTP; 11 Jan 2016 16:51:23 -0000 X-IronPort-AV: E=Sophos;i="5.20,553,1444694400"; d="scan'208";a="324238782" From: Andrew Cooper To: Xen-devel Date: Mon, 11 Jan 2016 16:51:19 +0000 Message-ID: <1452531079-4483-1-git-send-email-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.1.4 MIME-Version: 1.0 X-DLP: MIA2 Cc: Andrew Cooper , Stefano Stabellini , Ian Campbell , Jan Beulich Subject: [Xen-devel] [PATCH v2] x86/hvm: Allow the guest to permit the use of userspace hypercalls X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Currently, hypercalls issued from HVM userspace will unconditionally fail with -EPERM. This is inflexible, and a guest may wish to allow userspace to make hypercalls. Introduce HVMOP_set_hypercall_dpl which allows the guest to alter the permissions check for hypercalls. It behaves exactly like the dpl field for GDT/LDT/IDT entries. As the dpl is initialised to 0, hypercalls are restricted to cpl0 code until the OS explicitly chooses an alternative. Signed-off-by: Andrew Cooper --- CC: Jan Beulich CC: Ian Campbell CC: Stefano Stabellini v2: * Fix rcu lock and dpl check. * Use uint8_t for hypercall_dpl and reposition for better packing. The test framework (soon to be published officially) how has both positive and negative tests to confirm the correct behaviour of this hypercall. Arm folks: Is something like this sufficiently generic to be useful on Arm, perhaps with more generic naming? PV guest support for userspace hypercalls is substantially more involved, and will take longer to complete. --- xen/arch/x86/hvm/hvm.c | 28 +++++++++++++++++++++++++++- xen/include/asm-x86/hvm/domain.h | 2 ++ xen/include/public/hvm/hvm_op.h | 8 ++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 21470ec..5f3be6b 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -5228,7 +5228,8 @@ int hvm_do_hypercall(struct cpu_user_regs *regs) case 4: case 2: hvm_get_segment_register(curr, x86_seg_ss, &sreg); - if ( unlikely(sreg.attr.fields.dpl) ) + if ( unlikely(sreg.attr.fields.dpl > + currd->arch.hvm_domain.hypercall_dpl) ) { default: regs->eax = -EPERM; @@ -6839,6 +6840,31 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) rc = do_altp2m_op(arg); break; + case HVMOP_set_hypercall_dpl: + { + xen_hvm_hypercall_dpl_t a; + struct domain *d; + + if ( copy_from_guest(&a, arg, 1 ) ) + return -EFAULT; + + d = rcu_lock_domain_by_any_id(a.domid); + if ( d == NULL ) + return -ESRCH; + + if ( current->domain != d ) + return -EPERM; + + if ( !is_hvm_domain(d) ) + return -EINVAL; + + if ( a.dpl > 3 ) + return -EDOM; + + d->arch.hvm_domain.hypercall_dpl = a.dpl; + break; + } + default: { gdprintk(XENLOG_DEBUG, "Bad HVM op %ld.\n", op); diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h index a8cc2ad..ac426ce 100644 --- a/xen/include/asm-x86/hvm/domain.h +++ b/xen/include/asm-x86/hvm/domain.h @@ -123,6 +123,8 @@ struct hvm_domain { spinlock_t uc_lock; bool_t is_in_uc_mode; + uint8_t hypercall_dpl; + /* Pass-through */ struct hvm_iommu hvm_iommu; diff --git a/xen/include/public/hvm/hvm_op.h b/xen/include/public/hvm/hvm_op.h index 1606185..f8247db 100644 --- a/xen/include/public/hvm/hvm_op.h +++ b/xen/include/public/hvm/hvm_op.h @@ -489,6 +489,14 @@ struct xen_hvm_altp2m_op { typedef struct xen_hvm_altp2m_op xen_hvm_altp2m_op_t; DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_op_t); +#define HVMOP_set_hypercall_dpl 26 +struct xen_hvm_hypercall_dpl { + domid_t domid; + uint16_t dpl; /* IN[1:0] cpl required to make hypercalls. */ +}; +typedef struct xen_hvm_hypercall_dpl xen_hvm_hypercall_dpl_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_hypercall_dpl_t); + #endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */ /*