From: Jan Beulich Date: Tue, 9 Feb 2016 12:24:00 +0000 (+0100) Subject: x86/mm: make {cmpxchg,write}_guest_entry() hook shadow mode specific X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=7d738685db11de05f43a6193faa0b11830567ead;p=people%2Fliuw%2Flibxenctrl-split%2Fxen.git 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 Reviewed-by: Andrew Cooper Reviewed-by: Tim Deegan --- diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c index d41ff84ef0..4d0b317b83 100644 --- 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, walk_t *gw) #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, guest_intpte_t *p, paging_unlock(v->domain); return !failed; +#else + return 0; +#endif } /* @@ -395,10 +397,11 @@ sh_write_guest_entry(struct vcpu *v, guest_intpte_t *p, * 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, guest_intpte_t *p, 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 diff --git a/xen/include/asm-x86/paging.h b/xen/include/asm-x86/paging.h index 1ada61f92a..ab131cc437 100644 --- 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_modes(struct vcpu *v) /* 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_entry(struct vcpu *v, intpte_t *p, * 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) +static inline bool_t 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)); +#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