From patchwork Fri Jan 29 10:30:36 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 8162141 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 A66B09F96D for ; Fri, 29 Jan 2016 10:33:42 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E9CF92037E for ; Fri, 29 Jan 2016 10:33:39 +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 BCB1C20328 for ; Fri, 29 Jan 2016 10:33:38 +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 1aP6KD-0001Ac-6N; Fri, 29 Jan 2016 10:30:45 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aP6KC-00011g-4e for xen-devel@lists.xenproject.org; Fri, 29 Jan 2016 10:30:44 +0000 Received: from [85.158.137.68] by server-16.bemta-3.messagelabs.com id 7C/71-07451-E4F3BA65; Fri, 29 Jan 2016 10:30:38 +0000 X-Env-Sender: JBeulich@suse.com X-Msg-Ref: server-8.tower-31.messagelabs.com!1454063436!19125936!1 X-Originating-IP: [137.65.248.74] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 7.35.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 2542 invoked from network); 29 Jan 2016 10:30:37 -0000 Received: from prv-mh.provo.novell.com (HELO prv-mh.provo.novell.com) (137.65.248.74) by server-8.tower-31.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 29 Jan 2016 10:30:37 -0000 Received: from INET-PRV-MTA by prv-mh.provo.novell.com with Novell_GroupWise; Fri, 29 Jan 2016 03:30:35 -0700 Message-Id: <56AB4D5C02000078000CC547@prv-mh.provo.novell.com> X-Mailer: Novell GroupWise Internet Agent 14.2.0 Date: Fri, 29 Jan 2016 03:30:36 -0700 From: "Jan Beulich" To: "xen-devel" References: <56AB4B6102000078000CC51B@prv-mh.provo.novell.com> In-Reply-To: <56AB4B6102000078000CC51B@prv-mh.provo.novell.com> Mime-Version: 1.0 Cc: Andrew Cooper , Keir Fraser , Harmandeep Kaur , Shuai Ruan Subject: [Xen-devel] [PATCH 4/4] x86/xstate: extend validation to cover full header 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, MIME_QP_LONG_LINE, 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 Since we never hand out compacted state, at least for now we're also not going to accept such. Reported-by: Harmandeep Kaur Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -964,7 +964,7 @@ long arch_do_domctl( { if ( evc->size >= 2 * sizeof(uint64_t) + XSTATE_AREA_MIN_SIZE ) ret = validate_xstate(_xcr0, _xcr0_accum, - _xsave_area->xsave_hdr.xstate_bv); + &_xsave_area->xsave_hdr); } else if ( !_xcr0 ) ret = 0; --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -2188,6 +2188,19 @@ static int hvm_save_cpu_xsave_states(str return 0; } +/* + * Structure layout conformity checks, documenting correctness of the cast in + * the invocation of validate_xstate() below. + * Leverage CONFIG_COMPAT machinery to perform this. + */ +#define xen_xsave_hdr xsave_hdr +#define compat_xsave_hdr hvm_hw_cpu_xsave_hdr +CHECK_FIELD_(struct, xsave_hdr, xstate_bv); +CHECK_FIELD_(struct, xsave_hdr, xcomp_bv); +CHECK_FIELD_(struct, xsave_hdr, reserved); +#undef compat_xsave_hdr +#undef xen_xsave_hdr + static int hvm_load_cpu_xsave_states(struct domain *d, hvm_domain_context_t *h) { unsigned int vcpuid, size; @@ -2243,7 +2256,7 @@ static int hvm_load_cpu_xsave_states(str h->cur += desc->length; err = validate_xstate(ctxt->xcr0, ctxt->xcr0_accum, - ctxt->save_area.xsave_hdr.xstate_bv); + (const void *)&ctxt->save_area.xsave_hdr); if ( err ) { printk(XENLOG_G_WARNING --- a/xen/arch/x86/xstate.c +++ b/xen/arch/x86/xstate.c @@ -614,17 +614,24 @@ static bool_t valid_xcr0(u64 xcr0) return !(xcr0 & XSTATE_BNDREGS) == !(xcr0 & XSTATE_BNDCSR); } -int validate_xstate(u64 xcr0, u64 xcr0_accum, u64 xstate_bv) +int validate_xstate(u64 xcr0, u64 xcr0_accum, const struct xsave_hdr *hdr) { - if ( (xstate_bv & ~xcr0_accum) || + unsigned int i; + + if ( (hdr->xstate_bv & ~xcr0_accum) || (xcr0 & ~xcr0_accum) || !valid_xcr0(xcr0) || !valid_xcr0(xcr0_accum) ) return -EINVAL; - if ( xcr0_accum & ~xfeature_mask ) + if ( (xcr0_accum & ~xfeature_mask) || + hdr->xcomp_bv ) return -EOPNOTSUPP; + for ( i = 0; i < ARRAY_SIZE(hdr->reserved); ++i ) + if ( hdr->reserved[i] ) + return -EIO; + return 0; } --- a/xen/include/asm-x86/xstate.h +++ b/xen/include/asm-x86/xstate.h @@ -72,14 +72,13 @@ struct __attribute__((aligned (64))) xsa }; } fpu_sse; - struct { + struct xsave_hdr { u64 xstate_bv; u64 xcomp_bv; u64 reserved[6]; } xsave_hdr; /* The 64-byte header */ - struct { char x[XSTATE_YMM_SIZE]; } ymm; /* YMM */ - char data[]; /* Future new states */ + char data[]; /* Variable layout states */ }; /* extended state operations */ @@ -90,7 +89,8 @@ uint64_t get_msr_xss(void); void xsave(struct vcpu *v, uint64_t mask); void xrstor(struct vcpu *v, uint64_t mask); bool_t xsave_enabled(const struct vcpu *v); -int __must_check validate_xstate(u64 xcr0, u64 xcr0_accum, u64 xstate_bv); +int __must_check validate_xstate(u64 xcr0, u64 xcr0_accum, + const struct xsave_hdr *); int __must_check handle_xsetbv(u32 index, u64 new_bv); void expand_xsave_states(struct vcpu *v, void *dest, unsigned int size); void compress_xsave_states(struct vcpu *v, const void *src, unsigned int size); --- a/xen/include/public/arch-x86/hvm/save.h +++ b/xen/include/public/arch-x86/hvm/save.h @@ -564,12 +564,11 @@ struct hvm_hw_cpu_xsave { struct { struct { char x[512]; } fpu_sse; - struct { + struct hvm_hw_cpu_xsave_hdr { uint64_t xstate_bv; /* Updated by XRSTOR */ - uint64_t reserved[7]; + uint64_t xcomp_bv; /* Updated by XRSTOR{C,S} */ + uint64_t reserved[6]; } xsave_hdr; /* The 64-byte header */ - - struct { char x[0]; } ymm; /* YMM */ } save_area; };