[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC][PATCH] Hypercalls from HVM guests (2/2)
A sample test module for the HVM hypercall interface. Signed-off-by: Steve Ofsthun <sofsthun@xxxxxxxxxxxxxxx> 1) To use, put these files in a directory by themselves. 2) Edit the Makefile: Set XEN_ROOT to a populated xen tree. Set LINUX_ROOT to a linux build tree for your HVM domU kernel. 3) make The output should be test.ko. You should be able to load this module on an HVM guest using: # insmod test.ko Module output on the console should appear like: hypercall_page @ ffffffffa020f000 xen_features[0].writable_page_tables = 1 xen_features[0].writable_descriptor_tables = 0 xen_features[0].auto_translated_physmap = 1 xen_features[0].supervisor_mode_kernel = 0 xen_features[0].pae_pgdir_above_4gb = 1 Enjoy, Steve -- Steve Ofsthun - Virtual Iron Software, Inc. # Makefile for test driver #EXTRA_CFLAGS += -DDEBUG obj-m := test.o test-objs := features.o hypercall.o # Point XEN_ROOT at a valid xen tree ifeq ($(XEN_ROOT),) XEN_ROOT = ~/BK/xen-unstable-test64/ endif # Point LINUX_ROOT at a valid linux tree ifeq ($(LINUX_ROOT),) LINUX_ROOT = $(XEN_ROOT)/linux-2.6.16-xen/ endif LOCAL_DRIVER_LIST = . LOCAL_DRIVER_DIRS := $(foreach dir,$(LOCAL_DRIVER_LIST),$(shell pwd)/$(dir)) default: @if [ ! -d $(XEN_ROOT) ]; then \ echo XEN_ROOT must be set; exit 1; \ fi @if [ ! -d $(LINUX_ROOT) ]; then \ echo LINUX_ROOT must be set; exit 1; \ fi $(MAKE) -C $(LINUX_ROOT) SUBDIRS="$(LOCAL_DRIVER_DIRS)" modules clean: $(MAKE) -C $(LINUX_ROOT) SUBDIRS="$(LOCAL_DRIVER_DIRS)" $@ /****************************************************************************** * features.c * * Xen feature flags. * * Copyright (c) 2006, Ian Campbell, XenSource Inc. */ #include <linux/types.h> #include <linux/cache.h> #include <linux/module.h> #include <asm/hypervisor.h> #include <xen/features.h> #ifndef __read_mostly #define __read_mostly __cacheline_aligned #endif //#define DEBUG u8 xen_features[XENFEAT_NR_SUBMAPS * 32] __read_mostly; EXPORT_SYMBOL(xen_features); #ifdef DEBUG static const char *feature_names[XENFEAT_NR_SUBMAPS*32] = { [XENFEAT_writable_page_tables] = "writable_page_tables", [XENFEAT_writable_descriptor_tables] = "writable_descriptor_tables", [XENFEAT_auto_translated_physmap] = "auto_translated_physmap", [XENFEAT_supervisor_mode_kernel] = "supervisor_mode_kernel", [XENFEAT_pae_pgdir_above_4gb] = "pae_pgdir_above_4gb" }; #endif void setup_xen_features(void) { xen_feature_info_t fi; int i, j; for (i = 0; i < XENFEAT_NR_SUBMAPS; i++) { fi.submap_idx = i; if (HYPERVISOR_xen_version(XENVER_get_features, &fi) < 0) break; for (j=0; j<32; j++) xen_features[i*32+j] = !!(fi.submap & 1<<j); } #ifdef DEBUG for (i = 0; i < XENFEAT_NR_SUBMAPS; i++) { for (j=0; j<32; j++) { if (feature_names[j]) printk("xen_features[%d].%s = %d\n", i, feature_names[j], xen_features[i*32+j]); } } #endif } EXPORT_SYMBOL(setup_xen_features); /****************************************************************************** * hypercall.c * * Copyright (C) 2006, Virtual Iron Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope 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. * */ #include <linux/module.h> MODULE_LICENSE("GPL"); #include "hypercall.h" char hypercall_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE))); static inline int HYPERVISOR_arg_test(long a, long b, long c, long d, long e) { return _hypercall5(int, grant_table_op, a, b, c, d, e); } extern void setup_xen_features(void); static int __init hypercall_page_setup(void) { hypercall_page_init(&hypercall_page); printk(KERN_ERR "hypercall_page @ %p\n", &hypercall_page); #if BITS_PER_LONG == 64 HYPERVISOR_arg_test(0x1111111111111111, 0x2222222222222222, 0x3333333333333333, 0x4444444444444444, 0x5555555555555555); #else HYPERVISOR_arg_test(0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555); #endif setup_xen_features(); return 0; } static void __exit hypercall_page_cleanup(void) { } module_init(hypercall_page_setup); module_exit(hypercall_page_cleanup); /****************************************************************************** * hypercall.h * * Copyright (C) 2006, Virtual Iron Software, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope 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. * */ #include <linux/version.h> #include <asm/hypervisor.h> #include <xen/interface/xen.h> static inline int check_amd(void) { char id[12]; __asm__ __volatile__( "cpuid" : "=b" (*(int *)(&id[0])), "=c" (*(int *)(&id[8])), "=d" (*(int *)(&id[4])) : "a" (0) ); return __builtin_memcmp(id, "AuthenticAMD", 12) == 0; } #define VMCALL_INSTR 0x0f,0x01,0xc1 #define VMMCALL_INSTR 0x0f,0x01,0xd6 #define NR_hypercalls (PAGE_SIZE/32) static inline void hypercall_page_init(void *hypercall_page) { int i; char *p; char vmcall[3] = { VMCALL_INSTR }; char vmmcall[3] = { VMMCALL_INSTR }; int amd = check_amd(); for ( i = 0; i < NR_hypercalls; i++ ) { p = (char *)(hypercall_page + (i * 32)); /* * This call sequence works for 32-bit and 64-bit guests. */ memset(p, 0xcc, 32); *(u8 *)(p+ 0) = 0xb8; /* mov $<i>,%eax */ *(u32 *)(p+ 1) = i; if (amd) { *(u8 *)(p+ 5) = vmmcall[0]; *(u8 *)(p+ 6) = vmmcall[1]; *(u8 *)(p+ 7) = vmmcall[2]; } else { *(u8 *)(p+ 5) = vmcall[0]; *(u8 *)(p+ 6) = vmcall[1]; *(u8 *)(p+ 7) = vmcall[2]; } *(u8 *)(p+ 8) = 0xc3; /* ret */ } } _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |