# 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
|