All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrii Tseglytskyi <andrii.tseglytskyi@globallogic.com>
To: Ian Campbell <ian.campbell@citrix.com>,
	Stefano Stabellini <stefano.stabellini@citrix.com>,
	Julien Grall <julien.grall@linaro.org>,
	xen-devel@lists.xen.org
Subject: [PATCH v03 01/10] xen: implement guest_physmap_pin_range
Date: Tue,  2 Sep 2014 18:46:01 +0300	[thread overview]
Message-ID: <1409672770-23164-2-git-send-email-andrii.tseglytskyi@globallogic.com> (raw)
In-Reply-To: <1409672770-23164-1-git-send-email-andrii.tseglytskyi@globallogic.com>

From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

guest_physmap_pin_range pins a range of guest pages so that their p2m
mappings won't be changed.
guest_physmap_unpin_range unpins the previously pinned pages.
The pinning is done using a new count_info flag.

Provide empty stubs for x86.

Andrii Tseglytskyi <andrii.tseglytskyi@globallogic.com>:
- rebased to latest master branch
- added guest_physmap_pinned_range() API
- pass mfn instead of gmfn

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Andrii Tseglytskyi <andrii.tseglytskyi@globallogic.com>
---
 xen/arch/arm/p2m.c        | 82 +++++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/mm.h  | 11 +++++++
 xen/include/asm-x86/p2m.h | 20 ++++++++++++
 3 files changed, 113 insertions(+)

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 46ec01c..b3a16d3 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -214,6 +214,79 @@ err:
     return maddr;
 }
 
+int guest_physmap_pin_range(struct domain *d,
+                            xen_pfn_t mfn,
+                            unsigned int order)
+{
+    int i;
+    struct page_info *page;
+
+    for ( i = 0; i < (1UL << order); i++ )
+    {
+        if ( !mfn_valid(mfn + i) )
+            return -EINVAL;
+
+        page = mfn_to_page(mfn + i);
+        if ( !page )
+            return -EINVAL;
+
+        if ( !get_page_type(page, PGT_writable_page) )
+            return -EINVAL;
+
+        if ( test_and_set_bit(_PGC_p2m_pinned, &page->count_info) )
+            return -EBUSY;
+    }
+    return 0;
+}
+
+int guest_physmap_unpin_range(struct domain *d,
+                              xen_pfn_t mfn,
+                              unsigned int order)
+{
+    int i;
+    struct page_info *page;
+
+    for ( i = 0; i < (1UL << order); i++ )
+    {
+        if ( !mfn_valid(mfn + i) )
+            return -EINVAL;
+
+        page = mfn_to_page(mfn + i);
+        if ( !page )
+            return -EINVAL;
+
+        if ( !test_and_clear_bit(_PGC_p2m_pinned, &page->count_info) )
+            return -EINVAL;
+    }
+    return 0;
+}
+
+int guest_physmap_pinned_range(struct domain *d,
+                               xen_pfn_t mfn,
+                               unsigned int order)
+{
+    int i, pins = 0;
+    struct page_info *page;
+
+    for ( i = 0; i < (1UL << order); i++ )
+    {
+        if ( !mfn_valid(mfn + i) )
+            return 0;
+
+        page = mfn_to_page(mfn + i);
+        if ( !page )
+            return 0;
+
+        if ( test_bit(_PGC_p2m_pinned, &page->count_info) )
+            pins++;
+    }
+
+    if ( i && (i == pins) )
+        return 1;
+
+    return 0;
+}
+
 int guest_physmap_mark_populate_on_demand(struct domain *d,
                                           unsigned long gfn,
                                           unsigned int order)
@@ -478,10 +551,18 @@ static int apply_one_level(struct domain *d,
     struct p2m_domain *p2m = &d->arch.p2m;
     lpae_t pte;
     const lpae_t orig_pte = *entry;
+    struct page_info *page = NULL;
     int rc;
 
     BUG_ON(level > 3);
 
+    if ( guest_physmap_pinned_range(d, orig_pte.p2m.base, 0) )
+    {
+        gdprintk(XENLOG_WARNING, "cannot change p2m mapping for paddr=%"PRIpaddr
+                 " domid=%d, the page is pinned count_info %lu\n", *addr, d->domain_id, page->count_info);
+        return -EINVAL;
+    }
+
     switch ( op )
     {
     case ALLOCATE:
@@ -819,6 +900,7 @@ static int apply_p2m_changes(struct domain *d,
                               &addr, &maddr, &flush,
                               mattr, t);
         if ( ret < 0 ) { rc = ret ; goto out; }
+
         /* L3 had better have done something! We cannot descend any further */
         BUG_ON(ret == P2M_ONE_DESCEND);
         count += ret;
diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
index 9fa80a4..f6d9e6b 100644
--- a/xen/include/asm-arm/mm.h
+++ b/xen/include/asm-arm/mm.h
@@ -92,6 +92,10 @@ struct page_info
   /* Page is Xen heap? */
 #define _PGC_xen_heap     PG_shift(2)
 #define PGC_xen_heap      PG_mask(1, 2)
+/* The page belongs to a guest and it has been pinned. */
+#define _PGC_p2m_pinned   PG_shift(3)
+#define PGC_p2m_pinned    PG_mask(1, 3)
+
 /* ... */
 /* Page is broken? */
 #define _PGC_broken       PG_shift(7)
@@ -340,6 +344,13 @@ void free_init_memory(void);
 int guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn,
                                           unsigned int order);
 
+int guest_physmap_pin_range(struct domain *d, paddr_t mfn,
+                            unsigned int order);
+int guest_physmap_unpin_range(struct domain *d, paddr_t mfn,
+                              unsigned int order);
+int guest_physmap_pinned_range(struct domain *d, paddr_t mfn,
+                               unsigned int order);
+
 extern void put_page_type(struct page_info *page);
 static inline void put_page_and_type(struct page_info *page)
 {
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index 39f235d..c7f12b1 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -514,6 +514,26 @@ void guest_physmap_remove_page(struct domain *d,
 int guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn,
                                           unsigned int order);
 
+static inline int guest_physmap_pin_range(struct domain *d,
+                                          paddr_t mfn,
+                                          unsigned int order)
+{
+    return -ENOSYS;
+}
+static inline int guest_physmap_unpin_range(struct domain *d,
+                              paddr_t mfn,
+                              unsigned int order)
+{
+    return -ENOSYS;
+}
+
+static inline int guest_physmap_pinned_range(struct domain *d,
+                              paddr_t mfn,
+                              unsigned int order)
+{
+    return -ENOSYS;
+}
+
 /* Change types across all p2m entries in a domain */
 void p2m_change_entry_type_global(struct domain *d, 
                                   p2m_type_t ot, p2m_type_t nt);
-- 
1.9.1

  reply	other threads:[~2014-09-02 15:46 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-02 15:46 [PATCH v03 00/10] arm: introduce remoteprocessor iommu module Andrii Tseglytskyi
2014-09-02 15:46 ` Andrii Tseglytskyi [this message]
2014-09-03  9:43   ` [PATCH v03 01/10] xen: implement guest_physmap_pin_range Jan Beulich
2014-09-11  1:12   ` Julien Grall
2014-09-02 15:46 ` [PATCH v03 02/10] domctl: introduce access_remote_pagetable call Andrii Tseglytskyi
2014-09-03  9:46   ` Jan Beulich
2014-09-02 15:46 ` [PATCH v03 03/10] xsm: arm: create domU_rpc_t security label Andrii Tseglytskyi
2014-09-02 15:46 ` [PATCH v03 04/10] arm: introduce remoteprocessor iommu module Andrii Tseglytskyi
2014-09-11  0:41   ` Julien Grall
2014-09-02 15:46 ` [PATCH v03 05/10] arm: omap: introduce iommu translation for IPU remoteproc Andrii Tseglytskyi
2014-09-02 15:46 ` [PATCH v03 06/10] arm: omap: introduce iommu translation for GPU remoteproc Andrii Tseglytskyi
2014-09-02 15:46 ` [PATCH v03 07/10] arm: introduce remoteproc_mmu_translate_pagetable mem subops call Andrii Tseglytskyi
2014-09-03  9:48   ` Jan Beulich
2014-09-13  0:04   ` Stefano Stabellini
2014-09-02 15:46 ` [PATCH v03 08/10] arm: add trap for remoteproc mmio accesses Andrii Tseglytskyi
2014-09-03  9:52   ` Jan Beulich
2014-09-02 15:46 ` [PATCH v03 09/10] arm: omap: introduce print pagetable function for IPU remoteproc Andrii Tseglytskyi
2014-09-02 15:46 ` [PATCH v03 10/10] arm: omap: introduce print pagetable function for GPU remoteproc Andrii Tseglytskyi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1409672770-23164-2-git-send-email-andrii.tseglytskyi@globallogic.com \
    --to=andrii.tseglytskyi@globallogic.com \
    --cc=ian.campbell@citrix.com \
    --cc=julien.grall@linaro.org \
    --cc=stefano.stabellini@citrix.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.