# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Date 1188279728 -32400 # Node ID 904bc73dcfaaa7ebb627466b17b9fc7b971e9024 # Parent 14d0d5f4e11d2d273e4e756f60fdb17214481db5 foreign p2m exposure: libxc side PATCHNAME: foreign_p2m_exposure_libxc_side Signed-off-by: Isaku Yamahata diff -r 14d0d5f4e11d -r 904bc73dcfaa tools/libxc/ia64/xc_ia64.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxc/ia64/xc_ia64.h Tue Aug 28 14:42:08 2007 +0900 @@ -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 + * 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 -r 14d0d5f4e11d -r 904bc73dcfaa tools/libxc/ia64/xc_ia64_stubs.c --- a/tools/libxc/ia64/xc_ia64_stubs.c Tue Aug 28 15:35:26 2007 +0900 +++ b/tools/libxc/ia64/xc_ia64_stubs.c Tue Aug 28 14:42:08 2007 +0900 @@ -1,11 +1,5 @@ #include "xg_private.h" -#include "xenguest.h" -#include "xc_private.h" -#include "xc_elf.h" -#include -#include -#include "xen/arch-ia64.h" -#include +#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 } /* + * 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"