[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [IA64] xen: grant table support



# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 7296d8fb07ff4f8f9d16078c7494997f03864737
# Parent  8ac86f96879f202b7d9fb65dc402945c86e67735
[IA64] xen: grant table support

grant table support.

Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
---
 xen/arch/ia64/xen/domain.c                   |  174 +++++++++++++++++++++++++++
 xen/include/asm-ia64/config.h                |    4 
 xen/include/asm-ia64/grant_table.h           |   22 +++
 xen/include/asm-ia64/linux-xen/asm/pgtable.h |    2 
 xen/include/asm-ia64/shadow.h                |   57 ++++++++
 5 files changed, 257 insertions(+), 2 deletions(-)

diff -r 8ac86f96879f -r 7296d8fb07ff xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Tue May 09 11:34:45 2006 -0600
+++ b/xen/arch/ia64/xen/domain.c        Tue May 09 11:38:35 2006 -0600
@@ -394,6 +394,10 @@ static void relinquish_memory(struct dom
 
         /* Follow the list chain and /then/ potentially free the page. */
         ent = ent->next;
+#ifdef CONFIG_XEN_IA64_DOM0_VP
+        if (page_get_owner(page) == d)
+            set_gpfn_from_mfn(page_to_mfn(page), INVALID_M2P_ENTRY);
+#endif
         put_page(page);
     }
 
@@ -483,6 +487,7 @@ void new_thread(struct vcpu *v,
        }
 }
 
+//XXX !xxx_present() should be used instread of !xxx_none()?
 static pte_t*
 lookup_alloc_domain_pte(struct domain* d, unsigned long mpaddr)
 {
@@ -1006,6 +1011,175 @@ out1:
     put_domain(rd);
 out0:
     return error;
+}
+
+// grant table host mapping
+// mpaddr: host_addr: pseudo physical address
+// mfn: frame: machine page frame
+// flags: GNTMAP_readonly | GNTMAP_application_map | GNTMAP_contains_pte
+int
+create_grant_host_mapping(unsigned long gpaddr,
+                         unsigned long mfn, unsigned int flags)
+{
+    struct domain* d = current->domain;
+
+    if (flags & (GNTMAP_application_map | GNTMAP_contains_pte)) {
+        DPRINTK("%s: flags 0x%x\n", __func__, flags);
+        return GNTST_general_error;
+    }
+    if (flags & GNTMAP_readonly) {
+#if 0
+        DPRINTK("%s: GNTMAP_readonly is not implemented yet. flags %x\n",
+                __func__, flags);
+#endif
+        flags &= ~GNTMAP_readonly;
+    }
+
+    assign_domain_page_replace(d, gpaddr, mfn, flags);
+
+    return GNTST_okay;
+}
+
+// grant table host unmapping
+int
+destroy_grant_host_mapping(unsigned long gpaddr,
+                          unsigned long mfn, unsigned int flags)
+{
+    struct domain* d = current->domain;
+    pte_t* pte;
+    pte_t old_pte;
+    unsigned long old_mfn = INVALID_MFN;
+
+    if (flags & (GNTMAP_application_map | GNTMAP_contains_pte)) {
+        DPRINTK("%s: flags 0x%x\n", __func__, flags);
+        return GNTST_general_error;
+    }
+    if (flags & GNTMAP_readonly) {
+#if 0
+        DPRINTK("%s: GNTMAP_readonly is not implemented yet. flags %x\n",
+                __func__, flags);
+#endif
+        flags &= ~GNTMAP_readonly;
+    }
+
+    // get_page(mfn_to_page(mfn)) is not needed.
+    // the caller, __gnttab_map_grant_ref() does it.
+
+    pte = lookup_noalloc_domain_pte(d, gpaddr);
+    if (pte == NULL || !pte_present(*pte) || pte_pfn(*pte) != mfn)
+        return GNTST_general_error;//XXX GNTST_bad_pseudo_phys_addr
+
+    // update pte
+    old_pte = ptep_get_and_clear(d->arch.mm, gpaddr, pte);
+    if (pte_present(old_pte)) {
+        old_mfn = pte_pfn(old_pte);//XXX
+    }
+    domain_page_flush(d, gpaddr, old_mfn, INVALID_MFN);
+
+    return GNTST_okay;
+}
+
+//XXX needs refcount patch
+//XXX heavily depends on the struct page layout.
+//XXX SMP
+int
+steal_page_for_grant_transfer(struct domain *d, struct page_info *page)
+{
+#if 0 /* if big endian */
+# error "implement big endian version of steal_page_for_grant_transfer()"
+#endif
+    u32 _d, _nd;
+    u64 x, nx, y;
+    unsigned long mpaddr = get_gpfn_from_mfn(page_to_mfn(page)) << PAGE_SHIFT;
+    struct page_info *new;
+
+    // zap_domain_page_one() does put_page(page)
+    if (get_page(page, d) == 0) {
+        DPRINTK("%s:%d page %p mfn %ld d 0x%p id %d\n",
+                __func__, __LINE__, page, page_to_mfn(page), d, d->domain_id);
+        return -1;
+    }
+    zap_domain_page_one(d, mpaddr);
+
+    spin_lock(&d->page_alloc_lock);
+
+    /*
+     * The tricky bit: atomically release ownership while there is just one
+     * benign reference to the page (PGC_allocated). If that reference
+     * disappears then the deallocation routine will safely spin.
+     */
+    _d  = pickle_domptr(d);
+    y = *((u64*)&page->count_info);
+    do {
+        x = y;
+        nx = x & 0xffffffff;
+        // page->count_info: untouched
+        // page->u.inused._domain = 0;
+        _nd = x >> 32;
+
+        if (unlikely((x & (PGC_count_mask | PGC_allocated)) !=
+                     (1 | PGC_allocated)) ||
+            unlikely(_nd != _d)) {
+            struct domain* nd = unpickle_domptr(_nd);
+            if (nd == NULL) {
+                DPRINTK("gnttab_transfer: Bad page %p: ed=%p(%u) 0x%x, "
+                        "sd=%p 0x%x,"
+                        " caf=%016lx, taf=%" PRtype_info "\n",
+                        (void *) page_to_mfn(page),
+                        d, d->domain_id, _d,
+                        nd, _nd,
+                        x,
+                        page->u.inuse.type_info);
+            } else {
+                DPRINTK("gnttab_transfer: Bad page %p: ed=%p(%u) 0x%x, "
+                        "sd=%p(%u) 0x%x,"
+                        " caf=%016lx, taf=%" PRtype_info "\n",
+                        (void *) page_to_mfn(page),
+                        d, d->domain_id, _d,
+                        nd, nd->domain_id, _nd,
+                        x,
+                        page->u.inuse.type_info);
+            }
+            spin_unlock(&d->page_alloc_lock);
+            return -1;
+        }
+
+        y = cmpxchg((u64*)&page->count_info, x, nx);
+    } while (unlikely(y != x));
+
+    /*
+     * Unlink from 'd'. At least one reference remains (now anonymous), so
+     * noone else is spinning to try to delete this page from 'd'.
+     */
+    d->tot_pages--;
+    list_del(&page->list);
+
+    spin_unlock(&d->page_alloc_lock);
+
+#if 1
+    //XXX Until net_rx_action() fix
+    // assign new page for this mpaddr
+    new = assign_new_domain_page(d, mpaddr);
+    BUG_ON(new == NULL);//XXX
+#endif
+
+    return 0;
+}
+
+void
+guest_physmap_add_page(struct domain *d, unsigned long gpfn,
+                       unsigned long mfn)
+{
+    assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, 0/* XXX */);
+    set_gpfn_from_mfn(mfn, gpfn);
+}
+
+void
+guest_physmap_remove_page(struct domain *d, unsigned long gpfn,
+                          unsigned long mfn)
+{
+    BUG_ON(mfn == 0);//XXX
+    zap_domain_page_one(d, gpfn << PAGE_SHIFT);
 }
 #endif
 
diff -r 8ac86f96879f -r 7296d8fb07ff xen/include/asm-ia64/config.h
--- a/xen/include/asm-ia64/config.h     Tue May 09 11:34:45 2006 -0600
+++ b/xen/include/asm-ia64/config.h     Tue May 09 11:38:35 2006 -0600
@@ -239,6 +239,10 @@ void dummy_called(char *function);
 // these declarations got moved at some point, find a better place for them
 extern int ht_per_core;
 
+#ifdef CONFIG_XEN_IA64_DOM0_VP
+#define CONFIG_SHADOW  1
+#endif
+
 // xen/include/asm/config.h
 /******************************************************************************
  * config.h
diff -r 8ac86f96879f -r 7296d8fb07ff xen/include/asm-ia64/grant_table.h
--- a/xen/include/asm-ia64/grant_table.h        Tue May 09 11:34:45 2006 -0600
+++ b/xen/include/asm-ia64/grant_table.h        Tue May 09 11:38:35 2006 -0600
@@ -7,10 +7,22 @@
 
 #define ORDER_GRANT_FRAMES 0
 
+#ifndef CONFIG_XEN_IA64_DOM0_VP
+// for grant map/unmap
 #define create_grant_host_mapping(a, f, fl)  0
 #define destroy_grant_host_mapping(a, f, fl) 0
 
+// for grant transfer
 #define steal_page_for_grant_transfer(d, p)  0
+#else
+// for grant map/unmap
+int create_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, 
unsigned int flags);
+int destroy_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, 
unsigned int flags);
+
+// for grant transfer
+int steal_page_for_grant_transfer(struct domain *d, struct page_info *page);
+void guest_physmap_add_page(struct domain *d, unsigned long gpfn, unsigned 
long mfn);
+#endif
 
 #define gnttab_create_shared_page(d, t, i) ((void)0)
 
@@ -20,13 +32,21 @@
 #define gnttab_shared_maddr(d, t, i)                        \
     virt_to_maddr((char*)(t)->shared + ((i) << PAGE_SHIFT))
 
-#define gnttab_shared_gmfn(d, t, i)                                          \
+#ifndef CONFIG_XEN_IA64_DOM0_VP
+# define gnttab_shared_gmfn(d, t, i)                                         \
     ({ ((d) == dom0) ?                                                       \
             (virt_to_maddr((t)->shared) >> PAGE_SHIFT) + (i):                \
             assign_domain_page((d),                                          \
                                IA64_GRANT_TABLE_PADDR + ((i) << PAGE_SHIFT), \
                                gnttab_shared_maddr(d, t, i)),                \
             (IA64_GRANT_TABLE_PADDR >> PAGE_SHIFT) + (i);})
+#else
+# define gnttab_shared_gmfn(d, t, i)                                    \
+    ({ assign_domain_page((d),                                          \
+                          IA64_GRANT_TABLE_PADDR + ((i) << PAGE_SHIFT), \
+                          gnttab_shared_maddr((d), (t), (i)));          \
+        (IA64_GRANT_TABLE_PADDR >> PAGE_SHIFT) + (i);})
+#endif
 
 #define gnttab_log_dirty(d, f) ((void)0)
 
diff -r 8ac86f96879f -r 7296d8fb07ff 
xen/include/asm-ia64/linux-xen/asm/pgtable.h
--- a/xen/include/asm-ia64/linux-xen/asm/pgtable.h      Tue May 09 11:34:45 
2006 -0600
+++ b/xen/include/asm-ia64/linux-xen/asm/pgtable.h      Tue May 09 11:38:35 
2006 -0600
@@ -383,6 +383,7 @@ ptep_test_and_clear_dirty (struct vm_are
        return 1;
 #endif
 }
+#endif
 
 static inline pte_t
 ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
@@ -396,6 +397,7 @@ ptep_get_and_clear(struct mm_struct *mm,
 #endif
 }
 
+#ifndef XEN
 static inline void
 ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 {
diff -r 8ac86f96879f -r 7296d8fb07ff xen/include/asm-ia64/shadow.h
--- a/xen/include/asm-ia64/shadow.h     Tue May 09 11:34:45 2006 -0600
+++ b/xen/include/asm-ia64/shadow.h     Tue May 09 11:38:35 2006 -0600
@@ -1,2 +1,57 @@
-/* empty */
+/******************************************************************************
+ * include/asm-ia64/shadow.h
+ *
+ * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * 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 _XEN_SHADOW_H
+#define _XEN_SHADOW_H
+
+#include <xen/config.h>
+
+#ifdef CONFIG_XEN_IA64_DOM0_VP
+#ifndef CONFIG_SHADOW
+# error "CONFIG_SHADOW must be defined"
+#endif
+
+#define shadow_drop_references(d, p)          ((void)0)
+
+// this is used only x86-specific code
+//#define shadow_sync_and_drop_references(d, p) ((void)0)
+
+#define shadow_mode_translate(d)              (1)
+
+// for granttab transfer. XENMEM_populate_physmap
+void guest_physmap_add_page(struct domain *d, unsigned long gpfn, unsigned 
long mfn);
+// for balloon driver. XENMEM_decrease_reservation
+void guest_physmap_remove_page(struct domain *d, unsigned long gpfn, unsigned 
long mfn);
+#endif
+
+#endif // _XEN_SHADOW_H
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
+

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.