]> xenbits.xensource.com Git - people/liuw/xen.git/commitdiff
x86/shadow: sh_{write,cmpxchg}_guest_entry() are PV-only
authorJan Beulich <jbeulich@suse.com>
Tue, 12 Mar 2019 13:45:36 +0000 (14:45 +0100)
committerJan Beulich <jbeulich@suse.com>
Tue, 12 Mar 2019 13:45:36 +0000 (14:45 +0100)
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@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
xen/arch/x86/mm.c
xen/arch/x86/mm/shadow/Makefile
xen/arch/x86/mm/shadow/multi.c
xen/arch/x86/mm/shadow/private.h
xen/arch/x86/mm/shadow/pv.c [new file with mode: 0644]
xen/include/asm-x86/paging.h

index 3557cd1178989d30d6860896d4fe71aaac45e5af..dbec130da0ca74f3de1e7dd019082b70cf144b02 100644 (file)
 #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
index 72658f3fc6e27c394b15ed54de8a727799b38cab..ff03a9937f9b02c9464239c4db10f295163d05e7 100644 (file)
@@ -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
index 3e5651d0298c97778deaf1de45731e7444007419..953c0344aa6edb5ca08acc5967bfb556005676ff 100644 (file)
@@ -372,55 +372,6 @@ static void sh_audit_gw(struct vcpu *v, const walk_t *gw)
 #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
index 5a94b20c4d24a5a0a2232ae879257e90779ed42d..3251f34ba0a385979a7d0be6d28a9cc86c8893d3 100644 (file)
@@ -372,6 +372,12 @@ int shadow_write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn,
                            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. */
diff --git a/xen/arch/x86/mm/shadow/pv.c b/xen/arch/x86/mm/shadow/pv.c
new file mode 100644 (file)
index 0000000..25dca1e
--- /dev/null
@@ -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:
+ */
index 18a7eaeca405cce65e573add79580ff54e84b5fe..0d212d352e8f9f02a03b0879ef713378c6e20108 100644 (file)
@@ -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_modes(struct vcpu *v)
     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_entry(
     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)