[xen stable-4.7] x86/mm: Make PV linear pagetables optional

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[xen stable-4.7] x86/mm: Make PV linear pagetables optional

patchbot
commit 227cbb7bfcea21b4ff2b815527afaa513c052ac0
Author:     George Dunlap <[hidden email]>
AuthorDate: Thu Nov 16 12:00:28 2017 +0100
Commit:     Jan Beulich <[hidden email]>
CommitDate: Thu Nov 16 12:00:28 2017 +0100

    x86/mm: Make PV linear pagetables optional
   
    Allowing pagetables to point to other pagetables of the same level
    (often called 'linear pagetables') has been included in Xen since its
    inception; but recently it has been the source of a number of subtle
    reference-counting bugs.
   
    It is not used by Linux or MiniOS; but it is used by NetBSD and Novell
    Netware.  There are significant numbers of people who are never going
    to use the feature, along with significant numbers who need the
    feature.
   
    Add a Kconfig option for the feature (default to 'y').  Also add a
    command-line option to control whether PV linear pagetables are
    allowed (default to 'true').
   
    NB that we leave linear_pt_count in the page struct.  It's in a union,
    so its presence doesn't increase the size of the data struct.
    Changing the layout of the other elements based on configuration
    options is asking for trouble however; so we'll just leave it there
    and ASSERT that it's zero.
   
    Reported-by: Jann Horn <[hidden email]>
    Signed-off-by: George Dunlap <[hidden email]>
    Reviewed-by: Jan Beulich <[hidden email]>
    master commit: 3285e75dea89afb0ef5b3ee39bd15194bd7cc110
    master date: 2017-10-27 14:36:45 +0100
---
 docs/misc/xen-command-line.markdown | 19 +++++++++++++++++++
 xen/arch/x86/Kconfig                | 19 +++++++++++++++++++
 xen/arch/x86/mm.c                   | 38 ++++++++++++++++++++++++++++++++++++-
 3 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown
index 73f5265..2dacb5d 100644
--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -1280,6 +1280,25 @@ The following resources are available:
     CDP, one COS will corespond two CBMs other than one with CAT, due to the
     sum of CBMs is fixed, that means actual `cos_max` in use will automatically
     reduce to half when CDP is enabled.
+
+### pv-linear-pt
+> `= <boolean>`
+
+> Default: `true`
+
+Only available if Xen is compiled with CONFIG\_PV\_LINEAR\_PT support
+enabled.
+
+Allow PV guests to have pagetable entries pointing to other pagetables
+of the same level (i.e., allowing L2 PTEs to point to other L2 pages).
+This technique is often called "linear pagetables", and is sometimes
+used to allow operating systems a simple way to consistently map the
+current process's pagetables into its own virtual address space.
+
+Linux and MiniOS don't use this technique.  NetBSD and Novell Netware
+do; there may be other custom operating systems which do.  If you're
+certain you don't plan on having PV guests which use this feature,
+turning it off can reduce the attack surface.
 
 ### reboot
 > `= t[riple] | k[bd] | a[cpi] | p[ci] | P[ower] | e[fi] | n[o] [, [w]arm | [c]old]`
diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig
index 73f79cc..a452278 100644
--- a/xen/arch/x86/Kconfig
+++ b/xen/arch/x86/Kconfig
@@ -30,6 +30,25 @@ menu "Architecture Features"
 
 source "arch/Kconfig"
 
+config PV_LINEAR_PT
+       bool "Support for PV linear pagetables"
+       default y
+       ---help---
+         Linear pagetables (also called "recursive pagetables") refers
+         to the practice of a guest operating system having pagetable
+         entries pointing to other pagetables of the same level (i.e.,
+         allowing L2 PTEs to point to other L2 pages).  Some operating
+         systems use it as a simple way to consistently map the current
+         process's pagetables into its own virtual address space.
+
+         Linux and MiniOS don't use this technique.  NetBSD and Novell
+         Netware do; there may be other custom operating systems which
+         do.  If you're certain you don't plan on having PV guests
+         which use this feature, turning it off can reduce the attack
+         surface.
+
+         If unsure, say Y.
+
 config SHADOW_PAGING
         bool "Shadow Paging"
         default y
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 785438b..f4d2ecf 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -83,7 +83,7 @@
  * an application-supplied buffer).
  */
 
-#include <xen/config.h>
+#include <xen/kconfig.h>
 #include <xen/init.h>
 #include <xen/kernel.h>
 #include <xen/lib.h>
@@ -732,6 +732,8 @@ static void put_data_page(
         put_page(page);
 }
 
+#ifdef CONFIG_PV_LINEAR_PT
+
 static bool_t inc_linear_entries(struct page_info *pg)
 {
     typeof(pg->linear_pt_count) nc = read_atomic(&pg->linear_pt_count), oc;
@@ -799,6 +801,9 @@ static void dec_linear_uses(struct page_info *pg)
  *     frame if it is mapped by a different root table. This is sufficient and
  *     also necessary to allow validation of a root table mapping itself.
  */
+static bool_t __read_mostly opt_pv_linear_pt = 1;
+boolean_param("pv-linear-pt", opt_pv_linear_pt);
+
 #define define_get_linear_pagetable(level)                                  \
 static int                                                                  \
 get_##level##_linear_pagetable(                                             \
@@ -808,6 +813,12 @@ get_##level##_linear_pagetable(                                             \
     struct page_info *page;                                                 \
     unsigned long pfn;                                                      \
                                                                             \
+    if ( !opt_pv_linear_pt )                                                \
+    {                                                                       \
+        MEM_LOG("Attempt to create linear p.t. (feature disabled)\n");      \
+        return 0;                                                           \
+    }                                                                       \
+                                                                            \
     if ( (level##e_get_flags(pde) & _PAGE_RW) )                             \
     {                                                                       \
         MEM_LOG("Attempt to create linear p.t. with write perms");          \
@@ -864,6 +875,27 @@ get_##level##_linear_pagetable(                                             \
     return 1;                                                               \
 }
 
+#else /* CONFIG_PV_LINEAR_PT */
+
+#define define_get_linear_pagetable(level)                              \
+static int                                                              \
+get_##level##_linear_pagetable(                                         \
+        level##_pgentry_t pde, unsigned long pde_pfn, struct domain *d) \
+{                                                                       \
+        return 0;                                                       \
+}
+
+static void dec_linear_uses(struct page_info *pg)
+{
+    ASSERT(pg->linear_pt_count == 0);
+}
+
+static void dec_linear_entries(struct page_info *pg)
+{
+    ASSERT(pg->linear_pt_count == 0);
+}
+
+#endif /* CONFIG_PV_LINEAR_PT */
 
 int is_iomem_page(unsigned long mfn)
 {
@@ -2580,6 +2612,7 @@ static int _put_page_type(struct page_info *page, bool_t preemptible,
                 break;
             }
 
+#ifdef CONFIG_PV_LINEAR_PT
             if ( ptpg && PGT_type_equal(x, ptpg->u.inuse.type_info) )
             {
                 /*
@@ -2594,6 +2627,9 @@ static int _put_page_type(struct page_info *page, bool_t preemptible,
                 ASSERT(ptpg->linear_pt_count > 0);
                 ptpg = NULL;
             }
+#else /* CONFIG_PV_LINEAR_PT */
+            BUG_ON(ptpg && PGT_type_equal(x, ptpg->u.inuse.type_info));
+#endif
 
             /*
              * Record TLB information for flush later. We do not stamp page
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.7

_______________________________________________
Xen-changelog mailing list
[hidden email]
https://lists.xenproject.org/xen-changelog