From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
To: xen-devel@lists.xensource.com
Cc: Tim.Deegan@xen.org, Ian.Campbell@citrix.com,
Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Subject: [PATCH v2 4/6] xen/arm: implement get/put_page_type
Date: Fri, 20 Jul 2012 16:05:56 +0100 [thread overview]
Message-ID: <1342796758-4958-4-git-send-email-stefano.stabellini@eu.citrix.com> (raw)
In-Reply-To: <1342796758-4958-1-git-send-email-stefano.stabellini@eu.citrix.com>
Add a basic get_page_type and put_page_type implementation: the
implementation is similar to the x86 one, without all the code to handle
shadow pagetables and other unneeded features.
Also remove PGT_shared_page, that is unused.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
xen/arch/arm/dummy.S | 4 --
xen/arch/arm/mm.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++
xen/include/asm-arm/mm.h | 1 -
3 files changed, 91 insertions(+), 5 deletions(-)
diff --git a/xen/arch/arm/dummy.S b/xen/arch/arm/dummy.S
index baced25..2b96d22 100644
--- a/xen/arch/arm/dummy.S
+++ b/xen/arch/arm/dummy.S
@@ -22,10 +22,6 @@ DUMMY(arch_get_info_guest);
DUMMY(arch_vcpu_reset);
NOP(update_vcpu_system_time);
-/* Page Reference & Type Maintenance */
-DUMMY(get_page_type);
-DUMMY(put_page_type);
-
/* Grant Tables */
DUMMY(steal_page);
diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index 01a6781..7033023 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -28,8 +28,10 @@
#include <xen/guest_access.h>
#include <asm/page.h>
#include <asm/current.h>
+#include <asm/flushtlb.h>
#include <public/memory.h>
#include <xen/sched.h>
+#include <xen/perfc.h>
struct domain *dom_xen, *dom_io;
@@ -604,6 +606,95 @@ int get_page(struct page_info *page, struct domain *domain)
return 0;
}
+void put_page_type(struct page_info *page)
+{
+ unsigned long nx, x, y = page->u.inuse.type_info;
+
+ for ( ; ; )
+ {
+ x = y;
+ nx = x - 1;
+
+ ASSERT((x & PGT_count_mask) != 0);
+
+ if ( unlikely((nx & PGT_count_mask) == 0) )
+ /*
+ * Record TLB information for flush later
+ */
+ page->tlbflush_timestamp = tlbflush_current_time();
+
+ if ( likely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) == x) )
+ break;
+ }
+}
+
+int get_page_type(struct page_info *page, unsigned long type)
+{
+ unsigned long nx, x, y = page->u.inuse.type_info;
+
+ for ( ; ; )
+ {
+ x = y;
+ nx = x + 1;
+ if ( unlikely((nx & PGT_count_mask) == 0) )
+ {
+ printk("Type count overflow on pfn %lx", page_to_mfn(page));
+ return -EINVAL;
+ }
+ else if ( (x & PGT_count_mask) == 0 )
+ {
+ struct domain *d = page_get_owner(page);
+
+ if ( (x & PGT_type_mask) != type )
+ {
+ /*
+ * On type change we check to flush stale TLB entries. This
+ * may be unnecessary (e.g., page was GDT/LDT) but those
+ * circumstances should be very rare.
+ */
+ cpumask_t mask;
+
+ cpumask_copy(&mask, d->domain_dirty_cpumask);
+
+ /* Don't flush if the timestamp is old enough */
+ tlbflush_filter(mask, page->tlbflush_timestamp);
+
+ if ( unlikely(!cpumask_empty(&mask)) )
+ {
+ perfc_incr(need_flush_tlb_flush);
+ flush_tlb_mask(&mask);
+ }
+
+ /* We lose existing type and validity. */
+ nx &= ~(PGT_type_mask | PGT_validated);
+ nx |= type;
+
+ /* No special validation needed for writable pages. */
+ /* Page tables and GDT/LDT need to be scanned for validity. */
+ if ( type == PGT_writable_page )
+ nx |= PGT_validated;
+ }
+ }
+ else if ( unlikely(!(x & PGT_validated)) )
+ {
+ /* Someone else is updating validation of this page. Wait... */
+ while ( (y = page->u.inuse.type_info) == x )
+ {
+ cpu_relax();
+ }
+ continue;
+ }
+
+ if ( likely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) == x) )
+ break;
+ }
+
+ if ( unlikely(!(nx & PGT_validated)) )
+ BUG();
+
+ return 1;
+}
+
void gnttab_clear_flag(unsigned long nr, uint16_t *addr)
{
/*
diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
index 53801b0..b37bd35 100644
--- a/xen/include/asm-arm/mm.h
+++ b/xen/include/asm-arm/mm.h
@@ -71,7 +71,6 @@ struct page_info
#define PGT_none PG_mask(0, 4) /* no special uses of this page */
#define PGT_writable_page PG_mask(7, 4) /* has writable mappings? */
-#define PGT_shared_page PG_mask(8, 4) /* CoW sharable page */
#define PGT_type_mask PG_mask(15, 4) /* Bits 28-31 or 60-63. */
/* Owning guest has pinned this page to its current type? */
--
1.7.2.5
next prev parent reply other threads:[~2012-07-20 15:05 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-20 15:05 [PATCH v2 0/6] xen/arm: grant_table Stefano Stabellini
2012-07-20 15:05 ` [PATCH v2 1/6] Initialize lr_queue in vcpu_vgic_init for the first 32 irqs Stefano Stabellini
2012-07-20 15:05 ` [PATCH v2 2/6] xen/arm: set paging_mode_translate and paging_mode_external Stefano Stabellini
2012-07-20 15:05 ` [PATCH v2 3/6] xen/arm: implement page reference and grant table functions needed by grant_table.c Stefano Stabellini
2012-07-23 16:03 ` Ian Campbell
2012-07-24 10:25 ` Stefano Stabellini
2012-07-24 10:41 ` Ian Campbell
2012-07-26 17:56 ` Stefano Stabellini
2012-07-27 7:57 ` Ian Campbell
2012-07-20 15:05 ` Stefano Stabellini [this message]
2012-07-23 16:08 ` [PATCH v2 4/6] xen/arm: implement get/put_page_type Ian Campbell
2012-07-24 10:27 ` Stefano Stabellini
2012-07-24 10:42 ` Ian Campbell
2012-07-26 18:03 ` Stefano Stabellini
2012-07-23 20:01 ` Tim Deegan
2012-07-24 10:21 ` Stefano Stabellini
2012-07-20 15:05 ` [PATCH v2 5/6] xen/arm: create_p2m_entries should not call free_domheap_page Stefano Stabellini
2012-07-23 16:25 ` Ian Campbell
2012-07-24 10:28 ` Stefano Stabellini
2012-07-20 15:05 ` [PATCH v2 6/6] xen/arm: grant table Stefano Stabellini
2012-07-23 16:13 ` Ian Campbell
2012-07-24 10:30 ` Stefano Stabellini
2012-07-23 16:24 ` [PATCH v2 1/6] Initialize lr_queue in vcpu_vgic_init for the first 32 irqs Ian Campbell
2012-07-23 16:30 ` [PATCH v2 0/6] xen/arm: grant_table Ian Campbell
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=1342796758-4958-4-git-send-email-stefano.stabellini@eu.citrix.com \
--to=stefano.stabellini@eu.citrix.com \
--cc=Ian.Campbell@citrix.com \
--cc=Tim.Deegan@xen.org \
--cc=xen-devel@lists.xensource.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).