WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] This patch defines a new P2M type used fo

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] This patch defines a new P2M type used for sharable/shared pages. It also
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 16 Dec 2009 22:40:54 -0800
Delivery-date: Wed, 16 Dec 2009 22:42:46 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1261031276 0
# Node ID 7d841016536f4e5de66b387114c8e4ed67f76148
# Parent  3a3be3938b2c71d179330b10fcb187db00c837b2
This patch defines a new P2M type used for sharable/shared pages. It also
implements the basic functions to nominate GFNs for sharing, and to break
sharing (either by making page 'private' or creating private copy),
mem_sharing_nominate_page() and mem_sharing_unshare_page() respectively. Note
pages cannot be shared yet, because there is no efficient way to find all GFNs
mapping to the two MFNs scheduled for sharing.

Signed-off-by: Grzegorz Milos <Grzegorz.Milos@xxxxxxxxxx>
---
 tools/xenpaging/xenpaging.c       |    4 
 xen/arch/x86/mm/Makefile          |    1 
 xen/arch/x86/mm/mem_sharing.c     |  268 ++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/mm/p2m.c             |   41 +++++
 xen/include/asm-x86/mem_sharing.h |   38 +++++
 xen/include/asm-x86/p2m.h         |   20 ++
 xen/include/public/mem_event.h    |    4 
 7 files changed, 369 insertions(+), 7 deletions(-)

diff -r 3a3be3938b2c -r 7d841016536f tools/xenpaging/xenpaging.c
--- a/tools/xenpaging/xenpaging.c       Thu Dec 17 06:27:56 2009 +0000
+++ b/tools/xenpaging/xenpaging.c       Thu Dec 17 06:27:56 2009 +0000
@@ -566,11 +566,11 @@ int main(int argc, char *argv[])
             else
             {
                 DPRINTF("page already populated (domain = %d; vcpu = %d; gfn = 
%lx; paused = %ld)\n",
-                        paging->mem_event.domain_id, req.vcpu_id, req.gfn, 
req.flags & MEM_EVENT_FLAG_PAUSED);
+                        paging->mem_event.domain_id, req.vcpu_id, req.gfn, 
req.flags & MEM_EVENT_FLAG_VCPU_PAUSED);
 
                 /* Tell Xen to resume the vcpu */
                 /* XXX: Maybe just check if the vcpu was paused? */
-                if ( req.flags & MEM_EVENT_FLAG_PAUSED )
+                if ( req.flags & MEM_EVENT_FLAG_VCPU_PAUSED )
                 {
                     /* Prepare the response */
                     rsp.gfn = req.gfn;
diff -r 3a3be3938b2c -r 7d841016536f xen/arch/x86/mm/Makefile
--- a/xen/arch/x86/mm/Makefile  Thu Dec 17 06:27:56 2009 +0000
+++ b/xen/arch/x86/mm/Makefile  Thu Dec 17 06:27:56 2009 +0000
@@ -8,6 +8,7 @@ obj-$(x86_64) += guest_walk_4.o
 obj-$(x86_64) += guest_walk_4.o
 obj-y += mem_event.o
 obj-y += mem_paging.o
+obj-y += mem_sharing.o
 
 guest_walk_%.o: guest_walk.c Makefile
        $(CC) $(CFLAGS) -DGUEST_PAGING_LEVELS=$* -c $< -o $@
diff -r 3a3be3938b2c -r 7d841016536f xen/arch/x86/mm/mem_sharing.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/mm/mem_sharing.c     Thu Dec 17 06:27:56 2009 +0000
@@ -0,0 +1,268 @@
+/******************************************************************************
+ * arch/x86/mm/mem_sharing.c
+ *
+ * Memory sharing support.
+ *
+ * Copyright (c) 2009 Citrix (R&D) Ltd. (Grzegorz Milos)
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <asm/page.h>
+#include <asm/string.h>
+#include <asm/p2m.h>
+#include <asm/mem_event.h>
+#include <xen/domain_page.h>
+
+#undef mfn_to_page
+#define mfn_to_page(_m) __mfn_to_page(mfn_x(_m))
+#undef mfn_valid
+#define mfn_valid(_mfn) __mfn_valid(mfn_x(_mfn))
+#undef page_to_mfn
+#define page_to_mfn(_pg) _mfn(__page_to_mfn(_pg))
+
+
+static struct page_info* mem_sharing_alloc_page(struct domain *d, 
+                                                unsigned long gfn,
+                                                int must_succeed)
+{
+    struct page_info* page;
+    struct vcpu *v = current;
+    mem_event_request_t req;
+
+    page = alloc_domheap_page(d, 0); 
+    if(page != NULL) return page;
+
+    memset(&req, 0, sizeof(req));
+    if(must_succeed) 
+    {
+        /* We do not support 'must_succeed' any more. External operations such
+         * as grant table mappings may fail with OOM condition! 
+         */
+        BUG();
+    }
+    else
+    {
+        /* All foreign attempts to unshare pages should be handled through
+         * 'must_succeed' case. */
+        ASSERT(v->domain->domain_id == d->domain_id);
+        vcpu_pause_nosync(v);
+        req.flags |= MEM_EVENT_FLAG_VCPU_PAUSED;
+    }
+        
+    /* XXX: Need to reserve a request, not just check the ring! */
+    if(mem_event_check_ring(d)) return page;
+
+    req.flags |= MEM_EVENT_FLAG_OUT_OF_MEM;
+    req.gfn = gfn;
+    req.p2mt = p2m_ram_shared;
+    req.vcpu_id = v->vcpu_id;
+    mem_event_put_request(d, &req);
+
+    return page;
+}
+
+int mem_sharing_sharing_resume(struct domain *d)
+{
+    mem_event_response_t rsp;
+
+    /* Get request off the ring */
+    mem_event_get_response(d, &rsp);
+
+    /* Unpause domain/vcpu */
+    if( rsp.flags & MEM_EVENT_FLAG_VCPU_PAUSED )
+        vcpu_unpause(d->vcpu[rsp.vcpu_id]);
+    if( rsp.flags & MEM_EVENT_FLAG_DOM_PAUSED )
+        domain_unpause(d);
+
+    return 0;
+}
+
+int mem_sharing_debug_mfn(unsigned long mfn)
+{
+    struct page_info *page;
+
+    if(!mfn_valid(_mfn(mfn)))
+    {
+        printk("Invalid MFN=%lx\n", mfn);
+        return -1;
+    }
+    page = mfn_to_page(_mfn(mfn));
+
+    printk("Debug page: MFN=%lx is ci=%lx, ti=%lx, owner_id=%d\n",
+            mfn_x(page_to_mfn(page)), 
+            page->count_info, 
+            page->u.inuse.type_info,
+            page_get_owner(page)->domain_id);
+
+    return 0;
+}
+
+int mem_sharing_debug_gfn(struct domain *d, unsigned long gfn)
+{
+    p2m_type_t p2mt;
+    mfn_t mfn;
+    struct page_info *page;
+
+    mfn = gfn_to_mfn(d, gfn, &p2mt);
+    page = mfn_to_page(mfn);
+
+    printk("Debug for domain=%d, gfn=%lx, ", 
+            d->domain_id, 
+            gfn);
+    return mem_sharing_debug_mfn(mfn_x(mfn));
+}
+
+#define SHGNT_PER_PAGE_V1 (PAGE_SIZE / sizeof(grant_entry_v1_t))
+#define shared_entry_v1(t, e) \
+    ((t)->shared_v1[(e)/SHGNT_PER_PAGE_V1][(e)%SHGNT_PER_PAGE_V1])
+#define SHGNT_PER_PAGE_V2 (PAGE_SIZE / sizeof(grant_entry_v2_t))
+#define shared_entry_v2(t, e) \
+    ((t)->shared_v2[(e)/SHGNT_PER_PAGE_V2][(e)%SHGNT_PER_PAGE_V2])
+#define STGNT_PER_PAGE (PAGE_SIZE / sizeof(grant_status_t))
+#define status_entry(t, e) \
+    ((t)->status[(e)/STGNT_PER_PAGE][(e)%STGNT_PER_PAGE])
+
+static grant_entry_header_t *
+shared_entry_header(struct grant_table *t, grant_ref_t ref)
+{
+    ASSERT(t->gt_version != 0);
+    if (t->gt_version == 1)
+        return (grant_entry_header_t*)&shared_entry_v1(t, ref);
+    else
+        return &shared_entry_v2(t, ref).hdr;
+}
+
+int mem_sharing_debug_gref(struct domain *d, grant_ref_t ref)
+{
+    grant_entry_header_t *shah;
+    uint16_t status;
+    unsigned long gfn;
+
+    if(d->grant_table->gt_version < 1)
+    {
+        printk("Asked to debug [dom=%d,gref=%d], but not yet inited.\n",
+                d->domain_id, ref);
+        return -1;
+    }
+    shah = shared_entry_header(d->grant_table, ref);
+    if (d->grant_table->gt_version == 1) 
+    {
+        grant_entry_v1_t *sha1;
+        sha1 = &shared_entry_v1(d->grant_table, ref);
+        status = shah->flags;
+        gfn = sha1->frame;
+    } 
+    else 
+    {
+        grant_entry_v2_t *sha2;
+        sha2 = &shared_entry_v2(d->grant_table, ref);
+        status = status_entry(d->grant_table, ref);
+        gfn = sha2->full_page.frame;
+    }
+    
+    printk("==> Grant [dom=%d,ref=%d], status=%x. ", 
+            d->domain_id, ref, status);
+
+    return mem_sharing_debug_gfn(d, gfn); 
+}
+
+int mem_sharing_nominate_page(struct domain *d, 
+                              unsigned long gfn,
+                              int expected_refcnt)
+{
+    p2m_type_t p2mt;
+    mfn_t mfn;
+    struct page_info *page;
+    int ret;
+
+    mfn = gfn_to_mfn(d, gfn, &p2mt);
+
+    /* Check if mfn is valid */
+    ret = -EINVAL;
+    if (!mfn_valid(mfn))
+        goto out;
+
+    /* Check p2m type */
+    if (!p2m_is_sharable(p2mt))
+        goto out;
+
+    /* Try to convert the mfn to the sharable type */
+    page = mfn_to_page(mfn);
+    ret = page_make_sharable(d, page, expected_refcnt); 
+    if(ret) 
+        goto out;
+
+    /* Change the p2m type */
+    if(p2m_change_type(d, gfn, p2mt, p2m_ram_shared) != p2mt) 
+    {
+        /* This is unlikely, as the type must have changed since we've checked
+         * it a few lines above.
+         * The mfn needs to revert back to rw type. This should never fail,
+         * since no-one knew that the mfn was temporarily sharable */
+        ASSERT(page_make_private(d, page) == 0);
+        goto out;
+    }
+
+    ret = 0;
+
+out:
+    return ret;
+}
+
+int mem_sharing_unshare_page(struct domain *d, 
+                             unsigned long gfn, 
+                             uint16_t flags)
+{
+    p2m_type_t p2mt;
+    mfn_t mfn;
+    struct page_info *page, *old_page;
+    void *s, *t;
+    int ret;
+
+    mfn = gfn_to_mfn(d, gfn, &p2mt);
+
+    page = mfn_to_page(mfn);
+
+    ret = page_make_private(d, page);
+    if(ret == 0) goto private_page_found;
+        
+    old_page = page;
+    page = mem_sharing_alloc_page(d, gfn, flags & MEM_SHARING_MUST_SUCCEED);
+    BUG_ON(!page && (flags & MEM_SHARING_MUST_SUCCEED));
+    if(!page) return -ENOMEM;
+
+    s = map_domain_page(__page_to_mfn(old_page));
+    t = map_domain_page(__page_to_mfn(page));
+    memcpy(t, s, PAGE_SIZE);
+    unmap_domain_page(s);
+    unmap_domain_page(t);
+
+    ASSERT(set_shared_p2m_entry(d, gfn, page_to_mfn(page)) != 0);
+    put_page_and_type(old_page);
+
+private_page_found:    
+    if(p2m_change_type(d, gfn, p2m_ram_shared, p2m_ram_rw) != 
+                                                p2m_ram_shared) 
+    {
+        printk("Could not change p2m type.\n");
+        BUG();
+    }
+
+    return 0;
+}
+
+
+
diff -r 3a3be3938b2c -r 7d841016536f xen/arch/x86/mm/p2m.c
--- a/xen/arch/x86/mm/p2m.c     Thu Dec 17 06:27:56 2009 +0000
+++ b/xen/arch/x86/mm/p2m.c     Thu Dec 17 06:27:56 2009 +0000
@@ -32,6 +32,7 @@
 #include <xen/iommu.h>
 #include <asm/mem_event.h>
 #include <public/mem_event.h>
+#include <asm/mem_sharing.h>
 #include <xen/event.h>
 
 /* Debugging and auditing of the P2M code? */
@@ -1629,8 +1630,17 @@ void p2m_teardown(struct domain *d)
 {
     struct page_info *pg;
     struct p2m_domain *p2m = d->arch.p2m;
+    unsigned long gfn;
+    p2m_type_t t;
+    mfn_t mfn;
 
     p2m_lock(p2m);
+    for(gfn=0; gfn < p2m->max_mapped_pfn; gfn++)
+    {
+        mfn = p2m->get_entry(d, gfn, &t, p2m_query);
+        if(mfn_valid(mfn) && (t == p2m_ram_shared))
+            BUG_ON(mem_sharing_unshare_page(d, gfn, MEM_SHARING_DESTROY_GFN));
+    }
     d->arch.phys_table = pagetable_null();
 
     while ( (pg = page_list_remove_head(&p2m->pages)) )
@@ -2301,6 +2311,33 @@ clear_mmio_p2m_entry(struct domain *d, u
     return rc;
 }
 
+int
+set_shared_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn)
+{
+    int rc = 0;
+    p2m_type_t ot;
+    mfn_t omfn;
+
+    if ( !paging_mode_translate(d) )
+        return 0;
+
+    omfn = gfn_to_mfn_query(d, gfn, &ot);
+    /* At the moment we only allow p2m change if gfn has already been made
+     * sharable first */
+    ASSERT(p2m_is_shared(ot));
+    ASSERT(mfn_valid(omfn));
+    /* XXX: M2P translations have to be handled properly for shared pages */
+    set_gpfn_from_mfn(mfn_x(omfn), INVALID_M2P_ENTRY);
+
+    P2M_DEBUG("set shared %lx %lx\n", gfn, mfn_x(mfn));
+    rc = set_p2m_entry(d, gfn, mfn, 0, p2m_ram_shared);
+    if ( 0 == rc )
+        gdprintk(XENLOG_ERR,
+            "set_mmio_p2m_entry: set_p2m_entry failed! mfn=%08lx\n",
+            gmfn_to_mfn(d, gfn));
+    return rc;
+}
+
 int p2m_mem_paging_nominate(struct domain *d, unsigned long gfn)
 {
     struct page_info *page;
@@ -2406,7 +2443,7 @@ void p2m_mem_paging_populate(struct doma
     if ( v->domain->domain_id == d->domain_id )
     {
         vcpu_pause_nosync(v);
-        req.flags |= MEM_EVENT_FLAG_PAUSED;
+        req.flags |= MEM_EVENT_FLAG_VCPU_PAUSED;
     }
 
     /* Send request to pager */
@@ -2450,7 +2487,7 @@ void p2m_mem_paging_resume(struct domain
     p2m_unlock(d->arch.p2m);
 
     /* Unpause domain */
-    if ( rsp.flags & MEM_EVENT_FLAG_PAUSED )
+    if ( rsp.flags & MEM_EVENT_FLAG_VCPU_PAUSED )
         vcpu_unpause(d->vcpu[rsp.vcpu_id]);
 
     /* Unpause any domains that were paused because the ring was full */
diff -r 3a3be3938b2c -r 7d841016536f xen/include/asm-x86/mem_sharing.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/asm-x86/mem_sharing.h Thu Dec 17 06:27:56 2009 +0000
@@ -0,0 +1,38 @@
+/******************************************************************************
+ * include/asm-x86/mem_sharing.h
+ *
+ * Memory sharing support.
+ *
+ * Copyright (c) 2009 Citrix (R)&D) Ltd. (Grzegorz Milos)
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __MEM_SHARING_H__
+#define __MEM_SHARING_H__
+
+#define sharing_supported(_d) \
+    (is_hvm_domain(_d) && (_d)->arch.hvm_domain.hap_enabled) 
+int mem_sharing_nominate_page(struct domain *d, 
+                              unsigned long gfn,
+                              int expected_refcnt);
+#define MEM_SHARING_MUST_SUCCEED      (1<<0)
+#define MEM_SHARING_DESTROY_GFN       (1<<1)
+int mem_sharing_unshare_page(struct domain *d, 
+                             unsigned long gfn, 
+                             uint16_t flags);
+int mem_sharing_sharing_resume(struct domain *d);
+int mem_sharing_cache_resize(struct domain *d, int new_size);
+
+#endif /* __MEM_SHARING_H__ */
diff -r 3a3be3938b2c -r 7d841016536f xen/include/asm-x86/p2m.h
--- a/xen/include/asm-x86/p2m.h Thu Dec 17 06:27:56 2009 +0000
+++ b/xen/include/asm-x86/p2m.h Thu Dec 17 06:27:56 2009 +0000
@@ -28,6 +28,7 @@
 
 #include <xen/config.h>
 #include <xen/paging.h>
+#include <asm/mem_sharing.h>
 
 /*
  * The phys_to_machine_mapping maps guest physical frame numbers 
@@ -80,6 +81,8 @@ typedef enum {
     p2m_ram_paged = 10,           /* Memory that has been paged out */
     p2m_ram_paging_in = 11,       /* Memory that is being paged in */
     p2m_ram_paging_in_start = 12, /* Memory that is being paged in */
+
+    p2m_ram_shared = 13,          /* Shared or sharable memory */
 } p2m_type_t;
 
 typedef enum {
@@ -98,7 +101,8 @@ typedef enum {
                        | p2m_to_mask(p2m_ram_paging_out)      \
                        | p2m_to_mask(p2m_ram_paged)           \
                        | p2m_to_mask(p2m_ram_paging_in_start) \
-                       | p2m_to_mask(p2m_ram_paging_in))
+                       | p2m_to_mask(p2m_ram_paging_in)       \
+                       | p2m_to_mask(p2m_ram_shared))
 
 /* Grant mapping types, which map to a real machine frame in another
  * VM */
@@ -112,7 +116,8 @@ typedef enum {
 /* Read-only types, which must have the _PAGE_RW bit clear in their PTEs */
 #define P2M_RO_TYPES (p2m_to_mask(p2m_ram_logdirty)     \
                       | p2m_to_mask(p2m_ram_ro)         \
-                      | p2m_to_mask(p2m_grant_map_ro) )
+                      | p2m_to_mask(p2m_grant_map_ro)   \
+                      | p2m_to_mask(p2m_ram_shared) )
 
 #define P2M_MAGIC_TYPES (p2m_to_mask(p2m_populate_on_demand))
 
@@ -125,6 +130,12 @@ typedef enum {
                           | p2m_to_mask(p2m_ram_paging_in))
 
 #define P2M_PAGED_TYPES (p2m_to_mask(p2m_ram_paged))
+
+/* Shared types */
+/* XXX: Sharable types could include p2m_ram_ro too, but we would need to
+ * reinit the type correctly after fault */
+#define P2M_SHARABLE_TYPES (p2m_to_mask(p2m_ram_rw))
+#define P2M_SHARED_TYPES   (p2m_to_mask(p2m_ram_shared))
 
 /* Useful predicates */
 #define p2m_is_ram(_t) (p2m_to_mask(_t) & P2M_RAM_TYPES)
@@ -140,6 +151,8 @@ typedef enum {
 #define p2m_is_pageable(_t) (p2m_to_mask(_t) & P2M_PAGEABLE_TYPES)
 #define p2m_is_paging(_t)   (p2m_to_mask(_t) & P2M_PAGING_TYPES)
 #define p2m_is_paged(_t)    (p2m_to_mask(_t) & P2M_PAGED_TYPES)
+#define p2m_is_sharable(_t) (p2m_to_mask(_t) & P2M_SHARABLE_TYPES)
+#define p2m_is_shared(_t)   (p2m_to_mask(_t) & P2M_SHARED_TYPES)
 
 /* Populate-on-demand */
 #define POPULATE_ON_DEMAND_MFN  (1<<9)
@@ -391,6 +404,9 @@ p2m_type_t p2m_change_type(struct domain
 /* Set mmio addresses in the p2m table (for pass-through) */
 int set_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn);
 int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn);
+/* Modify p2m table for shared gfn */
+int
+set_shared_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn);
 
 /* Check if a nominated gfn is valid to be paged out */
 int p2m_mem_paging_nominate(struct domain *d, unsigned long gfn);
diff -r 3a3be3938b2c -r 7d841016536f xen/include/public/mem_event.h
--- a/xen/include/public/mem_event.h    Thu Dec 17 06:27:56 2009 +0000
+++ b/xen/include/public/mem_event.h    Thu Dec 17 06:27:56 2009 +0000
@@ -34,7 +34,9 @@
 #define MEM_EVENT_MODE_SYNC_ALL (1 << 1)
 
 /* Memory event flags */
-#define MEM_EVENT_FLAG_PAUSED   (1 << 0)
+#define MEM_EVENT_FLAG_VCPU_PAUSED  (1 << 0)
+#define MEM_EVENT_FLAG_DOM_PAUSED   (1 << 1)
+#define MEM_EVENT_FLAG_OUT_OF_MEM   (1 << 2)
 
 
 typedef struct mem_event_shared_page {

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] This patch defines a new P2M type used for sharable/shared pages. It also, Xen patchbot-unstable <=