[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 2/3] 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 <jbeulich@xxxxxxxx>

--- 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 


Attachment: x86-paging-modify-guest-entry-sh-only.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.