aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@hp.com>2007-09-06 14:37:50 -0600
committerAlex Williamson <alex.williamson@hp.com>2007-09-06 14:37:50 -0600
commit04284d57f287a41e3617e9955f2cb79917af39cb (patch)
tree8de3907bae670501cb68b0d0b65ba27e1acb3e86
parent8cd835c116fbc965fc3c0c7e7991b8129c17608d (diff)
downloadxen-04284d57f287a41e3617e9955f2cb79917af39cb.tar.gz
xen-04284d57f287a41e3617e9955f2cb79917af39cb.tar.bz2
xen-04284d57f287a41e3617e9955f2cb79917af39cb.zip
[IA64] Foreign p2m: libxc side
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
-rw-r--r--tools/libxc/ia64/xc_ia64.h53
-rw-r--r--tools/libxc/ia64/xc_ia64_stubs.c138
2 files changed, 184 insertions, 7 deletions
diff --git a/tools/libxc/ia64/xc_ia64.h b/tools/libxc/ia64/xc_ia64.h
new file mode 100644
index 0000000000..00707e75a0
--- /dev/null
+++ b/tools/libxc/ia64/xc_ia64.h
@@ -0,0 +1,53 @@
+/*
+ * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ *
+ */
+
+#ifndef _XC_IA64_H_
+#define _XC_IA64_H_
+
+struct xen_ia64_p2m_table {
+ unsigned long size;
+ unsigned long *p2m;
+};
+
+void xc_ia64_p2m_init(struct xen_ia64_p2m_table *p2m_table);
+int xc_ia64_p2m_map(struct xen_ia64_p2m_table *p2m_table, int xc_handle,
+ uint32_t domid, struct xen_ia64_memmap_info *memmap_info,
+ unsigned long flag);
+void xc_ia64_p2m_unmap(struct xen_ia64_p2m_table *p2m_table);
+int xc_ia64_p2m_present(struct xen_ia64_p2m_table *p2m_table,
+ unsigned long gpfn);
+int xc_ia64_p2m_allocated(struct xen_ia64_p2m_table *p2m_table,
+ unsigned long gpfn);
+
+unsigned long xc_ia64_p2m_mfn(struct xen_ia64_p2m_table *p2m_table,
+ unsigned long gpfn);
+
+
+#endif /* _XC_IA64_H_ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/libxc/ia64/xc_ia64_stubs.c b/tools/libxc/ia64/xc_ia64_stubs.c
index f5550c09cd..e2307ac2d3 100644
--- a/tools/libxc/ia64/xc_ia64_stubs.c
+++ b/tools/libxc/ia64/xc_ia64_stubs.c
@@ -1,11 +1,5 @@
#include "xg_private.h"
-#include "xenguest.h"
-#include "xc_private.h"
-#include "xc_elf.h"
-#include <stdlib.h>
-#include <zlib.h>
-#include "xen/arch-ia64.h"
-#include <xen/hvm/ioreq.h>
+#include "xc_ia64.h"
/* this is a very ugly way of getting FPSR_DEFAULT. struct ia64_fpreg is
* mysteriously declared in two places: /usr/include/asm/fpu.h and
@@ -66,6 +60,136 @@ xc_get_max_pages(int xc_handle, uint32_t domid)
}
/*
+ * XXX from xen/include/asm-ia64/linux-xen/asm/pgtable.h
+ * Should PTRS_PER_PTE be exported by arch-ia64.h?
+ */
+#define PTRS_PER_PTE (1UL << (PAGE_SHIFT - 3))
+
+static void*
+xc_ia64_map_foreign_p2m(int xc_handle, uint32_t dom,
+ struct xen_ia64_memmap_info *memmap_info,
+ unsigned long flags, unsigned long *p2m_size_p)
+{
+ unsigned long gpfn_max;
+ unsigned long p2m_size;
+ void *addr;
+ privcmd_hypercall_t hypercall;
+ int ret;
+ int saved_errno;
+
+ gpfn_max = xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &dom);
+ if (gpfn_max < 0)
+ return NULL;
+ p2m_size =
+ (((gpfn_max + 1) + PTRS_PER_PTE - 1) / PTRS_PER_PTE) << PAGE_SHIFT;
+ addr = mmap(NULL, p2m_size, PROT_READ, MAP_SHARED, xc_handle, 0);
+ if (addr == MAP_FAILED)
+ return NULL;
+
+ hypercall.op = __HYPERVISOR_ia64_dom0vp_op;
+ hypercall.arg[0] = IA64_DOM0VP_expose_foreign_p2m;
+ hypercall.arg[1] = (unsigned long)addr;
+ hypercall.arg[2] = dom;
+ hypercall.arg[3] = (unsigned long)memmap_info;
+ hypercall.arg[4] = flags;
+ hypercall.arg[5] = 0;
+
+ if (lock_pages(memmap_info,
+ sizeof(*memmap_info) + memmap_info->efi_memmap_size) != 0) {
+ saved_errno = errno;
+ munmap(addr, p2m_size);
+ errno = saved_errno;
+ return NULL;
+ }
+ ret = do_xen_hypercall(xc_handle, &hypercall);
+ saved_errno = errno;
+ unlock_pages(memmap_info,
+ sizeof(*memmap_info) + memmap_info->efi_memmap_size);
+ if (ret < 0) {
+ munmap(addr, p2m_size);
+ errno = saved_errno;
+ return NULL;
+ }
+
+ *p2m_size_p = p2m_size;
+ return addr;
+}
+
+void
+xc_ia64_p2m_init(struct xen_ia64_p2m_table *p2m_table)
+{
+ p2m_table->size = 0;
+ p2m_table->p2m = NULL;
+}
+
+int
+xc_ia64_p2m_map(struct xen_ia64_p2m_table *p2m_table, int xc_handle,
+ uint32_t domid, struct xen_ia64_memmap_info *memmap_info,
+ unsigned long flag)
+{
+ p2m_table->p2m = xc_ia64_map_foreign_p2m(xc_handle, domid, memmap_info,
+ flag, &p2m_table->size);
+ if (p2m_table->p2m == NULL) {
+ PERROR("Could not map foreign p2m. falling back to old method");
+ return -1;
+ }
+ return 0;
+}
+
+void
+xc_ia64_p2m_unmap(struct xen_ia64_p2m_table *p2m_table)
+{
+ if (p2m_table->p2m == NULL)
+ return;
+ munmap(p2m_table->p2m, p2m_table->size);
+ //p2m_table->p2m = NULL;
+ //p2m_table->size = 0;
+}
+
+/*
+ * XXX from xen/include/asm-ia64/linux-xen/asm/pgtable.h
+ * Should those be exported by arch-ia64.h?
+ */
+#define _PAGE_P_BIT 0
+#define _PAGE_P (1UL << _PAGE_P_BIT) /* page present bit */
+#define _PAGE_PGC_ALLOCATED_BIT 59 /* _PGC_allocated */
+#define _PAGE_PGC_ALLOCATED (1UL << _PAGE_PGC_ALLOCATED_BIT)
+
+#define IA64_MAX_PHYS_BITS 50 /* max. number of physical address bits (architected) */
+#define _PAGE_PPN_MASK (((1UL << IA64_MAX_PHYS_BITS) - 1) & ~0xfffUL)
+
+int
+xc_ia64_p2m_present(struct xen_ia64_p2m_table *p2m_table, unsigned long gpfn)
+{
+ if (sizeof(p2m_table->p2m[0]) * gpfn < p2m_table->size)
+ return !!(p2m_table->p2m[gpfn] & _PAGE_P);
+ return 0;
+}
+
+int
+xc_ia64_p2m_allocated(struct xen_ia64_p2m_table *p2m_table, unsigned long gpfn)
+{
+ if (sizeof(p2m_table->p2m[0]) * gpfn < p2m_table->size) {
+ unsigned long pte = p2m_table->p2m[gpfn];
+ return !!((pte & _PAGE_P) && (pte & _PAGE_PGC_ALLOCATED));
+ }
+ return 0;
+}
+
+unsigned long
+xc_ia64_p2m_mfn(struct xen_ia64_p2m_table *p2m_table, unsigned long gpfn)
+{
+ unsigned long pte;
+
+ if (sizeof(p2m_table->p2m[0]) * gpfn >= p2m_table->size)
+ return INVALID_MFN;
+ pte = p2m_table->p2m[gpfn];
+ if (!(pte & _PAGE_P))
+ return INVALID_MFN;
+ return (pte & _PAGE_PPN_MASK) >> PAGE_SHIFT;
+}
+
+/*
* Local variables:
* mode: C
* c-set-style: "BSD"