ia64/xen-unstable

changeset 13883:6a383beedf83

Add example xen-detect.c code for detecting application execution in
Xen PV or HVM contexts, using the Xen CPUID extensions.
Signed-off-by: Keir Fraser <keir@xensource.com>
author Keir Fraser <keir@xensource.com>
date Thu Feb 08 17:04:26 2007 +0000 (2007-02-08)
parents d609929f1408
children 870370439fb9
files .hgignore tools/misc/Makefile tools/misc/xen-detect.c
line diff
     1.1 --- a/.hgignore	Thu Feb 08 16:52:05 2007 +0000
     1.2 +++ b/.hgignore	Thu Feb 08 17:04:26 2007 +0000
     1.3 @@ -138,6 +138,7 @@
     1.4  ^tools/misc/miniterm/miniterm$
     1.5  ^tools/misc/xc_shadow$
     1.6  ^tools/misc/xen_cpuperf$
     1.7 +^tools/misc/xen-detect$
     1.8  ^tools/misc/xenperf$
     1.9  ^tools/pygrub/build/.*$
    1.10  ^tools/python/build/.*$
     2.1 --- a/tools/misc/Makefile	Thu Feb 08 16:52:05 2007 +0000
     2.2 +++ b/tools/misc/Makefile	Thu Feb 08 17:04:26 2007 +0000
     2.3 @@ -9,7 +9,7 @@ CFLAGS   += $(INCLUDES)
     2.4  
     2.5  HDRS     = $(wildcard *.h)
     2.6  
     2.7 -TARGETS  = xenperf xc_shadow
     2.8 +TARGETS  = xenperf xc_shadow xen-detect
     2.9  
    2.10  INSTALL_BIN  = $(TARGETS) xencons
    2.11  INSTALL_SBIN = netfix xm xen-bugtool xen-python-path xend xenperf
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/misc/xen-detect.c	Thu Feb 08 17:04:26 2007 +0000
     3.3 @@ -0,0 +1,107 @@
     3.4 +/******************************************************************************
     3.5 + * xen_detect.c
     3.6 + * 
     3.7 + * Simple GNU C / POSIX application to detect execution on Xen VMM platform.
     3.8 + * 
     3.9 + * Copyright (c) 2007, XenSource Inc.
    3.10 + * 
    3.11 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    3.12 + * of this software and associated documentation files (the "Software"), to
    3.13 + * deal in the Software without restriction, including without limitation the
    3.14 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
    3.15 + * sell copies of the Software, and to permit persons to whom the Software is
    3.16 + * furnished to do so, subject to the following conditions:
    3.17 + *
    3.18 + * The above copyright notice and this permission notice shall be included in
    3.19 + * all copies or substantial portions of the Software.
    3.20 + *
    3.21 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    3.22 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    3.23 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    3.24 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    3.25 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    3.26 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    3.27 + * DEALINGS IN THE SOFTWARE.
    3.28 + */
    3.29 +
    3.30 +#include <stdint.h>
    3.31 +#include <stdio.h>
    3.32 +#include <string.h>
    3.33 +#include <sys/types.h>
    3.34 +#include <sys/wait.h>
    3.35 +#include <unistd.h>
    3.36 +
    3.37 +static int pv_context;
    3.38 +
    3.39 +static void cpuid(uint32_t idx,
    3.40 +                  uint32_t *eax,
    3.41 +                  uint32_t *ebx,
    3.42 +                  uint32_t *ecx,
    3.43 +                  uint32_t *edx)
    3.44 +{
    3.45 +    asm volatile (
    3.46 +        "test %1,%1 ; jz 1f ; ud2a ; .ascii \"xen\" ; 1: cpuid"
    3.47 +        : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
    3.48 +        : "0" (idx), "1" (pv_context) );
    3.49 +}
    3.50 +
    3.51 +static int check_for_xen(void)
    3.52 +{
    3.53 +    uint32_t eax, ebx, ecx, edx;
    3.54 +    char signature[13];
    3.55 +
    3.56 +    cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
    3.57 +    *(uint32_t *)(signature + 0) = ebx;
    3.58 +    *(uint32_t *)(signature + 4) = ecx;
    3.59 +    *(uint32_t *)(signature + 8) = edx;
    3.60 +    signature[12] = '\0';
    3.61 +
    3.62 +    if ( strcmp("XenVMMXenVMM", signature) || (eax < 0x40000002) )
    3.63 +        return 0;
    3.64 +
    3.65 +    cpuid(0x40000001, &eax, &ebx, &ecx, &edx);
    3.66 +    printf("Running in %s context on Xen v%d.%d.\n",
    3.67 +           pv_context ? "PV" : "HVM", (uint16_t)(eax >> 16), (uint16_t)eax);
    3.68 +    return 1;
    3.69 +}
    3.70 +
    3.71 +int main(void)
    3.72 +{
    3.73 +    pid_t pid;
    3.74 +    int status;
    3.75 +    uint32_t dummy;
    3.76 +
    3.77 +    /* Check for execution in HVM context. */
    3.78 +    if ( check_for_xen() )
    3.79 +        return 0;
    3.80 +
    3.81 +    /* Now we check for execution in PV context. */
    3.82 +    pv_context = 1;
    3.83 +
    3.84 +    /*
    3.85 +     * Fork a child to test the paravirtualised CPUID instruction.
    3.86 +     * If executed outside Xen PV context, the extended opcode will fault.
    3.87 +     */
    3.88 +    pid = fork();
    3.89 +    switch ( pid )
    3.90 +    {
    3.91 +    case 0:
    3.92 +        /* Child: test paravirtualised CPUID opcode and then exit cleanly. */
    3.93 +        cpuid(0x40000000, &dummy, &dummy, &dummy, &dummy);
    3.94 +        exit(0);
    3.95 +    case -1:
    3.96 +        fprintf(stderr, "Fork failed.\n");
    3.97 +        return 0;
    3.98 +    }
    3.99 +
   3.100 +    /*
   3.101 +     * Parent waits for child to terminate and checks for clean exit.
   3.102 +     * Only if the exit is clean is it safe for us to try the extended CPUID.
   3.103 +     */
   3.104 +    waitpid(pid, &status, 0);
   3.105 +    if ( WIFEXITED(status) && check_for_xen() )
   3.106 +        return 0;
   3.107 +
   3.108 +    printf("Not running on Xen.\n");
   3.109 +    return 0;
   3.110 +}