]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/xen.git/commitdiff
x86/mm: make {cmpxchg,write}_guest_entry() hook shadow mode specific
authorJan Beulich <jbeulich@suse.com>
Tue, 9 Feb 2016 12:24:00 +0000 (13:24 +0100)
committerJan Beulich <jbeulich@suse.com>
Tue, 9 Feb 2016 12:24:00 +0000 (13:24 +0100)
... 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@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Tim Deegan <tim@xen.org>
xen/arch/x86/mm/shadow/multi.c
xen/include/asm-x86/paging.h

index d41ff84ef06f6ce2836f435b20e01fd941b70640..4d0b317b831da3d7e5976d07ba29fb1c461a7ed3 100644 (file)
@@ -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
index 1ada61f92a4da790771476088301ec2db7235521..ab131cc43703b7a73595c7a4d35d44e2a1fb7863 100644 (file)
@@ -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