[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2/2] x86/shadow: sh_{write, cmpxchg}_guest_entry() are PV-only
Move them to a new pv.c. Make the respective struct shadow_paging_mode fields as well as the paging.h wrappers PV-only as well. Take the liberty and switch both functions' "failed" local variables to more appropriate types. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -146,7 +146,9 @@ #include <asm/pv/grant_table.h> #include <asm/pv/mm.h> +#ifdef CONFIG_PV #include "pv/mm.h" +#endif /* Override macros from asm/page.h to make them work with mfn_t */ #undef virt_to_mfn --- a/xen/arch/x86/mm/shadow/Makefile +++ b/xen/arch/x86/mm/shadow/Makefile @@ -1,6 +1,7 @@ ifeq ($(CONFIG_SHADOW_PAGING),y) obj-y += common.o guest_2.o guest_3.o guest_4.o obj-$(CONFIG_HVM) += hvm.o +obj-$(CONFIG_PV) += pv.o else obj-y += none.o endif --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -372,55 +372,6 @@ static void sh_audit_gw(struct vcpu *v, #endif /* SHADOW_AUDIT & SHADOW_AUDIT_ENTRIES */ } -/* - * Write a new value into the guest pagetable, and update the shadows - * appropriately. Returns false if we page-faulted, true for success. - */ -static bool -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); - failed = __copy_to_user(p, &new, sizeof(new)); - if ( failed != sizeof(new) ) - sh_validate_guest_entry(v, gmfn, p, sizeof(new)); - paging_unlock(v->domain); - - return !failed; -#else - return false; -#endif -} - -/* - * Cmpxchg a new value into the guest pagetable, and update the shadows - * appropriately. Returns false if we page-faulted, true if not. - * N.B. caller should check the value of "old" to see if the cmpxchg itself - * was successful. - */ -static bool -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; - - paging_lock(v->domain); - failed = cmpxchg_user(p, t, new); - if ( t == *old ) - sh_validate_guest_entry(v, gmfn, p, sizeof(new)); - *old = t; - paging_unlock(v->domain); - - return !failed; -#else - return false; -#endif -} - /**************************************************************************/ /* Functions to compute the correct index into a shadow page, given an * index into the guest page (as returned by guest_get_index()). @@ -4925,8 +4876,10 @@ const struct paging_mode sh_paging_mode .write_p2m_entry = shadow_write_p2m_entry, .guest_levels = GUEST_PAGING_LEVELS, .shadow.detach_old_tables = sh_detach_old_tables, +#ifdef CONFIG_PV .shadow.write_guest_entry = sh_write_guest_entry, .shadow.cmpxchg_guest_entry = sh_cmpxchg_guest_entry, +#endif .shadow.make_monitor_table = sh_make_monitor_table, .shadow.destroy_monitor_table = sh_destroy_monitor_table, #if SHADOW_OPTIMIZATIONS & SHOPT_WRITABLE_HEURISTIC --- a/xen/arch/x86/mm/shadow/private.h +++ b/xen/arch/x86/mm/shadow/private.h @@ -372,6 +372,12 @@ int shadow_write_p2m_entry(struct p2m_do l1_pgentry_t *p, l1_pgentry_t new, unsigned int level); +/* Functions that atomically write PV guest PT entries */ +bool sh_write_guest_entry(struct vcpu *v, intpte_t *p, intpte_t new, + mfn_t gmfn); +bool sh_cmpxchg_guest_entry(struct vcpu *v, intpte_t *p, intpte_t *old, + intpte_t new, mfn_t gmfn); + /* Update all the things that are derived from the guest's CR0/CR3/CR4. * Called to initialize paging structures if the paging mode * has changed, and when bringing up a VCPU for the first time. */ --- /dev/null +++ b/xen/arch/x86/mm/shadow/pv.c @@ -0,0 +1,75 @@ +/****************************************************************************** + * arch/x86/mm/shadow/pv.c + * + * PV-only shadow code (which hence does not need to be multiply compiled). + * Parts of this code are Copyright (c) 2006 by XenSource Inc. + * Parts of this code are Copyright (c) 2006 by Michael A Fetterman + * Parts based on earlier work by Michael A Fetterman, Ian Pratt et al. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; If not, see <http://www.gnu.org/licenses/>. + */ + +#include <xen/types.h> +#include <asm/shadow.h> +#include "private.h" + +/* + * Write a new value into the guest pagetable, and update the shadows + * appropriately. Returns false if we page-faulted, true for success. + */ +bool +sh_write_guest_entry(struct vcpu *v, intpte_t *p, intpte_t new, mfn_t gmfn) +{ + unsigned int failed; + + paging_lock(v->domain); + failed = __copy_to_user(p, &new, sizeof(new)); + if ( failed != sizeof(new) ) + sh_validate_guest_entry(v, gmfn, p, sizeof(new)); + paging_unlock(v->domain); + + return !failed; +} + +/* + * Cmpxchg a new value into the guest pagetable, and update the shadows + * appropriately. Returns false if we page-faulted, true if not. + * N.B. caller should check the value of "old" to see if the cmpxchg itself + * was successful. + */ +bool +sh_cmpxchg_guest_entry(struct vcpu *v, intpte_t *p, intpte_t *old, + intpte_t new, mfn_t gmfn) +{ + bool failed; + intpte_t t = *old; + + paging_lock(v->domain); + failed = cmpxchg_user(p, t, new); + if ( t == *old ) + sh_validate_guest_entry(v, gmfn, p, sizeof(new)); + *old = t; + paging_unlock(v->domain); + + return !failed; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ --- a/xen/include/asm-x86/paging.h +++ b/xen/include/asm-x86/paging.h @@ -86,11 +86,13 @@ struct sh_emulate_ctxt; struct shadow_paging_mode { #ifdef CONFIG_SHADOW_PAGING void (*detach_old_tables )(struct vcpu *v); +#ifdef CONFIG_PV bool (*write_guest_entry )(struct vcpu *v, intpte_t *p, intpte_t new, mfn_t gmfn); bool (*cmpxchg_guest_entry )(struct vcpu *v, intpte_t *p, intpte_t *old, intpte_t new, mfn_t gmfn); +#endif mfn_t (*make_monitor_table )(struct vcpu *v); void (*destroy_monitor_table )(struct vcpu *v, mfn_t mmfn); int (*guess_wrmap )(struct vcpu *v, @@ -290,6 +292,7 @@ static inline void paging_update_paging_ paging_get_hostmode(v)->update_paging_modes(v); } +#ifdef CONFIG_PV /* * Write a new value into the guest pagetable, and update the @@ -325,6 +328,8 @@ static inline bool paging_cmpxchg_guest_ return !cmpxchg_user(p, *old, new); } +#endif /* CONFIG_PV */ + /* Helper function that writes a pte in such a way that a concurrent read * never sees a half-written entry that has _PAGE_PRESENT set */ static inline void safe_write_pte(l1_pgentry_t *p, l1_pgentry_t new) _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |