From patchwork Fri Feb 5 08:02:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 8232551 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 9D9F6BEEE5 for ; Fri, 5 Feb 2016 08:04:44 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 675072038E for ; Fri, 5 Feb 2016 08:04:43 +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 0C2AB20384 for ; Fri, 5 Feb 2016 08:04:42 +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 1aRbLF-0007E5-Cj; Fri, 05 Feb 2016 08:02:09 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aRbLE-0007Dw-Cz for xen-devel@lists.xenproject.org; Fri, 05 Feb 2016 08:02:08 +0000 Received: from [85.158.137.68] by server-13.bemta-3.messagelabs.com id E8/97-31443-FF654B65; Fri, 05 Feb 2016 08:02:07 +0000 X-Env-Sender: JBeulich@suse.com X-Msg-Ref: server-9.tower-31.messagelabs.com!1454659324!1043168!1 X-Originating-IP: [137.65.248.74] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 7.35.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 57020 invoked from network); 5 Feb 2016 08:02:06 -0000 Received: from prv-mh.provo.novell.com (HELO prv-mh.provo.novell.com) (137.65.248.74) by server-9.tower-31.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 5 Feb 2016 08:02:06 -0000 Received: from INET-PRV-MTA by prv-mh.provo.novell.com with Novell_GroupWise; Fri, 05 Feb 2016 01:02:04 -0700 Message-Id: <56B4650B02000078000CEDBB@prv-mh.provo.novell.com> X-Mailer: Novell GroupWise Internet Agent 14.2.0 Date: Fri, 05 Feb 2016 01:02:03 -0700 From: "Jan Beulich" To: "xen-devel" References: <56B4628602000078000CED9E@prv-mh.provo.novell.com> In-Reply-To: <56B4628602000078000CED9E@prv-mh.provo.novell.com> Mime-Version: 1.0 Cc: George Dunlap , Andrew Cooper , Keir Fraser , Tim Deegan Subject: [Xen-devel] [PATCH 2/3] x86/mm: make {cmpxchg, write}_guest_entry() hook shadow mode specific 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 ... as they're being used for PV guests only, which don't use HAP mode. This eliminates another pair of NULL callbacks in HAP as well as in 2- and 3-guest-level shadow modes. Signed-off-by: Jan Beulich x86/mm: make {cmpxchg,write}_guest_entry() hook shadow mode specific ... as they're being used for PV guests only, which don't use HAP mode. This eliminates another pair of NULL callbacks in HAP as well as in 2- and 3-guest-level shadow modes. Signed-off-by: Jan Beulich --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -369,15 +369,14 @@ static void sh_audit_gw(struct vcpu *v, #endif /* audit code */ -#if (CONFIG_PAGING_LEVELS == GUEST_PAGING_LEVELS) /* * Write a new value into the guest pagetable, and update the shadows * appropriately. Returns 0 if we page-faulted, 1 for success. */ -static int -sh_write_guest_entry(struct vcpu *v, guest_intpte_t *p, - guest_intpte_t new, mfn_t gmfn) +static bool_t +sh_write_guest_entry(struct vcpu *v, intpte_t *p, intpte_t new, mfn_t gmfn) { +#if CONFIG_PAGING_LEVELS == GUEST_PAGING_LEVELS int failed; paging_lock(v->domain); @@ -387,6 +386,9 @@ sh_write_guest_entry(struct vcpu *v, gue paging_unlock(v->domain); return !failed; +#else + return 0; +#endif } /* @@ -395,10 +397,11 @@ sh_write_guest_entry(struct vcpu *v, gue * N.B. caller should check the value of "old" to see if the cmpxchg itself * was successful. */ -static int -sh_cmpxchg_guest_entry(struct vcpu *v, guest_intpte_t *p, - guest_intpte_t *old, guest_intpte_t new, mfn_t gmfn) +static bool_t +sh_cmpxchg_guest_entry(struct vcpu *v, intpte_t *p, intpte_t *old, + intpte_t new, mfn_t gmfn) { +#if CONFIG_PAGING_LEVELS == GUEST_PAGING_LEVELS int failed; guest_intpte_t t = *old; @@ -410,8 +413,10 @@ sh_cmpxchg_guest_entry(struct vcpu *v, g paging_unlock(v->domain); return !failed; +#else + return 0; +#endif } -#endif /* CONFIG == GUEST (== SHADOW) */ /**************************************************************************/ /* Functions to compute the correct index into a shadow page, given an @@ -5194,14 +5199,12 @@ const struct paging_mode sh_paging_mode .update_cr3 = sh_update_cr3, .update_paging_modes = shadow_update_paging_modes, .write_p2m_entry = shadow_write_p2m_entry, -#if CONFIG_PAGING_LEVELS == GUEST_PAGING_LEVELS - .write_guest_entry = sh_write_guest_entry, - .cmpxchg_guest_entry = sh_cmpxchg_guest_entry, -#endif .guest_levels = GUEST_PAGING_LEVELS, .shadow.detach_old_tables = sh_detach_old_tables, .shadow.x86_emulate_write = sh_x86_emulate_write, .shadow.x86_emulate_cmpxchg = sh_x86_emulate_cmpxchg, + .shadow.write_guest_entry = sh_write_guest_entry, + .shadow.cmpxchg_guest_entry = sh_cmpxchg_guest_entry, .shadow.make_monitor_table = sh_make_monitor_table, .shadow.destroy_monitor_table = sh_destroy_monitor_table, #if SHADOW_OPTIMIZATIONS & SHOPT_WRITABLE_HEURISTIC --- a/xen/include/asm-x86/paging.h +++ b/xen/include/asm-x86/paging.h @@ -87,6 +87,11 @@ struct shadow_paging_mode { unsigned long new, unsigned int bytes, struct sh_emulate_ctxt *sh_ctxt); + bool_t (*write_guest_entry )(struct vcpu *v, intpte_t *p, + intpte_t new, mfn_t gmfn); + bool_t (*cmpxchg_guest_entry )(struct vcpu *v, intpte_t *p, + intpte_t *old, intpte_t new, + mfn_t gmfn); mfn_t (*make_monitor_table )(struct vcpu *v); void (*destroy_monitor_table )(struct vcpu *v, mfn_t mmfn); int (*guess_wrmap )(struct vcpu *v, @@ -119,11 +124,6 @@ struct paging_mode { void (*write_p2m_entry )(struct domain *d, unsigned long gfn, l1_pgentry_t *p, l1_pgentry_t new, unsigned int level); - int (*write_guest_entry )(struct vcpu *v, intpte_t *p, - intpte_t new, mfn_t gmfn); - int (*cmpxchg_guest_entry )(struct vcpu *v, intpte_t *p, - intpte_t *old, intpte_t new, - mfn_t gmfn); unsigned int guest_levels; @@ -299,14 +299,15 @@ static inline void paging_update_paging_ /* Write a new value into the guest pagetable, and update the * paging-assistance state appropriately. Returns 0 if we page-faulted, * 1 for success. */ -static inline int paging_write_guest_entry(struct vcpu *v, intpte_t *p, - intpte_t new, mfn_t gmfn) +static inline bool_t paging_write_guest_entry(struct vcpu *v, intpte_t *p, + intpte_t new, mfn_t gmfn) { - if ( unlikely(paging_mode_enabled(v->domain) - && v->arch.paging.mode != NULL) ) - return paging_get_hostmode(v)->write_guest_entry(v, p, new, gmfn); - else - return (!__copy_to_user(p, &new, sizeof(new))); +#ifdef CONFIG_SHADOW_PAGING + if ( unlikely(paging_mode_shadow(v->domain)) && paging_get_hostmode(v) ) + return paging_get_hostmode(v)->shadow.write_guest_entry(v, p, new, + gmfn); +#endif + return !__copy_to_user(p, &new, sizeof(new)); } @@ -314,15 +315,16 @@ static inline int paging_write_guest_ent * paging-assistance state appropriately. Returns 0 if we page-faulted, * 1 if not. N.B. caller should check the value of "old" to see if the * cmpxchg itself was successful. */ -static inline int paging_cmpxchg_guest_entry(struct vcpu *v, intpte_t *p, - intpte_t *old, intpte_t new, - mfn_t gmfn) -{ - if ( unlikely(paging_mode_enabled(v->domain) - && v->arch.paging.mode != NULL) ) - return paging_get_hostmode(v)->cmpxchg_guest_entry(v, p, old, new, gmfn); - else - return (!cmpxchg_user(p, *old, new)); +static inline bool_t paging_cmpxchg_guest_entry(struct vcpu *v, intpte_t *p, + intpte_t *old, intpte_t new, + mfn_t gmfn) +{ +#ifdef CONFIG_SHADOW_PAGING + if ( unlikely(paging_mode_shadow(v->domain)) && paging_get_hostmode(v) ) + return paging_get_hostmode(v)->shadow.cmpxchg_guest_entry(v, p, old, + new, gmfn); +#endif + return !cmpxchg_user(p, *old, new); } /* Helper function that writes a pte in such a way that a concurrent read Reviewed-by: Andrew Cooper , but with two --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -369,15 +369,14 @@ static void sh_audit_gw(struct vcpu *v, #endif /* audit code */ -#if (CONFIG_PAGING_LEVELS == GUEST_PAGING_LEVELS) /* * Write a new value into the guest pagetable, and update the shadows * appropriately. Returns 0 if we page-faulted, 1 for success. */ -static int -sh_write_guest_entry(struct vcpu *v, guest_intpte_t *p, - guest_intpte_t new, mfn_t gmfn) +static bool_t +sh_write_guest_entry(struct vcpu *v, intpte_t *p, intpte_t new, mfn_t gmfn) { +#if CONFIG_PAGING_LEVELS == GUEST_PAGING_LEVELS int failed; paging_lock(v->domain); @@ -387,6 +386,9 @@ sh_write_guest_entry(struct vcpu *v, gue paging_unlock(v->domain); return !failed; +#else + return 0; +#endif } /* @@ -395,10 +397,11 @@ sh_write_guest_entry(struct vcpu *v, gue * N.B. caller should check the value of "old" to see if the cmpxchg itself * was successful. */ -static int -sh_cmpxchg_guest_entry(struct vcpu *v, guest_intpte_t *p, - guest_intpte_t *old, guest_intpte_t new, mfn_t gmfn) +static bool_t +sh_cmpxchg_guest_entry(struct vcpu *v, intpte_t *p, intpte_t *old, + intpte_t new, mfn_t gmfn) { +#if CONFIG_PAGING_LEVELS == GUEST_PAGING_LEVELS int failed; guest_intpte_t t = *old; @@ -410,8 +413,10 @@ sh_cmpxchg_guest_entry(struct vcpu *v, g paging_unlock(v->domain); return !failed; +#else + return 0; +#endif } -#endif /* CONFIG == GUEST (== SHADOW) */ /**************************************************************************/ /* Functions to compute the correct index into a shadow page, given an @@ -5194,14 +5199,12 @@ const struct paging_mode sh_paging_mode .update_cr3 = sh_update_cr3, .update_paging_modes = shadow_update_paging_modes, .write_p2m_entry = shadow_write_p2m_entry, -#if CONFIG_PAGING_LEVELS == GUEST_PAGING_LEVELS - .write_guest_entry = sh_write_guest_entry, - .cmpxchg_guest_entry = sh_cmpxchg_guest_entry, -#endif .guest_levels = GUEST_PAGING_LEVELS, .shadow.detach_old_tables = sh_detach_old_tables, .shadow.x86_emulate_write = sh_x86_emulate_write, .shadow.x86_emulate_cmpxchg = sh_x86_emulate_cmpxchg, + .shadow.write_guest_entry = sh_write_guest_entry, + .shadow.cmpxchg_guest_entry = sh_cmpxchg_guest_entry, .shadow.make_monitor_table = sh_make_monitor_table, .shadow.destroy_monitor_table = sh_destroy_monitor_table, #if SHADOW_OPTIMIZATIONS & SHOPT_WRITABLE_HEURISTIC --- a/xen/include/asm-x86/paging.h +++ b/xen/include/asm-x86/paging.h @@ -87,6 +87,11 @@ struct shadow_paging_mode { unsigned long new, unsigned int bytes, struct sh_emulate_ctxt *sh_ctxt); + bool_t (*write_guest_entry )(struct vcpu *v, intpte_t *p, + intpte_t new, mfn_t gmfn); + bool_t (*cmpxchg_guest_entry )(struct vcpu *v, intpte_t *p, + intpte_t *old, intpte_t new, + mfn_t gmfn); mfn_t (*make_monitor_table )(struct vcpu *v); void (*destroy_monitor_table )(struct vcpu *v, mfn_t mmfn); int (*guess_wrmap )(struct vcpu *v, @@ -119,11 +124,6 @@ struct paging_mode { void (*write_p2m_entry )(struct domain *d, unsigned long gfn, l1_pgentry_t *p, l1_pgentry_t new, unsigned int level); - int (*write_guest_entry )(struct vcpu *v, intpte_t *p, - intpte_t new, mfn_t gmfn); - int (*cmpxchg_guest_entry )(struct vcpu *v, intpte_t *p, - intpte_t *old, intpte_t new, - mfn_t gmfn); unsigned int guest_levels; @@ -299,14 +299,15 @@ static inline void paging_update_paging_ /* Write a new value into the guest pagetable, and update the * paging-assistance state appropriately. Returns 0 if we page-faulted, * 1 for success. */ -static inline int paging_write_guest_entry(struct vcpu *v, intpte_t *p, - intpte_t new, mfn_t gmfn) +static inline bool_t paging_write_guest_entry(struct vcpu *v, intpte_t *p, + intpte_t new, mfn_t gmfn) { - if ( unlikely(paging_mode_enabled(v->domain) - && v->arch.paging.mode != NULL) ) - return paging_get_hostmode(v)->write_guest_entry(v, p, new, gmfn); - else - return (!__copy_to_user(p, &new, sizeof(new))); +#ifdef CONFIG_SHADOW_PAGING + if ( unlikely(paging_mode_shadow(v->domain)) && paging_get_hostmode(v) ) + return paging_get_hostmode(v)->shadow.write_guest_entry(v, p, new, + gmfn); +#endif + return !__copy_to_user(p, &new, sizeof(new)); } @@ -314,15 +315,16 @@ static inline int paging_write_guest_ent * paging-assistance state appropriately. Returns 0 if we page-faulted, * 1 if not. N.B. caller should check the value of "old" to see if the * cmpxchg itself was successful. */ -static inline int paging_cmpxchg_guest_entry(struct vcpu *v, intpte_t *p, - intpte_t *old, intpte_t new, - mfn_t gmfn) -{ - if ( unlikely(paging_mode_enabled(v->domain) - && v->arch.paging.mode != NULL) ) - return paging_get_hostmode(v)->cmpxchg_guest_entry(v, p, old, new, gmfn); - else - return (!cmpxchg_user(p, *old, new)); +static inline bool_t paging_cmpxchg_guest_entry(struct vcpu *v, intpte_t *p, + intpte_t *old, intpte_t new, + mfn_t gmfn) +{ +#ifdef CONFIG_SHADOW_PAGING + if ( unlikely(paging_mode_shadow(v->domain)) && paging_get_hostmode(v) ) + return paging_get_hostmode(v)->shadow.cmpxchg_guest_entry(v, p, old, + new, gmfn); +#endif + return !cmpxchg_user(p, *old, new); } /* Helper function that writes a pte in such a way that a concurrent read