ia64/xen-unstable

changeset 15844:005652f8e4e4

[IA64] Foreign p2m: test module

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Alex Williamson <alex.williamson@hp.com>
date Thu Sep 06 14:41:14 2007 -0600 (2007-09-06)
parents 3cde7ffdfd0f
children de247793f7b5
files xen/arch/ia64/tools/p2m_foreign/Makefile xen/arch/ia64/tools/p2m_foreign/p2m_foreign.c
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/xen/arch/ia64/tools/p2m_foreign/Makefile	Thu Sep 06 14:41:14 2007 -0600
     1.3 @@ -0,0 +1,52 @@
     1.4 +#
     1.5 +# xen/arch/ia64/tools/p2m_foreign
     1.6 +#
     1.7 +# Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
     1.8 +#                    VA Linux Systems Japan K.K.
     1.9 +#
    1.10 +# This program is free software; you can redistribute it and/or modify
    1.11 +# it under the terms of the GNU General Public License as published by
    1.12 +# the Free Software Foundation; either version 2 of the License, or
    1.13 +# (at your option) any later version.
    1.14 +#
    1.15 +# This program is distributed in the hope that it will be useful,
    1.16 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.17 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.18 +# GNU General Public License for more details.
    1.19 +#
    1.20 +# You should have received a copy of the GNU General Public License
    1.21 +# along with this program; if not, write to the Free Software
    1.22 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1.23 +
    1.24 +XEN_ROOT	= ../../../../..
    1.25 +include $(XEN_ROOT)/tools/Rules.mk
    1.26 +
    1.27 +CFLAGS += -Werror -ggdb3
    1.28 +CFLAGS += -I$(XEN_LIBXC) -I$(XEN_XENSTORE)
    1.29 +
    1.30 +# Make gcc generate dependencies.
    1.31 +CFLAGS += -Wp,-MD,.$(@F).d
    1.32 +DEPS = .*.d
    1.33 +
    1.34 +PROGRAMS = p2m_foreign
    1.35 +LDLIBS   = -L$(XEN_LIBXC) -L$(XEN_XENSTORE) -lxenguest -lxenctrl
    1.36 +
    1.37 +.PHONY: all
    1.38 +all: build
    1.39 +
    1.40 +.PHONY: build
    1.41 +build: $(PROGRAMS)
    1.42 +
    1.43 +$(PROGRAMS): %: %.o
    1.44 +	$(CC) $(CFLAGS) $^ $(LDLIBS) -o $@
    1.45 +
    1.46 +
    1.47 +.PHONY: install
    1.48 +install:
    1.49 +
    1.50 +.PHONY: clean
    1.51 +clean:
    1.52 +	$(RM) *.o $(PROGRAMS)
    1.53 +	$(RM) $(DEPS)
    1.54 +
    1.55 +-include $(DEPS)
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/xen/arch/ia64/tools/p2m_foreign/p2m_foreign.c	Thu Sep 06 14:41:14 2007 -0600
     2.3 @@ -0,0 +1,233 @@
     2.4 +/*
     2.5 + * Foreign p2m exposure test.
     2.6 + *
     2.7 + * This program is free software; you can redistribute it and/or modify
     2.8 + * it under the terms of the GNU General Public License as published by
     2.9 + * the Free Software Foundation; either version 2 of the License, or
    2.10 + * (at your option) any later version.
    2.11 + *
    2.12 + * This program is distributed in the hope that it will be useful,
    2.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2.15 + * GNU General Public License for more details.
    2.16 + *
    2.17 + * You should have received a copy of the GNU General Public License
    2.18 + * along with this program; if not, write to the Free Software
    2.19 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    2.20 + *
    2.21 + * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
    2.22 + *                    VA Linux Systems Japan K.K.
    2.23 + *
    2.24 + */
    2.25 +
    2.26 +#include <sys/mman.h>
    2.27 +#include <err.h>
    2.28 +#include <errno.h>
    2.29 +#include <assert.h>
    2.30 +
    2.31 +#include <xc_private.h>
    2.32 +#include <xenctrl.h>
    2.33 +#include <xenguest.h>
    2.34 +#include <xc_efi.h>
    2.35 +#include <ia64/xc_ia64.h>
    2.36 +
    2.37 +#if 1
    2.38 +# define printd(fmt, args...)	printf(fmt, ##args)
    2.39 +#else
    2.40 +# define printd(fmt, args...)	((void)0)
    2.41 +#endif
    2.42 +
    2.43 +/* xc_memory_op() in xc_private.c doesn't support translate_gpfn_list */
    2.44 +static int
    2.45 +__xc_memory_op(int xc_handle, int cmd, void *arg)
    2.46 +{
    2.47 +	DECLARE_HYPERCALL;
    2.48 +	struct xen_translate_gpfn_list* translate = arg;
    2.49 +
    2.50 +	xen_ulong_t* gpfns;
    2.51 +	xen_ulong_t* mfns;
    2.52 +	size_t len;
    2.53 +
    2.54 +	long ret = -EINVAL;
    2.55 +
    2.56 +	hypercall.op     = __HYPERVISOR_memory_op;
    2.57 +	hypercall.arg[0] = (unsigned long)cmd;
    2.58 +	hypercall.arg[1] = (unsigned long)arg;
    2.59 +
    2.60 +	assert(cmd == XENMEM_translate_gpfn_list);
    2.61 +
    2.62 +	get_xen_guest_handle(gpfns, translate->gpfn_list);
    2.63 +	get_xen_guest_handle(mfns, translate->mfn_list);
    2.64 +	len = sizeof(gpfns[0]) * translate->nr_gpfns;
    2.65 +	if (lock_pages(translate, sizeof(*translate)) ||
    2.66 +	    lock_pages(gpfns, len) ||
    2.67 +	    lock_pages(mfns, len))
    2.68 +		goto out;
    2.69 +
    2.70 +	ret = do_xen_hypercall(xc_handle, &hypercall);
    2.71 +
    2.72 +out:
    2.73 +	unlock_pages(mfns, len);
    2.74 +	unlock_pages(gpfns, len);
    2.75 +	unlock_pages(translate, sizeof(*translate));
    2.76 +
    2.77 +	return ret;
    2.78 +}
    2.79 +
    2.80 +int
    2.81 +xc_translate_gpfn_list(int xc_handle, uint32_t domid, xen_ulong_t nr_gpfns,
    2.82 +		       xen_ulong_t* gpfns, xen_ulong_t* mfns)
    2.83 +{
    2.84 +	struct xen_translate_gpfn_list translate = {
    2.85 +		.domid = domid,
    2.86 +		.nr_gpfns = nr_gpfns,
    2.87 +	};
    2.88 +	set_xen_guest_handle(translate.gpfn_list, gpfns);
    2.89 +	set_xen_guest_handle(translate.mfn_list, mfns);
    2.90 +
    2.91 +	return __xc_memory_op(xc_handle,
    2.92 +			      XENMEM_translate_gpfn_list, &translate);
    2.93 +}
    2.94 +
    2.95 +int
    2.96 +main(int argc, char** argv)
    2.97 +{
    2.98 +	uint32_t domid;
    2.99 +	int xc_handle;
   2.100 +
   2.101 +	xc_dominfo_t info;
   2.102 +	shared_info_t* shinfo;
   2.103 +
   2.104 +	unsigned long map_size;
   2.105 +	xen_ia64_memmap_info_t* memmap_info;
   2.106 +	struct xen_ia64_p2m_table p2m_table;
   2.107 +
   2.108 +	char* p;
   2.109 +	char* start;
   2.110 +	char* end;
   2.111 +	xen_ulong_t nr_gpfns;
   2.112 +
   2.113 +	xen_ulong_t* gpfns;
   2.114 +	xen_ulong_t* mfns;
   2.115 +
   2.116 +	unsigned long i;
   2.117 +
   2.118 +	if (argc != 2)
   2.119 +		errx(EXIT_FAILURE, "usage: %s <domid>", argv[0]);
   2.120 +	domid = atol(argv[1]);
   2.121 +
   2.122 +	printd("xc_interface_open()\n");
   2.123 +	xc_handle = xc_interface_open();
   2.124 +	if (xc_handle < 0)
   2.125 +		errx(EXIT_FAILURE, "can't open control interface");
   2.126 +
   2.127 +	printd("xc_domain_getinfo\n");
   2.128 +	if (xc_domain_getinfo(xc_handle, domid, 1, &info) != 1)
   2.129 +		errx(EXIT_FAILURE, "Could not get info for domain");
   2.130 +
   2.131 +
   2.132 +	printd("shared info\n");
   2.133 +	shinfo = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
   2.134 +				      PROT_READ, info.shared_info_frame);
   2.135 +	if (shinfo == NULL)
   2.136 +		errx(EXIT_FAILURE, "can't map shared info");
   2.137 +
   2.138 +	printd("memmap_info\n");
   2.139 +	map_size = PAGE_SIZE * shinfo->arch.memmap_info_num_pages;
   2.140 +	memmap_info = xc_map_foreign_range(xc_handle, info.domid,
   2.141 +					   map_size, PROT_READ,
   2.142 +					   shinfo->arch.memmap_info_pfn);
   2.143 +	if (memmap_info == NULL)
   2.144 +		errx(EXIT_FAILURE, "can't map memmap_info");
   2.145 +
   2.146 +#if 1
   2.147 +	start = (char*)&memmap_info->memdesc;
   2.148 +	end = start + memmap_info->efi_memmap_size;
   2.149 +	i = 0;
   2.150 +	for (p = start; p < end; p += memmap_info->efi_memdesc_size) {
   2.151 +		efi_memory_desc_t* md = (efi_memory_desc_t*)p;
   2.152 +		printd("%ld [0x%lx, 0x%lx) 0x%lx pages\n",
   2.153 +		       i, md->phys_addr,
   2.154 +		       md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
   2.155 +		       md->num_pages >> (PAGE_SHIFT - EFI_PAGE_SHIFT));
   2.156 +		i++;
   2.157 +	}
   2.158 +#endif
   2.159 +
   2.160 +
   2.161 +	printd("p2m map\n");
   2.162 +	if (xc_ia64_p2m_map(&p2m_table, xc_handle, domid, memmap_info, 0) < 0)
   2.163 +		errx(EXIT_FAILURE, "can't map foreign p2m table");
   2.164 +	printd("p2m map done\n");
   2.165 +
   2.166 +	start = (char*)&memmap_info->memdesc;
   2.167 +	end = start + memmap_info->efi_memmap_size;
   2.168 +	nr_gpfns = 0;
   2.169 +	i = 0;
   2.170 +	for (p = start; p < end; p += memmap_info->efi_memdesc_size) {
   2.171 +		efi_memory_desc_t* md = (efi_memory_desc_t*)p;
   2.172 +		if ( md->type != EFI_CONVENTIONAL_MEMORY ||
   2.173 +		     md->attribute != EFI_MEMORY_WB ||
   2.174 +		     md->num_pages == 0 )
   2.175 +			continue;
   2.176 +
   2.177 +		printd("%ld [0x%lx, 0x%lx) 0x%lx pages\n",
   2.178 +		       i, md->phys_addr,
   2.179 +		       md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
   2.180 +		       md->num_pages >> (PAGE_SHIFT - EFI_PAGE_SHIFT));
   2.181 +		nr_gpfns += md->num_pages >> (PAGE_SHIFT - EFI_PAGE_SHIFT);
   2.182 +		i++;
   2.183 +	}
   2.184 +
   2.185 +	printd("total 0x%lx gpfns\n", nr_gpfns);
   2.186 +	gpfns = malloc(sizeof(gpfns[0]) * nr_gpfns);
   2.187 +	mfns = malloc(sizeof(mfns[0]) * nr_gpfns);
   2.188 +	if (gpfns == NULL || mfns == NULL)
   2.189 +		err(EXIT_FAILURE, "can't allocate memory for gpfns/mfns");
   2.190 +
   2.191 +	i = 0;
   2.192 +	for (p = start; p < end; p += memmap_info->efi_memdesc_size) {
   2.193 +		efi_memory_desc_t* md = (efi_memory_desc_t*)p;
   2.194 +		unsigned long j;
   2.195 +		if ( md->type != EFI_CONVENTIONAL_MEMORY ||
   2.196 +		     md->attribute != EFI_MEMORY_WB ||
   2.197 +		     md->num_pages == 0 )
   2.198 +			continue;
   2.199 +
   2.200 +		for (j = 0;
   2.201 +		     j < md->num_pages >> (PAGE_SHIFT - EFI_PAGE_SHIFT);
   2.202 +		     j++) {
   2.203 +			gpfns[i] = (md->phys_addr >> PAGE_SHIFT) + j;
   2.204 +			i++;
   2.205 +		}
   2.206 +	}
   2.207 +	for (i = 0; i < nr_gpfns; i++)
   2.208 +		mfns[i] = INVALID_MFN;
   2.209 +
   2.210 +	printd("issue translate gpfn list hypercall. "
   2.211 +	       "this may take a while\n");
   2.212 +	if (xc_translate_gpfn_list(xc_handle,
   2.213 +				   domid, nr_gpfns, gpfns, mfns) < 0)
   2.214 +		err(EXIT_FAILURE, "translate gpfn list hypercall failure");
   2.215 +	printd("translate gpfn list hypercall done\n");
   2.216 +
   2.217 +	printd("checking p2m table\n");
   2.218 +	for (i = 0; i < nr_gpfns; i++) {
   2.219 +		unsigned long mfn_by_translated = mfns[i];
   2.220 +		unsigned long mfn_by_p2m =
   2.221 +			xc_ia64_p2m_mfn(&p2m_table, gpfns[i]);
   2.222 +		if (mfn_by_translated != mfn_by_p2m &&
   2.223 +		    !(mfn_by_translated == 0 && mfn_by_p2m == INVALID_MFN)) {
   2.224 +			printf("ERROR! i 0x%lx gpfn "
   2.225 +			       "0x%lx trnslated 0x%lx p2m 0x%lx\n",
   2.226 +			       i, gpfns[i], mfn_by_translated, mfn_by_p2m);
   2.227 +		}
   2.228 +	}
   2.229 +	printd("checking p2m table done\n");
   2.230 +
   2.231 +	xc_ia64_p2m_unmap(&p2m_table);
   2.232 +	munmap(memmap_info, map_size);
   2.233 +	munmap(shinfo, PAGE_SIZE);
   2.234 +
   2.235 +	return EXIT_SUCCESS;
   2.236 +}