hvm hypercall 2

来源:互联网 发布:长沙国安网络客服电话 编辑:程序博客网 时间:2024/06/02 04:53
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) makeThe output should be test.ko.  You should be able to load thismodule on an HVM guest using:# insmod test.koModule output on the console should appear like:hypercall_page @ ffffffffa020f000xen_features[0].writable_page_tables = 1xen_features[0].writable_descriptor_tables = 0xen_features[0].auto_translated_physmap = 1xen_features[0].supervisor_mode_kernel = 0xen_features[0].pae_pgdir_above_4gb = 1Enjoy,Steve--Steve Ofsthun - Virtual Iron Software, Inc.
# Makefile for test driver#EXTRA_CFLAGS += -DDEBUGobj-m := test.otest-objs := features.o hypercall.o# Point XEN_ROOT at a valid xen treeifeq ($(XEN_ROOT),)XEN_ROOT = ~/BK/xen-unstable-test64/endif# Point LINUX_ROOT at a valid linux treeifeq ($(LINUX_ROOT),)LINUX_ROOT = $(XEN_ROOT)/linux-2.6.16-xen/endifLOCAL_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)" modulesclean:        $(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 DEBUGu8 xen_features[XENFEAT_NR_SUBMAPS * 32] __read_mostly;EXPORT_SYMBOL(xen_features);#ifdef DEBUGstatic 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"};#endifvoid 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 intHYPERVISOR_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 intcheck_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 */    }}
原创粉丝点击